Skip to content

Commit 0d5a8ad

Browse files
Move get_landing_pad onto DropVal.
1 parent 6f368e6 commit 0d5a8ad

File tree

1 file changed

+69
-80
lines changed

1 file changed

+69
-80
lines changed

src/librustc_trans/cleanup.rs

Lines changed: 69 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,74 @@ impl<'tcx> DropValue<'tcx> {
4646
fn trans<'a>(&self, funclet: Option<&'a Funclet>, bcx: &BlockAndBuilder<'a, 'tcx>) {
4747
glue::call_drop_glue(bcx, self.val, self.ty, self.skip_dtor, funclet)
4848
}
49+
50+
/// Creates a landing pad for the top scope. The landing pad will perform all cleanups necessary
51+
/// for an unwind and then `resume` to continue error propagation:
52+
///
53+
/// landing_pad -> ... cleanups ... -> [resume]
54+
///
55+
/// This should only be called once per function, as it creates an alloca for the landingpad.
56+
fn get_landing_pad<'a>(&self, fcx: &FunctionContext<'a, 'tcx>) -> BasicBlockRef {
57+
debug!("get_landing_pad");
58+
59+
let mut pad_bcx = fcx.build_new_block("unwind_custom_");
60+
61+
let llpersonality = pad_bcx.fcx().eh_personality();
62+
63+
let resume_bcx = fcx.build_new_block("resume");
64+
let val = if base::wants_msvc_seh(fcx.ccx.sess()) {
65+
// A cleanup pad requires a personality function to be specified, so
66+
// we do that here explicitly (happens implicitly below through
67+
// creation of the landingpad instruction). We then create a
68+
// cleanuppad instruction which has no filters to run cleanup on all
69+
// exceptions.
70+
pad_bcx.set_personality_fn(llpersonality);
71+
let llretval = pad_bcx.cleanup_pad(None, &[]);
72+
resume_bcx.cleanup_ret(resume_bcx.cleanup_pad(None, &[]), None);
73+
UnwindKind::CleanupPad(llretval)
74+
} else {
75+
// The landing pad return type (the type being propagated). Not sure
76+
// what this represents but it's determined by the personality
77+
// function and this is what the EH proposal example uses.
78+
let llretty = Type::struct_(fcx.ccx, &[Type::i8p(fcx.ccx), Type::i32(fcx.ccx)], false);
79+
80+
// The only landing pad clause will be 'cleanup'
81+
let llretval = pad_bcx.landing_pad(llretty, llpersonality, 1, pad_bcx.fcx().llfn);
82+
83+
// The landing pad block is a cleanup
84+
pad_bcx.set_cleanup(llretval);
85+
86+
let addr = pad_bcx.fcx().alloca(common::val_ty(llretval), "");
87+
Lifetime::Start.call(&pad_bcx, addr);
88+
pad_bcx.store(llretval, addr);
89+
let lp = resume_bcx.load(addr);
90+
Lifetime::End.call(&resume_bcx, addr);
91+
if !resume_bcx.sess().target.target.options.custom_unwind_resume {
92+
resume_bcx.resume(lp);
93+
} else {
94+
let exc_ptr = resume_bcx.extract_value(lp, 0);
95+
resume_bcx.call(fcx.eh_unwind_resume().reify(fcx.ccx), &[exc_ptr], None);
96+
}
97+
UnwindKind::LandingPad
98+
};
99+
100+
let mut cleanup = fcx.build_new_block("clean_custom_");
101+
102+
// Insert cleanup instructions into the cleanup block
103+
let funclet = match val {
104+
UnwindKind::CleanupPad(_) => Some(Funclet::new(cleanup.cleanup_pad(None, &[]))),
105+
UnwindKind::LandingPad => None,
106+
};
107+
self.trans(funclet.as_ref(), &cleanup);
108+
109+
// Insert instruction into cleanup block to branch to the exit
110+
val.branch(&mut cleanup, resume_bcx.llbb());
111+
112+
// Branch into the cleanup block
113+
val.branch(&mut pad_bcx, cleanup.llbb());
114+
115+
pad_bcx.llbb()
116+
}
49117
}
50118

51119
#[derive(Copy, Clone, Debug)]
@@ -73,16 +141,6 @@ impl UnwindKind {
73141
}
74142
}
75143

