Rewrite emscripten unwinding to use libcxx

This commit is contained in:
Brian Anderson 2016-09-22 19:55:42 +00:00
parent 7c0bf41cff
commit 525a798ca6
5 changed files with 93 additions and 12 deletions

View File

@ -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",
]

View 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;
}

View File

@ -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

View File

@ -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;

View File

@ -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)]