Simplify the return lvalue

上级 a2baeb51
......@@ -66,8 +66,7 @@ pub struct Frame<'tcx> {
pub return_to_block: StackPopCleanup,
/// The location where the result of the current stack frame should be written to.
/// None if the function is a diverging function
pub return_lvalue: Option<Lvalue<'tcx>>,
pub return_lvalue: Lvalue<'tcx>,
/// The list of locals for this stack frame, stored in order as
/// `[arguments..., variables..., temporaries...]`. The locals are stored as `Option<Value>`s.
......@@ -272,7 +271,7 @@ pub fn push_stack_frame(
instance: ty::Instance<'tcx>,
span: codemap::Span,
mir: &'tcx mir::Mir<'tcx>,
return_lvalue: Option<Lvalue<'tcx>>,
return_lvalue: Lvalue<'tcx>,
return_to_block: StackPopCleanup,
) -> EvalResult<'tcx> {
::log_settings::settings().indentation += 1;
......@@ -329,7 +328,7 @@ pub(super) fn pop_stack_frame(&mut self) -> EvalResult<'tcx> {
::log_settings::settings().indentation -= 1;
let frame = self.stack.pop().expect("tried to pop a stack frame, but there were none");
match frame.return_to_block {
StackPopCleanup::MarkStatic(mutable) => if let Lvalue::Global(id) = frame.return_lvalue.expect("diverging static") {
StackPopCleanup::MarkStatic(mutable) => if let Lvalue::Global(id) = frame.return_lvalue {
let global_value = self.globals.get_mut(&id)
.expect("global should have been cached (static)");
match global_value.value {
......
......@@ -64,6 +64,14 @@ pub struct Global<'tcx> {
}
impl<'tcx> Lvalue<'tcx> {
/// Produces an Lvalue that will error if attempted to be read from
pub fn undef() -> Self {
Lvalue::Ptr {
ptr: PrimVal::Undef,
extra: LvalueExtra::None,
}
}
pub fn zst() -> Self {
Self::from_ptr(Pointer::zst_ptr())
}
......@@ -148,7 +156,7 @@ pub(super) fn eval_and_read_lvalue(&mut self, lvalue: &mir::Lvalue<'tcx>) -> Eva
pub(super) fn eval_lvalue(&mut self, mir_lvalue: &mir::Lvalue<'tcx>) -> EvalResult<'tcx, Lvalue<'tcx>> {
use rustc::mir::Lvalue::*;
let lvalue = match *mir_lvalue {
Local(mir::RETURN_POINTER) => self.frame().return_lvalue.expect("diverging function returned"),
Local(mir::RETURN_POINTER) => self.frame().return_lvalue,
Local(local) => Lvalue::Local { frame: self.stack.len() - 1, local, field: None },
Static(ref static_) => {
......
......@@ -192,7 +192,7 @@ fn global_item(
instance,
span,
mir,
Some(Lvalue::Global(cid)),
Lvalue::Global(cid),
cleanup,
)
});
......@@ -235,7 +235,7 @@ fn visit_constant(&mut self, constant: &mir::Constant<'tcx>, location: mir::Loca
this.ecx.push_stack_frame(this.instance,
constant.span,
mir,
Some(Lvalue::Global(cid)),
Lvalue::Global(cid),
StackPopCleanup::MarkStatic(false),
)
});
......
......@@ -49,7 +49,7 @@ pub(crate) fn drop(&mut self, arg: Value, mut instance: ty::Instance<'tcx>, ty:
instance,
span,
mir,
Some(Lvalue::zst()),
Lvalue::zst(),
StackPopCleanup::None,
)?;
......
......@@ -30,7 +30,7 @@ pub(super) fn eval_terminator(
use rustc::mir::TerminatorKind::*;
match terminator.kind {
Return => {
self.dump_local(self.frame().return_lvalue.expect("diverging function returned"));
self.dump_local(self.frame().return_lvalue);
self.pop_stack_frame()?
}
......@@ -430,8 +430,8 @@ fn eval_fn_call_inner(
Err(other) => return Err(other),
};
let (return_lvalue, return_to_block) = match destination {
Some((lvalue, block)) => (Some(lvalue), StackPopCleanup::Goto(block)),
None => (None, StackPopCleanup::None),
Some((lvalue, block)) => (lvalue, StackPopCleanup::Goto(block)),
None => (Lvalue::undef(), StackPopCleanup::None),
};
self.push_stack_frame(
......@@ -606,7 +606,7 @@ fn call_c_abi(
f_instance,
mir.span,
mir,
Some(Lvalue::zst()),
Lvalue::zst(),
StackPopCleanup::Goto(dest_block),
)?;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册