Reduce extensions to FunctionContext in cleanup.

This commit is contained in:
Mark Simulacrum 2016-12-17 15:34:38 -07:00
parent 1804131b6d
commit f051c60d92
3 changed files with 29 additions and 27 deletions

View File

@ -398,7 +398,7 @@ fn trans_fn_once_adapter_shim<'a, 'tcx>(
let llfn = callee.reify(bcx.ccx());
let llret;
if let Some(landing_pad) = self_scope.as_ref().and_then(|c| c.landing_pad) {
if let Some(landing_pad) = self_scope.landing_pad {
let normal_bcx = bcx.fcx().build_new_block("normal-return");
llret = bcx.invoke(llfn, &llargs[..], normal_bcx.llbb(), landing_pad, None);
bcx = normal_bcx;
@ -416,7 +416,7 @@ fn trans_fn_once_adapter_shim<'a, 'tcx>(
if fn_ret.0.is_never() {
bcx.unreachable();
}
fcx.trans_scope(&bcx, self_scope);
self_scope.trans(&bcx);
fcx.finish(&bcx);
ccx.instances().borrow_mut().insert(method_instance, lloncefn);

View File

@ -29,7 +29,7 @@ use rustc::ty::Ty;
pub struct CleanupScope<'tcx> {
// Cleanup to run upon scope exit.
cleanup: DropValue<'tcx>,
cleanup: Option<DropValue<'tcx>>,
// Computed on creation if compiling with landing pads (!sess.no_landing_pads)
pub landing_pad: Option<BasicBlockRef>,
@ -92,21 +92,11 @@ impl PartialEq for UnwindKind {
}
}
}
impl<'blk, 'tcx> FunctionContext<'blk, 'tcx> {
pub fn trans_scope(
&self,
bcx: &BlockAndBuilder<'blk, 'tcx>,
custom_scope: Option<CleanupScope<'tcx>>
) {
if let Some(scope) = custom_scope {
scope.cleanup.trans(None, &bcx);
}
}
/// Schedules a (deep) drop of `val`, which is a pointer to an instance of
/// `ty`
pub fn schedule_drop_mem(&self, val: ValueRef, ty: Ty<'tcx>) -> Option<CleanupScope<'tcx>> {
if !self.type_needs_drop(ty) { return None; }
impl<'blk, 'tcx> FunctionContext<'blk, 'tcx> {
/// Schedules a (deep) drop of `val`, which is a pointer to an instance of `ty`
pub fn schedule_drop_mem(&self, val: ValueRef, ty: Ty<'tcx>) -> CleanupScope<'tcx> {
if !self.type_needs_drop(ty) { return CleanupScope::noop(); }
let drop = DropValue {
val: val,
ty: ty,
@ -115,7 +105,7 @@ impl<'blk, 'tcx> FunctionContext<'blk, 'tcx> {
debug!("schedule_drop_mem(val={:?}, ty={:?}) skip_dtor={}", Value(val), ty, drop.skip_dtor);
Some(CleanupScope::new(self, drop))
CleanupScope::new(self, drop)
}
/// Issue #23611: Schedules a (deep) drop of the contents of
@ -123,11 +113,10 @@ impl<'blk, 'tcx> FunctionContext<'blk, 'tcx> {
/// `ty`. The scheduled code handles extracting the discriminant
/// and dropping the contents associated with that variant
/// *without* executing any associated drop implementation.
pub fn schedule_drop_adt_contents(&self, val: ValueRef, ty: Ty<'tcx>)
-> Option<CleanupScope<'tcx>> {
pub fn schedule_drop_adt_contents(&self, val: ValueRef, ty: Ty<'tcx>) -> CleanupScope<'tcx> {
// `if` below could be "!contents_needs_drop"; skipping drop
// is just an optimization, so sound to be conservative.
if !self.type_needs_drop(ty) { return None; }
if !self.type_needs_drop(ty) { return CleanupScope::noop(); }
let drop = DropValue {
val: val,
@ -138,15 +127,14 @@ impl<'blk, 'tcx> FunctionContext<'blk, 'tcx> {
debug!("schedule_drop_adt_contents(val={:?}, ty={:?}) skip_dtor={}",
Value(val), ty, drop.skip_dtor);
Some(CleanupScope::new(self, drop))
CleanupScope::new(self, drop)
}
}
impl<'tcx> CleanupScope<'tcx> {
fn new<'a>(fcx: &FunctionContext<'a, 'tcx>, drop_val: DropValue<'tcx>) -> CleanupScope<'tcx> {
CleanupScope {
cleanup: drop_val,
cleanup: Some(drop_val),
landing_pad: if !fcx.ccx.sess().no_landing_pads() {
Some(CleanupScope::get_landing_pad(fcx, &drop_val))
} else {
@ -155,6 +143,19 @@ impl<'tcx> CleanupScope<'tcx> {
}
}
pub fn noop() -> CleanupScope<'tcx> {
CleanupScope {
cleanup: None,
landing_pad: None,
}
}
pub fn trans<'a>(self, bcx: &'a BlockAndBuilder<'a, 'tcx>) {
if let Some(cleanup) = self.cleanup {
cleanup.trans(None, &bcx);
}
}
/// Creates a landing pad for the top scope. The landing pad will perform all cleanups necessary
/// for an unwind and then `resume` to continue error propagation:
///

View File

@ -32,6 +32,7 @@ use type_of::{type_of, sizing_type_of, align_of};
use type_::Type;
use value::Value;
use Disr;
use cleanup::CleanupScope;
use syntax_pos::DUMMY_SP;
@ -224,7 +225,7 @@ fn trans_custom_dtor<'blk, 'tcx>(mut bcx: BlockAndBuilder<'blk, 'tcx>,
let contents_scope = if !shallow_drop {
bcx.fcx().schedule_drop_adt_contents(v0, t)
} else {
None
CleanupScope::noop()
};
let (sized_args, unsized_args);
@ -252,7 +253,7 @@ fn trans_custom_dtor<'blk, 'tcx>(mut bcx: BlockAndBuilder<'blk, 'tcx>,
let callee = Callee::def(bcx.ccx(), dtor_did, vtbl.substs);
let fn_ty = callee.direct_fn_type(bcx.ccx(), &[]);
let llret;
if let Some(landing_pad) = contents_scope.as_ref().and_then(|c| c.landing_pad) {
if let Some(landing_pad) = contents_scope.landing_pad {
let normal_bcx = bcx.fcx().build_new_block("normal-return");
llret = bcx.invoke(callee.reify(bcx.ccx()), args, normal_bcx.llbb(), landing_pad, None);
bcx = normal_bcx;
@ -260,7 +261,7 @@ fn trans_custom_dtor<'blk, 'tcx>(mut bcx: BlockAndBuilder<'blk, 'tcx>,
llret = bcx.call(callee.reify(bcx.ccx()), args, None);
}
fn_ty.apply_attrs_callsite(llret);
bcx.fcx().trans_scope(&bcx, contents_scope);
contents_scope.trans(&bcx);
bcx
}