diff --git a/src/interpreter/mod.rs b/src/interpreter/mod.rs index 41828d7a2313..410b7a3d79e9 100644 --- a/src/interpreter/mod.rs +++ b/src/interpreter/mod.rs @@ -25,10 +25,6 @@ use std::collections::HashMap; mod stepper; -pub fn step<'ecx, 'a: 'ecx, 'tcx: 'a>(ecx: &'ecx mut EvalContext<'a, 'tcx>) -> EvalResult<'tcx, bool> { - stepper::Stepper::new(ecx).step() -} - pub struct EvalContext<'a, 'tcx: 'a> { /// The results of the type checker, from rustc. tcx: TyCtxt<'a, 'tcx, 'tcx>, @@ -1571,7 +1567,7 @@ pub fn eval_main<'a, 'tcx: 'a>( } loop { - match step(&mut ecx) { + match ecx.step() { Ok(true) => {} Ok(false) => break, // FIXME: diverging functions can end up here in some future miri diff --git a/src/interpreter/stepper.rs b/src/interpreter/stepper.rs index f1dfcd6cfcd7..37a7aa4d0117 100644 --- a/src/interpreter/stepper.rs +++ b/src/interpreter/stepper.rs @@ -1,3 +1,7 @@ +//! This module contains the `EvalContext` methods for executing a single step of the interpreter. +//! +//! The main entry point is the `step` method. + use super::{ CachedMir, ConstantId, @@ -12,57 +16,28 @@ use rustc::mir::visit::{Visitor, LvalueContext}; use syntax::codemap::Span; use std::rc::Rc; -pub(super) struct Stepper<'ecx, 'a: 'ecx, 'tcx: 'a>{ - ecx: &'ecx mut EvalContext<'a, 'tcx>, -} - -impl<'ecx, 'a, 'tcx> Stepper<'ecx, 'a, 'tcx> { - pub(super) fn new(ecx: &'ecx mut EvalContext<'a, 'tcx>) -> Self { - Stepper { - ecx: ecx, - } - } - - fn statement(&mut self, stmt: &mir::Statement<'tcx>) -> EvalResult<'tcx, ()> { - trace!("{:?}", stmt); - let mir::StatementKind::Assign(ref lvalue, ref rvalue) = stmt.kind; - self.ecx.eval_assignment(lvalue, rvalue)?; - self.ecx.frame_mut().stmt += 1; - Ok(()) - } - - fn terminator(&mut self, terminator: &mir::Terminator<'tcx>) -> EvalResult<'tcx, ()> { - // after a terminator we go to a new block - self.ecx.frame_mut().stmt = 0; - trace!("{:?}", terminator.kind); - self.ecx.eval_terminator(terminator)?; - if !self.ecx.stack.is_empty() { - trace!("// {:?}", self.ecx.frame().block); - } - Ok(()) - } - - // returns true as long as there are more things to do - pub(super) fn step(&mut self) -> EvalResult<'tcx, bool> { - if self.ecx.stack.is_empty() { +impl<'a, 'tcx> EvalContext<'a, 'tcx> { + /// Returns true as long as there are more things to do. + pub fn step(&mut self) -> EvalResult<'tcx, bool> { + if self.stack.is_empty() { return Ok(false); } - let block = self.ecx.frame().block; - let stmt = self.ecx.frame().stmt; - let mir = self.ecx.mir(); + let block = self.frame().block; + let stmt = self.frame().stmt; + let mir = self.mir(); let basic_block = &mir.basic_blocks()[block]; if let Some(ref stmt) = basic_block.statements.get(stmt) { - let current_stack = self.ecx.stack.len(); + let current_stack = self.stack.len(); ConstantExtractor { span: stmt.source_info.span, - substs: self.ecx.substs(), - def_id: self.ecx.frame().def_id, - ecx: self.ecx, + substs: self.substs(), + def_id: self.frame().def_id, + ecx: self, mir: &mir, }.visit_statement(block, stmt); - if current_stack == self.ecx.stack.len() { + if current_stack == self.stack.len() { self.statement(stmt)?; } else { // ConstantExtractor added some new frames for statics/constants/promoteds @@ -73,15 +48,15 @@ impl<'ecx, 'a, 'tcx> Stepper<'ecx, 'a, 'tcx> { } let terminator = basic_block.terminator(); - let current_stack = self.ecx.stack.len(); + let current_stack = self.stack.len(); ConstantExtractor { span: terminator.source_info.span, - substs: self.ecx.substs(), - def_id: self.ecx.frame().def_id, - ecx: self.ecx, + substs: self.substs(), + def_id: self.frame().def_id, + ecx: self, mir: &mir, }.visit_terminator(block, terminator); - if current_stack == self.ecx.stack.len() { + if current_stack == self.stack.len() { self.terminator(terminator)?; } else { // ConstantExtractor added some new frames for statics/constants/promoteds @@ -90,6 +65,25 @@ impl<'ecx, 'a, 'tcx> Stepper<'ecx, 'a, 'tcx> { } Ok(true) } + + fn statement(&mut self, stmt: &mir::Statement<'tcx>) -> EvalResult<'tcx, ()> { + trace!("{:?}", stmt); + let mir::StatementKind::Assign(ref lvalue, ref rvalue) = stmt.kind; + self.eval_assignment(lvalue, rvalue)?; + self.frame_mut().stmt += 1; + Ok(()) + } + + fn terminator(&mut self, terminator: &mir::Terminator<'tcx>) -> EvalResult<'tcx, ()> { + // after a terminator we go to a new block + self.frame_mut().stmt = 0; + trace!("{:?}", terminator.kind); + self.eval_terminator(terminator)?; + if !self.stack.is_empty() { + trace!("// {:?}", self.frame().block); + } + Ok(()) + } } // WARNING: make sure that any methods implemented on this type don't ever access ecx.stack diff --git a/src/lib.rs b/src/lib.rs index 8addef87b2fb..3745a960a271 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -36,7 +36,6 @@ pub use interpreter::{ EvalContext, Frame, eval_main, - step, }; pub use memory::Memory;