xref: /AOO41X/main/bridges/source/cpp_uno/s5abi_macosx_x86-64/uno2cpp.cxx (revision 67a794bc92a1e8ffd80bf2fdc9bf74ed09144659)
16d1ed1ddSHerbert Dürr /**************************************************************
26d1ed1ddSHerbert Dürr  *
36d1ed1ddSHerbert Dürr  * Licensed to the Apache Software Foundation (ASF) under one
46d1ed1ddSHerbert Dürr  * or more contributor license agreements.  See the NOTICE file
56d1ed1ddSHerbert Dürr  * distributed with this work for additional information
66d1ed1ddSHerbert Dürr  * regarding copyright ownership.  The ASF licenses this file
76d1ed1ddSHerbert Dürr  * to you under the Apache License, Version 2.0 (the
86d1ed1ddSHerbert Dürr  * "License"); you may not use this file except in compliance
96d1ed1ddSHerbert Dürr  * with the License.  You may obtain a copy of the License at
106d1ed1ddSHerbert Dürr  *
116d1ed1ddSHerbert Dürr  *   http://www.apache.org/licenses/LICENSE-2.0
126d1ed1ddSHerbert Dürr  *
136d1ed1ddSHerbert Dürr  * Unless required by applicable law or agreed to in writing,
146d1ed1ddSHerbert Dürr  * software distributed under the License is distributed on an
156d1ed1ddSHerbert Dürr  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
166d1ed1ddSHerbert Dürr  * KIND, either express or implied.  See the License for the
176d1ed1ddSHerbert Dürr  * specific language governing permissions and limitations
186d1ed1ddSHerbert Dürr  * under the License.
196d1ed1ddSHerbert Dürr  *
206d1ed1ddSHerbert Dürr  *************************************************************/
216d1ed1ddSHerbert Dürr 
226d1ed1ddSHerbert Dürr 
236d1ed1ddSHerbert Dürr 
246d1ed1ddSHerbert Dürr // MARKER(update_precomp.py): autogen include statement, do not remove
256d1ed1ddSHerbert Dürr #include "precompiled_bridges.hxx"
266d1ed1ddSHerbert Dürr 
276d1ed1ddSHerbert Dürr #include <exception>
286d1ed1ddSHerbert Dürr #include <typeinfo>
296d1ed1ddSHerbert Dürr #include <stdio.h>
306d1ed1ddSHerbert Dürr #include <stdlib.h>
316d1ed1ddSHerbert Dürr #include <string.h>
326d1ed1ddSHerbert Dürr 
336d1ed1ddSHerbert Dürr #include "rtl/alloc.h"
346d1ed1ddSHerbert Dürr #include "rtl/ustrbuf.hxx"
356d1ed1ddSHerbert Dürr 
366d1ed1ddSHerbert Dürr #include <com/sun/star/uno/genfunc.hxx>
376d1ed1ddSHerbert Dürr #include "com/sun/star/uno/RuntimeException.hpp"
386d1ed1ddSHerbert Dürr #include <uno/data.h>
396d1ed1ddSHerbert Dürr 
406d1ed1ddSHerbert Dürr #include <bridges/cpp_uno/shared/bridge.hxx>
416d1ed1ddSHerbert Dürr #include <bridges/cpp_uno/shared/types.hxx>
426d1ed1ddSHerbert Dürr #include "bridges/cpp_uno/shared/unointerfaceproxy.hxx"
436d1ed1ddSHerbert Dürr #include "bridges/cpp_uno/shared/vtables.hxx"
446d1ed1ddSHerbert Dürr 
456d1ed1ddSHerbert Dürr #include "abi.hxx"
466d1ed1ddSHerbert Dürr #include "share.hxx"
476d1ed1ddSHerbert Dürr 
486d1ed1ddSHerbert Dürr using namespace ::rtl;
496d1ed1ddSHerbert Dürr using namespace ::com::sun::star::uno;
506d1ed1ddSHerbert Dürr 
516d1ed1ddSHerbert Dürr //==================================================================================================
526d1ed1ddSHerbert Dürr static void callVirtualMethod(void * pThis, sal_uInt32 nVtableIndex,
536d1ed1ddSHerbert Dürr                               void * pRegisterReturn, typelib_TypeDescriptionReference * pReturnTypeRef, bool bSimpleReturn,
546d1ed1ddSHerbert Dürr                               sal_uInt64 *pStack, sal_uInt32 nStack,
556d1ed1ddSHerbert Dürr                               sal_uInt64 *pGPR, sal_uInt32 nGPR,
566d1ed1ddSHerbert Dürr                               double *pFPR, sal_uInt32 nFPR) __attribute__((noinline));
576d1ed1ddSHerbert Dürr 
callVirtualMethod(void * pThis,sal_uInt32 nVtableIndex,void * pRegisterReturn,typelib_TypeDescriptionReference * pReturnTypeRef,bool bSimpleReturn,sal_uInt64 * pStack,sal_uInt32 nStack,sal_uInt64 * pGPR,sal_uInt32 nGPR,double * pFPR,sal_uInt32 nFPR)586d1ed1ddSHerbert Dürr static void callVirtualMethod(void * pThis, sal_uInt32 nVtableIndex,
596d1ed1ddSHerbert Dürr                               void * pRegisterReturn, typelib_TypeDescriptionReference * pReturnTypeRef, bool bSimpleReturn,
606d1ed1ddSHerbert Dürr                               sal_uInt64 *pStack, sal_uInt32 nStack,
616d1ed1ddSHerbert Dürr                               sal_uInt64 *pGPR, sal_uInt32 nGPR,
626d1ed1ddSHerbert Dürr                               double *pFPR, sal_uInt32 nFPR)
636d1ed1ddSHerbert Dürr {
646d1ed1ddSHerbert Dürr #if OSL_DEBUG_LEVEL > 1
656d1ed1ddSHerbert Dürr     // Let's figure out what is really going on here
666d1ed1ddSHerbert Dürr     {
676d1ed1ddSHerbert Dürr         fprintf( stderr, "= callVirtualMethod() =\nGPR's (%d): ", nGPR );
686d1ed1ddSHerbert Dürr         for ( unsigned int i = 0; i < nGPR; ++i )
696d1ed1ddSHerbert Dürr             fprintf( stderr, "0x%lx, ", pGPR[i] );
706d1ed1ddSHerbert Dürr         fprintf( stderr, "\nFPR's (%d): ", nFPR );
716d1ed1ddSHerbert Dürr         for ( unsigned int i = 0; i < nFPR; ++i )
726d1ed1ddSHerbert Dürr             fprintf( stderr, "%f, ", pFPR[i] );
736d1ed1ddSHerbert Dürr         fprintf( stderr, "\nStack (%d): ", nStack );
746d1ed1ddSHerbert Dürr         for ( unsigned int i = 0; i < nStack; ++i )
756d1ed1ddSHerbert Dürr             fprintf( stderr, "0x%lx, ", pStack[i] );
766d1ed1ddSHerbert Dürr         fprintf( stderr, "\n" );
776d1ed1ddSHerbert Dürr     }
786d1ed1ddSHerbert Dürr #endif
796d1ed1ddSHerbert Dürr 
806d1ed1ddSHerbert Dürr     // The call instruction within the asm section of callVirtualMethod may throw
816d1ed1ddSHerbert Dürr     // exceptions.  So that the compiler handles this correctly, it is important
826d1ed1ddSHerbert Dürr     // that (a) callVirtualMethod might call dummy_can_throw_anything (although this
836d1ed1ddSHerbert Dürr     // never happens at runtime), which in turn can throw exceptions, and (b)
846d1ed1ddSHerbert Dürr     // callVirtualMethod is not inlined at its call site (so that any exceptions are
856d1ed1ddSHerbert Dürr     // caught which are thrown from the instruction calling callVirtualMethod):
866d1ed1ddSHerbert Dürr     if ( !pThis )
876d1ed1ddSHerbert Dürr         CPPU_CURRENT_NAMESPACE::dummy_can_throw_anything( "xxx" ); // address something
886d1ed1ddSHerbert Dürr 
896d1ed1ddSHerbert Dürr     // Should not happen, but...
906d1ed1ddSHerbert Dürr     if ( nFPR > x86_64::MAX_SSE_REGS )
916d1ed1ddSHerbert Dürr         nFPR = x86_64::MAX_SSE_REGS;
926d1ed1ddSHerbert Dürr     if ( nGPR > x86_64::MAX_GPR_REGS )
936d1ed1ddSHerbert Dürr         nGPR = x86_64::MAX_GPR_REGS;
946d1ed1ddSHerbert Dürr 
956d1ed1ddSHerbert Dürr     // Get pointer to method
966d1ed1ddSHerbert Dürr     sal_uInt64 pMethod = *((sal_uInt64 *)pThis);
976d1ed1ddSHerbert Dürr     pMethod += 8 * nVtableIndex;
986d1ed1ddSHerbert Dürr     pMethod = *((sal_uInt64 *)pMethod);
996d1ed1ddSHerbert Dürr 
1006d1ed1ddSHerbert Dürr     // Load parameters to stack, if necessary
1016d1ed1ddSHerbert Dürr     sal_uInt64* pCallStack = NULL;
1026d1ed1ddSHerbert Dürr     if ( nStack )
1036d1ed1ddSHerbert Dürr     {
1046d1ed1ddSHerbert Dürr         // 16-bytes aligned
1056d1ed1ddSHerbert Dürr         sal_uInt32 nStackBytes = ( ( nStack + 1 ) >> 1 ) * 16;
1066d1ed1ddSHerbert Dürr         pCallStack = (sal_uInt64*) __builtin_alloca( nStackBytes );
1076d1ed1ddSHerbert Dürr         memcpy( pCallStack, pStack, nStackBytes );
1086d1ed1ddSHerbert Dürr     }
1096d1ed1ddSHerbert Dürr 
1106d1ed1ddSHerbert Dürr     // Return values
1116d1ed1ddSHerbert Dürr     sal_uInt64 rax;
1126d1ed1ddSHerbert Dürr     sal_uInt64 rdx;
1136d1ed1ddSHerbert Dürr     double xmm0;
1146d1ed1ddSHerbert Dürr     double xmm1;
1156d1ed1ddSHerbert Dürr 
1166d1ed1ddSHerbert Dürr     asm volatile (
1176d1ed1ddSHerbert Dürr         // Fill the xmm registers
1186d1ed1ddSHerbert Dürr         "movq %2, %%rax\n\t"
1196d1ed1ddSHerbert Dürr 
1206d1ed1ddSHerbert Dürr         "movsd   (%%rax), %%xmm0\n\t"
1216d1ed1ddSHerbert Dürr         "movsd  8(%%rax), %%xmm1\n\t"
1226d1ed1ddSHerbert Dürr         "movsd 16(%%rax), %%xmm2\n\t"
1236d1ed1ddSHerbert Dürr         "movsd 24(%%rax), %%xmm3\n\t"
1246d1ed1ddSHerbert Dürr         "movsd 32(%%rax), %%xmm4\n\t"
1256d1ed1ddSHerbert Dürr         "movsd 40(%%rax), %%xmm5\n\t"
1266d1ed1ddSHerbert Dürr         "movsd 48(%%rax), %%xmm6\n\t"
1276d1ed1ddSHerbert Dürr         "movsd 56(%%rax), %%xmm7\n\t"
1286d1ed1ddSHerbert Dürr 
1296d1ed1ddSHerbert Dürr         // Fill the general purpose registers
1306d1ed1ddSHerbert Dürr         "movq %1, %%rax\n\t"
1316d1ed1ddSHerbert Dürr 
1326d1ed1ddSHerbert Dürr         "movq    (%%rax), %%rdi\n\t"
1336d1ed1ddSHerbert Dürr         "movq   8(%%rax), %%rsi\n\t"
1346d1ed1ddSHerbert Dürr         "movq  16(%%rax), %%rdx\n\t"
1356d1ed1ddSHerbert Dürr         "movq  24(%%rax), %%rcx\n\t"
1366d1ed1ddSHerbert Dürr         "movq  32(%%rax), %%r8\n\t"
1376d1ed1ddSHerbert Dürr         "movq  40(%%rax), %%r9\n\t"
1386d1ed1ddSHerbert Dürr 
1396d1ed1ddSHerbert Dürr         // Perform the call
1406d1ed1ddSHerbert Dürr         "movq %0, %%r11\n\t"
1416d1ed1ddSHerbert Dürr         "movq %3, %%rax\n\t"
1426d1ed1ddSHerbert Dürr         "call *%%r11\n\t"
1436d1ed1ddSHerbert Dürr 
1446d1ed1ddSHerbert Dürr         // Fill the return values
1456d1ed1ddSHerbert Dürr         "movq   %%rax, %4\n\t"
1466d1ed1ddSHerbert Dürr         "movq   %%rdx, %5\n\t"
1476d1ed1ddSHerbert Dürr         "movsd %%xmm0, %6\n\t"
1486d1ed1ddSHerbert Dürr         "movsd %%xmm1, %7\n\t"
1496d1ed1ddSHerbert Dürr         :
1506d1ed1ddSHerbert Dürr         : "m" ( pMethod ), "m" ( pGPR ), "m" ( pFPR ), "m" ( nFPR ),
1516d1ed1ddSHerbert Dürr           "m" ( rax ), "m" ( rdx ), "m" ( xmm0 ), "m" ( xmm1 ),
152*67a794bcSJim Jagielski           "m" (pCallStack) // dummy input to prevent the compiler from optimizing the alloca out
1536d1ed1ddSHerbert Dürr         : "rax", "rbx", "rcx", "rdx", "rdi", "rsi", "r8", "r9",
1546d1ed1ddSHerbert Dürr           "r10", "r11", "r10", "r12", "r13", "r14", "r15", "rbx",
1556d1ed1ddSHerbert Dürr           "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6", "xmm7"
1566d1ed1ddSHerbert Dürr     );
1576d1ed1ddSHerbert Dürr 
1586d1ed1ddSHerbert Dürr     switch (pReturnTypeRef->eTypeClass)
1596d1ed1ddSHerbert Dürr     {
1606d1ed1ddSHerbert Dürr     case typelib_TypeClass_HYPER:
1616d1ed1ddSHerbert Dürr     case typelib_TypeClass_UNSIGNED_HYPER:
1626d1ed1ddSHerbert Dürr         *reinterpret_cast<sal_uInt64 *>( pRegisterReturn ) = rax;
1636d1ed1ddSHerbert Dürr         break;
1646d1ed1ddSHerbert Dürr     case typelib_TypeClass_LONG:
1656d1ed1ddSHerbert Dürr     case typelib_TypeClass_UNSIGNED_LONG:
1666d1ed1ddSHerbert Dürr     case typelib_TypeClass_ENUM:
1676d1ed1ddSHerbert Dürr         *reinterpret_cast<sal_uInt32 *>( pRegisterReturn ) = *reinterpret_cast<sal_uInt32*>( &rax );
1686d1ed1ddSHerbert Dürr         break;
1696d1ed1ddSHerbert Dürr     case typelib_TypeClass_CHAR:
1706d1ed1ddSHerbert Dürr     case typelib_TypeClass_SHORT:
1716d1ed1ddSHerbert Dürr     case typelib_TypeClass_UNSIGNED_SHORT:
1726d1ed1ddSHerbert Dürr         *reinterpret_cast<sal_uInt16 *>( pRegisterReturn ) = *reinterpret_cast<sal_uInt16*>( &rax );
1736d1ed1ddSHerbert Dürr         break;
1746d1ed1ddSHerbert Dürr     case typelib_TypeClass_BOOLEAN:
1756d1ed1ddSHerbert Dürr     case typelib_TypeClass_BYTE:
1766d1ed1ddSHerbert Dürr         *reinterpret_cast<sal_uInt8 *>( pRegisterReturn ) = *reinterpret_cast<sal_uInt8*>( &rax );
1776d1ed1ddSHerbert Dürr         break;
1786d1ed1ddSHerbert Dürr     case typelib_TypeClass_FLOAT:
1796d1ed1ddSHerbert Dürr     case typelib_TypeClass_DOUBLE:
1806d1ed1ddSHerbert Dürr         *reinterpret_cast<double *>( pRegisterReturn ) = xmm0;
1816d1ed1ddSHerbert Dürr         break;
1826d1ed1ddSHerbert Dürr     default:
1836d1ed1ddSHerbert Dürr         {
1846d1ed1ddSHerbert Dürr             sal_Int32 const nRetSize = pReturnTypeRef->pType->nSize;
1856d1ed1ddSHerbert Dürr             if (bSimpleReturn && nRetSize <= 16 && nRetSize > 0)
1866d1ed1ddSHerbert Dürr             {
1876d1ed1ddSHerbert Dürr                 sal_uInt64 longs[2];
1886d1ed1ddSHerbert Dürr                 longs[0] = rax;
1896d1ed1ddSHerbert Dürr                 longs[1] = rdx;
1906d1ed1ddSHerbert Dürr 
1916d1ed1ddSHerbert Dürr                 double doubles[2];
1926d1ed1ddSHerbert Dürr                 doubles[0] = xmm0;
1936d1ed1ddSHerbert Dürr                 doubles[1] = xmm1;
1946d1ed1ddSHerbert Dürr                 x86_64::fill_struct( pReturnTypeRef, &longs[0], &doubles[0], pRegisterReturn);
1956d1ed1ddSHerbert Dürr             }
1966d1ed1ddSHerbert Dürr             break;
1976d1ed1ddSHerbert Dürr         }
1986d1ed1ddSHerbert Dürr     }
1996d1ed1ddSHerbert Dürr }
2006d1ed1ddSHerbert Dürr 
2016d1ed1ddSHerbert Dürr //==================================================================================================
2026d1ed1ddSHerbert Dürr 
2036d1ed1ddSHerbert Dürr // Macros for easier insertion of values to registers or stack
2046d1ed1ddSHerbert Dürr // pSV - pointer to the source
2056d1ed1ddSHerbert Dürr // nr - order of the value [will be increased if stored to register]
2066d1ed1ddSHerbert Dürr // pFPR, pGPR - pointer to the registers
2076d1ed1ddSHerbert Dürr // pDS - pointer to the stack [will be increased if stored here]
2086d1ed1ddSHerbert Dürr 
2096d1ed1ddSHerbert Dürr // The value in %xmm register is already prepared to be retrieved as a float,
2106d1ed1ddSHerbert Dürr // thus we treat float and double the same
2116d1ed1ddSHerbert Dürr #define INSERT_FLOAT_DOUBLE( pSV, nr, pFPR, pDS ) \
2126d1ed1ddSHerbert Dürr 	if ( nr < x86_64::MAX_SSE_REGS ) \
2136d1ed1ddSHerbert Dürr 		pFPR[nr++] = *reinterpret_cast<double *>( pSV ); \
2146d1ed1ddSHerbert Dürr 	else \
2156d1ed1ddSHerbert Dürr 		*pDS++ = *reinterpret_cast<sal_uInt64 *>( pSV ); // verbatim!
2166d1ed1ddSHerbert Dürr 
2176d1ed1ddSHerbert Dürr #define INSERT_INT64( pSV, nr, pGPR, pDS ) \
2186d1ed1ddSHerbert Dürr 	if ( nr < x86_64::MAX_GPR_REGS ) \
2196d1ed1ddSHerbert Dürr 		pGPR[nr++] = *reinterpret_cast<sal_uInt64 *>( pSV ); \
2206d1ed1ddSHerbert Dürr 	else \
2216d1ed1ddSHerbert Dürr 		*pDS++ = *reinterpret_cast<sal_uInt64 *>( pSV );
2226d1ed1ddSHerbert Dürr 
2236d1ed1ddSHerbert Dürr #define INSERT_INT32( pSV, nr, pGPR, pDS ) \
2246d1ed1ddSHerbert Dürr 	if ( nr < x86_64::MAX_GPR_REGS ) \
2256d1ed1ddSHerbert Dürr 		pGPR[nr++] = *reinterpret_cast<sal_uInt32 *>( pSV ); \
2266d1ed1ddSHerbert Dürr 	else \
2276d1ed1ddSHerbert Dürr 		*pDS++ = *reinterpret_cast<sal_uInt32 *>( pSV );
2286d1ed1ddSHerbert Dürr 
2296d1ed1ddSHerbert Dürr #define INSERT_INT16( pSV, nr, pGPR, pDS ) \
2306d1ed1ddSHerbert Dürr 	if ( nr < x86_64::MAX_GPR_REGS ) \
2316d1ed1ddSHerbert Dürr 		pGPR[nr++] = *reinterpret_cast<sal_uInt16 *>( pSV ); \
2326d1ed1ddSHerbert Dürr 	else \
2336d1ed1ddSHerbert Dürr 		*pDS++ = *reinterpret_cast<sal_uInt16 *>( pSV );
2346d1ed1ddSHerbert Dürr 
2356d1ed1ddSHerbert Dürr #define INSERT_INT8( pSV, nr, pGPR, pDS ) \
2366d1ed1ddSHerbert Dürr 	if ( nr < x86_64::MAX_GPR_REGS ) \
2376d1ed1ddSHerbert Dürr 		pGPR[nr++] = *reinterpret_cast<sal_uInt8 *>( pSV ); \
2386d1ed1ddSHerbert Dürr 	else \
2396d1ed1ddSHerbert Dürr 		*pDS++ = *reinterpret_cast<sal_uInt8 *>( pSV );
2406d1ed1ddSHerbert Dürr 
2416d1ed1ddSHerbert Dürr //==================================================================================================
2426d1ed1ddSHerbert Dürr 
2436d1ed1ddSHerbert Dürr namespace {
2446d1ed1ddSHerbert Dürr 
appendCString(OUStringBuffer & buffer,char const * text)2456d1ed1ddSHerbert Dürr void appendCString(OUStringBuffer & buffer, char const * text) {
2466d1ed1ddSHerbert Dürr     if (text != 0) {
2476d1ed1ddSHerbert Dürr         buffer.append(
2486d1ed1ddSHerbert Dürr             OStringToOUString(OString(text), RTL_TEXTENCODING_ISO_8859_1));
2496d1ed1ddSHerbert Dürr             // use 8859-1 to avoid conversion failure
2506d1ed1ddSHerbert Dürr     }
2516d1ed1ddSHerbert Dürr }
2526d1ed1ddSHerbert Dürr 
2536d1ed1ddSHerbert Dürr }
2546d1ed1ddSHerbert Dürr 
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)2556d1ed1ddSHerbert Dürr static void cpp_call(
2566d1ed1ddSHerbert Dürr 	bridges::cpp_uno::shared::UnoInterfaceProxy * pThis,
2576d1ed1ddSHerbert Dürr 	bridges::cpp_uno::shared::VtableSlot aVtableSlot,
2586d1ed1ddSHerbert Dürr 	typelib_TypeDescriptionReference * pReturnTypeRef,
2596d1ed1ddSHerbert Dürr 	sal_Int32 nParams, typelib_MethodParameter * pParams,
2606d1ed1ddSHerbert Dürr 	void * pUnoReturn, void * pUnoArgs[], uno_Any ** ppUnoExc )
2616d1ed1ddSHerbert Dürr {
2626d1ed1ddSHerbert Dürr 	// Maxium space for [complex ret ptr], values | ptr ...
2636d1ed1ddSHerbert Dürr 	// (but will be used less - some of the values will be in pGPR and pFPR)
2646d1ed1ddSHerbert Dürr   	sal_uInt64 *pStack = (sal_uInt64 *)__builtin_alloca( (nParams + 3) * sizeof(sal_uInt64) );
2656d1ed1ddSHerbert Dürr   	sal_uInt64 *pStackStart = pStack;
2666d1ed1ddSHerbert Dürr 
2676d1ed1ddSHerbert Dürr 	sal_uInt64 pGPR[x86_64::MAX_GPR_REGS];
2686d1ed1ddSHerbert Dürr 	sal_uInt32 nGPR = 0;
2696d1ed1ddSHerbert Dürr 
2706d1ed1ddSHerbert Dürr 	double pFPR[x86_64::MAX_SSE_REGS];
2716d1ed1ddSHerbert Dürr 	sal_uInt32 nFPR = 0;
2726d1ed1ddSHerbert Dürr 
2736d1ed1ddSHerbert Dürr 	// Return
2746d1ed1ddSHerbert Dürr 	typelib_TypeDescription * pReturnTypeDescr = 0;
2756d1ed1ddSHerbert Dürr 	TYPELIB_DANGER_GET( &pReturnTypeDescr, pReturnTypeRef );
2766d1ed1ddSHerbert Dürr 	OSL_ENSURE( pReturnTypeDescr, "### expected return type description!" );
2776d1ed1ddSHerbert Dürr 
2786d1ed1ddSHerbert Dürr 	void * pCppReturn = 0; // if != 0 && != pUnoReturn, needs reconversion (see below)
2796d1ed1ddSHerbert Dürr 
2806d1ed1ddSHerbert Dürr 	bool bSimpleReturn = true;
2816d1ed1ddSHerbert Dürr 	if ( pReturnTypeDescr )
2826d1ed1ddSHerbert Dürr 	{
2836d1ed1ddSHerbert Dürr 		if ( x86_64::return_in_hidden_param( pReturnTypeRef ) )
2846d1ed1ddSHerbert Dürr 			bSimpleReturn = false;
2856d1ed1ddSHerbert Dürr 
2866d1ed1ddSHerbert Dürr 		if ( bSimpleReturn )
2876d1ed1ddSHerbert Dürr 			pCppReturn = pUnoReturn; // direct way for simple types
2886d1ed1ddSHerbert Dürr 		else
2896d1ed1ddSHerbert Dürr 		{
2906d1ed1ddSHerbert Dürr 			// complex return via ptr
2916d1ed1ddSHerbert Dürr 			pCppReturn = bridges::cpp_uno::shared::relatesToInterfaceType( pReturnTypeDescr )?
2926d1ed1ddSHerbert Dürr 						 __builtin_alloca( pReturnTypeDescr->nSize ) : pUnoReturn;
2936d1ed1ddSHerbert Dürr 			INSERT_INT64( &pCppReturn, nGPR, pGPR, pStack );
2946d1ed1ddSHerbert Dürr 		}
2956d1ed1ddSHerbert Dürr 	}
2966d1ed1ddSHerbert Dürr 
2976d1ed1ddSHerbert Dürr 	// Push "this" pointer
2986d1ed1ddSHerbert Dürr 	void * pAdjustedThisPtr = reinterpret_cast< void ** >( pThis->getCppI() ) + aVtableSlot.offset;
2996d1ed1ddSHerbert Dürr 	INSERT_INT64( &pAdjustedThisPtr, nGPR, pGPR, pStack );
3006d1ed1ddSHerbert Dürr 
3016d1ed1ddSHerbert Dürr 	// Args
3026d1ed1ddSHerbert Dürr 	void ** pCppArgs = (void **)alloca( 3 * sizeof(void *) * nParams );
3036d1ed1ddSHerbert Dürr 	// Indizes of values this have to be converted (interface conversion cpp<=>uno)
3046d1ed1ddSHerbert Dürr 	sal_Int32 * pTempIndizes = (sal_Int32 *)(pCppArgs + nParams);
3056d1ed1ddSHerbert Dürr 	// Type descriptions for reconversions
3066d1ed1ddSHerbert Dürr 	typelib_TypeDescription ** ppTempParamTypeDescr = (typelib_TypeDescription **)(pCppArgs + (2 * nParams));
3076d1ed1ddSHerbert Dürr 
3086d1ed1ddSHerbert Dürr 	sal_Int32 nTempIndizes = 0;
3096d1ed1ddSHerbert Dürr 
3106d1ed1ddSHerbert Dürr 	for ( sal_Int32 nPos = 0; nPos < nParams; ++nPos )
3116d1ed1ddSHerbert Dürr 	{
3126d1ed1ddSHerbert Dürr 		const typelib_MethodParameter & rParam = pParams[nPos];
3136d1ed1ddSHerbert Dürr 		typelib_TypeDescription * pParamTypeDescr = 0;
3146d1ed1ddSHerbert Dürr 		TYPELIB_DANGER_GET( &pParamTypeDescr, rParam.pTypeRef );
3156d1ed1ddSHerbert Dürr 
3166d1ed1ddSHerbert Dürr 		if (!rParam.bOut && bridges::cpp_uno::shared::isSimpleType( pParamTypeDescr ))
3176d1ed1ddSHerbert Dürr 		{
3186d1ed1ddSHerbert Dürr 			uno_copyAndConvertData( pCppArgs[nPos] = alloca( 8 ), pUnoArgs[nPos], pParamTypeDescr,
3196d1ed1ddSHerbert Dürr 									pThis->getBridge()->getUno2Cpp() );
3206d1ed1ddSHerbert Dürr 
3216d1ed1ddSHerbert Dürr 			switch (pParamTypeDescr->eTypeClass)
3226d1ed1ddSHerbert Dürr 			{
3236d1ed1ddSHerbert Dürr 			case typelib_TypeClass_HYPER:
3246d1ed1ddSHerbert Dürr 			case typelib_TypeClass_UNSIGNED_HYPER:
3256d1ed1ddSHerbert Dürr 				INSERT_INT64( pCppArgs[nPos], nGPR, pGPR, pStack );
3266d1ed1ddSHerbert Dürr 				break;
3276d1ed1ddSHerbert Dürr 			case typelib_TypeClass_LONG:
3286d1ed1ddSHerbert Dürr 			case typelib_TypeClass_UNSIGNED_LONG:
3296d1ed1ddSHerbert Dürr 			case typelib_TypeClass_ENUM:
3306d1ed1ddSHerbert Dürr 				INSERT_INT32( pCppArgs[nPos], nGPR, pGPR, pStack );
3316d1ed1ddSHerbert Dürr 				break;
3326d1ed1ddSHerbert Dürr 			case typelib_TypeClass_SHORT:
3336d1ed1ddSHerbert Dürr 			case typelib_TypeClass_CHAR:
3346d1ed1ddSHerbert Dürr 			case typelib_TypeClass_UNSIGNED_SHORT:
3356d1ed1ddSHerbert Dürr 				INSERT_INT16( pCppArgs[nPos], nGPR, pGPR, pStack );
3366d1ed1ddSHerbert Dürr 				break;
3376d1ed1ddSHerbert Dürr 			case typelib_TypeClass_BOOLEAN:
3386d1ed1ddSHerbert Dürr 			case typelib_TypeClass_BYTE:
3396d1ed1ddSHerbert Dürr 				INSERT_INT8( pCppArgs[nPos], nGPR, pGPR, pStack );
3406d1ed1ddSHerbert Dürr 				break;
3416d1ed1ddSHerbert Dürr 			case typelib_TypeClass_FLOAT:
3426d1ed1ddSHerbert Dürr 			case typelib_TypeClass_DOUBLE:
3436d1ed1ddSHerbert Dürr 				INSERT_FLOAT_DOUBLE( pCppArgs[nPos], nFPR, pFPR, pStack );
3446d1ed1ddSHerbert Dürr 				break;
3456d1ed1ddSHerbert Dürr 			default:
3466d1ed1ddSHerbert Dürr 				break;
3476d1ed1ddSHerbert Dürr 			}
3486d1ed1ddSHerbert Dürr 
3496d1ed1ddSHerbert Dürr 			// no longer needed
3506d1ed1ddSHerbert Dürr 			TYPELIB_DANGER_RELEASE( pParamTypeDescr );
3516d1ed1ddSHerbert Dürr 		}
3526d1ed1ddSHerbert Dürr 		else // ptr to complex value | ref
3536d1ed1ddSHerbert Dürr 		{
3546d1ed1ddSHerbert Dürr 			if (! rParam.bIn) // is pure out
3556d1ed1ddSHerbert Dürr 			{
3566d1ed1ddSHerbert Dürr 				// cpp out is constructed mem, uno out is not!
3576d1ed1ddSHerbert Dürr 				uno_constructData(
3586d1ed1ddSHerbert Dürr 					pCppArgs[nPos] = alloca( pParamTypeDescr->nSize ),
3596d1ed1ddSHerbert Dürr 					pParamTypeDescr );
3606d1ed1ddSHerbert Dürr 				pTempIndizes[nTempIndizes] = nPos; // default constructed for cpp call
3616d1ed1ddSHerbert Dürr 				// will be released at reconversion
3626d1ed1ddSHerbert Dürr 				ppTempParamTypeDescr[nTempIndizes++] = pParamTypeDescr;
3636d1ed1ddSHerbert Dürr 			}
3646d1ed1ddSHerbert Dürr 			// is in/inout
3656d1ed1ddSHerbert Dürr 			else if (bridges::cpp_uno::shared::relatesToInterfaceType( pParamTypeDescr ))
3666d1ed1ddSHerbert Dürr 			{
3676d1ed1ddSHerbert Dürr 				uno_copyAndConvertData(
3686d1ed1ddSHerbert Dürr 					pCppArgs[nPos] = alloca( pParamTypeDescr->nSize ),
3696d1ed1ddSHerbert Dürr 					pUnoArgs[nPos], pParamTypeDescr, pThis->getBridge()->getUno2Cpp() );
3706d1ed1ddSHerbert Dürr 
3716d1ed1ddSHerbert Dürr 				pTempIndizes[nTempIndizes] = nPos; // has to be reconverted
3726d1ed1ddSHerbert Dürr 				// will be released at reconversion
3736d1ed1ddSHerbert Dürr 				ppTempParamTypeDescr[nTempIndizes++] = pParamTypeDescr;
3746d1ed1ddSHerbert Dürr 			}
3756d1ed1ddSHerbert Dürr 			else // direct way
3766d1ed1ddSHerbert Dürr 			{
3776d1ed1ddSHerbert Dürr 				pCppArgs[nPos] = pUnoArgs[nPos];
3786d1ed1ddSHerbert Dürr 				// no longer needed
3796d1ed1ddSHerbert Dürr 				TYPELIB_DANGER_RELEASE( pParamTypeDescr );
3806d1ed1ddSHerbert Dürr 			}
3816d1ed1ddSHerbert Dürr 			INSERT_INT64( &(pCppArgs[nPos]), nGPR, pGPR, pStack );
3826d1ed1ddSHerbert Dürr 		}
3836d1ed1ddSHerbert Dürr 	}
3846d1ed1ddSHerbert Dürr 
3856d1ed1ddSHerbert Dürr 	try
3866d1ed1ddSHerbert Dürr 	{
3876d1ed1ddSHerbert Dürr         try {
3886d1ed1ddSHerbert Dürr             callVirtualMethod(
3896d1ed1ddSHerbert Dürr                 pAdjustedThisPtr, aVtableSlot.index,
3906d1ed1ddSHerbert Dürr                 pCppReturn, pReturnTypeRef, bSimpleReturn,
3916d1ed1ddSHerbert Dürr                 pStackStart, ( pStack - pStackStart ),
3926d1ed1ddSHerbert Dürr                 pGPR, nGPR,
3936d1ed1ddSHerbert Dürr                 pFPR, nFPR );
3946d1ed1ddSHerbert Dürr         } catch (Exception &) {
3956d1ed1ddSHerbert Dürr             throw;
3966d1ed1ddSHerbert Dürr         } catch (std::exception & e) {
3976d1ed1ddSHerbert Dürr             OUStringBuffer buf;
3986d1ed1ddSHerbert Dürr             buf.appendAscii(RTL_CONSTASCII_STRINGPARAM("C++ code threw "));
3996d1ed1ddSHerbert Dürr             appendCString(buf, typeid(e).name());
4006d1ed1ddSHerbert Dürr             buf.appendAscii(RTL_CONSTASCII_STRINGPARAM(": "));
4016d1ed1ddSHerbert Dürr             appendCString(buf, e.what());
4026d1ed1ddSHerbert Dürr             throw RuntimeException(
4036d1ed1ddSHerbert Dürr                 buf.makeStringAndClear(), Reference< XInterface >());
4046d1ed1ddSHerbert Dürr         } catch (...) {
4056d1ed1ddSHerbert Dürr             throw RuntimeException(
4066d1ed1ddSHerbert Dürr                 OUString(
4076d1ed1ddSHerbert Dürr                     RTL_CONSTASCII_USTRINGPARAM(
4086d1ed1ddSHerbert Dürr                         "C++ code threw unknown exception")),
4096d1ed1ddSHerbert Dürr                 Reference< XInterface >());
4106d1ed1ddSHerbert Dürr         }
4116d1ed1ddSHerbert Dürr 
412*67a794bcSJim Jagielski 		// NO exception occurred...
4136d1ed1ddSHerbert Dürr 		*ppUnoExc = 0;
4146d1ed1ddSHerbert Dürr 
4156d1ed1ddSHerbert Dürr 		// reconvert temporary params
4166d1ed1ddSHerbert Dürr 		for ( ; nTempIndizes--; )
4176d1ed1ddSHerbert Dürr 		{
4186d1ed1ddSHerbert Dürr 			sal_Int32 nIndex = pTempIndizes[nTempIndizes];
4196d1ed1ddSHerbert Dürr 			typelib_TypeDescription * pParamTypeDescr = ppTempParamTypeDescr[nTempIndizes];
4206d1ed1ddSHerbert Dürr 
4216d1ed1ddSHerbert Dürr 			if (pParams[nIndex].bIn)
4226d1ed1ddSHerbert Dürr 			{
4236d1ed1ddSHerbert Dürr 				if (pParams[nIndex].bOut) // inout
4246d1ed1ddSHerbert Dürr 				{
4256d1ed1ddSHerbert Dürr 					uno_destructData( pUnoArgs[nIndex], pParamTypeDescr, 0 ); // destroy uno value
4266d1ed1ddSHerbert Dürr 					uno_copyAndConvertData( pUnoArgs[nIndex], pCppArgs[nIndex], pParamTypeDescr,
4276d1ed1ddSHerbert Dürr 											pThis->getBridge()->getCpp2Uno() );
4286d1ed1ddSHerbert Dürr 				}
4296d1ed1ddSHerbert Dürr 			}
4306d1ed1ddSHerbert Dürr 			else // pure out
4316d1ed1ddSHerbert Dürr 			{
4326d1ed1ddSHerbert Dürr 				uno_copyAndConvertData( pUnoArgs[nIndex], pCppArgs[nIndex], pParamTypeDescr,
4336d1ed1ddSHerbert Dürr 										pThis->getBridge()->getCpp2Uno() );
4346d1ed1ddSHerbert Dürr 			}
4356d1ed1ddSHerbert Dürr 			// destroy temp cpp param => cpp: every param was constructed
4366d1ed1ddSHerbert Dürr 			uno_destructData( pCppArgs[nIndex], pParamTypeDescr, cpp_release );
4376d1ed1ddSHerbert Dürr 
4386d1ed1ddSHerbert Dürr 			TYPELIB_DANGER_RELEASE( pParamTypeDescr );
4396d1ed1ddSHerbert Dürr 		}
4406d1ed1ddSHerbert Dürr 		// return value
4416d1ed1ddSHerbert Dürr 		if (pCppReturn && pUnoReturn != pCppReturn)
4426d1ed1ddSHerbert Dürr 		{
4436d1ed1ddSHerbert Dürr 			uno_copyAndConvertData( pUnoReturn, pCppReturn, pReturnTypeDescr,
4446d1ed1ddSHerbert Dürr 									pThis->getBridge()->getCpp2Uno() );
4456d1ed1ddSHerbert Dürr 			uno_destructData( pCppReturn, pReturnTypeDescr, cpp_release );
4466d1ed1ddSHerbert Dürr 		}
4476d1ed1ddSHerbert Dürr 	}
4486d1ed1ddSHerbert Dürr  	catch (...)
4496d1ed1ddSHerbert Dürr  	{
4506d1ed1ddSHerbert Dürr   		// fill uno exception
4516d1ed1ddSHerbert Dürr 		fillUnoException( CPPU_CURRENT_NAMESPACE::__cxa_get_globals()->caughtExceptions, *ppUnoExc, pThis->getBridge()->getCpp2Uno() );
4526d1ed1ddSHerbert Dürr 
4536d1ed1ddSHerbert Dürr 		// temporary params
4546d1ed1ddSHerbert Dürr 		for ( ; nTempIndizes--; )
4556d1ed1ddSHerbert Dürr 		{
4566d1ed1ddSHerbert Dürr 			sal_Int32 nIndex = pTempIndizes[nTempIndizes];
4576d1ed1ddSHerbert Dürr 			// destroy temp cpp param => cpp: every param was constructed
4586d1ed1ddSHerbert Dürr 			uno_destructData( pCppArgs[nIndex], ppTempParamTypeDescr[nTempIndizes], cpp_release );
4596d1ed1ddSHerbert Dürr 			TYPELIB_DANGER_RELEASE( ppTempParamTypeDescr[nTempIndizes] );
4606d1ed1ddSHerbert Dürr 		}
4616d1ed1ddSHerbert Dürr 		// return type
4626d1ed1ddSHerbert Dürr 		if (pReturnTypeDescr)
4636d1ed1ddSHerbert Dürr 			TYPELIB_DANGER_RELEASE( pReturnTypeDescr );
4646d1ed1ddSHerbert Dürr 	}
4656d1ed1ddSHerbert Dürr }
4666d1ed1ddSHerbert Dürr 
4676d1ed1ddSHerbert Dürr //==================================================================================================
4686d1ed1ddSHerbert Dürr 
4696d1ed1ddSHerbert Dürr namespace bridges { namespace cpp_uno { namespace shared {
4706d1ed1ddSHerbert Dürr 
unoInterfaceProxyDispatch(uno_Interface * pUnoI,const typelib_TypeDescription * pMemberDescr,void * pReturn,void * pArgs[],uno_Any ** ppException)4716d1ed1ddSHerbert Dürr void unoInterfaceProxyDispatch(
4726d1ed1ddSHerbert Dürr 	uno_Interface * pUnoI, const typelib_TypeDescription * pMemberDescr,
4736d1ed1ddSHerbert Dürr 	void * pReturn, void * pArgs[], uno_Any ** ppException )
4746d1ed1ddSHerbert Dürr {
4756d1ed1ddSHerbert Dürr 	// is my surrogate
4766d1ed1ddSHerbert Dürr 	bridges::cpp_uno::shared::UnoInterfaceProxy * pThis
4776d1ed1ddSHerbert Dürr 		= static_cast< bridges::cpp_uno::shared::UnoInterfaceProxy * >(pUnoI);
4786d1ed1ddSHerbert Dürr #if OSL_DEBUG_LEVEL > 0
4796d1ed1ddSHerbert Dürr 	typelib_InterfaceTypeDescription * pTypeDescr = pThis->pTypeDescr;
4806d1ed1ddSHerbert Dürr #endif
4816d1ed1ddSHerbert Dürr 
4826d1ed1ddSHerbert Dürr 	switch (pMemberDescr->eTypeClass)
4836d1ed1ddSHerbert Dürr 	{
4846d1ed1ddSHerbert Dürr 	case typelib_TypeClass_INTERFACE_ATTRIBUTE:
4856d1ed1ddSHerbert Dürr 	{
4866d1ed1ddSHerbert Dürr #if OSL_DEBUG_LEVEL > 0
4876d1ed1ddSHerbert Dürr 		// determine vtable call index
4886d1ed1ddSHerbert Dürr 		sal_Int32 nMemberPos = ((typelib_InterfaceMemberTypeDescription *)pMemberDescr)->nPosition;
4896d1ed1ddSHerbert Dürr 		OSL_ENSURE( nMemberPos < pTypeDescr->nAllMembers, "### member pos out of range!" );
4906d1ed1ddSHerbert Dürr #endif
4916d1ed1ddSHerbert Dürr 		VtableSlot aVtableSlot(
4926d1ed1ddSHerbert Dürr 				getVtableSlot(
4936d1ed1ddSHerbert Dürr 					reinterpret_cast<
4946d1ed1ddSHerbert Dürr 					typelib_InterfaceAttributeTypeDescription const * >(
4956d1ed1ddSHerbert Dürr 						pMemberDescr)));
4966d1ed1ddSHerbert Dürr 
4976d1ed1ddSHerbert Dürr 		if (pReturn)
4986d1ed1ddSHerbert Dürr 		{
4996d1ed1ddSHerbert Dürr 			// dependent dispatch
5006d1ed1ddSHerbert Dürr 			cpp_call(
5016d1ed1ddSHerbert Dürr 				pThis, aVtableSlot,
5026d1ed1ddSHerbert Dürr 				((typelib_InterfaceAttributeTypeDescription *)pMemberDescr)->pAttributeTypeRef,
5036d1ed1ddSHerbert Dürr 				0, 0, // no params
5046d1ed1ddSHerbert Dürr 				pReturn, pArgs, ppException );
5056d1ed1ddSHerbert Dürr 		}
5066d1ed1ddSHerbert Dürr 		else
5076d1ed1ddSHerbert Dürr 		{
5086d1ed1ddSHerbert Dürr 			// is SET
5096d1ed1ddSHerbert Dürr 			typelib_MethodParameter aParam;
5106d1ed1ddSHerbert Dürr 			aParam.pTypeRef =
5116d1ed1ddSHerbert Dürr 				((typelib_InterfaceAttributeTypeDescription *)pMemberDescr)->pAttributeTypeRef;
5126d1ed1ddSHerbert Dürr 			aParam.bIn		= sal_True;
5136d1ed1ddSHerbert Dürr 			aParam.bOut		= sal_False;
5146d1ed1ddSHerbert Dürr 
5156d1ed1ddSHerbert Dürr 			typelib_TypeDescriptionReference * pReturnTypeRef = 0;
5166d1ed1ddSHerbert Dürr 			OUString aVoidName( RTL_CONSTASCII_USTRINGPARAM("void") );
5176d1ed1ddSHerbert Dürr 			typelib_typedescriptionreference_new(
5186d1ed1ddSHerbert Dürr 				&pReturnTypeRef, typelib_TypeClass_VOID, aVoidName.pData );
5196d1ed1ddSHerbert Dürr 
5206d1ed1ddSHerbert Dürr 			// dependent dispatch
5216d1ed1ddSHerbert Dürr 			aVtableSlot.index += 1; // get, then set method
5226d1ed1ddSHerbert Dürr 			cpp_call(
5236d1ed1ddSHerbert Dürr 				pThis, aVtableSlot, // get, then set method
5246d1ed1ddSHerbert Dürr 				pReturnTypeRef,
5256d1ed1ddSHerbert Dürr 				1, &aParam,
5266d1ed1ddSHerbert Dürr 				pReturn, pArgs, ppException );
5276d1ed1ddSHerbert Dürr 
5286d1ed1ddSHerbert Dürr 			typelib_typedescriptionreference_release( pReturnTypeRef );
5296d1ed1ddSHerbert Dürr 		}
5306d1ed1ddSHerbert Dürr 
5316d1ed1ddSHerbert Dürr 		break;
5326d1ed1ddSHerbert Dürr 	}
5336d1ed1ddSHerbert Dürr 	case typelib_TypeClass_INTERFACE_METHOD:
5346d1ed1ddSHerbert Dürr 	{
5356d1ed1ddSHerbert Dürr #if OSL_DEBUG_LEVEL > 0
5366d1ed1ddSHerbert Dürr 		// determine vtable call index
5376d1ed1ddSHerbert Dürr 		sal_Int32 nMemberPos = ((typelib_InterfaceMemberTypeDescription *)pMemberDescr)->nPosition;
5386d1ed1ddSHerbert Dürr 		OSL_ENSURE( nMemberPos < pTypeDescr->nAllMembers, "### member pos out of range!" );
5396d1ed1ddSHerbert Dürr #endif
5406d1ed1ddSHerbert Dürr 		VtableSlot aVtableSlot(
5416d1ed1ddSHerbert Dürr 				getVtableSlot(
5426d1ed1ddSHerbert Dürr 					reinterpret_cast<
5436d1ed1ddSHerbert Dürr 					typelib_InterfaceMethodTypeDescription const * >(
5446d1ed1ddSHerbert Dürr 						pMemberDescr)));
5456d1ed1ddSHerbert Dürr 
5466d1ed1ddSHerbert Dürr 		switch (aVtableSlot.index)
5476d1ed1ddSHerbert Dürr 		{
5486d1ed1ddSHerbert Dürr 			// standard calls
5496d1ed1ddSHerbert Dürr 		case 1: // acquire uno interface
5506d1ed1ddSHerbert Dürr 			(*pUnoI->acquire)( pUnoI );
5516d1ed1ddSHerbert Dürr 			*ppException = 0;
5526d1ed1ddSHerbert Dürr 			break;
5536d1ed1ddSHerbert Dürr 		case 2: // release uno interface
5546d1ed1ddSHerbert Dürr 			(*pUnoI->release)( pUnoI );
5556d1ed1ddSHerbert Dürr 			*ppException = 0;
5566d1ed1ddSHerbert Dürr 			break;
5576d1ed1ddSHerbert Dürr 		case 0: // queryInterface() opt
5586d1ed1ddSHerbert Dürr 		{
5596d1ed1ddSHerbert Dürr 			typelib_TypeDescription * pTD = 0;
5606d1ed1ddSHerbert Dürr 			TYPELIB_DANGER_GET( &pTD, reinterpret_cast< Type * >( pArgs[0] )->getTypeLibType() );
5616d1ed1ddSHerbert Dürr 			if (pTD)
5626d1ed1ddSHerbert Dürr 			{
5636d1ed1ddSHerbert Dürr                 uno_Interface * pInterface = 0;
5646d1ed1ddSHerbert Dürr                 (*pThis->getBridge()->getUnoEnv()->getRegisteredInterface)(
5656d1ed1ddSHerbert Dürr                     pThis->getBridge()->getUnoEnv(),
5666d1ed1ddSHerbert Dürr                     (void **)&pInterface, pThis->oid.pData, (typelib_InterfaceTypeDescription *)pTD );
5676d1ed1ddSHerbert Dürr 
5686d1ed1ddSHerbert Dürr                 if (pInterface)
5696d1ed1ddSHerbert Dürr                 {
5706d1ed1ddSHerbert Dürr                     ::uno_any_construct(
5716d1ed1ddSHerbert Dürr                         reinterpret_cast< uno_Any * >( pReturn ),
5726d1ed1ddSHerbert Dürr                         &pInterface, pTD, 0 );
5736d1ed1ddSHerbert Dürr                     (*pInterface->release)( pInterface );
5746d1ed1ddSHerbert Dürr                     TYPELIB_DANGER_RELEASE( pTD );
5756d1ed1ddSHerbert Dürr                     *ppException = 0;
5766d1ed1ddSHerbert Dürr                     break;
5776d1ed1ddSHerbert Dürr                 }
5786d1ed1ddSHerbert Dürr                 TYPELIB_DANGER_RELEASE( pTD );
5796d1ed1ddSHerbert Dürr             }
5806d1ed1ddSHerbert Dürr 		} // else perform queryInterface()
5816d1ed1ddSHerbert Dürr 		default:
5826d1ed1ddSHerbert Dürr 			// dependent dispatch
5836d1ed1ddSHerbert Dürr 			cpp_call(
5846d1ed1ddSHerbert Dürr 				pThis, aVtableSlot,
5856d1ed1ddSHerbert Dürr 				((typelib_InterfaceMethodTypeDescription *)pMemberDescr)->pReturnTypeRef,
5866d1ed1ddSHerbert Dürr 				((typelib_InterfaceMethodTypeDescription *)pMemberDescr)->nParams,
5876d1ed1ddSHerbert Dürr 				((typelib_InterfaceMethodTypeDescription *)pMemberDescr)->pParams,
5886d1ed1ddSHerbert Dürr 				pReturn, pArgs, ppException );
5896d1ed1ddSHerbert Dürr 		}
5906d1ed1ddSHerbert Dürr 		break;
5916d1ed1ddSHerbert Dürr 	}
5926d1ed1ddSHerbert Dürr 	default:
5936d1ed1ddSHerbert Dürr 	{
5946d1ed1ddSHerbert Dürr 		::com::sun::star::uno::RuntimeException aExc(
5956d1ed1ddSHerbert Dürr 			OUString( RTL_CONSTASCII_USTRINGPARAM("illegal member type description!") ),
5966d1ed1ddSHerbert Dürr 			::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >() );
5976d1ed1ddSHerbert Dürr 
5986d1ed1ddSHerbert Dürr 		Type const & rExcType = ::getCppuType( &aExc );
5996d1ed1ddSHerbert Dürr 		// binary identical null reference
6006d1ed1ddSHerbert Dürr 		::uno_type_any_construct( *ppException, &aExc, rExcType.getTypeLibType(), 0 );
6016d1ed1ddSHerbert Dürr 	}
6026d1ed1ddSHerbert Dürr 	}
6036d1ed1ddSHerbert Dürr }
6046d1ed1ddSHerbert Dürr 
6056d1ed1ddSHerbert Dürr } } }
606