https://github.com/alexcrichton created https://github.com/llvm/llvm-project/pull/185770
This commit is an extension of some work in [wasi-sdk] to get C++ exceptions working on WASI targets. This is intended to complement the work in #168449 and together is enough to get C++ exceptions working within wasi-sdk. The changes here are: * The `__cpp_exception` symbol is now defined in libunwind instead of compiler-rt. This is moved for a few reasons, but the primary reason is that compiler-rt is linked duplicate-ly into all shared objects meaning that it's not suitable for define-once symbols such as `__cpp_exception`. By moving the definition to the user of the symbol, libunwind itself, that guarantees that the symbol should be defined exactly once and only when appropriate. A secondary reason for this movement is that it avoids the need to compile compiler-rt twice: once with exception and once without, and instead the same build can be used for both exceptions-and-not. * A minor compile error is fixed in libunwind's `assembly.h`. Without this the preexisting sources fail to compile, so this is along the lines of #168449 in terms of getting the in-tree sources to compile for wasm exceptions. >From 2540fb82dd5d0d2d8e09baa6ee437eeef1004276 Mon Sep 17 00:00:00 2001 From: Alex Crichton <[email protected]> Date: Tue, 10 Mar 2026 15:49:55 -0700 Subject: [PATCH] Fix compiling/using libunwind for wasm targets This commit is an extension of some work in [wasi-sdk] to get C++ exceptions working on WASI targets. This is intended to complement the work in #168449 and together is enough to get C++ exceptions working within wasi-sdk. The changes here are: * The `__cpp_exception` symbol is now defined in libunwind instead of compiler-rt. This is moved for a few reasons, but the primary reason is that compiler-rt is linked duplicate-ly into all shared objects meaning that it's not suitable for define-once symbols such as `__cpp_exception`. By moving the definition to the user of the symbol, libunwind itself, that guarantees that the symbol should be defined exactly once and only when appropriate. A secondary reason for this movement is that it avoids the need to compile compiler-rt twice: once with exception and once without, and instead the same build can be used for both exceptions-and-not. * A minor compile error is fixed in libunwind's `assembly.h`. Without this the preexisting sources fail to compile, so this is along the lines of #168449 in terms of getting the in-tree sources to compile for wasm exceptions. --- compiler-rt/lib/builtins/CMakeLists.txt | 1 - .../lib/builtins/wasm/__cpp_exception.S | 26 ------------------- libunwind/src/Unwind-wasm.c | 17 ++++++++++++ libunwind/src/assembly.h | 3 +++ .../compiler-rt/lib/builtins/sources.gni | 1 - 5 files changed, 20 insertions(+), 28 deletions(-) delete mode 100644 compiler-rt/lib/builtins/wasm/__cpp_exception.S diff --git a/compiler-rt/lib/builtins/CMakeLists.txt b/compiler-rt/lib/builtins/CMakeLists.txt index 6c27f6d4d529e..f0570a9092f40 100644 --- a/compiler-rt/lib/builtins/CMakeLists.txt +++ b/compiler-rt/lib/builtins/CMakeLists.txt @@ -891,7 +891,6 @@ set(s390x_SOURCES set(wasm_SOURCES wasm/__c_longjmp.S - wasm/__cpp_exception.S ${GENERIC_TF_SOURCES} ${GENERIC_SOURCES} ) diff --git a/compiler-rt/lib/builtins/wasm/__cpp_exception.S b/compiler-rt/lib/builtins/wasm/__cpp_exception.S deleted file mode 100644 index 0496e1dbf6158..0000000000000 --- a/compiler-rt/lib/builtins/wasm/__cpp_exception.S +++ /dev/null @@ -1,26 +0,0 @@ -//===-- __cpp_exception.S - Implement __cpp_exception ---------------------===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// -// -// This file implements __cpp_exception which LLVM uses to implement exception -// handling when Wasm EH is enabled. -// -//===----------------------------------------------------------------------===// - -#ifdef __wasm_exception_handling__ - -#ifdef __wasm64__ -#define PTR i64 -#else -#define PTR i32 -#endif - -.globl __cpp_exception -.tagtype __cpp_exception PTR -__cpp_exception: - -#endif // !__wasm_exception_handling__ diff --git a/libunwind/src/Unwind-wasm.c b/libunwind/src/Unwind-wasm.c index 2f4498c3f3989..44d284ba85b8f 100644 --- a/libunwind/src/Unwind-wasm.c +++ b/libunwind/src/Unwind-wasm.c @@ -69,6 +69,23 @@ _Unwind_RaiseException(_Unwind_Exception *exception_object) { __builtin_wasm_throw(0, exception_object); } +// Define the `__cpp_exception` symbol which `__builtin_wasm_throw` above will +// reference. This is defined here in `libunwind` as the single canonical +// definition for this API and it's required for users to ensure that there's +// only one copy of `libunwind` within a wasm module to ensure this is only +// defined once and exactly once. +__asm__( +".globl __cpp_exception\n" +#if defined(__wasm32__) +".tagtype __cpp_exception i32\n" +#elif defined(__wasm64__) +".tagtype __cpp_exception i64\n" +#else +# error "Unsupported Wasm architecture" +#endif +"__cpp_exception:\n" +); + /// Called by __cxa_end_catch. _LIBUNWIND_EXPORT void _Unwind_DeleteException(_Unwind_Exception *exception_object) { diff --git a/libunwind/src/assembly.h b/libunwind/src/assembly.h index 84c9d526f1d75..2167326605b8a 100644 --- a/libunwind/src/assembly.h +++ b/libunwind/src/assembly.h @@ -253,6 +253,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/llvm/utils/gn/secondary/compiler-rt/lib/builtins/sources.gni b/llvm/utils/gn/secondary/compiler-rt/lib/builtins/sources.gni index 2ac71aa8e8367..c9eeede16e3eb 100644 --- a/llvm/utils/gn/secondary/compiler-rt/lib/builtins/sources.gni +++ b/llvm/utils/gn/secondary/compiler-rt/lib/builtins/sources.gni @@ -539,7 +539,6 @@ if (current_cpu == "ve") { if (current_cpu == "wasm") { builtins_sources += [ "wasm/__c_longjmp.S", - "wasm/__cpp_exception.S", ] } _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
