about summary refs log tree commit diff
diff options
context:
space:
mode:
authorNoa <coolreader18@gmail.com>2024-10-08 15:33:50 -0500
committerNoa <coolreader18@gmail.com>2024-10-08 15:50:37 -0500
commit35d9bdbcdebeb95e747efa366dac2c811ceab92d (patch)
tree7b2b4a23fdb6f9122a2052ac684e38d95f0c6682
parent10a9ee0607a6ab4d334a5361375c79de46bc5d12 (diff)
downloadrust-35d9bdbcdebeb95e747efa366dac2c811ceab92d.tar.gz
rust-35d9bdbcdebeb95e747efa366dac2c811ceab92d.zip
Use throw intrinsic from stdarch in wasm libunwind
-rw-r--r--library/unwind/src/lib.rs3
-rw-r--r--library/unwind/src/wasm.rs24
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::<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()
         }
     }
 }