01-emscripten.patch 9.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230
  1. --- contrib/libs/cxxsupp/libcxxabi/src/abort_message.cpp (d1f0c42a1f66211dc9b8b0cd7a0560228ddbc65c)
  2. +++ contrib/libs/cxxsupp/libcxxabi/src/abort_message.cpp (index)
  3. @@ -33,12 +33,21 @@ void abort_message(const char* format, ...)
  4. // formatting into the variable-sized buffer fails.
  5. #if !defined(NDEBUG) || !defined(LIBCXXABI_BAREMETAL)
  6. {
  7. +#if defined(__EMSCRIPTEN__) && defined(NDEBUG)
  8. + // Just trap in a non-debug build. These internal libcxxabi assertions are
  9. + // very rare, and it's not worth linking in vfprintf stdio support or
  10. + // even minimal logging for them, as we'll have a proper call stack, which
  11. + // will show a call into "abort_message", and can help debugging. (In a
  12. + // debug build that won't be inlined.)
  13. + abort();
  14. +#else
  15. fprintf(stderr, "libc++abi: ");
  16. va_list list;
  17. va_start(list, format);
  18. vfprintf(stderr, format, list);
  19. va_end(list);
  20. fprintf(stderr, "\n");
  21. +#endif
  22. }
  23. #endif
  24. --- contrib/libs/cxxsupp/libcxxabi/src/cxa_exception.cpp (d1f0c42a1f66211dc9b8b0cd7a0560228ddbc65c)
  25. +++ contrib/libs/cxxsupp/libcxxabi/src/cxa_exception.cpp (index)
  26. @@ -271,6 +271,13 @@ handler, _Unwind_RaiseException may return. In that case, __cxa_throw
  27. will call terminate, assuming that there was no handler for the
  28. exception.
  29. */
  30. +
  31. +#if defined(__EMSCRIPTEN__) && defined(__WASM_EXCEPTIONS__) && !defined(NDEBUG)
  32. +extern "C" {
  33. +void __throw_exception_with_stack_trace(_Unwind_Exception*);
  34. +} // extern "C"
  35. +#endif
  36. +
  37. void
  38. #ifdef __wasm__
  39. // In Wasm, a destructor returns its argument
  40. @@ -291,6 +298,10 @@ __cxa_throw(void *thrown_object, std::type_info *tinfo, void (_LIBCXXABI_DTOR_FU
  41. #ifdef __USING_SJLJ_EXCEPTIONS__
  42. _Unwind_SjLj_RaiseException(&exception_header->unwindHeader);
  43. +#elif defined(__EMSCRIPTEN__) && defined(__WASM_EXCEPTIONS__) && !defined(NDEBUG)
  44. + // In debug mode, call a JS library function to use WebAssembly.Exception JS
  45. + // API, which enables us to include stack traces
  46. + __throw_exception_with_stack_trace(&exception_header->unwindHeader);
  47. #else
  48. _Unwind_RaiseException(&exception_header->unwindHeader);
  49. #endif
  50. @@ -645,6 +656,10 @@ void __cxa_rethrow() {
  51. }
  52. #ifdef __USING_SJLJ_EXCEPTIONS__
  53. _Unwind_SjLj_RaiseException(&exception_header->unwindHeader);
  54. +#elif defined(__EMSCRIPTEN__) && defined(__WASM_EXCEPTIONS__) && !defined(NDEBUG)
  55. + // In debug mode, call a JS library function to use WebAssembly.Exception JS
  56. + // API, which enables us to include stack traces
  57. + __throw_exception_with_stack_trace(&exception_header->unwindHeader);
  58. #else
  59. _Unwind_RaiseException(&exception_header->unwindHeader);
  60. #endif
  61. @@ -770,8 +785,13 @@ __cxa_rethrow_primary_exception(void* thrown_object)
  62. dep_exception_header->unwindHeader.exception_cleanup = dependent_exception_cleanup;
  63. #ifdef __USING_SJLJ_EXCEPTIONS__
  64. _Unwind_SjLj_RaiseException(&dep_exception_header->unwindHeader);
  65. +#elif defined(__EMSCRIPTEN__) && defined(__WASM_EXCEPTIONS__) && !defined(NDEBUG)
  66. + // In debug mode, call a JS library function to use
  67. + // WebAssembly.Exception JS API, which enables us to include stack
  68. + // traces
  69. + __throw_exception_with_stack_trace(&exception_header->unwindHeader);
  70. #else
  71. - _Unwind_RaiseException(&dep_exception_header->unwindHeader);
  72. + _Unwind_RaiseException(&exception_header->unwindHeader);
  73. #endif
  74. // Some sort of unwinding error. Note that terminate is a handler.
  75. __cxa_begin_catch(&dep_exception_header->unwindHeader);
  76. --- contrib/libs/cxxsupp/libcxxabi/src/cxa_exception.h (d1f0c42a1f66211dc9b8b0cd7a0560228ddbc65c)
  77. +++ contrib/libs/cxxsupp/libcxxabi/src/cxa_exception.h (index)
  78. @@ -19,6 +19,26 @@
  79. namespace __cxxabiv1 {
  80. +#ifdef __EMSCRIPTEN_EXCEPTIONS__
  81. +
  82. +struct _LIBCXXABI_HIDDEN __cxa_exception {
  83. + size_t referenceCount;
  84. + std::type_info *exceptionType;
  85. + // In wasm, destructors return 'this' as in ARM
  86. + void* (*exceptionDestructor)(void *);
  87. + uint8_t caught;
  88. + uint8_t rethrown;
  89. + void *adjustedPtr;
  90. + // Add padding to ensure that the size of __cxa_exception is a multiple of
  91. + // the maximum useful alignment for the target machine. This ensures that
  92. + // the thrown object that follows has that correct alignment.
  93. + void *padding;
  94. +};
  95. +
  96. +static_assert(sizeof(__cxa_exception) % alignof(max_align_t) == 0, "__cxa_exception must have a size that is multipl of max alignment");
  97. +
  98. +#else
  99. +
  100. static const uint64_t kOurExceptionClass = 0x434C4E47432B2B00; // CLNGC++\0
  101. static const uint64_t kOurDependentExceptionClass = 0x434C4E47432B2B01; // CLNGC++\1
  102. static const uint64_t get_vendor_and_language = 0xFFFFFFFFFFFFFF00; // mask for CLNGC++
  103. @@ -164,6 +184,8 @@ extern "C" _LIBCXXABI_FUNC_VIS __cxa_eh_globals * __cxa_get_globals_fast ();
  104. extern "C" _LIBCXXABI_FUNC_VIS void * __cxa_allocate_dependent_exception ();
  105. extern "C" _LIBCXXABI_FUNC_VIS void __cxa_free_dependent_exception (void * dependent_exception);
  106. +#endif // !__EMSCRIPTEN_EXCEPTIONS__
  107. +
  108. } // namespace __cxxabiv1
  109. #endif // _CXA_EXCEPTION_H
  110. --- contrib/libs/cxxsupp/libcxxabi/src/cxa_handlers.cpp (d1f0c42a1f66211dc9b8b0cd7a0560228ddbc65c)
  111. +++ contrib/libs/cxxsupp/libcxxabi/src/cxa_handlers.cpp (index)
  112. @@ -73,7 +73,7 @@ __attribute__((noreturn))
  113. void
  114. terminate() noexcept
  115. {
  116. -#ifndef _LIBCXXABI_NO_EXCEPTIONS
  117. +#if !defined(_LIBCXXABI_NO_EXCEPTIONS) && !defined(__EMSCRIPTEN_EXCEPTIONS__)
  118. // If there might be an uncaught exception
  119. using namespace __cxxabiv1;
  120. __cxa_eh_globals* globals = __cxa_get_globals_fast();
  121. --- contrib/libs/cxxsupp/libcxxabi/src/cxa_personality.cpp (d1f0c42a1f66211dc9b8b0cd7a0560228ddbc65c)
  122. +++ contrib/libs/cxxsupp/libcxxabi/src/cxa_personality.cpp (index)
  123. @@ -663,6 +663,7 @@ static void scan_eh_tab(scan_results &results, _Unwind_Action actions,
  124. const uint8_t* lpStart = lpStartEncoding == DW_EH_PE_omit
  125. ? (const uint8_t*)funcStart
  126. : (const uint8_t*)readEncodedPointer(&lsda, lpStartEncoding, base);
  127. + (void)(lpStart); // Unused when using SjLj/Wasm exceptions
  128. uint8_t ttypeEncoding = *lsda++;
  129. if (ttypeEncoding != DW_EH_PE_omit)
  130. {
  131. @@ -676,7 +677,7 @@ static void scan_eh_tab(scan_results &results, _Unwind_Action actions,
  132. // includes current PC.
  133. uint8_t callSiteEncoding = *lsda++;
  134. #if defined(__USING_SJLJ_EXCEPTIONS__) || defined(__WASM_EXCEPTIONS__)
  135. - (void)callSiteEncoding; // When using SjLj/Wasm exceptions, callSiteEncoding is never used
  136. + (void)callSiteEncoding; // Unused when using SjLj/Wasm exceptions
  137. #endif
  138. uint32_t callSiteTableLength = static_cast<uint32_t>(readULEB128(&lsda));
  139. const uint8_t* callSiteTableStart = lsda;
  140. --- contrib/libs/cxxsupp/libcxxabi/src/cxa_thread_atexit.cpp (d1f0c42a1f66211dc9b8b0cd7a0560228ddbc65c)
  141. +++ contrib/libs/cxxsupp/libcxxabi/src/cxa_thread_atexit.cpp (index)
  142. @@ -112,9 +112,14 @@ extern "C" {
  143. #ifdef HAVE___CXA_THREAD_ATEXIT_IMPL
  144. return __cxa_thread_atexit_impl(dtor, obj, dso_symbol);
  145. #else
  146. +#ifndef __EMSCRIPTEN__
  147. + // Emscripten doesn't implement __cxa_thread_atexit_impl, so we can simply
  148. + // avoid this check.
  149. if (__cxa_thread_atexit_impl) {
  150. return __cxa_thread_atexit_impl(dtor, obj, dso_symbol);
  151. - } else {
  152. + } else
  153. +#endif
  154. + {
  155. // Initialize the dtors std::__libcpp_tls_key (uses __cxa_guard_*() for
  156. // one-time initialization and __cxa_atexit() for destruction)
  157. static DtorsManager manager;
  158. --- contrib/libs/cxxsupp/libcxxabi/src/private_typeinfo.cpp (d1f0c42a1f66211dc9b8b0cd7a0560228ddbc65c)
  159. +++ contrib/libs/cxxsupp/libcxxabi/src/private_typeinfo.cpp (index)
  160. @@ -1542,5 +1542,64 @@ __base_class_type_info::search_below_dst(__dynamic_cast_info* info,
  161. not_public_path,
  162. use_strcmp);
  163. }
  164. +} // __cxxabiv1
  165. +
  166. +
  167. +// XXX EMSCRIPTEN
  168. +#ifndef __WASM_EXCEPTIONS__
  169. +
  170. +#include "cxa_exception.h"
  171. +
  172. +namespace __cxxabiv1
  173. +{
  174. +
  175. +// These functions are used by the emscripten-style exception handling
  176. +// mechanism.
  177. +// Note that they need to be included even in the `-noexcept` build of
  178. +// libc++abi to support the case where some parts of a project are built
  179. +// with exception catching enabled, but at link time exception catching
  180. +// is disabled. In this case dependencies to these functions (and the JS
  181. +// functions which call them) will still exist in the final build.
  182. +extern "C" {
  183. +
  184. +int __cxa_can_catch(__shim_type_info* catchType, __shim_type_info* excpType, void **thrown) {
  185. + //std::type_info *t1 = static_cast<std::type_info*>(catchType);
  186. + //std::type_info *t2 = static_cast<std::type_info*>(excpType);
  187. + //printf("can %s catch %s (%p)?\n", t1->name(), t2->name(), thrown);
  188. +
  189. + void *temp = *thrown;
  190. + int ret = catchType->can_catch(excpType, temp);
  191. + if (ret) *thrown = temp; // apply changes only if we are catching
  192. + return ret;
  193. +}
  194. +
  195. +static
  196. +inline
  197. +__cxa_exception*
  198. +cxa_exception_from_thrown_object(void* thrown_object)
  199. +{
  200. + return static_cast<__cxa_exception*>(thrown_object) - 1;
  201. +}
  202. +
  203. +void *__cxa_get_exception_ptr(void *thrown_object) throw() {
  204. + // Get pointer which is expected to be received by catch clause in C++ code.
  205. + // It may be adjusted when the pointer is casted to some of the exception
  206. + // object base classes (e.g. when virtual inheritance is used). When a pointer
  207. + // is thrown this method should return the thrown pointer itself.
  208. + // Work around a fastcomp bug, this code is still included for some reason in
  209. + // a build without exceptions support.
  210. + __cxa_exception* ex = cxa_exception_from_thrown_object(thrown_object);
  211. + bool is_pointer = !!dynamic_cast<__pointer_type_info*>(ex->exceptionType);
  212. + if (is_pointer)
  213. + return *(void**)thrown_object;
  214. + if (ex->adjustedPtr)
  215. + return ex->adjustedPtr;
  216. + return ex;
  217. +}
  218. +
  219. +}
  220. } // __cxxabiv1
  221. +
  222. +#endif // !__WASM_EXCEPTIONS__
  223. +