Skip to content

[libunwind][libcxx][libcxxabi] Fix Exception Handling build for wasm #140365

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion compiler-rt/lib/builtins/fp_compare_impl.inc
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
// functions. We need to ensure that the return value is sign-extended in the
// same way as GCC expects (since otherwise GCC-generated __builtin_isinf
// returns true for finite 128-bit floating-point numbers).
#if defined(__aarch64__) || defined(__arm64ec__)
#if defined(__aarch64__) || defined(__arm64ec__) || defined(__wasm__)
// AArch64 GCC overrides libgcc_cmp_return to use int instead of long.
typedef int CMP_RESULT;
#elif __SIZEOF_POINTER__ == 8 && __SIZEOF_LONG__ == 4
Expand Down
21 changes: 10 additions & 11 deletions libcxx/include/__exception/exception_ptr.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,22 +28,21 @@

namespace __cxxabiv1 {

# if defined(__wasm__)
typedef void* (*__libcpp_exception_destructor_func)(void*);
# elif defined(_WIN32)
typedef void(__thiscall* __libcpp_exception_destructor_func)(void*);
# else
typedef void (*__libcpp_exception_destructor_func)(void*);
# endif

extern "C" {
_LIBCPP_OVERRIDABLE_FUNC_VIS void* __cxa_allocate_exception(size_t) throw();
_LIBCPP_OVERRIDABLE_FUNC_VIS void __cxa_free_exception(void*) throw();

struct __cxa_exception;
_LIBCPP_OVERRIDABLE_FUNC_VIS __cxa_exception* __cxa_init_primary_exception(
void*,
std::type_info*,
# if defined(_WIN32)
void(__thiscall*)(void*)) throw();
# elif defined(__wasm__)
// In Wasm, a destructor returns its argument
void* (*)(void*)) throw();
# else
void (*)(void*)) throw();
# endif
_LIBCPP_OVERRIDABLE_FUNC_VIS __cxa_exception*
__cxa_init_primary_exception(void*, std::type_info*, __libcpp_exception_destructor_func) throw();
}

} // namespace __cxxabiv1
Expand Down
134 changes: 55 additions & 79 deletions libcxxabi/include/cxxabi.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,49 +20,41 @@
#include <__cxxabi_config.h>

#define _LIBCPPABI_VERSION 15000
#define _LIBCXXABI_NORETURN __attribute__((noreturn))
#define _LIBCXXABI_NORETURN __attribute__((noreturn))
#define _LIBCXXABI_ALWAYS_COLD __attribute__((cold))

#ifdef __cplusplus

namespace std {
#if defined(_WIN32)
# if defined(_WIN32)
class _LIBCXXABI_TYPE_VIS type_info; // forward declaration
#else
# else
class type_info; // forward declaration
#endif
}

# endif
} // namespace std

