Make step
an EvalContext
method and remove Stepper
.
This commit is contained in:
parent
3c19db95b8
commit
7bda9f24d6
3 changed files with 41 additions and 52 deletions
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -36,7 +36,6 @@ pub use interpreter::{
|
|||
EvalContext,
|
||||
Frame,
|
||||
eval_main,
|
||||
step,
|
||||
};
|
||||
|
||||
pub use memory::Memory;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue