Re-add support for integer binops.
This commit is contained in:
parent
83adde623f
commit
619daf0129
2 changed files with 96 additions and 96 deletions
|
@ -236,90 +236,39 @@ impl<'a, 'tcx: 'a> Interpreter<'a, 'tcx> {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn lvalue_to_ptr(&self, lvalue: &mir::Lvalue<'tcx>) -> EvalResult<Pointer> {
|
fn eval_binary_op(
|
||||||
let frame = self.current_frame();
|
&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::*;
|
use rustc::mir::repr::BinOp::*;
|
||||||
let ptr = match *lvalue {
|
let n = match bin_op {
|
||||||
ReturnPointer =>
|
Add => l + r,
|
||||||
frame.return_ptr.expect("ReturnPointer used in a function with no return value"),
|
Sub => l - r,
|
||||||
Arg(i) => frame.arg_ptr(i),
|
Mul => l * r,
|
||||||
Var(i) => frame.var_ptr(i),
|
Div => l / r,
|
||||||
Temp(i) => frame.temp_ptr(i),
|
Rem => l % r,
|
||||||
ref l => panic!("can't handle lvalue: {:?}", l),
|
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)
|
||||||
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 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>)
|
fn eval_assignment(&mut self, lvalue: &mir::Lvalue<'tcx>, rvalue: &mir::Rvalue<'tcx>)
|
||||||
-> EvalResult<()>
|
-> EvalResult<()>
|
||||||
{
|
{
|
||||||
|
@ -334,8 +283,8 @@ impl<'a, 'tcx: 'a> Interpreter<'a, 'tcx> {
|
||||||
self.memory.copy(src, dest, dest_repr.size())
|
self.memory.copy(src, dest, dest_repr.size())
|
||||||
}
|
}
|
||||||
|
|
||||||
// BinaryOp(bin_op, ref left, ref right) =>
|
BinaryOp(bin_op, ref left, ref right) =>
|
||||||
// self.eval_binary_op(lvalue, bin_op, left, right),
|
self.eval_binary_op(bin_op, left, right, dest),
|
||||||
|
|
||||||
// UnaryOp(un_op, ref operand) => {
|
// UnaryOp(un_op, ref operand) => {
|
||||||
// let ptr = try!(self.operand_to_ptr(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<Pointer> {
|
||||||
|
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<Pointer> {
|
fn const_to_ptr(&mut self, const_val: &const_eval::ConstVal) -> EvalResult<Pointer> {
|
||||||
use rustc::middle::const_eval::ConstVal::*;
|
use rustc::middle::const_eval::ConstVal::*;
|
||||||
match *const_val {
|
match *const_val {
|
||||||
|
|
|
@ -11,10 +11,10 @@ fn ret() -> i32 {
|
||||||
// -1
|
// -1
|
||||||
// }
|
// }
|
||||||
|
|
||||||
// #[miri_run]
|
#[miri_run]
|
||||||
// fn add() -> i32 {
|
fn add() -> i32 {
|
||||||
// 1 + 2
|
1 + 2
|
||||||
// }
|
}
|
||||||
|
|
||||||
#[miri_run]
|
#[miri_run]
|
||||||
fn empty() {}
|
fn empty() {}
|
||||||
|
@ -34,17 +34,17 @@ fn tuple_5() -> (i32, i32, i32, i32, i32) {
|
||||||
(1, 2, 3, 4, 5)
|
(1, 2, 3, 4, 5)
|
||||||
}
|
}
|
||||||
|
|
||||||
// #[miri_run]
|
#[miri_run]
|
||||||
// fn indirect_add() -> i32 {
|
fn indirect_add() -> i32 {
|
||||||
// let x = 1;
|
let x = 1;
|
||||||
// let y = 2;
|
let y = 2;
|
||||||
// x + y
|
x + y
|
||||||
// }
|
}
|
||||||
|
|
||||||
// #[miri_run]
|
#[miri_run]
|
||||||
// fn arith() -> i32 {
|
fn arith() -> i32 {
|
||||||
// 3*3 + 4*4
|
3*3 + 4*4
|
||||||
// }
|
}
|
||||||
|
|
||||||
#[miri_run]
|
#[miri_run]
|
||||||
fn boolean() -> bool {
|
fn boolean() -> bool {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue