Skip to content

Commit d212b13

Browse files
authored
[EH] Apply Call EH personality fix from LLVM (emscripten-core#27445)
After llvm/llvm-project#209282, the user code calls a personality function instead of `Unwind_CallPersonality`. It also changed the signature of Wasm personality function. It had both code generation and library changes, but now our waterfall picks up the codegen changes but our libraries are still from the last release. This applies llvm/llvm-project#209282 library side patch here as well. This kind of change is rare enough so I don't think we necessary should follow LLVM tot for libunwind, unless we decide to do that broadly for all LLVM libraries. Also this adds `system/lib/libunwind/include` to libcxx's `includes` directory. Turns out so far we have been including Clang's default `unwind.h` and it was OK but now we need to include the correct file. This temporarily skips all Wasm EH tests to make the LLVM roll land. They will be reenabled once the roll lands. Fixes emscripten-core#27442.
1 parent 8682166 commit d212b13

6 files changed

Lines changed: 52 additions & 44 deletions

File tree

system/lib/libcxxabi/src/cxa_personality.cpp

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1021,9 +1021,7 @@ static inline void get_landing_pad(__cxa_catch_temp_type &dest,
10211021
#endif
10221022
}
10231023

1024-
#ifdef __WASM_EXCEPTIONS__
1025-
_Unwind_Reason_Code __gxx_personality_wasm0
1026-
#elif defined(__SEH__) && !defined(__USING_SJLJ_EXCEPTIONS__)
1024+
#if (defined(__SEH__) && !defined(__USING_SJLJ_EXCEPTIONS__)) || defined(__WASM_EXCEPTIONS__)
10271025
static _Unwind_Reason_Code __gxx_personality_imp
10281026
#else
10291027
_LIBCXXABI_FUNC_VIS _Unwind_Reason_Code
@@ -1124,6 +1122,20 @@ __gxx_personality_seh0(PEXCEPTION_RECORD ms_exc, void *this_frame,
11241122
}
11251123
#endif
11261124

1125+
#ifdef __WASM_EXCEPTIONS__
1126+
extern "C" _LIBCXXABI_FUNC_VIS _Unwind_Reason_Code __gxx_wasm_personality_v0(void* exception_ptr) {
1127+
struct _Unwind_Exception* exception_object = (struct _Unwind_Exception*)exception_ptr;
1128+
1129+
// Reset the selector.
1130+
__wasm_lpad_context.selector = 0;
1131+
1132+
// Call personality function. Wasm does not have two-phase unwinding, so we
1133+
// only do the search phase.
1134+
return __gxx_personality_imp(1, _UA_SEARCH_PHASE, exception_object->exception_class, exception_object,
1135+
(struct _Unwind_Context*)&__wasm_lpad_context);
1136+
}
1137+
#endif
1138+
11271139
#else
11281140

11291141
// Helper function to unwind one frame.

system/lib/libunwind/include/unwind.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,10 @@ typedef struct _Unwind_Context _Unwind_Context; // opaque
6161
#include <unwind_itanium.h>
6262
#endif
6363

64+
#if defined(__WASM_EXCEPTIONS__)
65+
#include <unwind_wasm.h>
66+
#endif
67+
6468
typedef _Unwind_Reason_Code (*_Unwind_Stop_Fn)
6569
(int version,
6670
_Unwind_Action actions,
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
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+
9+
#ifndef __WASM_UNWIND_H__
10+
#define __WASM_UNWIND_H__
11+
12+
#include <threads.h>
13+
14+
struct _Unwind_LandingPadContext {
15+
// Input information to personality function
16+
uintptr_t lpad_index; // landing pad index
17+
uintptr_t lsda; // LSDA address
18+
19+
// Output information computed by personality function
20+
uintptr_t selector; // selector value
21+
};
22+
23+
// Communication channel between compiler-generated user code and personality
24+
// function
25+
extern thread_local struct _Unwind_LandingPadContext __wasm_lpad_context;
26+
27+
#endif // __WASM_UNWIND_H__

system/lib/libunwind/src/Unwind-wasm.c

Lines changed: 2 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -19,46 +19,8 @@
1919
#include "unwind.h"
2020
#include <threads.h>
2121

22-
_Unwind_Reason_Code __gxx_personality_wasm0(int version, _Unwind_Action actions,
23-
uint64_t exceptionClass,
24-
_Unwind_Exception *unwind_exception,
25-
_Unwind_Context *context);
26-
27-
struct _Unwind_LandingPadContext {
28-
// Input information to personality function
29-
uintptr_t lpad_index; // landing pad index
30-
uintptr_t lsda; // LSDA address
31-
32-
// Output information computed by personality function
33-
uintptr_t selector; // selector value
34-
};
35-
36-
// Communication channel between compiler-generated user code and personality
37-
// function
38-
thread_local struct _Unwind_LandingPadContext __wasm_lpad_context;
39-
40-
/// Calls to this function are in landing pads in compiler-generated user code.
41-
/// In other EH schemes, stack unwinding is done by libunwind library, which
42-
/// calls the personality function for each frame it lands. On the other hand,
43-
/// WebAssembly stack unwinding process is performed by a VM, and the
44-
/// personality function cannot be called from there. So the compiler inserts a
45-
/// call to this function in landing pads in the user code, which in turn calls
46-
/// the personality function.
47-
_Unwind_Reason_Code _Unwind_CallPersonality(void *exception_ptr) {
48-
struct _Unwind_Exception *exception_object =
49-
(struct _Unwind_Exception *)exception_ptr;
50-
_LIBUNWIND_TRACE_API("_Unwind_CallPersonality(exception_object=%p)",
51-
(void *)exception_object);
52-
53-
// Reset the selector.
54-
__wasm_lpad_context.selector = 0;
55-
56-
// Call personality function. Wasm does not have two-phase unwinding, so we
57-
// only do the cleanup phase.
58-
return __gxx_personality_wasm0(
59-
1, _UA_SEARCH_PHASE, exception_object->exception_class, exception_object,
60-
(struct _Unwind_Context *)&__wasm_lpad_context);
61-
}
22+
_LIBUNWIND_EXPORT thread_local struct _Unwind_LandingPadContext
23+
__wasm_lpad_context;
6224

6325
/// Called by __cxa_throw.
6426
_LIBUNWIND_EXPORT _Unwind_Reason_Code

test/decorators.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -579,6 +579,9 @@ def metafunc(self, mode, *args, **kwargs):
579579
if DEBUG:
580580
print('parameterize:eh_mode=%s' % mode)
581581
if mode in {'wasm', 'wasm_legacy'}:
582+
# FIXME Remove this after
583+
# https://github.com/emscripten-core/emscripten/issues/27442 is fixed
584+
self.skipTest('https://github.com/emscripten-core/emscripten/issues/27442')
582585
# Wasm EH is currently supported only in wasm backend and V8
583586
if self.is_wasm2js():
584587
self.skipTest('wasm2js does not support wasm EH/SjLj')

tools/system_libs.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1644,7 +1644,7 @@ class libcxxabi(ExceptionLibrary, MTLibrary, DebugLibrary):
16441644
'-std=c++23',
16451645
'-Wno-unused-but-set-variable',
16461646
]
1647-
includes = ['system/lib/libcxx/src']
1647+
includes = ['system/lib/libcxx/src', 'system/lib/libunwind/include']
16481648

16491649
def __init__(self, **kwargs):
16501650
super().__init__(**kwargs)

0 commit comments

Comments
 (0)