From a3ca2db48aff772b0ff4e317c22681332eda0293 Mon Sep 17 00:00:00 2001 From: Scott Olson Date: Mon, 28 Dec 2015 22:24:05 -0600 Subject: [PATCH] Add support for references. --- src/interpreter.rs | 28 +++++++++++++++++++--------- test/basic.rs | 28 ++++++++++++++++++++++++++++ 2 files changed, 47 insertions(+), 9 deletions(-) diff --git a/src/interpreter.rs b/src/interpreter.rs index f5a60770f7fd..e290a8d0c731 100644 --- a/src/interpreter.rs +++ b/src/interpreter.rs @@ -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 diff --git a/test/basic.rs b/test/basic.rs index a4d0b4eb8b2d..923abb1b80ea 100644 --- a/test/basic.rs +++ b/test/basic.rs @@ -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;