bridges/source/cpp_uno/gcc3_wasm/abi.hxx |   78 +++++++++++++++++++++++++++----
 1 file changed, 68 insertions(+), 10 deletions(-)

New commits:
commit f4ec967599f5dafa1ce477631d7c2e8de005e28f
Author:     Stephan Bergmann <stephan.bergm...@allotropia.de>
AuthorDate: Thu Jun 20 17:09:45 2024 +0200
Commit:     Stephan Bergmann <stephan.bergm...@allotropia.de>
CommitDate: Thu Jun 20 21:49:23 2024 +0200

    Fix redefinion of Emscripten __cxxabiv1::__cxa_exception
    
    <https://github.com/emscripten-core/emscripten/>
    system/lib/libcxxabi/src/cxa_exception.h has two different definitions of 
that
    struct, a short one for when __USING_EMSCRIPTEN_EXCEPTIONS__ is defined, 
and a
    long one for the other case.  In 7175431a4b2154113c2c3c28f7ae8a8f14a84c7a
    "Implement exception catching", I had naively copied the short version, 
assuming
    that __USING_EMSCRIPTEN_EXCEPTIONS__ was something that sounded like it 
would be
    defined with --enable-wasm-exceptions.  But some debugging of actual 
exception
    handling now showed that the assumption had apparently been wrong (though I
    still have no idea about the semantics of that 
__USING_EMSCRIPTEN_EXCEPTIONS__
    define, and when it would or would not be defined), and that I had copied 
the
    wrong version.
    
    The relevant test code
    
    >         try {
    >             const ret = invoke.invoke('throwRuntimeException', params, 
outparamindex, outparam);
    >             console.assert(false);
    >             ret.delete();
    >         } catch (e) {
    >             const [type, message] = getExceptionMessage(e);
    >             console.assert(type === 
'com::sun::star::reflection::InvocationTargetException');
    >             console.assert(message === undefined); //TODO
    >             //TODO: inspect wrapped css.uno.RuntimeException
    >             decrementExceptionRefcount(e);
    >         }
    
    in unotest/source/embindtest/embindtest.js had apparently happened to not 
cause a
    crash with the wrong version of __cxxabiv1::__cxa_exception, but had also
    happened to not detect the mistake due to the relevant parts being 
commented out
    with TODO (because, in turn, proper UNO exception catching is still lacking 
in
    our Embind-based JS binding).
    
    Change-Id: I718087c7ed2c17808696267ece17237d5cdf2f54
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/169305
    Tested-by: Jenkins
    Reviewed-by: Stephan Bergmann <stephan.bergm...@allotropia.de>

diff --git a/bridges/source/cpp_uno/gcc3_wasm/abi.hxx 
b/bridges/source/cpp_uno/gcc3_wasm/abi.hxx
index 67dbd06c0390..160c15ee8259 100644
--- a/bridges/source/cpp_uno/gcc3_wasm/abi.hxx
+++ b/bridges/source/cpp_uno/gcc3_wasm/abi.hxx
@@ -13,6 +13,7 @@
 
 #include <cstddef>
 #include <cstdint>
+#include <exception>
 #include <typeinfo>
 
 #include <cxxabi.h>
@@ -22,24 +23,81 @@
 #include <uno/mapping.h>
 
 #if !HAVE_CXXABI_H_CXA_EXCEPTION
-// <https://github.com/emscripten-core/emscripten/>, 
system/lib/libcxxabi/src/cxa_exception.h:
+
+// <https://github.com/emscripten-core/emscripten/>, 
system/lib/libunwind/include/unwind_itanium.h,
+// except where MODIFIED:
+typedef std::/*MODIFIED*/ uint64_t _Unwind_Exception_Class;
+struct _Unwind_Exception
+{
+    _Unwind_Exception_Class exception_class;
+    void (*exception_cleanup)(/*MODIFIED: _Unwind_Reason_Code reason, 
_Unwind_Exception* exc*/);
+#if defined(__SEH__) && !defined(__USING_SJLJ_EXCEPTIONS__)
+    std::/*MODIFIED*/ uintptr_t private_[6];
+#elif !defined(__USING_WASM_EXCEPTIONS__)
+    std::/*MODIFIED*/ uintptr_t private_1; // non-zero means forced unwind
+    std::/*MODIFIED*/ uintptr_t private_2; // holds sp that phase1 found for 
phase2 to use
+#endif
+#if __SIZEOF_POINTER__ == 4
+    // The implementation of _Unwind_Exception uses an attribute mode on the
+    // above fields which has the side effect of causing this whole struct to
+    // round up to 32 bytes in size (48 with SEH). To be more explicit, we add
+    // pad fields added for binary compatibility.
+    std::/*MODIFIED*/ uint32_t reserved[3];
+#endif
+    // The Itanium ABI requires that _Unwind_Exception objects are "double-word
+    // aligned".  GCC has interpreted this to mean "use the maximum useful
+    // alignment for the target"; so do we.
+} __attribute__((__aligned__));
+
+// <https://github.com/emscripten-core/emscripten/>, 
system/lib/libcxxabi/src/cxa_exception.h,
+// except where MODIFIED:
 namespace __cxxabiv1
 {
 struct __cxa_exception
 {
-    std::size_t referenceCount;
+#if defined(__LP64__) || defined(_WIN64) || defined(_LIBCXXABI_ARM_EHABI)
+    // Now _Unwind_Exception is marked with __attribute__((aligned)),
+    // which implies __cxa_exception is also aligned. Insert padding
+    // in the beginning of the struct, rather than before unwindHeader.
+    void* reserve;
+    // This is a new field to support C++11 exception_ptr.
+    // For binary compatibility it is at the start of this
+    // struct which is prepended to the object thrown in
+    // __cxa_allocate_exception.
+    std::/*MODIFIED*/ size_t referenceCount;
+#endif
+    //  Manage the exception object itself.
     std::type_info* exceptionType;
-    // In wasm, destructors return 'this' as in ARM
-    void* (*exceptionDestructor)(void*);
-    std::uint8_t caught;
-    std::uint8_t rethrown;
+#if 1 //MODIFIED: #ifdef __USING_WASM_EXCEPTIONS__
+    // In wasm, destructors return their argument
+    void*(_LIBCXXABI_DTOR_FUNC* exceptionDestructor)(void*);
+#else
+    void(_LIBCXXABI_DTOR_FUNC* exceptionDestructor)(void*);
+#endif
+    void* /*MODIFIED: std::unexpected_handler*/ unexpectedHandler;
+    std::terminate_handler terminateHandler;
+    __cxa_exception* nextException;
+    int handlerCount;
+#if defined(_LIBCXXABI_ARM_EHABI)
+    __cxa_exception* nextPropagatingException;
+    int propagationCount;
+#else
+    int handlerSwitchValue;
+    const unsigned char* actionRecord;
+    const unsigned char* languageSpecificData;
+    void* catchTemp;
     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;
+#endif
+#if !defined(__LP64__) && !defined(_WIN64) && !defined(_LIBCXXABI_ARM_EHABI)
+    // This is a new field to support C++11 exception_ptr.
+    // For binary compatibility it is placed where the compiler
+    // previously added padding to 64-bit align unwindHeader.
+    std::/*MODIFIED*/ size_t referenceCount;
+#endif
+    _Unwind_Exception unwindHeader;
 };
 }
+
 #endif
 
 #if !HAVE_CXXABI_H_CXA_EH_GLOBALS

Reply via email to