This is an automated email from the ASF dual-hosted git repository.

asf-gitbox-commits pushed a commit to branch trunk
in repository https://gitbox.apache.org/repos/asf/openoffice.git

commit dcfbcfcc0e65200ed7e642920dcdc93553b55d00
Author: Pedro Giffuni <[email protected]>
AuthorDate: Wed Oct 21 10:48:21 2026 -0500

    freebsd_aarch64: Complete C++-UNO bridge implementation for FreeBSD aarch64
    Implement the gcc3 FreeBSD aarch64 C++-UNO bridge, mirroring the
    macOS aarch64 reference implementation with adaptations for the
    System V / AAPCS64 ABI (FreeBSD).
    
    - abi.cxx: Implement align_stack_offset (8-byte alignment) and
      stack_size (rounded to 8 bytes) matching AAPCS64.
    - call.s: Add callVirtualFunction and privateSnippetExecutor assembly
      trampolines for aarch64. Fix return value loading with correct
      sp+144 offsets, add Lpse_void label for void returns, and fix
      typelib_TypeClass enum values (VOID=0, CHAR=1, BYTE=2, etc.).
    - cpp2uno.cxx: Implement cpp2uno_call and cpp_vtable_call for
      converting incoming C++ ABI arguments to UNO format, and
      VtableFactory methods (mapBlockToVtable, getBlockSize,
      initializeBlock, addLocalFunctions, flushCode).
    - except.cxx: Implement exception handling (synthesiseRTTI,
      deleteException, raiseException, fillUnoException).
    - uno2cpp.cxx: Implement cpp_call for converting UNO args to C++
      ABI arguments, INSERT_* macros for register/stack parameter
      packing, and callVirtualMethod wrapper around the assembly
      trampoline.
---
 .../source/cpp_uno/gcc3_freebsd_aarch64/abi.cxx    | 170 +++++---
 .../source/cpp_uno/gcc3_freebsd_aarch64/call.s     |  65 +--
 .../cpp_uno/gcc3_freebsd_aarch64/cpp2uno.cxx       | 146 +++++--
 .../source/cpp_uno/gcc3_freebsd_aarch64/except.cxx | 149 +++++++
 .../cpp_uno/gcc3_freebsd_aarch64/uno2cpp.cxx       | 446 ++++++++++++++++++++-
 5 files changed, 856 insertions(+), 120 deletions(-)

