From 619daf0129027fcbb526cb5beef19f470a43c6ae Mon Sep 17 00:00:00 2001 From: Scott Olson Date: Mon, 7 Mar 2016 07:48:38 -0600 Subject: [PATCH] Re-add support for integer binops. --- src/interpreter.rs | 164 ++++++++++++++++++++++----------------------- test/new_values.rs | 28 ++++---- 2 files changed, 96 insertions(+), 96 deletions(-) diff --git a/src/interpreter.rs b/src/interpreter.rs index b5023b5b9fd2..d37a95113bb8 100644 --- a/src/interpreter.rs +++ b/src/interpreter.rs @@ -236,90 +236,39 @@ impl<'a, 'tcx: 'a> Interpreter<'a, 'tcx> { Ok(()) } - fn lvalue_to_ptr(&self, lvalue: &mir::Lvalue<'tcx>) -> EvalResult { - let frame = self.current_frame(); + fn eval_binary_op( + &mut self, bin_op: mir::BinOp, left_operand: &mir::Operand<'tcx>, + right_operand: &mir::Operand<'tcx>, dest: Pointer + ) -> EvalResult<()> { + // FIXME(tsion): Check for non-integer binary operations. + let left = try!(self.operand_to_ptr(left_operand)); + let right = try!(self.operand_to_ptr(right_operand)); + let l = try!(self.memory.read_int(left)); + let r = try!(self.memory.read_int(right)); - use rustc::mir::repr::Lvalue::*; - let ptr = match *lvalue { - ReturnPointer => - frame.return_ptr.expect("ReturnPointer used in a function with no return value"), - Arg(i) => frame.arg_ptr(i), - Var(i) => frame.var_ptr(i), - Temp(i) => frame.temp_ptr(i), - ref l => panic!("can't handle lvalue: {:?}", l), + use rustc::mir::repr::BinOp::*; + let n = match bin_op { + Add => l + r, + Sub => l - r, + Mul => l * r, + Div => l / r, + Rem => l % r, + BitXor => l ^ r, + BitAnd => l & r, + BitOr => l | r, + Shl => l << r, + Shr => l >> r, + _ => unimplemented!(), + // Eq => Value::Bool(l == r), + // Lt => Value::Bool(l < r), + // Le => Value::Bool(l <= r), + // Ne => Value::Bool(l != r), + // Ge => Value::Bool(l >= r), + // Gt => Value::Bool(l > r), }; - - Ok(ptr) - - // mir::Lvalue::Projection(ref proj) => { - // let base_ptr = self.lvalue_to_ptr(&proj.base); - - // match proj.elem { - // mir::ProjectionElem::Field(field, _) => { - // base_ptr.offset(field.index()) - // } - - // mir::ProjectionElem::Downcast(_, variant) => { - // let adt_val = self.read_pointer(base_ptr); - // 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::Index(ref _operand) => unimplemented!(), - // mir::ProjectionElem::ConstantIndex { .. } => unimplemented!(), - // } - // } - - // _ => unimplemented!(), - // } + self.memory.write_int(dest, n) } - // fn eval_binary_op(&mut self, bin_op: mir::BinOp, left: Pointer, right: Pointer, dest: Pointer) - // -> EvalResult<()> { - // use rustc::mir::repr::BinOp::*; - // match (&left.repr, &right.repr, &dest.repr) { - // (&Repr::Int, &Repr::Int, &Repr::Int) => { - // let l = try!(self.memory.read_int(left)); - // let r = try!(self.memory.read_int(right)); - // let n = match bin_op { - // Add => l + r, - // Sub => l - r, - // Mul => l * r, - // Div => l / r, - // Rem => l % r, - // BitXor => l ^ r, - // BitAnd => l & r, - // BitOr => l | r, - // Shl => l << r, - // Shr => l >> r, - // _ => unimplemented!(), - // // Eq => Value::Bool(l == r), - // // Lt => Value::Bool(l < r), - // // Le => Value::Bool(l <= r), - // // Ne => Value::Bool(l != r), - // // Ge => Value::Bool(l >= r), - // // Gt => Value::Bool(l > r), - // }; - // self.memory.write_int(dest, n) - // } - // (l, r, o) => - // panic!("unhandled binary operation: {:?}({:?}, {:?}) into {:?}", bin_op, l, r, o), - // } - // } - fn eval_assignment(&mut self, lvalue: &mir::Lvalue<'tcx>, rvalue: &mir::Rvalue<'tcx>) -> EvalResult<()> { @@ -334,8 +283,8 @@ impl<'a, 'tcx: 'a> Interpreter<'a, 'tcx> { self.memory.copy(src, dest, dest_repr.size()) } - // BinaryOp(bin_op, ref left, ref right) => - // self.eval_binary_op(lvalue, bin_op, left, right), + BinaryOp(bin_op, ref left, ref right) => + self.eval_binary_op(bin_op, left, right, dest), // UnaryOp(un_op, ref operand) => { // let ptr = try!(self.operand_to_ptr(operand)); @@ -408,6 +357,57 @@ impl<'a, 'tcx: 'a> Interpreter<'a, 'tcx> { } } + fn lvalue_to_ptr(&self, lvalue: &mir::Lvalue<'tcx>) -> EvalResult { + let frame = self.current_frame(); + + use rustc::mir::repr::Lvalue::*; + let ptr = match *lvalue { + ReturnPointer => + frame.return_ptr.expect("ReturnPointer used in a function with no return value"), + Arg(i) => frame.arg_ptr(i), + Var(i) => frame.var_ptr(i), + Temp(i) => frame.temp_ptr(i), + ref l => panic!("can't handle lvalue: {:?}", l), + }; + + Ok(ptr) + + // mir::Lvalue::Projection(ref proj) => { + // let base_ptr = self.lvalue_to_ptr(&proj.base); + + // match proj.elem { + // mir::ProjectionElem::Field(field, _) => { + // base_ptr.offset(field.index()) + // } + + // mir::ProjectionElem::Downcast(_, variant) => { + // let adt_val = self.read_pointer(base_ptr); + // 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::Index(ref _operand) => unimplemented!(), + // mir::ProjectionElem::ConstantIndex { .. } => unimplemented!(), + // } + // } + + // _ => unimplemented!(), + // } + } + fn const_to_ptr(&mut self, const_val: &const_eval::ConstVal) -> EvalResult { use rustc::middle::const_eval::ConstVal::*; match *const_val { diff --git a/test/new_values.rs b/test/new_values.rs index 64b56b01e171..8bba137da6c0 100644 --- a/test/new_values.rs +++ b/test/new_values.rs @@ -11,10 +11,10 @@ fn ret() -> i32 { // -1 // } -// #[miri_run] -// fn add() -> i32 { -// 1 + 2 -// } +#[miri_run] +fn add() -> i32 { + 1 + 2 +} #[miri_run] fn empty() {} @@ -34,17 +34,17 @@ fn tuple_5() -> (i32, i32, i32, i32, i32) { (1, 2, 3, 4, 5) } -// #[miri_run] -// fn indirect_add() -> i32 { -// let x = 1; -// let y = 2; -// x + y -// } +#[miri_run] +fn indirect_add() -> i32 { + let x = 1; + let y = 2; + x + y +} -// #[miri_run] -// fn arith() -> i32 { -// 3*3 + 4*4 -// } +#[miri_run] +fn arith() -> i32 { + 3*3 + 4*4 +} #[miri_run] fn boolean() -> bool {