diff --git a/compiler-rt/emscripten_tempret.s b/compiler-rt/emscripten_tempret.s index 4e3b307a03e72..a098e33d15913 100644 --- a/compiler-rt/emscripten_tempret.s +++ b/compiler-rt/emscripten_tempret.s @@ -1,6 +1,10 @@ +.section .globals,"",@ + .globaltype tempRet0, i32 tempRet0: +.section .text,"",@ + .globl setTempRet0 setTempRet0: .functype setTempRet0 (i32) -> () diff --git a/compiler-rt/stack_limits.S b/compiler-rt/stack_limits.S index 1171afa8174fc..7bb9d895c46e8 100644 --- a/compiler-rt/stack_limits.S +++ b/compiler-rt/stack_limits.S @@ -16,6 +16,8 @@ .globaltype __stack_pointer, PTR +.section .globals,"",@ + # TODO(sbc): It would be nice if these we initialized directly # using PTR.const rather than using the `emscripten_stack_init` .globaltype __stack_end, PTR @@ -23,6 +25,8 @@ __stack_end: .globaltype __stack_base, PTR __stack_base: +.section .text,"",@ + emscripten_stack_get_base: .functype emscripten_stack_get_base () -> (PTR) global.get __stack_base diff --git a/libcxxabi/include/cxxabi.h b/libcxxabi/include/cxxabi.h index 3f79df260a495..6f4f823bc273f 100644 --- a/libcxxabi/include/cxxabi.h +++ b/libcxxabi/include/cxxabi.h @@ -40,14 +40,15 @@ extern "C" { // 2.4.2 Allocating the Exception Object extern _LIBCXXABI_FUNC_VIS void * -__cxa_allocate_exception(size_t thrown_size) _NOEXCEPT; +__cxa_allocate_exception(size_t thrown_size) throw(); extern _LIBCXXABI_FUNC_VIS void -__cxa_free_exception(void *thrown_exception) _NOEXCEPT; +__cxa_free_exception(void *thrown_exception) throw(); // 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 *)); @@ -55,9 +56,9 @@ __cxa_throw(void *thrown_exception, std::type_info *tinfo, // 2.5.3 Exception Handlers extern _LIBCXXABI_FUNC_VIS void * -__cxa_get_exception_ptr(void *exceptionObject) _NOEXCEPT; +__cxa_get_exception_ptr(void *exceptionObject) throw(); extern _LIBCXXABI_FUNC_VIS void * -__cxa_begin_catch(void *exceptionObject) _NOEXCEPT; +__cxa_begin_catch(void *exceptionObject) throw(); extern _LIBCXXABI_FUNC_VIS void __cxa_end_catch(); #if defined(_LIBCXXABI_ARM_EHABI) extern _LIBCXXABI_FUNC_VIS bool @@ -152,17 +153,17 @@ extern _LIBCXXABI_FUNC_VIS char *__cxa_demangle(const char *mangled_name, // Apple additions to support C++ 0x exception_ptr class // These are primitives to wrap a smart pointer around an exception object -extern _LIBCXXABI_FUNC_VIS void *__cxa_current_primary_exception() _NOEXCEPT; +extern _LIBCXXABI_FUNC_VIS void *__cxa_current_primary_exception() throw(); extern _LIBCXXABI_FUNC_VIS void __cxa_rethrow_primary_exception(void *primary_exception); extern _LIBCXXABI_FUNC_VIS void -__cxa_increment_exception_refcount(void *primary_exception) _NOEXCEPT; +__cxa_increment_exception_refcount(void *primary_exception) throw(); extern _LIBCXXABI_FUNC_VIS void -__cxa_decrement_exception_refcount(void *primary_exception) _NOEXCEPT; +__cxa_decrement_exception_refcount(void *primary_exception) throw(); // Apple extension to support std::uncaught_exception() -extern _LIBCXXABI_FUNC_VIS bool __cxa_uncaught_exception() _NOEXCEPT; -extern _LIBCXXABI_FUNC_VIS unsigned int __cxa_uncaught_exceptions() _NOEXCEPT; +extern _LIBCXXABI_FUNC_VIS bool __cxa_uncaught_exception() throw(); +extern _LIBCXXABI_FUNC_VIS unsigned int __cxa_uncaught_exceptions() throw(); #if defined(__linux__) || defined(__Fuchsia__) // Linux and Fuchsia TLS support. Not yet an official part of the Itanium ABI. diff --git a/libcxxabi/src/cxa_exception.cpp b/libcxxabi/src/cxa_exception.cpp index 64f14c8c1a202..43537f159b22a 100644 --- a/libcxxabi/src/cxa_exception.cpp +++ b/libcxxabi/src/cxa_exception.cpp @@ -180,7 +180,7 @@ extern "C" { // object. Zero-fill the object. If memory can't be allocated, call // std::terminate. Return a pointer to the memory to be used for the // user's exception object. -void *__cxa_allocate_exception(size_t thrown_size) _NOEXCEPT { +void *__cxa_allocate_exception(size_t thrown_size) throw() { size_t actual_size = cxa_exception_size_from_exception_thrown_size(thrown_size); // Allocate extra space before the __cxa_exception header to ensure the @@ -198,7 +198,7 @@ void *__cxa_allocate_exception(size_t thrown_size) _NOEXCEPT { // Free a __cxa_exception object allocated with __cxa_allocate_exception. -void __cxa_free_exception(void *thrown_object) _NOEXCEPT { +void __cxa_free_exception(void *thrown_object) throw() { // Compute the size of the padding before the header. size_t header_offset = get_cxa_exception_offset(); char *raw_buffer = @@ -254,7 +254,7 @@ will call terminate, assuming that there was no handler for the exception. */ -#if defined(__USING_WASM_EXCEPTIONS__) && !defined(NDEBUG) +#if defined(__EMSCRIPTEN__) && defined(__USING_WASM_EXCEPTIONS__) && !defined(NDEBUG) extern "C" { void __throw_exception_with_stack_trace(_Unwind_Exception*); } // extern "C" @@ -262,7 +262,7 @@ void __throw_exception_with_stack_trace(_Unwind_Exception*); void #ifdef __USING_WASM_EXCEPTIONS__ -// In wasm, destructors return their argument +// 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 *)) { @@ -287,14 +287,10 @@ __cxa_throw(void *thrown_object, std::type_info *tinfo, void (_LIBCXXABI_DTOR_FU #ifdef __USING_SJLJ_EXCEPTIONS__ _Unwind_SjLj_RaiseException(&exception_header->unwindHeader); -#elif __USING_WASM_EXCEPTIONS__ -#ifdef NDEBUG - _Unwind_RaiseException(&exception_header->unwindHeader); -#else +#elif defined(__EMSCRIPTEN__) && defined(__USING_WASM_EXCEPTIONS__) && !defined(NDEBUG) // In debug mode, call a JS library function to use WebAssembly.Exception JS // API, which enables us to include stack traces __throw_exception_with_stack_trace(&exception_header->unwindHeader); -#endif #else _Unwind_RaiseException(&exception_header->unwindHeader); #endif @@ -312,7 +308,7 @@ The adjusted pointer is computed by the personality routine during phase 1 Requires: exception is native */ -void *__cxa_get_exception_ptr(void *unwind_exception) _NOEXCEPT { +void *__cxa_get_exception_ptr(void *unwind_exception) throw() { #if defined(_LIBCXXABI_ARM_EHABI) return reinterpret_cast( static_cast<_Unwind_Control_Block*>(unwind_exception)->barrier_cache.bitpattern[0]); @@ -327,7 +323,7 @@ void *__cxa_get_exception_ptr(void *unwind_exception) _NOEXCEPT { The routine to be called before the cleanup. This will save __cxa_exception in __cxa_eh_globals, so that __cxa_end_cleanup() can recover later. */ -bool __cxa_begin_cleanup(void *unwind_arg) _NOEXCEPT { +bool __cxa_begin_cleanup(void *unwind_arg) throw() { _Unwind_Exception* unwind_exception = static_cast<_Unwind_Exception*>(unwind_arg); __cxa_eh_globals* globals = __cxa_get_globals(); __cxa_exception* exception_header = @@ -451,7 +447,7 @@ to terminate or unexpected during unwinding. _Unwind_Exception and return a pointer to that. */ void* -__cxa_begin_catch(void* unwind_arg) _NOEXCEPT +__cxa_begin_catch(void* unwind_arg) throw() { _Unwind_Exception* unwind_exception = static_cast<_Unwind_Exception*>(unwind_arg); bool native_exception = __isOurExceptionClass(unwind_exception); @@ -644,6 +640,10 @@ void __cxa_rethrow() { } #ifdef __USING_SJLJ_EXCEPTIONS__ _Unwind_SjLj_RaiseException(&exception_header->unwindHeader); +#elif defined(__EMSCRIPTEN__) && defined(__USING_WASM_EXCEPTIONS__) && !defined(NDEBUG) + // In debug mode, call a JS library function to use WebAssembly.Exception JS + // API, which enables us to include stack traces + __throw_exception_with_stack_trace(&exception_header->unwindHeader); #else _Unwind_RaiseException(&exception_header->unwindHeader); #endif @@ -667,7 +667,7 @@ void __cxa_rethrow() { Requires: If thrown_object is not NULL, it is a native exception. */ void -__cxa_increment_exception_refcount(void *thrown_object) _NOEXCEPT { +__cxa_increment_exception_refcount(void *thrown_object) throw() { if (thrown_object != NULL ) { __cxa_exception* exception_header = cxa_exception_from_thrown_object(thrown_object); @@ -684,7 +684,7 @@ __cxa_increment_exception_refcount(void *thrown_object) _NOEXCEPT { Requires: If thrown_object is not NULL, it is a native exception. */ _LIBCXXABI_NO_CFI -void __cxa_decrement_exception_refcount(void *thrown_object) _NOEXCEPT { +void __cxa_decrement_exception_refcount(void *thrown_object) throw() { if (thrown_object != NULL ) { __cxa_exception* exception_header = cxa_exception_from_thrown_object(thrown_object); @@ -707,7 +707,7 @@ void __cxa_decrement_exception_refcount(void *thrown_object) _NOEXCEPT { been no exceptions thrown, ever, on this thread, we can return NULL without the need to allocate the exception-handling globals. */ -void *__cxa_current_primary_exception() _NOEXCEPT { +void *__cxa_current_primary_exception() throw() { // get the current exception __cxa_eh_globals* globals = __cxa_get_globals_fast(); if (NULL == globals) @@ -769,8 +769,13 @@ __cxa_rethrow_primary_exception(void* thrown_object) dep_exception_header->unwindHeader.exception_cleanup = dependent_exception_cleanup; #ifdef __USING_SJLJ_EXCEPTIONS__ _Unwind_SjLj_RaiseException(&dep_exception_header->unwindHeader); +#elif defined(__EMSCRIPTEN__) && defined(__USING_WASM_EXCEPTIONS__) && !defined(NDEBUG) + // In debug mode, call a JS library function to use + // WebAssembly.Exception JS API, which enables us to include stack + // traces + __throw_exception_with_stack_trace(&exception_header->unwindHeader); #else - _Unwind_RaiseException(&dep_exception_header->unwindHeader); + _Unwind_RaiseException(&exception_header->unwindHeader); #endif // Some sort of unwinding error. Note that terminate is a handler. __cxa_begin_catch(&dep_exception_header->unwindHeader); @@ -779,10 +784,10 @@ __cxa_rethrow_primary_exception(void* thrown_object) } bool -__cxa_uncaught_exception() _NOEXCEPT { return __cxa_uncaught_exceptions() != 0; } +__cxa_uncaught_exception() throw() { return __cxa_uncaught_exceptions() != 0; } unsigned int -__cxa_uncaught_exceptions() _NOEXCEPT +__cxa_uncaught_exceptions() throw() { // This does not report foreign exceptions in flight __cxa_eh_globals* globals = __cxa_get_globals_fast(); diff --git a/libcxxabi/src/cxa_exception.h b/libcxxabi/src/cxa_exception.h index 96f828d003239..098e0bf95aef8 100644 --- a/libcxxabi/src/cxa_exception.h +++ b/libcxxabi/src/cxa_exception.h @@ -64,7 +64,7 @@ struct _LIBCXXABI_HIDDEN __cxa_exception { // Manage the exception object itself. std::type_info *exceptionType; #ifdef __USING_WASM_EXCEPTIONS__ - // In wasm, destructors return their argument + // In Wasm, a destructor returns its argument void *(_LIBCXXABI_DTOR_FUNC *exceptionDestructor)(void *); #else void (_LIBCXXABI_DTOR_FUNC *exceptionDestructor)(void *); diff --git a/libcxxabi/src/cxa_exception_emscripten.cpp b/libcxxabi/src/cxa_exception_emscripten.cpp index fef9bf9a0e90d..a80e644da865e 100644 --- a/libcxxabi/src/cxa_exception_emscripten.cpp +++ b/libcxxabi/src/cxa_exception_emscripten.cpp @@ -11,6 +11,8 @@ // //===----------------------------------------------------------------------===// +#ifdef __EMSCRIPTEN__ + #include "cxxabi.h" #include "cxa_exception.h" #include "include/atomic_support.h" @@ -85,7 +87,7 @@ extern "C" { // object. Zero-fill the object. If memory can't be allocated, call // std::terminate. Return a pointer to the memory to be used for the // user's exception object. -void *__cxa_allocate_exception(size_t thrown_size) _NOEXCEPT { +void *__cxa_allocate_exception(size_t thrown_size) throw() { size_t actual_size = cxa_exception_size_from_exception_thrown_size(thrown_size); char *raw_buffer = @@ -100,7 +102,7 @@ void *__cxa_allocate_exception(size_t thrown_size) _NOEXCEPT { // Free a __cxa_exception object allocated with __cxa_allocate_exception. -void __cxa_free_exception(void *thrown_object) _NOEXCEPT { +void __cxa_free_exception(void *thrown_object) throw() { // Compute the size of the padding before the header. char *raw_buffer = ((char *)cxa_exception_from_thrown_object(thrown_object)); @@ -115,7 +117,7 @@ void __cxa_free_exception(void *thrown_object) _NOEXCEPT { Requires: If thrown_object is not NULL, it is a native exception. */ void -__cxa_increment_exception_refcount(void *thrown_object) _NOEXCEPT { +__cxa_increment_exception_refcount(void *thrown_object) throw() { if (thrown_object != NULL ) { __cxa_exception* exception_header = cxa_exception_from_thrown_object(thrown_object); @@ -133,7 +135,7 @@ __cxa_increment_exception_refcount(void *thrown_object) _NOEXCEPT { Requires: If thrown_object is not NULL, it is a native exception. */ _LIBCXXABI_NO_CFI -void __cxa_decrement_exception_refcount(void *thrown_object) _NOEXCEPT { +void __cxa_decrement_exception_refcount(void *thrown_object) throw() { if (thrown_object != NULL ) { __cxa_exception* exception_header = cxa_exception_from_thrown_object(thrown_object); @@ -153,3 +155,5 @@ void __cxa_decrement_exception_refcount(void *thrown_object) _NOEXCEPT { } // extern "C" } // abi + +#endif // __EMSCRIPTEN__ diff --git a/libcxxabi/src/cxa_exception_js_utils.cpp b/libcxxabi/src/cxa_exception_js_utils.cpp index e2c61aa0967e5..a898a0232dc73 100644 --- a/libcxxabi/src/cxa_exception_js_utils.cpp +++ b/libcxxabi/src/cxa_exception_js_utils.cpp @@ -1,3 +1,5 @@ +#ifdef __EMSCRIPTEN__ + #include "cxxabi.h" #include "cxa_exception.h" @@ -103,3 +105,5 @@ char* __get_exception_terminate_message(void* thrown_object) { } // extern "C" } // namespace __cxxabiv1 + +#endif // __EMSCRIPTEN__ diff --git a/libcxxabi/src/cxa_noexception.cpp b/libcxxabi/src/cxa_noexception.cpp index 1ef53bf79f243..38731e6aad8e3 100644 --- a/libcxxabi/src/cxa_noexception.cpp +++ b/libcxxabi/src/cxa_noexception.cpp @@ -54,7 +54,7 @@ __cxa_uncaught_exceptions() throw() { return 0; } // DISABLE_EXCEPTION_CATCHING is set but DISABLE_EXCEPTION_THROWING is not. // TODO(sbc): Perhaps just call std::terminate here. It could // just be some test code that needs updating. -void *__cxa_allocate_exception(size_t thrown_size) _NOEXCEPT { +void *__cxa_allocate_exception(size_t thrown_size) throw() { char* allocation = (char*)malloc(thrown_size + sizeof(__cxa_exception)); return allocation + sizeof(__cxa_exception); } @@ -68,7 +68,7 @@ cxa_exception_from_thrown_object(void* thrown_object) } // Free a __cxa_exception object allocated with __cxa_allocate_exception. -void __cxa_free_exception(void *thrown_object) _NOEXCEPT { +void __cxa_free_exception(void *thrown_object) throw() { // Compute the size of the padding before the header. char *raw_buffer = ((char *)cxa_exception_from_thrown_object(thrown_object)); diff --git a/libcxxabi/src/cxa_personality.cpp b/libcxxabi/src/cxa_personality.cpp index 1c37a6434dfb4..69d695d7f8b58 100644 --- a/libcxxabi/src/cxa_personality.cpp +++ b/libcxxabi/src/cxa_personality.cpp @@ -31,8 +31,6 @@ # define _LIBUNWIND_VERSION #endif -#define __USING_SJLJ_OR_WASM_EXCEPTIONS__ (__USING_SJLJ_EXCEPTIONS__ || __USING_WASM_EXCEPTIONS__) - #if defined(__SEH__) && !defined(__USING_SJLJ_EXCEPTIONS__) #include #include @@ -72,7 +70,7 @@ extern "C" EXCEPTION_DISPOSITION _GCC_specific_handler(PEXCEPTION_RECORD, +------------------+--+-----+-----+------------------------+--------------------------+ | callSiteTableLength | (ULEB128) | Call Site Table length, used to find Action table | +---------------------+-----------+---------------------------------------------------+ -#ifndef __USING_SJLJ_OR_WASM_EXCEPTIONS__ +#if !defined(__USING_SJLJ_EXCEPTIONS__) && !defined(__USING_WASM_EXCEPTIONS__) +---------------------+-----------+------------------------------------------------+ | Beginning of Call Site Table The current ip lies within the | | ... (start, length) range of one of these | @@ -86,7 +84,7 @@ extern "C" EXCEPTION_DISPOSITION _GCC_specific_handler(PEXCEPTION_RECORD, | +-------------+---------------------------------+------------------------------+ | | ... | +----------------------------------------------------------------------------------+ -#else // !__USING_SJLJ_OR_WASM_EXCEPTIONS__ +#else // __USING_SJLJ_EXCEPTIONS__ || __USING_WASM_EXCEPTIONS__ +---------------------+-----------+------------------------------------------------+ | Beginning of Call Site Table The current ip is a 1-based index into | | ... this table. Or it is -1 meaning no | @@ -99,7 +97,7 @@ extern "C" EXCEPTION_DISPOSITION _GCC_specific_handler(PEXCEPTION_RECORD, | +-------------+---------------------------------+------------------------------+ | | ... | +----------------------------------------------------------------------------------+ -#endif // __USING_SJLJ_OR_WASM_EXCEPTIONS__ +#endif // __USING_SJLJ_EXCEPTIONS__ || __USING_WASM_EXCEPTIONS__ +---------------------------------------------------------------------+ | Beginning of Action Table ttypeIndex == 0 : cleanup | | ... ttypeIndex > 0 : catch | @@ -549,7 +547,7 @@ void set_registers(_Unwind_Exception* unwind_exception, _Unwind_Context* context, const scan_results& results) { -#ifdef __USING_SJLJ_OR_WASM_EXCEPTIONS__ +#if defined(__USING_SJLJ_EXCEPTIONS__) || defined(__USING_WASM_EXCEPTIONS__) #define __builtin_eh_return_data_regno(regno) regno #elif defined(__ibmxl__) // IBM xlclang++ compiler does not support __builtin_eh_return_data_regno. @@ -644,7 +642,7 @@ static void scan_eh_tab(scan_results &results, _Unwind_Action actions, // Get beginning current frame's code (as defined by the // emitted dwarf code) uintptr_t funcStart = _Unwind_GetRegionStart(context); -#ifdef __USING_SJLJ_OR_WASM_EXCEPTIONS__ +#if defined(__USING_SJLJ_EXCEPTIONS__) || defined(__USING_WASM_EXCEPTIONS__) if (ip == uintptr_t(-1)) { // no action @@ -654,9 +652,9 @@ static void scan_eh_tab(scan_results &results, _Unwind_Action actions, else if (ip == 0) call_terminate(native_exception, unwind_exception); // ip is 1-based index into call site table -#else // !__USING_SJLJ_OR_WASM_EXCEPTIONS__ +#else // !__USING_SJLJ_EXCEPTIONS__ && !__USING_WASM_EXCEPTIONS__ uintptr_t ipOffset = ip - funcStart; -#endif // !defined(__USING_SJLJ_OR_WASM_EXCEPTIONS__) +#endif // !__USING_SJLJ_EXCEPTIONS__ && !__USING_WASM_EXCEPTIONS__ const uint8_t* classInfo = NULL; // Note: See JITDwarfEmitter::EmitExceptionTable(...) for corresponding // dwarf emission @@ -678,7 +676,7 @@ static void scan_eh_tab(scan_results &results, _Unwind_Action actions, // Walk call-site table looking for range that // includes current PC. uint8_t callSiteEncoding = *lsda++; -#ifdef __USING_SJLJ_OR_WASM_EXCEPTIONS__ +#if defined(__USING_SJLJ_EXCEPTIONS__) || defined(__USING_WASM_EXCEPTIONS__) (void)callSiteEncoding; // When using SjLj/Wasm exceptions, callSiteEncoding is never used #endif uint32_t callSiteTableLength = static_cast(readULEB128(&lsda)); @@ -689,7 +687,7 @@ static void scan_eh_tab(scan_results &results, _Unwind_Action actions, while (callSitePtr < callSiteTableEnd) { // There is one entry per call site. -#ifndef __USING_SJLJ_OR_WASM_EXCEPTIONS__ +#if !defined(__USING_SJLJ_EXCEPTIONS__) && !defined(__USING_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); @@ -697,15 +695,15 @@ static void scan_eh_tab(scan_results &results, _Unwind_Action actions, uintptr_t landingPad = readEncodedPointer(&callSitePtr, callSiteEncoding); uintptr_t actionEntry = readULEB128(&callSitePtr); if ((start <= ipOffset) && (ipOffset < (start + length))) -#else // __USING_SJLJ_OR_WASM_EXCEPTIONS__ +#else // __USING_SJLJ_EXCEPTIONS__ || __USING_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_OR_WASM_EXCEPTIONS__ +#endif // __USING_SJLJ_EXCEPTIONS__ || __USING_WASM_EXCEPTIONS__ { // Found the call site containing ip. -#ifndef __USING_SJLJ_OR_WASM_EXCEPTIONS__ +#if !defined(__USING_SJLJ_EXCEPTIONS__) && !defined(__USING_WASM_EXCEPTIONS__) if (landingPad == 0) { // No handler here @@ -713,9 +711,9 @@ static void scan_eh_tab(scan_results &results, _Unwind_Action actions, return; } landingPad = (uintptr_t)lpStart + landingPad; -#else // __USING_SJLJ_OR_WASM_EXCEPTIONS__ +#else // __USING_SJLJ_EXCEPTIONS__ || __USING_WASM_EXCEPTIONS__ ++landingPad; -#endif // __USING_SJLJ_OR_WASM_EXCEPTIONS__ +#endif // __USING_SJLJ_EXCEPTIONS__ || __USING_WASM_EXCEPTIONS__ results.landingPad = landingPad; if (actionEntry == 0) { @@ -843,7 +841,7 @@ static void scan_eh_tab(scan_results &results, _Unwind_Action actions, action += actionOffset; } // there is no break out of this loop, only return } -#ifndef __USING_SJLJ_OR_WASM_EXCEPTIONS__ +#if !defined(__USING_SJLJ_EXCEPTIONS__) && !defined(__USING_WASM_EXCEPTIONS__) else if (ipOffset < start) { // There is no call site for this ip @@ -851,7 +849,7 @@ static void scan_eh_tab(scan_results &results, _Unwind_Action actions, // Possible stack corruption. call_terminate(native_exception, unwind_exception); } -#endif // !__USING_SJLJ_OR_WASM_EXCEPTIONS__ +#endif // !__USING_SJLJ_EXCEPTIONS__ && !__USING_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 diff --git a/libunwind/include/unwind_itanium.h b/libunwind/include/unwind_itanium.h index ffa46ed9fdc1b..d94a6183be290 100644 --- a/libunwind/include/unwind_itanium.h +++ b/libunwind/include/unwind_itanium.h @@ -24,7 +24,7 @@ struct _Unwind_Exception { _Unwind_Exception *exc); #if defined(__SEH__) && !defined(__USING_SJLJ_EXCEPTIONS__) uintptr_t private_[6]; -#elif !defined(__USING_WASM_EXCEPTIONS__) +#else uintptr_t private_1; // non-zero means forced unwind uintptr_t private_2; // holds sp that phase1 found for phase2 to use #endif diff --git a/libunwind/src/Unwind-wasm.c b/libunwind/src/Unwind-wasm.c index daa7d093d72af..35f2f9aeab080 100644 --- a/libunwind/src/Unwind-wasm.c +++ b/libunwind/src/Unwind-wasm.c @@ -1,3 +1,15 @@ +//===----------------------------------------------------------------------===// +// +// 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 +// +// +// Implements Wasm exception handling proposal +// (https://github.com/WebAssembly/exception-handling) based C++ exceptions +// +//===----------------------------------------------------------------------===// + #include "config.h" #include "unwind.h" #include @@ -41,10 +53,9 @@ _Unwind_Reason_Code _Unwind_CallPersonality(void *exception_ptr) { // Call personality function. Wasm does not have two-phase unwinding, so we // only do the cleanup phase. - _Unwind_Reason_Code ret = __gxx_personality_wasm0( + return __gxx_personality_wasm0( 1, _UA_SEARCH_PHASE, exception_object->exception_class, exception_object, (struct _Unwind_Context *)&__wasm_lpad_context); - return ret; } /// Called by __cxa_throw. @@ -52,6 +63,7 @@ _LIBUNWIND_EXPORT _Unwind_Reason_Code _Unwind_RaiseException(_Unwind_Exception *exception_object) { _LIBUNWIND_TRACE_API("_Unwind_RaiseException(exception_object=%p)", (void *)exception_object); + // Use Wasm EH's 'throw' instruction. __builtin_wasm_throw(0, exception_object); } @@ -72,9 +84,8 @@ _LIBUNWIND_EXPORT void _Unwind_SetGR(struct _Unwind_Context *context, int index, (void *)context, index, value); // We only use this function to set __wasm_lpad_context.selector field, which // is index 1 in the personality function. - if (index != 1) - return; - ((struct _Unwind_LandingPadContext *)context)->selector = value; + if (index == 1) + ((struct _Unwind_LandingPadContext *)context)->selector = value; } /// Called by personality handler to get instruction pointer. @@ -88,7 +99,7 @@ _LIBUNWIND_EXPORT uintptr_t _Unwind_GetIP(struct _Unwind_Context *context) { return result; } -/// Not used in wasm. +/// Not used in Wasm. _LIBUNWIND_EXPORT void _Unwind_SetIP(struct _Unwind_Context *context, uintptr_t value) {} @@ -101,7 +112,7 @@ _Unwind_GetLanguageSpecificData(struct _Unwind_Context *context) { return result; } -/// Not used in wasm. +/// Not used in Wasm. _LIBUNWIND_EXPORT uintptr_t _Unwind_GetRegionStart(struct _Unwind_Context *context) { return 0; diff --git a/libunwind/src/config.h b/libunwind/src/config.h index c7584edc34438..d0c062cad5f1a 100644 --- a/libunwind/src/config.h +++ b/libunwind/src/config.h @@ -83,7 +83,7 @@ __asm__(".globl " SYMBOL_NAME(aliasname)); \ __asm__(SYMBOL_NAME(aliasname) " = " SYMBOL_NAME(name)); \ _LIBUNWIND_ALIAS_VISIBILITY(SYMBOL_NAME(aliasname)) -#elif defined(__ELF__) || defined(_AIX) +#elif defined(__ELF__) || defined(_AIX) || defined(__wasm__) #define _LIBUNWIND_WEAK_ALIAS(name, aliasname) \ extern "C" _LIBUNWIND_EXPORT __typeof(name) aliasname \ __attribute__((weak, alias(#name))); @@ -98,7 +98,6 @@ SYMBOL_NAME(name))) \ extern "C" _LIBUNWIND_EXPORT __typeof(name) aliasname; #endif -#elif defined(__EMSCRIPTEN__) #else #error Unsupported target #endif