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 <typelib/typedescription.hxx> 35*cdf0e10cSrcweir #include <sal/alloca.h> 36*cdf0e10cSrcweir 37*cdf0e10cSrcweir #include "bridges/cpp_uno/shared/bridge.hxx" 38*cdf0e10cSrcweir #include "bridges/cpp_uno/shared/cppinterfaceproxy.hxx" 39*cdf0e10cSrcweir #include "bridges/cpp_uno/shared/types.hxx" 40*cdf0e10cSrcweir #include "bridges/cpp_uno/shared/vtablefactory.hxx" 41*cdf0e10cSrcweir 42*cdf0e10cSrcweir #include "share.hxx" 43*cdf0e10cSrcweir #include "smallstruct.hxx" 44*cdf0e10cSrcweir 45*cdf0e10cSrcweir using namespace ::com::sun::star::uno; 46*cdf0e10cSrcweir 47*cdf0e10cSrcweir namespace 48*cdf0e10cSrcweir { 49*cdf0e10cSrcweir 50*cdf0e10cSrcweir //================================================================================================== 51*cdf0e10cSrcweir void cpp2uno_call( 52*cdf0e10cSrcweir bridges::cpp_uno::shared::CppInterfaceProxy * pThis, 53*cdf0e10cSrcweir const typelib_TypeDescription * pMemberTypeDescr, 54*cdf0e10cSrcweir typelib_TypeDescriptionReference * pReturnTypeRef, // 0 indicates void return 55*cdf0e10cSrcweir sal_Int32 nParams, typelib_MethodParameter * pParams, 56*cdf0e10cSrcweir void ** pCallStack, 57*cdf0e10cSrcweir void * pReturnValue ) 58*cdf0e10cSrcweir { 59*cdf0e10cSrcweir // pCallStack: ret, [return ptr], this, params 60*cdf0e10cSrcweir char * pCppStack = (char *)(pCallStack +1); 61*cdf0e10cSrcweir 62*cdf0e10cSrcweir // return 63*cdf0e10cSrcweir typelib_TypeDescription * pReturnTypeDescr = 0; 64*cdf0e10cSrcweir if (pReturnTypeRef) 65*cdf0e10cSrcweir TYPELIB_DANGER_GET( &pReturnTypeDescr, pReturnTypeRef ); 66*cdf0e10cSrcweir 67*cdf0e10cSrcweir void * pUnoReturn = 0; 68*cdf0e10cSrcweir void * pCppReturn = 0; // complex return ptr: if != 0 && != pUnoReturn, reconversion need 69*cdf0e10cSrcweir 70*cdf0e10cSrcweir if (pReturnTypeDescr) 71*cdf0e10cSrcweir { 72*cdf0e10cSrcweir if (bridges::cpp_uno::shared::isSimpleType( pReturnTypeDescr )) 73*cdf0e10cSrcweir { 74*cdf0e10cSrcweir pUnoReturn = pReturnValue; // direct way for simple types 75*cdf0e10cSrcweir } 76*cdf0e10cSrcweir else // complex return via ptr (pCppReturn) 77*cdf0e10cSrcweir { 78*cdf0e10cSrcweir if (!bridges::cpp_uno::shared::isSmallStruct(pReturnTypeDescr)) { 79*cdf0e10cSrcweir pCppReturn = *(void **)pCppStack; 80*cdf0e10cSrcweir pCppStack += sizeof(void *); 81*cdf0e10cSrcweir } 82*cdf0e10cSrcweir else { 83*cdf0e10cSrcweir pCppReturn = pReturnValue; 84*cdf0e10cSrcweir } 85*cdf0e10cSrcweir 86*cdf0e10cSrcweir pUnoReturn = (bridges::cpp_uno::shared::relatesToInterfaceType( 87*cdf0e10cSrcweir pReturnTypeDescr ) 88*cdf0e10cSrcweir ? alloca( pReturnTypeDescr->nSize ) 89*cdf0e10cSrcweir : pCppReturn); // direct way 90*cdf0e10cSrcweir } 91*cdf0e10cSrcweir } 92*cdf0e10cSrcweir // pop this 93*cdf0e10cSrcweir pCppStack += sizeof( void* ); 94*cdf0e10cSrcweir 95*cdf0e10cSrcweir // stack space 96*cdf0e10cSrcweir OSL_ENSURE( sizeof(void *) == sizeof(sal_Int32), "### unexpected size!" ); 97*cdf0e10cSrcweir // parameters 98*cdf0e10cSrcweir void ** pUnoArgs = (void **)alloca( 4 * sizeof(void *) * nParams ); 99*cdf0e10cSrcweir void ** pCppArgs = pUnoArgs + nParams; 100*cdf0e10cSrcweir // indizes of values this have to be converted (interface conversion cpp<=>uno) 101*cdf0e10cSrcweir sal_Int32 * pTempIndizes = (sal_Int32 *)(pUnoArgs + (2 * nParams)); 102*cdf0e10cSrcweir // type descriptions for reconversions 103*cdf0e10cSrcweir typelib_TypeDescription ** ppTempParamTypeDescr = (typelib_TypeDescription **)(pUnoArgs + (3 * nParams)); 104*cdf0e10cSrcweir 105*cdf0e10cSrcweir sal_Int32 nTempIndizes = 0; 106*cdf0e10cSrcweir 107*cdf0e10cSrcweir for ( sal_Int32 nPos = 0; nPos < nParams; ++nPos ) 108*cdf0e10cSrcweir { 109*cdf0e10cSrcweir const typelib_MethodParameter & rParam = pParams[nPos]; 110*cdf0e10cSrcweir typelib_TypeDescription * pParamTypeDescr = 0; 111*cdf0e10cSrcweir TYPELIB_DANGER_GET( &pParamTypeDescr, rParam.pTypeRef ); 112*cdf0e10cSrcweir 113*cdf0e10cSrcweir if (!rParam.bOut 114*cdf0e10cSrcweir && bridges::cpp_uno::shared::isSimpleType( pParamTypeDescr )) 115*cdf0e10cSrcweir // value 116*cdf0e10cSrcweir { 117*cdf0e10cSrcweir pCppArgs[nPos] = pCppStack; 118*cdf0e10cSrcweir pUnoArgs[nPos] = pCppStack; 119*cdf0e10cSrcweir switch (pParamTypeDescr->eTypeClass) 120*cdf0e10cSrcweir { 121*cdf0e10cSrcweir case typelib_TypeClass_HYPER: 122*cdf0e10cSrcweir case typelib_TypeClass_UNSIGNED_HYPER: 123*cdf0e10cSrcweir case typelib_TypeClass_DOUBLE: 124*cdf0e10cSrcweir pCppStack += sizeof(sal_Int32); // extra long 125*cdf0e10cSrcweir break; 126*cdf0e10cSrcweir default: 127*cdf0e10cSrcweir break; 128*cdf0e10cSrcweir } 129*cdf0e10cSrcweir // no longer needed 130*cdf0e10cSrcweir TYPELIB_DANGER_RELEASE( pParamTypeDescr ); 131*cdf0e10cSrcweir } 132*cdf0e10cSrcweir else // ptr to complex value | ref 133*cdf0e10cSrcweir { 134*cdf0e10cSrcweir pCppArgs[nPos] = *(void **)pCppStack; 135*cdf0e10cSrcweir 136*cdf0e10cSrcweir if (! rParam.bIn) // is pure out 137*cdf0e10cSrcweir { 138*cdf0e10cSrcweir // uno out is unconstructed mem! 139*cdf0e10cSrcweir pUnoArgs[nPos] = alloca( pParamTypeDescr->nSize ); 140*cdf0e10cSrcweir pTempIndizes[nTempIndizes] = nPos; 141*cdf0e10cSrcweir // will be released at reconversion 142*cdf0e10cSrcweir ppTempParamTypeDescr[nTempIndizes++] = pParamTypeDescr; 143*cdf0e10cSrcweir } 144*cdf0e10cSrcweir // is in/inout 145*cdf0e10cSrcweir else if (bridges::cpp_uno::shared::relatesToInterfaceType( 146*cdf0e10cSrcweir pParamTypeDescr )) 147*cdf0e10cSrcweir { 148*cdf0e10cSrcweir uno_copyAndConvertData( pUnoArgs[nPos] = alloca( pParamTypeDescr->nSize ), 149*cdf0e10cSrcweir *(void **)pCppStack, pParamTypeDescr, 150*cdf0e10cSrcweir pThis->getBridge()->getCpp2Uno() ); 151*cdf0e10cSrcweir pTempIndizes[nTempIndizes] = nPos; // has to be reconverted 152*cdf0e10cSrcweir // will be released at reconversion 153*cdf0e10cSrcweir ppTempParamTypeDescr[nTempIndizes++] = pParamTypeDescr; 154*cdf0e10cSrcweir } 155*cdf0e10cSrcweir else // direct way 156*cdf0e10cSrcweir { 157*cdf0e10cSrcweir pUnoArgs[nPos] = *(void **)pCppStack; 158*cdf0e10cSrcweir // no longer needed 159*cdf0e10cSrcweir TYPELIB_DANGER_RELEASE( pParamTypeDescr ); 160*cdf0e10cSrcweir } 161*cdf0e10cSrcweir } 162*cdf0e10cSrcweir pCppStack += sizeof(sal_Int32); // standard parameter length 163*cdf0e10cSrcweir } 164*cdf0e10cSrcweir 165*cdf0e10cSrcweir // ExceptionHolder 166*cdf0e10cSrcweir uno_Any aUnoExc; // Any will be constructed by callee 167*cdf0e10cSrcweir uno_Any * pUnoExc = &aUnoExc; 168*cdf0e10cSrcweir 169*cdf0e10cSrcweir // invoke uno dispatch call 170*cdf0e10cSrcweir (*pThis->getUnoI()->pDispatcher)( 171*cdf0e10cSrcweir pThis->getUnoI(), pMemberTypeDescr, pUnoReturn, pUnoArgs, &pUnoExc ); 172*cdf0e10cSrcweir 173*cdf0e10cSrcweir // in case an exception occured... 174*cdf0e10cSrcweir if (pUnoExc) 175*cdf0e10cSrcweir { 176*cdf0e10cSrcweir // destruct temporary in/inout params 177*cdf0e10cSrcweir for ( ; nTempIndizes--; ) 178*cdf0e10cSrcweir { 179*cdf0e10cSrcweir sal_Int32 nIndex = pTempIndizes[nTempIndizes]; 180*cdf0e10cSrcweir 181*cdf0e10cSrcweir if (pParams[nIndex].bIn) // is in/inout => was constructed 182*cdf0e10cSrcweir uno_destructData( pUnoArgs[nIndex], ppTempParamTypeDescr[nTempIndizes], 0 ); 183*cdf0e10cSrcweir TYPELIB_DANGER_RELEASE( ppTempParamTypeDescr[nTempIndizes] ); 184*cdf0e10cSrcweir } 185*cdf0e10cSrcweir if (pReturnTypeDescr) 186*cdf0e10cSrcweir TYPELIB_DANGER_RELEASE( pReturnTypeDescr ); 187*cdf0e10cSrcweir 188*cdf0e10cSrcweir CPPU_CURRENT_NAMESPACE::raiseException( 189*cdf0e10cSrcweir &aUnoExc, pThis->getBridge()->getUno2Cpp() ); 190*cdf0e10cSrcweir // has to destruct the any 191*cdf0e10cSrcweir } 192*cdf0e10cSrcweir else // else no exception occured... 193*cdf0e10cSrcweir { 194*cdf0e10cSrcweir // temporary params 195*cdf0e10cSrcweir for ( ; nTempIndizes--; ) 196*cdf0e10cSrcweir { 197*cdf0e10cSrcweir sal_Int32 nIndex = pTempIndizes[nTempIndizes]; 198*cdf0e10cSrcweir typelib_TypeDescription * pParamTypeDescr = ppTempParamTypeDescr[nTempIndizes]; 199*cdf0e10cSrcweir 200*cdf0e10cSrcweir if (pParams[nIndex].bOut) // inout/out 201*cdf0e10cSrcweir { 202*cdf0e10cSrcweir // convert and assign 203*cdf0e10cSrcweir uno_destructData( pCppArgs[nIndex], pParamTypeDescr, cpp_release ); 204*cdf0e10cSrcweir uno_copyAndConvertData( pCppArgs[nIndex], pUnoArgs[nIndex], pParamTypeDescr, 205*cdf0e10cSrcweir pThis->getBridge()->getUno2Cpp() ); 206*cdf0e10cSrcweir } 207*cdf0e10cSrcweir // destroy temp uno param 208*cdf0e10cSrcweir uno_destructData( pUnoArgs[nIndex], pParamTypeDescr, 0 ); 209*cdf0e10cSrcweir 210*cdf0e10cSrcweir TYPELIB_DANGER_RELEASE( pParamTypeDescr ); 211*cdf0e10cSrcweir } 212*cdf0e10cSrcweir // return 213*cdf0e10cSrcweir if (pCppReturn) // has complex return 214*cdf0e10cSrcweir { 215*cdf0e10cSrcweir if (pUnoReturn != pCppReturn) // needs reconversion 216*cdf0e10cSrcweir { 217*cdf0e10cSrcweir uno_copyAndConvertData( pCppReturn, pUnoReturn, pReturnTypeDescr, 218*cdf0e10cSrcweir pThis->getBridge()->getUno2Cpp() ); 219*cdf0e10cSrcweir // destroy temp uno return 220*cdf0e10cSrcweir uno_destructData( pUnoReturn, pReturnTypeDescr, 0 ); 221*cdf0e10cSrcweir } 222*cdf0e10cSrcweir if (pReturnValue != pCppReturn) 223*cdf0e10cSrcweir // complex return ptr is set to eax 224*cdf0e10cSrcweir *static_cast< void ** >(pReturnValue) = pCppReturn; 225*cdf0e10cSrcweir } 226*cdf0e10cSrcweir if (pReturnTypeDescr) 227*cdf0e10cSrcweir { 228*cdf0e10cSrcweir TYPELIB_DANGER_RELEASE( pReturnTypeDescr ); 229*cdf0e10cSrcweir } 230*cdf0e10cSrcweir } 231*cdf0e10cSrcweir } 232*cdf0e10cSrcweir 233*cdf0e10cSrcweir 234*cdf0e10cSrcweir //================================================================================================== 235*cdf0e10cSrcweir extern "C" void cpp_vtable_call( 236*cdf0e10cSrcweir int nFunctionIndex, int nVtableOffset, void** pCallStack, 237*cdf0e10cSrcweir void * pReturnValue ) 238*cdf0e10cSrcweir { 239*cdf0e10cSrcweir OSL_ENSURE( sizeof(sal_Int32)==sizeof(void *), "### unexpected!" ); 240*cdf0e10cSrcweir 241*cdf0e10cSrcweir // pCallStack: ret adr, [ret *], this, params 242*cdf0e10cSrcweir void * pThis; 243*cdf0e10cSrcweir if( nFunctionIndex & 0x80000000 ) 244*cdf0e10cSrcweir { 245*cdf0e10cSrcweir nFunctionIndex &= 0x7fffffff; 246*cdf0e10cSrcweir pThis = pCallStack[2]; 247*cdf0e10cSrcweir } 248*cdf0e10cSrcweir else 249*cdf0e10cSrcweir { 250*cdf0e10cSrcweir pThis = pCallStack[1]; 251*cdf0e10cSrcweir } 252*cdf0e10cSrcweir pThis = static_cast< char * >(pThis) - nVtableOffset; 253*cdf0e10cSrcweir bridges::cpp_uno::shared::CppInterfaceProxy * pCppI 254*cdf0e10cSrcweir = bridges::cpp_uno::shared::CppInterfaceProxy::castInterfaceToProxy( 255*cdf0e10cSrcweir pThis); 256*cdf0e10cSrcweir 257*cdf0e10cSrcweir typelib_InterfaceTypeDescription * pTypeDescr = pCppI->getTypeDescr(); 258*cdf0e10cSrcweir 259*cdf0e10cSrcweir OSL_ENSURE( nFunctionIndex < pTypeDescr->nMapFunctionIndexToMemberIndex, "### illegal vtable index!" ); 260*cdf0e10cSrcweir if (nFunctionIndex >= pTypeDescr->nMapFunctionIndexToMemberIndex) 261*cdf0e10cSrcweir { 262*cdf0e10cSrcweir throw RuntimeException( 263*cdf0e10cSrcweir rtl::OUString::createFromAscii("illegal vtable index!"), 264*cdf0e10cSrcweir (XInterface *)pThis ); 265*cdf0e10cSrcweir } 266*cdf0e10cSrcweir 267*cdf0e10cSrcweir // determine called method 268*cdf0e10cSrcweir sal_Int32 nMemberPos = pTypeDescr->pMapFunctionIndexToMemberIndex[nFunctionIndex]; 269*cdf0e10cSrcweir OSL_ENSURE( nMemberPos < pTypeDescr->nAllMembers, "### illegal member index!" ); 270*cdf0e10cSrcweir 271*cdf0e10cSrcweir TypeDescription aMemberDescr( pTypeDescr->ppAllMembers[nMemberPos] ); 272*cdf0e10cSrcweir 273*cdf0e10cSrcweir switch (aMemberDescr.get()->eTypeClass) 274*cdf0e10cSrcweir { 275*cdf0e10cSrcweir case typelib_TypeClass_INTERFACE_ATTRIBUTE: 276*cdf0e10cSrcweir { 277*cdf0e10cSrcweir if (pTypeDescr->pMapMemberIndexToFunctionIndex[nMemberPos] == nFunctionIndex) 278*cdf0e10cSrcweir { 279*cdf0e10cSrcweir // is GET method 280*cdf0e10cSrcweir cpp2uno_call( 281*cdf0e10cSrcweir pCppI, aMemberDescr.get(), 282*cdf0e10cSrcweir ((typelib_InterfaceAttributeTypeDescription *)aMemberDescr.get())->pAttributeTypeRef, 283*cdf0e10cSrcweir 0, 0, // no params 284*cdf0e10cSrcweir pCallStack, pReturnValue ); 285*cdf0e10cSrcweir } 286*cdf0e10cSrcweir else 287*cdf0e10cSrcweir { 288*cdf0e10cSrcweir // is SET method 289*cdf0e10cSrcweir typelib_MethodParameter aParam; 290*cdf0e10cSrcweir aParam.pTypeRef = 291*cdf0e10cSrcweir ((typelib_InterfaceAttributeTypeDescription *)aMemberDescr.get())->pAttributeTypeRef; 292*cdf0e10cSrcweir aParam.bIn = sal_True; 293*cdf0e10cSrcweir aParam.bOut = sal_False; 294*cdf0e10cSrcweir 295*cdf0e10cSrcweir cpp2uno_call( 296*cdf0e10cSrcweir pCppI, aMemberDescr.get(), 297*cdf0e10cSrcweir 0, // indicates void return 298*cdf0e10cSrcweir 1, &aParam, 299*cdf0e10cSrcweir pCallStack, pReturnValue ); 300*cdf0e10cSrcweir } 301*cdf0e10cSrcweir break; 302*cdf0e10cSrcweir } 303*cdf0e10cSrcweir case typelib_TypeClass_INTERFACE_METHOD: 304*cdf0e10cSrcweir { 305*cdf0e10cSrcweir // is METHOD 306*cdf0e10cSrcweir switch (nFunctionIndex) 307*cdf0e10cSrcweir { 308*cdf0e10cSrcweir case 1: // acquire() 309*cdf0e10cSrcweir pCppI->acquireProxy(); // non virtual call! 310*cdf0e10cSrcweir break; 311*cdf0e10cSrcweir case 2: // release() 312*cdf0e10cSrcweir pCppI->releaseProxy(); // non virtual call! 313*cdf0e10cSrcweir break; 314*cdf0e10cSrcweir case 0: // queryInterface() opt 315*cdf0e10cSrcweir { 316*cdf0e10cSrcweir typelib_TypeDescription * pTD = 0; 317*cdf0e10cSrcweir TYPELIB_DANGER_GET( &pTD, reinterpret_cast< Type * >( pCallStack[3] )->getTypeLibType() ); 318*cdf0e10cSrcweir if (pTD) 319*cdf0e10cSrcweir { 320*cdf0e10cSrcweir XInterface * pInterface = 0; 321*cdf0e10cSrcweir (*pCppI->getBridge()->getCppEnv()->getRegisteredInterface)( 322*cdf0e10cSrcweir pCppI->getBridge()->getCppEnv(), 323*cdf0e10cSrcweir (void **)&pInterface, pCppI->getOid().pData, 324*cdf0e10cSrcweir (typelib_InterfaceTypeDescription *)pTD ); 325*cdf0e10cSrcweir 326*cdf0e10cSrcweir if (pInterface) 327*cdf0e10cSrcweir { 328*cdf0e10cSrcweir ::uno_any_construct( 329*cdf0e10cSrcweir reinterpret_cast< uno_Any * >( pCallStack[1] ), 330*cdf0e10cSrcweir &pInterface, pTD, cpp_acquire ); 331*cdf0e10cSrcweir pInterface->release(); 332*cdf0e10cSrcweir TYPELIB_DANGER_RELEASE( pTD ); 333*cdf0e10cSrcweir *static_cast< void ** >(pReturnValue) = pCallStack[1]; 334*cdf0e10cSrcweir break; 335*cdf0e10cSrcweir } 336*cdf0e10cSrcweir TYPELIB_DANGER_RELEASE( pTD ); 337*cdf0e10cSrcweir } 338*cdf0e10cSrcweir } // else perform queryInterface() 339*cdf0e10cSrcweir default: 340*cdf0e10cSrcweir cpp2uno_call( 341*cdf0e10cSrcweir pCppI, aMemberDescr.get(), 342*cdf0e10cSrcweir ((typelib_InterfaceMethodTypeDescription *)aMemberDescr.get())->pReturnTypeRef, 343*cdf0e10cSrcweir ((typelib_InterfaceMethodTypeDescription *)aMemberDescr.get())->nParams, 344*cdf0e10cSrcweir ((typelib_InterfaceMethodTypeDescription *)aMemberDescr.get())->pParams, 345*cdf0e10cSrcweir pCallStack, pReturnValue ); 346*cdf0e10cSrcweir } 347*cdf0e10cSrcweir break; 348*cdf0e10cSrcweir } 349*cdf0e10cSrcweir default: 350*cdf0e10cSrcweir { 351*cdf0e10cSrcweir throw RuntimeException( 352*cdf0e10cSrcweir rtl::OUString::createFromAscii("no member description found!"), 353*cdf0e10cSrcweir (XInterface *)pThis ); 354*cdf0e10cSrcweir } 355*cdf0e10cSrcweir } 356*cdf0e10cSrcweir } 357*cdf0e10cSrcweir 358*cdf0e10cSrcweir //================================================================================================== 359*cdf0e10cSrcweir extern "C" void privateSnippetExecutorGeneral(); 360*cdf0e10cSrcweir extern "C" void privateSnippetExecutorVoid(); 361*cdf0e10cSrcweir extern "C" void privateSnippetExecutorHyper(); 362*cdf0e10cSrcweir extern "C" void privateSnippetExecutorFloat(); 363*cdf0e10cSrcweir extern "C" void privateSnippetExecutorDouble(); 364*cdf0e10cSrcweir extern "C" void privateSnippetExecutorClass(); 365*cdf0e10cSrcweir extern "C" typedef void (*PrivateSnippetExecutor)(); 366*cdf0e10cSrcweir 367*cdf0e10cSrcweir int const codeSnippetSize = 16; 368*cdf0e10cSrcweir 369*cdf0e10cSrcweir unsigned char * codeSnippet( 370*cdf0e10cSrcweir unsigned char * code, sal_Int32 functionIndex, sal_Int32 vtableOffset, 371*cdf0e10cSrcweir typelib_TypeDescriptionReference * returnType) 372*cdf0e10cSrcweir { 373*cdf0e10cSrcweir typelib_TypeDescription * returnTypeDescr = 0; 374*cdf0e10cSrcweir if (returnType) 375*cdf0e10cSrcweir TYPELIB_DANGER_GET( &returnTypeDescr, returnType ); 376*cdf0e10cSrcweir 377*cdf0e10cSrcweir typelib_TypeClass returnTypeClass = returnType ? returnType->eTypeClass : typelib_TypeClass_VOID; 378*cdf0e10cSrcweir if (!bridges::cpp_uno::shared::isSimpleType(returnTypeClass) && 379*cdf0e10cSrcweir !bridges::cpp_uno::shared::isSmallStruct(returnTypeDescr)) { 380*cdf0e10cSrcweir functionIndex |= 0x80000000; 381*cdf0e10cSrcweir } 382*cdf0e10cSrcweir PrivateSnippetExecutor exec; 383*cdf0e10cSrcweir switch (returnTypeClass) { 384*cdf0e10cSrcweir case typelib_TypeClass_VOID: 385*cdf0e10cSrcweir exec = privateSnippetExecutorVoid; 386*cdf0e10cSrcweir break; 387*cdf0e10cSrcweir case typelib_TypeClass_HYPER: 388*cdf0e10cSrcweir case typelib_TypeClass_UNSIGNED_HYPER: 389*cdf0e10cSrcweir exec = privateSnippetExecutorHyper; 390*cdf0e10cSrcweir break; 391*cdf0e10cSrcweir case typelib_TypeClass_FLOAT: 392*cdf0e10cSrcweir exec = privateSnippetExecutorFloat; 393*cdf0e10cSrcweir break; 394*cdf0e10cSrcweir case typelib_TypeClass_DOUBLE: 395*cdf0e10cSrcweir exec = privateSnippetExecutorDouble; 396*cdf0e10cSrcweir break; 397*cdf0e10cSrcweir case typelib_TypeClass_STRUCT: 398*cdf0e10cSrcweir if (bridges::cpp_uno::shared::isSmallStruct(returnTypeDescr)) { 399*cdf0e10cSrcweir if (returnType->pType->nSize <= 4) { 400*cdf0e10cSrcweir exec = privateSnippetExecutorGeneral; 401*cdf0e10cSrcweir } 402*cdf0e10cSrcweir else if (returnType->pType->nSize <= 8) { 403*cdf0e10cSrcweir exec = privateSnippetExecutorHyper; 404*cdf0e10cSrcweir } 405*cdf0e10cSrcweir } 406*cdf0e10cSrcweir else { 407*cdf0e10cSrcweir exec = privateSnippetExecutorClass; 408*cdf0e10cSrcweir } 409*cdf0e10cSrcweir break; 410*cdf0e10cSrcweir case typelib_TypeClass_STRING: 411*cdf0e10cSrcweir case typelib_TypeClass_TYPE: 412*cdf0e10cSrcweir case typelib_TypeClass_ANY: 413*cdf0e10cSrcweir case typelib_TypeClass_SEQUENCE: 414*cdf0e10cSrcweir case typelib_TypeClass_INTERFACE: 415*cdf0e10cSrcweir exec = privateSnippetExecutorClass; 416*cdf0e10cSrcweir break; 417*cdf0e10cSrcweir default: 418*cdf0e10cSrcweir exec = privateSnippetExecutorGeneral; 419*cdf0e10cSrcweir break; 420*cdf0e10cSrcweir } 421*cdf0e10cSrcweir if (returnType) 422*cdf0e10cSrcweir TYPELIB_DANGER_RELEASE( returnTypeDescr ); 423*cdf0e10cSrcweir unsigned char * p = code; 424*cdf0e10cSrcweir OSL_ASSERT(sizeof (sal_Int32) == 4); 425*cdf0e10cSrcweir // mov function_index, %eax: 426*cdf0e10cSrcweir *p++ = 0xB8; 427*cdf0e10cSrcweir *reinterpret_cast< sal_Int32 * >(p) = functionIndex; 428*cdf0e10cSrcweir p += sizeof (sal_Int32); 429*cdf0e10cSrcweir // mov vtable_offset, %edx: 430*cdf0e10cSrcweir *p++ = 0xBA; 431*cdf0e10cSrcweir *reinterpret_cast< sal_Int32 * >(p) = vtableOffset; 432*cdf0e10cSrcweir p += sizeof (sal_Int32); 433*cdf0e10cSrcweir // jmp privateSnippetExecutor: 434*cdf0e10cSrcweir *p++ = 0xE9; 435*cdf0e10cSrcweir *reinterpret_cast< sal_Int32 * >(p) 436*cdf0e10cSrcweir = ((unsigned char *) exec) - p - sizeof (sal_Int32); 437*cdf0e10cSrcweir p += sizeof (sal_Int32); 438*cdf0e10cSrcweir OSL_ASSERT(p - code <= codeSnippetSize); 439*cdf0e10cSrcweir return code + codeSnippetSize; 440*cdf0e10cSrcweir } 441*cdf0e10cSrcweir 442*cdf0e10cSrcweir } 443*cdf0e10cSrcweir 444*cdf0e10cSrcweir struct bridges::cpp_uno::shared::VtableFactory::Slot { void * fn; }; 445*cdf0e10cSrcweir 446*cdf0e10cSrcweir bridges::cpp_uno::shared::VtableFactory::Slot * 447*cdf0e10cSrcweir bridges::cpp_uno::shared::VtableFactory::mapBlockToVtable(void * block) 448*cdf0e10cSrcweir { 449*cdf0e10cSrcweir return static_cast< Slot * >(block) + 2; 450*cdf0e10cSrcweir } 451*cdf0e10cSrcweir 452*cdf0e10cSrcweir sal_Size bridges::cpp_uno::shared::VtableFactory::getBlockSize( 453*cdf0e10cSrcweir sal_Int32 slotCount) 454*cdf0e10cSrcweir { 455*cdf0e10cSrcweir return (slotCount + 2) * sizeof (Slot) + slotCount * codeSnippetSize; 456*cdf0e10cSrcweir } 457*cdf0e10cSrcweir 458*cdf0e10cSrcweir bridges::cpp_uno::shared::VtableFactory::Slot * 459*cdf0e10cSrcweir bridges::cpp_uno::shared::VtableFactory::initializeBlock( 460*cdf0e10cSrcweir void * block, sal_Int32 slotCount) 461*cdf0e10cSrcweir { 462*cdf0e10cSrcweir Slot * slots = mapBlockToVtable(block); 463*cdf0e10cSrcweir slots[-2].fn = 0; 464*cdf0e10cSrcweir slots[-1].fn = 0; 465*cdf0e10cSrcweir return slots + slotCount; 466*cdf0e10cSrcweir } 467*cdf0e10cSrcweir 468*cdf0e10cSrcweir unsigned char * bridges::cpp_uno::shared::VtableFactory::addLocalFunctions( 469*cdf0e10cSrcweir Slot ** slots, unsigned char * code, 470*cdf0e10cSrcweir typelib_InterfaceTypeDescription const * type, sal_Int32 functionOffset, 471*cdf0e10cSrcweir sal_Int32 functionCount, sal_Int32 vtableOffset) 472*cdf0e10cSrcweir { 473*cdf0e10cSrcweir (*slots) -= functionCount; 474*cdf0e10cSrcweir Slot * s = *slots; 475*cdf0e10cSrcweir for (sal_Int32 i = 0; i < type->nMembers; ++i) { 476*cdf0e10cSrcweir typelib_TypeDescription * member = 0; 477*cdf0e10cSrcweir TYPELIB_DANGER_GET(&member, type->ppMembers[i]); 478*cdf0e10cSrcweir OSL_ASSERT(member != 0); 479*cdf0e10cSrcweir switch (member->eTypeClass) { 480*cdf0e10cSrcweir case typelib_TypeClass_INTERFACE_ATTRIBUTE: 481*cdf0e10cSrcweir // Getter: 482*cdf0e10cSrcweir (s++)->fn = code; 483*cdf0e10cSrcweir code = codeSnippet( 484*cdf0e10cSrcweir code, functionOffset++, vtableOffset, 485*cdf0e10cSrcweir reinterpret_cast< typelib_InterfaceAttributeTypeDescription * >( 486*cdf0e10cSrcweir member)->pAttributeTypeRef); 487*cdf0e10cSrcweir // Setter: 488*cdf0e10cSrcweir if (!reinterpret_cast< 489*cdf0e10cSrcweir typelib_InterfaceAttributeTypeDescription * >( 490*cdf0e10cSrcweir member)->bReadOnly) 491*cdf0e10cSrcweir { 492*cdf0e10cSrcweir (s++)->fn = code; 493*cdf0e10cSrcweir code = codeSnippet( 494*cdf0e10cSrcweir code, functionOffset++, vtableOffset, 495*cdf0e10cSrcweir NULL); 496*cdf0e10cSrcweir } 497*cdf0e10cSrcweir break; 498*cdf0e10cSrcweir 499*cdf0e10cSrcweir case typelib_TypeClass_INTERFACE_METHOD: 500*cdf0e10cSrcweir (s++)->fn = code; 501*cdf0e10cSrcweir code = codeSnippet( 502*cdf0e10cSrcweir code, functionOffset++, vtableOffset, 503*cdf0e10cSrcweir reinterpret_cast< typelib_InterfaceMethodTypeDescription * >( 504*cdf0e10cSrcweir member)->pReturnTypeRef); 505*cdf0e10cSrcweir break; 506*cdf0e10cSrcweir 507*cdf0e10cSrcweir default: 508*cdf0e10cSrcweir OSL_ASSERT(false); 509*cdf0e10cSrcweir break; 510*cdf0e10cSrcweir } 511*cdf0e10cSrcweir TYPELIB_DANGER_RELEASE(member); 512*cdf0e10cSrcweir } 513*cdf0e10cSrcweir return code; 514*cdf0e10cSrcweir } 515*cdf0e10cSrcweir 516*cdf0e10cSrcweir void bridges::cpp_uno::shared::VtableFactory::flushCode( 517*cdf0e10cSrcweir unsigned char const *, unsigned char const *) 518*cdf0e10cSrcweir {} 519