@@ -118,7 +118,9 @@ mod libunwind {
118
118
exception : * _Unwind_Exception ) ;
119
119
120
120
extern "C" {
121
+ #[ cfg( not( target_os = "android" ) ) ]
121
122
pub fn _Unwind_RaiseException ( exception : * _Unwind_Exception ) -> _Unwind_Reason_Code ;
123
+ #[ cfg( not( target_os = "android" ) ) ]
122
124
pub fn _Unwind_DeleteException ( exception : * _Unwind_Exception ) ;
123
125
}
124
126
}
@@ -140,6 +142,7 @@ impl Unwinder {
140
142
self . unwinding
141
143
}
142
144
145
+ #[ cfg( not( target_os = "android" ) ) ]
143
146
pub fn try ( & mut self , f: ||) {
144
147
use unstable:: raw:: Closure ;
145
148
@@ -174,6 +177,35 @@ impl Unwinder {
174
177
}
175
178
}
176
179
180
+ // FIXME #11147. On Android we're using C++ to do our unwinding because
181
+ // our initial attempts at using libunwind directly don't seem to work
182
+ // correctly. Would love to not be doing this.
183
+ #[ cfg( target_os = "android" ) ]
184
+ pub fn try ( & mut self , f: ||) {
185
+ use unstable:: raw:: Closure ;
186
+
187
+ unsafe {
188
+ let closure: Closure = cast:: transmute ( f) ;
189
+ rust_cxx_try ( try_fn, closure. code as * c_void , closure. env as * c_void ) ;
190
+ }
191
+
192
+ extern fn try_fn ( code : * c_void , env : * c_void ) {
193
+ unsafe {
194
+ let closure: || = cast:: transmute ( Closure {
195
+ code : code as * ( ) ,
196
+ env : env as * ( ) ,
197
+ } ) ;
198
+ closure ( ) ;
199
+ }
200
+ }
201
+
202
+ extern {
203
+ fn rust_cxx_try ( f : extern "C" fn ( * c_void , * c_void ) ,
204
+ code : * c_void ,
205
+ data : * c_void ) ;
206
+ }
207
+ }
208
+
177
209
pub fn begin_unwind ( & mut self , cause : ~Any ) -> ! {
178
210
rtdebug ! ( "begin_unwind()" ) ;
179
211
@@ -186,6 +218,11 @@ impl Unwinder {
186
218
#[ inline( never) ]
187
219
#[ no_mangle]
188
220
fn rust_fail ( ) -> ! {
221
+ throw ( ) ;
222
+ }
223
+
224
+ #[ cfg( not( target_os = "android" ) ) ]
225
+ fn throw ( ) -> ! {
189
226
unsafe {
190
227
let exception = ~uw:: _Unwind_Exception {
191
228
exception_class : rust_exception_class ( ) ,
@@ -205,6 +242,15 @@ impl Unwinder {
205
242
}
206
243
}
207
244
}
245
+
246
+ #[ cfg( target_os = "android" ) ]
247
+ fn throw ( ) -> ! {
248
+ unsafe { rust_cxx_throw ( ) ; }
249
+
250
+ extern {
251
+ fn rust_cxx_throw ( ) -> !;
252
+ }
253
+ }
208
254
}
209
255
210
256
pub fn result ( & mut self ) -> TaskResult {
@@ -218,6 +264,7 @@ impl Unwinder {
218
264
219
265
// Rust's exception class identifier. This is used by personality routines to
220
266
// determine whether the exception was thrown by their own runtime.
267
+ #[ cfg( not( target_os = "android" ) ) ]
221
268
fn rust_exception_class ( ) -> uw:: _Unwind_Exception_Class {
222
269
// M O Z \0 R U S T -- vendor, language
223
270
0x4d4f5a_00_52555354
@@ -243,12 +290,21 @@ fn rust_exception_class() -> uw::_Unwind_Exception_Class {
243
290
// say "catch!".
244
291
245
292
extern "C" {
293
+ #[ cfg( not( target_os = "android" ) ) ]
246
294
fn __gcc_personality_v0 ( version : c_int ,
247
295
actions : uw:: _Unwind_Action ,
248
296
exception_class : uw:: _Unwind_Exception_Class ,
249
297
ue_header : * uw:: _Unwind_Exception ,
250
298
context : * uw:: _Unwind_Context )
251
299
-> uw:: _Unwind_Reason_Code ;
300
+
301
+ #[ cfg( target_os = "android" ) ]
302
+ fn __gxx_personality_v0 ( version : c_int ,
303
+ actions : uw:: _Unwind_Action ,
304
+ exception_class : uw:: _Unwind_Exception_Class ,
305
+ ue_header : * uw:: _Unwind_Exception ,
306
+ context : * uw:: _Unwind_Context )
307
+ -> uw:: _Unwind_Reason_Code ;
252
308
}
253
309
254
310
#[ lang="eh_personality" ]
@@ -263,10 +319,8 @@ pub extern "C" fn rust_eh_personality(
263
319
context : * uw:: _Unwind_Context
264
320
) -> uw:: _Unwind_Reason_Code
265
321
{
266
- unsafe {
267
- __gcc_personality_v0 ( version, actions, exception_class, ue_header,
268
- context)
269
- }
322
+ native_personality ( version, actions, exception_class, ue_header,
323
+ context)
270
324
}
271
325
272
326
#[ no_mangle] // referenced from rust_try.ll
@@ -284,10 +338,38 @@ pub extern "C" fn rust_eh_personality_catch(
284
338
uw:: _URC_HANDLER_FOUND // catch!
285
339
}
286
340
else { // cleanup phase
287
- unsafe {
288
- __gcc_personality_v0 ( version, actions, exception_class, ue_header,
289
- context)
290
- }
341
+ native_personality ( version, actions, exception_class, ue_header,
342
+ context)
343
+ }
344
+ }
345
+
346
+ #[ cfg( not( target_os = "android" ) ) ]
347
+ fn native_personality (
348
+ version : c_int ,
349
+ actions : uw:: _Unwind_Action ,
350
+ exception_class : uw:: _Unwind_Exception_Class ,
351
+ ue_header : * uw:: _Unwind_Exception ,
352
+ context : * uw:: _Unwind_Context
353
+ ) -> uw:: _Unwind_Reason_Code
354
+ {
355
+ unsafe {
356
+ __gcc_personality_v0 ( version, actions, exception_class, ue_header,
357
+ context)
358
+ }
359
+ }
360
+
361
+ #[ cfg( target_os = "android" ) ]
362
+ fn native_personality (
363
+ version : c_int ,
364
+ actions : uw:: _Unwind_Action ,
365
+ exception_class : uw:: _Unwind_Exception_Class ,
366
+ ue_header : * uw:: _Unwind_Exception ,
367
+ context : * uw:: _Unwind_Context
368
+ ) -> uw:: _Unwind_Reason_Code
369
+ {
370
+ unsafe {
371
+ __gxx_personality_v0 ( version, actions, exception_class, ue_header,
372
+ context)
291
373
}
292
374
}
293
375
0 commit comments