76-
impl PartialEq for UnwindKind {
77-
fn eq(&self, label: &UnwindKind) -> bool {
78-
match (*self, *label) {
79-
(UnwindKind::LandingPad, UnwindKind::LandingPad) |
80-
(UnwindKind::CleanupPad(..), UnwindKind::CleanupPad(..)) => true,
81-
_ => false,
82-
}
83-
}
84-
}
85-
86144
impl<'a, 'tcx> FunctionContext<'a, 'tcx> {
87145
/// Schedules a (deep) drop of `val`, which is a pointer to an instance of `ty`
88146
pub fn schedule_drop_mem(&self, val: ValueRef, ty: Ty<'tcx>) -> CleanupScope<'tcx> {
@@ -126,7 +184,7 @@ impl<'tcx> CleanupScope<'tcx> {
126184
CleanupScope {
127185
cleanup: Some(drop_val),
128186
landing_pad: if !fcx.ccx.sess().no_landing_pads() {
129-
Some(CleanupScope::get_landing_pad(fcx, &drop_val))
187+
Some(drop_val.get_landing_pad(fcx))
130188
} else {
131189
None
132190
},
@@ -145,73 +203,4 @@ impl<'tcx> CleanupScope<'tcx> {
145203
cleanup.trans(None, &bcx);
146204
}
147205
}
148-
149-
/// Creates a landing pad for the top scope. The landing pad will perform all cleanups necessary
150-
/// for an unwind and then `resume` to continue error propagation:
151-
///
152-
/// landing_pad -> ... cleanups ... -> [resume]
153-
///
154-
/// This should only be called once per function, as it creates an alloca for the landingpad.
155-
fn get_landing_pad<'a>(fcx: &FunctionContext<'a, 'tcx>, drop_val: &DropValue<'tcx>)
156-
-> BasicBlockRef {
157-
debug!("get_landing_pad");
158-
159-
let mut pad_bcx = fcx.build_new_block("unwind_custom_");
160-
161-
let llpersonality = pad_bcx.fcx().eh_personality();
162-
163-
let resume_bcx = fcx.build_new_block("resume");
164-
let val = if base::wants_msvc_seh(fcx.ccx.sess()) {
165-
// A cleanup pad requires a personality function to be specified, so
166-
// we do that here explicitly (happens implicitly below through
167-
// creation of the landingpad instruction). We then create a
168-
// cleanuppad instruction which has no filters to run cleanup on all
169-
// exceptions.
170-
pad_bcx.set_personality_fn(llpersonality);
171-
let llretval = pad_bcx.cleanup_pad(None, &[]);
172-
resume_bcx.cleanup_ret(resume_bcx.cleanup_pad(None, &[]), None);
173-
UnwindKind::CleanupPad(llretval)
174-
} else {
175-
// The landing pad return type (the type being propagated). Not sure
176-
// what this represents but it's determined by the personality
177-
// function and this is what the EH proposal example uses.
178-
let llretty = Type::struct_(fcx.ccx, &[Type::i8p(fcx.ccx), Type::i32(fcx.ccx)], false);
179-
180-
// The only landing pad clause will be 'cleanup'
181-
let llretval = pad_bcx.landing_pad(llretty, llpersonality, 1, pad_bcx.fcx().llfn);
182-
183-
// The landing pad block is a cleanup
184-
pad_bcx.set_cleanup(llretval);
185-
186-
let addr = pad_bcx.fcx().alloca(common::val_ty(llretval), "");
187-
Lifetime::Start.call(&pad_bcx, addr);
188-
pad_bcx.store(llretval, addr);
189-
let lp = resume_bcx.load(addr);
190-
Lifetime::End.call(&resume_bcx, addr);
191-
if !resume_bcx.sess().target.target.options.custom_unwind_resume {
192-
resume_bcx.resume(lp);
193-
} else {
194-
let exc_ptr = resume_bcx.extract_value(lp, 0);
195-
resume_bcx.call(fcx.eh_unwind_resume().reify(fcx.ccx), &[exc_ptr], None);
196-
}
197-
UnwindKind::LandingPad
198-
};
199-
200-
let mut cleanup = fcx.build_new_block("clean_custom_");
201-
202-
// Insert cleanup instructions into the cleanup block
203-
let funclet = match val {
204-
UnwindKind::CleanupPad(_) => Some(Funclet::new(cleanup.cleanup_pad(None, &[]))),
205-
UnwindKind::LandingPad => None,
206-
};
207-
drop_val.trans(funclet.as_ref(), &cleanup);
208-
209-
// Insert instruction into cleanup block to branch to the exit
210-
val.branch(&mut cleanup, resume_bcx.llbb());
211-
212-
// Branch into the cleanup block
213-
val.branch(&mut pad_bcx, cleanup.llbb());
214-
215-
return pad_bcx.llbb();
216-
}
217206
}

0 commit comments

Comments
 (0)