move constants stack to stackframe

This commit is contained in:
Oliver Schneider 2016-06-03 17:08:51 +02:00
parent 02eed64cc0
commit 4743842821
No known key found for this signature in database
GPG key ID: 56D6EEA0FC67AC46
2 changed files with 13 additions and 19 deletions

View file

@ -14,7 +14,7 @@ use std::rc::Rc;
use std::{iter, mem};
use syntax::ast;
use syntax::attr;
use syntax::codemap::{self, DUMMY_SP};
use syntax::codemap::{self, DUMMY_SP, Span};
use error::{EvalError, EvalResult};
use memory::{Memory, Pointer};
@ -97,6 +97,9 @@ struct Frame<'a, 'tcx: 'a> {
/// The index of the currently evaluated statment
stmt: usize,
// Constants that need to be evaluated before the next statement can be evaluated
constants: Vec<(ConstantId<'tcx>, Span, Pointer, CachedMir<'a, 'tcx>)>,
}
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
@ -250,6 +253,7 @@ impl<'a, 'b, 'mir, 'tcx> FnEvalContext<'a, 'b, 'mir, 'tcx> {
def_id: def_id,
substs: substs,
stmt: 0,
constants: Vec::new(),
});
let locals: Vec<Pointer> = arg_tys.chain(var_tys).chain(temp_tys).map(|ty| {

View file

@ -24,8 +24,6 @@ pub struct Stepper<'fncx, 'a: 'fncx, 'b: 'a + 'mir, 'mir: 'fncx, 'tcx: 'b>{
fncx: &'fncx mut FnEvalContext<'a, 'b, 'mir, 'tcx>,
mir: CachedMir<'mir, 'tcx>,
process: fn (&mut Stepper<'fncx, 'a, 'b, 'mir, 'tcx>) -> EvalResult<()>,
// a stack of constants
constants: Vec<Vec<(ConstantId<'tcx>, Span, Pointer, CachedMir<'mir, 'tcx>)>>,
}
impl<'fncx, 'a, 'b: 'a + 'mir, 'mir, 'tcx: 'b> Stepper<'fncx, 'a, 'b, 'mir, 'tcx> {
@ -34,7 +32,6 @@ impl<'fncx, 'a, 'b: 'a + 'mir, 'mir, 'tcx: 'b> Stepper<'fncx, 'a, 'b, 'mir, 'tcx
mir: fncx.mir(),
fncx: fncx,
process: Self::dummy,
constants: vec![Vec::new()],
}
}
@ -62,37 +59,33 @@ impl<'fncx, 'a, 'b: 'a + 'mir, 'mir, 'tcx: 'b> Stepper<'fncx, 'a, 'b, 'mir, 'tcx
match term {
TerminatorTarget::Block => {},
TerminatorTarget::Return => {
assert!(self.fncx.frame().constants.is_empty());
self.fncx.pop_stack_frame();
assert!(self.constants.last().unwrap().is_empty());
self.constants.pop();
if !self.fncx.stack.is_empty() {
self.mir = self.fncx.mir();
}
},
TerminatorTarget::Call => {
self.mir = self.fncx.mir();
self.constants.push(Vec::new());
},
}
Ok(())
}
fn constant(&mut self) -> EvalResult<()> {
match self.constants.last_mut().unwrap().pop() {
match self.fncx.frame_mut().constants.pop() {
Some((ConstantId::Promoted { index }, span, return_ptr, mir)) => {
trace!("adding promoted constant {}, {:?}", index, span);
let substs = self.fncx.substs();
// FIXME: somehow encode that this is a promoted constant's frame
let def_id = self.fncx.frame().def_id;
self.fncx.push_stack_frame(def_id, span, mir, substs, Some(return_ptr));
self.constants.push(Vec::new());
self.mir = self.fncx.mir();
},
Some((ConstantId::Static { def_id, substs }, span, return_ptr, mir)) => {
trace!("adding static {:?}, {:?}", def_id, span);
self.fncx.gecx.statics.insert(def_id, return_ptr);
self.fncx.push_stack_frame(def_id, span, mir, substs, Some(return_ptr));
self.constants.push(Vec::new());
self.mir = self.fncx.mir();
},
None => unreachable!(),
@ -109,7 +102,7 @@ impl<'fncx, 'a, 'b: 'a + 'mir, 'mir, 'tcx: 'b> Stepper<'fncx, 'a, 'b, 'mir, 'tcx
return Ok(Event::Done);
}
if !self.constants.last().unwrap().is_empty() {
if !self.fncx.frame().constants.is_empty() {
self.process = Self::constant;
return Ok(Event::Constant);
}
@ -119,14 +112,13 @@ impl<'fncx, 'a, 'b: 'a + 'mir, 'mir, 'tcx: 'b> Stepper<'fncx, 'a, 'b, 'mir, 'tcx
let basic_block = self.mir.basic_block_data(block);
if let Some(ref stmt) = basic_block.statements.get(stmt) {
assert!(self.constants.last().unwrap().is_empty());
assert!(self.fncx.frame().constants.is_empty());
ConstantExtractor {
constants: &mut self.constants.last_mut().unwrap(),
span: stmt.span,
fncx: self.fncx,
mir: &self.mir,
}.visit_statement(block, stmt);
if self.constants.last().unwrap().is_empty() {
if self.fncx.frame().constants.is_empty() {
self.process = Self::statement;
return Ok(Event::Assignment);
} else {
@ -137,12 +129,11 @@ impl<'fncx, 'a, 'b: 'a + 'mir, 'mir, 'tcx: 'b> Stepper<'fncx, 'a, 'b, 'mir, 'tcx
let terminator = basic_block.terminator();
ConstantExtractor {
constants: &mut self.constants.last_mut().unwrap(),
span: terminator.span,
fncx: self.fncx,
mir: &self.mir,
}.visit_terminator(block, terminator);
if self.constants.last().unwrap().is_empty() {
if self.fncx.frame().constants.is_empty() {
self.process = Self::terminator;
Ok(Event::Terminator)
} else {
@ -167,7 +158,6 @@ impl<'fncx, 'a, 'b: 'a + 'mir, 'mir, 'tcx: 'b> Stepper<'fncx, 'a, 'b, 'mir, 'tcx
}
struct ConstantExtractor<'a: 'c, 'b: 'a + 'mir + 'c, 'c, 'mir: 'c, 'tcx: 'a + 'b + 'c> {
constants: &'c mut Vec<(ConstantId<'tcx>, Span, Pointer, CachedMir<'mir, 'tcx>)>,
span: Span,
mir: &'c mir::Mir<'tcx>,
fncx: &'c mut FnEvalContext<'a, 'b, 'mir, 'tcx>,
@ -184,7 +174,7 @@ impl<'a, 'b, 'c, 'mir, 'tcx> ConstantExtractor<'a, 'b, 'c, 'mir, 'tcx> {
};
let mir = self.fncx.load_mir(def_id);
let ptr = self.fncx.alloc_ret_ptr(mir.return_ty).expect("there's no such thing as an unreachable static");
self.constants.push((cid, span, ptr, mir));
self.fncx.frame_mut().constants.push((cid, span, ptr, mir));
}
}
@ -211,7 +201,7 @@ impl<'a, 'b, 'c, 'mir, 'tcx> Visitor<'tcx> for ConstantExtractor<'a, 'b, 'c, 'mi
let return_ptr = self.fncx.alloc_ret_ptr(return_ty).expect("there's no such thing as an unreachable static");
self.fncx.frame_mut().promoted.insert(index, return_ptr);
let mir = CachedMir::Owned(Rc::new(mir));
self.constants.push((ConstantId::Promoted { index: index }, constant.span, return_ptr, mir));
self.fncx.frame_mut().constants.push((ConstantId::Promoted { index: index }, constant.span, return_ptr, mir));
}
}
}