Rewrite emscripten unwinding to use libcxx
This commit is contained in:
parent
7c0bf41cff
commit
525a798ca6
9
src/libpanic_unwind/Cargo.lock
generated
9
src/libpanic_unwind/Cargo.lock
generated
@ -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",
|
||||
]
|
||||
|
||||
|
76
src/libpanic_unwind/emcc.rs
Normal file
76
src/libpanic_unwind/emcc.rs
Normal file
@ -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;
|
||||
}
|
@ -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
|
||||
|
@ -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;
|
||||
|
||||
|
@ -65,7 +65,7 @@ pub const unwinder_private_data_size: usize = 2;
|
||||
#[cfg(target_arch = "s390x")]
|
||||
pub const unwinder_private_data_size: usize = 2;
|
||||
|
||||
#[cfg(any(target_arch = "asmjs", target_arch = "wasm32"))]
|
||||
#[cfg(target_os = "emscripten")]
|
||||
pub const unwinder_private_data_size: usize = 20;
|
||||
|
||||
#[repr(C)]
|
||||
|
Loading…
Reference in New Issue
Block a user