1
Fork 0

Refactor get_landing_pad to take a CleanupScope

It unwrapped the Option anyway, so this more closely resembles the
reality of what's happening.
This commit is contained in:
Mark-Simulacrum 2016-12-14 09:26:27 -07:00 committed by Mark Simulacrum
parent 28d00e781b
commit cd57bbe27a
3 changed files with 24 additions and 30 deletions

View file

@ -743,7 +743,7 @@ fn trans_call_fn_once_adapter_shim<'a, 'blk, 'tcx>(
let _icx = push_ctxt("invoke_");
let (llret, bcx) = if cleanup_scope.is_some() && !bcx.sess().no_landing_pads() {
let normal_bcx = bcx.fcx().build_new_block("normal-return");
let landing_pad = bcx.fcx().get_landing_pad(cleanup_scope);
let landing_pad = bcx.fcx().get_landing_pad(cleanup_scope.as_mut().unwrap());
let llresult = bcx.invoke(llfn, &llargs[..], normal_bcx.llbb(), landing_pad, None);
(llresult, normal_bcx)

View file

@ -207,14 +207,10 @@ impl<'blk, 'tcx> FunctionContext<'blk, 'tcx> {
///
/// (The cleanups and resume instruction are created by
/// `trans_cleanups_to_exit_scope()`, not in this function itself.)
pub fn get_landing_pad(&'blk self, scope: &mut Option<CleanupScope<'tcx>>) -> BasicBlockRef {
// TODO: Factor out and take a CleanupScope.
assert!(scope.is_some());
pub fn get_landing_pad(&'blk self, scope: &mut CleanupScope<'tcx>) -> BasicBlockRef {
debug!("get_landing_pad");
// Check if a landing pad block exists; if not, create one.
let mut scope = scope.as_mut().unwrap();
let mut pad_bcx = match scope.cached_landing_pad {
Some(llbb) => return llbb,
None => {
@ -270,7 +266,21 @@ impl<'blk, 'tcx> FunctionContext<'blk, 'tcx> {
return pad_bcx.llbb();
}
fn generate_resume_block(&self, label: UnwindKind) -> BasicBlockRef {
/// Used when the caller wishes to jump to an early exit, such as a return,
/// break, continue, or unwind. This function will generate all cleanups
/// between the top of the stack and the exit `label` and return a basic
/// block that the caller can branch to.
fn trans_cleanups_to_exit_scope(
&'blk self,
label: UnwindKind,
scope: &mut CleanupScope<'tcx>
) -> BasicBlockRef {
debug!("trans_cleanups_to_exit_scope label={:?}`", label);
let cached_exit = scope.cached_early_exit(label);
// Check if we have already cached the unwinding of this
// scope for this label. If so, we can just branch to the cached block.
let exit_llbb = cached_exit.unwrap_or_else(|| {
// Generate a block that will resume unwinding to the calling function
let bcx = self.build_new_block("resume");
match label {
@ -290,23 +300,7 @@ impl<'blk, 'tcx> FunctionContext<'blk, 'tcx> {
}
}
bcx.llbb()
}
/// Used when the caller wishes to jump to an early exit, such as a return,
/// break, continue, or unwind. This function will generate all cleanups
/// between the top of the stack and the exit `label` and return a basic
/// block that the caller can branch to.
fn trans_cleanups_to_exit_scope(
&'blk self,
label: UnwindKind,
scope: &mut CleanupScope<'tcx>
) -> BasicBlockRef {
debug!("trans_cleanups_to_exit_scope label={:?}`", label);
let cached_exit = scope.cached_early_exit(label);
// Check if we have already cached the unwinding of this
// scope for this label. If so, we can just branch to the cached block.
let exit_llbb = cached_exit.unwrap_or_else(|| self.generate_resume_block(label));
});
let name = scope.block_name("clean");
debug!("generating cleanup for {}", name);

View file

@ -312,7 +312,7 @@ fn trans_call_custom_dtor<'a, 'blk, 'tcx>(
let _icx = push_ctxt("invoke_");
let (llret, bcx) = if cleanup_scope.is_some() && !bcx.sess().no_landing_pads() {
let normal_bcx = bcx.fcx().build_new_block("normal-return");
let landing_pad = bcx.fcx().get_landing_pad(cleanup_scope);
let landing_pad = bcx.fcx().get_landing_pad(cleanup_scope.as_mut().unwrap());
let llresult = bcx.invoke(llfn, &llargs[..], normal_bcx.llbb(), landing_pad, None);
(llresult, normal_bcx)