Make eval_place_to_op iterate instead of recurse

This commit is contained in:
Santiago Pastorino 2019-05-24 01:28:41 +02:00
parent 6d7a36231a
commit e38b399d03
1 changed files with 25 additions and 14 deletions

View File

@ -467,23 +467,34 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> InterpretCx<'a, 'mir, 'tcx, M>
mir_place: &mir::Place<'tcx>, mir_place: &mir::Place<'tcx>,
layout: Option<TyLayout<'tcx>>, layout: Option<TyLayout<'tcx>>,
) -> EvalResult<'tcx, OpTy<'tcx, M::PointerTag>> { ) -> EvalResult<'tcx, OpTy<'tcx, M::PointerTag>> {
use rustc::mir::Place::*; use rustc::mir::Place;
use rustc::mir::PlaceBase; use rustc::mir::PlaceBase;
let op = match mir_place {
Base(PlaceBase::Local(mir::RETURN_PLACE)) => return err!(ReadFromReturnPointer), mir_place.iterate(|place_base, place_projection| {
Base(PlaceBase::Local(local)) => self.access_local(self.frame(), *local, layout)?, let mut op = match place_base {
Base(PlaceBase::Static(place_static)) => { PlaceBase::Local(mir::RETURN_PLACE) => return err!(ReadFromReturnPointer),
self.eval_static_to_mplace(place_static)?.into() PlaceBase::Local(local) => {
// FIXME use place_projection.is_empty() when is available
let layout = if let Place::Base(_) = mir_place {
layout
} else {
None
};
self.access_local(self.frame(), *local, layout)?
}
PlaceBase::Static(place_static) => {
self.eval_static_to_mplace(place_static)?.into()
}
};
for proj in place_projection {
op = self.operand_projection(op, &proj.elem)?
} }
Projection(proj) => { trace!("eval_place_to_op: got {:?}", *op);
let op = self.eval_place_to_op(&proj.base, None)?; Ok(op)
self.operand_projection(op, &proj.elem)? })
}
};
trace!("eval_place_to_op: got {:?}", *op);
Ok(op)
} }
/// Evaluate the operand, returning a place where you can then find the data. /// Evaluate the operand, returning a place where you can then find the data.