Skip to content

Commit 7bfed2e

Browse files
committed
refactor goto_block and also add unwind_to_block
1 parent d902539 commit 7bfed2e

File tree

3 files changed

+38
-21
lines changed

3 files changed

+38
-21
lines changed

src/librustc_mir/const_eval.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -338,7 +338,7 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for CompileTimeInterpreter<'mir,
338338
// that for const fn! We certainly do *not* want to actually call the fn
339339
// though, so be sure we return here.
340340
return if ecx.hook_panic_fn(instance, args, dest)? {
341-
ecx.goto_block(ret)?; // fully evaluated and done
341+
ecx.return_to_block(ret)?; // callee is fully evaluated and done
342342
Ok(None)
343343
} else {
344344
throw_unsup_format!("calling non-const function `{}`", instance)

src/librustc_mir/interpret/eval_context.rs

+33-5
Original file line numberDiff line numberDiff line change
@@ -553,6 +553,37 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
553553
}
554554
}
555555

556+
/// Jump to the given block.
557+
#[inline]
558+
pub fn go_to_block(&mut self, target: mir::BasicBlock) {
559+
let frame = self.frame_mut();
560+
frame.block = Some(target);
561+
frame.stmt = 0;
562+
}
563+
564+
/// *Return* to the given `target` basic block.
565+
/// Do *not* use for unwinding! Use `unwind_to_block` instead.
566+
///
567+
/// If `target` is `None`, that indicates the function cannot return, so we raise UB.
568+
pub fn return_to_block(&mut self, target: Option<mir::BasicBlock>) -> InterpResult<'tcx> {
569+
if let Some(target) = target {
570+
Ok(self.go_to_block(target))
571+
} else {
572+
throw_ub!(Unreachable)
573+
}
574+
}
575+
576+
/// *Unwind* to the given `target` basic block.
577+
/// Do *not* use for returning! Use `return_to_block` instead.
578+
///
579+
/// If `target` is `None`, that indicates the function does not need cleanup during
580+
/// unwinding, and we will just keep propagating that upwards.
581+
pub fn unwind_to_block(&mut self, target: Option<mir::BasicBlock>) {
582+
let frame = self.frame_mut();
583+
frame.block = target;
584+
frame.stmt = 0;
585+
}
586+
556587
/// Pops the current frame from the stack, deallocating the
557588
/// memory for allocated locals.
558589
///
@@ -628,10 +659,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
628659
if cur_unwinding {
629660
// Follow the unwind edge.
630661
let unwind = next_block.expect("Encounted StackPopCleanup::None when unwinding!");
631-
let next_frame = self.frame_mut();
632-
// If `unwind` is `None`, we'll leave that function immediately again.
633-
next_frame.block = unwind;
634-
next_frame.stmt = 0;
662+
self.unwind_to_block(unwind);
635663
} else {
636664
// Follow the normal return edge.
637665
// Validate the return value. Do this after deallocating so that we catch dangling
@@ -658,7 +686,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
658686

659687
// Jump to new block -- *after* validation so that the spans make more sense.
660688
if let Some(ret) = next_block {
661-
self.goto_block(ret)?;
689+
self.return_to_block(ret)?;
662690
}
663691
}
664692

src/librustc_mir/interpret/terminator.rs

+4-15
Original file line numberDiff line numberDiff line change
@@ -12,17 +12,6 @@ use super::{
1212
};
1313

1414
impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
15-
#[inline]
16-
pub fn goto_block(&mut self, target: Option<mir::BasicBlock>) -> InterpResult<'tcx> {
17-
if let Some(target) = target {
18-
self.frame_mut().block = Some(target);
19-
self.frame_mut().stmt = 0;
20-
Ok(())
21-
} else {
22-
throw_ub!(Unreachable)
23-
}
24-
}
25-
2615
pub(super) fn eval_terminator(
2716
&mut self,
2817
terminator: &mir::Terminator<'tcx>,
@@ -34,7 +23,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
3423
self.pop_stack_frame(/* unwinding */ false)?
3524
}
3625

37-
Goto { target } => self.goto_block(Some(target))?,
26+
Goto { target } => self.go_to_block(target),
3827

3928
SwitchInt {
4029
ref discr,
@@ -60,7 +49,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
6049
}
6150
}
6251

63-
self.goto_block(Some(target_block))?;
52+
self.go_to_block(target_block);
6453
}
6554

6655
Call {
@@ -133,7 +122,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
133122
let cond_val = self.read_immediate(self.eval_operand(cond, None)?)?
134123
.to_scalar()?.to_bool()?;
135124
if expected == cond_val {
136-
self.goto_block(Some(target))?;
125+
self.go_to_block(target);
137126
} else {
138127
// Compute error message
139128
use rustc::mir::interpret::PanicInfo::*;
@@ -272,7 +261,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
272261
// No stack frame gets pushed, the main loop will just act as if the
273262
// call completed.
274263
if ret.is_some() {
275-
self.goto_block(ret)?;
264+
self.return_to_block(ret)?;
276265
} else {
277266
// If this intrinsic call doesn't have a ret block,
278267
// then the intrinsic implementation should have

0 commit comments

Comments
 (0)