Skip to content

Commit

Permalink
Rewrite emscripten unwinding to use libcxx
Browse files Browse the repository at this point in the history
  • Loading branch information
brson committed Sep 30, 2016
1 parent 7c0bf41 commit 525a798
Show file tree
Hide file tree
Showing 5 changed files with 93 additions and 12 deletions.
9 changes: 9 additions & 0 deletions src/libpanic_unwind/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

76 changes: 76 additions & 0 deletions 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;
}
10 changes: 0 additions & 10 deletions src/libpanic_unwind/gcc.rs
Expand Up @@ -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
Expand Down
8 changes: 7 additions & 1 deletion src/libpanic_unwind/lib.rs
Expand Up @@ -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;

Expand Down
2 changes: 1 addition & 1 deletion src/libunwind/libunwind.rs
Expand Up @@ -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)]
Expand Down

0 comments on commit 525a798

Please sign in to comment.