Emit the right types for vtable pointers when dropping dyn*

This commit is contained in:
Michael Goulet 2023-02-15 05:11:27 +00:00
parent e82cc656c8
commit 7f798c2b21

View file

@ -452,86 +452,84 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
args1 = [place.llval]; args1 = [place.llval];
&args1[..] &args1[..]
}; };
let (drop_fn, fn_abi) = match ty.kind() { let (drop_fn, fn_abi) =
// FIXME(eddyb) perhaps move some of this logic into match ty.kind() {
// `Instance::resolve_drop_in_place`? // FIXME(eddyb) perhaps move some of this logic into
ty::Dynamic(_, _, ty::Dyn) => { // `Instance::resolve_drop_in_place`?
// IN THIS ARM, WE HAVE: ty::Dynamic(_, _, ty::Dyn) => {
// ty = *mut (dyn Trait) // IN THIS ARM, WE HAVE:
// which is: exists<T> ( *mut T, Vtable<T: Trait> ) // ty = *mut (dyn Trait)
// args[0] args[1] // which is: exists<T> ( *mut T, Vtable<T: Trait> )
// // args[0] args[1]
// args = ( Data, Vtable ) //
// | // args = ( Data, Vtable )
// v // |
// /-------\ // v
// | ... | // /-------\
// \-------/ // | ... |
// // \-------/
let virtual_drop = Instance { //
def: ty::InstanceDef::Virtual(drop_fn.def_id(), 0), let virtual_drop = Instance {
substs: drop_fn.substs, def: ty::InstanceDef::Virtual(drop_fn.def_id(), 0),
}; substs: drop_fn.substs,
debug!("ty = {:?}", ty); };
debug!("drop_fn = {:?}", drop_fn); debug!("ty = {:?}", ty);
debug!("args = {:?}", args); debug!("drop_fn = {:?}", drop_fn);
let fn_abi = bx.fn_abi_of_instance(virtual_drop, ty::List::empty()); debug!("args = {:?}", args);
let vtable = args[1]; let fn_abi = bx.fn_abi_of_instance(virtual_drop, ty::List::empty());
// Truncate vtable off of args list let vtable = args[1];
args = &args[..1]; // Truncate vtable off of args list
( args = &args[..1];
meth::VirtualIndex::from_index(ty::COMMON_VTABLE_ENTRIES_DROPINPLACE) (
.get_fn(bx, vtable, ty, &fn_abi), meth::VirtualIndex::from_index(ty::COMMON_VTABLE_ENTRIES_DROPINPLACE)
fn_abi, .get_fn(bx, vtable, ty, &fn_abi),
) fn_abi,
} )
ty::Dynamic(_, _, ty::DynStar) => { }
// IN THIS ARM, WE HAVE: ty::Dynamic(_, _, ty::DynStar) => {
// ty = *mut (dyn* Trait) // IN THIS ARM, WE HAVE:
// which is: *mut exists<T: sizeof(T) == sizeof(usize)> (T, Vtable<T: Trait>) // ty = *mut (dyn* Trait)
// // which is: *mut exists<T: sizeof(T) == sizeof(usize)> (T, Vtable<T: Trait>)
// args = [ * ] //
// | // args = [ * ]
// v // |
// ( Data, Vtable ) // v
// | // ( Data, Vtable )
// v // |
// /-------\ // v
// | ... | // /-------\
// \-------/ // | ... |
// // \-------/
// //
// WE CAN CONVERT THIS INTO THE ABOVE LOGIC BY DOING //
// // WE CAN CONVERT THIS INTO THE ABOVE LOGIC BY DOING
// data = &(*args[0]).0 // gives a pointer to Data above (really the same pointer) //
// vtable = (*args[0]).1 // loads the vtable out // data = &(*args[0]).0 // gives a pointer to Data above (really the same pointer)
// (data, vtable) // an equivalent Rust `*mut dyn Trait` // vtable = (*args[0]).1 // loads the vtable out
// // (data, vtable) // an equivalent Rust `*mut dyn Trait`
// SO THEN WE CAN USE THE ABOVE CODE. //
let virtual_drop = Instance { // SO THEN WE CAN USE THE ABOVE CODE.
def: ty::InstanceDef::Virtual(drop_fn.def_id(), 0), let virtual_drop = Instance {
substs: drop_fn.substs, def: ty::InstanceDef::Virtual(drop_fn.def_id(), 0),
}; substs: drop_fn.substs,
debug!("ty = {:?}", ty); };
debug!("drop_fn = {:?}", drop_fn); debug!("ty = {:?}", ty);
debug!("args = {:?}", args); debug!("drop_fn = {:?}", drop_fn);
let fn_abi = bx.fn_abi_of_instance(virtual_drop, ty::List::empty()); debug!("args = {:?}", args);
let data = args[0]; let fn_abi = bx.fn_abi_of_instance(virtual_drop, ty::List::empty());
let data_ty = bx.cx().backend_type(place.layout); let meta_ptr = place.project_field(bx, 1);
let vtable_ptr = let meta = bx.load_operand(meta_ptr);
bx.gep(data_ty, data, &[bx.cx().const_i32(0), bx.cx().const_i32(1)]); // Truncate vtable off of args list
let vtable = bx.load(bx.type_i8p(), vtable_ptr, abi::Align::ONE); args = &args[..1];
// Truncate vtable off of args list debug!("args' = {:?}", args);
args = &args[..1]; (
debug!("args' = {:?}", args); meth::VirtualIndex::from_index(ty::COMMON_VTABLE_ENTRIES_DROPINPLACE)
( .get_fn(bx, meta.immediate(), ty, &fn_abi),
meth::VirtualIndex::from_index(ty::COMMON_VTABLE_ENTRIES_DROPINPLACE) fn_abi,
.get_fn(bx, vtable, ty, &fn_abi), )
fn_abi, }
) _ => (bx.get_fn_addr(drop_fn), bx.fn_abi_of_instance(drop_fn, ty::List::empty())),
} };
_ => (bx.get_fn_addr(drop_fn), bx.fn_abi_of_instance(drop_fn, ty::List::empty())),
};
helper.do_call( helper.do_call(
self, self,
bx, bx,