1
Fork 0

Thinify the fat pointer on virtual function calls

This commit is contained in:
Oliver Schneider 2017-03-23 18:32:57 +01:00
parent cb867d250a
commit bbeb7216e0
3 changed files with 55 additions and 1 deletions

View file

@ -200,6 +200,12 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
(Size::from_bytes(field * elem_size), false)
}
FatPointer { .. } => {
let bytes = field_index as u64 * self.memory.pointer_size();
let offset = Size::from_bytes(bytes);
(offset, false)
}
_ => bug!("field access on non-product type: {:?}", base_layout),
};

View file

@ -337,11 +337,18 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
let (_, vtable) = self.eval_operand(&arg_operands[0])?.expect_ptr_vtable_pair(&self.memory)?;
let fn_ptr = self.memory.read_ptr(vtable.offset(ptr_size * (idx as u64 + 3)))?;
let instance = self.memory.get_fn(fn_ptr.alloc_id)?;
let mut arg_operands = arg_operands.to_vec();
let ty = self.operand_ty(&arg_operands[0]);
let ty = self.get_field_ty(ty, 0)?;
match arg_operands[0] {
mir::Operand::Consume(ref mut lval) => *lval = lval.clone().field(mir::Field::new(0), ty),
_ => bug!("virtual call first arg cannot be a constant"),
}
// recurse with concrete function
self.eval_fn_call(
instance,
destination,
arg_operands,
&arg_operands,
span,
sig,
)

View file

@ -0,0 +1,41 @@
// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
#![feature(box_syntax)]
trait T {
fn print(&self);
}
#[derive(Debug)]
struct S {
s: isize,
}
impl T for S {
fn print(&self) {
println!("{:?}", self);
}
}
fn print_t(t: &T) {
t.print();
}
fn print_s(s: &S) {
s.print();
}
pub fn main() {
let s: Box<S> = box S { s: 5 };
print_s(&*s);
let t: Box<T> = s as Box<T>;
print_t(&*t);
}