-
Notifications
You must be signed in to change notification settings - Fork 14k
Use inline asm rather than llvm intrinsic for panics on wasm #149141
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
|
rustbot has assigned @Mark-Simulacrum. Use |
|
Helps with #148533 (comment). cc @purplesyringa |
|
Hmm. Doesn't inline asm need to be accounted for in Otherwise, this looks like the best way forward. |
|
Indeed. It we forgot to handle inline asm in that function. Pushed a commit to fix that. |
|
That looks good, thanks! |
|
Some changes occurred to MIR optimizations cc @rust-lang/wg-mir-opt |
This way we don't have to support unwinding llvm intrinsics in the codegen backends.
This is required for the soundness of options(may_unwind)
73c5f1c to
730c764
Compare
library/unwind/src/wasm.rs
Outdated
| } | ||
| } | ||
|
|
||
| #[any(not(target_os = "emscripten"), emscripten_wasm_eh)] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Isn't emscripten considered unix? cfg_select! in the root of the unwind crate prefers a libunwind-based implementation over wasm for unix targets, so this check doesn't look like it can ever fail.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Indeed. Removed this commit again.
In preparation for changes in rust-lang/rust#149141.
730c764 to
2754e75
Compare
In preparation for changes in rust-lang/rust#149141.
In preparation for changes in rust-lang/rust#149141.
|
I copied the |
|
Ah, I see. It seems like This bug can also only be reproduced with a high Also, this only fails on wasip1 for some reason, but not Emscripten. (Yes, I know EH on wasip1 is not supported, but that shouldn't affect codegen at this point.) Not sure if that's due to random chance or something else. |
|
This seems to work for me: diff --git a/src/backend/itanium.rs b/src/backend/itanium.rs
index 8a20236..40ed67f 100644
--- a/src/backend/itanium.rs
+++ b/src/backend/itanium.rs
@@ -173,6 +173,7 @@ unsafe fn _Unwind_RaiseException(ex: *mut u8) -> ! {
unsafe {
core::arch::asm!(
".tagtype __cpp_exception i32",
+ ".globl __cpp_exception",
"local.get {ex}",
"throw __cpp_exception",
ex = in(local) ex,
diff --git a/src/backend/wasm.rs b/src/backend/wasm.rs
index 698af54..dfea843 100644
--- a/src/backend/wasm.rs
+++ b/src/backend/wasm.rs
@@ -55,6 +55,7 @@ unsafe fn throw(ex: *mut u8) -> ! {
unsafe {
core::arch::asm!(
".tagtype __cpp_exception i32",
+ ".globl __cpp_exception",
"local.get {ex}",
"throw __cpp_exception",
ex = in(local) ex, |
|
But if I also do that in libunwind, I get |
|
LLVM has this code: void WasmException::endModule() {
// These are symbols used to throw/catch C++ exceptions and C longjmps. These
// symbols have to be emitted somewhere once in the module. Check if each of
// the symbols has already been created, i.e., we have at least one 'throw' or
// 'catch' instruction with the symbol in the module, and emit the symbol only
// if so.
//
// But in dynamic linking, it is in general not possible to come up with a
// module instantiating order in which tag-defining modules are loaded before
// the importing modules. So we make them undefined symbols here, define tags
// in the JS side, and feed them to each importing module.
if (!Asm->isPositionIndependent()) {
for (const char *SymName : {"__cpp_exception", "__c_longjmp"}) {
SmallString<60> NameStr;
Mangler::getNameWithPrefix(NameStr, SymName, Asm->getDataLayout());
if (Asm->OutContext.lookupSymbol(NameStr)) {
MCSymbol *ExceptionSym = Asm->GetExternalSymbolSymbol(SymName);
Asm->OutStreamer->emitLabel(ExceptionSym);
}
}
}
}...so I'm assuming the difference can be chalked up to the default |
|
Looking at the wasm object generated with |
In preparation for changes in rust-lang/rust#149141.
|
Seems to work on my side on the current |
3b13aa0 to
9bb90f3
Compare
In preparation for changes in rust-lang/rust#149141.
|
I meant to mark it as both
For emscripten dynamic linking we should be emitting a true import and not a weak definition I think. |
|
Yeah, I forgot how symbols worked and thought I tried to confirm that dynamic linking requires a true import, but I'm not sure how to do that. I mean that makes sense, but the error looks odd: I am defining the symbol, after all, even if weak, so it's not clear why it's considered undefined. I feel like I'm missing something. Is this something I need to handle in Lithium alone, or should this be taken into consideration for |
|
Is this connected to mangling in some way? As far as I can see, |
This way we don't have to support unwinding llvm intrinsics in the codegen backends.