Rollup merge of #131418 - coolreader18:wasm-exc-use-stdarch, r=bjorn3

Use throw intrinsic from stdarch in wasm libunwind

Tracking issue: #118168

This is a very belated followup to #121438; now that rust-lang/stdarch#1542 is merged, we can use the intrinsic exported from `core::arch` instead of defining it inline. I also cleaned up the cfgs a bit and added a more detailed comment.
This commit is contained in:
Trevor Gross 2024-10-12 21:38:36 -05:00 committed by GitHub
commit 415e61c209
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 11 additions and 16 deletions

View File

@ -3,11 +3,10 @@
#![feature(link_cfg)] #![feature(link_cfg)]
#![feature(staged_api)] #![feature(staged_api)]
#![feature(strict_provenance)] #![feature(strict_provenance)]
#![cfg_attr(target_arch = "wasm64", feature(simd_wasm64))]
#![cfg_attr(not(target_env = "msvc"), feature(libc))] #![cfg_attr(not(target_env = "msvc"), feature(libc))]
#![cfg_attr( #![cfg_attr(
all(target_family = "wasm", not(target_os = "emscripten")), all(target_family = "wasm", not(target_os = "emscripten")),
feature(link_llvm_intrinsics) feature(simd_wasm64, wasm_exception_handling_intrinsics)
)] )]
#![allow(internal_features)] #![allow(internal_features)]

View File

@ -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 { 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 // The wasm `throw` instruction takes a "tag", which differentiates certain
// types of exceptions from others. LLVM currently just identifies these // types of exceptions from others. LLVM currently just identifies these
// via integers, with 0 corresponding to C++ exceptions and 1 to C setjmp()/longjmp(). // 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, // 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. // we pretend to be C++ and implement the Itanium exception-handling ABI.
cfg_if::cfg_if! { 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")] { 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::<CPP_EXCEPTION_TAG>(exception.cast())
} else { } else {
let _ = exception; let _ = exception;
#[cfg(target_arch = "wasm32")] core::arch::wasm::unreachable()
core::arch::wasm32::unreachable();
#[cfg(target_arch = "wasm64")]
core::arch::wasm64::unreachable();
} }
} }
} }