Skip to content

Commit

Permalink
refactor away the closures and Event enum
Browse files Browse the repository at this point in the history
  • Loading branch information
oli-obk committed Jun 9, 2016
1 parent cbbf58b commit 59d858a
Show file tree
Hide file tree
Showing 2 changed files with 20 additions and 38 deletions.
12 changes: 1 addition & 11 deletions src/interpreter/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -395,17 +395,7 @@ impl<'a, 'b, 'mir, 'tcx> FnEvalContext<'a, 'b, 'mir, 'tcx> {

fn run(&mut self) -> EvalResult<()> {
let mut stepper = stepper::Stepper::new(self);
let mut done = false;
while !done {
use self::stepper::Event::*;
stepper.step(|event| match event {
Block(b) => trace!("// {:?}", b),
Assignment(a) => trace!("{:?}", a),
Terminator(t) => trace!("{:?}", t.kind),
Done => done = true,
_ => {},
})?;
}
while stepper.step()? {}
Ok(())
}

Expand Down
46 changes: 19 additions & 27 deletions src/interpreter/stepper.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,16 +15,6 @@ use syntax::codemap::Span;
use std::rc::Rc;
use memory::Pointer;

pub enum Event<'a, 'tcx: 'a> {
Block(mir::BasicBlock),
Return,
Call,
Constant,
Assignment(&'a mir::Statement<'tcx>),
Terminator(&'a mir::Terminator<'tcx>),
Done,
}

pub struct Stepper<'fncx, 'a: 'fncx, 'b: 'a + 'mir, 'mir: 'fncx, 'tcx: 'b>{
fncx: &'fncx mut FnEvalContext<'a, 'b, 'mir, 'tcx>,

Expand All @@ -41,39 +31,37 @@ impl<'fncx, 'a, 'b: 'a + 'mir, 'mir, 'tcx: 'b> Stepper<'fncx, 'a, 'b, 'mir, 'tcx
}
}

fn statement<F: for<'f> FnMut(Event<'f, 'tcx>)>(&mut self, mut f: F, stmt: &mir::Statement<'tcx>) -> EvalResult<()> {
f(Event::Assignment(stmt));
fn statement(&mut self, stmt: &mir::Statement<'tcx>) -> EvalResult<()> {
trace!("{:?}", stmt);
let mir::StatementKind::Assign(ref lvalue, ref rvalue) = stmt.kind;
let result = self.fncx.eval_assignment(lvalue, rvalue);
self.fncx.maybe_report(result)?;
self.fncx.frame_mut().stmt += 1;
Ok(())
}

fn terminator<F: for<'f> FnMut(Event<'f, 'tcx>)>(&mut self, mut f: F, terminator: &mir::Terminator<'tcx>) -> EvalResult<()> {
fn terminator(&mut self, terminator: &mir::Terminator<'tcx>) -> EvalResult<()> {
// after a terminator we go to a new block
self.fncx.frame_mut().stmt = 0;
let term = {
f(Event::Terminator(terminator));
trace!("{:?}", terminator.kind);
let result = self.fncx.eval_terminator(terminator);
self.fncx.maybe_report(result)?
};
match term {
TerminatorTarget::Block => f(Event::Block(self.fncx.frame().next_block)),
TerminatorTarget::Return => {
f(Event::Return);
self.fncx.pop_stack_frame();
},
TerminatorTarget::Call => f(Event::Call),
TerminatorTarget::Block |
TerminatorTarget::Call => trace!("// {:?}", self.fncx.frame().next_block),
}
Ok(())
}

// returns true as long as there are more things to do
pub fn step<F: for<'f> FnMut(Event<'f, 'tcx>)>(&mut self, mut f: F) -> EvalResult<()> {
pub fn step(&mut self) -> EvalResult<bool> {
if self.fncx.stack.is_empty() {
f(Event::Done);
return Ok(());
return Ok(false);
}

let block = self.fncx.frame().next_block;
Expand All @@ -92,10 +80,11 @@ impl<'fncx, 'a, 'b: 'a + 'mir, 'mir, 'tcx: 'b> Stepper<'fncx, 'a, 'b, 'mir, 'tcx
mir: &mir,
}.visit_statement(block, stmt);
if self.constants.is_empty() {
return self.statement(f, stmt);
self.statement(stmt)?;
} else {
return self.extract_constants(f);
self.extract_constants()?;
}
return Ok(true);
}

let terminator = basic_block.terminator();
Expand All @@ -109,19 +98,22 @@ impl<'fncx, 'a, 'b: 'a + 'mir, 'mir, 'tcx: 'b> Stepper<'fncx, 'a, 'b, 'mir, 'tcx
mir: &mir,
}.visit_terminator(block, terminator);
if self.constants.is_empty() {
self.terminator(f, terminator)
self.terminator(terminator)?;
} else {
self.extract_constants(f)
self.extract_constants()?;
}
Ok(true)
}

fn extract_constants<F: for<'f> FnMut(Event<'f, 'tcx>)>(&mut self, mut f: F) -> EvalResult<()> {
fn extract_constants(&mut self) -> EvalResult<()> {
assert!(!self.constants.is_empty());
for (cid, span, return_ptr, mir) in self.constants.drain(..) {
f(Event::Constant);
trace!("queuing a constant");
self.fncx.push_stack_frame(cid.def_id, span, mir, cid.substs, Some(return_ptr));
}
self.step(f)
// self.step() can't be "done", so it can't return false
assert!(self.step()?);
Ok(())
}
}

Expand Down

0 comments on commit 59d858a

Please sign in to comment.