From 57985b3646f1f6c6c0a16179689d8d2297eb8a8e Mon Sep 17 00:00:00 2001 From: Alisa Sireneva Date: Thu, 31 Oct 2024 22:28:31 +0300 Subject: [PATCH] Use wasm throw instruction on wasm32 --- .github/workflows/ci.yml | 8 ++++++-- build.rs | 4 +++- src/backend/itanium.rs | 30 +++++++++++++++++++++++++----- src/lib.rs | 4 ++++ 4 files changed, 38 insertions(+), 8 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index dd1372f..86854d6 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -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 }} diff --git a/build.rs b/build.rs index f891fb9..9c0de1e 100644 --- a/build.rs +++ b/build.rs @@ -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 diff --git a/src/backend/itanium.rs b/src/backend/itanium.rs index 7fba1dc..c11b0b9 100644 --- a/src/backend/itanium.rs +++ b/src/backend/itanium.rs @@ -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()); } } @@ -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); } } @@ -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 { @@ -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); + } +} diff --git a/src/lib.rs b/src/lib.rs index c58de1b..d4cd14a 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -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,