Link the Wasm EH runtime under -fwasm-exceptions without requiring C++ - #27496
Link the Wasm EH runtime under -fwasm-exceptions without requiring C++#27496guybedford wants to merge 1 commit into
Conversation
|
Is this really needed? Rust with wasm eh has been working, so if it's needed it should be fixing a regression. |
Oh I see. This is pretty confusing because what does it mean for the linker? |
sbc100
left a comment
There was a problem hiding this comment.
How does this work on other platforms? Does rust use exception thrown/catching without linking libc++abi there? Does rust use clang (not clang++) during linking?
Yes and yes. rustc hardcodes Comment made with AI assistance |
|
I see. I hadn't realized that libunwind was not a C++ specific thing. I was able to reproduce this using my desktop clang: |
Extract `_Unwind_*` functions and `uncaughtExceptionCount` / `exceptionLast` JS state from libcore.js and libexceptions.js into a dedicated `libunwind.js`. This new libunwind.js is included as long as wasm EH is not being used. Also, invert the dependency between `__cxa_throw` and `_Unwind_RaiseException` so that `__cxa_throw` now calls `_Unwind_RaiseException` rather than the other way around. This is important as it allows C programs (or rather non-C++ programs like Rust) to call `_Unwind_RaiseException` without linking as C++. Inspired by emscripten-core#27496
Extract `_Unwind_*` functions and `uncaughtExceptionCount` / `exceptionLast` JS state from libcore.js and libexceptions.js into a dedicated `libunwind.js`. This new libunwind.js is included as long as wasm EH is not being used. Also, invert the dependency between `__cxa_throw` and `_Unwind_RaiseException` so that `__cxa_throw` now calls `_Unwind_RaiseException` rather than the other way around. This is important as it allows C programs (or rather non-C++ programs like Rust) to call `_Unwind_RaiseException` without linking as C++. Inspired by emscripten-core#27496
Extract `_Unwind_*` functions and `uncaughtExceptionCount` / `exceptionLast` JS state from libcore.js and libexceptions.js into a dedicated `libunwind.js`. This new libunwind.js is included as long as wasm EH is not being used. Also, invert the dependency between `__cxa_throw` and `_Unwind_RaiseException` so that `__cxa_throw` now calls `_Unwind_RaiseException` rather than the other way around. This is important as it allows C programs (or rather non-C++ programs like Rust) to call `_Unwind_RaiseException` without linking as C++. Inspired by emscripten-core#27496
Extract `_Unwind_*` functions and `uncaughtExceptionCount` / `exceptionLast` JS state from libcore.js and libexceptions.js into a dedicated `libunwind.js`. This new libunwind.js is included as long as wasm EH is not being used. Also, invert the dependency between `__cxa_throw` and `_Unwind_RaiseException` so that `__cxa_throw` now calls `_Unwind_RaiseException` rather than the other way around. This is important as it allows C programs (or rather non-C++ programs like Rust) to call `_Unwind_RaiseException` without linking as C++. Inspired by emscripten-core#27496
Extract `_Unwind_*` functions and `uncaughtExceptionCount` / `exceptionLast` JS state from libcore.js and libexceptions.js into a dedicated `libunwind.js`. This new libunwind.js is included as long as wasm EH is not being used. Also, invert the dependency between `__cxa_throw` and `_Unwind_RaiseException` so that `__cxa_throw` now calls `_Unwind_RaiseException` rather than the other way around. This is important as it allows C programs (or rather non-C++ programs like Rust) to call `_Unwind_RaiseException` without linking as C++. Inspired by emscripten-core#27496
Extract `_Unwind_*` functions and `uncaughtExceptionCount` / `exceptionLast` JS state from libcore.js and libexceptions.js into a dedicated `libunwind.js`. This new libunwind.js is included as long as wasm EH is not being used. Also, invert the dependency between `__cxa_throw` and `_Unwind_RaiseException` so that `__cxa_throw` now calls `_Unwind_RaiseException` rather than the other way around. This is important as it allows C programs (or rather non-C++ programs like Rust) to call `_Unwind_RaiseException` without linking as C++. Inspired by emscripten-core#27496
Extract `_Unwind_*` functions and `uncaughtExceptionCount` / `exceptionLast` JS state from libcore.js and libexceptions.js into a dedicated `libunwind.js`. This new libunwind.js is included as long as wasm EH is not being used. Also, invert the dependency between `__cxa_throw` and `_Unwind_RaiseException` so that `__cxa_throw` now calls `_Unwind_RaiseException` rather than the other way around. This is important as it allows C programs (or rather non-C++ programs like Rust) to call `_Unwind_RaiseException` without linking as C++. Inspired by emscripten-core#27496
d728e2b to
778e804
Compare
Extract `_Unwind_*` functions and `uncaughtExceptionCount` / `exceptionLast` JS state from libcore.js and libexceptions.js into a dedicated `libunwind.js`. This new libunwind.js is included as long as wasm EH is not being used. Also, invert the dependency between `__cxa_throw` and `_Unwind_RaiseException` so that `__cxa_throw` now calls `_Unwind_RaiseException` rather than the other way around. This is important as it allows C programs (or rather non-C++ programs like Rust) to call `_Unwind_RaiseException` without linking as C++. Inspired by emscripten-core#27496
382bb6d to
43189b4
Compare
Extract `_Unwind_*` functions and `uncaughtExceptionCount` / `exceptionLast` JS state from libcore.js and libexceptions.js into a dedicated `libunwind.js`. This new libunwind.js is included as long as wasm EH is not being used. Also, invert the dependency between `__cxa_throw` and `_Unwind_RaiseException` so that `__cxa_throw` now calls `_Unwind_RaiseException` rather than the other way around. This is important as it allows C programs (or rather non-C++ programs like Rust) to call `_Unwind_RaiseException` without linking as C++. Inspired by emscripten-core#27496
…eption` (#27498) It turns out the libunwind symbols are supposed to always be available, enen non-C++ programs. This means that `__cxa_throw` should be implemented in terms of `_Unwind_RaiseException` and not the other way around. - Moves the libunwind code into a new libunwind.js file (only use for Emscripten EH). - Add support for `_Unwind_Resume` - Implement `__cxa_throw` and other exception-handling APIs in terms of the lower level `_Unwind` API. Inspired by #27496
43189b4 to
9238f70
Compare
| # unwinding runtime and the `__cpp_exception` tag it defines are linked | ||
| # independently of C++. When WASM_EXCEPTIONS is not enabled, `_Unwind_*` | ||
| # symbols are instead provided by JS stubs in libcore.js (under | ||
| # LINK_AS_CXX). |
There was a problem hiding this comment.
I think this full comment is no longer needed. libunwind should always be linked into all programs one or another. I should have known that before.
How about just:
`libunwind` is implement in JS, and not nativly, when Emscripten EH is used.
| - `-fwasm-exceptions` now links the Wasm EH runtime (libunwind and the | ||
| `__cpp_exception` tag) independently of C++ linking, so Wasm EH objects from | ||
| non-C++ frontends (e.g. rustc, which links via `emcc`) link without | ||
| requiring `em++` or `-sDEFAULT_TO_CXX`. |
| # independently of C++. When WASM_EXCEPTIONS is not enabled, `_Unwind_*` | ||
| # symbols are instead provided by JS stubs in libcore.js (under | ||
| # LINK_AS_CXX). |
There was a problem hiding this comment.
Does this mean we need LINK_AS_CXX in case of Emscripten EH? This sounds weird. If LINK_AS_CXX should not be required for linking linbunwind in Wasm EH, shouldn't that be true also for Emscripten EH too?
| 'exceptions': (['-fexceptions'],), | ||
| 'wasm_eh': (['-fwasm-exceptions'],), | ||
| 'wasm_legacy_eh': (['-fwasm-exceptions', '-sWASM_LEGACY_EXCEPTIONS'],), |
There was a problem hiding this comment.
Can we use @with_all_eh_sjlj instead of this?
This makes
-fwasm-exceptionslink the Wasm EH runtime independently of C++ linking.Wasm EH objects can be produced by non-C++ frontends - notably rustc, whose precompiled std uses Wasm exceptions for unwinding and which invokes
emcc(notem++) as its linker. SinceDEFAULT_TO_CXXwas disabled by default in #27469, any rust-driven emcc link now fails with:because both libunwind and the
__cpp_exceptiontag (previously defined in libc++abi) were only linked underLINK_AS_CXX. The tag and the unwinding runtime are language-agnostic runtime support for the Wasm EH LLVM lowering, not part of the C++ ABI surface.This PR now includes #27498 as its base, which provides the same
_Unwind_*linkability for the non-Wasm-EH modes on the JS side.What's implemented:
__cpp_exceptiontag definition moves from libc++abi (__cpp_exception.S) into libunwind'sUnwind-wasm.cas inline asm, matching upstream [WebAssembly] Move __cpp_exception to libunwind llvm/llvm-project#185770.WASM_EXCEPTIONSis enabled, rather than only when linking as C++.Test coverage extends
test_libunwindfrom #27498 withwasm_ehandwasm_legacy_ehvariants (completing its TODO), and addstest_cpp_exception_taglinking an asm object that throws the tag directly from a C caller - the same reference pattern as rustc-generated catch/throw sites - which fails to link without this change. The now-unneededDEFAULT_TO_CXXworkaround is dropped fromtest_wasi_with_sjlj. Existing C++ Wasm EH coverage (core0.test_exceptions_*) passes unchanged.Made with AI assistance under my review