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, _)) => { (_, &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)

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

View file

@ -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)
} }