|
19 | 19 | //! completing evaluation successfully without panic).
|
20 | 20 |
|
21 | 21 | use llvm::{BasicBlockRef, ValueRef};
|
22 |
| -use base::{self, Lifetime}; |
23 |
| -use common; |
| 22 | +use base; |
24 | 23 | use common::{BlockAndBuilder, FunctionContext, Funclet};
|
25 | 24 | use glue;
|
26 | 25 | use type_::Type;
|
@@ -55,90 +54,41 @@ impl<'tcx> DropValue<'tcx> {
|
55 | 54 | /// This should only be called once per function, as it creates an alloca for the landingpad.
|
56 | 55 | fn get_landing_pad<'a>(&self, fcx: &FunctionContext<'a, 'tcx>) -> BasicBlockRef {
|
57 | 56 | debug!("get_landing_pad");
|
| 57 | + let bcx = fcx.build_new_block("cleanup_unwind"); |
| 58 | + let llpersonality = bcx.ccx.eh_personality(); |
| 59 | + bcx.set_personality_fn(llpersonality); |
58 | 60 |
|
59 |
| - let mut pad_bcx = fcx.build_new_block("unwind_custom_"); |
60 |
| - |
61 |
| - let llpersonality = pad_bcx.ccx.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) |
| 61 | + if base::wants_msvc_seh(fcx.ccx.sess()) { |
| 62 | + // Insert cleanup instructions into the cleanup block |
| 63 | + let funclet = Some(Funclet::new(bcx.cleanup_pad(None, &[]))); |
| 64 | + self.trans(funclet.as_ref(), &bcx); |
| 65 | + |
| 66 | + bcx.cleanup_ret(bcx.cleanup_pad(None, &[]), None); |
74 | 67 | } else {
|
75 | 68 | // The landing pad return type (the type being propagated). Not sure
|
76 | 69 | // what this represents but it's determined by the personality
|
77 | 70 | // function and this is what the EH proposal example uses.
|
78 | 71 | let llretty = Type::struct_(fcx.ccx, &[Type::i8p(fcx.ccx), Type::i32(fcx.ccx)], false);
|
79 | 72 |
|
80 | 73 | // The only landing pad clause will be 'cleanup'
|
81 |
| - let llretval = pad_bcx.landing_pad(llretty, llpersonality, 1, pad_bcx.fcx().llfn); |
| 74 | + let llretval = bcx.landing_pad(llretty, llpersonality, 1, bcx.fcx().llfn); |
82 | 75 |
|
83 | 76 | // 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 |
| - resume_bcx.unreachable(); |
97 |
| - } |
98 |
| - UnwindKind::LandingPad |
99 |
| - }; |
| 77 | + bcx.set_cleanup(llretval); |
100 | 78 |
|
101 |
| - let mut cleanup = fcx.build_new_block("clean_custom_"); |
| 79 | + // Insert cleanup instructions into the cleanup block |
| 80 | + self.trans(None, &bcx); |
102 | 81 |
|
103 |
| - // Insert cleanup instructions into the cleanup block |
104 |
| - let funclet = match val { |
105 |
| - UnwindKind::CleanupPad(_) => Some(Funclet::new(cleanup.cleanup_pad(None, &[]))), |
106 |
| - UnwindKind::LandingPad => None, |
107 |
| - }; |
108 |
| - self.trans(funclet.as_ref(), &cleanup); |
109 |
| - |
110 |
| - // Insert instruction into cleanup block to branch to the exit |
111 |
| - val.branch(&mut cleanup, resume_bcx.llbb()); |
112 |
| - |
113 |
| - // Branch into the cleanup block |
114 |
| - val.branch(&mut pad_bcx, cleanup.llbb()); |
115 |
| - |
116 |
| - pad_bcx.llbb() |
117 |
| - } |
118 |
| -} |
119 |
| - |
120 |
| -#[derive(Copy, Clone, Debug)] |
121 |
| -enum UnwindKind { |
122 |
| - LandingPad, |
123 |
| - CleanupPad(ValueRef), |
124 |
| -} |
125 |
| - |
126 |
| -impl UnwindKind { |
127 |
| - /// Generates a branch going from `bcx` to `to_llbb` where `self` is |
128 |
| - /// the exit label attached to the start of `bcx`. |
129 |
| - /// |
130 |
| - /// Transitions from an exit label to other exit labels depend on the type |
131 |
| - /// of label. For example with MSVC exceptions unwind exit labels will use |
132 |
| - /// the `cleanupret` instruction instead of the `br` instruction. |
133 |
| - fn branch(&self, bcx: &BlockAndBuilder, to_llbb: BasicBlockRef) { |
134 |
| - match *self { |
135 |
| - UnwindKind::CleanupPad(pad) => { |
136 |
| - bcx.cleanup_ret(pad, Some(to_llbb)); |
137 |
| - } |
138 |
| - UnwindKind::LandingPad => { |
139 |
| - bcx.br(to_llbb); |
| 82 | + if !bcx.sess().target.target.options.custom_unwind_resume { |
| 83 | + bcx.resume(llretval); |
| 84 | + } else { |
| 85 | + let exc_ptr = bcx.extract_value(llretval, 0); |
| 86 | + bcx.call(fcx.eh_unwind_resume().reify(fcx.ccx), &[exc_ptr], None); |
| 87 | + bcx.unreachable(); |
140 | 88 | }
|
141 | 89 | }
|
| 90 | + |
| 91 | + bcx.llbb() |
142 | 92 | }
|
143 | 93 | }
|
144 | 94 |
|
|
0 commit comments