From 7112fc8cd1d42bc660f60cbae7beb86cfa81936c Mon Sep 17 00:00:00 2001 From: Scott Olson Date: Thu, 19 Nov 2015 03:23:50 -0600 Subject: [PATCH] Handle Goto, Panic, and If terminators properly. --- src/interpreter.rs | 62 +++++++++++++++++++++++++++++++++------------- test/basic.rs | 10 ++++++++ 2 files changed, 55 insertions(+), 17 deletions(-) diff --git a/src/interpreter.rs b/src/interpreter.rs index 3da416de8148..47b1ab252a42 100644 --- a/src/interpreter.rs +++ b/src/interpreter.rs @@ -34,7 +34,7 @@ impl Interpreter { } } - fn call(&mut self, mir: &Mir, _args: &[Value]) -> Value { + fn push_stack_frame(&mut self, mir: &Mir, _args: &[Value]) { self.call_stack.push(Frame { offset: self.value_stack.len(), num_args: mir.arg_decls.len(), @@ -42,27 +42,55 @@ impl Interpreter { num_temps: mir.temp_decls.len(), }); - { - let frame = self.call_stack.last().unwrap(); - let frame_size = 1 + frame.num_args + frame.num_vars + frame.num_temps; - self.value_stack.extend(iter::repeat(Value::Uninit).take(frame_size)); - } + let frame = self.call_stack.last().unwrap(); + let frame_size = 1 + frame.num_args + frame.num_vars + frame.num_temps; + self.value_stack.extend(iter::repeat(Value::Uninit).take(frame_size)); - let start_block = mir.basic_block_data(mir::START_BLOCK); + // TODO(tsion): Write args into value_stack. + } - for stmt in &start_block.statements { - use rustc_mir::repr::StatementKind::*; + fn call(&mut self, mir: &Mir, args: &[Value]) -> Value { + self.push_stack_frame(mir, args); + let mut block = mir::START_BLOCK; - match stmt.kind { - Assign(ref lvalue, ref rvalue) => { - let index = self.eval_lvalue(lvalue); - let value = self.eval_rvalue(rvalue); - self.value_stack[index] = value; + loop { + use rustc_mir::repr::Terminator::*; + + let block_data = mir.basic_block_data(block); + + for stmt in &block_data.statements { + use rustc_mir::repr::StatementKind::*; + + match stmt.kind { + Assign(ref lvalue, ref rvalue) => { + let index = self.eval_lvalue(lvalue); + let value = self.eval_rvalue(rvalue); + self.value_stack[index] = value; + } + + Drop(_kind, ref _lv) => { + // TODO + }, + } + } + + println!("{:?}", block_data.terminator); + match block_data.terminator { + Goto { target } => block = target, + + Panic { target: _target } => unimplemented!(), + + If { ref cond, targets } => { + match self.eval_operand(&cond) { + Value::Bool(true) => block = targets[0], + Value::Bool(false) => block = targets[1], + cond_val => panic!("Non-boolean `if` condition value: {:?}", cond_val), + } } - Drop(_kind, ref _lv) => { - // TODO - }, + Return => break, + + _ => unimplemented!(), } } diff --git a/test/basic.rs b/test/basic.rs index 24ef19b3fdb0..ceb82466ea69 100644 --- a/test/basic.rs +++ b/test/basic.rs @@ -28,4 +28,14 @@ fn arith() -> i32 { 3*3 + 4*4 } +#[miri_run(expected = "Int(0)")] +fn if_false() -> i32 { + if false { 1 } else { 0 } +} + +#[miri_run(expected = "Int(1)")] +fn if_true() -> i32 { + if true { 1 } else { 0 } +} + fn main() {}