diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-17 12:02:58 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-17 12:02:58 +0000 |
commit | 698f8c2f01ea549d77d7dc3338a12e04c11057b9 (patch) | |
tree | 173a775858bd501c378080a10dca74132f05bc50 /compiler/rustc_codegen_cranelift/src/vtable.rs | |
parent | Initial commit. (diff) | |
download | rustc-698f8c2f01ea549d77d7dc3338a12e04c11057b9.tar.xz rustc-698f8c2f01ea549d77d7dc3338a12e04c11057b9.zip |
Adding upstream version 1.64.0+dfsg1.upstream/1.64.0+dfsg1
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'compiler/rustc_codegen_cranelift/src/vtable.rs')
-rw-r--r-- | compiler/rustc_codegen_cranelift/src/vtable.rs | 79 |
1 files changed, 79 insertions, 0 deletions
diff --git a/compiler/rustc_codegen_cranelift/src/vtable.rs b/compiler/rustc_codegen_cranelift/src/vtable.rs new file mode 100644 index 000000000..36b3725ef --- /dev/null +++ b/compiler/rustc_codegen_cranelift/src/vtable.rs @@ -0,0 +1,79 @@ +//! Codegen vtables and vtable accesses. +//! +//! See `rustc_codegen_ssa/src/meth.rs` for reference. + +use crate::constant::data_id_for_alloc_id; +use crate::prelude::*; + +pub(crate) fn vtable_memflags() -> MemFlags { + let mut flags = MemFlags::trusted(); // A vtable access is always aligned and will never trap. + flags.set_readonly(); // A vtable is always read-only. + flags +} + +pub(crate) fn drop_fn_of_obj(fx: &mut FunctionCx<'_, '_, '_>, vtable: Value) -> Value { + let usize_size = fx.layout_of(fx.tcx.types.usize).size.bytes() as usize; + fx.bcx.ins().load( + fx.pointer_type, + vtable_memflags(), + vtable, + (ty::COMMON_VTABLE_ENTRIES_DROPINPLACE * usize_size) as i32, + ) +} + +pub(crate) fn size_of_obj(fx: &mut FunctionCx<'_, '_, '_>, vtable: Value) -> Value { + let usize_size = fx.layout_of(fx.tcx.types.usize).size.bytes() as usize; + fx.bcx.ins().load( + fx.pointer_type, + vtable_memflags(), + vtable, + (ty::COMMON_VTABLE_ENTRIES_SIZE * usize_size) as i32, + ) +} + +pub(crate) fn min_align_of_obj(fx: &mut FunctionCx<'_, '_, '_>, vtable: Value) -> Value { + let usize_size = fx.layout_of(fx.tcx.types.usize).size.bytes() as usize; + fx.bcx.ins().load( + fx.pointer_type, + vtable_memflags(), + vtable, + (ty::COMMON_VTABLE_ENTRIES_ALIGN * usize_size) as i32, + ) +} + +pub(crate) fn get_ptr_and_method_ref<'tcx>( + fx: &mut FunctionCx<'_, '_, 'tcx>, + arg: CValue<'tcx>, + idx: usize, +) -> (Value, Value) { + let (ptr, vtable) = if let Abi::ScalarPair(_, _) = arg.layout().abi { + arg.load_scalar_pair(fx) + } else { + let (ptr, vtable) = arg.try_to_ptr().unwrap(); + (ptr.get_addr(fx), vtable.unwrap()) + }; + + let usize_size = fx.layout_of(fx.tcx.types.usize).size.bytes(); + let func_ref = fx.bcx.ins().load( + fx.pointer_type, + vtable_memflags(), + vtable, + (idx * usize_size as usize) as i32, + ); + (ptr, func_ref) +} + +pub(crate) fn get_vtable<'tcx>( + fx: &mut FunctionCx<'_, '_, 'tcx>, + ty: Ty<'tcx>, + trait_ref: Option<ty::PolyExistentialTraitRef<'tcx>>, +) -> Value { + let alloc_id = fx.tcx.vtable_allocation((ty, trait_ref)); + let data_id = + data_id_for_alloc_id(&mut fx.constants_cx, &mut *fx.module, alloc_id, Mutability::Not); + let local_data_id = fx.module.declare_data_in_func(data_id, &mut fx.bcx.func); + if fx.clif_comments.enabled() { + fx.add_comment(local_data_id, format!("vtable: {:?}", alloc_id)); + } + fx.bcx.ins().global_value(fx.pointer_type, local_data_id) +} |