Skip to content

Commit 0d48931

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

File tree

3 files changed

+41
-29
lines changed

3 files changed

+41
-29
lines changed

src/backend/itanium.rs

Lines changed: 20 additions & 23 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,30 @@ 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) -> !;
170-
}
171-
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")]
172166
/// Raise an Itanium EH ABI-compatible exception.
173167
///
174168
/// # Safety
175169
///
176170
/// `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.
171+
unsafe fn _Unwind_RaiseException(ex: *mut u8) -> ! {
172+
// SAFETY: Directly throws the exception.
181173
unsafe {
182-
_Unwind_RaiseException(ex);
174+
core::arch::asm!(
175+
".tagtype __cpp_exception i32",
176+
".globl __cpp_exception",
177+
".weak __cpp_exception",
178+
"local.get {ex}",
179+
"throw __cpp_exception",
180+
ex = in(local) ex,
181+
options(may_unwind, noreturn, nostack),
182+
);
183183
}
184+
}
184185

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-
}
186+
#[cfg(not(target_arch = "wasm32"))]
187+
unsafe extern "C-unwind" {
188+
fn _Unwind_RaiseException(ex: *mut u8) -> !;
192189
}

src/backend/wasm.rs

Lines changed: 20 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,24 @@ 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+
/// Raise an Itanium EH ABI-compatible exception.
49+
///
50+
/// # Safety
51+
///
52+
/// `ex` must point at a valid instance of `_Unwind_Exception`.
53+
unsafe fn throw(ex: *mut u8) -> ! {
54+
// SAFETY: Directly throws the exception.
55+
unsafe {
56+
core::arch::asm!(
57+
".tagtype __cpp_exception i32",
58+
".globl __cpp_exception",
59+
".weak __cpp_exception",
60+
"local.get {ex}",
61+
"throw __cpp_exception",
62+
ex = in(local) ex,
63+
options(may_unwind, noreturn, nostack),
64+
);
65+
}
5166
}
5267

5368
#[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)