]> git.proxmox.com Git - rustc.git/blame - compiler/rustc_codegen_cranelift/src/vtable.rs
New upstream version 1.66.0+dfsg1
[rustc.git] / compiler / rustc_codegen_cranelift / src / vtable.rs
CommitLineData
29967ef6
XL
1//! Codegen vtables and vtable accesses.
2//!
cdc7bbd5 3//! See `rustc_codegen_ssa/src/meth.rs` for reference.
29967ef6 4
136023e0 5use crate::constant::data_id_for_alloc_id;
29967ef6
XL
6use crate::prelude::*;
7
94222f64 8pub(crate) fn vtable_memflags() -> MemFlags {
29967ef6
XL
9 let mut flags = MemFlags::trusted(); // A vtable access is always aligned and will never trap.
10 flags.set_readonly(); // A vtable is always read-only.
11 flags
12}
13
6a06907d 14pub(crate) fn drop_fn_of_obj(fx: &mut FunctionCx<'_, '_, '_>, vtable: Value) -> Value {
29967ef6
XL
15 let usize_size = fx.layout_of(fx.tcx.types.usize).size.bytes() as usize;
16 fx.bcx.ins().load(
94222f64 17 fx.pointer_type,
29967ef6
XL
18 vtable_memflags(),
19 vtable,
136023e0 20 (ty::COMMON_VTABLE_ENTRIES_DROPINPLACE * usize_size) as i32,
29967ef6
XL
21 )
22}
23
6a06907d 24pub(crate) fn size_of_obj(fx: &mut FunctionCx<'_, '_, '_>, vtable: Value) -> Value {
29967ef6
XL
25 let usize_size = fx.layout_of(fx.tcx.types.usize).size.bytes() as usize;
26 fx.bcx.ins().load(
94222f64 27 fx.pointer_type,
29967ef6
XL
28 vtable_memflags(),
29 vtable,
136023e0 30 (ty::COMMON_VTABLE_ENTRIES_SIZE * usize_size) as i32,
29967ef6
XL
31 )
32}
33
6a06907d 34pub(crate) fn min_align_of_obj(fx: &mut FunctionCx<'_, '_, '_>, vtable: Value) -> Value {
29967ef6
XL
35 let usize_size = fx.layout_of(fx.tcx.types.usize).size.bytes() as usize;
36 fx.bcx.ins().load(
94222f64 37 fx.pointer_type,
29967ef6
XL
38 vtable_memflags(),
39 vtable,
136023e0 40 (ty::COMMON_VTABLE_ENTRIES_ALIGN * usize_size) as i32,
29967ef6
XL
41 )
42}
43
44pub(crate) fn get_ptr_and_method_ref<'tcx>(
6a06907d 45 fx: &mut FunctionCx<'_, '_, 'tcx>,
29967ef6
XL
46 arg: CValue<'tcx>,
47 idx: usize,
2b03887a
FG
48) -> (Pointer, Value) {
49 let (ptr, vtable) = 'block: {
50 if let ty::Ref(_, ty, _) = arg.layout().ty.kind() {
51 if ty.is_dyn_star() {
52 let inner_layout = fx.layout_of(arg.layout().ty.builtin_deref(true).unwrap().ty);
53 let dyn_star = CPlace::for_ptr(Pointer::new(arg.load_scalar(fx)), inner_layout);
54 let ptr = dyn_star.place_field(fx, mir::Field::new(0)).to_ptr();
55 let vtable =
56 dyn_star.place_field(fx, mir::Field::new(1)).to_cvalue(fx).load_scalar(fx);
57 break 'block (ptr, vtable);
58 }
59 }
60
61 if let Abi::ScalarPair(_, _) = arg.layout().abi {
62 let (ptr, vtable) = arg.load_scalar_pair(fx);
63 (Pointer::new(ptr), vtable)
64 } else {
65 let (ptr, vtable) = arg.try_to_ptr().unwrap();
66 (ptr, vtable.unwrap())
67 }
29967ef6
XL
68 };
69
70 let usize_size = fx.layout_of(fx.tcx.types.usize).size.bytes();
71 let func_ref = fx.bcx.ins().load(
94222f64 72 fx.pointer_type,
29967ef6
XL
73 vtable_memflags(),
74 vtable,
136023e0 75 (idx * usize_size as usize) as i32,
29967ef6
XL
76 );
77 (ptr, func_ref)
78}
79
80pub(crate) fn get_vtable<'tcx>(
6a06907d 81 fx: &mut FunctionCx<'_, '_, 'tcx>,
136023e0 82 ty: Ty<'tcx>,
29967ef6
XL
83 trait_ref: Option<ty::PolyExistentialTraitRef<'tcx>>,
84) -> Value {
dc3f5686 85 let alloc_id = fx.tcx.vtable_allocation((ty, trait_ref));
136023e0
XL
86 let data_id =
87 data_id_for_alloc_id(&mut fx.constants_cx, &mut *fx.module, alloc_id, Mutability::Not);
17df50a5 88 let local_data_id = fx.module.declare_data_in_func(data_id, &mut fx.bcx.func);
136023e0
XL
89 if fx.clif_comments.enabled() {
90 fx.add_comment(local_data_id, format!("vtable: {:?}", alloc_id));
29967ef6 91 }
136023e0 92 fx.bcx.ins().global_value(fx.pointer_type, local_data_id)
29967ef6 93}