aboutsummaryrefslogtreecommitdiffstats
path: root/contrib/libs/cxxsupp/libcxxabi/src
diff options
context:
space:
mode:
authordtorilov <dtorilov@yandex-team.com>2023-05-24 20:01:25 +0300
committerdtorilov <dtorilov@yandex-team.com>2023-05-24 20:01:25 +0300
commitf14549c83decddd1c8634ce32c8616ebb654c5a3 (patch)
tree5e016684f9d81eed049e148cf99f6a111410cdef /contrib/libs/cxxsupp/libcxxabi/src
parent39b4a50f6cc323d60f9cee1b3e3f55e1df2dd9bd (diff)
downloadydb-f14549c83decddd1c8634ce32c8616ebb654c5a3.tar.gz
YT-19142: Add emscripten patches to libcxxabi
Diffstat (limited to 'contrib/libs/cxxsupp/libcxxabi/src')
-rw-r--r--contrib/libs/cxxsupp/libcxxabi/src/abort_message.cpp9
-rw-r--r--contrib/libs/cxxsupp/libcxxabi/src/cxa_exception.cpp97
-rw-r--r--contrib/libs/cxxsupp/libcxxabi/src/cxa_exception.h26
-rw-r--r--contrib/libs/cxxsupp/libcxxabi/src/cxa_handlers.cpp2
-rw-r--r--contrib/libs/cxxsupp/libcxxabi/src/cxa_personality.cpp43
-rw-r--r--contrib/libs/cxxsupp/libcxxabi/src/cxa_thread_atexit.cpp7
-rw-r--r--contrib/libs/cxxsupp/libcxxabi/src/private_typeinfo.cpp31
-rw-r--r--contrib/libs/cxxsupp/libcxxabi/src/stdlib_new_delete.cpp8
8 files changed, 196 insertions, 27 deletions
diff --git a/contrib/libs/cxxsupp/libcxxabi/src/abort_message.cpp b/contrib/libs/cxxsupp/libcxxabi/src/abort_message.cpp
index 859a5031b93..0cbce088228 100644
--- a/contrib/libs/cxxsupp/libcxxabi/src/abort_message.cpp
+++ b/contrib/libs/cxxsupp/libcxxabi/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/contrib/libs/cxxsupp/libcxxabi/src/cxa_exception.cpp b/contrib/libs/cxxsupp/libcxxabi/src/cxa_exception.cpp
index 36388d50dad..82123825afc 100644
--- a/contrib/libs/cxxsupp/libcxxabi/src/cxa_exception.cpp
+++ b/contrib/libs/cxxsupp/libcxxabi/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 =
@@ -253,8 +263,21 @@ handler, _Unwind_RaiseException may return. In that case, __cxa_throw
will call terminate, assuming that there was no handler for the
exception.
*/
+
+#if defined(__USING_WASM_EXCEPTIONS__) && !defined(NDEBUG)
+extern "C" {
+void __throw_exception_with_stack_trace(_Unwind_Exception*);
+} // extern "C"
+#endif
+
void
-__cxa_throw(void *thrown_object, std::type_info *tinfo, void (*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 (*dest)(void *))
+#endif
+{
__cxa_eh_globals *globals = __cxa_get_globals();
__cxa_exception* exception_header = cxa_exception_from_thrown_object(thrown_object);
@@ -273,11 +296,27 @@ __cxa_throw(void *thrown_object, std::type_info *tinfo, void (*dest)(void *)) {
__asan_handle_no_return();
#endif
+#ifdef __EMSCRIPTEN__
+#ifdef __USING_SJLJ_EXCEPTIONS__
+ _Unwind_SjLj_RaiseException(&exception_header->unwindHeader);
+#elif __USING_WASM_EXCEPTIONS__
+#ifdef NDEBUG
+ _Unwind_RaiseException(&exception_header->unwindHeader);
+#else
+ // 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
+#else // !__EMSCRIPTEN__
#ifdef __USING_SJLJ_EXCEPTIONS__
_Unwind_SjLj_RaiseException(&exception_header->unwindHeader);
#else
_Unwind_RaiseException(&exception_header->unwindHeader);
#endif
+#endif
// This only happens when there is no handler, or some unexpected unwinding
// error happens.
failed_throw(exception_header);
@@ -292,7 +331,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<void*>(
static_cast<_Unwind_Control_Block*>(unwind_exception)->barrier_cache.bitpattern[0]);
@@ -307,7 +351,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 =
@@ -425,8 +474,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);
@@ -633,8 +687,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()
+#else
void
-__cxa_increment_exception_refcount(void *thrown_object) throw() {
+__cxa_increment_exception_refcount(void *thrown_object) _NOEXCEPT
+#endif
+{
if (thrown_object != NULL )
{
__cxa_exception* exception_header = cxa_exception_from_thrown_object(thrown_object);
@@ -650,8 +710,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()
+#else
_LIBCXXABI_NO_CFI
-void __cxa_decrement_exception_refcount(void *thrown_object) throw() {
+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);
@@ -674,7 +740,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)
@@ -745,11 +816,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/contrib/libs/cxxsupp/libcxxabi/src/cxa_exception.h b/contrib/libs/cxxsupp/libcxxabi/src/cxa_exception.h
index 7a32fb653b0..4d1770c3145 100644
--- a/contrib/libs/cxxsupp/libcxxabi/src/cxa_exception.h
+++ b/contrib/libs/cxxsupp/libcxxabi/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 *(*exceptionDestructor)(void *);
+#else
void (*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/contrib/libs/cxxsupp/libcxxabi/src/cxa_handlers.cpp b/contrib/libs/cxxsupp/libcxxabi/src/cxa_handlers.cpp
index 344250dde0c..07913fba397 100644
--- a/contrib/libs/cxxsupp/libcxxabi/src/cxa_handlers.cpp
+++ b/contrib/libs/cxxsupp/libcxxabi/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/contrib/libs/cxxsupp/libcxxabi/src/cxa_personality.cpp b/contrib/libs/cxxsupp/libcxxabi/src/cxa_personality.cpp
index f6e135f137c..12387bd7ad9 100644
--- a/contrib/libs/cxxsupp/libcxxabi/src/cxa_personality.cpp
+++ b/contrib/libs/cxxsupp/libcxxabi/src/cxa_personality.cpp
@@ -32,6 +32,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:
@@ -61,7 +63,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 |
@@ -75,7 +77,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 |
@@ -88,7 +90,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 |
@@ -538,7 +540,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.
@@ -633,7 +635,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
@@ -643,9 +645,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
@@ -667,7 +669,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<uint32_t>(readULEB128(&lsda));
@@ -678,7 +680,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);
@@ -686,15 +688,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
@@ -702,9 +704,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)
{
@@ -832,7 +834,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
@@ -840,7 +842,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
@@ -897,7 +899,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
@@ -962,6 +966,11 @@ __gxx_personality_v0
exc->languageSpecificData = results.languageSpecificData;
exc->catchTemp = reinterpret_cast<void*>(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;
}
diff --git a/contrib/libs/cxxsupp/libcxxabi/src/cxa_thread_atexit.cpp b/contrib/libs/cxxsupp/libcxxabi/src/cxa_thread_atexit.cpp
index 665f9e55694..bd7677a10ef 100644
--- a/contrib/libs/cxxsupp/libcxxabi/src/cxa_thread_atexit.cpp
+++ b/contrib/libs/cxxsupp/libcxxabi/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 implement __cxa_thread_atexit_impl, so we can simply
+ // avoid this check.
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/contrib/libs/cxxsupp/libcxxabi/src/private_typeinfo.cpp b/contrib/libs/cxxsupp/libcxxabi/src/private_typeinfo.cpp
index e1086661c01..8ee2e7607c7 100644
--- a/contrib/libs/cxxsupp/libcxxabi/src/private_typeinfo.cpp
+++ b/contrib/libs/cxxsupp/libcxxabi/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<std::type_info*>(catchType);
+ //std::type_info *t2 = static_cast<std::type_info*>(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/contrib/libs/cxxsupp/libcxxabi/src/stdlib_new_delete.cpp b/contrib/libs/cxxsupp/libcxxabi/src/stdlib_new_delete.cpp
index 4a664e15a50..48e509ba2b3 100644
--- a/contrib/libs/cxxsupp/libcxxabi/src/stdlib_new_delete.cpp
+++ b/contrib/libs/cxxsupp/libcxxabi/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;
}