mirror of https://github.com/WebAssembly/wasi-sdk
Add experimental support for C++ exceptions (#590)
> **Note**: this PR is me weaving together the work of many others. For example @yerzham's and @cpetig's work on #565 pretty much shaped this PR. Thank you! This commit adds initial configuration support for building wasi-sdk with support for C++ exceptions in WebAssembly. A small test is included which is exercised in CI at this time, but otherwise this does not update CI to actually ship sdk builds with C++ exceptions enabled. Instead the intention here is to make it easier to test builds with support for C++ exceptions and centralize planning/development around this. The goal here is to get things compiling to the point that applications can be compiled. I haven't thoroughly tested C++ exceptions and as evident in this PR it still requires changes in LLVM. Some small logic is added here to apply a `*.patch` file to LLVM to avoid needing a new submodule fork or waiting for upstream changes. The intention is that this `*.patch` is short-lived once the changes are officially merged into LLVM itself. The `*.patch` included here contains llvm/llvm-project#168449 as well as another minor edit I found was necessary to get things compiling locally. Given the discussion on that PR it looks like once LLVM is updated with that merged the extra part of the `*.patch` won't be necessary. This PR notably does not enable shared libraries when exceptions are enabled. I don't know enough about how things are supposed to work to be able to fully diagnose the compilation errors I'm seeing if shared libraries are enabled. This is something I'd hope would be fixed before actually shipping exceptions support. This PR then additionally folds in [this gist][gist] for various bits of build logic to this repository itself. Finally, this PR includes some documentation about the current status of exceptions and links to various tracking issues too. [gist]: https://gist.github.com/yerzham/302efcec6a2e82c1e8de4aed576ea29dpull/592/head
parent
3d4ea12dbe
commit
372ba0d222
@ -0,0 +1,60 @@
|
||||
# Support for C++ Exceptions
|
||||
|
||||
The released artifacts for wasi-sdk at this time do not support C++ exceptions.
|
||||
LLVM and Clang, however, have support for C++ exceptions in WebAssembly and this
|
||||
is intended to serve as documentation of the current state of affairs of using
|
||||
C++ exceptions. It should be noted though that the current status of C++
|
||||
exceptions support is not intended to be the final state of support, and this is
|
||||
all continuing to be iterated on over time.
|
||||
|
||||
## Building wasi-sdk with exceptions
|
||||
|
||||
When building the sysroot with wasi-sdk you can pass `-DWASI_SDK_EXCEPTIONS=ON`
|
||||
to enable support for C++ exceptions. For example:
|
||||
|
||||
```shell script
|
||||
$ cmake -G Ninja -B build/sysroot -S . \
|
||||
-DCMAKE_TOOLCHAIN_FILE=$path/to/wasi-sdk-p1.cmake \
|
||||
-DWASI_SDK_EXCEPTIONS=ON
|
||||
```
|
||||
|
||||
The C++ standard library will be compiled with support for exceptions for the
|
||||
desired targets and the resulting sysroot supports using exceptions.
|
||||
|
||||
## Compiling code with C++ exceptions
|
||||
|
||||
Currently extra compilation flags are required to fully support C++ exceptions.
|
||||
Without these flags programs using C++ exceptions will not work correctly:
|
||||
|
||||
* `-fwasm-exceptions` - needed to enable the WebAssembly exception-handling
|
||||
proposal.
|
||||
* `-mllvm -wasm-use-legacy-eh=false` - indicates that the standard WebAssembly
|
||||
exception-handling instructions should be used.
|
||||
* `-lunwind` - links in support for unwinding which C++ exceptions requires.
|
||||
|
||||
This can be specified for example with:
|
||||
|
||||
```shell script
|
||||
$ export CFLAGS="-fwasm-exceptions -mllvm -wasm-use-legacy-eh=false"
|
||||
$ export LDFLAGS="-lunwind"
|
||||
```
|
||||
|
||||
## Limitations
|
||||
|
||||
Currently C++ exceptions support in wasi-sdk does not support shared libraries.
|
||||
Fixing this will require resolving some miscellaneous build issues in this
|
||||
repository itself.
|
||||
|
||||
## Future Plans
|
||||
|
||||
There are a few tracking issues with historical discussion about C++ exceptions
|
||||
support in wasi-sdk such as [#334](https://github.com/WebAssembly/wasi-sdk/issues/334)
|
||||
and [#565](https://github.com/WebAssembly/wasi-sdk/issues/565). The major
|
||||
remaining items are:
|
||||
|
||||
* Figure out support for shared libraries.
|
||||
* Determine how to ship a sysroot that supports both with-and-without
|
||||
exceptions.
|
||||
* Figure out how to avoid the need for extra compiler flags when using
|
||||
exceptions.
|
||||
* Figure out if a new wasm target is warranted.
|
||||
@ -0,0 +1,28 @@
|
||||
diff --git a/libunwind/src/assembly.h b/libunwind/src/assembly.h
|
||||
index f8e83e138eff..c5097d25b0c6 100644
|
||||
--- a/libunwind/src/assembly.h
|
||||
+++ b/libunwind/src/assembly.h
|
||||
@@ -249,6 +249,9 @@ aliasname: \
|
||||
#define WEAK_ALIAS(name, aliasname)
|
||||
#define NO_EXEC_STACK_DIRECTIVE
|
||||
|
||||
+#elif defined(__wasm__)
|
||||
+#define NO_EXEC_STACK_DIRECTIVE
|
||||
+
|
||||
// clang-format on
|
||||
#else
|
||||
|
||||
diff --git a/libunwind/src/config.h b/libunwind/src/config.h
|
||||
index deb5a4d4d73d..23c9f012cbcf 100644
|
||||
--- a/libunwind/src/config.h
|
||||
+++ b/libunwind/src/config.h
|
||||
@@ -66,7 +66,8 @@
|
||||
#define _LIBUNWIND_EXPORT
|
||||
#define _LIBUNWIND_HIDDEN
|
||||
#else
|
||||
- #if !defined(__ELF__) && !defined(__MACH__) && !defined(_AIX)
|
||||
+ #if !defined(__ELF__) && !defined(__MACH__) && !defined(_AIX) && \
|
||||
+ !defined(__wasm__)
|
||||
#define _LIBUNWIND_EXPORT __declspec(dllexport)
|
||||
#define _LIBUNWIND_HIDDEN
|
||||
#else
|
||||
@ -0,0 +1,17 @@
|
||||
#include <iostream>
|
||||
#include <stdlib.h>
|
||||
|
||||
int main() {
|
||||
#ifdef __wasm_exception_handling__
|
||||
try {
|
||||
throw std::runtime_error("An error occurred");
|
||||
abort();
|
||||
} catch (const std::runtime_error& e) {
|
||||
// ..
|
||||
return 0;
|
||||
}
|
||||
abort();
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
Loading…
Reference in new issue