Make step an EvalContext method and remove Stepper.
This commit is contained in:
@@ -25,10 +25,6 @@ use std::collections::HashMap;
|
|||||||
|
|
||||||
mod stepper;
|
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> {
|
pub struct EvalContext<'a, 'tcx: 'a> {
|
||||||
/// The results of the type checker, from rustc.
|
/// The results of the type checker, from rustc.
|
||||||
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||||
@@ -1571,7 +1567,7 @@ pub fn eval_main<'a, 'tcx: 'a>(
|
|||||||
}
|
}
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
match step(&mut ecx) {
|
match ecx.step() {
|
||||||
Ok(true) => {}
|
Ok(true) => {}
|
||||||
Ok(false) => break,
|
Ok(false) => break,
|
||||||
// FIXME: diverging functions can end up here in some future miri
|
// 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::{
|
use super::{
|
||||||
CachedMir,
|
CachedMir,
|
||||||
ConstantId,
|
ConstantId,
|
||||||
@@ -12,57 +16,28 @@ use rustc::mir::visit::{Visitor, LvalueContext};
|
|||||||
use syntax::codemap::Span;
|
use syntax::codemap::Span;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
|
|
||||||
pub(super) struct Stepper<'ecx, 'a: 'ecx, 'tcx: 'a>{
|
impl<'a, 'tcx> EvalContext<'a, 'tcx> {
|
||||||
ecx: &'ecx mut 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() {
|
||||||
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() {
|
|
||||||
return Ok(false);
|
return Ok(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
let block = self.ecx.frame().block;
|
let block = self.frame().block;
|
||||||
let stmt = self.ecx.frame().stmt;
|
let stmt = self.frame().stmt;
|
||||||
let mir = self.ecx.mir();
|
let mir = self.mir();
|
||||||
let basic_block = &mir.basic_blocks()[block];
|
let basic_block = &mir.basic_blocks()[block];
|
||||||
|
|
||||||
if let Some(ref stmt) = basic_block.statements.get(stmt) {
|
if let Some(ref stmt) = basic_block.statements.get(stmt) {
|
||||||
let current_stack = self.ecx.stack.len();
|
let current_stack = self.stack.len();
|
||||||
ConstantExtractor {
|
ConstantExtractor {
|
||||||
span: stmt.source_info.span,
|
span: stmt.source_info.span,
|
||||||
substs: self.ecx.substs(),
|
substs: self.substs(),
|
||||||
def_id: self.ecx.frame().def_id,
|
def_id: self.frame().def_id,
|
||||||
ecx: self.ecx,
|
ecx: self,
|
||||||
mir: &mir,
|
mir: &mir,
|
||||||
}.visit_statement(block, stmt);
|
}.visit_statement(block, stmt);
|
||||||
if current_stack == self.ecx.stack.len() {
|
if current_stack == self.stack.len() {
|
||||||
self.statement(stmt)?;
|
self.statement(stmt)?;
|
||||||
} else {
|
} else {
|
||||||
// ConstantExtractor added some new frames for statics/constants/promoteds
|
// 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 terminator = basic_block.terminator();
|
||||||
let current_stack = self.ecx.stack.len();
|
let current_stack = self.stack.len();
|
||||||
ConstantExtractor {
|
ConstantExtractor {
|
||||||
span: terminator.source_info.span,
|
span: terminator.source_info.span,
|
||||||
substs: self.ecx.substs(),
|
substs: self.substs(),
|
||||||
def_id: self.ecx.frame().def_id,
|
def_id: self.frame().def_id,
|
||||||
ecx: self.ecx,
|
ecx: self,
|
||||||
mir: &mir,
|
mir: &mir,
|
||||||
}.visit_terminator(block, terminator);
|
}.visit_terminator(block, terminator);
|
||||||
if current_stack == self.ecx.stack.len() {
|
if current_stack == self.stack.len() {
|
||||||
self.terminator(terminator)?;
|
self.terminator(terminator)?;
|
||||||
} else {
|
} else {
|
||||||
// ConstantExtractor added some new frames for statics/constants/promoteds
|
// ConstantExtractor added some new frames for statics/constants/promoteds
|
||||||
@@ -90,6 +65,25 @@ impl<'ecx, 'a, 'tcx> Stepper<'ecx, 'a, 'tcx> {
|
|||||||
}
|
}
|
||||||
Ok(true)
|
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
|
// WARNING: make sure that any methods implemented on this type don't ever access ecx.stack
|
||||||
|
|||||||
@@ -36,7 +36,6 @@ pub use interpreter::{
|
|||||||
EvalContext,
|
EvalContext,
|
||||||
Frame,
|
Frame,
|
||||||
eval_main,
|
eval_main,
|
||||||
step,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
pub use memory::Memory;
|
pub use memory::Memory;
|
||||||
|
|||||||
Reference in New Issue
Block a user