From 35d9bdbcdebeb95e747efa366dac2c811ceab92d Mon Sep 17 00:00:00 2001 From: Noa Date: Tue, 8 Oct 2024 15:33:50 -0500 Subject: [PATCH] Use throw intrinsic from stdarch in wasm libunwind --- library/unwind/src/lib.rs | 3 +-- library/unwind/src/wasm.rs | 24 ++++++++++-------------- 2 files changed, 11 insertions(+), 16 deletions(-) diff --git a/library/unwind/src/lib.rs b/library/unwind/src/lib.rs index 46026324d2f..5a476d5843b 100644 --- a/library/unwind/src/lib.rs +++ b/library/unwind/src/lib.rs @@ -3,11 +3,10 @@ #![feature(link_cfg)] #![feature(staged_api)] #![feature(strict_provenance)] -#![cfg_attr(target_arch = "wasm64", feature(simd_wasm64))] #![cfg_attr(not(target_env = "msvc"), feature(libc))] #![cfg_attr( all(target_family = "wasm", not(target_os = "emscripten")), - feature(link_llvm_intrinsics) + feature(simd_wasm64, wasm_exception_handling_intrinsics) )] #![allow(internal_features)] diff --git a/library/unwind/src/wasm.rs b/library/unwind/src/wasm.rs index f4ffac1ba16..2d36a8be004 100644 --- a/library/unwind/src/wasm.rs +++ b/library/unwind/src/wasm.rs @@ -40,29 +40,25 @@ pub unsafe fn _Unwind_DeleteException(exception: *mut _Unwind_Exception) { } pub unsafe fn _Unwind_RaiseException(exception: *mut _Unwind_Exception) -> _Unwind_Reason_Code { - #[cfg(panic = "unwind")] - extern "C" { - /// LLVM lowers this intrinsic to the `throw` instruction. - // FIXME(coolreader18): move to stdarch - #[link_name = "llvm.wasm.throw"] - fn wasm_throw(tag: i32, ptr: *mut u8) -> !; - } - // The wasm `throw` instruction takes a "tag", which differentiates certain // types of exceptions from others. LLVM currently just identifies these // via integers, with 0 corresponding to C++ exceptions and 1 to C setjmp()/longjmp(). // Ideally, we'd be able to choose something unique for Rust, but for now, // we pretend to be C++ and implement the Itanium exception-handling ABI. cfg_if::cfg_if! { - // for now, unless we're -Zbuild-std with panic=unwind, never codegen a throw. + // panic=abort is default for wasm targets. Because an unknown instruction is a load-time + // error on wasm, instead of a runtime error like on traditional architectures, we never + // want to codegen a `throw` instruction, as that would break users using runtimes that + // don't yet support exceptions. The only time this first branch would be selected is if + // the user explicitly opts in to wasm exceptions, via -Zbuild-std with -Cpanic=unwind. if #[cfg(panic = "unwind")] { - wasm_throw(0, exception.cast()) + // corresponds with llvm::WebAssembly::Tag::CPP_EXCEPTION + // in llvm-project/llvm/include/llvm/CodeGen/WasmEHFuncInfo.h + const CPP_EXCEPTION_TAG: i32 = 0; + core::arch::wasm::throw::(exception.cast()) } else { let _ = exception; - #[cfg(target_arch = "wasm32")] - core::arch::wasm32::unreachable(); - #[cfg(target_arch = "wasm64")] - core::arch::wasm64::unreachable(); + core::arch::wasm::unreachable() } } }