1
Fork 0

Pass thin self ptr to virtual calls.

This commit is contained in:
Scott Olson 2016-10-16 02:12:26 -06:00
parent 268bf9c185
commit c1b97f1440
3 changed files with 14 additions and 6 deletions

View file

@ -352,7 +352,7 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
} }
} }
ty::TyTrait(..) => { 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. // 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 size = self.memory.read_usize(vtable.offset(pointer_size as isize))?;
let align = self.memory.read_usize(vtable.offset(pointer_size as isize * 2))?; let align = self.memory.read_usize(vtable.offset(pointer_size as isize * 2))?;

View file

@ -452,7 +452,8 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
traits::VtableObject(ref data) => { traits::VtableObject(ref data) => {
let idx = self.tcx.get_vtable_index_of_object_method(data, def_id); 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) { 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 idx = idx + 3;
let offset = idx * self.memory.pointer_size(); let offset = idx * self.memory.pointer_size();
let fn_ptr = self.memory.read_ptr(vtable.offset(offset as isize))?; let fn_ptr = self.memory.read_ptr(vtable.offset(offset as isize))?;

View file

@ -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::*; use self::Value::*;
match *self { match *self {
ByRef(ptr) => mem.read_ptr(ptr.offset(mem.pointer_size() as isize)), ByRef(ptr) => {
ByValPair(_, PrimVal::Ptr(vtable)) => Ok(vtable), let ptr = mem.read_ptr(ptr)?;
_ => unimplemented!(), 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),
} }
} }