Skip to content

Commit 525a798

Browse files
committed
Rewrite emscripten unwinding to use libcxx
1 parent 7c0bf41 commit 525a798

File tree

5 files changed

+93
-12
lines changed

5 files changed

+93
-12
lines changed

src/libpanic_unwind/Cargo.lock

Lines changed: 9 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/libpanic_unwind/emcc.rs

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
#![allow(private_no_mangle_fns)]
12+
13+
use core::any::Any;
14+
use core::ptr;
15+
use alloc::boxed::Box;
16+
use libc::{self, c_int};
17+
use unwind as uw;
18+
use core::mem;
19+
20+
pub fn payload() -> *mut u8 {
21+
ptr::null_mut()
22+
}
23+
24+
pub unsafe fn cleanup(ptr: *mut u8) -> Box<Any + Send> {
25+
assert!(!ptr.is_null());
26+
let ex = ptr::read(ptr as *mut _);
27+
__cxa_free_exception(ptr as *mut _);
28+
ex
29+
}
30+
31+
pub unsafe fn panic(data: Box<Any + Send>) -> u32 {
32+
let sz = mem::size_of_val(&data);
33+
let exception = __cxa_allocate_exception(sz);
34+
if exception == ptr::null_mut() {
35+
return uw::_URC_FATAL_PHASE1_ERROR as u32;
36+
}
37+
let exception = exception as *mut Box<Any + Send>;
38+
ptr::write(exception, data);
39+
__cxa_throw(exception as *mut _, ptr::null_mut(), ptr::null_mut());
40+
41+
unreachable!()
42+
}
43+
44+
#[lang = "eh_personality"]
45+
#[no_mangle]
46+
unsafe extern "C" fn rust_eh_personality(version: c_int,
47+
actions: uw::_Unwind_Action,
48+
exception_class: uw::_Unwind_Exception_Class,
49+
exception_object: *mut uw::_Unwind_Exception,
50+
context: *mut uw::_Unwind_Context)
51+
-> uw::_Unwind_Reason_Code {
52+
__gxx_personality_v0(version, actions,
53+
exception_class,
54+
exception_object,
55+
context)
56+
}
57+
58+
#[lang = "eh_unwind_resume"]
59+
#[unwind]
60+
unsafe extern "C" fn rust_eh_unwind_resume(panic_ctx: *mut u8) -> ! {
61+
uw::_Unwind_Resume(panic_ctx as *mut uw::_Unwind_Exception);
62+
}
63+
64+
extern {
65+
fn __cxa_allocate_exception(thrown_size: libc::size_t) -> *mut libc::c_void;
66+
fn __cxa_free_exception(thrown_exception: *mut libc::c_void);
67+
fn __cxa_throw(thrown_exception: *mut libc::c_void,
68+
tinfo: *mut libc::c_void,
69+
dest: *mut libc::c_void);
70+
fn __gxx_personality_v0(version: c_int,
71+
actions: uw::_Unwind_Action,
72+
exception_class: uw::_Unwind_Exception_Class,
73+
exception_object: *mut uw::_Unwind_Exception,
74+
context: *mut uw::_Unwind_Context)
75+
-> uw::_Unwind_Reason_Code;
76+
}

src/libpanic_unwind/gcc.rs

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -133,16 +133,6 @@ const UNWIND_DATA_REG: (i32, i32) = (3, 4); // R3, R4 / X3, X4
133133
#[cfg(target_arch = "s390x")]
134134
const UNWIND_DATA_REG: (i32, i32) = (6, 7); // R6, R7
135135

136-
// FIXME: This is completely and utterly wrong.
137-
// I copy'n'pasted the x86 thing just to see if asmjs-unknown-emscripten compiles at all
138-
// (the happy path)
139-
#[cfg(target_arch = "asmjs")]
140-
const UNWIND_DATA_REG: (i32, i32) = (0, 2); // EAX, EDX
141-
142-
// FIXME: Ditto the above
143-
#[cfg(target_arch = "wasm32")]
144-
const UNWIND_DATA_REG: (i32, i32) = (0, 2); // EAX, EDX
145-
146136
// The following code is based on GCC's C and C++ personality routines. For reference, see:
147137
// https://github.com/gcc-mirror/gcc/blob/master/libstdc++-v3/libsupc++/eh_personality.cc
148138
// https://github.com/gcc-mirror/gcc/blob/trunk/libgcc/unwind-c.c

src/libpanic_unwind/lib.rs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,10 +68,16 @@ mod imp;
6868
mod imp;
6969

7070
// i686-pc-windows-gnu and all others
71-
#[cfg(any(unix, all(windows, target_arch = "x86", target_env = "gnu")))]
71+
#[cfg(any(all(unix, not(target_os = "emscripten")),
72+
all(windows, target_arch = "x86", target_env = "gnu")))]
7273
#[path = "gcc.rs"]
7374
mod imp;
7475

76+
// emscripten
77+
#[cfg(target_os = "emscripten")]
78+
#[path = "emcc.rs"]
79+
mod imp;
80+
7581
mod dwarf;
7682
mod windows;
7783

src/libunwind/libunwind.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ pub const unwinder_private_data_size: usize = 2;
6565
#[cfg(target_arch = "s390x")]
6666
pub const unwinder_private_data_size: usize = 2;
6767

68-
#[cfg(any(target_arch = "asmjs", target_arch = "wasm32"))]
68+
#[cfg(target_os = "emscripten")]
6969
pub const unwinder_private_data_size: usize = 20;
7070

7171
#[repr(C)]

0 commit comments

Comments
 (0)