Add support for references.

This commit is contained in:
Scott Olson 2015-12-28 22:24:05 -06:00
parent 947c1badd1
commit a3ca2db48a
2 changed files with 47 additions and 9 deletions

View file

@ -14,6 +14,7 @@ enum Value {
Uninit,
Bool(bool),
Int(i64), // FIXME(tsion): Should be bit-width aware.
Pointer(Pointer),
Adt { variant: usize, data_ptr: Pointer },
Func(def_id::DefId),
}
@ -247,18 +248,23 @@ impl<'a, 'tcx> Interpreter<'a, 'tcx> {
mir::ProjectionElem::Downcast(_, variant) => {
let adt_val = self.read_pointer(base_ptr);
match adt_val {
Value::Adt { variant: actual_variant, data_ptr } => {
debug_assert_eq!(variant, actual_variant);
data_ptr
}
_ => panic!("Downcast attempted on non-Adt: {:?}", adt_val),
if let Value::Adt { variant: actual_variant, data_ptr } = adt_val {
debug_assert_eq!(variant, actual_variant);
data_ptr
} else {
panic!("Downcast attempted on non-ADT: {:?}", adt_val)
}
}
mir::ProjectionElem::Deref => {
let ptr_val = self.read_pointer(base_ptr);
if let Value::Pointer(ptr) = ptr_val {
ptr
} else {
panic!("Deref attempted on non-pointer: {:?}", ptr_val)
}
}
mir::ProjectionElem::Deref => unimplemented!(),
mir::ProjectionElem::Index(ref _operand) => unimplemented!(),
mir::ProjectionElem::ConstantIndex { .. } => unimplemented!(),
}
@ -313,6 +319,10 @@ impl<'a, 'tcx> Interpreter<'a, 'tcx> {
}
}
mir::Rvalue::Ref(_region, _kind, ref lvalue) => {
Value::Pointer(self.eval_lvalue(lvalue))
}
mir::Rvalue::Aggregate(mir::AggregateKind::Adt(ref adt_def, variant, _substs),
ref operands) => {
let max_fields = adt_def.variants

View file

@ -94,6 +94,34 @@ fn match_int() -> i32 {
}
}
#[miri_run(expected = "Int(1)")]
fn one_line_ref() -> i32 {
*&1
}
#[miri_run(expected = "Int(1)")]
fn basic_ref() -> i32 {
let x = &1;
*x
}
#[miri_run(expected = "Int(3)")]
fn basic_ref_mut() -> i32 {
let x = &mut 1;
*x += 2;
*x
}
#[miri_run(expected = "Int(3)")]
fn basic_ref_mut_var() -> i32 {
let mut a = 1;
{
let x = &mut a;
*x += 2;
}
a
}
// #[miri_run(expected = "Int(4)")]
// fn match_int_range() -> i32 {
// let n = 42;