Skip to content

Commit

Permalink
Use wasm throw instruction on wasm32
Browse files Browse the repository at this point in the history
  • Loading branch information
purplesyringa committed Oct 31, 2024
1 parent e9baf97 commit 57985b3
Show file tree
Hide file tree
Showing 4 changed files with 38 additions and 8 deletions.
8 changes: 6 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -120,9 +120,13 @@ jobs:
- name: Install rust-src
run: rustup component add rust-src
- name: Test with panic backend (debug)
run: ./cargo-wasi test --target wasm32-wasip1
run: LITHIUM_BACKEND=panic ./cargo-wasi test --target wasm32-wasip1
- name: Test with Itanium backend (debug)
run: LITHIUM_BACKEND=itanium ./cargo-wasi test --target wasm32-wasip1
- name: Test with panic backend (release)
run: ./cargo-wasi test --target wasm32-wasip1 --release
run: LITHIUM_BACKEND=panic ./cargo-wasi test --target wasm32-wasip1 --release
- name: Test with Itanium backend (release)
run: LITHIUM_BACKEND=itanium ./cargo-wasi test --target wasm32-wasip1 --release

darwin:
runs-on: ${{ matrix.os }}
Expand Down
4 changes: 3 additions & 1 deletion build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,9 @@ fn main() {
} else if cfg("target_os") == "emscripten" {
println!("cargo::rustc-cfg=backend=\"emscripten\"");
} else if version_meta().unwrap().channel == Channel::Nightly
&& (has_cfg("unix") || (has_cfg("windows") && cfg("target_env") == "gnu"))
&& (has_cfg("unix")
|| (has_cfg("windows") && cfg("target_env") == "gnu")
|| cfg("target_arch") == "wasm32")
{
println!("cargo::rustc-cfg=backend=\"itanium\"");
} else if version_meta().unwrap().channel == Channel::Nightly
Expand Down
30 changes: 25 additions & 5 deletions src/backend/itanium.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,7 @@ unsafe impl ThrowByPointer for ActiveBackend {
unsafe fn throw(ex: *mut Header) -> ! {
// SAFETY: We provide a valid exception header.
unsafe {
#[expect(clippy::used_underscore_items, reason = "External API")]
_Unwind_RaiseException(ex.cast());
raise(ex.cast());
}
}

Expand Down Expand Up @@ -73,8 +72,7 @@ unsafe impl ThrowByPointer for ActiveBackend {
// If project-ffi-unwind changes the rustc behavior, we might have to update this
// code.
unsafe {
#[expect(clippy::used_underscore_items, reason = "External API")]
_Unwind_RaiseException(ex);
raise(ex);
}
}

Expand Down Expand Up @@ -141,7 +139,8 @@ const fn get_unwinder_private_word_count() -> usize {
target_arch = "sparc64",
target_arch = "riscv64",
target_arch = "riscv32",
target_arch = "loongarch64"
target_arch = "loongarch64",
target_arch = "wasm32"
)) {
2
} else {
Expand All @@ -166,6 +165,27 @@ unsafe extern "C" fn cleanup(_code: i32, _ex: *mut Header) {
core::intrinsics::abort();
}

#[cfg(not(target_arch = "wasm32"))]
extern "C-unwind" {
fn _Unwind_RaiseException(ex: *mut u8) -> !;
}

/// Raise an Itanium EH ABI-compatible exception.
///
/// # Safety
///
/// `ex` must point at a valid instance of `_Unwind_Exception`.
unsafe fn raise(ex: *mut u8) -> ! {
#[cfg(not(target_arch = "wasm32"))]
#[expect(clippy::used_underscore_items, reason = "External API")]
// SAFETY: Passthrough.
unsafe {
_Unwind_RaiseException(ex);
}

#[cfg(target_arch = "wasm32")]
// SAFETY: Passthrough.
unsafe {
core::arch::wasm32::throw::<0>(ex);
}
}
4 changes: 4 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,10 @@
feature(core_intrinsics)
)]
#![cfg_attr(backend = "seh", feature(fn_ptr_trait, std_internals))]
#![cfg_attr(
all(backend = "itanium", target_arch = "wasm32"),
feature(wasm_exception_handling_intrinsics)
)]
#![deny(unsafe_op_in_unsafe_fn)]
#![warn(
clippy::cargo,
Expand Down

0 comments on commit 57985b3

Please sign in to comment.