Skip to content

Commit bd51081

Browse files
aheejinfredldotme
authored andcommitted
[libunwind][WebAssembly] Support Wasm EH
This adds Wasm-specific libunwind port to support Wasm exception handling (https://github.com/WebAssembly/exception-handling). Wasm EH requires `__USING_WASM_EXCEPTIONS__` to be defined. This adds `Unwind-wasm.c`, which defines libunwind APIs for Wasm. This also adds a `thread_local` struct of type `_Unwind_LandingPadContext`, which serves as a medium for input/output data between the user code and the personality function. How all these work is explained in https://github.com/WebAssembly/tool-conventions/blob/main/EHScheme.md. (The doc is old and "You Shouldn't Prune Unreachable Resumes" section doesn't apply anymore, but otherwise it should be good) The bulk of these changes was added back in Mar 2020 in emscripten-core/emscripten#10577 to emscripten repo and has been used ever since. Now we'd like to upstream this so that other toolchains that don't use emscripten libraries, e.g., WASI, can use this too. Companion patch: D158918 Reviewed By: dschuff, #libunwind, phosek Differential Revision: https://reviews.llvm.org/D158919
1 parent 9eaaf9c commit bd51081

File tree

2 files changed

+19
-10
lines changed

2 files changed

+19
-10
lines changed

libunwind/src/Unwind-wasm.c

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,21 @@
1-
#define NDEBUG
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//
8+
// Implements Wasm exception handling proposal
9+
// (https://github.com/WebAssembly/exception-handling) based C++ exceptions
10+
//
11+
//===----------------------------------------------------------------------===//
212

313
#include "config.h"
414
#include "unwind.h"
515
#include <stdbool.h>
616
#include <threads.h>
717

8-
#if 1 //def __USING_WASM_EXCEPTIONS__
18+
#ifdef __USING_WASM_EXCEPTIONS__
919

1020
_Unwind_Reason_Code __gxx_personality_wasm0(int version, _Unwind_Action actions,
1121
uint64_t exceptionClass,
@@ -43,17 +53,17 @@ _Unwind_Reason_Code _Unwind_CallPersonality(void *exception_ptr) {
4353

4454
// Call personality function. Wasm does not have two-phase unwinding, so we
4555
// only do the cleanup phase.
46-
_Unwind_Reason_Code ret = __gxx_personality_wasm0(
56+
return __gxx_personality_wasm0(
4757
1, _UA_SEARCH_PHASE, exception_object->exception_class, exception_object,
4858
(struct _Unwind_Context *)&__wasm_lpad_context);
49-
return ret;
5059
}
5160

5261
/// Called by __cxa_throw.
5362
_LIBUNWIND_EXPORT _Unwind_Reason_Code
5463
_Unwind_RaiseException(_Unwind_Exception *exception_object) {
5564
_LIBUNWIND_TRACE_API("_Unwind_RaiseException(exception_object=%p)",
5665
(void *)exception_object);
66+
// Use Wasm EH's 'throw' instruction.
5767
__builtin_wasm_throw(0, exception_object);
5868
}
5969

@@ -74,9 +84,8 @@ _LIBUNWIND_EXPORT void _Unwind_SetGR(struct _Unwind_Context *context, int index,
7484
(void *)context, index, value);
7585
// We only use this function to set __wasm_lpad_context.selector field, which
7686
// is index 1 in the personality function.
77-
if (index != 1)
78-
return;
79-
((struct _Unwind_LandingPadContext *)context)->selector = value;
87+
if (index == 1)
88+
((struct _Unwind_LandingPadContext *)context)->selector = value;
8089
}
8190

8291
/// Called by personality handler to get instruction pointer.
@@ -90,7 +99,7 @@ _LIBUNWIND_EXPORT uintptr_t _Unwind_GetIP(struct _Unwind_Context *context) {
9099
return result;
91100
}
92101

93-
/// Not used in wasm.
102+
/// Not used in Wasm.
94103
_LIBUNWIND_EXPORT void _Unwind_SetIP(struct _Unwind_Context *context,
95104
uintptr_t value) {}
96105

@@ -103,7 +112,7 @@ _Unwind_GetLanguageSpecificData(struct _Unwind_Context *context) {
103112
return result;
104113
}
105114

106-
/// Not used in wasm.
115+
/// Not used in Wasm.
107116
_LIBUNWIND_EXPORT uintptr_t
108117
_Unwind_GetRegionStart(struct _Unwind_Context *context) {
109118
return 0;

libunwind/src/config.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@
8585
__asm__(".globl " SYMBOL_NAME(aliasname)); \
8686
__asm__(SYMBOL_NAME(aliasname) " = " SYMBOL_NAME(name)); \
8787
_LIBUNWIND_ALIAS_VISIBILITY(SYMBOL_NAME(aliasname))
88-
#elif defined(__ELF__) || defined(_AIX)
88+
#elif defined(__ELF__) || defined(_AIX) || defined(__wasm__)
8989
#define _LIBUNWIND_WEAK_ALIAS(name, aliasname) \
9090
extern "C" _LIBUNWIND_EXPORT __typeof(name) aliasname \
9191
__attribute__((weak, alias(#name)));

0 commit comments

Comments
 (0)