mirror of
https://github.com/rust-lang/rust.git
synced 2026-04-27 18:57:42 +03:00
For panic=unwind on Wasm targets, define __cpp_exception tag
Since llvm/llvm-project 159143, llvm no longer weak links the __cpp_exception tag into each object that uses it. They are now defined in compiler-rt. Rust doesn't seem to get them from compiler-rt so llvm decides they need to be imported. This adds them to libunwind.
This commit is contained in:
@@ -7,7 +7,7 @@
|
||||
#![cfg_attr(not(target_env = "msvc"), feature(libc))]
|
||||
#![cfg_attr(
|
||||
all(target_family = "wasm", any(not(target_os = "emscripten"), emscripten_wasm_eh)),
|
||||
feature(link_llvm_intrinsics, simd_wasm64)
|
||||
feature(link_llvm_intrinsics, simd_wasm64, asm_experimental_arch)
|
||||
)]
|
||||
#![allow(internal_features)]
|
||||
#![deny(unsafe_op_in_unsafe_fn)]
|
||||
|
||||
@@ -2,6 +2,30 @@
|
||||
|
||||
#![allow(nonstandard_style)]
|
||||
|
||||
// Define the __cpp_exception tag that LLVM's wasm exception handling requires.
|
||||
// In particular it is required to use either of:
|
||||
// 1. the wasm_throw llvm intrinsic, or
|
||||
// 2. the Rust try intrinsic.
|
||||
//
|
||||
// This must be provided since LLVM commit
|
||||
// aee99e8015daa9f53ab1fd4e5b24cc4c694bdc4a which changed the tag from being
|
||||
// weakly defined in each object file to being an external reference that must
|
||||
// be linked from somewhere.
|
||||
//
|
||||
// We only define this for wasm32-unknown-unknown because on Emscripten/WASI
|
||||
// targets, this symbol should be defined by the external toolchain. In
|
||||
// particular, defining this on Emscripten would break Emscripten dynamic
|
||||
// libraries.
|
||||
#[cfg(all(target_os = "unknown", panic = "unwind"))]
|
||||
core::arch::global_asm!(
|
||||
".globl __cpp_exception",
|
||||
#[cfg(target_pointer_width = "64")]
|
||||
".tagtype __cpp_exception i64",
|
||||
#[cfg(target_pointer_width = "32")]
|
||||
".tagtype __cpp_exception i32",
|
||||
"__cpp_exception:",
|
||||
);
|
||||
|
||||
#[repr(C)]
|
||||
#[derive(Debug, Copy, Clone, PartialEq)]
|
||||
pub enum _Unwind_Reason_Code {
|
||||
|
||||
@@ -267,3 +267,18 @@ the meantime using `-Cpanic=unwind` will require using [`-Zbuild-std`] and
|
||||
passing the appropriate flags to rustc.
|
||||
|
||||
[`-Zbuild-std`]: ../../cargo/reference/unstable.html#build-std
|
||||
|
||||
### The exception tag for panics
|
||||
|
||||
Rust panics are currently implemented as a specific class of C++ exceptions.
|
||||
This is because llvm only supports throwing and catching the C++ exception tag
|
||||
from `wasm_throw` intrinsic and the lowering for the catchpads emitted by the
|
||||
Rust try intrinsic.
|
||||
|
||||
In particular, llvm throw and catch blocks expect a `WebAssembly.Tag` symbol
|
||||
called `__cpp_exception`. If it is not defined somewhere, llvm will generate an
|
||||
Emscripten style import from `env.__cpp_exception`. We don't want this, so we
|
||||
define the symbol in `libunwind` but only for wasm32-unknown-unknown. WASI
|
||||
doesn't currently support unwinding at all, and the Emscripten linker provides
|
||||
the tag in an appropriate manner depending on what sort of binary is being
|
||||
linked.
|
||||
|
||||
Reference in New Issue
Block a user