1
Fork 0

Handle Goto, Panic, and If terminators properly.

This commit is contained in:
Scott Olson 2015-11-19 03:23:50 -06:00
parent c37b2bba05
commit 7112fc8cd1
2 changed files with 55 additions and 17 deletions

View file

@ -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,15 +42,23 @@ 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));
// TODO(tsion): Write args into value_stack.
}
let start_block = mir.basic_block_data(mir::START_BLOCK);
fn call(&mut self, mir: &Mir, args: &[Value]) -> Value {
self.push_stack_frame(mir, args);
let mut block = mir::START_BLOCK;
for stmt in &start_block.statements {
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 {
@ -66,6 +74,26 @@ impl Interpreter {
}
}
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),
}
}
Return => break,
_ => unimplemented!(),
}
}
self.value_stack[self.eval_lvalue(&mir::Lvalue::ReturnPointer)].clone()
}

View file

@ -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() {}