Synchronize get_vtable with the codegen_llvm
one
This commit is contained in:
parent
80feed380d
commit
8ac7fa414b
3 changed files with 14 additions and 13 deletions
|
@ -327,12 +327,7 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M>
|
||||||
}
|
}
|
||||||
(_, &ty::Dynamic(ref data, _)) => {
|
(_, &ty::Dynamic(ref data, _)) => {
|
||||||
// Initial cast from sized to dyn trait
|
// Initial cast from sized to dyn trait
|
||||||
let trait_ref = data.principal().with_self_ty(
|
let vtable = self.get_vtable(src_pointee_ty, data.principal())?;
|
||||||
*self.tcx,
|
|
||||||
src_pointee_ty,
|
|
||||||
);
|
|
||||||
let trait_ref = self.tcx.erase_regions(&trait_ref);
|
|
||||||
let vtable = self.get_vtable(src_pointee_ty, trait_ref)?;
|
|
||||||
let ptr = self.read_value(src)?.to_scalar_ptr()?;
|
let ptr = self.read_value(src)?.to_scalar_ptr()?;
|
||||||
let val = Value::new_dyn_trait(ptr, vtable);
|
let val = Value::new_dyn_trait(ptr, vtable);
|
||||||
self.write_value(val, dest)
|
self.write_value(val, dest)
|
||||||
|
|
|
@ -53,7 +53,7 @@ pub struct EvalContext<'a, 'mir, 'tcx: 'a + 'mir, M: Machine<'a, 'mir, 'tcx>> {
|
||||||
pub(crate) stack: Vec<Frame<'mir, 'tcx, M::PointerTag>>,
|
pub(crate) stack: Vec<Frame<'mir, 'tcx, M::PointerTag>>,
|
||||||
|
|
||||||
/// A cache for deduplicating vtables
|
/// A cache for deduplicating vtables
|
||||||
pub(super) vtables: FxHashMap<(Ty<'tcx>, ty::PolyTraitRef<'tcx>), AllocId>,
|
pub(super) vtables: FxHashMap<(Ty<'tcx>, ty::PolyExistentialTraitRef<'tcx>), AllocId>,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A stack frame.
|
/// A stack frame.
|
||||||
|
|
|
@ -24,22 +24,28 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M>
|
||||||
pub fn get_vtable(
|
pub fn get_vtable(
|
||||||
&mut self,
|
&mut self,
|
||||||
ty: Ty<'tcx>,
|
ty: Ty<'tcx>,
|
||||||
trait_ref: ty::PolyTraitRef<'tcx>,
|
poly_trait_ref: ty::PolyExistentialTraitRef<'tcx>,
|
||||||
) -> EvalResult<'tcx, Pointer<M::PointerTag>> {
|
) -> EvalResult<'tcx, Pointer<M::PointerTag>> {
|
||||||
debug!("get_vtable(trait_ref={:?})", trait_ref);
|
debug!("get_vtable(trait_ref={:?})", poly_trait_ref);
|
||||||
|
|
||||||
if let Some(&vtable) = self.vtables.get(&(ty, trait_ref)) {
|
let (ty, poly_trait_ref) = self.tcx.erase_regions(&(ty, poly_trait_ref));
|
||||||
|
|
||||||
|
if let Some(&vtable) = self.vtables.get(&(ty, poly_trait_ref)) {
|
||||||
return Ok(Pointer::from(vtable).with_default_tag());
|
return Ok(Pointer::from(vtable).with_default_tag());
|
||||||
}
|
}
|
||||||
|
|
||||||
let layout = self.layout_of(trait_ref.self_ty())?;
|
let trait_ref = poly_trait_ref.with_self_ty(*self.tcx, ty);
|
||||||
|
let trait_ref = self.tcx.erase_regions(&trait_ref);
|
||||||
|
|
||||||
|
let methods = self.tcx.vtable_methods(trait_ref);
|
||||||
|
|
||||||
|
let layout = self.layout_of(ty)?;
|
||||||
assert!(!layout.is_unsized(), "can't create a vtable for an unsized type");
|
assert!(!layout.is_unsized(), "can't create a vtable for an unsized type");
|
||||||
let size = layout.size.bytes();
|
let size = layout.size.bytes();
|
||||||
let align = layout.align.abi();
|
let align = layout.align.abi();
|
||||||
|
|
||||||
let ptr_size = self.pointer_size();
|
let ptr_size = self.pointer_size();
|
||||||
let ptr_align = self.tcx.data_layout.pointer_align;
|
let ptr_align = self.tcx.data_layout.pointer_align;
|
||||||
let methods = self.tcx.vtable_methods(trait_ref);
|
|
||||||
let vtable = self.memory.allocate(
|
let vtable = self.memory.allocate(
|
||||||
ptr_size * (3 + methods.len() as u64),
|
ptr_size * (3 + methods.len() as u64),
|
||||||
ptr_align,
|
ptr_align,
|
||||||
|
@ -66,7 +72,7 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M>
|
||||||
}
|
}
|
||||||
|
|
||||||
self.memory.mark_immutable(vtable.alloc_id)?;
|
self.memory.mark_immutable(vtable.alloc_id)?;
|
||||||
assert!(self.vtables.insert((ty, trait_ref), vtable.alloc_id).is_none());
|
assert!(self.vtables.insert((ty, poly_trait_ref), vtable.alloc_id).is_none());
|
||||||
|
|
||||||
Ok(vtable)
|
Ok(vtable)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue