12755751fSHerbert Dürr /**************************************************************
22755751fSHerbert Dürr *
32755751fSHerbert Dürr * Licensed to the Apache Software Foundation (ASF) under one
42755751fSHerbert Dürr * or more contributor license agreements. See the NOTICE file
52755751fSHerbert Dürr * distributed with this work for additional information
62755751fSHerbert Dürr * regarding copyright ownership. The ASF licenses this file
72755751fSHerbert Dürr * to you under the Apache License, Version 2.0 (the
82755751fSHerbert Dürr * "License"); you may not use this file except in compliance
92755751fSHerbert Dürr * with the License. You may obtain a copy of the License at
102755751fSHerbert Dürr *
112755751fSHerbert Dürr * http://www.apache.org/licenses/LICENSE-2.0
122755751fSHerbert Dürr *
132755751fSHerbert Dürr * Unless required by applicable law or agreed to in writing,
142755751fSHerbert Dürr * software distributed under the License is distributed on an
152755751fSHerbert Dürr * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
162755751fSHerbert Dürr * KIND, either express or implied. See the License for the
172755751fSHerbert Dürr * specific language governing permissions and limitations
182755751fSHerbert Dürr * under the License.
192755751fSHerbert Dürr *
202755751fSHerbert Dürr *************************************************************/
212755751fSHerbert Dürr
222755751fSHerbert Dürr
232755751fSHerbert Dürr
242755751fSHerbert Dürr // MARKER(update_precomp.py): autogen include statement, do not remove
252755751fSHerbert Dürr #include "precompiled_bridges.hxx"
262755751fSHerbert Dürr
272755751fSHerbert Dürr #include <exception>
282755751fSHerbert Dürr #include <typeinfo>
292755751fSHerbert Dürr #include <stdio.h>
302755751fSHerbert Dürr #include <stdlib.h>
312755751fSHerbert Dürr #include <string.h>
322755751fSHerbert Dürr
332755751fSHerbert Dürr #include "rtl/alloc.h"
342755751fSHerbert Dürr #include "rtl/ustrbuf.hxx"
352755751fSHerbert Dürr
362755751fSHerbert Dürr #include <com/sun/star/uno/genfunc.hxx>
372755751fSHerbert Dürr #include "com/sun/star/uno/RuntimeException.hpp"
382755751fSHerbert Dürr #include <uno/data.h>
392755751fSHerbert Dürr
402755751fSHerbert Dürr #include <bridges/cpp_uno/shared/bridge.hxx>
412755751fSHerbert Dürr #include <bridges/cpp_uno/shared/types.hxx>
422755751fSHerbert Dürr #include "bridges/cpp_uno/shared/unointerfaceproxy.hxx"
432755751fSHerbert Dürr #include "bridges/cpp_uno/shared/vtables.hxx"
442755751fSHerbert Dürr
452755751fSHerbert Dürr #include "abi.hxx"
462755751fSHerbert Dürr #include "share.hxx"
472755751fSHerbert Dürr
482755751fSHerbert Dürr using namespace ::rtl;
492755751fSHerbert Dürr using namespace ::com::sun::star::uno;
502755751fSHerbert Dürr
512755751fSHerbert Dürr //==================================================================================================
522755751fSHerbert Dürr static void callVirtualMethod(void * pThis, sal_uInt32 nVtableIndex,
532755751fSHerbert Dürr void * pRegisterReturn, typelib_TypeDescriptionReference * pReturnTypeRef, bool bSimpleReturn,
542755751fSHerbert Dürr sal_uInt64 *pStack, sal_uInt32 nStack,
552755751fSHerbert Dürr sal_uInt64 *pGPR, sal_uInt32 nGPR,
562755751fSHerbert Dürr double *pFPR, sal_uInt32 nFPR) __attribute__((noinline));
572755751fSHerbert 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)582755751fSHerbert Dürr static void callVirtualMethod(void * pThis, sal_uInt32 nVtableIndex,
592755751fSHerbert Dürr void * pRegisterReturn, typelib_TypeDescriptionReference * pReturnTypeRef, bool bSimpleReturn,
602755751fSHerbert Dürr sal_uInt64 *pStack, sal_uInt32 nStack,
612755751fSHerbert Dürr sal_uInt64 *pGPR, sal_uInt32 nGPR,
622755751fSHerbert Dürr double *pFPR, sal_uInt32 nFPR)
632755751fSHerbert Dürr {
642755751fSHerbert Dürr #if OSL_DEBUG_LEVEL > 1
652755751fSHerbert Dürr // Let's figure out what is really going on here
662755751fSHerbert Dürr {
672755751fSHerbert Dürr fprintf( stderr, "= callVirtualMethod() =\nGPR's (%d): ", nGPR );
682755751fSHerbert Dürr for ( unsigned int i = 0; i < nGPR; ++i )
692755751fSHerbert Dürr fprintf( stderr, "0x%lx, ", pGPR[i] );
702755751fSHerbert Dürr fprintf( stderr, "\nFPR's (%d): ", nFPR );
712755751fSHerbert Dürr for ( unsigned int i = 0; i < nFPR; ++i )
722755751fSHerbert Dürr fprintf( stderr, "%f, ", pFPR[i] );
732755751fSHerbert Dürr fprintf( stderr, "\nStack (%d): ", nStack );
742755751fSHerbert Dürr for ( unsigned int i = 0; i < nStack; ++i )
752755751fSHerbert Dürr fprintf( stderr, "0x%lx, ", pStack[i] );
762755751fSHerbert Dürr fprintf( stderr, "\n" );
772755751fSHerbert Dürr }
782755751fSHerbert Dürr #endif
792755751fSHerbert Dürr
802755751fSHerbert Dürr // The call instruction within the asm section of callVirtualMethod may throw
812755751fSHerbert Dürr // exceptions. So that the compiler handles this correctly, it is important
822755751fSHerbert Dürr // that (a) callVirtualMethod might call dummy_can_throw_anything (although this
832755751fSHerbert Dürr // never happens at runtime), which in turn can throw exceptions, and (b)
842755751fSHerbert Dürr // callVirtualMethod is not inlined at its call site (so that any exceptions are
852755751fSHerbert Dürr // caught which are thrown from the instruction calling callVirtualMethod):
862755751fSHerbert Dürr if ( !pThis )
872755751fSHerbert Dürr CPPU_CURRENT_NAMESPACE::dummy_can_throw_anything( "xxx" ); // address something
882755751fSHerbert Dürr
892755751fSHerbert Dürr // Should not happen, but...
902755751fSHerbert Dürr if ( nFPR > x86_64::MAX_SSE_REGS )
912755751fSHerbert Dürr nFPR = x86_64::MAX_SSE_REGS;
922755751fSHerbert Dürr if ( nGPR > x86_64::MAX_GPR_REGS )
932755751fSHerbert Dürr nGPR = x86_64::MAX_GPR_REGS;
942755751fSHerbert Dürr
952755751fSHerbert Dürr // Get pointer to method
962755751fSHerbert Dürr sal_uInt64 pMethod = *((sal_uInt64 *)pThis);
972755751fSHerbert Dürr pMethod += 8 * nVtableIndex;
982755751fSHerbert Dürr pMethod = *((sal_uInt64 *)pMethod);
992755751fSHerbert Dürr
1002755751fSHerbert Dürr // Load parameters to stack, if necessary
1013f6fbc83SHerbert Dürr sal_uInt64* pCallStack = NULL;
1022755751fSHerbert Dürr if ( nStack )
1032755751fSHerbert Dürr {
1042755751fSHerbert Dürr // 16-bytes aligned
1052755751fSHerbert Dürr sal_uInt32 nStackBytes = ( ( nStack + 1 ) >> 1 ) * 16;
1063f6fbc83SHerbert Dürr pCallStack = (sal_uInt64*) __builtin_alloca( nStackBytes );
1072755751fSHerbert Dürr memcpy( pCallStack, pStack, nStackBytes );
1082755751fSHerbert Dürr }
1092755751fSHerbert Dürr
1102755751fSHerbert Dürr // Return values
1112755751fSHerbert Dürr sal_uInt64 rax;
1122755751fSHerbert Dürr sal_uInt64 rdx;
1132755751fSHerbert Dürr double xmm0;
1142755751fSHerbert Dürr double xmm1;
1152755751fSHerbert Dürr
1162755751fSHerbert Dürr asm volatile (
1172755751fSHerbert Dürr // Fill the xmm registers
1182755751fSHerbert Dürr "movq %2, %%rax\n\t"
1192755751fSHerbert Dürr
1202755751fSHerbert Dürr "movsd (%%rax), %%xmm0\n\t"
1212755751fSHerbert Dürr "movsd 8(%%rax), %%xmm1\n\t"
1222755751fSHerbert Dürr "movsd 16(%%rax), %%xmm2\n\t"
1232755751fSHerbert Dürr "movsd 24(%%rax), %%xmm3\n\t"
1242755751fSHerbert Dürr "movsd 32(%%rax), %%xmm4\n\t"
1252755751fSHerbert Dürr "movsd 40(%%rax), %%xmm5\n\t"
1262755751fSHerbert Dürr "movsd 48(%%rax), %%xmm6\n\t"
1272755751fSHerbert Dürr "movsd 56(%%rax), %%xmm7\n\t"
1282755751fSHerbert Dürr
1292755751fSHerbert Dürr // Fill the general purpose registers
1302755751fSHerbert Dürr "movq %1, %%rax\n\t"
1312755751fSHerbert Dürr
1322755751fSHerbert Dürr "movq (%%rax), %%rdi\n\t"
1332755751fSHerbert Dürr "movq 8(%%rax), %%rsi\n\t"
1342755751fSHerbert Dürr "movq 16(%%rax), %%rdx\n\t"
1352755751fSHerbert Dürr "movq 24(%%rax), %%rcx\n\t"
1362755751fSHerbert Dürr "movq 32(%%rax), %%r8\n\t"
1372755751fSHerbert Dürr "movq 40(%%rax), %%r9\n\t"
1382755751fSHerbert Dürr
1392755751fSHerbert Dürr // Perform the call
1402755751fSHerbert Dürr "movq %0, %%r11\n\t"
1412755751fSHerbert Dürr "movq %3, %%rax\n\t"
1422755751fSHerbert Dürr "call *%%r11\n\t"
1432755751fSHerbert Dürr
1442755751fSHerbert Dürr // Fill the return values
1452755751fSHerbert Dürr "movq %%rax, %4\n\t"
1462755751fSHerbert Dürr "movq %%rdx, %5\n\t"
1472755751fSHerbert Dürr "movsd %%xmm0, %6\n\t"
1482755751fSHerbert Dürr "movsd %%xmm1, %7\n\t"
1492755751fSHerbert Dürr :
1502755751fSHerbert Dürr : "m" ( pMethod ), "m" ( pGPR ), "m" ( pFPR ), "m" ( nFPR ),
1513f6fbc83SHerbert 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
1533f6fbc83SHerbert Dürr : "rax", "rbx", "rcx", "rdx", "rdi", "rsi", "r8", "r9",
1543f6fbc83SHerbert Dürr "r10", "r11", "r10", "r12", "r13", "r14", "r15", "rbx",
1553f6fbc83SHerbert Dürr "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6", "xmm7"
1562755751fSHerbert Dürr );
1572755751fSHerbert Dürr
1582755751fSHerbert Dürr switch (pReturnTypeRef->eTypeClass)
1592755751fSHerbert Dürr {
1602755751fSHerbert Dürr case typelib_TypeClass_HYPER:
1612755751fSHerbert Dürr case typelib_TypeClass_UNSIGNED_HYPER:
1622755751fSHerbert Dürr *reinterpret_cast<sal_uInt64 *>( pRegisterReturn ) = rax;
1632755751fSHerbert Dürr break;
1642755751fSHerbert Dürr case typelib_TypeClass_LONG:
1652755751fSHerbert Dürr case typelib_TypeClass_UNSIGNED_LONG:
1662755751fSHerbert Dürr case typelib_TypeClass_ENUM:
1672755751fSHerbert Dürr *reinterpret_cast<sal_uInt32 *>( pRegisterReturn ) = *reinterpret_cast<sal_uInt32*>( &rax );
1682755751fSHerbert Dürr break;
1692755751fSHerbert Dürr case typelib_TypeClass_CHAR:
1702755751fSHerbert Dürr case typelib_TypeClass_SHORT:
1712755751fSHerbert Dürr case typelib_TypeClass_UNSIGNED_SHORT:
1722755751fSHerbert Dürr *reinterpret_cast<sal_uInt16 *>( pRegisterReturn ) = *reinterpret_cast<sal_uInt16*>( &rax );
1732755751fSHerbert Dürr break;
1742755751fSHerbert Dürr case typelib_TypeClass_BOOLEAN:
1752755751fSHerbert Dürr case typelib_TypeClass_BYTE:
1762755751fSHerbert Dürr *reinterpret_cast<sal_uInt8 *>( pRegisterReturn ) = *reinterpret_cast<sal_uInt8*>( &rax );
1772755751fSHerbert Dürr break;
1782755751fSHerbert Dürr case typelib_TypeClass_FLOAT:
1792755751fSHerbert Dürr case typelib_TypeClass_DOUBLE:
1802755751fSHerbert Dürr *reinterpret_cast<double *>( pRegisterReturn ) = xmm0;
1812755751fSHerbert Dürr break;
1822755751fSHerbert Dürr default:
1832755751fSHerbert Dürr {
1842755751fSHerbert Dürr sal_Int32 const nRetSize = pReturnTypeRef->pType->nSize;
1852755751fSHerbert Dürr if (bSimpleReturn && nRetSize <= 16 && nRetSize > 0)
1862755751fSHerbert Dürr {
1872755751fSHerbert Dürr sal_uInt64 longs[2];
1882755751fSHerbert Dürr longs[0] = rax;
1892755751fSHerbert Dürr longs[1] = rdx;
1902755751fSHerbert Dürr
1912755751fSHerbert Dürr double doubles[2];
1922755751fSHerbert Dürr doubles[0] = xmm0;
1932755751fSHerbert Dürr doubles[1] = xmm1;
1942755751fSHerbert Dürr x86_64::fill_struct( pReturnTypeRef, &longs[0], &doubles[0], pRegisterReturn);
1952755751fSHerbert Dürr }
1962755751fSHerbert Dürr break;
1972755751fSHerbert Dürr }
1982755751fSHerbert Dürr }
1992755751fSHerbert Dürr }
2002755751fSHerbert Dürr
2012755751fSHerbert Dürr //==================================================================================================
2022755751fSHerbert Dürr
2032755751fSHerbert Dürr // Macros for easier insertion of values to registers or stack
2042755751fSHerbert Dürr // pSV - pointer to the source
2052755751fSHerbert Dürr // nr - order of the value [will be increased if stored to register]
2062755751fSHerbert Dürr // pFPR, pGPR - pointer to the registers
2072755751fSHerbert Dürr // pDS - pointer to the stack [will be increased if stored here]
2082755751fSHerbert Dürr
2092755751fSHerbert Dürr // The value in %xmm register is already prepared to be retrieved as a float,
2102755751fSHerbert Dürr // thus we treat float and double the same
2112755751fSHerbert Dürr #define INSERT_FLOAT_DOUBLE( pSV, nr, pFPR, pDS ) \
2122755751fSHerbert Dürr if ( nr < x86_64::MAX_SSE_REGS ) \
2132755751fSHerbert Dürr pFPR[nr++] = *reinterpret_cast<double *>( pSV ); \
2142755751fSHerbert Dürr else \
2152755751fSHerbert Dürr *pDS++ = *reinterpret_cast<sal_uInt64 *>( pSV ); // verbatim!
2162755751fSHerbert Dürr
2172755751fSHerbert Dürr #define INSERT_INT64( pSV, nr, pGPR, pDS ) \
2182755751fSHerbert Dürr if ( nr < x86_64::MAX_GPR_REGS ) \
2192755751fSHerbert Dürr pGPR[nr++] = *reinterpret_cast<sal_uInt64 *>( pSV ); \
2202755751fSHerbert Dürr else \
2212755751fSHerbert Dürr *pDS++ = *reinterpret_cast<sal_uInt64 *>( pSV );
2222755751fSHerbert Dürr
2232755751fSHerbert Dürr #define INSERT_INT32( pSV, nr, pGPR, pDS ) \
2242755751fSHerbert Dürr if ( nr < x86_64::MAX_GPR_REGS ) \
2252755751fSHerbert Dürr pGPR[nr++] = *reinterpret_cast<sal_uInt32 *>( pSV ); \
2262755751fSHerbert Dürr else \
2272755751fSHerbert Dürr *pDS++ = *reinterpret_cast<sal_uInt32 *>( pSV );
2282755751fSHerbert Dürr
2292755751fSHerbert Dürr #define INSERT_INT16( pSV, nr, pGPR, pDS ) \
2302755751fSHerbert Dürr if ( nr < x86_64::MAX_GPR_REGS ) \
2312755751fSHerbert Dürr pGPR[nr++] = *reinterpret_cast<sal_uInt16 *>( pSV ); \
2322755751fSHerbert Dürr else \
2332755751fSHerbert Dürr *pDS++ = *reinterpret_cast<sal_uInt16 *>( pSV );
2342755751fSHerbert Dürr
2352755751fSHerbert Dürr #define INSERT_INT8( pSV, nr, pGPR, pDS ) \
2362755751fSHerbert Dürr if ( nr < x86_64::MAX_GPR_REGS ) \
2372755751fSHerbert Dürr pGPR[nr++] = *reinterpret_cast<sal_uInt8 *>( pSV ); \
2382755751fSHerbert Dürr else \
2392755751fSHerbert Dürr *pDS++ = *reinterpret_cast<sal_uInt8 *>( pSV );
2402755751fSHerbert Dürr
2412755751fSHerbert Dürr //==================================================================================================
2422755751fSHerbert Dürr
2432755751fSHerbert Dürr namespace {
2442755751fSHerbert Dürr
appendCString(OUStringBuffer & buffer,char const * text)2452755751fSHerbert Dürr void appendCString(OUStringBuffer & buffer, char const * text) {
2462755751fSHerbert Dürr if (text != 0) {
2472755751fSHerbert Dürr buffer.append(
2482755751fSHerbert Dürr OStringToOUString(OString(text), RTL_TEXTENCODING_ISO_8859_1));
2492755751fSHerbert Dürr // use 8859-1 to avoid conversion failure
2502755751fSHerbert Dürr }
2512755751fSHerbert Dürr }
2522755751fSHerbert Dürr
2532755751fSHerbert Dürr }
2542755751fSHerbert 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)2552755751fSHerbert Dürr static void cpp_call(
2562755751fSHerbert Dürr bridges::cpp_uno::shared::UnoInterfaceProxy * pThis,
2572755751fSHerbert Dürr bridges::cpp_uno::shared::VtableSlot aVtableSlot,
2582755751fSHerbert Dürr typelib_TypeDescriptionReference * pReturnTypeRef,
2592755751fSHerbert Dürr sal_Int32 nParams, typelib_MethodParameter * pParams,
2602755751fSHerbert Dürr void * pUnoReturn, void * pUnoArgs[], uno_Any ** ppUnoExc )
2612755751fSHerbert Dürr {
2622755751fSHerbert Dürr // Maxium space for [complex ret ptr], values | ptr ...
2632755751fSHerbert Dürr // (but will be used less - some of the values will be in pGPR and pFPR)
2642755751fSHerbert Dürr sal_uInt64 *pStack = (sal_uInt64 *)__builtin_alloca( (nParams + 3) * sizeof(sal_uInt64) );
2652755751fSHerbert Dürr sal_uInt64 *pStackStart = pStack;
2662755751fSHerbert Dürr
2672755751fSHerbert Dürr sal_uInt64 pGPR[x86_64::MAX_GPR_REGS];
2682755751fSHerbert Dürr sal_uInt32 nGPR = 0;
2692755751fSHerbert Dürr
2702755751fSHerbert Dürr double pFPR[x86_64::MAX_SSE_REGS];
2712755751fSHerbert Dürr sal_uInt32 nFPR = 0;
2722755751fSHerbert Dürr
2732755751fSHerbert Dürr // Return
2742755751fSHerbert Dürr typelib_TypeDescription * pReturnTypeDescr = 0;
2752755751fSHerbert Dürr TYPELIB_DANGER_GET( &pReturnTypeDescr, pReturnTypeRef );
2762755751fSHerbert Dürr OSL_ENSURE( pReturnTypeDescr, "### expected return type description!" );
2772755751fSHerbert Dürr
2782755751fSHerbert Dürr void * pCppReturn = 0; // if != 0 && != pUnoReturn, needs reconversion (see below)
2792755751fSHerbert Dürr
2802755751fSHerbert Dürr bool bSimpleReturn = true;
2812755751fSHerbert Dürr if ( pReturnTypeDescr )
2822755751fSHerbert Dürr {
2832755751fSHerbert Dürr if ( x86_64::return_in_hidden_param( pReturnTypeRef ) )
2842755751fSHerbert Dürr bSimpleReturn = false;
2852755751fSHerbert Dürr
2862755751fSHerbert Dürr if ( bSimpleReturn )
2872755751fSHerbert Dürr pCppReturn = pUnoReturn; // direct way for simple types
2882755751fSHerbert Dürr else
2892755751fSHerbert Dürr {
2902755751fSHerbert Dürr // complex return via ptr
2912755751fSHerbert Dürr pCppReturn = bridges::cpp_uno::shared::relatesToInterfaceType( pReturnTypeDescr )?
2922755751fSHerbert Dürr __builtin_alloca( pReturnTypeDescr->nSize ) : pUnoReturn;
2932755751fSHerbert Dürr INSERT_INT64( &pCppReturn, nGPR, pGPR, pStack );
2942755751fSHerbert Dürr }
2952755751fSHerbert Dürr }
2962755751fSHerbert Dürr
2972755751fSHerbert Dürr // Push "this" pointer
2982755751fSHerbert Dürr void * pAdjustedThisPtr = reinterpret_cast< void ** >( pThis->getCppI() ) + aVtableSlot.offset;
2992755751fSHerbert Dürr INSERT_INT64( &pAdjustedThisPtr, nGPR, pGPR, pStack );
3002755751fSHerbert Dürr
3012755751fSHerbert Dürr // Args
3022755751fSHerbert Dürr void ** pCppArgs = (void **)alloca( 3 * sizeof(void *) * nParams );
3032755751fSHerbert Dürr // Indizes of values this have to be converted (interface conversion cpp<=>uno)
3042755751fSHerbert Dürr sal_Int32 * pTempIndizes = (sal_Int32 *)(pCppArgs + nParams);
3052755751fSHerbert Dürr // Type descriptions for reconversions
3062755751fSHerbert Dürr typelib_TypeDescription ** ppTempParamTypeDescr = (typelib_TypeDescription **)(pCppArgs + (2 * nParams));
3072755751fSHerbert Dürr
3082755751fSHerbert Dürr sal_Int32 nTempIndizes = 0;
3092755751fSHerbert Dürr
3102755751fSHerbert Dürr for ( sal_Int32 nPos = 0; nPos < nParams; ++nPos )
3112755751fSHerbert Dürr {
3122755751fSHerbert Dürr const typelib_MethodParameter & rParam = pParams[nPos];
3132755751fSHerbert Dürr typelib_TypeDescription * pParamTypeDescr = 0;
3142755751fSHerbert Dürr TYPELIB_DANGER_GET( &pParamTypeDescr, rParam.pTypeRef );
3152755751fSHerbert Dürr
3162755751fSHerbert Dürr if (!rParam.bOut && bridges::cpp_uno::shared::isSimpleType( pParamTypeDescr ))
3172755751fSHerbert Dürr {
3182755751fSHerbert Dürr uno_copyAndConvertData( pCppArgs[nPos] = alloca( 8 ), pUnoArgs[nPos], pParamTypeDescr,
3192755751fSHerbert Dürr pThis->getBridge()->getUno2Cpp() );
3202755751fSHerbert Dürr
3212755751fSHerbert Dürr switch (pParamTypeDescr->eTypeClass)
3222755751fSHerbert Dürr {
3232755751fSHerbert Dürr case typelib_TypeClass_HYPER:
3242755751fSHerbert Dürr case typelib_TypeClass_UNSIGNED_HYPER:
3252755751fSHerbert Dürr INSERT_INT64( pCppArgs[nPos], nGPR, pGPR, pStack );
3262755751fSHerbert Dürr break;
3272755751fSHerbert Dürr case typelib_TypeClass_LONG:
3282755751fSHerbert Dürr case typelib_TypeClass_UNSIGNED_LONG:
3292755751fSHerbert Dürr case typelib_TypeClass_ENUM:
3302755751fSHerbert Dürr INSERT_INT32( pCppArgs[nPos], nGPR, pGPR, pStack );
3312755751fSHerbert Dürr break;
3322755751fSHerbert Dürr case typelib_TypeClass_SHORT:
3332755751fSHerbert Dürr case typelib_TypeClass_CHAR:
3342755751fSHerbert Dürr case typelib_TypeClass_UNSIGNED_SHORT:
3352755751fSHerbert Dürr INSERT_INT16( pCppArgs[nPos], nGPR, pGPR, pStack );
3362755751fSHerbert Dürr break;
3372755751fSHerbert Dürr case typelib_TypeClass_BOOLEAN:
3382755751fSHerbert Dürr case typelib_TypeClass_BYTE:
3392755751fSHerbert Dürr INSERT_INT8( pCppArgs[nPos], nGPR, pGPR, pStack );
3402755751fSHerbert Dürr break;
3412755751fSHerbert Dürr case typelib_TypeClass_FLOAT:
3422755751fSHerbert Dürr case typelib_TypeClass_DOUBLE:
3432755751fSHerbert Dürr INSERT_FLOAT_DOUBLE( pCppArgs[nPos], nFPR, pFPR, pStack );
3442755751fSHerbert Dürr break;
3452755751fSHerbert Dürr default:
3462755751fSHerbert Dürr break;
3472755751fSHerbert Dürr }
3482755751fSHerbert Dürr
3492755751fSHerbert Dürr // no longer needed
3502755751fSHerbert Dürr TYPELIB_DANGER_RELEASE( pParamTypeDescr );
3512755751fSHerbert Dürr }
3522755751fSHerbert Dürr else // ptr to complex value | ref
3532755751fSHerbert Dürr {
3542755751fSHerbert Dürr if (! rParam.bIn) // is pure out
3552755751fSHerbert Dürr {
3562755751fSHerbert Dürr // cpp out is constructed mem, uno out is not!
3572755751fSHerbert Dürr uno_constructData(
3582755751fSHerbert Dürr pCppArgs[nPos] = alloca( pParamTypeDescr->nSize ),
3592755751fSHerbert Dürr pParamTypeDescr );
3602755751fSHerbert Dürr pTempIndizes[nTempIndizes] = nPos; // default constructed for cpp call
3612755751fSHerbert Dürr // will be released at reconversion
3622755751fSHerbert Dürr ppTempParamTypeDescr[nTempIndizes++] = pParamTypeDescr;
3632755751fSHerbert Dürr }
3642755751fSHerbert Dürr // is in/inout
3652755751fSHerbert Dürr else if (bridges::cpp_uno::shared::relatesToInterfaceType( pParamTypeDescr ))
3662755751fSHerbert Dürr {
3672755751fSHerbert Dürr uno_copyAndConvertData(
3682755751fSHerbert Dürr pCppArgs[nPos] = alloca( pParamTypeDescr->nSize ),
3692755751fSHerbert Dürr pUnoArgs[nPos], pParamTypeDescr, pThis->getBridge()->getUno2Cpp() );
3702755751fSHerbert Dürr
3712755751fSHerbert Dürr pTempIndizes[nTempIndizes] = nPos; // has to be reconverted
3722755751fSHerbert Dürr // will be released at reconversion
3732755751fSHerbert Dürr ppTempParamTypeDescr[nTempIndizes++] = pParamTypeDescr;
3742755751fSHerbert Dürr }
3752755751fSHerbert Dürr else // direct way
3762755751fSHerbert Dürr {
3772755751fSHerbert Dürr pCppArgs[nPos] = pUnoArgs[nPos];
3782755751fSHerbert Dürr // no longer needed
3792755751fSHerbert Dürr TYPELIB_DANGER_RELEASE( pParamTypeDescr );
3802755751fSHerbert Dürr }
3812755751fSHerbert Dürr INSERT_INT64( &(pCppArgs[nPos]), nGPR, pGPR, pStack );
3822755751fSHerbert Dürr }
3832755751fSHerbert Dürr }
3842755751fSHerbert Dürr
3852755751fSHerbert Dürr try
3862755751fSHerbert Dürr {
3872755751fSHerbert Dürr try {
3882755751fSHerbert Dürr callVirtualMethod(
3892755751fSHerbert Dürr pAdjustedThisPtr, aVtableSlot.index,
3902755751fSHerbert Dürr pCppReturn, pReturnTypeRef, bSimpleReturn,
3912755751fSHerbert Dürr pStackStart, ( pStack - pStackStart ),
3922755751fSHerbert Dürr pGPR, nGPR,
3932755751fSHerbert Dürr pFPR, nFPR );
3942755751fSHerbert Dürr } catch (Exception &) {
3952755751fSHerbert Dürr throw;
3962755751fSHerbert Dürr } catch (std::exception & e) {
3972755751fSHerbert Dürr OUStringBuffer buf;
3982755751fSHerbert Dürr buf.appendAscii(RTL_CONSTASCII_STRINGPARAM("C++ code threw "));
3992755751fSHerbert Dürr appendCString(buf, typeid(e).name());
4002755751fSHerbert Dürr buf.appendAscii(RTL_CONSTASCII_STRINGPARAM(": "));
4012755751fSHerbert Dürr appendCString(buf, e.what());
4022755751fSHerbert Dürr throw RuntimeException(
4032755751fSHerbert Dürr buf.makeStringAndClear(), Reference< XInterface >());
4042755751fSHerbert Dürr } catch (...) {
4052755751fSHerbert Dürr throw RuntimeException(
4062755751fSHerbert Dürr OUString(
4072755751fSHerbert Dürr RTL_CONSTASCII_USTRINGPARAM(
4082755751fSHerbert Dürr "C++ code threw unknown exception")),
4092755751fSHerbert Dürr Reference< XInterface >());
4102755751fSHerbert Dürr }
4112755751fSHerbert Dürr
412*67a794bcSJim Jagielski // NO exception occurred...
4132755751fSHerbert Dürr *ppUnoExc = 0;
4142755751fSHerbert Dürr
4152755751fSHerbert Dürr // reconvert temporary params
4162755751fSHerbert Dürr for ( ; nTempIndizes--; )
4172755751fSHerbert Dürr {
4182755751fSHerbert Dürr sal_Int32 nIndex = pTempIndizes[nTempIndizes];
4192755751fSHerbert Dürr typelib_TypeDescription * pParamTypeDescr = ppTempParamTypeDescr[nTempIndizes];
4202755751fSHerbert Dürr
4212755751fSHerbert Dürr if (pParams[nIndex].bIn)
4222755751fSHerbert Dürr {
4232755751fSHerbert Dürr if (pParams[nIndex].bOut) // inout
4242755751fSHerbert Dürr {
4252755751fSHerbert Dürr uno_destructData( pUnoArgs[nIndex], pParamTypeDescr, 0 ); // destroy uno value
4262755751fSHerbert Dürr uno_copyAndConvertData( pUnoArgs[nIndex], pCppArgs[nIndex], pParamTypeDescr,
4272755751fSHerbert Dürr pThis->getBridge()->getCpp2Uno() );
4282755751fSHerbert Dürr }
4292755751fSHerbert Dürr }
4302755751fSHerbert Dürr else // pure out
4312755751fSHerbert Dürr {
4322755751fSHerbert Dürr uno_copyAndConvertData( pUnoArgs[nIndex], pCppArgs[nIndex], pParamTypeDescr,
4332755751fSHerbert Dürr pThis->getBridge()->getCpp2Uno() );
4342755751fSHerbert Dürr }
4352755751fSHerbert Dürr // destroy temp cpp param => cpp: every param was constructed
4362755751fSHerbert Dürr uno_destructData( pCppArgs[nIndex], pParamTypeDescr, cpp_release );
4372755751fSHerbert Dürr
4382755751fSHerbert Dürr TYPELIB_DANGER_RELEASE( pParamTypeDescr );
4392755751fSHerbert Dürr }
4402755751fSHerbert Dürr // return value
4412755751fSHerbert Dürr if (pCppReturn && pUnoReturn != pCppReturn)
4422755751fSHerbert Dürr {
4432755751fSHerbert Dürr uno_copyAndConvertData( pUnoReturn, pCppReturn, pReturnTypeDescr,
4442755751fSHerbert Dürr pThis->getBridge()->getCpp2Uno() );
4452755751fSHerbert Dürr uno_destructData( pCppReturn, pReturnTypeDescr, cpp_release );
4462755751fSHerbert Dürr }
4472755751fSHerbert Dürr }
4482755751fSHerbert Dürr catch (...)
4492755751fSHerbert Dürr {
4502755751fSHerbert Dürr // fill uno exception
4512755751fSHerbert Dürr fillUnoException( CPPU_CURRENT_NAMESPACE::__cxa_get_globals()->caughtExceptions, *ppUnoExc, pThis->getBridge()->getCpp2Uno() );
4522755751fSHerbert Dürr
4532755751fSHerbert Dürr // temporary params
4542755751fSHerbert Dürr for ( ; nTempIndizes--; )
4552755751fSHerbert Dürr {
4562755751fSHerbert Dürr sal_Int32 nIndex = pTempIndizes[nTempIndizes];
4572755751fSHerbert Dürr // destroy temp cpp param => cpp: every param was constructed
4582755751fSHerbert Dürr uno_destructData( pCppArgs[nIndex], ppTempParamTypeDescr[nTempIndizes], cpp_release );
4592755751fSHerbert Dürr TYPELIB_DANGER_RELEASE( ppTempParamTypeDescr[nTempIndizes] );
4602755751fSHerbert Dürr }
4612755751fSHerbert Dürr // return type
4622755751fSHerbert Dürr if (pReturnTypeDescr)
4632755751fSHerbert Dürr TYPELIB_DANGER_RELEASE( pReturnTypeDescr );
4642755751fSHerbert Dürr }
4652755751fSHerbert Dürr }
4662755751fSHerbert Dürr
4672755751fSHerbert Dürr //==================================================================================================
4682755751fSHerbert Dürr
4692755751fSHerbert Dürr namespace bridges { namespace cpp_uno { namespace shared {
4702755751fSHerbert Dürr
unoInterfaceProxyDispatch(uno_Interface * pUnoI,const typelib_TypeDescription * pMemberDescr,void * pReturn,void * pArgs[],uno_Any ** ppException)4712755751fSHerbert Dürr void unoInterfaceProxyDispatch(
4722755751fSHerbert Dürr uno_Interface * pUnoI, const typelib_TypeDescription * pMemberDescr,
4732755751fSHerbert Dürr void * pReturn, void * pArgs[], uno_Any ** ppException )
4742755751fSHerbert Dürr {
4752755751fSHerbert Dürr // is my surrogate
4762755751fSHerbert Dürr bridges::cpp_uno::shared::UnoInterfaceProxy * pThis
4772755751fSHerbert Dürr = static_cast< bridges::cpp_uno::shared::UnoInterfaceProxy * >(pUnoI);
4782755751fSHerbert Dürr #if OSL_DEBUG_LEVEL > 0
4792755751fSHerbert Dürr typelib_InterfaceTypeDescription * pTypeDescr = pThis->pTypeDescr;
4802755751fSHerbert Dürr #endif
4812755751fSHerbert Dürr
4822755751fSHerbert Dürr switch (pMemberDescr->eTypeClass)
4832755751fSHerbert Dürr {
4842755751fSHerbert Dürr case typelib_TypeClass_INTERFACE_ATTRIBUTE:
4852755751fSHerbert Dürr {
4862755751fSHerbert Dürr #if OSL_DEBUG_LEVEL > 0
4872755751fSHerbert Dürr // determine vtable call index
4882755751fSHerbert Dürr sal_Int32 nMemberPos = ((typelib_InterfaceMemberTypeDescription *)pMemberDescr)->nPosition;
4892755751fSHerbert Dürr OSL_ENSURE( nMemberPos < pTypeDescr->nAllMembers, "### member pos out of range!" );
4902755751fSHerbert Dürr #endif
4912755751fSHerbert Dürr VtableSlot aVtableSlot(
4922755751fSHerbert Dürr getVtableSlot(
4932755751fSHerbert Dürr reinterpret_cast<
4942755751fSHerbert Dürr typelib_InterfaceAttributeTypeDescription const * >(
4952755751fSHerbert Dürr pMemberDescr)));
4962755751fSHerbert Dürr
4972755751fSHerbert Dürr if (pReturn)
4982755751fSHerbert Dürr {
4992755751fSHerbert Dürr // dependent dispatch
5002755751fSHerbert Dürr cpp_call(
5012755751fSHerbert Dürr pThis, aVtableSlot,
5022755751fSHerbert Dürr ((typelib_InterfaceAttributeTypeDescription *)pMemberDescr)->pAttributeTypeRef,
5032755751fSHerbert Dürr 0, 0, // no params
5042755751fSHerbert Dürr pReturn, pArgs, ppException );
5052755751fSHerbert Dürr }
5062755751fSHerbert Dürr else
5072755751fSHerbert Dürr {
5082755751fSHerbert Dürr // is SET
5092755751fSHerbert Dürr typelib_MethodParameter aParam;
5102755751fSHerbert Dürr aParam.pTypeRef =
5112755751fSHerbert Dürr ((typelib_InterfaceAttributeTypeDescription *)pMemberDescr)->pAttributeTypeRef;
5122755751fSHerbert Dürr aParam.bIn = sal_True;
5132755751fSHerbert Dürr aParam.bOut = sal_False;
5142755751fSHerbert Dürr
5152755751fSHerbert Dürr typelib_TypeDescriptionReference * pReturnTypeRef = 0;
5162755751fSHerbert Dürr OUString aVoidName( RTL_CONSTASCII_USTRINGPARAM("void") );
5172755751fSHerbert Dürr typelib_typedescriptionreference_new(
5182755751fSHerbert Dürr &pReturnTypeRef, typelib_TypeClass_VOID, aVoidName.pData );
5192755751fSHerbert Dürr
5202755751fSHerbert Dürr // dependent dispatch
5212755751fSHerbert Dürr aVtableSlot.index += 1; // get, then set method
5222755751fSHerbert Dürr cpp_call(
5232755751fSHerbert Dürr pThis, aVtableSlot, // get, then set method
5242755751fSHerbert Dürr pReturnTypeRef,
5252755751fSHerbert Dürr 1, &aParam,
5262755751fSHerbert Dürr pReturn, pArgs, ppException );
5272755751fSHerbert Dürr
5282755751fSHerbert Dürr typelib_typedescriptionreference_release( pReturnTypeRef );
5292755751fSHerbert Dürr }
5302755751fSHerbert Dürr
5312755751fSHerbert Dürr break;
5322755751fSHerbert Dürr }
5332755751fSHerbert Dürr case typelib_TypeClass_INTERFACE_METHOD:
5342755751fSHerbert Dürr {
5352755751fSHerbert Dürr #if OSL_DEBUG_LEVEL > 0
5362755751fSHerbert Dürr // determine vtable call index
5372755751fSHerbert Dürr sal_Int32 nMemberPos = ((typelib_InterfaceMemberTypeDescription *)pMemberDescr)->nPosition;
5382755751fSHerbert Dürr OSL_ENSURE( nMemberPos < pTypeDescr->nAllMembers, "### member pos out of range!" );
5392755751fSHerbert Dürr #endif
5402755751fSHerbert Dürr VtableSlot aVtableSlot(
5412755751fSHerbert Dürr getVtableSlot(
5422755751fSHerbert Dürr reinterpret_cast<
5432755751fSHerbert Dürr typelib_InterfaceMethodTypeDescription const * >(
5442755751fSHerbert Dürr pMemberDescr)));
5452755751fSHerbert Dürr
5462755751fSHerbert Dürr switch (aVtableSlot.index)
5472755751fSHerbert Dürr {
5482755751fSHerbert Dürr // standard calls
5492755751fSHerbert Dürr case 1: // acquire uno interface
5502755751fSHerbert Dürr (*pUnoI->acquire)( pUnoI );
5512755751fSHerbert Dürr *ppException = 0;
5522755751fSHerbert Dürr break;
5532755751fSHerbert Dürr case 2: // release uno interface
5542755751fSHerbert Dürr (*pUnoI->release)( pUnoI );
5552755751fSHerbert Dürr *ppException = 0;
5562755751fSHerbert Dürr break;
5572755751fSHerbert Dürr case 0: // queryInterface() opt
5582755751fSHerbert Dürr {
5592755751fSHerbert Dürr typelib_TypeDescription * pTD = 0;
5602755751fSHerbert Dürr TYPELIB_DANGER_GET( &pTD, reinterpret_cast< Type * >( pArgs[0] )->getTypeLibType() );
5612755751fSHerbert Dürr if (pTD)
5622755751fSHerbert Dürr {
5632755751fSHerbert Dürr uno_Interface * pInterface = 0;
5642755751fSHerbert Dürr (*pThis->getBridge()->getUnoEnv()->getRegisteredInterface)(
5652755751fSHerbert Dürr pThis->getBridge()->getUnoEnv(),
5662755751fSHerbert Dürr (void **)&pInterface, pThis->oid.pData, (typelib_InterfaceTypeDescription *)pTD );
5672755751fSHerbert Dürr
5682755751fSHerbert Dürr if (pInterface)
5692755751fSHerbert Dürr {
5702755751fSHerbert Dürr ::uno_any_construct(
5712755751fSHerbert Dürr reinterpret_cast< uno_Any * >( pReturn ),
5722755751fSHerbert Dürr &pInterface, pTD, 0 );
5732755751fSHerbert Dürr (*pInterface->release)( pInterface );
5742755751fSHerbert Dürr TYPELIB_DANGER_RELEASE( pTD );
5752755751fSHerbert Dürr *ppException = 0;
5762755751fSHerbert Dürr break;
5772755751fSHerbert Dürr }
5782755751fSHerbert Dürr TYPELIB_DANGER_RELEASE( pTD );
5792755751fSHerbert Dürr }
5802755751fSHerbert Dürr } // else perform queryInterface()
5812755751fSHerbert Dürr default:
5822755751fSHerbert Dürr // dependent dispatch
5832755751fSHerbert Dürr cpp_call(
5842755751fSHerbert Dürr pThis, aVtableSlot,
5852755751fSHerbert Dürr ((typelib_InterfaceMethodTypeDescription *)pMemberDescr)->pReturnTypeRef,
5862755751fSHerbert Dürr ((typelib_InterfaceMethodTypeDescription *)pMemberDescr)->nParams,
5872755751fSHerbert Dürr ((typelib_InterfaceMethodTypeDescription *)pMemberDescr)->pParams,
5882755751fSHerbert Dürr pReturn, pArgs, ppException );
5892755751fSHerbert Dürr }
5902755751fSHerbert Dürr break;
5912755751fSHerbert Dürr }
5922755751fSHerbert Dürr default:
5932755751fSHerbert Dürr {
5942755751fSHerbert Dürr ::com::sun::star::uno::RuntimeException aExc(
5952755751fSHerbert Dürr OUString( RTL_CONSTASCII_USTRINGPARAM("illegal member type description!") ),
5962755751fSHerbert Dürr ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >() );
5972755751fSHerbert Dürr
5982755751fSHerbert Dürr Type const & rExcType = ::getCppuType( &aExc );
5992755751fSHerbert Dürr // binary identical null reference
6002755751fSHerbert Dürr ::uno_type_any_construct( *ppException, &aExc, rExcType.getTypeLibType(), 0 );
6012755751fSHerbert Dürr }
6022755751fSHerbert Dürr }
6032755751fSHerbert Dürr }
6042755751fSHerbert Dürr
6052755751fSHerbert Dürr } } }
606