01-commit-e0e82fc-initial.patch 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578
  1. From e0e82fcf1ab23805ce90709320ae688e1ea8be57 Mon Sep 17 00:00:00 2001
  2. From: Sam Clegg <sbc@chromium.org>
  3. Date: Sat, 22 May 2021 06:39:33 -0700
  4. Subject: [PATCH] Rebase of changed from emscripten-libs-13.0.0 onto
  5. llvmorg-14.0.0
  6. diff --git a/include/cxxabi.h b/include/cxxabi.h
  7. --- a/include/cxxabi.h
  8. +++ b/include/cxxabi.h
  9. @@ -39,21 +39,44 @@ namespace __cxxabiv1 {
  10. extern "C" {
  11. // 2.4.2 Allocating the Exception Object
  12. +#ifndef __EMSCRIPTEN__
  13. extern _LIBCXXABI_FUNC_VIS void *
  14. __cxa_allocate_exception(size_t thrown_size) throw();
  15. extern _LIBCXXABI_FUNC_VIS void
  16. __cxa_free_exception(void *thrown_exception) throw();
  17. +#else
  18. +extern _LIBCXXABI_FUNC_VIS void *
  19. +__cxa_allocate_exception(size_t thrown_size) _NOEXCEPT;
  20. +extern _LIBCXXABI_FUNC_VIS void
  21. +__cxa_free_exception(void *thrown_exception) _NOEXCEPT;
  22. +#endif
  23. // 2.4.3 Throwing the Exception Object
  24. +#ifdef __USING_WASM_EXCEPTIONS__
  25. +extern _LIBCXXABI_FUNC_VIS _LIBCXXABI_NORETURN void
  26. +__cxa_throw(void *thrown_exception, std::type_info *tinfo,
  27. + void *(_LIBCXXABI_DTOR_FUNC *dest)(void *));
  28. +#else
  29. extern _LIBCXXABI_FUNC_VIS _LIBCXXABI_NORETURN void
  30. __cxa_throw(void *thrown_exception, std::type_info *tinfo,
  31. void (_LIBCXXABI_DTOR_FUNC *dest)(void *));
  32. +#endif
  33. // 2.5.3 Exception Handlers
  34. +#ifndef __EMSCRIPTEN__
  35. extern _LIBCXXABI_FUNC_VIS void *
  36. __cxa_get_exception_ptr(void *exceptionObject) throw();
  37. +#else
  38. +extern _LIBCXXABI_FUNC_VIS void *
  39. +__cxa_get_exception_ptr(void *exceptionObject) _NOEXCEPT;
  40. +#endif
  41. +#ifndef __EMSCRIPTEN__
  42. extern _LIBCXXABI_FUNC_VIS void *
  43. __cxa_begin_catch(void *exceptionObject) throw();
  44. +#else
  45. +extern _LIBCXXABI_FUNC_VIS void *
  46. +__cxa_begin_catch(void *exceptionObject) _NOEXCEPT;
  47. +#endif
  48. extern _LIBCXXABI_FUNC_VIS void __cxa_end_catch();
  49. #if defined(_LIBCXXABI_ARM_EHABI)
  50. extern _LIBCXXABI_FUNC_VIS bool
  51. @@ -148,17 +171,36 @@ extern _LIBCXXABI_FUNC_VIS char *__cxa_demangle(const char *mangled_name,
  52. // Apple additions to support C++ 0x exception_ptr class
  53. // These are primitives to wrap a smart pointer around an exception object
  54. +#ifndef __EMSCRIPTEN__
  55. extern _LIBCXXABI_FUNC_VIS void *__cxa_current_primary_exception() throw();
  56. +#else
  57. +extern _LIBCXXABI_FUNC_VIS void *__cxa_current_primary_exception() _NOEXCEPT;
  58. +#endif
  59. extern _LIBCXXABI_FUNC_VIS void
  60. __cxa_rethrow_primary_exception(void *primary_exception);
  61. +#ifndef __EMSCRIPTEN__
  62. extern _LIBCXXABI_FUNC_VIS void
  63. __cxa_increment_exception_refcount(void *primary_exception) throw();
  64. +#else
  65. +extern _LIBCXXABI_FUNC_VIS void
  66. +__cxa_increment_exception_refcount(void *primary_exception) _NOEXCEPT;
  67. +#endif
  68. +#ifndef __EMSCRIPTEN__
  69. extern _LIBCXXABI_FUNC_VIS void
  70. __cxa_decrement_exception_refcount(void *primary_exception) throw();
  71. +#else
  72. +extern _LIBCXXABI_FUNC_VIS void
  73. +__cxa_decrement_exception_refcount(void *primary_exception) _NOEXCEPT;
  74. +#endif
  75. // Apple extension to support std::uncaught_exception()
  76. +#ifndef __EMSCRIPTEN__
  77. extern _LIBCXXABI_FUNC_VIS bool __cxa_uncaught_exception() throw();
  78. extern _LIBCXXABI_FUNC_VIS unsigned int __cxa_uncaught_exceptions() throw();
  79. +#else
  80. +extern _LIBCXXABI_FUNC_VIS bool __cxa_uncaught_exception() _NOEXCEPT;
  81. +extern _LIBCXXABI_FUNC_VIS unsigned int __cxa_uncaught_exceptions() _NOEXCEPT;
  82. +#endif
  83. #if defined(__linux__) || defined(__Fuchsia__)
  84. // Linux and Fuchsia TLS support. Not yet an official part of the Itanium ABI.
  85. diff --git a/src/abort_message.cpp b/src/abort_message.cpp
  86. --- a/src/abort_message.cpp
  87. +++ b/src/abort_message.cpp
  88. @@ -33,12 +33,21 @@ void abort_message(const char* format, ...)
  89. // formatting into the variable-sized buffer fails.
  90. #if !defined(NDEBUG) || !defined(LIBCXXABI_BAREMETAL)
  91. {
  92. +#if defined(__EMSCRIPTEN__) && defined(NDEBUG)
  93. + // Just trap in a non-debug build. These internal libcxxabi assertions are
  94. + // very rare, and it's not worth linking in vfprintf stdio support or
  95. + // even minimal logging for them, as we'll have a proper call stack, which
  96. + // will show a call into "abort_message", and can help debugging. (In a
  97. + // debug build that won't be inlined.)
  98. + abort();
  99. +#else
  100. fprintf(stderr, "libc++abi: ");
  101. va_list list;
  102. va_start(list, format);
  103. vfprintf(stderr, format, list);
  104. va_end(list);
  105. fprintf(stderr, "\n");
  106. +#endif
  107. }
  108. #endif
  109. diff --git a/src/cxa_exception.cpp b/src/cxa_exception.cpp
  110. --- a/src/cxa_exception.cpp
  111. +++ b/src/cxa_exception.cpp
  112. @@ -180,7 +180,12 @@ extern "C" {
  113. // object. Zero-fill the object. If memory can't be allocated, call
  114. // std::terminate. Return a pointer to the memory to be used for the
  115. // user's exception object.
  116. -void *__cxa_allocate_exception(size_t thrown_size) throw() {
  117. +#ifndef __EMSCRIPTEN__
  118. +void *__cxa_allocate_exception(size_t thrown_size) throw()
  119. +#else
  120. +void *__cxa_allocate_exception(size_t thrown_size) _NOEXCEPT
  121. +#endif
  122. +{
  123. size_t actual_size = cxa_exception_size_from_exception_thrown_size(thrown_size);
  124. // Allocate extra space before the __cxa_exception header to ensure the
  125. @@ -198,7 +203,12 @@ void *__cxa_allocate_exception(size_t thrown_size) throw() {
  126. // Free a __cxa_exception object allocated with __cxa_allocate_exception.
  127. -void __cxa_free_exception(void *thrown_object) throw() {
  128. +#ifndef __EMSCRIPTEN__
  129. +void __cxa_free_exception(void *thrown_object) throw()
  130. +#else
  131. +void __cxa_free_exception(void *thrown_object) _NOEXCEPT
  132. +#endif
  133. +{
  134. // Compute the size of the padding before the header.
  135. size_t header_offset = get_cxa_exception_offset();
  136. char *raw_buffer =
  137. @@ -254,7 +264,13 @@ will call terminate, assuming that there was no handler for the
  138. exception.
  139. */
  140. void
  141. -__cxa_throw(void *thrown_object, std::type_info *tinfo, void (_LIBCXXABI_DTOR_FUNC *dest)(void *)) {
  142. +#ifdef __USING_WASM_EXCEPTIONS__
  143. +// In wasm, destructors return their argument
  144. +__cxa_throw(void *thrown_object, std::type_info *tinfo, void *(_LIBCXXABI_DTOR_FUNC *dest)(void *))
  145. +#else
  146. +__cxa_throw(void *thrown_object, std::type_info *tinfo, void (_LIBCXXABI_DTOR_FUNC *dest)(void *))
  147. +#endif
  148. +{
  149. __cxa_eh_globals *globals = __cxa_get_globals();
  150. __cxa_exception* exception_header = cxa_exception_from_thrown_object(thrown_object);
  151. @@ -292,7 +308,12 @@ The adjusted pointer is computed by the personality routine during phase 1
  152. Requires: exception is native
  153. */
  154. -void *__cxa_get_exception_ptr(void *unwind_exception) throw() {
  155. +#ifndef __EMSCRIPTEN__
  156. +void *__cxa_get_exception_ptr(void *unwind_exception) throw()
  157. +#else
  158. +void *__cxa_get_exception_ptr(void *unwind_exception) _NOEXCEPT
  159. +#endif
  160. +{
  161. #if defined(_LIBCXXABI_ARM_EHABI)
  162. return reinterpret_cast<void*>(
  163. static_cast<_Unwind_Control_Block*>(unwind_exception)->barrier_cache.bitpattern[0]);
  164. @@ -307,7 +328,12 @@ void *__cxa_get_exception_ptr(void *unwind_exception) throw() {
  165. The routine to be called before the cleanup. This will save __cxa_exception in
  166. __cxa_eh_globals, so that __cxa_end_cleanup() can recover later.
  167. */
  168. -bool __cxa_begin_cleanup(void *unwind_arg) throw() {
  169. +#ifndef __EMSCRIPTEN__
  170. +bool __cxa_begin_cleanup(void *unwind_arg) throw()
  171. +#else
  172. +bool __cxa_begin_cleanup(void *unwind_arg) _NOEXCEPT
  173. +#endif
  174. +{
  175. _Unwind_Exception* unwind_exception = static_cast<_Unwind_Exception*>(unwind_arg);
  176. __cxa_eh_globals* globals = __cxa_get_globals();
  177. __cxa_exception* exception_header =
  178. @@ -430,8 +456,13 @@ to terminate or unexpected during unwinding.
  179. * If we haven't terminated, assume the exception object is just past the
  180. _Unwind_Exception and return a pointer to that.
  181. */
  182. +#ifndef __EMSCRIPTEN__
  183. void*
  184. __cxa_begin_catch(void* unwind_arg) throw()
  185. +#else
  186. +void*
  187. +__cxa_begin_catch(void* unwind_arg) _NOEXCEPT
  188. +#endif
  189. {
  190. _Unwind_Exception* unwind_exception = static_cast<_Unwind_Exception*>(unwind_arg);
  191. bool native_exception = __isOurExceptionClass(unwind_exception);
  192. @@ -646,8 +677,14 @@ void __cxa_rethrow() {
  193. Requires: If thrown_object is not NULL, it is a native exception.
  194. */
  195. +#ifndef __EMSCRIPTEN__
  196. void
  197. -__cxa_increment_exception_refcount(void *thrown_object) throw() {
  198. +__cxa_increment_exception_refcount(void *thrown_object) throw()
  199. +#else
  200. +void
  201. +__cxa_increment_exception_refcount(void *thrown_object) _NOEXCEPT
  202. +#endif
  203. +{
  204. if (thrown_object != NULL )
  205. {
  206. __cxa_exception* exception_header = cxa_exception_from_thrown_object(thrown_object);
  207. @@ -663,8 +700,14 @@ __cxa_increment_exception_refcount(void *thrown_object) throw() {
  208. Requires: If thrown_object is not NULL, it is a native exception.
  209. */
  210. +#ifndef __EMSCRIPTEN__
  211. _LIBCXXABI_NO_CFI
  212. -void __cxa_decrement_exception_refcount(void *thrown_object) throw() {
  213. +void __cxa_decrement_exception_refcount(void *thrown_object) throw()
  214. +#else
  215. +_LIBCXXABI_NO_CFI
  216. +void __cxa_decrement_exception_refcount(void *thrown_object) _NOEXCEPT
  217. +#endif
  218. +{
  219. if (thrown_object != NULL )
  220. {
  221. __cxa_exception* exception_header = cxa_exception_from_thrown_object(thrown_object);
  222. @@ -687,7 +730,12 @@ void __cxa_decrement_exception_refcount(void *thrown_object) throw() {
  223. been no exceptions thrown, ever, on this thread, we can return NULL without
  224. the need to allocate the exception-handling globals.
  225. */
  226. -void *__cxa_current_primary_exception() throw() {
  227. +#ifndef __EMSCRIPTEN__
  228. +void *__cxa_current_primary_exception() throw()
  229. +#else
  230. +void *__cxa_current_primary_exception() _NOEXCEPT
  231. +#endif
  232. +{
  233. // get the current exception
  234. __cxa_eh_globals* globals = __cxa_get_globals_fast();
  235. if (NULL == globals)
  236. @@ -758,11 +806,21 @@ __cxa_rethrow_primary_exception(void* thrown_object)
  237. // If we return client will call terminate()
  238. }
  239. +#ifndef __EMSCRIPTEN__
  240. bool
  241. __cxa_uncaught_exception() throw() { return __cxa_uncaught_exceptions() != 0; }
  242. +#else
  243. +bool
  244. +__cxa_uncaught_exception() _NOEXCEPT { return __cxa_uncaught_exceptions() != 0; }
  245. +#endif
  246. +#ifndef __EMSCRIPTEN__
  247. unsigned int
  248. __cxa_uncaught_exceptions() throw()
  249. +#else
  250. +unsigned int
  251. +__cxa_uncaught_exceptions() _NOEXCEPT
  252. +#endif
  253. {
  254. // This does not report foreign exceptions in flight
  255. __cxa_eh_globals* globals = __cxa_get_globals_fast();
  256. diff --git a/src/cxa_exception.h b/src/cxa_exception.h
  257. --- a/src/cxa_exception.h
  258. +++ b/src/cxa_exception.h
  259. @@ -19,6 +19,25 @@
  260. namespace __cxxabiv1 {
  261. +#ifdef __USING_EMSCRIPTEN_EXCEPTIONS__
  262. +
  263. +struct _LIBCXXABI_HIDDEN __cxa_exception {
  264. + size_t referenceCount;
  265. + std::type_info *exceptionType;
  266. + void (*exceptionDestructor)(void *);
  267. + uint8_t caught;
  268. + uint8_t rethrown;
  269. + void *adjustedPtr;
  270. + // Add padding to ensure that the size of __cxa_exception is a multiple of
  271. + // the maximum useful alignment for the target machine. This ensures that
  272. + // the thrown object that follows has that correct alignment.
  273. + void *padding;
  274. +};
  275. +
  276. +static_assert(sizeof(__cxa_exception) % alignof(max_align_t) == 0, "__cxa_exception must have a size that is multipl of max alignment");
  277. +
  278. +#else
  279. +
  280. static const uint64_t kOurExceptionClass = 0x434C4E47432B2B00; // CLNGC++\0
  281. static const uint64_t kOurDependentExceptionClass = 0x434C4E47432B2B01; // CLNGC++\1
  282. static const uint64_t get_vendor_and_language = 0xFFFFFFFFFFFFFF00; // mask for CLNGC++
  283. @@ -43,7 +62,12 @@ struct _LIBCXXABI_HIDDEN __cxa_exception {
  284. // Manage the exception object itself.
  285. std::type_info *exceptionType;
  286. +#ifdef __USING_WASM_EXCEPTIONS__
  287. + // In wasm, destructors return their argument
  288. + void *(_LIBCXXABI_DTOR_FUNC *exceptionDestructor)(void *);
  289. +#else
  290. void (_LIBCXXABI_DTOR_FUNC *exceptionDestructor)(void *);
  291. +#endif
  292. std::unexpected_handler unexpectedHandler;
  293. std::terminate_handler terminateHandler;
  294. @@ -159,6 +183,8 @@ extern "C" _LIBCXXABI_FUNC_VIS __cxa_eh_globals * __cxa_get_globals_fast ();
  295. extern "C" _LIBCXXABI_FUNC_VIS void * __cxa_allocate_dependent_exception ();
  296. extern "C" _LIBCXXABI_FUNC_VIS void __cxa_free_dependent_exception (void * dependent_exception);
  297. +#endif // !__USING_EMSCRIPTEN_EXCEPTIONS__
  298. +
  299. } // namespace __cxxabiv1
  300. #endif // _CXA_EXCEPTION_H
  301. diff --git a/src/cxa_handlers.cpp b/src/cxa_handlers.cpp
  302. --- a/src/cxa_handlers.cpp
  303. +++ b/src/cxa_handlers.cpp
  304. @@ -73,7 +73,7 @@ __attribute__((noreturn))
  305. void
  306. terminate() noexcept
  307. {
  308. -#ifndef _LIBCXXABI_NO_EXCEPTIONS
  309. +#if !defined(_LIBCXXABI_NO_EXCEPTIONS) && !defined(__USING_EMSCRIPTEN_EXCEPTIONS__)
  310. // If there might be an uncaught exception
  311. using namespace __cxxabiv1;
  312. __cxa_eh_globals* globals = __cxa_get_globals_fast();
  313. diff --git a/src/cxa_personality.cpp b/src/cxa_personality.cpp
  314. --- a/src/cxa_personality.cpp
  315. +++ b/src/cxa_personality.cpp
  316. @@ -41,6 +41,8 @@ extern "C" EXCEPTION_DISPOSITION _GCC_specific_handler(PEXCEPTION_RECORD,
  317. _Unwind_Personality_Fn);
  318. #endif
  319. +#define __USING_SJLJ_OR_WASM_EXCEPTIONS__ (__USING_SJLJ_EXCEPTIONS__ || __USING_WASM_EXCEPTIONS__)
  320. +
  321. /*
  322. Exception Header Layout:
  323. @@ -70,7 +72,7 @@ extern "C" EXCEPTION_DISPOSITION _GCC_specific_handler(PEXCEPTION_RECORD,
  324. +------------------+--+-----+-----+------------------------+--------------------------+
  325. | callSiteTableLength | (ULEB128) | Call Site Table length, used to find Action table |
  326. +---------------------+-----------+---------------------------------------------------+
  327. -#ifndef __USING_SJLJ_EXCEPTIONS__
  328. +#ifndef __USING_SJLJ_OR_WASM_EXCEPTIONS__
  329. +---------------------+-----------+------------------------------------------------+
  330. | Beginning of Call Site Table The current ip lies within the |
  331. | ... (start, length) range of one of these |
  332. @@ -84,7 +86,7 @@ extern "C" EXCEPTION_DISPOSITION _GCC_specific_handler(PEXCEPTION_RECORD,
  333. | +-------------+---------------------------------+------------------------------+ |
  334. | ... |
  335. +----------------------------------------------------------------------------------+
  336. -#else // __USING_SJLJ_EXCEPTIONS__
  337. +#else // !__USING_SJLJ_OR_WASM_EXCEPTIONS__
  338. +---------------------+-----------+------------------------------------------------+
  339. | Beginning of Call Site Table The current ip is a 1-based index into |
  340. | ... this table. Or it is -1 meaning no |
  341. @@ -97,7 +99,7 @@ extern "C" EXCEPTION_DISPOSITION _GCC_specific_handler(PEXCEPTION_RECORD,
  342. | +-------------+---------------------------------+------------------------------+ |
  343. | ... |
  344. +----------------------------------------------------------------------------------+
  345. -#endif // __USING_SJLJ_EXCEPTIONS__
  346. +#endif // __USING_SJLJ_OR_WASM_EXCEPTIONS__
  347. +---------------------------------------------------------------------+
  348. | Beginning of Action Table ttypeIndex == 0 : cleanup |
  349. | ... ttypeIndex > 0 : catch |
  350. @@ -547,7 +549,7 @@ void
  351. set_registers(_Unwind_Exception* unwind_exception, _Unwind_Context* context,
  352. const scan_results& results)
  353. {
  354. -#if defined(__USING_SJLJ_EXCEPTIONS__)
  355. +#ifdef __USING_SJLJ_OR_WASM_EXCEPTIONS__
  356. #define __builtin_eh_return_data_regno(regno) regno
  357. #elif defined(__ibmxl__)
  358. // IBM xlclang++ compiler does not support __builtin_eh_return_data_regno.
  359. @@ -642,7 +644,7 @@ static void scan_eh_tab(scan_results &results, _Unwind_Action actions,
  360. // Get beginning current frame's code (as defined by the
  361. // emitted dwarf code)
  362. uintptr_t funcStart = _Unwind_GetRegionStart(context);
  363. -#ifdef __USING_SJLJ_EXCEPTIONS__
  364. +#ifdef __USING_SJLJ_OR_WASM_EXCEPTIONS__
  365. if (ip == uintptr_t(-1))
  366. {
  367. // no action
  368. @@ -652,9 +654,9 @@ static void scan_eh_tab(scan_results &results, _Unwind_Action actions,
  369. else if (ip == 0)
  370. call_terminate(native_exception, unwind_exception);
  371. // ip is 1-based index into call site table
  372. -#else // !__USING_SJLJ_EXCEPTIONS__
  373. +#else // !__USING_SJLJ_OR_WASM_EXCEPTIONS__
  374. uintptr_t ipOffset = ip - funcStart;
  375. -#endif // !defined(_USING_SLJL_EXCEPTIONS__)
  376. +#endif // !defined(__USING_SJLJ_OR_WASM_EXCEPTIONS__)
  377. const uint8_t* classInfo = NULL;
  378. // Note: See JITDwarfEmitter::EmitExceptionTable(...) for corresponding
  379. // dwarf emission
  380. @@ -676,7 +678,7 @@ static void scan_eh_tab(scan_results &results, _Unwind_Action actions,
  381. // Walk call-site table looking for range that
  382. // includes current PC.
  383. uint8_t callSiteEncoding = *lsda++;
  384. -#ifdef __USING_SJLJ_EXCEPTIONS__
  385. +#ifdef __USING_SJLJ_OR_WASM_EXCEPTIONS__
  386. (void)callSiteEncoding; // When using SjLj exceptions, callSiteEncoding is never used
  387. #endif
  388. uint32_t callSiteTableLength = static_cast<uint32_t>(readULEB128(&lsda));
  389. @@ -687,7 +689,7 @@ static void scan_eh_tab(scan_results &results, _Unwind_Action actions,
  390. while (callSitePtr < callSiteTableEnd)
  391. {
  392. // There is one entry per call site.
  393. -#ifndef __USING_SJLJ_EXCEPTIONS__
  394. +#ifndef __USING_SJLJ_OR_WASM_EXCEPTIONS__
  395. // The call sites are non-overlapping in [start, start+length)
  396. // The call sites are ordered in increasing value of start
  397. uintptr_t start = readEncodedPointer(&callSitePtr, callSiteEncoding);
  398. @@ -695,15 +697,15 @@ static void scan_eh_tab(scan_results &results, _Unwind_Action actions,
  399. uintptr_t landingPad = readEncodedPointer(&callSitePtr, callSiteEncoding);
  400. uintptr_t actionEntry = readULEB128(&callSitePtr);
  401. if ((start <= ipOffset) && (ipOffset < (start + length)))
  402. -#else // __USING_SJLJ_EXCEPTIONS__
  403. +#else // __USING_SJLJ_OR_WASM_EXCEPTIONS__
  404. // ip is 1-based index into this table
  405. uintptr_t landingPad = readULEB128(&callSitePtr);
  406. uintptr_t actionEntry = readULEB128(&callSitePtr);
  407. if (--ip == 0)
  408. -#endif // __USING_SJLJ_EXCEPTIONS__
  409. +#endif // __USING_SJLJ_OR_WASM_EXCEPTIONS__
  410. {
  411. // Found the call site containing ip.
  412. -#ifndef __USING_SJLJ_EXCEPTIONS__
  413. +#ifndef __USING_SJLJ_OR_WASM_EXCEPTIONS__
  414. if (landingPad == 0)
  415. {
  416. // No handler here
  417. @@ -711,9 +713,9 @@ static void scan_eh_tab(scan_results &results, _Unwind_Action actions,
  418. return;
  419. }
  420. landingPad = (uintptr_t)lpStart + landingPad;
  421. -#else // __USING_SJLJ_EXCEPTIONS__
  422. +#else // __USING_SJLJ_OR_WASM_EXCEPTIONS__
  423. ++landingPad;
  424. -#endif // __USING_SJLJ_EXCEPTIONS__
  425. +#endif // __USING_SJLJ_OR_WASM_EXCEPTIONS__
  426. results.landingPad = landingPad;
  427. if (actionEntry == 0)
  428. {
  429. @@ -841,7 +843,7 @@ static void scan_eh_tab(scan_results &results, _Unwind_Action actions,
  430. action += actionOffset;
  431. } // there is no break out of this loop, only return
  432. }
  433. -#ifndef __USING_SJLJ_EXCEPTIONS__
  434. +#ifndef __USING_SJLJ_OR_WASM_EXCEPTIONS__
  435. else if (ipOffset < start)
  436. {
  437. // There is no call site for this ip
  438. @@ -849,7 +851,7 @@ static void scan_eh_tab(scan_results &results, _Unwind_Action actions,
  439. // Possible stack corruption.
  440. call_terminate(native_exception, unwind_exception);
  441. }
  442. -#endif // !__USING_SJLJ_EXCEPTIONS__
  443. +#endif // !__USING_SJLJ_OR_WASM_EXCEPTIONS__
  444. } // there might be some tricky cases which break out of this loop
  445. // It is possible that no eh table entry specify how to handle
  446. @@ -906,7 +908,9 @@ _UA_CLEANUP_PHASE
  447. */
  448. #if !defined(_LIBCXXABI_ARM_EHABI)
  449. -#if defined(__SEH__) && !defined(__USING_SJLJ_EXCEPTIONS__)
  450. +#ifdef __USING_WASM_EXCEPTIONS__
  451. +_Unwind_Reason_Code __gxx_personality_wasm0
  452. +#elif defined(__SEH__) && !defined(__USING_SJLJ_EXCEPTIONS__)
  453. static _Unwind_Reason_Code __gxx_personality_imp
  454. #else
  455. _LIBCXXABI_FUNC_VIS _Unwind_Reason_Code
  456. @@ -990,6 +994,16 @@ __gxx_personality_v0
  457. exception_header->catchTemp = 0;
  458. #endif
  459. }
  460. +#ifdef __USING_WASM_EXCEPTIONS__
  461. + // Wasm uses only one phase in _UA_CLEANUP_PHASE, so we should set
  462. + // these here.
  463. + __cxa_exception* exception_header = (__cxa_exception*)(unwind_exception+1) - 1;
  464. + exception_header->handlerSwitchValue = static_cast<int>(results.ttypeIndex);
  465. + exception_header->actionRecord = results.actionRecord;
  466. + exception_header->languageSpecificData = results.languageSpecificData;
  467. + exception_header->catchTemp = reinterpret_cast<void*>(results.landingPad);
  468. + exception_header->adjustedPtr = results.adjustedPtr;
  469. +#endif
  470. return _URC_INSTALL_CONTEXT;
  471. }
  472. diff --git a/src/cxa_thread_atexit.cpp b/src/cxa_thread_atexit.cpp
  473. --- a/src/cxa_thread_atexit.cpp
  474. +++ b/src/cxa_thread_atexit.cpp
  475. @@ -112,9 +112,14 @@ extern "C" {
  476. #ifdef HAVE___CXA_THREAD_ATEXIT_IMPL
  477. return __cxa_thread_atexit_impl(dtor, obj, dso_symbol);
  478. #else
  479. +#ifndef __EMSCRIPTEN__
  480. + // Emscripten doesn't fully support weak undefined symbols yet
  481. + // https://github.com/emscripten-core/emscripten/issues/12819
  482. if (__cxa_thread_atexit_impl) {
  483. return __cxa_thread_atexit_impl(dtor, obj, dso_symbol);
  484. - } else {
  485. + } else
  486. +#endif
  487. + {
  488. // Initialize the dtors std::__libcpp_tls_key (uses __cxa_guard_*() for
  489. // one-time initialization and __cxa_atexit() for destruction)
  490. static DtorsManager manager;
  491. diff --git a/src/private_typeinfo.cpp b/src/private_typeinfo.cpp
  492. --- a/src/private_typeinfo.cpp
  493. +++ b/src/private_typeinfo.cpp
  494. @@ -1323,4 +1323,35 @@ __base_class_type_info::search_below_dst(__dynamic_cast_info* info,
  495. use_strcmp);
  496. }
  497. +// XXX EMSCRIPTEN
  498. +
  499. +#ifndef __USING_WASM_EXCEPTIONS__
  500. +
  501. +// These functions are used by the emscripten-style exception handling
  502. +// mechanism.
  503. +// Note that they need to be included even in the `-noexcept` build of
  504. +// libc++abi to support the case where some parts of a project are built
  505. +// with exception catching enabled, but at link time exception catching
  506. +// is disabled. In this case dependencies to these functions (and the JS
  507. +// functions which call them) will still exist in the final build.
  508. +extern "C" {
  509. +
  510. +int __cxa_can_catch(__shim_type_info* catchType, __shim_type_info* excpType, void **thrown) {
  511. + //std::type_info *t1 = static_cast<std::type_info*>(catchType);
  512. + //std::type_info *t2 = static_cast<std::type_info*>(excpType);
  513. + //printf("can %s catch %s (%p)?\n", t1->name(), t2->name(), thrown);
  514. +
  515. + void *temp = *thrown;
  516. + int ret = catchType->can_catch(excpType, temp);
  517. + if (ret) *thrown = temp; // apply changes only if we are catching
  518. + return ret;
  519. +}
  520. +
  521. +int __cxa_is_pointer_type(__shim_type_info* type) {
  522. + return !!dynamic_cast<__pointer_type_info*>(type);
  523. +}
  524. +
  525. +}
  526. +#endif // __USING_EMSCRIPTEN_EXCEPTIONS__
  527. +
  528. } // __cxxabiv1
  529. diff --git a/src/stdlib_new_delete.cpp b/src/stdlib_new_delete.cpp
  530. --- a/src/stdlib_new_delete.cpp
  531. +++ b/src/stdlib_new_delete.cpp
  532. @@ -37,9 +37,17 @@ operator new(std::size_t size) _THROW_BAD_ALLOC
  533. else
  534. #ifndef _LIBCXXABI_NO_EXCEPTIONS
  535. throw std::bad_alloc();
  536. +#ifdef __EMSCRIPTEN__
  537. + // Abort here so that when exceptions are disabled, we do not just
  538. + // return 0 when malloc returns 0.
  539. + // We could also do this with set_new_handler, but that adds a
  540. + // global constructor and a table entry, overhead that we can avoid
  541. + // by doing it this way.
  542. + abort();
  543. #else
  544. break;
  545. #endif
  546. +#endif
  547. }
  548. return p;
  549. }