1
Fork 0

Synchronize get_vtable with the codegen_llvm one

This commit is contained in:
Oliver Scherer 2018-10-12 16:45:17 +02:00
parent 80feed380d
commit 8ac7fa414b
3 changed files with 14 additions and 13 deletions

View file

@ -327,12 +327,7 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M>
}
(_, &ty::Dynamic(ref data, _)) => {
// Initial cast from sized to dyn trait
let trait_ref = data.principal().with_self_ty(
*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 vtable = self.get_vtable(src_pointee_ty, data.principal())?;
let ptr = self.read_value(src)?.to_scalar_ptr()?;
let val = Value::new_dyn_trait(ptr, vtable);
self.write_value(val, dest)

View file

@ -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>>,
/// 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.

View file

@ -24,22 +24,28 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M>
pub fn get_vtable(
&mut self,
ty: Ty<'tcx>,
trait_ref: ty::PolyTraitRef<'tcx>,
poly_trait_ref: ty::PolyExistentialTraitRef<'tcx>,
) -> 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());
}
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");
let size = layout.size.bytes();
let align = layout.align.abi();
let ptr_size = self.pointer_size();
let ptr_align = self.tcx.data_layout.pointer_align;
let methods = self.tcx.vtable_methods(trait_ref);
let vtable = self.memory.allocate(
ptr_size * (3 + methods.len() as u64),
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)?;
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)
}