// runtime routines use C calling conventions, but are in __cxxabiv1 namespace
namespace __cxxabiv1 {

struct __cxa_exception;
# if defined(__wasm__)
typedef void* (*__libcxxabi_exception_destructor_func)(void*);
# else
typedef void(_LIBCXXABI_DTOR_FUNC* __libcxxabi_exception_destructor_func)(void*);
# endif

extern "C" {
extern "C" {

// 2.4.2 Allocating the Exception Object
extern _LIBCXXABI_FUNC_VIS void *
__cxa_allocate_exception(size_t thrown_size) _LIBCXXABI_NOEXCEPT;
extern _LIBCXXABI_FUNC_VIS void
__cxa_free_exception(void *thrown_exception) _LIBCXXABI_NOEXCEPT;
extern _LIBCXXABI_FUNC_VIS void* __cxa_allocate_exception(size_t thrown_size) _LIBCXXABI_NOEXCEPT;
extern _LIBCXXABI_FUNC_VIS void __cxa_free_exception(void* thrown_exception) _LIBCXXABI_NOEXCEPT;
// This function is an LLVM extension, which mirrors the same extension in libsupc++ and libcxxrt
extern _LIBCXXABI_FUNC_VIS __cxa_exception*
#ifdef __wasm__
// In Wasm, a destructor returns its argument
__cxa_init_primary_exception(void* object, std::type_info* tinfo, void*(_LIBCXXABI_DTOR_FUNC* dest)(void*)) _LIBCXXABI_NOEXCEPT;
#else
__cxa_init_primary_exception(void* object, std::type_info* tinfo, void(_LIBCXXABI_DTOR_FUNC* dest)(void*)) _LIBCXXABI_NOEXCEPT;
#endif
extern _LIBCXXABI_FUNC_VIS __cxa_exception* __cxa_init_primary_exception(void* object, std::type_info* tinfo,
__libcxxabi_exception_destructor_func) _LIBCXXABI_NOEXCEPT;

// 2.4.3 Throwing the Exception Object
extern _LIBCXXABI_FUNC_VIS _LIBCXXABI_NORETURN void
__cxa_throw(void *thrown_exception, std::type_info *tinfo,
#ifdef __wasm__
void *(_LIBCXXABI_DTOR_FUNC *dest)(void *));
#else
void (_LIBCXXABI_DTOR_FUNC *dest)(void *));
#endif
extern _LIBCXXABI_FUNC_VIS _LIBCXXABI_NORETURN void __cxa_throw(void* thrown_exception, std::type_info* tinfo,
__libcxxabi_exception_destructor_func);

// 2.5.3 Exception Handlers
extern _LIBCXXABI_FUNC_VIS void *
Expand All @@ -74,8 +66,8 @@ extern _LIBCXXABI_FUNC_VIS void __cxa_end_catch();
extern _LIBCXXABI_FUNC_VIS bool
__cxa_begin_cleanup(void *exceptionObject) _LIBCXXABI_NOEXCEPT;
extern _LIBCXXABI_FUNC_VIS void __cxa_end_cleanup();
#endif
extern _LIBCXXABI_FUNC_VIS std::type_info *__cxa_current_exception_type();
# endif
extern _LIBCXXABI_FUNC_VIS std::type_info* __cxa_current_exception_type();

// GNU extension
// Calls `terminate` with the current exception being caught. This function is used by GCC when a `noexcept` function
Expand All @@ -88,8 +80,7 @@ extern _LIBCXXABI_FUNC_VIS _LIBCXXABI_NORETURN void __cxa_rethrow();
// 2.6 Auxiliary Runtime APIs
extern _LIBCXXABI_FUNC_VIS _LIBCXXABI_NORETURN void __cxa_bad_cast(void);
extern _LIBCXXABI_FUNC_VIS _LIBCXXABI_NORETURN void __cxa_bad_typeid(void);
extern _LIBCXXABI_FUNC_VIS _LIBCXXABI_NORETURN void
__cxa_throw_bad_array_new_length(void);
extern _LIBCXXABI_FUNC_VIS _LIBCXXABI_NORETURN void __cxa_throw_bad_array_new_length(void);

// 3.2.6 Pure Virtual Function API
extern _LIBCXXABI_FUNC_VIS _LIBCXXABI_NORETURN void __cxa_pure_virtual(void);
Expand All @@ -98,73 +89,58 @@ extern _LIBCXXABI_FUNC_VIS _LIBCXXABI_NORETURN void __cxa_pure_virtual(void);
extern _LIBCXXABI_FUNC_VIS _LIBCXXABI_NORETURN void __cxa_deleted_virtual(void);

// 3.3.2 One-time Construction API
#if defined(_LIBCXXABI_GUARD_ABI_ARM)
extern _LIBCXXABI_FUNC_VIS _LIBCXXABI_ALWAYS_COLD int __cxa_guard_acquire(uint32_t *);
extern _LIBCXXABI_FUNC_VIS _LIBCXXABI_ALWAYS_COLD void __cxa_guard_release(uint32_t *);
extern _LIBCXXABI_FUNC_VIS _LIBCXXABI_ALWAYS_COLD void __cxa_guard_abort(uint32_t *);
#else
extern _LIBCXXABI_FUNC_VIS _LIBCXXABI_ALWAYS_COLD int __cxa_guard_acquire(uint64_t *);
extern _LIBCXXABI_FUNC_VIS _LIBCXXABI_ALWAYS_COLD void __cxa_guard_release(uint64_t *);
extern _LIBCXXABI_FUNC_VIS _LIBCXXABI_ALWAYS_COLD void __cxa_guard_abort(uint64_t *);
#endif
# if defined(_LIBCXXABI_GUARD_ABI_ARM)
extern _LIBCXXABI_FUNC_VIS _LIBCXXABI_ALWAYS_COLD int __cxa_guard_acquire(uint32_t*);
extern _LIBCXXABI_FUNC_VIS _LIBCXXABI_ALWAYS_COLD void __cxa_guard_release(uint32_t*);
extern _LIBCXXABI_FUNC_VIS _LIBCXXABI_ALWAYS_COLD void __cxa_guard_abort(uint32_t*);
# else
extern _LIBCXXABI_FUNC_VIS _LIBCXXABI_ALWAYS_COLD int __cxa_guard_acquire(uint64_t*);
extern _LIBCXXABI_FUNC_VIS _LIBCXXABI_ALWAYS_COLD void __cxa_guard_release(uint64_t*);
extern _LIBCXXABI_FUNC_VIS _LIBCXXABI_ALWAYS_COLD void __cxa_guard_abort(uint64_t*);
# endif

// 3.3.3 Array Construction and Destruction API
extern _LIBCXXABI_FUNC_VIS void *
__cxa_vec_new(size_t element_count, size_t element_size, size_t padding_size,
void (*constructor)(void *), void (*destructor)(void *));
extern _LIBCXXABI_FUNC_VIS void* __cxa_vec_new(size_t element_count, size_t element_size, size_t padding_size,
void (*constructor)(void*), void (*destructor)(void*));

extern _LIBCXXABI_FUNC_VIS void *
__cxa_vec_new2(size_t element_count, size_t element_size, size_t padding_size,
void (*constructor)(void *), void (*destructor)(void *),
void *(*alloc)(size_t), void (*dealloc)(void *));
extern _LIBCXXABI_FUNC_VIS void* __cxa_vec_new2(size_t element_count, size_t element_size, size_t padding_size,
void (*constructor)(void*), void (*destructor)(void*),
void* (*alloc)(size_t), void (*dealloc)(void*));

extern _LIBCXXABI_FUNC_VIS void *
__cxa_vec_new3(size_t element_count, size_t element_size, size_t padding_size,
void (*constructor)(void *), void (*destructor)(void *),
void *(*alloc)(size_t), void (*dealloc)(void *, size_t));
extern _LIBCXXABI_FUNC_VIS void* __cxa_vec_new3(size_t element_count, size_t element_size, size_t padding_size,
void (*constructor)(void*), void (*destructor)(void*),
void* (*alloc)(size_t), void (*dealloc)(void*, size_t));

extern _LIBCXXABI_FUNC_VIS void
__cxa_vec_ctor(void *array_address, size_t element_count, size_t element_size,
void (*constructor)(void *), void (*destructor)(void *));
extern _LIBCXXABI_FUNC_VIS void __cxa_vec_ctor(void* array_address, size_t element_count, size_t element_size,
void (*constructor)(void*), void (*destructor)(void*));

extern _LIBCXXABI_FUNC_VIS void __cxa_vec_dtor(void *array_address,
size_t element_count,
size_t element_size,
void (*destructor)(void *));
extern _LIBCXXABI_FUNC_VIS void __cxa_vec_dtor(void* array_address, size_t element_count, size_t element_size,
void (*destructor)(void*));

extern _LIBCXXABI_FUNC_VIS void __cxa_vec_cleanup(void *array_address,
size_t element_count,
size_t element_size,
void (*destructor)(void *));
extern _LIBCXXABI_FUNC_VIS void __cxa_vec_cleanup(void* array_address, size_t element_count, size_t element_size,
void (*destructor)(void*));

extern _LIBCXXABI_FUNC_VIS void __cxa_vec_delete(void *array_address,
size_t element_size,
size_t padding_size,
void (*destructor)(void *));
extern _LIBCXXABI_FUNC_VIS void __cxa_vec_delete(void* array_address, size_t element_size, size_t padding_size,
void (*destructor)(void*));

extern _LIBCXXABI_FUNC_VIS void
__cxa_vec_delete2(void *array_address, size_t element_size, size_t padding_size,
void (*destructor)(void *), void (*dealloc)(void *));
extern _LIBCXXABI_FUNC_VIS void __cxa_vec_delete2(void* array_address, size_t element_size, size_t padding_size,
void (*destructor)(void*), void (*dealloc)(void*));

extern _LIBCXXABI_FUNC_VIS void
__cxa_vec_delete3(void *__array_address, size_t element_size,
size_t padding_size, void (*destructor)(void *),
void (*dealloc)(void *, size_t));
extern _LIBCXXABI_FUNC_VIS void __cxa_vec_delete3(void* __array_address, size_t element_size, size_t padding_size,
void (*destructor)(void*), void (*dealloc)(void*, size_t));

extern _LIBCXXABI_FUNC_VIS void
__cxa_vec_cctor(void *dest_array, void *src_array, size_t element_count,
size_t element_size, void (*constructor)(void *, void *),
void (*destructor)(void *));
extern _LIBCXXABI_FUNC_VIS void __cxa_vec_cctor(void* dest_array, void* src_array, size_t element_count,
size_t element_size, void (*constructor)(void*, void*),
void (*destructor)(void*));

// 3.3.5.3 Runtime API
// These functions are part of the C++ ABI, but they are not defined in libc++abi:
// int __cxa_atexit(void (*)(void *), void *, void *);
// void __cxa_finalize(void *);

// 3.4 Demangler API
extern _LIBCXXABI_FUNC_VIS char *__cxa_demangle(const char *mangled_name,
char *output_buffer,
size_t *length, int *status);
extern _LIBCXXABI_FUNC_VIS char* __cxa_demangle(const char* mangled_name, char* output_buffer, size_t* length,
int* status);

// Apple additions to support C++ 0x exception_ptr class
// These are primitives to wrap a smart pointer around an exception object
Expand All @@ -180,7 +156,7 @@ __cxa_decrement_exception_refcount(void *primary_exception) _LIBCXXABI_NOEXCEPT;
extern _LIBCXXABI_FUNC_VIS bool __cxa_uncaught_exception() _LIBCXXABI_NOEXCEPT;
extern _LIBCXXABI_FUNC_VIS unsigned int __cxa_uncaught_exceptions() _LIBCXXABI_NOEXCEPT;

#if defined(__linux__) || defined(__Fuchsia__)
# if defined(__linux__) || defined(__Fuchsia__)
// Linux and Fuchsia TLS support. Not yet an official part of the Itanium ABI.
// https://sourceware.org/glibc/wiki/Destructor%20support%20for%20thread_local%20variables
extern _LIBCXXABI_FUNC_VIS int __cxa_thread_atexit(void (*)(void *), void *,
Expand Down
Loading