diff --git a/main/bridges/source/cpp_uno/gcc3_freebsd_aarch64/abi.cxx 
b/main/bridges/source/cpp_uno/gcc3_freebsd_aarch64/abi.cxx
index 71b8692f79..c119e4580b 100644
--- a/main/bridges/source/cpp_uno/gcc3_freebsd_aarch64/abi.cxx
+++ b/main/bridges/source/cpp_uno/gcc3_freebsd_aarch64/abi.cxx
@@ -197,115 +197,159 @@ namespace aarch64
 
 bool examine_argument( typelib_TypeDescriptionReference *pTypeRef, bool 
bInReturn, int &nUsedGPR, int &nUsedFPR )
 {
-       // For returns, the hidden param rule uses >16 bytes for aggregates.
-       if ( pTypeRef->eTypeClass == typelib_TypeClass_STRUCT || 
pTypeRef->eTypeClass == typelib_TypeClass_EXCEPTION )
-       {
-               return classifyAggregate( pTypeRef, nUsedGPR, nUsedFPR );
-       }
+       nUsedGPR = 0;
+       nUsedFPR = 0;
 
-       // Scalars: floats -> FPR, others -> GPR
        switch ( pTypeRef->eTypeClass )
        {
+               case typelib_TypeClass_VOID:
+                       return true;
+
+               case typelib_TypeClass_CHAR:
+               case typelib_TypeClass_BOOLEAN:
+               case typelib_TypeClass_BYTE:
+               case typelib_TypeClass_SHORT:
+               case typelib_TypeClass_UNSIGNED_SHORT:
+               case typelib_TypeClass_LONG:
+               case typelib_TypeClass_UNSIGNED_LONG:
+               case typelib_TypeClass_HYPER:
+               case typelib_TypeClass_UNSIGNED_HYPER:
+               case typelib_TypeClass_ENUM:
+                       nUsedGPR = 1;
+                       return true;
+
                case typelib_TypeClass_FLOAT:
-                       nUsedFPR = 1; nUsedGPR = 0; return true;
                case typelib_TypeClass_DOUBLE:
-                       nUsedFPR = 1; nUsedGPR = 0; return true;
+                       nUsedFPR = 1;
+                       return true;
+
+               // These UNO types are always handled by the bridge as a 
pointer/
+               // reference (one GPR), never passed by value through this 
classifier.
+               case typelib_TypeClass_STRING:
+               case typelib_TypeClass_TYPE:
+               case typelib_TypeClass_ANY:
+               case typelib_TypeClass_TYPEDEF:
+               case typelib_TypeClass_SEQUENCE:
+               case typelib_TypeClass_INTERFACE:
+                       nUsedGPR = 1;
+                       return true;
+
+               case typelib_TypeClass_STRUCT:
+               case typelib_TypeClass_EXCEPTION:
+                       if ( bInReturn )
+                               return classifyAggregate( pTypeRef, nUsedGPR, 
nUsedFPR );
+                       nUsedGPR = 1; // generated UNO C++ bindings pass 
aggregates by const reference
+                       return true;
+
                default:
-                       nUsedFPR = 0; nUsedGPR = 1; return true;
+                       return false;
        }
 }
 
 bool return_in_hidden_param( typelib_TypeDescriptionReference *pTypeRef )
 {
-       if ( pTypeRef->eTypeClass == typelib_TypeClass_STRUCT || 
pTypeRef->eTypeClass == typelib_TypeClass_EXCEPTION )
+       switch ( pTypeRef->eTypeClass )
        {
-               typelib_TypeDescription * pTypeDescr = 0;
-               TYPELIB_DANGER_GET( &pTypeDescr, pTypeRef );
-               bool ret = pTypeDescr->nSize > 16;
-               TYPELIB_DANGER_RELEASE( pTypeDescr );
-               return ret;
+               case typelib_TypeClass_STRING:
+               case typelib_TypeClass_TYPE:
+               case typelib_TypeClass_ANY:
+               case typelib_TypeClass_TYPEDEF:
+               case typelib_TypeClass_UNION:
+               case typelib_TypeClass_ARRAY:
+               case typelib_TypeClass_SEQUENCE:
+               case typelib_TypeClass_INTERFACE:
+                       // These are C++ wrapper objects, not pointer-sized 
scalar values.
+                       // On FreeBSD aarch64 (System V), C++ class return 
values (non-POD
+                       // with non-trivial copy constructor) are returned via 
x8 buffer.
+                       return true;
+               default:
+                       break;
+       }
+
+       if ( pTypeRef->eTypeClass == typelib_TypeClass_STRUCT ||
+                pTypeRef->eTypeClass == typelib_TypeClass_EXCEPTION )
+       {
+               if ( isComplexAggregate( pTypeRef ) )
+                       return true;
        }
-       return false; // scalars and small aggregates return in registers
+
+       int g, s;
+       // Returned in registers iff examine_argument() says it fits;
+       // otherwise the caller must pass an indirect-result buffer in x8.
+       return !examine_argument( pTypeRef, true, g, s );
 }
 
 sal_uInt32 get_return_kind( typelib_TypeDescriptionReference *pTypeRef )
 {
-       if ( pTypeRef->eTypeClass == typelib_TypeClass_FLOAT )
-               return typelib_TypeClass_FLOAT;
-
-       if ( pTypeRef->eTypeClass == typelib_TypeClass_DOUBLE )
-               return typelib_TypeClass_DOUBLE;
-
        if ( pTypeRef->eTypeClass == typelib_TypeClass_STRUCT ||
                 pTypeRef->eTypeClass == typelib_TypeClass_EXCEPTION )
        {
                HfaKind kind = HFA_NONE;
                int count = 0;
-
-               if ( collectHfa( pTypeRef, kind, count ) )
-               {
-                       if ( kind == HFA_FLOAT )
-                               return RETURN_KIND_HFA_FLOAT;
-
-                       if ( kind == HFA_DOUBLE )
-                               return RETURN_KIND_HFA_DOUBLE;
-               }
+               if ( collectHfa( pTypeRef, kind, count ) && count >= 1 && count 
<= 4 )
+                       return kind == HFA_FLOAT ? RETURN_KIND_HFA_FLOAT : 
RETURN_KIND_HFA_DOUBLE;
        }
-
        return pTypeRef->eTypeClass;
 }
 
 void fill_struct( typelib_TypeDescriptionReference *pTypeRef, const 
sal_uInt64* pGPR, const double* pFPR, void *pStruct )
 {
-       // For small aggregates, copy from GPR slots; for HFAs, copy from FPR 
slots.
-       if ( pTypeRef->eTypeClass == typelib_TypeClass_STRUCT || 
pTypeRef->eTypeClass == typelib_TypeClass_EXCEPTION )
+       int nUsedGPR = 0;
+       int nUsedFPR = 0;
+       if ( !examine_argument( pTypeRef, true, nUsedGPR, nUsedFPR ) )
+       {
+               return;
+       }
+
+       if ( nUsedFPR > 0 )
        {
-               int nGPR=0, nFPR=0;
-               if ( classifyAggregate( pTypeRef, nGPR, nFPR ) )
+               // HFA: each member occupies one v register; the members are 
contiguous
+               // in the struct.  Copy element-by-element to honour FLOAT 
(4-byte) vs
+               // DOUBLE (8-byte) element width.
+               HfaKind kind = HFA_NONE;
+               int count = 0;
+               collectHfa( pTypeRef, kind, count );
+               if ( kind == HFA_FLOAT )
                {
-                       if ( nFPR > 0 )
-                       {
-                       // HFA: copy elements from FPR slots. For FLOAT HFAs 
each element is
-                       // 4 bytes but occupies an 8-byte saved slot; copy each 
float from the
-                       // low 4 bytes of the corresponding double-sized slot. 
DOUBLE HFAs
-                       // can be copied directly.
-                       HfaKind kind = HFA_NONE;
-                       int count = 0;
-                       if ( collectHfa( pTypeRef, kind, count ) && kind == 
HFA_FLOAT )
-                       {
-                               for ( int i = 0; i < nFPR; ++i )
-                                       memcpy(
-                                               static_cast<char *>( pStruct ) 
+ i * sizeof(float),
-                                               reinterpret_cast<const char *>( 
pFPR) + i * sizeof(double),
-                                               sizeof(float) );
-                       }
-                       else
-                       {
-                               memcpy( pStruct, pFPR, nFPR * sizeof(double) );
-                       }
-                       }
-                       else
-                       {
-                               memcpy( pStruct, pGPR, nGPR * 
sizeof(sal_uInt64) );
-                       }
+                       float *pDest = reinterpret_cast< float *>( pStruct );
+                       for ( int i = 0; i < nUsedFPR; ++i )
+                               pDest[i] = *reinterpret_cast< const float *>( 
pFPR + i );
+               }
+               else // HFA_DOUBLE
+               {
+                       double *pDest = reinterpret_cast< double *>( pStruct );
+                       for ( int i = 0; i < nUsedFPR; ++i )
+                               pDest[i] = pFPR[i];
                }
        }
+       else
+       {
+               typelib_TypeDescription * pTypeDescr = 0;
+               TYPELIB_DANGER_GET( &pTypeDescr, pTypeRef );
+               memcpy( pStruct, pGPR, pTypeDescr->nSize );
+               TYPELIB_DANGER_RELEASE( pTypeDescr );
+       }
 }
 
 sal_uInt32 align_stack_offset( sal_uInt32 offset, 
typelib_TypeDescriptionReference *pTypeRef )
 {
-       // AArch64 stack overflow area is packed; align to natural alignment of 
the type (8)
+       // On aarch64 System V ABI, the smallest stack slot is 8 bytes.
+       // Align to 8 bytes regardless of the type's natural alignment.
        const sal_uInt32 align = 8;
        return ( offset + align - 1 ) & ~( align - 1 );
 }
 
 sal_uInt32 stack_size( typelib_TypeDescriptionReference *pTypeRef )
 {
-       // For simple types and small aggregates, size is rounded to 8
        typelib_TypeDescription * pTypeDescr = 0;
        TYPELIB_DANGER_GET( &pTypeDescr, pTypeRef );
        sal_uInt32 size = pTypeDescr->nSize;
        TYPELIB_DANGER_RELEASE( pTypeDescr );
+       // In the System V AMD64 / AAPCS64 stack layout, the smallest slot that
+       // can be passed is 8 bytes (the natural stack slot size).  Round up
+       // so that small types like BOOLEAN (1B), SHORT (2B), LONG (4B) each
+       // occupy a full 8-byte slot on the overflow stack, matching what the
+       // callee's ABI expects.
        return ( size + 7 ) & ~7u;
 }
 
diff --git a/main/bridges/source/cpp_uno/gcc3_freebsd_aarch64/call.s 
b/main/bridges/source/cpp_uno/gcc3_freebsd_aarch64/call.s
index 8eb2c6449e..284eff1f09 100644
--- a/main/bridges/source/cpp_uno/gcc3_freebsd_aarch64/call.s
+++ b/main/bridges/source/cpp_uno/gcc3_freebsd_aarch64/call.s
@@ -143,54 +143,67 @@ privateSnippetExecutor:
        b.eq    Lpse_signed_byte
        cmp     w0, #4                  // typelib_TypeClass_SHORT
        b.eq    Lpse_signed_short
-       cmp     w0, #1                  // typelib_TypeClass_VOID
+       cmp     w0, #1                  // typelib_TypeClass_CHAR
+       b.eq    Lpse_unsigned_short
+       cmp     w0, #5                  // typelib_TypeClass_UNSIGNED_SHORT
+       b.eq    Lpse_unsigned_short
+       cmp     w0, #2                  // typelib_TypeClass_BOOLEAN
+       b.eq    Lpse_unsigned_byte
+       cmp     w0, #6                  // typelib_TypeClass_LONG
+       b.eq    Lpse_word
+       cmp     w0, #7                  // typelib_TypeClass_UNSIGNED_LONG
+       b.eq    Lpse_word
+       cmp     w0, #0                  // typelib_TypeClass_VOID
        b.eq    Lpse_void
+       cmp     w0, #15                 // typelib_TypeClass_ENUM
+       b.eq    Lpse_word
 
-       // integer / pointer return
-       ldr     x0, [x6, #0]
-       ldr     x1, [x6, #8]
-       ldr     d0, [x6, #16]
-       ldr     d1, [x6, #24]
+       // integer / pointer / <=16B aggregate
+       ldr     x0, [sp, #144]
+       ldr     x1, [sp, #152]
+       b       Lpse_finish
+
+Lpse_void:
+       mov     x0, #0
        b       Lpse_finish
 
 Lpse_hfa_float:
-       // HFA float: up to 4 floats in d0..d3
-       ldr     d0, [x6, #0]
-       ldr     d1, [x6, #8]
-       ldr     d2, [x6, #16]
-       ldr     d3, [x6, #24]
+       ldr     s0, [sp, #144]
+       ldr     s1, [sp, #148]
+       ldr     s2, [sp, #152]
+       ldr     s3, [sp, #156]
        b       Lpse_finish
 
 Lpse_hfa_double:
-       // HFA double: up to 4 doubles in d0..d3
-       ldr     d0, [x6, #0]
-       ldr     d1, [x6, #8]
-       ldr     d2, [x6, #16]
-       ldr     d3, [x6, #24]
+       ldp     d0, d1, [sp, #144]
+       ldp     d2, d3, [sp, #160]
        b       Lpse_finish
 
 Lpse_float:
-       // single float/double returned in d0
-       ldr     d0, [x6, #16]
+       ldr     d0, [sp, #144]
        b       Lpse_finish
 
 Lpse_signed_byte:
-       ldr     x0, [x6, #0]
+       ldrsb   w0, [sp, #144]
+       b       Lpse_finish
+
+Lpse_unsigned_byte:
+       ldrb    w0, [sp, #144]
        b       Lpse_finish
 
 Lpse_signed_short:
-       ldr     x0, [x6, #0]
+       ldrsh   w0, [sp, #144]
        b       Lpse_finish
 
-Lpse_void:
-       mov     x0, #0
+Lpse_unsigned_short:
+       ldrh    w0, [sp, #144]
        b       Lpse_finish
 
+Lpse_word:
+       ldr     w0, [sp, #144]
 Lpse_finish:
-       ldp     x23, x24, [sp], #16
-       ldp     x21, x22, [sp], #16
-       ldp     x19, x20, [sp], #16
-       ldp     x29, x30, [sp], #16
+       mov     sp, x29
+       ldp     x29, x30, [sp], #176
        ret
        .cfi_endproc
 
diff --git a/main/bridges/source/cpp_uno/gcc3_freebsd_aarch64/cpp2uno.cxx 
b/main/bridges/source/cpp_uno/gcc3_freebsd_aarch64/cpp2uno.cxx
index c6204dadf7..c97b3c3998 100644
--- a/main/bridges/source/cpp_uno/gcc3_freebsd_aarch64/cpp2uno.cxx
+++ b/main/bridges/source/cpp_uno/gcc3_freebsd_aarch64/cpp2uno.cxx
@@ -120,19 +120,9 @@ static typelib_TypeClass cpp2uno_call(
 
                int nUsedGPR = 0;
                int nUsedFPR = 0;
+               aarch64::examine_argument( rParam.pTypeRef, false, nUsedGPR, 
nUsedFPR );
                if ( !rParam.bOut && bridges::cpp_uno::shared::isSimpleType( 
rParam.pTypeRef ) ) // value
                {
-                       // A simple UNO type occupies exactly one register, GPR 
or FPR.
-                       if ( rParam.pTypeRef->eTypeClass == 
typelib_TypeClass_FLOAT ||
-                                rParam.pTypeRef->eTypeClass == 
typelib_TypeClass_DOUBLE )
-                       {
-                               nUsedFPR = 1; nUsedGPR = 0;
-                       }
-                       else
-                       {
-                               nUsedFPR = 0; nUsedGPR = 1;
-                       }
-
                        OSL_ASSERT( ( nUsedFPR == 1 && nUsedGPR == 0 ) || ( 
nUsedFPR == 0 && nUsedGPR == 1 ) );
 
                        if ( nUsedFPR == 1 )
@@ -203,24 +193,13 @@ static typelib_TypeClass cpp2uno_call(
                                // will be released at reconversion
                                ppTempParamTypeDescr[nTempIndizes++] = 
pParamTypeDescr;
                        }
-
-                       if ( pCppStack )
+                       else // direct way
                        {
-                               if ( pParamTypeDescr->eTypeClass == 
typelib_TypeClass_STRUCT ||
-                                        pParamTypeDescr->eTypeClass == 
typelib_TypeClass_EXCEPTION )
-                               {
-                                       // struct in registers/stack: copy it 
to a temporary if
-                                       // it needs conversion
-                                       if ( 
bridges::cpp_uno::shared::relatesToInterfaceType( pParamTypeDescr ) )
-                                       {
-                                               // already handled above
-                                       }
-                                       else
-                                               pUnoArgs[nPos] = pCppStack;
-                               }
-                       }
-                       if ( pParamTypeDescr )
+                               // struct in registers/stack: copy it directly
+                               pUnoArgs[nPos] = pCppStack;
+                               // no longer needed
                                TYPELIB_DANGER_RELEASE( pParamTypeDescr );
+                       }
                }
        }
 
@@ -436,3 +415,116 @@ extern "C" sal_uInt32 cpp_vtable_call(
 
        return eRet;
 }
+
+
+//==================================================================================================
+extern "C" void privateSnippetExecutor( void );
+
+const int codeSnippetSize = 40;
+
+unsigned char * codeSnippet( unsigned char * code,
+       sal_Int32 nFunctionIndex, sal_Int32 nVtableOffset,
+       bool bHasHiddenParam ) SAL_THROW( () )
+{
+       sal_uInt64 nOffsetAndIndex = ( static_cast<sal_uInt64>( nVtableOffset ) 
<< 32 ) | static_cast<sal_uInt64>( nFunctionIndex );
+
+       if ( bHasHiddenParam )
+               nOffsetAndIndex |= 0x80000000;
+
+       sal_uInt32 * p = reinterpret_cast<sal_uInt32 *>( code );
+
+       p[0] = 0x58000000 | ( 6 << 5 ) | 16;
+       p[1] = 0x58000000 | ( 7 << 5 ) | 17;
+       p[2] = 0xD61F0000 | ( 17 << 5 );
+       p[3] = 0xD503201F; // NOP
+       p[4] = 0xD503201F; // NOP
+
+       *reinterpret_cast<sal_uInt64 *>( code + 24 ) = nOffsetAndIndex;
+       *reinterpret_cast<sal_uInt64 *>( code + 32 ) = 
reinterpret_cast<sal_uInt64>( privateSnippetExecutor );
+
+       return code + codeSnippetSize;
+}
+
+//==================================================================================================
+struct bridges::cpp_uno::shared::VtableFactory::Slot { void * fn; };
+
+bridges::cpp_uno::shared::VtableFactory::Slot *
+bridges::cpp_uno::shared::VtableFactory::mapBlockToVtable(void * block)
+{
+    return static_cast< Slot * >(block) + 2;
+}
+
+//==================================================================================================
+sal_Size bridges::cpp_uno::shared::VtableFactory::getBlockSize(
+    sal_Int32 slotCount)
+{
+    return (slotCount + 2) * sizeof (Slot) + slotCount * codeSnippetSize;
+}
+
+//==================================================================================================
+bridges::cpp_uno::shared::VtableFactory::Slot *
+bridges::cpp_uno::shared::VtableFactory::initializeBlock(
+    void * block, sal_Int32 slotCount)
+{
+    Slot * slots = mapBlockToVtable(block);
+    slots[-2].fn = 0;
+    slots[-1].fn = 0;
+    return slots + slotCount;
+}
+
+//==================================================================================================
+
+unsigned char * bridges::cpp_uno::shared::VtableFactory::addLocalFunctions(
+       Slot ** slots, unsigned char * code, sal_PtrDiff writetoexecdiff,
+       typelib_InterfaceTypeDescription const * type, sal_Int32 
nFunctionOffset,
+       sal_Int32 functionCount, sal_Int32 nVtableOffset )
+{
+       (*slots) -= functionCount;
+       Slot * s = *slots;
+       for ( sal_Int32 nPos = 0; nPos < type->nMembers; ++nPos )
+       {
+               typelib_TypeDescription * pTD = 0;
+
+               TYPELIB_DANGER_GET( &pTD, type->ppMembers[ nPos ] );
+               OSL_ASSERT( pTD );
+
+               if ( typelib_TypeClass_INTERFACE_ATTRIBUTE == pTD->eTypeClass )
+               {
+                       typelib_InterfaceAttributeTypeDescription *pAttrTD =
+                               
reinterpret_cast<typelib_InterfaceAttributeTypeDescription *>( pTD );
+
+                       (s++)->fn = code + writetoexecdiff;
+                       code = codeSnippet( code, nFunctionOffset++, 
nVtableOffset,
+                                                               
aarch64::return_in_hidden_param( pAttrTD->pAttributeTypeRef ) );
+
+                       if ( ! pAttrTD->bReadOnly )
+                       {
+                               (s++)->fn = code + writetoexecdiff;
+                               code = codeSnippet( code, nFunctionOffset++, 
nVtableOffset, false );
+                       }
+               }
+               else if ( typelib_TypeClass_INTERFACE_METHOD == pTD->eTypeClass 
)
+               {
+                       typelib_InterfaceMethodTypeDescription *pMethodTD =
+                               
reinterpret_cast<typelib_InterfaceMethodTypeDescription *>( pTD );
+
+                       (s++)->fn = code + writetoexecdiff;
+                       code = codeSnippet( code, nFunctionOffset++, 
nVtableOffset,
+                                                               
aarch64::return_in_hidden_param( pMethodTD->pReturnTypeRef ) );
+               }
+               else
+                       OSL_ASSERT( false );
+
+               TYPELIB_DANGER_RELEASE( pTD );
+       }
+       return code;
+}
+
+//==================================================================================================
+void bridges::cpp_uno::shared::VtableFactory::flushCode(
+       unsigned char const * begin, unsigned char const * end )
+{
+       __clear_cache(
+               const_cast<unsigned char *>(begin),
+               const_cast<unsigned char *>(end) );
+}
diff --git a/main/bridges/source/cpp_uno/gcc3_freebsd_aarch64/except.cxx 
b/main/bridges/source/cpp_uno/gcc3_freebsd_aarch64/except.cxx
index e8caa2151c..6161e1958d 100644
--- a/main/bridges/source/cpp_uno/gcc3_freebsd_aarch64/except.cxx
+++ b/main/bridges/source/cpp_uno/gcc3_freebsd_aarch64/except.cxx
@@ -250,4 +250,153 @@ type_info * RTTI::getRTTI( 
typelib_CompoundTypeDescription *pTypeDescr ) SAL_THR
        return p;
 }
 
+//__________________________________________________________________________________________________
+type_info * RTTI::synthesiseRTTI(
+       OString const & rSymbolName,
+       typelib_CompoundTypeDescription * pTypeDescr ) SAL_THROW( () )
+{
+       if (! rttiDonorsUsable())
+               return 0;
+
+       type_info * pBaseRtti = 0;
+       if (pTypeDescr->pBaseTypeDescription != 0)
+       {
+               pBaseRtti = getRTTI(
+                       (typelib_CompoundTypeDescription *) 
pTypeDescr->pBaseTypeDescription );
+               if (pBaseRtti == 0)
+                       return 0;
+       }
+
+       char * pName = strdup( rSymbolName.getStr() + 4 );
+       if (pName == 0)
+               return 0;
+       sal_uIntPtr nName = reinterpret_cast< sal_uIntPtr >( pName );
+       if (rttiIsNonUnique())
+               nName |= NON_UNIQUE_RTTI_BIT;
+
+       if (pBaseRtti != 0)
+       {
+               RttiSiClassLayout * p = static_cast< RttiSiClassLayout * >(
+                       calloc( 1, sizeof (RttiSiClassLayout) ) );
+               if (p == 0) { free( pName ); return 0; }
+               p->pVtable = siDonor()->pVtable;
+               p->nName   = nName;
+               p->pBase   = pBaseRtti;
+               return reinterpret_cast< type_info * >( p );
+       }
+
+       RttiClassLayout * p = static_cast< RttiClassLayout * >(
+               calloc( 1, sizeof (RttiClassLayout) ) );
+       if (p == 0) { free( pName ); return 0; }
+       p->pVtable = classDonor()->pVtable;
+       p->nName   = nName;
+       return reinterpret_cast< type_info * >( p );
+}
+
+//--------------------------------------------------------------------------------------------------
+static void deleteException( void * pExc )
+{
+       typelib_TypeDescription * pTD = 0;
+       {
+               MutexGuard guard( exceptionMapsMutex() );
+               ThrownTypes::iterator i = thrownTypes().find( pExc );
+               if ( i != thrownTypes().end() )
+               {
+                       pTD = i->second;
+                       thrownTypes().erase( i );
+               }
+       }
+       if ( pTD )
+       {
+               ::uno_destructData( pExc, pTD, cpp_release );
+               ::typelib_typedescription_release( pTD );
+       }
+}
+
+//==================================================================================================
+void raiseException( uno_Any * pUnoExc, uno_Mapping * pUno2Cpp )
+{
+       void * pCppExc;
+       type_info * rtti;
+       OUString typeName(
+               *reinterpret_cast< OUString const * >( 
&pUnoExc->pType->pTypeName ) );
+
+       OUString message;
+       if ( pUnoExc->pData != 0 &&
+                *reinterpret_cast< rtl_uString * const * >( pUnoExc->pData ) 
!= 0 )
+       {
+               message = *reinterpret_cast< OUString const * >( pUnoExc->pData 
);
+       }
+
+       {
+       typelib_TypeDescription * pTypeDescr = 0;
+       TYPELIB_DANGER_GET( &pTypeDescr, pUnoExc->pType );
+       OSL_ASSERT( pTypeDescr );
+       if (! pTypeDescr)
+       {
+               throw RuntimeException(
+                       OUString( RTL_CONSTASCII_USTRINGPARAM("cannot get 
typedescription for type ") ) +
+                       typeName + OUString( RTL_CONSTASCII_USTRINGPARAM(": ") 
) + message,
+                       Reference< XInterface >() );
+       }
+
+       pCppExc = __cxa_allocate_exception( pTypeDescr->nSize );
+       ::uno_copyAndConvertData( pCppExc, pUnoExc->pData, pTypeDescr, pUno2Cpp 
);
+
+       static RTTI rtti_data;
+       rtti = rtti_data.getRTTI(
+               (typelib_CompoundTypeDescription *) pTypeDescr );
+       OSL_ENSURE( rtti, "### no rtti for throwing exception!" );
+       if (! rtti)
+       {
+               ::uno_destructData( pCppExc, pTypeDescr, cpp_release );
+               __cxa_free_exception( pCppExc );
+               TYPELIB_DANGER_RELEASE( pTypeDescr );
+               ::uno_any_destruct( pUnoExc, 0 );
+               throw RuntimeException(
+                       OUString( RTL_CONSTASCII_USTRINGPARAM("no rtti for type 
") ) +
+                       typeName + OUString( RTL_CONSTASCII_USTRINGPARAM(": ") 
) + message,
+                       Reference< XInterface >() );
+       }
+
+       {
+               MutexGuard guard( exceptionMapsMutex() );
+               typelib_typedescription_acquire( pTypeDescr );
+               thrownTypes()[pCppExc] = pTypeDescr;
+       }
+       TYPELIB_DANGER_RELEASE( pTypeDescr );
+       ::uno_any_destruct( pUnoExc, 0 );
+       }
+
+       __cxa_throw( pCppExc, rtti, deleteException );
+}
+
+void fillUnoException(
+       std::type_info const & type, void * exception, uno_Any * pUnoExc,
+       uno_Mapping * pCpp2Uno )
+{
+       typelib_TypeDescription * pExcTypeDescr = 0;
+       OUString unoName( toUNOname( type.name() ) );
+       {
+               MutexGuard guard( exceptionMapsMutex() );
+               observedRttis()[unoName] = const_cast<std::type_info *>( &type 
);
+       }
+       typelib_typedescription_getByName( &pExcTypeDescr, unoName.pData );
+       if ( pExcTypeDescr == 0 )
+       {
+               RuntimeException aRE(
+                       OUString( RTL_CONSTASCII_USTRINGPARAM("exception type 
not found: ") ) + unoName,
+                       Reference< XInterface >() );
+               Type const & rType = ::getCppuType( &aRE );
+               uno_type_any_constructAndConvert(
+                       pUnoExc, &aRE, rType.getTypeLibType(), pCpp2Uno );
+       }
+       else
+       {
+               uno_any_constructAndConvert(
+                       pUnoExc, exception, pExcTypeDescr, pCpp2Uno );
+               typelib_typedescription_release( pExcTypeDescr );
+       }
+}
+
 } // namespace CPPU_CURRENT_NAMESPACE
diff --git a/main/bridges/source/cpp_uno/gcc3_freebsd_aarch64/uno2cpp.cxx 
b/main/bridges/source/cpp_uno/gcc3_freebsd_aarch64/uno2cpp.cxx
index 24e2627918..8cb8c0d517 100644
--- a/main/bridges/source/cpp_uno/gcc3_freebsd_aarch64/uno2cpp.cxx
+++ b/main/bridges/source/cpp_uno/gcc3_freebsd_aarch64/uno2cpp.cxx
@@ -162,12 +162,11 @@ static void callVirtualMethod(void * pThis, sal_uInt32 
nVtableIndex,
                        *reinterpret_cast<float *>( &fpReturn[0] );
                break;
        case typelib_TypeClass_DOUBLE:
-               *reinterpret_cast<double *>( pRegisterReturn ) =
-                       *reinterpret_cast<double *>( &fpReturn[0] );
+               *reinterpret_cast<double *>( pRegisterReturn ) = fpReturn[0];
                break;
        case typelib_TypeClass_STRUCT:
        case typelib_TypeClass_EXCEPTION:
-               aarch64::fill_struct( pReturnTypeRef, gpReturn, fpReturn, 
pRegisterReturn );
+               aarch64::fill_struct( pReturnTypeRef, &gpReturn[0], 
&fpReturn[0], pRegisterReturn );
                break;
        default:
                break;
@@ -186,4 +185,443 @@ extern "C" void callVirtualFunction(
        unsigned char *pStack, sal_uInt32 nStackBytes,
        sal_uInt64 *pGPRReturn, double *pFPRReturn );
 
-// ... per-bridge wrappers are generated at build time; no further code 
required here.
+// Macros for inserting values into registers. Stack arguments are handled
+// separately with a byte cursor because the AAPCS packs them by 
size/alignment.
+// pSV - pointer to the source
+// nr - order of the value [will be increased if stored to register]
+// pFPR, pGPR - pointer to the register arrays
+
+#define INSERT_FLOAT( pSV, nr, pFPR ) \
+       if ( nr < aarch64::MAX_FPR_REGS ) \
+       { \
+               pFPR[nr] = 0; \
+               *reinterpret_cast<float *>( pFPR + nr++ ) = 
*reinterpret_cast<const float *>( pSV ); \
+       }
+
+#define INSERT_DOUBLE( pSV, nr, pFPR ) \
+       if ( nr < aarch64::MAX_FPR_REGS ) \
+               pFPR[nr++] = *reinterpret_cast<const double *>( pSV );
+
+#define INSERT_INT64( pSV, nr, pGPR ) \
+       if ( nr < aarch64::MAX_GPR_REGS ) \
+               pGPR[nr++] = *reinterpret_cast<const sal_uInt64 *>( pSV );
+
+#define INSERT_INT32( pSV, nr, pGPR ) \
+       if ( nr < aarch64::MAX_GPR_REGS ) \
+               pGPR[nr++] = *reinterpret_cast<const sal_uInt32 *>( pSV );
+
+#define INSERT_SIGNED_INT32( pSV, nr, pGPR ) \
+       if ( nr < aarch64::MAX_GPR_REGS ) \
+               pGPR[nr++] = static_cast<sal_uInt64>( *reinterpret_cast<const 
sal_Int32 *>( pSV ) );
+
+#define INSERT_INT16( pSV, nr, pGPR ) \
+       if ( nr < aarch64::MAX_GPR_REGS ) \
+               pGPR[nr++] = *reinterpret_cast<const sal_uInt16 *>( pSV );
+
+#define INSERT_SIGNED_INT16( pSV, nr, pGPR ) \
+       if ( nr < aarch64::MAX_GPR_REGS ) \
+               pGPR[nr++] = static_cast<sal_uInt64>( *reinterpret_cast<const 
sal_Int16 *>( pSV ) );
+
+#define INSERT_INT8( pSV, nr, pGPR ) \
+       if ( nr < aarch64::MAX_GPR_REGS ) \
+               pGPR[nr++] = *reinterpret_cast<const sal_uInt8 *>( pSV );
+
+#define INSERT_SIGNED_INT8( pSV, nr, pGPR ) \
+       if ( nr < aarch64::MAX_GPR_REGS ) \
+               pGPR[nr++] = static_cast<sal_uInt64>( *reinterpret_cast<const 
sal_Int8 *>( pSV ) );
+
+//==================================================================================================
+
+namespace {
+
+void appendCString(OUStringBuffer & buffer, char const * text) {
+    if (text != 0) {
+        buffer.append(
+            OStringToOUString(OString(text), RTL_TEXTENCODING_ISO_8859_1));
+    }
+}
+
+}
+
+static void cpp_call(
+       bridges::cpp_uno::shared::UnoInterfaceProxy * pThis,
+       bridges::cpp_uno::shared::VtableSlot aVtableSlot,
+       typelib_TypeDescriptionReference * pReturnTypeRef,
+       sal_Int32 nParams, typelib_MethodParameter * pParams,
+       void * pUnoReturn, void * pUnoArgs[], uno_Any ** ppUnoExc )
+{
+       unsigned char *pStackStart = static_cast<unsigned char *>(
+               __builtin_alloca( (nParams + 3) * sizeof(sal_uInt64) ) );
+       sal_uInt32 nStack = 0;
+
+       sal_uInt64 pGPR[aarch64::MAX_GPR_REGS];
+       sal_uInt32 nGPR = 0;
+
+       double pFPR[aarch64::MAX_FPR_REGS];
+       sal_uInt32 nFPR = 0;
+
+       typelib_TypeDescription * pReturnTypeDescr = 0;
+       TYPELIB_DANGER_GET( &pReturnTypeDescr, pReturnTypeRef );
+       OSL_ENSURE( pReturnTypeDescr, "### expected return type description!" );
+
+       void * pCppReturn = 0;
+
+       // Indirect-result pointer. On AArch64 this is passed in the dedicated 
x8
+       // register, NOT as the first general-purpose argument (unlike x86-64 
SysV).
+       void * pIndirectReturn = 0;
+
+       bool bSimpleReturn = true;
+       if ( pReturnTypeDescr )
+       {
+               if ( aarch64::return_in_hidden_param( pReturnTypeRef ) )
+                       bSimpleReturn = false;
+
+               if ( bSimpleReturn )
+                       pCppReturn = pUnoReturn;
+               else
+               {
+                       pCppReturn = 
bridges::cpp_uno::shared::relatesToInterfaceType( pReturnTypeDescr )?
+                                                __builtin_alloca( 
pReturnTypeDescr->nSize ) : pUnoReturn;
+                       pIndirectReturn = pCppReturn;
+               }
+       }
+
+       void * pAdjustedThisPtr = reinterpret_cast< void ** >( pThis->getCppI() 
) + aVtableSlot.offset;
+       INSERT_INT64( &pAdjustedThisPtr, nGPR, pGPR );
+
+       void ** pCppArgs = (void **)alloca( 3 * sizeof(void *) * nParams );
+       sal_Int32 * pTempIndizes = (sal_Int32 *)(pCppArgs + nParams);
+       typelib_TypeDescription ** ppTempParamTypeDescr = 
(typelib_TypeDescription **)(pCppArgs + (2 * nParams));
+
+       sal_Int32 nTempIndizes = 0;
+
+       for ( sal_Int32 nPos = 0; nPos < nParams; ++nPos )
+       {
+               const typelib_MethodParameter & rParam = pParams[nPos];
+               typelib_TypeDescription * pParamTypeDescr = 0;
+               TYPELIB_DANGER_GET( &pParamTypeDescr, rParam.pTypeRef );
+
+               if (!rParam.bOut && bridges::cpp_uno::shared::isSimpleType( 
pParamTypeDescr ))
+               {
+                       uno_copyAndConvertData( pCppArgs[nPos] = alloca( 8 ), 
pUnoArgs[nPos], pParamTypeDescr,
+                                                                       
pThis->getBridge()->getUno2Cpp() );
+                       bool onStack = false;
+
+                       switch (pParamTypeDescr->eTypeClass)
+                       {
+                       case typelib_TypeClass_HYPER:
+                       case typelib_TypeClass_UNSIGNED_HYPER:
+                               onStack = nGPR >= aarch64::MAX_GPR_REGS;
+                               INSERT_INT64( pCppArgs[nPos], nGPR, pGPR );
+                               break;
+                       case typelib_TypeClass_LONG:
+                               onStack = nGPR >= aarch64::MAX_GPR_REGS;
+                               INSERT_SIGNED_INT32( pCppArgs[nPos], nGPR, pGPR 
);
+                               break;
+                       case typelib_TypeClass_UNSIGNED_LONG:
+                       case typelib_TypeClass_ENUM:
+                               onStack = nGPR >= aarch64::MAX_GPR_REGS;
+                               INSERT_INT32( pCppArgs[nPos], nGPR, pGPR );
+                               break;
+                       case typelib_TypeClass_SHORT:
+                               onStack = nGPR >= aarch64::MAX_GPR_REGS;
+                               INSERT_SIGNED_INT16( pCppArgs[nPos], nGPR, pGPR 
);
+                               break;
+                       case typelib_TypeClass_CHAR:
+                       case typelib_TypeClass_UNSIGNED_SHORT:
+                               onStack = nGPR >= aarch64::MAX_GPR_REGS;
+                               INSERT_INT16( pCppArgs[nPos], nGPR, pGPR );
+                               break;
+                       case typelib_TypeClass_BYTE:
+                               onStack = nGPR >= aarch64::MAX_GPR_REGS;
+                               INSERT_SIGNED_INT8( pCppArgs[nPos], nGPR, pGPR 
);
+                               break;
+                       case typelib_TypeClass_BOOLEAN:
+                               onStack = nGPR >= aarch64::MAX_GPR_REGS;
+                               INSERT_INT8( pCppArgs[nPos], nGPR, pGPR );
+                               break;
+                       case typelib_TypeClass_FLOAT:
+                               onStack = nFPR >= aarch64::MAX_FPR_REGS;
+                               INSERT_FLOAT( pCppArgs[nPos], nFPR, pFPR );
+                               break;
+                       case typelib_TypeClass_DOUBLE:
+                               onStack = nFPR >= aarch64::MAX_FPR_REGS;
+                               INSERT_DOUBLE( pCppArgs[nPos], nFPR, pFPR );
+                               break;
+                       default:
+                               break;
+                       }
+                       if ( onStack )
+                       {
+                               nStack = aarch64::align_stack_offset( nStack, 
rParam.pTypeRef );
+                               sal_uInt32 size = aarch64::stack_size( 
rParam.pTypeRef );
+                               memcpy( pStackStart + nStack, pCppArgs[nPos], 
size );
+                               nStack += size;
+                       }
+
+                       TYPELIB_DANGER_RELEASE( pParamTypeDescr );
+               }
+               else
+               {
+                       if (! rParam.bIn)
+                       {
+                               uno_constructData(
+                                       pCppArgs[nPos] = alloca( 
pParamTypeDescr->nSize ),
+                                       pParamTypeDescr );
+                               pTempIndizes[nTempIndizes] = nPos;
+                               ppTempParamTypeDescr[nTempIndizes++] = 
pParamTypeDescr;
+                       }
+                       else if 
(bridges::cpp_uno::shared::relatesToInterfaceType( pParamTypeDescr ))
+                       {
+                               uno_copyAndConvertData(
+                                       pCppArgs[nPos] = alloca( 
pParamTypeDescr->nSize ),
+                                       pUnoArgs[nPos], pParamTypeDescr, 
pThis->getBridge()->getUno2Cpp() );
+
+                               pTempIndizes[nTempIndizes] = nPos;
+                               ppTempParamTypeDescr[nTempIndizes++] = 
pParamTypeDescr;
+                       }
+                       else
+                       {
+                               pCppArgs[nPos] = pUnoArgs[nPos];
+                               TYPELIB_DANGER_RELEASE( pParamTypeDescr );
+                       }
+                       if ( nGPR < aarch64::MAX_GPR_REGS )
+                       {
+                               INSERT_INT64( &(pCppArgs[nPos]), nGPR, pGPR );
+                       }
+                       else
+                       {
+                               nStack = (nStack + sizeof(void *) - 1) & 
~(sizeof(void *) - 1);
+                               memcpy( pStackStart + nStack, &pCppArgs[nPos], 
sizeof(void *) );
+                               nStack += sizeof(void *);
+                       }
+               }
+       }
+
+       try
+       {
+        try {
+            callVirtualMethod(
+                pAdjustedThisPtr, aVtableSlot.index,
+                pCppReturn, pReturnTypeRef, bSimpleReturn,
+                pIndirectReturn,
+                               pStackStart, nStack,
+                pGPR, nGPR,
+                pFPR, nFPR );
+        } catch (Exception &) {
+            throw;
+        } catch (std::exception & e) {
+            OUStringBuffer buf;
+            buf.appendAscii(RTL_CONSTASCII_STRINGPARAM("C++ code threw "));
+            appendCString(buf, typeid(e).name());
+            buf.appendAscii(RTL_CONSTASCII_STRINGPARAM(": "));
+            appendCString(buf, e.what());
+            throw RuntimeException(
+                buf.makeStringAndClear(), Reference< XInterface >());
+        } catch (...) {
+            throw RuntimeException(
+                OUString(
+                    RTL_CONSTASCII_USTRINGPARAM(
+                        "C++ code threw unknown exception")),
+                Reference< XInterface >());
+        }
+
+               *ppUnoExc = 0;
+
+               for ( ; nTempIndizes--; )
+               {
+                       sal_Int32 nIndex = pTempIndizes[nTempIndizes];
+                       typelib_TypeDescription * pParamTypeDescr = 
ppTempParamTypeDescr[nTempIndizes];
+
+                       if (pParams[nIndex].bIn)
+                       {
+                               if (pParams[nIndex].bOut)
+                               {
+                                       uno_destructData( pUnoArgs[nIndex], 
pParamTypeDescr, 0 );
+                                       uno_copyAndConvertData( 
pUnoArgs[nIndex], pCppArgs[nIndex], pParamTypeDescr,
+                                                                               
        pThis->getBridge()->getCpp2Uno() );
+                               }
+                       }
+                       else
+                       {
+                               uno_copyAndConvertData( pUnoArgs[nIndex], 
pCppArgs[nIndex], pParamTypeDescr,
+                                                                               
pThis->getBridge()->getCpp2Uno() );
+                       }
+                       uno_destructData( pCppArgs[nIndex], pParamTypeDescr, 
cpp_release );
+
+                       TYPELIB_DANGER_RELEASE( pParamTypeDescr );
+               }
+               if (pCppReturn && pUnoReturn != pCppReturn)
+               {
+                       uno_copyAndConvertData( pUnoReturn, pCppReturn, 
pReturnTypeDescr,
+                                                                       
pThis->getBridge()->getCpp2Uno() );
+                       uno_destructData( pCppReturn, pReturnTypeDescr, 
cpp_release );
+               }
+       }
+       catch (Exception & e)
+       {
+               std::type_info * type = 
CPPU_CURRENT_NAMESPACE::__cxa_current_exception_type();
+               CPPU_CURRENT_NAMESPACE::fillUnoException(
+                       type ? *type : typeid(e), &e, *ppUnoExc,
+                       pThis->getBridge()->getCpp2Uno() );
+
+               for ( ; nTempIndizes--; )
+               {
+                       sal_Int32 nIndex = pTempIndizes[nTempIndizes];
+                       uno_destructData(
+                               pCppArgs[nIndex], 
ppTempParamTypeDescr[nTempIndizes], cpp_release );
+                       TYPELIB_DANGER_RELEASE( 
ppTempParamTypeDescr[nTempIndizes] );
+               }
+               if (pReturnTypeDescr)
+                       TYPELIB_DANGER_RELEASE( pReturnTypeDescr );
+       }
+       catch (...)
+       {
+               RuntimeException e(
+                       OUString( RTL_CONSTASCII_USTRINGPARAM("C++ code threw 
unknown exception") ),
+                       Reference< XInterface >() );
+               uno_type_any_constructAndConvert(
+                       *ppUnoExc, &e, ::getCppuType( &e ).getTypeLibType(),
+                       pThis->getBridge()->getCpp2Uno() );
+               for ( ; nTempIndizes--; )
+               {
+                       sal_Int32 nIndex = pTempIndizes[nTempIndizes];
+                       uno_destructData(
+                               pCppArgs[nIndex], 
ppTempParamTypeDescr[nTempIndizes], cpp_release );
+                       TYPELIB_DANGER_RELEASE( 
ppTempParamTypeDescr[nTempIndizes] );
+               }
+               if (pReturnTypeDescr)
+                       TYPELIB_DANGER_RELEASE( pReturnTypeDescr );
+       }
+}
+
+//==================================================================================================
+
+namespace bridges { namespace cpp_uno { namespace shared {
+
+void unoInterfaceProxyDispatch(
+       uno_Interface * pUnoI, const typelib_TypeDescription * pMemberDescr,
+       void * pReturn, void * pArgs[], uno_Any ** ppException )
+{
+       bridges::cpp_uno::shared::UnoInterfaceProxy * pThis
+               = static_cast< bridges::cpp_uno::shared::UnoInterfaceProxy * 
>(pUnoI);
+#if OSL_DEBUG_LEVEL > 0
+       typelib_InterfaceTypeDescription * pTypeDescr = pThis->pTypeDescr;
+#endif
+
+       switch (pMemberDescr->eTypeClass)
+       {
+       case typelib_TypeClass_INTERFACE_ATTRIBUTE:
+       {
+#if OSL_DEBUG_LEVEL > 0
+               sal_Int32 nMemberPos = ((typelib_InterfaceMemberTypeDescription 
*)pMemberDescr)->nPosition;
+               OSL_ENSURE( nMemberPos < pTypeDescr->nAllMembers, "### member 
pos out of range!" );
+#endif
+               VtableSlot aVtableSlot(
+                               getVtableSlot(
+                                       reinterpret_cast<
+                                       
typelib_InterfaceAttributeTypeDescription const * >(
+                                               pMemberDescr)));
+
+               if (pReturn)
+               {
+                       cpp_call(
+                               pThis, aVtableSlot,
+                               ((typelib_InterfaceAttributeTypeDescription 
*)pMemberDescr)->pAttributeTypeRef,
+                               0, 0,
+                               pReturn, pArgs, ppException );
+               }
+               else
+               {
+                       typelib_MethodParameter aParam;
+                       aParam.pTypeRef =
+                               ((typelib_InterfaceAttributeTypeDescription 
*)pMemberDescr)->pAttributeTypeRef;
+                       aParam.bIn              = sal_True;
+                       aParam.bOut             = sal_False;
+
+                       typelib_TypeDescriptionReference * pReturnTypeRef = 0;
+                       OUString aVoidName( RTL_CONSTASCII_USTRINGPARAM("void") 
);
+                       typelib_typedescriptionreference_new(
+                               &pReturnTypeRef, typelib_TypeClass_VOID, 
aVoidName.pData );
+
+                       aVtableSlot.index += 1;
+                       cpp_call(
+                               pThis, aVtableSlot,
+                               pReturnTypeRef,
+                               1, &aParam,
+                               pReturn, pArgs, ppException );
+
+                       typelib_typedescriptionreference_release( 
pReturnTypeRef );
+               }
+
+               break;
+       }
+       case typelib_TypeClass_INTERFACE_METHOD:
+       {
+#if OSL_DEBUG_LEVEL > 0
+               sal_Int32 nMemberPos = ((typelib_InterfaceMemberTypeDescription 
*)pMemberDescr)->nPosition;
+               OSL_ENSURE( nMemberPos < pTypeDescr->nAllMembers, "### member 
pos out of range!" );
+#endif
+               VtableSlot aVtableSlot(
+                               getVtableSlot(
+                                       reinterpret_cast<
+                                       typelib_InterfaceMethodTypeDescription 
const * >(
+                                               pMemberDescr)));
+
+               switch (aVtableSlot.index)
+               {
+               case 1:
+                       (*pUnoI->acquire)( pUnoI );
+                       *ppException = 0;
+                       break;
+               case 2:
+                       (*pUnoI->release)( pUnoI );
+                       *ppException = 0;
+                       break;
+               case 0:
+               {
+                       typelib_TypeDescription * pTD = 0;
+                       TYPELIB_DANGER_GET( &pTD, reinterpret_cast< Type * >( 
pArgs[0] )->getTypeLibType() );
+                       if (pTD)
+                       {
+                uno_Interface * pInterface = 0;
+                (*pThis->getBridge()->getUnoEnv()->getRegisteredInterface)(
+                    pThis->getBridge()->getUnoEnv(),
+                    (void **)&pInterface, pThis->oid.pData, 
(typelib_InterfaceTypeDescription *)pTD );
+
+                if (pInterface)
+                {
+                    ::uno_any_construct(
+                        reinterpret_cast< uno_Any * >( pReturn ),
+                        &pInterface, pTD, 0 );
+                    (*pInterface->release)( pInterface );
+                    TYPELIB_DANGER_RELEASE( pTD );
+                    *ppException = 0;
+                    break;
+                }
+                TYPELIB_DANGER_RELEASE( pTD );
+            }
+               }
+               default:
+                       cpp_call(
+                               pThis, aVtableSlot,
+                               ((typelib_InterfaceMethodTypeDescription 
*)pMemberDescr)->pReturnTypeRef,
+                               ((typelib_InterfaceMethodTypeDescription 
*)pMemberDescr)->nParams,
+                               ((typelib_InterfaceMethodTypeDescription 
*)pMemberDescr)->pParams,
+                               pReturn, pArgs, ppException );
+               }
+               break;
+       }
+       default:
+       {
+               ::com::sun::star::uno::RuntimeException aExc(
+                               OUString( RTL_CONSTASCII_USTRINGPARAM("illegal 
member type description!") ),
+                               ::com::sun::star::uno::Reference< 
::com::sun::star::uno::XInterface >() );
+
+               Type const & rExcType = ::getCppuType( &aExc );
+               ::uno_type_any_construct( *ppException, &aExc, 
rExcType.getTypeLibType(), 0 );
+       }
+       }
+}
+
+} } }

Reply via email to