mod stepper;
-struct GlobalEvalContext<'a, 'tcx: 'a> {
+pub struct GlobalEvalContext<'a, 'tcx: 'a> {
/// The results of the type checker, from rustc.
tcx: TyCtxt<'a, 'tcx, 'tcx>,
err.emit();
}
- fn run(&mut self) -> EvalResult<()> {
- let mut stepper = stepper::Stepper::new(self);
- while stepper.step()? {}
- Ok(())
- }
-
fn push_stack_frame(&mut self, def_id: DefId, span: codemap::Span, mir: CachedMir<'a, 'tcx>, substs: &'tcx Substs<'tcx>,
return_ptr: Option<Pointer>)
{
gecx.push_stack_frame(tcx.map.local_def_id(id), mir.span, CachedMir::Ref(mir), substs, return_ptr);
- match (gecx.run(), return_ptr) {
- (Ok(()), Some(ptr)) => if log_enabled!(::log::LogLevel::Debug) {
+ loop { match (stepper::step(&mut gecx), return_ptr) {
+ (Ok(true), _) => {},
+ (Ok(false), Some(ptr)) => if log_enabled!(::log::LogLevel::Debug) {
gecx.memory.dump(ptr.alloc_id);
+ break;
+ },
+ (Ok(false), None) => {
+ warn!("diverging function returned");
+ break;
},
- (Ok(()), None) => warn!("diverging function returned"),
// FIXME: diverging functions can end up here in some future miri
- (Err(e), _) => gecx.report(e),
- }
+ (Err(e), _) => {
+ gecx.report(e);
+ break;
+ },
+ } }
}
}
}
use syntax::codemap::Span;
use std::rc::Rc;
-pub struct Stepper<'fncx, 'a: 'fncx, 'tcx: 'a>{
+struct Stepper<'fncx, 'a: 'fncx, 'tcx: 'a>{
gecx: &'fncx mut GlobalEvalContext<'a, 'tcx>,
}
+pub fn step<'fncx, 'a: 'fncx, 'tcx: 'a>(gecx: &'fncx mut GlobalEvalContext<'a, 'tcx>) -> EvalResult<bool> {
+ Stepper::new(gecx).step()
+}
+
impl<'fncx, 'a, 'tcx> Stepper<'fncx, 'a, 'tcx> {
- pub(super) fn new(gecx: &'fncx mut GlobalEvalContext<'a, 'tcx>) -> Self {
+ fn new(gecx: &'fncx mut GlobalEvalContext<'a, 'tcx>) -> Self {
Stepper {
gecx: gecx,
}
}
// returns true as long as there are more things to do
- pub fn step(&mut self) -> EvalResult<bool> {
+ fn step(&mut self) -> EvalResult<bool> {
if self.gecx.stack.is_empty() {
return Ok(false);
}