mirror of
https://github.com/rust-lang/rust.git
synced 2026-06-01 05:57:03 +03:00
No more terminators
This commit is contained in:
+9
-28
@@ -99,18 +99,6 @@ enum CachedMir<'mir, 'tcx: 'mir> {
|
||||
Owned(Rc<mir::Mir<'tcx>>)
|
||||
}
|
||||
|
||||
/// Represents the action to be taken in the main loop as a result of executing a terminator.
|
||||
enum TerminatorTarget {
|
||||
/// Make a local jump to the next block
|
||||
Block,
|
||||
|
||||
/// Start executing from the new current frame. (For function calls.)
|
||||
Call,
|
||||
|
||||
/// Stop executing the current frame and resume the previous frame.
|
||||
Return,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Eq, PartialEq, Hash)]
|
||||
/// Uniquely identifies a specific constant or static
|
||||
struct ConstantId<'tcx> {
|
||||
@@ -412,21 +400,19 @@ fn pop_stack_frame(&mut self) {
|
||||
}
|
||||
|
||||
fn eval_terminator(&mut self, terminator: &mir::Terminator<'tcx>)
|
||||
-> EvalResult<TerminatorTarget> {
|
||||
-> EvalResult<()> {
|
||||
use rustc::mir::repr::TerminatorKind::*;
|
||||
let target = match terminator.kind {
|
||||
Return => TerminatorTarget::Return,
|
||||
match terminator.kind {
|
||||
Return => self.pop_stack_frame(),
|
||||
|
||||
Goto { target } => {
|
||||
self.frame_mut().next_block = target;
|
||||
TerminatorTarget::Block
|
||||
},
|
||||
|
||||
If { ref cond, targets: (then_target, else_target) } => {
|
||||
let cond_ptr = self.eval_operand(cond)?;
|
||||
let cond_val = self.memory.read_bool(cond_ptr)?;
|
||||
self.frame_mut().next_block = if cond_val { then_target } else { else_target };
|
||||
TerminatorTarget::Block
|
||||
}
|
||||
|
||||
SwitchInt { ref discr, ref values, ref targets, .. } => {
|
||||
@@ -450,7 +436,6 @@ fn eval_terminator(&mut self, terminator: &mir::Terminator<'tcx>)
|
||||
}
|
||||
|
||||
self.frame_mut().next_block = target_block;
|
||||
TerminatorTarget::Block
|
||||
}
|
||||
|
||||
Switch { ref discr, ref targets, adt_def } => {
|
||||
@@ -463,7 +448,6 @@ fn eval_terminator(&mut self, terminator: &mir::Terminator<'tcx>)
|
||||
match matching {
|
||||
Some(i) => {
|
||||
self.frame_mut().next_block = targets[i];
|
||||
TerminatorTarget::Block
|
||||
},
|
||||
None => return Err(EvalError::InvalidDiscriminant),
|
||||
}
|
||||
@@ -549,8 +533,6 @@ fn eval_terminator(&mut self, terminator: &mir::Terminator<'tcx>)
|
||||
let dest = self.frame().locals[i];
|
||||
self.move_(src, dest, src_ty)?;
|
||||
}
|
||||
|
||||
TerminatorTarget::Call
|
||||
}
|
||||
|
||||
abi => return Err(EvalError::Unimplemented(format!("can't handle function with {:?} ABI", abi))),
|
||||
@@ -566,13 +548,12 @@ fn eval_terminator(&mut self, terminator: &mir::Terminator<'tcx>)
|
||||
let ty = self.lvalue_ty(value);
|
||||
self.drop(ptr, ty)?;
|
||||
self.frame_mut().next_block = target;
|
||||
TerminatorTarget::Block
|
||||
}
|
||||
|
||||
Resume => unimplemented!(),
|
||||
};
|
||||
}
|
||||
|
||||
Ok(target)
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn drop(&mut self, ptr: Pointer, ty: Ty<'tcx>) -> EvalResult<()> {
|
||||
@@ -662,7 +643,7 @@ fn call_intrinsic(
|
||||
args: &[mir::Operand<'tcx>],
|
||||
dest: Pointer,
|
||||
dest_size: usize
|
||||
) -> EvalResult<TerminatorTarget> {
|
||||
) -> EvalResult<()> {
|
||||
let args_res: EvalResult<Vec<Pointer>> = args.iter()
|
||||
.map(|arg| self.eval_operand(arg))
|
||||
.collect();
|
||||
@@ -799,7 +780,7 @@ fn call_intrinsic(
|
||||
// Since we pushed no stack frame, the main loop will act
|
||||
// as if the call just completed and it's returning to the
|
||||
// current frame.
|
||||
Ok(TerminatorTarget::Call)
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn call_c_abi(
|
||||
@@ -808,7 +789,7 @@ fn call_c_abi(
|
||||
args: &[mir::Operand<'tcx>],
|
||||
dest: Pointer,
|
||||
dest_size: usize,
|
||||
) -> EvalResult<TerminatorTarget> {
|
||||
) -> EvalResult<()> {
|
||||
let name = self.tcx.item_name(def_id);
|
||||
let attrs = self.tcx.get_attrs(def_id);
|
||||
let link_name = match attr::first_attr_value_str_by_name(&attrs, "link_name") {
|
||||
@@ -861,7 +842,7 @@ fn call_c_abi(
|
||||
// Since we pushed no stack frame, the main loop will act
|
||||
// as if the call just completed and it's returning to the
|
||||
// current frame.
|
||||
Ok(TerminatorTarget::Call)
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn assign_fields<I: IntoIterator<Item = u64>>(
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
use super::{
|
||||
CachedMir,
|
||||
TerminatorTarget,
|
||||
ConstantId,
|
||||
GlobalEvalContext,
|
||||
ConstantKind,
|
||||
@@ -42,17 +41,11 @@ fn statement(&mut self, stmt: &mir::Statement<'tcx>) -> EvalResult<()> {
|
||||
fn terminator(&mut self, terminator: &mir::Terminator<'tcx>) -> EvalResult<()> {
|
||||
// after a terminator we go to a new block
|
||||
self.gecx.frame_mut().stmt = 0;
|
||||
let term = {
|
||||
trace!("{:?}", terminator.kind);
|
||||
let result = self.gecx.eval_terminator(terminator);
|
||||
self.gecx.maybe_report(result)?
|
||||
};
|
||||
match term {
|
||||
TerminatorTarget::Return => {
|
||||
self.gecx.pop_stack_frame();
|
||||
},
|
||||
TerminatorTarget::Block |
|
||||
TerminatorTarget::Call => trace!("// {:?}", self.gecx.frame().next_block),
|
||||
trace!("{:?}", terminator.kind);
|
||||
let result = self.gecx.eval_terminator(terminator);
|
||||
self.gecx.maybe_report(result)?;
|
||||
if !self.gecx.stack.is_empty() {
|
||||
trace!("// {:?}", self.gecx.frame().next_block);
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user