diff --git a/libcxxabi/include/cxxabi.h b/libcxxabi/include/cxxabi.h --- a/libcxxabi/include/cxxabi.h +++ b/libcxxabi/include/cxxabi.h @@ -47,7 +47,12 @@ // 2.4.3 Throwing the Exception Object extern _LIBCXXABI_FUNC_VIS _LIBCXXABI_NORETURN void __cxa_throw(void *thrown_exception, std::type_info *tinfo, +#ifdef __USING_WASM_EXCEPTIONS__ + // In Wasm, a destructor returns its argument + void *(_LIBCXXABI_DTOR_FUNC *dest)(void *)); +#else void (_LIBCXXABI_DTOR_FUNC *dest)(void *)); +#endif // 2.5.3 Exception Handlers extern _LIBCXXABI_FUNC_VIS void * diff --git a/libcxxabi/src/cxa_exception.h b/libcxxabi/src/cxa_exception.h --- a/libcxxabi/src/cxa_exception.h +++ b/libcxxabi/src/cxa_exception.h @@ -43,7 +43,12 @@ // Manage the exception object itself. std::type_info *exceptionType; +#ifdef __USING_WASM_EXCEPTIONS__ + // In Wasm, a destructor returns its argument + void *(_LIBCXXABI_DTOR_FUNC *exceptionDestructor)(void *); +#else void (_LIBCXXABI_DTOR_FUNC *exceptionDestructor)(void *); +#endif std::unexpected_handler unexpectedHandler; std::terminate_handler terminateHandler; diff --git a/libcxxabi/src/cxa_exception.cpp b/libcxxabi/src/cxa_exception.cpp --- a/libcxxabi/src/cxa_exception.cpp +++ b/libcxxabi/src/cxa_exception.cpp @@ -254,7 +254,12 @@ exception. */ void +#ifdef __USING_WASM_EXCEPTIONS__ +// In Wasm, a destructor returns its argument +__cxa_throw(void *thrown_object, std::type_info *tinfo, void *(_LIBCXXABI_DTOR_FUNC *dest)(void *)) { +#else __cxa_throw(void *thrown_object, std::type_info *tinfo, void (_LIBCXXABI_DTOR_FUNC *dest)(void *)) { +#endif __cxa_eh_globals *globals = __cxa_get_globals(); __cxa_exception* exception_header = cxa_exception_from_thrown_object(thrown_object); diff --git a/libcxxabi/src/cxa_personality.cpp b/libcxxabi/src/cxa_personality.cpp --- a/libcxxabi/src/cxa_personality.cpp +++ b/libcxxabi/src/cxa_personality.cpp @@ -31,6 +31,10 @@ # define _LIBUNWIND_VERSION #endif +#if defined(__USING_SJLJ_EXCEPTIONS__) || defined (__USING_WASM_EXCEPTIONS__) +#define __USING_SJLJ_OR_WASM_EXCEPTIONS__ +#endif + #if defined(__SEH__) && !defined(__USING_SJLJ_EXCEPTIONS__) #include #include @@ -70,7 +74,7 @@ +------------------+--+-----+-----+------------------------+--------------------------+ | callSiteTableLength | (ULEB128) | Call Site Table length, used to find Action table | +---------------------+-----------+---------------------------------------------------+ -#ifndef __USING_SJLJ_EXCEPTIONS__ +#ifndef __USING_SJLJ_OR_WASM_EXCEPTIONS__ +---------------------+-----------+------------------------------------------------+ | Beginning of Call Site Table The current ip lies within the | | ... (start, length) range of one of these | @@ -84,7 +88,7 @@ | +-------------+---------------------------------+------------------------------+ | | ... | +----------------------------------------------------------------------------------+ -#else // __USING_SJLJ_EXCEPTIONS__ +#else // !__USING_SJLJ_OR_WASM_EXCEPTIONS__ +---------------------+-----------+------------------------------------------------+ | Beginning of Call Site Table The current ip is a 1-based index into | | ... this table. Or it is -1 meaning no | @@ -97,7 +101,7 @@ | +-------------+---------------------------------+------------------------------+ | | ... | +----------------------------------------------------------------------------------+ -#endif // __USING_SJLJ_EXCEPTIONS__ +#endif // __USING_SJLJ_OR_WASM_EXCEPTIONS__ +---------------------------------------------------------------------+ | Beginning of Action Table ttypeIndex == 0 : cleanup | | ... ttypeIndex > 0 : catch | @@ -547,7 +551,7 @@ set_registers(_Unwind_Exception* unwind_exception, _Unwind_Context* context, const scan_results& results) { -#if defined(__USING_SJLJ_EXCEPTIONS__) +#ifdef __USING_SJLJ_OR_WASM_EXCEPTIONS__ #define __builtin_eh_return_data_regno(regno) regno #elif defined(__ibmxl__) // IBM xlclang++ compiler does not support __builtin_eh_return_data_regno. @@ -642,7 +646,7 @@ // Get beginning current frame's code (as defined by the // emitted dwarf code) uintptr_t funcStart = _Unwind_GetRegionStart(context); -#ifdef __USING_SJLJ_EXCEPTIONS__ +#ifdef __USING_SJLJ_OR_WASM_EXCEPTIONS__ if (ip == uintptr_t(-1)) { // no action @@ -652,9 +656,9 @@ else if (ip == 0) call_terminate(native_exception, unwind_exception); // ip is 1-based index into call site table -#else // !__USING_SJLJ_EXCEPTIONS__ +#else // !__USING_SJLJ_OR_WASM_EXCEPTIONS__ uintptr_t ipOffset = ip - funcStart; -#endif // !defined(_USING_SLJL_EXCEPTIONS__) +#endif // !defined(__USING_SJLJ_OR_WASM_EXCEPTIONS__) const uint8_t* classInfo = NULL; // Note: See JITDwarfEmitter::EmitExceptionTable(...) for corresponding // dwarf emission @@ -676,8 +680,8 @@ // Walk call-site table looking for range that // includes current PC. uint8_t callSiteEncoding = *lsda++; -#ifdef __USING_SJLJ_EXCEPTIONS__ - (void)callSiteEncoding; // When using SjLj exceptions, callSiteEncoding is never used +#ifdef __USING_SJLJ_OR_WASM_EXCEPTIONS__ + (void)callSiteEncoding; // When using SjLj/Wasm exceptions, callSiteEncoding is never used #endif uint32_t callSiteTableLength = static_cast(readULEB128(&lsda)); const uint8_t* callSiteTableStart = lsda; @@ -687,7 +691,7 @@ while (callSitePtr < callSiteTableEnd) { // There is one entry per call site. -#ifndef __USING_SJLJ_EXCEPTIONS__ +#ifndef __USING_SJLJ_OR_WASM_EXCEPTIONS__ // The call sites are non-overlapping in [start, start+length) // The call sites are ordered in increasing value of start uintptr_t start = readEncodedPointer(&callSitePtr, callSiteEncoding); @@ -695,15 +699,15 @@ uintptr_t landingPad = readEncodedPointer(&callSitePtr, callSiteEncoding); uintptr_t actionEntry = readULEB128(&callSitePtr); if ((start <= ipOffset) && (ipOffset < (start + length))) -#else // __USING_SJLJ_EXCEPTIONS__ +#else // __USING_SJLJ_OR_WASM_EXCEPTIONS__ // ip is 1-based index into this table uintptr_t landingPad = readULEB128(&callSitePtr); uintptr_t actionEntry = readULEB128(&callSitePtr); if (--ip == 0) -#endif // __USING_SJLJ_EXCEPTIONS__ +#endif // __USING_SJLJ_OR_WASM_EXCEPTIONS__ { // Found the call site containing ip. -#ifndef __USING_SJLJ_EXCEPTIONS__ +#ifndef __USING_SJLJ_OR_WASM_EXCEPTIONS__ if (landingPad == 0) { // No handler here @@ -711,9 +715,9 @@ return; } landingPad = (uintptr_t)lpStart + landingPad; -#else // __USING_SJLJ_EXCEPTIONS__ +#else // __USING_SJLJ_OR_WASM_EXCEPTIONS__ ++landingPad; -#endif // __USING_SJLJ_EXCEPTIONS__ +#endif // __USING_SJLJ_OR_WASM_EXCEPTIONS__ results.landingPad = landingPad; if (actionEntry == 0) { @@ -841,7 +845,7 @@ action += actionOffset; } // there is no break out of this loop, only return } -#ifndef __USING_SJLJ_EXCEPTIONS__ +#ifndef __USING_SJLJ_OR_WASM_EXCEPTIONS__ else if (ipOffset < start) { // There is no call site for this ip @@ -849,7 +853,7 @@ // Possible stack corruption. call_terminate(native_exception, unwind_exception); } -#endif // !__USING_SJLJ_EXCEPTIONS__ +#endif // !__USING_SJLJ_OR_WASM_EXCEPTIONS__ } // there might be some tricky cases which break out of this loop // It is possible that no eh table entry specify how to handle @@ -906,7 +910,9 @@ */ #if !defined(_LIBCXXABI_ARM_EHABI) -#if defined(__SEH__) && !defined(__USING_SJLJ_EXCEPTIONS__) +#ifdef __USING_WASM_EXCEPTIONS__ +_Unwind_Reason_Code __gxx_personality_wasm0 +#elif defined(__SEH__) && !defined(__USING_SJLJ_EXCEPTIONS__) static _Unwind_Reason_Code __gxx_personality_imp #else _LIBCXXABI_FUNC_VIS _Unwind_Reason_Code @@ -973,6 +979,11 @@ exc->languageSpecificData = results.languageSpecificData; exc->catchTemp = reinterpret_cast(results.landingPad); exc->adjustedPtr = results.adjustedPtr; +#ifdef __USING_WASM_EXCEPTIONS__ + // Wasm only uses a single phase (_UA_SEARCH_PHASE), so save the + // results here. + set_registers(unwind_exception, context, results); +#endif } return _URC_HANDLER_FOUND; }