diff options
| author | Brian Anderson <banderson@mozilla.com> | 2016-09-22 19:55:42 +0000 |
|---|---|---|
| committer | Brian Anderson <banderson@mozilla.com> | 2016-09-30 14:02:55 -0700 |
| commit | 525a798ca6513a204de8bd434bf260d79cbdfc9f (patch) | |
| tree | d8169b462b219d52c4187565c91181b611339ea6 /src/libpanic_unwind | |
| parent | 7c0bf41cffc39d011bde4ca722c94d58617c4c91 (diff) | |
| download | rust-525a798ca6513a204de8bd434bf260d79cbdfc9f.tar.gz rust-525a798ca6513a204de8bd434bf260d79cbdfc9f.zip | |
Rewrite emscripten unwinding to use libcxx
Diffstat (limited to 'src/libpanic_unwind')
| -rw-r--r-- | src/libpanic_unwind/Cargo.lock | 9 | ||||
| -rw-r--r-- | src/libpanic_unwind/emcc.rs | 76 | ||||
| -rw-r--r-- | src/libpanic_unwind/gcc.rs | 10 | ||||
| -rw-r--r-- | src/libpanic_unwind/lib.rs | 8 |
4 files changed, 92 insertions, 11 deletions
diff --git a/src/libpanic_unwind/Cargo.lock b/src/libpanic_unwind/Cargo.lock index 20d826d4a47..0cf75c94150 100644 --- a/src/libpanic_unwind/Cargo.lock +++ b/src/libpanic_unwind/Cargo.lock @@ -5,6 +5,7 @@ dependencies = [ "alloc 0.0.0", "core 0.0.0", "libc 0.0.0", + "unwind 0.0.0", ] [[package]] @@ -25,3 +26,11 @@ dependencies = [ "core 0.0.0", ] +[[package]] +name = "unwind" +version = "0.0.0" +dependencies = [ + "core 0.0.0", + "libc 0.0.0", +] + diff --git a/src/libpanic_unwind/emcc.rs b/src/libpanic_unwind/emcc.rs new file mode 100644 index 00000000000..598f99ba27b --- /dev/null +++ b/src/libpanic_unwind/emcc.rs @@ -0,0 +1,76 @@ +// Copyright 2016 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![allow(private_no_mangle_fns)] + +use core::any::Any; +use core::ptr; +use alloc::boxed::Box; +use libc::{self, c_int}; +use unwind as uw; +use core::mem; + +pub fn payload() -> *mut u8 { + ptr::null_mut() +} + +pub unsafe fn cleanup(ptr: *mut u8) -> Box<Any + Send> { + assert!(!ptr.is_null()); + let ex = ptr::read(ptr as *mut _); + __cxa_free_exception(ptr as *mut _); + ex +} + +pub unsafe fn panic(data: Box<Any + Send>) -> u32 { + let sz = mem::size_of_val(&data); + let exception = __cxa_allocate_exception(sz); + if exception == ptr::null_mut() { + return uw::_URC_FATAL_PHASE1_ERROR as u32; + } + let exception = exception as *mut Box<Any + Send>; + ptr::write(exception, data); + __cxa_throw(exception as *mut _, ptr::null_mut(), ptr::null_mut()); + + unreachable!() +} + +#[lang = "eh_personality"] +#[no_mangle] +unsafe extern "C" fn rust_eh_personality(version: c_int, + actions: uw::_Unwind_Action, + exception_class: uw::_Unwind_Exception_Class, + exception_object: *mut uw::_Unwind_Exception, + context: *mut uw::_Unwind_Context) + -> uw::_Unwind_Reason_Code { + __gxx_personality_v0(version, actions, + exception_class, + exception_object, + context) +} + +#[lang = "eh_unwind_resume"] +#[unwind] +unsafe extern "C" fn rust_eh_unwind_resume(panic_ctx: *mut u8) -> ! { + uw::_Unwind_Resume(panic_ctx as *mut uw::_Unwind_Exception); +} + +extern { + fn __cxa_allocate_exception(thrown_size: libc::size_t) -> *mut libc::c_void; + fn __cxa_free_exception(thrown_exception: *mut libc::c_void); + fn __cxa_throw(thrown_exception: *mut libc::c_void, + tinfo: *mut libc::c_void, + dest: *mut libc::c_void); + fn __gxx_personality_v0(version: c_int, + actions: uw::_Unwind_Action, + exception_class: uw::_Unwind_Exception_Class, + exception_object: *mut uw::_Unwind_Exception, + context: *mut uw::_Unwind_Context) + -> uw::_Unwind_Reason_Code; +} diff --git a/src/libpanic_unwind/gcc.rs b/src/libpanic_unwind/gcc.rs index 5bfa77cba7a..33b24fbaa26 100644 --- a/src/libpanic_unwind/gcc.rs +++ b/src/libpanic_unwind/gcc.rs @@ -133,16 +133,6 @@ const UNWIND_DATA_REG: (i32, i32) = (3, 4); // R3, R4 / X3, X4 #[cfg(target_arch = "s390x")] const UNWIND_DATA_REG: (i32, i32) = (6, 7); // R6, R7 -// FIXME: This is completely and utterly wrong. -// I copy'n'pasted the x86 thing just to see if asmjs-unknown-emscripten compiles at all -// (the happy path) -#[cfg(target_arch = "asmjs")] -const UNWIND_DATA_REG: (i32, i32) = (0, 2); // EAX, EDX - -// FIXME: Ditto the above -#[cfg(target_arch = "wasm32")] -const UNWIND_DATA_REG: (i32, i32) = (0, 2); // EAX, EDX - // The following code is based on GCC's C and C++ personality routines. For reference, see: // https://github.com/gcc-mirror/gcc/blob/master/libstdc++-v3/libsupc++/eh_personality.cc // https://github.com/gcc-mirror/gcc/blob/trunk/libgcc/unwind-c.c diff --git a/src/libpanic_unwind/lib.rs b/src/libpanic_unwind/lib.rs index 11dd9befe0a..ff483fa823e 100644 --- a/src/libpanic_unwind/lib.rs +++ b/src/libpanic_unwind/lib.rs @@ -68,10 +68,16 @@ mod imp; mod imp; // i686-pc-windows-gnu and all others -#[cfg(any(unix, all(windows, target_arch = "x86", target_env = "gnu")))] +#[cfg(any(all(unix, not(target_os = "emscripten")), + all(windows, target_arch = "x86", target_env = "gnu")))] #[path = "gcc.rs"] mod imp; +// emscripten +#[cfg(target_os = "emscripten")] +#[path = "emcc.rs"] +mod imp; + mod dwarf; mod windows; |
