diff --git a/src/interpreter/terminator/intrinsics.rs b/src/interpreter/terminator/intrinsics.rs index 236bb5ca00b..49cef471dab 100644 --- a/src/interpreter/terminator/intrinsics.rs +++ b/src/interpreter/terminator/intrinsics.rs @@ -352,7 +352,7 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> { } } ty::TyTrait(..) => { - let vtable = value.expect_vtable(&self.memory)?; + let (_, vtable) = value.expect_ptr_vtable_pair(&self.memory)?; // the second entry in the vtable is the dynamic size of the object. let size = self.memory.read_usize(vtable.offset(pointer_size as isize))?; let align = self.memory.read_usize(vtable.offset(pointer_size as isize * 2))?; diff --git a/src/interpreter/terminator/mod.rs b/src/interpreter/terminator/mod.rs index 132aa101f87..1555f22efb2 100644 --- a/src/interpreter/terminator/mod.rs +++ b/src/interpreter/terminator/mod.rs @@ -452,7 +452,8 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> { traits::VtableObject(ref data) => { let idx = self.tcx.get_vtable_index_of_object_method(data, def_id); if let Some(&mut(ref mut first_arg, ref mut first_ty)) = args.get_mut(0) { - let vtable = first_arg.expect_vtable(&self.memory)?; + let (self_ptr, vtable) = first_arg.expect_ptr_vtable_pair(&self.memory)?; + *first_arg = Value::ByVal(PrimVal::Ptr(self_ptr)); let idx = idx + 3; let offset = idx * self.memory.pointer_size(); let fn_ptr = self.memory.read_ptr(vtable.offset(offset as isize))?; diff --git a/src/interpreter/value.rs b/src/interpreter/value.rs index 178dbac8401..b89210c065d 100644 --- a/src/interpreter/value.rs +++ b/src/interpreter/value.rs @@ -29,12 +29,19 @@ impl<'a, 'tcx: 'a> Value { } } - pub(super) fn expect_vtable(&self, mem: &Memory<'a, 'tcx>) -> EvalResult<'tcx, Pointer> { + pub(super) fn expect_ptr_vtable_pair( + &self, + mem: &Memory<'a, 'tcx> + ) -> EvalResult<'tcx, (Pointer, Pointer)> { use self::Value::*; match *self { - ByRef(ptr) => mem.read_ptr(ptr.offset(mem.pointer_size() as isize)), - ByValPair(_, PrimVal::Ptr(vtable)) => Ok(vtable), - _ => unimplemented!(), + ByRef(ptr) => { + let ptr = mem.read_ptr(ptr)?; + let vtable = mem.read_ptr(ptr.offset(mem.pointer_size() as isize))?; + Ok((ptr, vtable)) + } + ByValPair(PrimVal::Ptr(ptr), PrimVal::Ptr(vtable)) => Ok((ptr, vtable)), + _ => bug!("expected ptr and vtable, got {:?}", self), } }