Skip to content

Commit

Permalink
Rollup merge of rust-lang#131418 - coolreader18:wasm-exc-use-stdarch,…
Browse files Browse the repository at this point in the history
… r=bjorn3

Use throw intrinsic from stdarch in wasm libunwind

Tracking issue: rust-lang#118168

This is a very belated followup to rust-lang#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.
  • Loading branch information
tgross35 authored Oct 13, 2024
2 parents 1ee9b69 + cc1e8b5 commit b6c0376
Show file tree
Hide file tree
Showing 2 changed files with 11 additions and 16 deletions.
3 changes: 1 addition & 2 deletions unwind/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)]

Expand Down
24 changes: 10 additions & 14 deletions unwind/src/wasm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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::<CPP_EXCEPTION_TAG>(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()
}
}
}

0 comments on commit b6c0376

Please sign in to comment.