1*cdf0e10cSrcweir /************************************************************************* 2*cdf0e10cSrcweir * 3*cdf0e10cSrcweir * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4*cdf0e10cSrcweir * 5*cdf0e10cSrcweir * Copyright 2000, 2010 Oracle and/or its affiliates. 6*cdf0e10cSrcweir * 7*cdf0e10cSrcweir * OpenOffice.org - a multi-platform office productivity suite 8*cdf0e10cSrcweir * 9*cdf0e10cSrcweir * This file is part of OpenOffice.org. 10*cdf0e10cSrcweir * 11*cdf0e10cSrcweir * OpenOffice.org is free software: you can redistribute it and/or modify 12*cdf0e10cSrcweir * it under the terms of the GNU Lesser General Public License version 3 13*cdf0e10cSrcweir * only, as published by the Free Software Foundation. 14*cdf0e10cSrcweir * 15*cdf0e10cSrcweir * OpenOffice.org is distributed in the hope that it will be useful, 16*cdf0e10cSrcweir * but WITHOUT ANY WARRANTY; without even the implied warranty of 17*cdf0e10cSrcweir * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18*cdf0e10cSrcweir * GNU Lesser General Public License version 3 for more details 19*cdf0e10cSrcweir * (a copy is included in the LICENSE file that accompanied this code). 20*cdf0e10cSrcweir * 21*cdf0e10cSrcweir * You should have received a copy of the GNU Lesser General Public License 22*cdf0e10cSrcweir * version 3 along with OpenOffice.org. If not, see 23*cdf0e10cSrcweir * <http://www.openoffice.org/license.html> 24*cdf0e10cSrcweir * for a copy of the LGPLv3 License. 25*cdf0e10cSrcweir * 26*cdf0e10cSrcweir ************************************************************************/ 27*cdf0e10cSrcweir 28*cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove 29*cdf0e10cSrcweir #include "precompiled_bridges.hxx" 30*cdf0e10cSrcweir 31*cdf0e10cSrcweir #include <com/sun/star/uno/genfunc.hxx> 32*cdf0e10cSrcweir #include "com/sun/star/uno/RuntimeException.hpp" 33*cdf0e10cSrcweir #include <uno/data.h> 34*cdf0e10cSrcweir #include <sal/alloca.h> 35*cdf0e10cSrcweir 36*cdf0e10cSrcweir #include "bridges/cpp_uno/shared/bridge.hxx" 37*cdf0e10cSrcweir #include "bridges/cpp_uno/shared/types.hxx" 38*cdf0e10cSrcweir #include "bridges/cpp_uno/shared/unointerfaceproxy.hxx" 39*cdf0e10cSrcweir #include "bridges/cpp_uno/shared/vtables.hxx" 40*cdf0e10cSrcweir 41*cdf0e10cSrcweir #include "share.hxx" 42*cdf0e10cSrcweir #include "smallstruct.hxx" 43*cdf0e10cSrcweir 44*cdf0e10cSrcweir using namespace ::rtl; 45*cdf0e10cSrcweir using namespace ::com::sun::star::uno; 46*cdf0e10cSrcweir 47*cdf0e10cSrcweir namespace 48*cdf0e10cSrcweir { 49*cdf0e10cSrcweir 50*cdf0e10cSrcweir //================================================================================================== 51*cdf0e10cSrcweir // The call instruction within the asm section of callVirtualMethod may throw 52*cdf0e10cSrcweir // exceptions. So that the compiler handles this correctly, it is important 53*cdf0e10cSrcweir // that (a) callVirtualMethod might call dummy_can_throw_anything (although this 54*cdf0e10cSrcweir // never happens at runtime), which in turn can throw exceptions, and (b) 55*cdf0e10cSrcweir // callVirtualMethod is not inlined at its call site (so that any exceptions are 56*cdf0e10cSrcweir // caught which are thrown from the instruction calling callVirtualMethod): 57*cdf0e10cSrcweir void callVirtualMethod( 58*cdf0e10cSrcweir void * pAdjustedThisPtr, 59*cdf0e10cSrcweir sal_Int32 nVtableIndex, 60*cdf0e10cSrcweir void * pRegisterReturn, 61*cdf0e10cSrcweir typelib_TypeDescription const * returnType, 62*cdf0e10cSrcweir sal_Int32 * pStackLongs, 63*cdf0e10cSrcweir sal_Int32 nStackLongs ) __attribute__((noinline)); 64*cdf0e10cSrcweir 65*cdf0e10cSrcweir void callVirtualMethod( 66*cdf0e10cSrcweir void * pAdjustedThisPtr, 67*cdf0e10cSrcweir sal_Int32 nVtableIndex, 68*cdf0e10cSrcweir void * pRegisterReturn, 69*cdf0e10cSrcweir typelib_TypeDescription const * returnType, 70*cdf0e10cSrcweir sal_Int32 * pStackLongs, 71*cdf0e10cSrcweir sal_Int32 nStackLongs ) 72*cdf0e10cSrcweir { 73*cdf0e10cSrcweir // parameter list is mixed list of * and values 74*cdf0e10cSrcweir // reference parameters are pointers 75*cdf0e10cSrcweir 76*cdf0e10cSrcweir OSL_ENSURE( pStackLongs && pAdjustedThisPtr, "### null ptr!" ); 77*cdf0e10cSrcweir OSL_ENSURE( (sizeof(void *) == 4) && (sizeof(sal_Int32) == 4), "### unexpected size of int!" ); 78*cdf0e10cSrcweir OSL_ENSURE( nStackLongs && pStackLongs, "### no stack in callVirtualMethod !" ); 79*cdf0e10cSrcweir 80*cdf0e10cSrcweir // never called 81*cdf0e10cSrcweir if (! pAdjustedThisPtr) CPPU_CURRENT_NAMESPACE::dummy_can_throw_anything("xxx"); // address something 82*cdf0e10cSrcweir 83*cdf0e10cSrcweir volatile long edx = 0, eax = 0; // for register returns 84*cdf0e10cSrcweir void * stackptr; 85*cdf0e10cSrcweir asm volatile ( 86*cdf0e10cSrcweir "mov %%esp, %6\n\t" 87*cdf0e10cSrcweir // copy values 88*cdf0e10cSrcweir "mov %0, %%eax\n\t" 89*cdf0e10cSrcweir "mov %%eax, %%edx\n\t" 90*cdf0e10cSrcweir "dec %%edx\n\t" 91*cdf0e10cSrcweir "shl $2, %%edx\n\t" 92*cdf0e10cSrcweir "add %1, %%edx\n" 93*cdf0e10cSrcweir "Lcopy:\n\t" 94*cdf0e10cSrcweir "pushl 0(%%edx)\n\t" 95*cdf0e10cSrcweir "sub $4, %%edx\n\t" 96*cdf0e10cSrcweir "dec %%eax\n\t" 97*cdf0e10cSrcweir "jne Lcopy\n\t" 98*cdf0e10cSrcweir // do the actual call 99*cdf0e10cSrcweir "mov %2, %%edx\n\t" 100*cdf0e10cSrcweir "mov 0(%%edx), %%edx\n\t" 101*cdf0e10cSrcweir "mov %3, %%eax\n\t" 102*cdf0e10cSrcweir "shl $2, %%eax\n\t" 103*cdf0e10cSrcweir "add %%eax, %%edx\n\t" 104*cdf0e10cSrcweir "mov 0(%%edx), %%edx\n\t" 105*cdf0e10cSrcweir "call *%%edx\n\t" 106*cdf0e10cSrcweir // save return registers 107*cdf0e10cSrcweir "mov %%eax, %4\n\t" 108*cdf0e10cSrcweir "mov %%edx, %5\n\t" 109*cdf0e10cSrcweir // cleanup stack 110*cdf0e10cSrcweir "mov %6, %%esp\n\t" 111*cdf0e10cSrcweir : 112*cdf0e10cSrcweir : "m"(nStackLongs), "m"(pStackLongs), "m"(pAdjustedThisPtr), 113*cdf0e10cSrcweir "m"(nVtableIndex), "m"(eax), "m"(edx), "m"(stackptr) 114*cdf0e10cSrcweir : "eax", "edx" ); 115*cdf0e10cSrcweir switch( returnType->eTypeClass ) 116*cdf0e10cSrcweir { 117*cdf0e10cSrcweir case typelib_TypeClass_VOID: 118*cdf0e10cSrcweir break; 119*cdf0e10cSrcweir case typelib_TypeClass_HYPER: 120*cdf0e10cSrcweir case typelib_TypeClass_UNSIGNED_HYPER: 121*cdf0e10cSrcweir ((long*)pRegisterReturn)[1] = edx; 122*cdf0e10cSrcweir case typelib_TypeClass_LONG: 123*cdf0e10cSrcweir case typelib_TypeClass_UNSIGNED_LONG: 124*cdf0e10cSrcweir case typelib_TypeClass_CHAR: 125*cdf0e10cSrcweir case typelib_TypeClass_ENUM: 126*cdf0e10cSrcweir ((long*)pRegisterReturn)[0] = eax; 127*cdf0e10cSrcweir break; 128*cdf0e10cSrcweir case typelib_TypeClass_SHORT: 129*cdf0e10cSrcweir case typelib_TypeClass_UNSIGNED_SHORT: 130*cdf0e10cSrcweir *(unsigned short*)pRegisterReturn = eax; 131*cdf0e10cSrcweir break; 132*cdf0e10cSrcweir case typelib_TypeClass_BOOLEAN: 133*cdf0e10cSrcweir case typelib_TypeClass_BYTE: 134*cdf0e10cSrcweir *(unsigned char*)pRegisterReturn = eax; 135*cdf0e10cSrcweir break; 136*cdf0e10cSrcweir case typelib_TypeClass_FLOAT: 137*cdf0e10cSrcweir asm ( "fstps %0" : : "m"(*(char *)pRegisterReturn) ); 138*cdf0e10cSrcweir break; 139*cdf0e10cSrcweir case typelib_TypeClass_DOUBLE: 140*cdf0e10cSrcweir asm ( "fstpl %0\n\t" : : "m"(*(char *)pRegisterReturn) ); 141*cdf0e10cSrcweir break; 142*cdf0e10cSrcweir case typelib_TypeClass_STRUCT: 143*cdf0e10cSrcweir if (bridges::cpp_uno::shared::isSmallStruct(returnType)) { 144*cdf0e10cSrcweir if (returnType->nSize <= 1) { 145*cdf0e10cSrcweir *(unsigned char*)pRegisterReturn = eax; 146*cdf0e10cSrcweir } 147*cdf0e10cSrcweir else if (returnType->nSize <= 2) { 148*cdf0e10cSrcweir *(unsigned short*)pRegisterReturn = eax; 149*cdf0e10cSrcweir } 150*cdf0e10cSrcweir else if (returnType->nSize <= 8) { 151*cdf0e10cSrcweir ((long*)pRegisterReturn)[0] = eax; 152*cdf0e10cSrcweir if (returnType->nSize > 4) { 153*cdf0e10cSrcweir ((long*)pRegisterReturn)[1] = edx; 154*cdf0e10cSrcweir } 155*cdf0e10cSrcweir } 156*cdf0e10cSrcweir } 157*cdf0e10cSrcweir break; 158*cdf0e10cSrcweir default: 159*cdf0e10cSrcweir break; 160*cdf0e10cSrcweir } 161*cdf0e10cSrcweir } 162*cdf0e10cSrcweir 163*cdf0e10cSrcweir //================================================================================================== 164*cdf0e10cSrcweir static void cpp_call( 165*cdf0e10cSrcweir bridges::cpp_uno::shared::UnoInterfaceProxy * pThis, 166*cdf0e10cSrcweir bridges::cpp_uno::shared::VtableSlot aVtableSlot, 167*cdf0e10cSrcweir typelib_TypeDescriptionReference * pReturnTypeRef, 168*cdf0e10cSrcweir sal_Int32 nParams, typelib_MethodParameter * pParams, 169*cdf0e10cSrcweir void * pUnoReturn, void * pUnoArgs[], uno_Any ** ppUnoExc ) 170*cdf0e10cSrcweir { 171*cdf0e10cSrcweir // max space for: [complex ret ptr], values|ptr ... 172*cdf0e10cSrcweir char * pCppStack = 173*cdf0e10cSrcweir #ifdef BROKEN_ALLOCA 174*cdf0e10cSrcweir (char *)malloc( sizeof(sal_Int32) + ((nParams+2) * sizeof(sal_Int64)) ); 175*cdf0e10cSrcweir #else 176*cdf0e10cSrcweir (char *)alloca( sizeof(sal_Int32) + ((nParams+2) * sizeof(sal_Int64)) ); 177*cdf0e10cSrcweir #endif 178*cdf0e10cSrcweir char * pCppStackStart = pCppStack; 179*cdf0e10cSrcweir 180*cdf0e10cSrcweir // return 181*cdf0e10cSrcweir typelib_TypeDescription * pReturnTypeDescr = 0; 182*cdf0e10cSrcweir TYPELIB_DANGER_GET( &pReturnTypeDescr, pReturnTypeRef ); 183*cdf0e10cSrcweir OSL_ENSURE( pReturnTypeDescr, "### expected return type description!" ); 184*cdf0e10cSrcweir 185*cdf0e10cSrcweir void * pCppReturn = 0; // if != 0 && != pUnoReturn, needs reconversion 186*cdf0e10cSrcweir 187*cdf0e10cSrcweir if (pReturnTypeDescr) 188*cdf0e10cSrcweir { 189*cdf0e10cSrcweir if (bridges::cpp_uno::shared::isSimpleType( pReturnTypeDescr )) 190*cdf0e10cSrcweir { 191*cdf0e10cSrcweir pCppReturn = pUnoReturn; // direct way for simple types 192*cdf0e10cSrcweir } 193*cdf0e10cSrcweir else 194*cdf0e10cSrcweir { 195*cdf0e10cSrcweir // complex return via ptr 196*cdf0e10cSrcweir pCppReturn 197*cdf0e10cSrcweir = (bridges::cpp_uno::shared::relatesToInterfaceType( 198*cdf0e10cSrcweir pReturnTypeDescr ) 199*cdf0e10cSrcweir #ifdef BROKEN_ALLOCA 200*cdf0e10cSrcweir ? malloc( pReturnTypeDescr->nSize ) 201*cdf0e10cSrcweir #else 202*cdf0e10cSrcweir ? alloca( pReturnTypeDescr->nSize ) 203*cdf0e10cSrcweir #endif 204*cdf0e10cSrcweir : pUnoReturn); // direct way 205*cdf0e10cSrcweir if (!bridges::cpp_uno::shared::isSmallStruct(pReturnTypeDescr)) { 206*cdf0e10cSrcweir *(void **)pCppStack = pCppReturn; 207*cdf0e10cSrcweir pCppStack += sizeof(void *); 208*cdf0e10cSrcweir } 209*cdf0e10cSrcweir } 210*cdf0e10cSrcweir } 211*cdf0e10cSrcweir // push this 212*cdf0e10cSrcweir void * pAdjustedThisPtr = reinterpret_cast< void ** >(pThis->getCppI()) 213*cdf0e10cSrcweir + aVtableSlot.offset; 214*cdf0e10cSrcweir *(void**)pCppStack = pAdjustedThisPtr; 215*cdf0e10cSrcweir pCppStack += sizeof( void* ); 216*cdf0e10cSrcweir 217*cdf0e10cSrcweir // stack space 218*cdf0e10cSrcweir OSL_ENSURE( sizeof(void *) == sizeof(sal_Int32), "### unexpected size!" ); 219*cdf0e10cSrcweir // args 220*cdf0e10cSrcweir #ifdef BROKEN_ALLOCA 221*cdf0e10cSrcweir void ** pCppArgs = (void **)malloc( 3 * sizeof(void *) * nParams ); 222*cdf0e10cSrcweir #else 223*cdf0e10cSrcweir void ** pCppArgs = (void **)alloca( 3 * sizeof(void *) * nParams ); 224*cdf0e10cSrcweir #endif 225*cdf0e10cSrcweir // indizes of values this have to be converted (interface conversion cpp<=>uno) 226*cdf0e10cSrcweir sal_Int32 * pTempIndizes = (sal_Int32 *)(pCppArgs + nParams); 227*cdf0e10cSrcweir // type descriptions for reconversions 228*cdf0e10cSrcweir typelib_TypeDescription ** ppTempParamTypeDescr = (typelib_TypeDescription **)(pCppArgs + (2 * nParams)); 229*cdf0e10cSrcweir 230*cdf0e10cSrcweir sal_Int32 nTempIndizes = 0; 231*cdf0e10cSrcweir 232*cdf0e10cSrcweir for ( sal_Int32 nPos = 0; nPos < nParams; ++nPos ) 233*cdf0e10cSrcweir { 234*cdf0e10cSrcweir const typelib_MethodParameter & rParam = pParams[nPos]; 235*cdf0e10cSrcweir typelib_TypeDescription * pParamTypeDescr = 0; 236*cdf0e10cSrcweir TYPELIB_DANGER_GET( &pParamTypeDescr, rParam.pTypeRef ); 237*cdf0e10cSrcweir 238*cdf0e10cSrcweir if (!rParam.bOut 239*cdf0e10cSrcweir && bridges::cpp_uno::shared::isSimpleType( pParamTypeDescr )) 240*cdf0e10cSrcweir { 241*cdf0e10cSrcweir uno_copyAndConvertData( pCppArgs[nPos] = pCppStack, pUnoArgs[nPos], pParamTypeDescr, 242*cdf0e10cSrcweir pThis->getBridge()->getUno2Cpp() ); 243*cdf0e10cSrcweir 244*cdf0e10cSrcweir switch (pParamTypeDescr->eTypeClass) 245*cdf0e10cSrcweir { 246*cdf0e10cSrcweir case typelib_TypeClass_HYPER: 247*cdf0e10cSrcweir case typelib_TypeClass_UNSIGNED_HYPER: 248*cdf0e10cSrcweir case typelib_TypeClass_DOUBLE: 249*cdf0e10cSrcweir pCppStack += sizeof(sal_Int32); // extra long 250*cdf0e10cSrcweir break; 251*cdf0e10cSrcweir default: 252*cdf0e10cSrcweir break; 253*cdf0e10cSrcweir } 254*cdf0e10cSrcweir // no longer needed 255*cdf0e10cSrcweir TYPELIB_DANGER_RELEASE( pParamTypeDescr ); 256*cdf0e10cSrcweir } 257*cdf0e10cSrcweir else // ptr to complex value | ref 258*cdf0e10cSrcweir { 259*cdf0e10cSrcweir if (! rParam.bIn) // is pure out 260*cdf0e10cSrcweir { 261*cdf0e10cSrcweir // cpp out is constructed mem, uno out is not! 262*cdf0e10cSrcweir uno_constructData( 263*cdf0e10cSrcweir #ifdef BROKEN_ALLOCA 264*cdf0e10cSrcweir *(void **)pCppStack = pCppArgs[nPos] = malloc( pParamTypeDescr->nSize ), 265*cdf0e10cSrcweir #else 266*cdf0e10cSrcweir *(void **)pCppStack = pCppArgs[nPos] = alloca( pParamTypeDescr->nSize ), 267*cdf0e10cSrcweir #endif 268*cdf0e10cSrcweir pParamTypeDescr ); 269*cdf0e10cSrcweir pTempIndizes[nTempIndizes] = nPos; // default constructed for cpp call 270*cdf0e10cSrcweir // will be released at reconversion 271*cdf0e10cSrcweir ppTempParamTypeDescr[nTempIndizes++] = pParamTypeDescr; 272*cdf0e10cSrcweir } 273*cdf0e10cSrcweir // is in/inout 274*cdf0e10cSrcweir else if (bridges::cpp_uno::shared::relatesToInterfaceType( 275*cdf0e10cSrcweir pParamTypeDescr )) 276*cdf0e10cSrcweir { 277*cdf0e10cSrcweir uno_copyAndConvertData( 278*cdf0e10cSrcweir #ifdef BROKEN_ALLOCA 279*cdf0e10cSrcweir *(void **)pCppStack = pCppArgs[nPos] = malloc( pParamTypeDescr->nSize ), 280*cdf0e10cSrcweir #else 281*cdf0e10cSrcweir *(void **)pCppStack = pCppArgs[nPos] = alloca( pParamTypeDescr->nSize ), 282*cdf0e10cSrcweir #endif 283*cdf0e10cSrcweir pUnoArgs[nPos], pParamTypeDescr, 284*cdf0e10cSrcweir pThis->getBridge()->getUno2Cpp() ); 285*cdf0e10cSrcweir 286*cdf0e10cSrcweir pTempIndizes[nTempIndizes] = nPos; // has to be reconverted 287*cdf0e10cSrcweir // will be released at reconversion 288*cdf0e10cSrcweir ppTempParamTypeDescr[nTempIndizes++] = pParamTypeDescr; 289*cdf0e10cSrcweir } 290*cdf0e10cSrcweir else // direct way 291*cdf0e10cSrcweir { 292*cdf0e10cSrcweir *(void **)pCppStack = pCppArgs[nPos] = pUnoArgs[nPos]; 293*cdf0e10cSrcweir // no longer needed 294*cdf0e10cSrcweir TYPELIB_DANGER_RELEASE( pParamTypeDescr ); 295*cdf0e10cSrcweir } 296*cdf0e10cSrcweir } 297*cdf0e10cSrcweir pCppStack += sizeof(sal_Int32); // standard parameter length 298*cdf0e10cSrcweir } 299*cdf0e10cSrcweir 300*cdf0e10cSrcweir try 301*cdf0e10cSrcweir { 302*cdf0e10cSrcweir OSL_ENSURE( !( (pCppStack - pCppStackStart ) & 3), "UNALIGNED STACK !!! (Please DO panic)" ); 303*cdf0e10cSrcweir callVirtualMethod( 304*cdf0e10cSrcweir pAdjustedThisPtr, aVtableSlot.index, 305*cdf0e10cSrcweir pCppReturn, pReturnTypeDescr, 306*cdf0e10cSrcweir (sal_Int32 *)pCppStackStart, (pCppStack - pCppStackStart) / sizeof(sal_Int32) ); 307*cdf0e10cSrcweir // NO exception occured... 308*cdf0e10cSrcweir *ppUnoExc = 0; 309*cdf0e10cSrcweir 310*cdf0e10cSrcweir // reconvert temporary params 311*cdf0e10cSrcweir for ( ; nTempIndizes--; ) 312*cdf0e10cSrcweir { 313*cdf0e10cSrcweir sal_Int32 nIndex = pTempIndizes[nTempIndizes]; 314*cdf0e10cSrcweir typelib_TypeDescription * pParamTypeDescr = ppTempParamTypeDescr[nTempIndizes]; 315*cdf0e10cSrcweir 316*cdf0e10cSrcweir if (pParams[nIndex].bIn) 317*cdf0e10cSrcweir { 318*cdf0e10cSrcweir if (pParams[nIndex].bOut) // inout 319*cdf0e10cSrcweir { 320*cdf0e10cSrcweir uno_destructData( pUnoArgs[nIndex], pParamTypeDescr, 0 ); // destroy uno value 321*cdf0e10cSrcweir uno_copyAndConvertData( pUnoArgs[nIndex], pCppArgs[nIndex], pParamTypeDescr, 322*cdf0e10cSrcweir pThis->getBridge()->getCpp2Uno() ); 323*cdf0e10cSrcweir } 324*cdf0e10cSrcweir } 325*cdf0e10cSrcweir else // pure out 326*cdf0e10cSrcweir { 327*cdf0e10cSrcweir uno_copyAndConvertData( pUnoArgs[nIndex], pCppArgs[nIndex], pParamTypeDescr, 328*cdf0e10cSrcweir pThis->getBridge()->getCpp2Uno() ); 329*cdf0e10cSrcweir } 330*cdf0e10cSrcweir // destroy temp cpp param => cpp: every param was constructed 331*cdf0e10cSrcweir uno_destructData( pCppArgs[nIndex], pParamTypeDescr, cpp_release ); 332*cdf0e10cSrcweir #ifdef BROKEN_ALLOCA 333*cdf0e10cSrcweir free( pCppArgs[nIndex] ); 334*cdf0e10cSrcweir #endif 335*cdf0e10cSrcweir 336*cdf0e10cSrcweir TYPELIB_DANGER_RELEASE( pParamTypeDescr ); 337*cdf0e10cSrcweir } 338*cdf0e10cSrcweir // return value 339*cdf0e10cSrcweir if (pCppReturn && pUnoReturn != pCppReturn) 340*cdf0e10cSrcweir { 341*cdf0e10cSrcweir uno_copyAndConvertData( pUnoReturn, pCppReturn, pReturnTypeDescr, 342*cdf0e10cSrcweir pThis->getBridge()->getCpp2Uno() ); 343*cdf0e10cSrcweir uno_destructData( pCppReturn, pReturnTypeDescr, cpp_release ); 344*cdf0e10cSrcweir } 345*cdf0e10cSrcweir } 346*cdf0e10cSrcweir catch (...) 347*cdf0e10cSrcweir { 348*cdf0e10cSrcweir // fill uno exception 349*cdf0e10cSrcweir fillUnoException( CPPU_CURRENT_NAMESPACE::__cxa_get_globals()->caughtExceptions, *ppUnoExc, pThis->getBridge()->getCpp2Uno() ); 350*cdf0e10cSrcweir 351*cdf0e10cSrcweir // temporary params 352*cdf0e10cSrcweir for ( ; nTempIndizes--; ) 353*cdf0e10cSrcweir { 354*cdf0e10cSrcweir sal_Int32 nIndex = pTempIndizes[nTempIndizes]; 355*cdf0e10cSrcweir // destroy temp cpp param => cpp: every param was constructed 356*cdf0e10cSrcweir uno_destructData( pCppArgs[nIndex], ppTempParamTypeDescr[nTempIndizes], cpp_release ); 357*cdf0e10cSrcweir TYPELIB_DANGER_RELEASE( ppTempParamTypeDescr[nTempIndizes] ); 358*cdf0e10cSrcweir #ifdef BROKEN_ALLOCA 359*cdf0e10cSrcweir free( pCppArgs[nIndex] ); 360*cdf0e10cSrcweir #endif 361*cdf0e10cSrcweir } 362*cdf0e10cSrcweir // return type 363*cdf0e10cSrcweir if (pReturnTypeDescr) 364*cdf0e10cSrcweir TYPELIB_DANGER_RELEASE( pReturnTypeDescr ); 365*cdf0e10cSrcweir } 366*cdf0e10cSrcweir if (pCppReturn && pUnoReturn != pCppReturn) 367*cdf0e10cSrcweir { 368*cdf0e10cSrcweir #ifdef BROKEN_ALLOCA 369*cdf0e10cSrcweir free( pCppReturn ); 370*cdf0e10cSrcweir #endif 371*cdf0e10cSrcweir } 372*cdf0e10cSrcweir #ifdef BROKEN_ALLOCA 373*cdf0e10cSrcweir free( pCppStackStart ); 374*cdf0e10cSrcweir #endif 375*cdf0e10cSrcweir } 376*cdf0e10cSrcweir 377*cdf0e10cSrcweir } 378*cdf0e10cSrcweir 379*cdf0e10cSrcweir namespace bridges { namespace cpp_uno { namespace shared { 380*cdf0e10cSrcweir 381*cdf0e10cSrcweir void unoInterfaceProxyDispatch( 382*cdf0e10cSrcweir uno_Interface * pUnoI, const typelib_TypeDescription * pMemberDescr, 383*cdf0e10cSrcweir void * pReturn, void * pArgs[], uno_Any ** ppException ) 384*cdf0e10cSrcweir { 385*cdf0e10cSrcweir // is my surrogate 386*cdf0e10cSrcweir bridges::cpp_uno::shared::UnoInterfaceProxy * pThis 387*cdf0e10cSrcweir = static_cast< bridges::cpp_uno::shared::UnoInterfaceProxy * >(pUnoI); 388*cdf0e10cSrcweir 389*cdf0e10cSrcweir switch (pMemberDescr->eTypeClass) 390*cdf0e10cSrcweir { 391*cdf0e10cSrcweir case typelib_TypeClass_INTERFACE_ATTRIBUTE: 392*cdf0e10cSrcweir { 393*cdf0e10cSrcweir VtableSlot aVtableSlot( 394*cdf0e10cSrcweir getVtableSlot( 395*cdf0e10cSrcweir reinterpret_cast< 396*cdf0e10cSrcweir typelib_InterfaceAttributeTypeDescription const * >( 397*cdf0e10cSrcweir pMemberDescr))); 398*cdf0e10cSrcweir if (pReturn) 399*cdf0e10cSrcweir { 400*cdf0e10cSrcweir // dependent dispatch 401*cdf0e10cSrcweir cpp_call( 402*cdf0e10cSrcweir pThis, aVtableSlot, 403*cdf0e10cSrcweir ((typelib_InterfaceAttributeTypeDescription *)pMemberDescr)->pAttributeTypeRef, 404*cdf0e10cSrcweir 0, 0, // no params 405*cdf0e10cSrcweir pReturn, pArgs, ppException ); 406*cdf0e10cSrcweir } 407*cdf0e10cSrcweir else 408*cdf0e10cSrcweir { 409*cdf0e10cSrcweir // is SET 410*cdf0e10cSrcweir typelib_MethodParameter aParam; 411*cdf0e10cSrcweir aParam.pTypeRef = 412*cdf0e10cSrcweir ((typelib_InterfaceAttributeTypeDescription *)pMemberDescr)->pAttributeTypeRef; 413*cdf0e10cSrcweir aParam.bIn = sal_True; 414*cdf0e10cSrcweir aParam.bOut = sal_False; 415*cdf0e10cSrcweir 416*cdf0e10cSrcweir typelib_TypeDescriptionReference * pReturnTypeRef = 0; 417*cdf0e10cSrcweir OUString aVoidName( RTL_CONSTASCII_USTRINGPARAM("void") ); 418*cdf0e10cSrcweir typelib_typedescriptionreference_new( 419*cdf0e10cSrcweir &pReturnTypeRef, typelib_TypeClass_VOID, aVoidName.pData ); 420*cdf0e10cSrcweir 421*cdf0e10cSrcweir // dependent dispatch 422*cdf0e10cSrcweir aVtableSlot.index += 1; // get, then set method 423*cdf0e10cSrcweir cpp_call( 424*cdf0e10cSrcweir pThis, aVtableSlot, 425*cdf0e10cSrcweir pReturnTypeRef, 426*cdf0e10cSrcweir 1, &aParam, 427*cdf0e10cSrcweir pReturn, pArgs, ppException ); 428*cdf0e10cSrcweir 429*cdf0e10cSrcweir typelib_typedescriptionreference_release( pReturnTypeRef ); 430*cdf0e10cSrcweir } 431*cdf0e10cSrcweir 432*cdf0e10cSrcweir break; 433*cdf0e10cSrcweir } 434*cdf0e10cSrcweir case typelib_TypeClass_INTERFACE_METHOD: 435*cdf0e10cSrcweir { 436*cdf0e10cSrcweir VtableSlot aVtableSlot( 437*cdf0e10cSrcweir getVtableSlot( 438*cdf0e10cSrcweir reinterpret_cast< 439*cdf0e10cSrcweir typelib_InterfaceMethodTypeDescription const * >( 440*cdf0e10cSrcweir pMemberDescr))); 441*cdf0e10cSrcweir switch (aVtableSlot.index) 442*cdf0e10cSrcweir { 443*cdf0e10cSrcweir // standard calls 444*cdf0e10cSrcweir case 1: // acquire uno interface 445*cdf0e10cSrcweir (*pUnoI->acquire)( pUnoI ); 446*cdf0e10cSrcweir *ppException = 0; 447*cdf0e10cSrcweir break; 448*cdf0e10cSrcweir case 2: // release uno interface 449*cdf0e10cSrcweir (*pUnoI->release)( pUnoI ); 450*cdf0e10cSrcweir *ppException = 0; 451*cdf0e10cSrcweir break; 452*cdf0e10cSrcweir case 0: // queryInterface() opt 453*cdf0e10cSrcweir { 454*cdf0e10cSrcweir typelib_TypeDescription * pTD = 0; 455*cdf0e10cSrcweir TYPELIB_DANGER_GET( &pTD, reinterpret_cast< Type * >( pArgs[0] )->getTypeLibType() ); 456*cdf0e10cSrcweir if (pTD) 457*cdf0e10cSrcweir { 458*cdf0e10cSrcweir uno_Interface * pInterface = 0; 459*cdf0e10cSrcweir (*pThis->pBridge->getUnoEnv()->getRegisteredInterface)( 460*cdf0e10cSrcweir pThis->pBridge->getUnoEnv(), 461*cdf0e10cSrcweir (void **)&pInterface, pThis->oid.pData, (typelib_InterfaceTypeDescription *)pTD ); 462*cdf0e10cSrcweir 463*cdf0e10cSrcweir if (pInterface) 464*cdf0e10cSrcweir { 465*cdf0e10cSrcweir ::uno_any_construct( 466*cdf0e10cSrcweir reinterpret_cast< uno_Any * >( pReturn ), 467*cdf0e10cSrcweir &pInterface, pTD, 0 ); 468*cdf0e10cSrcweir (*pInterface->release)( pInterface ); 469*cdf0e10cSrcweir TYPELIB_DANGER_RELEASE( pTD ); 470*cdf0e10cSrcweir *ppException = 0; 471*cdf0e10cSrcweir break; 472*cdf0e10cSrcweir } 473*cdf0e10cSrcweir TYPELIB_DANGER_RELEASE( pTD ); 474*cdf0e10cSrcweir } 475*cdf0e10cSrcweir } // else perform queryInterface() 476*cdf0e10cSrcweir default: 477*cdf0e10cSrcweir // dependent dispatch 478*cdf0e10cSrcweir cpp_call( 479*cdf0e10cSrcweir pThis, aVtableSlot, 480*cdf0e10cSrcweir ((typelib_InterfaceMethodTypeDescription *)pMemberDescr)->pReturnTypeRef, 481*cdf0e10cSrcweir ((typelib_InterfaceMethodTypeDescription *)pMemberDescr)->nParams, 482*cdf0e10cSrcweir ((typelib_InterfaceMethodTypeDescription *)pMemberDescr)->pParams, 483*cdf0e10cSrcweir pReturn, pArgs, ppException ); 484*cdf0e10cSrcweir } 485*cdf0e10cSrcweir break; 486*cdf0e10cSrcweir } 487*cdf0e10cSrcweir default: 488*cdf0e10cSrcweir { 489*cdf0e10cSrcweir ::com::sun::star::uno::RuntimeException aExc( 490*cdf0e10cSrcweir OUString( RTL_CONSTASCII_USTRINGPARAM("illegal member type description!") ), 491*cdf0e10cSrcweir ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >() ); 492*cdf0e10cSrcweir 493*cdf0e10cSrcweir Type const & rExcType = ::getCppuType( &aExc ); 494*cdf0e10cSrcweir // binary identical null reference 495*cdf0e10cSrcweir ::uno_type_any_construct( *ppException, &aExc, rExcType.getTypeLibType(), 0 ); 496*cdf0e10cSrcweir } 497*cdf0e10cSrcweir } 498*cdf0e10cSrcweir } 499*cdf0e10cSrcweir 500*cdf0e10cSrcweir } } } 501