From e0e82fcf1ab23805ce90709320ae688e1ea8be57 Mon Sep 17 00:00:00 2001 From: Sam Clegg Date: Sat, 22 May 2021 06:39:33 -0700 Subject: [PATCH] Rebase of changed from emscripten-libs-13.0.0 onto llvmorg-14.0.0 diff --git a/include/cxxabi.h b/include/cxxabi.h --- a/include/cxxabi.h +++ b/include/cxxabi.h @@ -39,21 +39,44 @@ namespace __cxxabiv1 { extern "C" { // 2.4.2 Allocating the Exception Object +#ifndef __EMSCRIPTEN__ extern _LIBCXXABI_FUNC_VIS void * __cxa_allocate_exception(size_t thrown_size) throw(); extern _LIBCXXABI_FUNC_VIS void __cxa_free_exception(void *thrown_exception) throw(); +#else +extern _LIBCXXABI_FUNC_VIS void * +__cxa_allocate_exception(size_t thrown_size) _NOEXCEPT; +extern _LIBCXXABI_FUNC_VIS void +__cxa_free_exception(void *thrown_exception) _NOEXCEPT; +#endif // 2.4.3 Throwing the Exception Object +#ifdef __USING_WASM_EXCEPTIONS__ +extern _LIBCXXABI_FUNC_VIS _LIBCXXABI_NORETURN void +__cxa_throw(void *thrown_exception, std::type_info *tinfo, + void *(_LIBCXXABI_DTOR_FUNC *dest)(void *)); +#else extern _LIBCXXABI_FUNC_VIS _LIBCXXABI_NORETURN void __cxa_throw(void *thrown_exception, std::type_info *tinfo, void (_LIBCXXABI_DTOR_FUNC *dest)(void *)); +#endif // 2.5.3 Exception Handlers +#ifndef __EMSCRIPTEN__ extern _LIBCXXABI_FUNC_VIS void * __cxa_get_exception_ptr(void *exceptionObject) throw(); +#else +extern _LIBCXXABI_FUNC_VIS void * +__cxa_get_exception_ptr(void *exceptionObject) _NOEXCEPT; +#endif +#ifndef __EMSCRIPTEN__ extern _LIBCXXABI_FUNC_VIS void * __cxa_begin_catch(void *exceptionObject) throw(); +#else +extern _LIBCXXABI_FUNC_VIS void * +__cxa_begin_catch(void *exceptionObject) _NOEXCEPT; +#endif extern _LIBCXXABI_FUNC_VIS void __cxa_end_catch(); #if defined(_LIBCXXABI_ARM_EHABI) extern _LIBCXXABI_FUNC_VIS bool @@ -148,17 +171,36 @@ 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 +#ifndef __EMSCRIPTEN__ extern _LIBCXXABI_FUNC_VIS void *__cxa_current_primary_exception() throw(); +#else +extern _LIBCXXABI_FUNC_VIS void *__cxa_current_primary_exception() _NOEXCEPT; +#endif extern _LIBCXXABI_FUNC_VIS void __cxa_rethrow_primary_exception(void *primary_exception); +#ifndef __EMSCRIPTEN__ extern _LIBCXXABI_FUNC_VIS void __cxa_increment_exception_refcount(void *primary_exception) throw(); +#else +extern _LIBCXXABI_FUNC_VIS void +__cxa_increment_exception_refcount(void *primary_exception) _NOEXCEPT; +#endif +#ifndef __EMSCRIPTEN__ extern _LIBCXXABI_FUNC_VIS void __cxa_decrement_exception_refcount(void *primary_exception) throw(); +#else +extern _LIBCXXABI_FUNC_VIS void +__cxa_decrement_exception_refcount(void *primary_exception) _NOEXCEPT; +#endif // Apple extension to support std::uncaught_exception() +#ifndef __EMSCRIPTEN__ extern _LIBCXXABI_FUNC_VIS bool __cxa_uncaught_exception() throw(); extern _LIBCXXABI_FUNC_VIS unsigned int __cxa_uncaught_exceptions() throw(); +#else +extern _LIBCXXABI_FUNC_VIS bool __cxa_uncaught_exception() _NOEXCEPT; +extern _LIBCXXABI_FUNC_VIS unsigned int __cxa_uncaught_exceptions() _NOEXCEPT; +#endif #if defined(__linux__) || defined(__Fuchsia__) // Linux and Fuchsia TLS support. Not yet an official part of the Itanium ABI. diff --git a/src/abort_message.cpp b/src/abort_message.cpp --- a/src/abort_message.cpp +++ b/src/abort_message.cpp @@ -33,12 +33,21 @@ void abort_message(const char* format, ...) // formatting into the variable-sized buffer fails. #if !defined(NDEBUG) || !defined(LIBCXXABI_BAREMETAL) { +#if defined(__EMSCRIPTEN__) && defined(NDEBUG) + // Just trap in a non-debug build. These internal libcxxabi assertions are + // very rare, and it's not worth linking in vfprintf stdio support or + // even minimal logging for them, as we'll have a proper call stack, which + // will show a call into "abort_message", and can help debugging. (In a + // debug build that won't be inlined.) + abort(); +#else fprintf(stderr, "libc++abi: "); va_list list; va_start(list, format); vfprintf(stderr, format, list); va_end(list); fprintf(stderr, "\n"); +#endif } #endif diff --git a/src/cxa_exception.cpp b/src/cxa_exception.cpp --- a/src/cxa_exception.cpp +++ b/src/cxa_exception.cpp @@ -180,7 +180,12 @@ 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) throw() { +#ifndef __EMSCRIPTEN__ +void *__cxa_allocate_exception(size_t thrown_size) throw() +#else +void *__cxa_allocate_exception(size_t thrown_size) _NOEXCEPT +#endif +{ 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 +203,12 @@ void *__cxa_allocate_exception(size_t thrown_size) throw() { // Free a __cxa_exception object allocated with __cxa_allocate_exception. -void __cxa_free_exception(void *thrown_object) throw() { +#ifndef __EMSCRIPTEN__ +void __cxa_free_exception(void *thrown_object) throw() +#else +void __cxa_free_exception(void *thrown_object) _NOEXCEPT +#endif +{ // Compute the size of the padding before the header. size_t header_offset = get_cxa_exception_offset(); char *raw_buffer = @@ -254,7 +264,13 @@ will call terminate, assuming that there was no handler for the exception. */ void -__cxa_throw(void *thrown_object, std::type_info *tinfo, void (_LIBCXXABI_DTOR_FUNC *dest)(void *)) { +#ifdef __USING_WASM_EXCEPTIONS__ +// In wasm, destructors return their 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); @@ -292,7 +308,12 @@ The adjusted pointer is computed by the personality routine during phase 1 Requires: exception is native */ -void *__cxa_get_exception_ptr(void *unwind_exception) throw() { +#ifndef __EMSCRIPTEN__ +void *__cxa_get_exception_ptr(void *unwind_exception) throw() +#else +void *__cxa_get_exception_ptr(void *unwind_exception) _NOEXCEPT +#endif +{ #if defined(_LIBCXXABI_ARM_EHABI) return reinterpret_cast( static_cast<_Unwind_Control_Block*>(unwind_exception)->barrier_cache.bitpattern[0]); @@ -307,7 +328,12 @@ void *__cxa_get_exception_ptr(void *unwind_exception) throw() { 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) throw() { +#ifndef __EMSCRIPTEN__ +bool __cxa_begin_cleanup(void *unwind_arg) throw() +#else +bool __cxa_begin_cleanup(void *unwind_arg) _NOEXCEPT +#endif +{ _Unwind_Exception* unwind_exception = static_cast<_Unwind_Exception*>(unwind_arg); __cxa_eh_globals* globals = __cxa_get_globals(); __cxa_exception* exception_header = @@ -430,8 +456,13 @@ to terminate or unexpected during unwinding. * If we haven't terminated, assume the exception object is just past the _Unwind_Exception and return a pointer to that. */ +#ifndef __EMSCRIPTEN__ void* __cxa_begin_catch(void* unwind_arg) throw() +#else +void* +__cxa_begin_catch(void* unwind_arg) _NOEXCEPT +#endif { _Unwind_Exception* unwind_exception = static_cast<_Unwind_Exception*>(unwind_arg); bool native_exception = __isOurExceptionClass(unwind_exception); @@ -646,8 +677,14 @@ void __cxa_rethrow() { Requires: If thrown_object is not NULL, it is a native exception. */ +#ifndef __EMSCRIPTEN__ void -__cxa_increment_exception_refcount(void *thrown_object) throw() { +__cxa_increment_exception_refcount(void *thrown_object) throw() +#else +void +__cxa_increment_exception_refcount(void *thrown_object) _NOEXCEPT +#endif +{ if (thrown_object != NULL ) { __cxa_exception* exception_header = cxa_exception_from_thrown_object(thrown_object); @@ -663,8 +700,14 @@ __cxa_increment_exception_refcount(void *thrown_object) throw() { Requires: If thrown_object is not NULL, it is a native exception. */ +#ifndef __EMSCRIPTEN__ _LIBCXXABI_NO_CFI -void __cxa_decrement_exception_refcount(void *thrown_object) throw() { +void __cxa_decrement_exception_refcount(void *thrown_object) throw() +#else +_LIBCXXABI_NO_CFI +void __cxa_decrement_exception_refcount(void *thrown_object) _NOEXCEPT +#endif +{ if (thrown_object != NULL ) { __cxa_exception* exception_header = cxa_exception_from_thrown_object(thrown_object); @@ -687,7 +730,12 @@ void __cxa_decrement_exception_refcount(void *thrown_object) throw() { 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() throw() { +#ifndef __EMSCRIPTEN__ +void *__cxa_current_primary_exception() throw() +#else +void *__cxa_current_primary_exception() _NOEXCEPT +#endif +{ // get the current exception __cxa_eh_globals* globals = __cxa_get_globals_fast(); if (NULL == globals) @@ -758,11 +806,21 @@ __cxa_rethrow_primary_exception(void* thrown_object) // If we return client will call terminate() } +#ifndef __EMSCRIPTEN__ bool __cxa_uncaught_exception() throw() { return __cxa_uncaught_exceptions() != 0; } +#else +bool +__cxa_uncaught_exception() _NOEXCEPT { return __cxa_uncaught_exceptions() != 0; } +#endif +#ifndef __EMSCRIPTEN__ unsigned int __cxa_uncaught_exceptions() throw() +#else +unsigned int +__cxa_uncaught_exceptions() _NOEXCEPT +#endif { // This does not report foreign exceptions in flight __cxa_eh_globals* globals = __cxa_get_globals_fast(); diff --git a/src/cxa_exception.h b/src/cxa_exception.h --- a/src/cxa_exception.h +++ b/src/cxa_exception.h @@ -19,6 +19,25 @@ namespace __cxxabiv1 { +#ifdef __USING_EMSCRIPTEN_EXCEPTIONS__ + +struct _LIBCXXABI_HIDDEN __cxa_exception { + size_t referenceCount; + std::type_info *exceptionType; + void (*exceptionDestructor)(void *); + uint8_t caught; + uint8_t rethrown; + void *adjustedPtr; + // Add padding to ensure that the size of __cxa_exception is a multiple of + // the maximum useful alignment for the target machine. This ensures that + // the thrown object that follows has that correct alignment. + void *padding; +}; + +static_assert(sizeof(__cxa_exception) % alignof(max_align_t) == 0, "__cxa_exception must have a size that is multipl of max alignment"); + +#else + static const uint64_t kOurExceptionClass = 0x434C4E47432B2B00; // CLNGC++\0 static const uint64_t kOurDependentExceptionClass = 0x434C4E47432B2B01; // CLNGC++\1 static const uint64_t get_vendor_and_language = 0xFFFFFFFFFFFFFF00; // mask for CLNGC++ @@ -43,7 +62,12 @@ struct _LIBCXXABI_HIDDEN __cxa_exception { // Manage the exception object itself. std::type_info *exceptionType; +#ifdef __USING_WASM_EXCEPTIONS__ + // In wasm, destructors return their argument + void *(_LIBCXXABI_DTOR_FUNC *exceptionDestructor)(void *); +#else void (_LIBCXXABI_DTOR_FUNC *exceptionDestructor)(void *); +#endif std::unexpected_handler unexpectedHandler; std::terminate_handler terminateHandler; @@ -159,6 +183,8 @@ extern "C" _LIBCXXABI_FUNC_VIS __cxa_eh_globals * __cxa_get_globals_fast (); extern "C" _LIBCXXABI_FUNC_VIS void * __cxa_allocate_dependent_exception (); extern "C" _LIBCXXABI_FUNC_VIS void __cxa_free_dependent_exception (void * dependent_exception); +#endif // !__USING_EMSCRIPTEN_EXCEPTIONS__ + } // namespace __cxxabiv1 #endif // _CXA_EXCEPTION_H diff --git a/src/cxa_handlers.cpp b/src/cxa_handlers.cpp --- a/src/cxa_handlers.cpp +++ b/src/cxa_handlers.cpp @@ -73,7 +73,7 @@ __attribute__((noreturn)) void terminate() noexcept { -#ifndef _LIBCXXABI_NO_EXCEPTIONS +#if !defined(_LIBCXXABI_NO_EXCEPTIONS) && !defined(__USING_EMSCRIPTEN_EXCEPTIONS__) // If there might be an uncaught exception using namespace __cxxabiv1; __cxa_eh_globals* globals = __cxa_get_globals_fast(); diff --git a/src/cxa_personality.cpp b/src/cxa_personality.cpp --- a/src/cxa_personality.cpp +++ b/src/cxa_personality.cpp @@ -41,6 +41,8 @@ extern "C" EXCEPTION_DISPOSITION _GCC_specific_handler(PEXCEPTION_RECORD, _Unwind_Personality_Fn); #endif +#define __USING_SJLJ_OR_WASM_EXCEPTIONS__ (__USING_SJLJ_EXCEPTIONS__ || __USING_WASM_EXCEPTIONS__) + /* Exception Header Layout: @@ -70,7 +72,7 @@ extern "C" EXCEPTION_DISPOSITION _GCC_specific_handler(PEXCEPTION_RECORD, +------------------+--+-----+-----+------------------------+--------------------------+ | 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 +86,7 @@ extern "C" EXCEPTION_DISPOSITION _GCC_specific_handler(PEXCEPTION_RECORD, | +-------------+---------------------------------+------------------------------+ | | ... | +----------------------------------------------------------------------------------+ -#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 +99,7 @@ extern "C" EXCEPTION_DISPOSITION _GCC_specific_handler(PEXCEPTION_RECORD, | +-------------+---------------------------------+------------------------------+ | | ... | +----------------------------------------------------------------------------------+ -#endif // __USING_SJLJ_EXCEPTIONS__ +#endif // __USING_SJLJ_OR_WASM_EXCEPTIONS__ +---------------------------------------------------------------------+ | Beginning of Action Table ttypeIndex == 0 : cleanup | | ... ttypeIndex > 0 : catch | @@ -547,7 +549,7 @@ void 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 +644,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_EXCEPTIONS__ +#ifdef __USING_SJLJ_OR_WASM_EXCEPTIONS__ if (ip == uintptr_t(-1)) { // no action @@ -652,9 +654,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_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,7 +678,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_EXCEPTIONS__ +#ifdef __USING_SJLJ_OR_WASM_EXCEPTIONS__ (void)callSiteEncoding; // When using SjLj exceptions, callSiteEncoding is never used #endif uint32_t callSiteTableLength = static_cast(readULEB128(&lsda)); @@ -687,7 +689,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_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 +697,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_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 +713,9 @@ static void scan_eh_tab(scan_results &results, _Unwind_Action actions, 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 +843,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_EXCEPTIONS__ +#ifndef __USING_SJLJ_OR_WASM_EXCEPTIONS__ else if (ipOffset < start) { // There is no call site for this ip @@ -849,7 +851,7 @@ static void scan_eh_tab(scan_results &results, _Unwind_Action actions, // 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 +908,9 @@ _UA_CLEANUP_PHASE */ #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 @@ -990,6 +994,16 @@ __gxx_personality_v0 exception_header->catchTemp = 0; #endif } +#ifdef __USING_WASM_EXCEPTIONS__ + // Wasm uses only one phase in _UA_CLEANUP_PHASE, so we should set + // these here. + __cxa_exception* exception_header = (__cxa_exception*)(unwind_exception+1) - 1; + exception_header->handlerSwitchValue = static_cast(results.ttypeIndex); + exception_header->actionRecord = results.actionRecord; + exception_header->languageSpecificData = results.languageSpecificData; + exception_header->catchTemp = reinterpret_cast(results.landingPad); + exception_header->adjustedPtr = results.adjustedPtr; +#endif return _URC_INSTALL_CONTEXT; } diff --git a/src/cxa_thread_atexit.cpp b/src/cxa_thread_atexit.cpp --- a/src/cxa_thread_atexit.cpp +++ b/src/cxa_thread_atexit.cpp @@ -112,9 +112,14 @@ extern "C" { #ifdef HAVE___CXA_THREAD_ATEXIT_IMPL return __cxa_thread_atexit_impl(dtor, obj, dso_symbol); #else +#ifndef __EMSCRIPTEN__ + // Emscripten doesn't fully support weak undefined symbols yet + // https://github.com/emscripten-core/emscripten/issues/12819 if (__cxa_thread_atexit_impl) { return __cxa_thread_atexit_impl(dtor, obj, dso_symbol); - } else { + } else +#endif + { // Initialize the dtors std::__libcpp_tls_key (uses __cxa_guard_*() for // one-time initialization and __cxa_atexit() for destruction) static DtorsManager manager; diff --git a/src/private_typeinfo.cpp b/src/private_typeinfo.cpp --- a/src/private_typeinfo.cpp +++ b/src/private_typeinfo.cpp @@ -1323,4 +1323,35 @@ __base_class_type_info::search_below_dst(__dynamic_cast_info* info, use_strcmp); } +// XXX EMSCRIPTEN + +#ifndef __USING_WASM_EXCEPTIONS__ + +// These functions are used by the emscripten-style exception handling +// mechanism. +// Note that they need to be included even in the `-noexcept` build of +// libc++abi to support the case where some parts of a project are built +// with exception catching enabled, but at link time exception catching +// is disabled. In this case dependencies to these functions (and the JS +// functions which call them) will still exist in the final build. +extern "C" { + +int __cxa_can_catch(__shim_type_info* catchType, __shim_type_info* excpType, void **thrown) { + //std::type_info *t1 = static_cast(catchType); + //std::type_info *t2 = static_cast(excpType); + //printf("can %s catch %s (%p)?\n", t1->name(), t2->name(), thrown); + + void *temp = *thrown; + int ret = catchType->can_catch(excpType, temp); + if (ret) *thrown = temp; // apply changes only if we are catching + return ret; +} + +int __cxa_is_pointer_type(__shim_type_info* type) { + return !!dynamic_cast<__pointer_type_info*>(type); +} + +} +#endif // __USING_EMSCRIPTEN_EXCEPTIONS__ + } // __cxxabiv1 diff --git a/src/stdlib_new_delete.cpp b/src/stdlib_new_delete.cpp --- a/src/stdlib_new_delete.cpp +++ b/src/stdlib_new_delete.cpp @@ -37,9 +37,17 @@ operator new(std::size_t size) _THROW_BAD_ALLOC else #ifndef _LIBCXXABI_NO_EXCEPTIONS throw std::bad_alloc(); +#ifdef __EMSCRIPTEN__ + // Abort here so that when exceptions are disabled, we do not just + // return 0 when malloc returns 0. + // We could also do this with set_new_handler, but that adds a + // global constructor and a table entry, overhead that we can avoid + // by doing it this way. + abort(); #else break; #endif +#endif } return p; }