Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make eval_place_to_op iterate instead of recurse #61104

Merged
merged 3 commits into from
May 25, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 24 additions & 12 deletions src/librustc_mir/interpret/operand.rs
Original file line number Diff line number Diff line change
Expand Up @@ -467,22 +467,34 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> InterpretCx<'a, 'mir, 'tcx, M>
mir_place: &mir::Place<'tcx>,
layout: Option<TyLayout<'tcx>>,
) -> EvalResult<'tcx, OpTy<'tcx, M::PointerTag>> {
use rustc::mir::Place::*;
use rustc::mir::Place;
use rustc::mir::PlaceBase;
let op = match *mir_place {
Base(PlaceBase::Local(mir::RETURN_PLACE)) => return err!(ReadFromReturnPointer),
Base(PlaceBase::Local(local)) => self.access_local(self.frame(), local, layout)?,

Projection(ref proj) => {
let op = self.eval_place_to_op(&proj.base, None)?;
self.operand_projection(op, &proj.elem)?
}
mir_place.iterate(|place_base, place_projection| {
let mut op = match place_base {
PlaceBase::Local(mir::RETURN_PLACE) => return err!(ReadFromReturnPointer),
PlaceBase::Local(local) => {
// FIXME use place_projection.is_empty() when is available
let layout = if let Place::Base(_) = mir_place {
layout
} else {
None
};
spastorino marked this conversation as resolved.
Show resolved Hide resolved

self.access_local(self.frame(), *local, layout)?
}
PlaceBase::Static(place_static) => {
self.eval_static_to_mplace(place_static)?.into()
}
};

_ => self.eval_place_to_mplace(mir_place)?.into(),
};
for proj in place_projection {
op = self.operand_projection(op, &proj.elem)?
}

trace!("eval_place_to_op: got {:?}", *op);
Ok(op)
trace!("eval_place_to_op: got {:?}", *op);
Ok(op)
})
}

/// Evaluate the operand, returning a place where you can then find the data.
Expand Down
30 changes: 15 additions & 15 deletions src/librustc_mir/interpret/place.rs
Original file line number Diff line number Diff line change
Expand Up @@ -562,23 +562,23 @@ where

/// Evaluate statics and promoteds to an `MPlace`. Used to share some code between
/// `eval_place` and `eval_place_to_op`.
pub(super) fn eval_place_to_mplace(
pub(super) fn eval_static_to_mplace(
&self,
mir_place: &mir::Place<'tcx>
place_static: &mir::Static<'tcx>
) -> EvalResult<'tcx, MPlaceTy<'tcx, M::PointerTag>> {
use rustc::mir::Place::*;
use rustc::mir::PlaceBase;
use rustc::mir::{Static, StaticKind};
Ok(match *mir_place {
Base(PlaceBase::Static(box Static { kind: StaticKind::Promoted(promoted), .. })) => {
use rustc::mir::StaticKind;

Ok(match place_static.kind {
StaticKind::Promoted(promoted) => {
let instance = self.frame().instance;
self.const_eval_raw(GlobalId {
instance,
promoted: Some(promoted),
})?
}

Base(PlaceBase::Static(box Static { kind: StaticKind::Static(def_id), ty })) => {
StaticKind::Static(def_id) => {
let ty = place_static.ty;
assert!(!ty.needs_subst());
let layout = self.layout_of(ty)?;
let instance = ty::Instance::mono(*self.tcx, def_id);
Expand All @@ -600,8 +600,6 @@ where
let alloc = self.tcx.alloc_map.lock().intern_static(cid.instance.def_id());
MPlaceTy::from_aligned_ptr(Pointer::from(alloc).with_default_tag(), layout)
}

_ => bug!("eval_place_to_mplace called on {:?}", mir_place),
})
}

Expand All @@ -613,7 +611,7 @@ where
) -> EvalResult<'tcx, PlaceTy<'tcx, M::PointerTag>> {
use rustc::mir::Place::*;
use rustc::mir::PlaceBase;
let place = match *mir_place {
let place = match mir_place {
Base(PlaceBase::Local(mir::RETURN_PLACE)) => match self.frame().return_place {
Some(return_place) =>
// We use our layout to verify our assumption; caller will validate
Expand All @@ -628,17 +626,19 @@ where
// This works even for dead/uninitialized locals; we check further when writing
place: Place::Local {
frame: self.cur_frame(),
local,
local: *local,
},
layout: self.layout_of_local(self.frame(), local, None)?,
layout: self.layout_of_local(self.frame(), *local, None)?,
},

Projection(ref proj) => {
Projection(proj) => {
let place = self.eval_place(&proj.base)?;
self.place_projection(place, &proj.elem)?
}

_ => self.eval_place_to_mplace(mir_place)?.into(),
Base(PlaceBase::Static(place_static)) => {
self.eval_static_to_mplace(place_static)?.into()
}
};

self.dump_place(place.place);
Expand Down