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