Skip to content

Commit aba07b5

Browse files
authored
[EH] Use _UA_SEARCH_PHASE in personality function (NFC) (#17991)
In two-phase unwinding, the first phase is the search phase (`_UA_SEARCH_PHASE`) and the second one is the cleanup phase (`_UA_CLEANUP_PHASE`). The search phase searches up the stack to see if there is a matching catch handler, and if it finds one, it caches the result. And in the second cleanup phase, it retrieves the cached result (to avoid doing same work twice) and unwinds the stack. Wasm does not do the two-phase unwinding; it only has a single phase. We used `_UA_CLEANUP_PHASE` for this single phase, so in Wasm the cleanup phase is supposed to the search. So we several many custom `#ifdef`s to use the code guarded by `_UA_SEARCH_PHASE`, for example: https://github.com/aheejin/emscripten/blob/d57db5bea1719319a680699c50b91fa3d88fa0ec/system/lib/libcxxabi/src/cxa_personality.cpp#L771-L776 https://github.com/aheejin/emscripten/blob/d57db5bea1719319a680699c50b91fa3d88fa0ec/system/lib/libcxxabi/src/cxa_personality.cpp#L850-L855 These are apparently gone in #14288, which replaced many `if`s with `assert`s. This in effect removed our special handling for `_UA_CLEANUP_PHASE`; there are several `assert`s that asserts the current phase is `_UA_SEARCH_PHASE`, while Wasm is in `_UA_CLEANUP_PHASE`. But this has not caused problems so far because we have built libc++abi with `-NDEBUG`, so all assertions were no-op. https://github.com/emscripten-core/emscripten/blob/40fb7d2071e439f1de614898b88518df582faa94/tools/system_libs.py#L1366 But this is now a problem because #17979 adds a debug build of libc++abi, which enables assertions. Come to think of it, I'm not sure why I decided to use `_UA_CLEANUP_PHASE` for our single phase in the first place. If we use `_UA_SEARCH_PHASE`, we can remove more our custom code and reduce the difference between our port and the upstream library.
1 parent 7751ba7 commit aba07b5

File tree

2 files changed

+8
-11
lines changed

2 files changed

+8
-11
lines changed

system/lib/libcxxabi/src/cxa_personality.cpp

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -798,6 +798,8 @@ static void scan_eh_tab(scan_results &results, _Unwind_Action actions,
798798
{
799799
// Native exception caught by exception
800800
// specification.
801+
assert(actions & _UA_SEARCH_PHASE);
802+
results.ttypeIndex = ttypeIndex;
801803
results.actionRecord = actionRecord;
802804
results.adjustedPtr = adjustedPtr;
803805
results.reason = _URC_HANDLER_FOUND;
@@ -964,6 +966,11 @@ __gxx_personality_v0
964966
exc->languageSpecificData = results.languageSpecificData;
965967
exc->catchTemp = reinterpret_cast<void*>(results.landingPad);
966968
exc->adjustedPtr = results.adjustedPtr;
969+
#ifdef __USING_WASM_EXCEPTIONS__
970+
// Wasm only uses a single phase (_UA_SEARCH_PHASE), so save the
971+
// results here.
972+
set_registers(unwind_exception, context, results);
973+
#endif
967974
}
968975
return _URC_HANDLER_FOUND;
969976
}
@@ -981,16 +988,6 @@ __gxx_personality_v0
981988
exception_header->catchTemp = 0;
982989
#endif
983990
}
984-
#ifdef __USING_WASM_EXCEPTIONS__
985-
// Wasm uses only one phase in _UA_CLEANUP_PHASE, so we should set
986-
// these here.
987-
__cxa_exception* exception_header = (__cxa_exception*)(unwind_exception+1) - 1;
988-
exception_header->handlerSwitchValue = static_cast<int>(results.ttypeIndex);
989-
exception_header->actionRecord = results.actionRecord;
990-
exception_header->languageSpecificData = results.languageSpecificData;
991-
exception_header->catchTemp = reinterpret_cast<void*>(results.landingPad);
992-
exception_header->adjustedPtr = results.adjustedPtr;
993-
#endif
994991
return _URC_INSTALL_CONTEXT;
995992
}
996993

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ _Unwind_Reason_Code _Unwind_CallPersonality(void *exception_ptr) {
4242
// Call personality function. Wasm does not have two-phase unwinding, so we
4343
// only do the cleanup phase.
4444
_Unwind_Reason_Code ret = __gxx_personality_wasm0(
45-
1, _UA_CLEANUP_PHASE, exception_object->exception_class, exception_object,
45+
1, _UA_SEARCH_PHASE, exception_object->exception_class, exception_object,
4646
(struct _Unwind_Context *)&__wasm_lpad_context);
4747
return ret;
4848
}

0 commit comments

Comments
 (0)