Skip to content

Commit b2a4b02

Browse files
committed
Switch wasm from LLVM intrinsic to inline assembly
In preparation for changes in rust-lang/rust#149141.
1 parent 48d6536 commit b2a4b02

File tree

3 files changed

+27
-35
lines changed

3 files changed

+27
-35
lines changed

src/backend/itanium.rs

Lines changed: 16 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ unsafe impl ThrowByPointer for ActiveBackend {
4242
unsafe fn throw(ex: *mut Header) -> ! {
4343
// SAFETY: We provide a valid exception header.
4444
unsafe {
45-
raise(ex.cast());
45+
_Unwind_RaiseException(ex.cast());
4646
}
4747
}
4848

@@ -81,7 +81,7 @@ unsafe impl ThrowByPointer for ActiveBackend {
8181
// If project-ffi-unwind changes the rustc behavior, we might have to update this
8282
// code.
8383
unsafe {
84-
raise(ex);
84+
_Unwind_RaiseException(ex);
8585
}
8686
}
8787

@@ -160,33 +160,20 @@ unsafe extern "C" fn cleanup(_code: i32, _ex: *mut Header) {
160160
);
161161
}
162162

163-
unsafe extern "C-unwind" {
164-
#[cfg(target_arch = "wasm32")]
165-
#[link_name = "llvm.wasm.throw"]
166-
fn wasm_throw(tag: i32, ex: *mut u8) -> !;
167-
168-
#[cfg(not(target_arch = "wasm32"))]
169-
fn _Unwind_RaiseException(ex: *mut u8) -> !;
163+
// Although Wasm has its own backend, it has worse debug experience than Itanium can offer, so we
164+
// teach this backend how to handle Wasm as well.
165+
#[cfg(target_arch = "wasm32")]
166+
unsafe fn _Unwind_RaiseException(ex: *mut u8) -> ! {
167+
core::arch::asm!(
168+
".tagtype __cpp_exception i32",
169+
"local.get {ex}",
170+
"throw __cpp_exception",
171+
ex = in(local) ex,
172+
options(may_unwind, noreturn, nostack),
173+
);
170174
}
171175

172-
/// Raise an Itanium EH ABI-compatible exception.
173-
///
174-
/// # Safety
175-
///
176-
/// `ex` must point at a valid instance of `_Unwind_Exception`.
177-
#[inline]
178-
unsafe fn raise(ex: *mut u8) -> ! {
179-
#[cfg(not(target_arch = "wasm32"))]
180-
// SAFETY: Passthrough.
181-
unsafe {
182-
_Unwind_RaiseException(ex);
183-
}
184-
185-
// Although Wasm has its own backend, it has worse debug experience than Itanium can offer, so
186-
// we teach this backend how to handle Wasm as well.
187-
#[cfg(target_arch = "wasm32")]
188-
// SAFETY: Passthrough.
189-
unsafe {
190-
wasm_throw(0, ex);
191-
}
176+
#[cfg(not(target_arch = "wasm32"))]
177+
unsafe extern "C-unwind" {
178+
fn _Unwind_RaiseException(ex: *mut u8) -> !;
192179
}

src/backend/wasm.rs

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ unsafe impl ThrowByPointer for ActiveBackend {
1818
unsafe fn throw(ex: *mut Header) -> ! {
1919
// SAFETY: Wasm has no unwinder, so the pointer reaches `intercept` as-is.
2020
unsafe {
21-
wasm_throw(0, ex.cast::<u8>().wrapping_add(1));
21+
throw(ex.cast::<u8>().wrapping_add(1));
2222
}
2323
}
2424

@@ -34,7 +34,7 @@ unsafe impl ThrowByPointer for ActiveBackend {
3434
// safe because it's indistinguishable from not catching it in the first place due to
3535
// Wasm EH being performed by the VM.
3636
unsafe {
37-
wasm_throw(0, ex.cast());
37+
throw(ex.cast());
3838
}
3939
}
4040

@@ -45,9 +45,14 @@ unsafe impl ThrowByPointer for ActiveBackend {
4545
}
4646
}
4747

48-
unsafe extern "C-unwind" {
49-
#[link_name = "llvm.wasm.throw"]
50-
fn wasm_throw(tag: i32, ex: *mut u8) -> !;
48+
unsafe fn throw(ex: *mut u8) -> ! {
49+
core::arch::asm!(
50+
".tagtype __cpp_exception i32",
51+
"local.get {ex}",
52+
"throw __cpp_exception",
53+
ex = in(local) ex,
54+
options(may_unwind, noreturn, nostack),
55+
);
5156
}
5257

5358
#[repr(C, align(2))]

src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -191,7 +191,7 @@
191191
#![cfg_attr(backend = "seh", feature(fn_ptr_trait, std_internals))]
192192
#![cfg_attr(
193193
any(backend = "wasm", all(backend = "itanium", target_arch = "wasm32")),
194-
feature(link_llvm_intrinsics)
194+
feature(asm_experimental_arch, asm_unwind)
195195
)]
196196
#![deny(unsafe_op_in_unsafe_fn)]
197197
#![warn(

0 commit comments

Comments
 (0)