]> git.lizzy.rs Git - rust.git/blob - src/libpanic_unwind/emcc.rs
Rollup merge of #61389 - Zoxc:arena-cleanup, r=eddyb
[rust.git] / src / libpanic_unwind / emcc.rs
1 //! Unwinding for *emscripten* target.
2 //!
3 //! Whereas Rust's usual unwinding implementation for Unix platforms
4 //! calls into the libunwind APIs directly, on Emscripten we instead
5 //! call into the C++ unwinding APIs. This is just an expedience since
6 //! Emscripten's runtime always implements those APIs and does not
7 //! implement libunwind.
8
9 #![allow(private_no_mangle_fns)]
10
11 use core::any::Any;
12 use core::ptr;
13 use core::mem;
14 use alloc::boxed::Box;
15 use libc::{self, c_int};
16 use unwind as uw;
17
18 pub fn payload() -> *mut u8 {
19     ptr::null_mut()
20 }
21
22 pub unsafe fn cleanup(ptr: *mut u8) -> Box<dyn Any + Send> {
23     assert!(!ptr.is_null());
24     let ex = ptr::read(ptr as *mut _);
25     __cxa_free_exception(ptr as *mut _);
26     ex
27 }
28
29 pub unsafe fn panic(data: Box<dyn Any + Send>) -> u32 {
30     let sz = mem::size_of_val(&data);
31     let exception = __cxa_allocate_exception(sz);
32     if exception == ptr::null_mut() {
33         return uw::_URC_FATAL_PHASE1_ERROR as u32;
34     }
35     let exception = exception as *mut Box<dyn Any + Send>;
36     ptr::write(exception, data);
37     __cxa_throw(exception as *mut _, ptr::null_mut(), ptr::null_mut());
38
39     unreachable!()
40 }
41
42 #[lang = "eh_personality"]
43 #[no_mangle]
44 unsafe extern "C" fn rust_eh_personality(version: c_int,
45                                          actions: uw::_Unwind_Action,
46                                          exception_class: uw::_Unwind_Exception_Class,
47                                          exception_object: *mut uw::_Unwind_Exception,
48                                          context: *mut uw::_Unwind_Context)
49                                          -> uw::_Unwind_Reason_Code {
50     __gxx_personality_v0(version, actions, exception_class, exception_object, context)
51 }
52
53 extern "C" {
54     fn __cxa_allocate_exception(thrown_size: libc::size_t) -> *mut libc::c_void;
55     fn __cxa_free_exception(thrown_exception: *mut libc::c_void);
56     fn __cxa_throw(thrown_exception: *mut libc::c_void,
57                    tinfo: *mut libc::c_void,
58                    dest: *mut libc::c_void);
59     fn __gxx_personality_v0(version: c_int,
60                             actions: uw::_Unwind_Action,
61                             exception_class: uw::_Unwind_Exception_Class,
62                             exception_object: *mut uw::_Unwind_Exception,
63                             context: *mut uw::_Unwind_Context)
64                             -> uw::_Unwind_Reason_Code;
65 }