LCOV - code coverage report
Current view: top level - bridges/source/cpp_uno/gcc3_linux_x86-64 - cpp2uno.cxx (source / functions) Hit Total Coverage
Test: commit 10e77ab3ff6f4314137acd6e2702a6e5c1ce1fae Lines: 177 183 96.7 %
Date: 2014-11-03 Functions: 8 8 100.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /*
       3             :  * This file is part of the LibreOffice project.
       4             :  *
       5             :  * This Source Code Form is subject to the terms of the Mozilla Public
       6             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       7             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       8             :  *
       9             :  * This file incorporates work covered by the following license notice:
      10             :  *
      11             :  *   Licensed to the Apache Software Foundation (ASF) under one or more
      12             :  *   contributor license agreements. See the NOTICE file distributed
      13             :  *   with this work for additional information regarding copyright
      14             :  *   ownership. The ASF licenses this file to you under the Apache
      15             :  *   License, Version 2.0 (the "License"); you may not use this file
      16             :  *   except in compliance with the License. You may obtain a copy of
      17             :  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
      18             :  */
      19             : 
      20             : 
      21             : #include <stdio.h>
      22             : #include <stdlib.h>
      23             : #include <boost/unordered_map.hpp>
      24             : 
      25             : #include <rtl/alloc.h>
      26             : #include <osl/mutex.hxx>
      27             : 
      28             : #include <com/sun/star/uno/genfunc.hxx>
      29             : #include "com/sun/star/uno/RuntimeException.hpp"
      30             : #include <config_options.h>
      31             : #include <uno/data.h>
      32             : #include <typelib/typedescription.hxx>
      33             : 
      34             : #include "bridges/cpp_uno/shared/bridge.hxx"
      35             : #include "bridges/cpp_uno/shared/cppinterfaceproxy.hxx"
      36             : #include "bridges/cpp_uno/shared/types.hxx"
      37             : #include "bridges/cpp_uno/shared/vtablefactory.hxx"
      38             : 
      39             : #include "abi.hxx"
      40             : #include "call.hxx"
      41             : #include "rtti.hxx"
      42             : #include "share.hxx"
      43             : 
      44             : using namespace ::osl;
      45             : using namespace ::com::sun::star::uno;
      46             : 
      47             : 
      48             : 
      49             : // Perform the UNO call
      50             : //
      51             : // We must convert the parameters stored in gpreg, fpreg and ovrflw to UNO
      52             : // arguments and call pThis->getUnoI()->pDispatcher.
      53             : //
      54             : // gpreg:  [ret *], this, [gpr params]
      55             : // fpreg:  [fpr params]
      56             : // ovrflw: [gpr or fpr params (properly aligned)]
      57             : //
      58             : // [ret *] is present when we are returning a structure bigger than 16 bytes
      59             : // Simple types are returned in rax, rdx (int), or xmm0, xmm1 (fp).
      60             : // Similarly structures <= 16 bytes are in rax, rdx, xmm0, xmm1 as necessary.
      61       71334 : static typelib_TypeClass cpp2uno_call(
      62             :     bridges::cpp_uno::shared::CppInterfaceProxy * pThis,
      63             :     const typelib_TypeDescription * pMemberTypeDescr,
      64             :     typelib_TypeDescriptionReference * pReturnTypeRef, // 0 indicates void return
      65             :     sal_Int32 nParams, typelib_MethodParameter * pParams,
      66             :     void ** gpreg, void ** fpreg, void ** ovrflw,
      67             :     sal_uInt64 * pRegisterReturn /* space for register return */ )
      68             : {
      69       71334 :     unsigned int nr_gpr = 0; //number of gpr registers used
      70       71334 :     unsigned int nr_fpr = 0; //number of fpr registers used
      71             : 
      72             :     // return
      73       71334 :     typelib_TypeDescription * pReturnTypeDescr = 0;
      74       71334 :     if (pReturnTypeRef)
      75       71288 :         TYPELIB_DANGER_GET( &pReturnTypeDescr, pReturnTypeRef );
      76             : 
      77       71334 :     void * pUnoReturn = 0;
      78       71334 :     void * pCppReturn = 0; // complex return ptr: if != 0 && != pUnoReturn, reconversion need
      79             : 
      80       71334 :     if ( pReturnTypeDescr )
      81             :     {
      82       71288 :         if ( x86_64::return_in_hidden_param( pReturnTypeRef ) )
      83             :         {
      84       19909 :             pCppReturn = *gpreg++;
      85       19909 :             nr_gpr++;
      86             : 
      87       19909 :             pUnoReturn = ( bridges::cpp_uno::shared::relatesToInterfaceType( pReturnTypeDescr )
      88        9424 :                            ? alloca( pReturnTypeDescr->nSize )
      89       29333 :                            : pCppReturn ); // direct way
      90             :         }
      91             :         else
      92       51379 :             pUnoReturn = pRegisterReturn; // direct way for simple types
      93             :     }
      94             : 
      95             :     // pop this
      96       71334 :     gpreg++;
      97       71334 :     nr_gpr++;
      98             : 
      99             :     // stack space
     100             :     // parameters
     101       71334 :     void ** pUnoArgs = (void **)alloca( 4 * sizeof(void *) * nParams );
     102       71334 :     void ** pCppArgs = pUnoArgs + nParams;
     103             :     // indices of values this have to be converted (interface conversion cpp<=>uno)
     104       71334 :     sal_Int32 * pTempIndices = (sal_Int32 *)(pUnoArgs + (2 * nParams));
     105             :     // type descriptions for reconversions
     106       71334 :     typelib_TypeDescription ** ppTempParamTypeDescr = (typelib_TypeDescription **)(pUnoArgs + (3 * nParams));
     107             : 
     108       71334 :     sal_Int32 nTempIndices = 0;
     109             : 
     110      133391 :     for ( sal_Int32 nPos = 0; nPos < nParams; ++nPos )
     111             :     {
     112       62057 :         const typelib_MethodParameter & rParam = pParams[nPos];
     113             : 
     114       62057 :         int nUsedGPR = 0;
     115       62057 :         int nUsedSSE = 0;
     116             : #if OSL_DEBUG_LEVEL > 0
     117             :         bool bFitsRegisters =
     118             : #endif
     119       62057 :             x86_64::examine_argument( rParam.pTypeRef, false, nUsedGPR, nUsedSSE );
     120       62057 :         if ( !rParam.bOut && bridges::cpp_uno::shared::isSimpleType( rParam.pTypeRef ) ) // value
     121             :         {
     122             :             // Simple types must fit exactly one register on x86_64
     123             :             OSL_ASSERT( bFitsRegisters && ( ( nUsedSSE == 1 && nUsedGPR == 0 ) || ( nUsedSSE == 0 && nUsedGPR == 1 ) ) );
     124             : 
     125        9022 :             if ( nUsedSSE == 1 )
     126             :             {
     127          36 :                 if ( nr_fpr < x86_64::MAX_SSE_REGS )
     128             :                 {
     129          32 :                     pCppArgs[nPos] = pUnoArgs[nPos] = fpreg++;
     130          32 :                     nr_fpr++;
     131             :                 }
     132             :                 else
     133           4 :                     pCppArgs[nPos] = pUnoArgs[nPos] = ovrflw++;
     134             :             }
     135        8986 :             else if ( nUsedGPR == 1 )
     136             :             {
     137        8986 :                 if ( nr_gpr < x86_64::MAX_GPR_REGS )
     138             :                 {
     139        8976 :                     pCppArgs[nPos] = pUnoArgs[nPos] = gpreg++;
     140        8976 :                     nr_gpr++;
     141             :                 }
     142             :                 else
     143          10 :                     pCppArgs[nPos] = pUnoArgs[nPos] = ovrflw++;
     144             :             }
     145             :         }
     146             :         else // struct <= 16 bytes || ptr to complex value || ref
     147             :         {
     148       53035 :             typelib_TypeDescription * pParamTypeDescr = 0;
     149       53035 :             TYPELIB_DANGER_GET( &pParamTypeDescr, rParam.pTypeRef );
     150             : 
     151             :             void *pCppStack;
     152       53035 :             if ( nr_gpr < x86_64::MAX_GPR_REGS )
     153             :             {
     154       52899 :                 pCppArgs[nPos] = pCppStack = *gpreg++;
     155       52899 :                 nr_gpr++;
     156             :             }
     157             :             else
     158         136 :                 pCppArgs[nPos] = pCppStack = *ovrflw++;
     159             : 
     160       53035 :             if (! rParam.bIn) // is pure out
     161             :             {
     162             :                 // uno out is unconstructed mem!
     163         118 :                 pUnoArgs[nPos] = alloca( pParamTypeDescr->nSize );
     164         118 :                 pTempIndices[nTempIndices] = nPos;
     165             :                 // will be released at reconversion
     166         118 :                 ppTempParamTypeDescr[nTempIndices++] = pParamTypeDescr;
     167             :             }
     168       52917 :             else if ( bridges::cpp_uno::shared::relatesToInterfaceType( pParamTypeDescr ) ) // is in/inout
     169             :             {
     170       89006 :                 uno_copyAndConvertData( pUnoArgs[nPos] = alloca( pParamTypeDescr->nSize ),
     171             :                                         pCppStack, pParamTypeDescr,
     172      133509 :                                         pThis->getBridge()->getCpp2Uno() );
     173       44503 :                 pTempIndices[nTempIndices] = nPos; // has to be reconverted
     174             :                 // will be released at reconversion
     175       44503 :                 ppTempParamTypeDescr[nTempIndices++] = pParamTypeDescr;
     176             :             }
     177             :             else // direct way
     178             :             {
     179        8414 :                 pUnoArgs[nPos] = pCppStack;
     180             :                 // no longer needed
     181        8414 :                 TYPELIB_DANGER_RELEASE( pParamTypeDescr );
     182             :             }
     183             :         }
     184             :     }
     185             : 
     186             :     // ExceptionHolder
     187             :     uno_Any aUnoExc; // Any will be constructed by callee
     188       71334 :     uno_Any * pUnoExc = &aUnoExc;
     189             : 
     190             :     // invoke uno dispatch call
     191       71334 :     (*pThis->getUnoI()->pDispatcher)( pThis->getUnoI(), pMemberTypeDescr, pUnoReturn, pUnoArgs, &pUnoExc );
     192             : 
     193             :     // in case an exception occurred...
     194       71334 :     if ( pUnoExc )
     195             :     {
     196             :         // destruct temporary in/inout params
     197      103032 :         for ( ; nTempIndices--; )
     198             :         {
     199       34316 :             sal_Int32 nIndex = pTempIndices[nTempIndices];
     200             : 
     201       34316 :             if (pParams[nIndex].bIn) // is in/inout => was constructed
     202       34316 :                 uno_destructData( pUnoArgs[nIndex], ppTempParamTypeDescr[nTempIndices], 0 );
     203       34316 :             TYPELIB_DANGER_RELEASE( ppTempParamTypeDescr[nTempIndices] );
     204             :         }
     205       34358 :         if (pReturnTypeDescr)
     206       34354 :             TYPELIB_DANGER_RELEASE( pReturnTypeDescr );
     207             : 
     208       34358 :         CPPU_CURRENT_NAMESPACE::raiseException( &aUnoExc, pThis->getBridge()->getUno2Cpp() ); // has to destruct the any
     209             :         // is here for dummy
     210           0 :         return typelib_TypeClass_VOID;
     211             :     }
     212             :     else // else no exception occurred...
     213             :     {
     214             :         // temporary params
     215       84257 :         for ( ; nTempIndices--; )
     216             :         {
     217       10305 :             sal_Int32 nIndex = pTempIndices[nTempIndices];
     218       10305 :             typelib_TypeDescription * pParamTypeDescr = ppTempParamTypeDescr[nTempIndices];
     219             : 
     220       10305 :             if ( pParams[nIndex].bOut ) // inout/out
     221             :             {
     222             :                 // convert and assign
     223         130 :                 uno_destructData( pCppArgs[nIndex], pParamTypeDescr, cpp_release );
     224         260 :                 uno_copyAndConvertData( pCppArgs[nIndex], pUnoArgs[nIndex], pParamTypeDescr,
     225         390 :                                         pThis->getBridge()->getUno2Cpp() );
     226             :             }
     227             :             // destroy temp uno param
     228       10305 :             uno_destructData( pUnoArgs[nIndex], pParamTypeDescr, 0 );
     229             : 
     230       10305 :             TYPELIB_DANGER_RELEASE( pParamTypeDescr );
     231             :         }
     232             :         // return
     233       36976 :         if ( pCppReturn ) // has complex return
     234             :         {
     235       19907 :             if ( pUnoReturn != pCppReturn ) // needs reconversion
     236             :             {
     237             :                 uno_copyAndConvertData( pCppReturn, pUnoReturn, pReturnTypeDescr,
     238        9422 :                                         pThis->getBridge()->getUno2Cpp() );
     239             :                 // destroy temp uno return
     240        9422 :                 uno_destructData( pUnoReturn, pReturnTypeDescr, 0 );
     241             :             }
     242             :             // complex return ptr is set to return reg
     243       19907 :             *(void **)pRegisterReturn = pCppReturn;
     244             :         }
     245       36976 :         if ( pReturnTypeDescr )
     246             :         {
     247       36934 :             typelib_TypeClass eRet = (typelib_TypeClass)pReturnTypeDescr->eTypeClass;
     248       36934 :             TYPELIB_DANGER_RELEASE( pReturnTypeDescr );
     249       36934 :             return eRet;
     250             :         }
     251             :         else
     252          42 :             return typelib_TypeClass_VOID;
     253             :     }
     254             : }
     255             : 
     256             : 
     257      348236 : typelib_TypeClass cpp_vtable_call(
     258             :     sal_Int32 nFunctionIndex, sal_Int32 nVtableOffset,
     259             :     void ** gpreg, void ** fpreg, void ** ovrflw,
     260             :     sal_uInt64 * pRegisterReturn /* space for register return */ )
     261             : {
     262             :     // gpreg:  [ret *], this, [other gpr params]
     263             :     // fpreg:  [fpr params]
     264             :     // ovrflw: [gpr or fpr params (properly aligned)]
     265             :     void * pThis;
     266      348236 :     if ( nFunctionIndex & 0x80000000 )
     267             :     {
     268       34629 :         nFunctionIndex &= 0x7fffffff;
     269       34629 :         pThis = gpreg[1];
     270             :     }
     271             :     else
     272             :     {
     273      313607 :         pThis = gpreg[0];
     274             :     }
     275      348236 :     pThis = static_cast<char *>( pThis ) - nVtableOffset;
     276             : 
     277             :     bridges::cpp_uno::shared::CppInterfaceProxy * pCppI =
     278      348236 :         bridges::cpp_uno::shared::CppInterfaceProxy::castInterfaceToProxy( pThis );
     279             : 
     280      348236 :     typelib_InterfaceTypeDescription * pTypeDescr = pCppI->getTypeDescr();
     281             : 
     282      348236 :     if ( nFunctionIndex >= pTypeDescr->nMapFunctionIndexToMemberIndex )
     283             :     {
     284             :         SAL_WARN(
     285             :             "bridges",
     286             :             "illegal " << OUString::unacquired(&pTypeDescr->aBase.pTypeName)
     287             :                 << " vtable index " << nFunctionIndex << "/"
     288             :                 << pTypeDescr->nMapFunctionIndexToMemberIndex);
     289             :         throw RuntimeException(
     290           0 :             ("illegal " + OUString::unacquired(&pTypeDescr->aBase.pTypeName)
     291           0 :              + " vtable index " + OUString::number(nFunctionIndex) + "/"
     292           0 :              + OUString::number(pTypeDescr->nMapFunctionIndexToMemberIndex)),
     293           0 :             reinterpret_cast<XInterface *>( pCppI ) );
     294             :     }
     295             : 
     296             :     // determine called method
     297      348236 :     sal_Int32 nMemberPos = pTypeDescr->pMapFunctionIndexToMemberIndex[nFunctionIndex];
     298             :     OSL_ENSURE( nMemberPos < pTypeDescr->nAllMembers, "### illegal member index!\n" );
     299             : 
     300      348236 :     TypeDescription aMemberDescr( pTypeDescr->ppAllMembers[nMemberPos] );
     301             : 
     302             :     typelib_TypeClass eRet;
     303      348236 :     switch ( aMemberDescr.get()->eTypeClass )
     304             :     {
     305             :         case typelib_TypeClass_INTERFACE_ATTRIBUTE:
     306             :         {
     307             :             typelib_TypeDescriptionReference *pAttrTypeRef =
     308        3227 :                 reinterpret_cast<typelib_InterfaceAttributeTypeDescription *>( aMemberDescr.get() )->pAttributeTypeRef;
     309             : 
     310        3227 :             if ( pTypeDescr->pMapMemberIndexToFunctionIndex[nMemberPos] == nFunctionIndex )
     311             :             {
     312             :                 // is GET method
     313        3181 :                 eRet = cpp2uno_call( pCppI, aMemberDescr.get(), pAttrTypeRef,
     314             :                         0, 0, // no params
     315        3181 :                         gpreg, fpreg, ovrflw, pRegisterReturn );
     316             :             }
     317             :             else
     318             :             {
     319             :                 // is SET method
     320             :                 typelib_MethodParameter aParam;
     321          46 :                 aParam.pTypeRef = pAttrTypeRef;
     322          46 :                 aParam.bIn      = sal_True;
     323          46 :                 aParam.bOut     = sal_False;
     324             : 
     325          46 :                 eRet = cpp2uno_call( pCppI, aMemberDescr.get(),
     326             :                         0, // indicates void return
     327             :                         1, &aParam,
     328          46 :                         gpreg, fpreg, ovrflw, pRegisterReturn );
     329             :             }
     330        3217 :             break;
     331             :         }
     332             :         case typelib_TypeClass_INTERFACE_METHOD:
     333             :         {
     334             :             // is METHOD
     335      345009 :             switch ( nFunctionIndex )
     336             :             {
     337             :                 case 1: // acquire()
     338      108517 :                     pCppI->acquireProxy(); // non virtual call!
     339      108517 :                     eRet = typelib_TypeClass_VOID;
     340      108517 :                     break;
     341             :                 case 2: // release()
     342      153665 :                     pCppI->releaseProxy(); // non virtual call!
     343      153665 :                     eRet = typelib_TypeClass_VOID;
     344      153665 :                     break;
     345             :                 case 0: // queryInterface() opt
     346             :                 {
     347       21586 :                     typelib_TypeDescription * pTD = 0;
     348       21586 :                     TYPELIB_DANGER_GET( &pTD, reinterpret_cast<Type *>( gpreg[2] )->getTypeLibType() );
     349       21586 :                     if ( pTD )
     350             :                     {
     351       21586 :                         XInterface * pInterface = 0;
     352       21586 :                         (*pCppI->getBridge()->getCppEnv()->getRegisteredInterface)
     353             :                             ( pCppI->getBridge()->getCppEnv(),
     354             :                               (void **)&pInterface,
     355             :                               pCppI->getOid().pData,
     356       21586 :                               reinterpret_cast<typelib_InterfaceTypeDescription *>( pTD ) );
     357             : 
     358       21586 :                         if ( pInterface )
     359             :                         {
     360             :                             ::uno_any_construct( reinterpret_cast<uno_Any *>( gpreg[0] ),
     361       14720 :                                                  &pInterface, pTD, cpp_acquire );
     362             : 
     363       14720 :                             pInterface->release();
     364       14720 :                             TYPELIB_DANGER_RELEASE( pTD );
     365             : 
     366       14720 :                             reinterpret_cast<void **>( pRegisterReturn )[0] = gpreg[0];
     367       14720 :                             eRet = typelib_TypeClass_ANY;
     368       14720 :                             break;
     369             :                         }
     370        6866 :                         TYPELIB_DANGER_RELEASE( pTD );
     371             :                     }
     372             :                 } // else perform queryInterface()
     373             :                 default:
     374             :                 {
     375             :                     typelib_InterfaceMethodTypeDescription *pMethodTD =
     376       68107 :                         reinterpret_cast<typelib_InterfaceMethodTypeDescription *>( aMemberDescr.get() );
     377             : 
     378       68107 :                     eRet = cpp2uno_call( pCppI, aMemberDescr.get(),
     379             :                                          pMethodTD->pReturnTypeRef,
     380             :                                          pMethodTD->nParams,
     381             :                                          pMethodTD->pParams,
     382      136214 :                                          gpreg, fpreg, ovrflw, pRegisterReturn );
     383             :                 }
     384             :             }
     385      310661 :             break;
     386             :         }
     387             :         default:
     388             :         {
     389             :             throw RuntimeException("no member description found!",
     390           0 :                                     reinterpret_cast<XInterface *>( pCppI ) );
     391             :         }
     392             :     }
     393             : 
     394      348236 :     return eRet;
     395             : }
     396             : 
     397             : const int codeSnippetSize = 24;
     398             : 
     399             : // Generate a trampoline that redirects method calls to
     400             : // privateSnippetExecutor().
     401             : //
     402             : // privateSnippetExecutor() saves all the registers that are used for
     403             : // parameter passing on x86_64, and calls the cpp_vtable_call().
     404             : // When it returns, privateSnippetExecutor() sets the return value.
     405             : //
     406             : // Note: The code snippet we build here must not create a stack frame,
     407             : // otherwise the UNO exceptions stop working thanks to non-existing
     408             : // unwinding info.
     409        7187 : unsigned char * codeSnippet( unsigned char * code,
     410             :         sal_Int32 nFunctionIndex, sal_Int32 nVtableOffset,
     411             :         bool bHasHiddenParam )
     412             : {
     413        7187 :     sal_uInt64 nOffsetAndIndex = ( ( (sal_uInt64) nVtableOffset ) << 32 ) | ( (sal_uInt64) nFunctionIndex );
     414             : 
     415        7187 :     if ( bHasHiddenParam )
     416        2315 :         nOffsetAndIndex |= 0x80000000;
     417             : 
     418             :     // movq $<nOffsetAndIndex>, %r10
     419        7187 :     *reinterpret_cast<sal_uInt16 *>( code ) = 0xba49;
     420        7187 :     *reinterpret_cast<sal_uInt16 *>( code + 2 ) = nOffsetAndIndex & 0xFFFF;
     421        7187 :     *reinterpret_cast<sal_uInt32 *>( code + 4 ) = nOffsetAndIndex >> 16;
     422        7187 :     *reinterpret_cast<sal_uInt16 *>( code + 8 ) = nOffsetAndIndex >> 48;
     423             : 
     424             :     // movq $<address of the privateSnippetExecutor>, %r11
     425        7187 :     *reinterpret_cast<sal_uInt16 *>( code + 10 ) = 0xbb49;
     426             :     *reinterpret_cast<sal_uInt32 *>( code + 12 )
     427        7187 :         = reinterpret_cast<sal_uInt64>(privateSnippetExecutor);
     428             :     *reinterpret_cast<sal_uInt32 *>( code + 16 )
     429        7187 :         = reinterpret_cast<sal_uInt64>(privateSnippetExecutor) >> 32;
     430             : 
     431             :     // jmpq *%r11
     432        7187 :     *reinterpret_cast<sal_uInt32 *>( code + 20 ) = 0x00e3ff49;
     433             : 
     434             : #if OSL_DEBUG_LEVEL > 1
     435             :     fprintf(stderr,
     436             :             "==> codeSnippet, functionIndex=%d%s, vtableOffset=%d\n",
     437             :             nFunctionIndex, (bHasHiddenParam ? "|0x80000000":""), nVtableOffset);
     438             : #endif
     439             : 
     440        7187 :     return code + codeSnippetSize;
     441             : }
     442             : 
     443             : struct bridges::cpp_uno::shared::VtableFactory::Slot { void * fn; };
     444             : 
     445             : bridges::cpp_uno::shared::VtableFactory::Slot *
     446       51587 : bridges::cpp_uno::shared::VtableFactory::mapBlockToVtable(void * block)
     447             : {
     448       51587 :     return static_cast< Slot * >(block) + 2;
     449             : }
     450             : 
     451         905 : sal_Size bridges::cpp_uno::shared::VtableFactory::getBlockSize(
     452             :     sal_Int32 slotCount)
     453             : {
     454         905 :     return (slotCount + 2) * sizeof (Slot) + slotCount * codeSnippetSize;
     455             : }
     456             : 
     457             : bridges::cpp_uno::shared::VtableFactory::Slot *
     458         905 : bridges::cpp_uno::shared::VtableFactory::initializeBlock(
     459             :     void * block, sal_Int32 slotCount, sal_Int32 vtableNumber,
     460             :     typelib_InterfaceTypeDescription * type)
     461             : {
     462         905 :     Slot * slots = mapBlockToVtable(block);
     463         905 :     slots[-2].fn = reinterpret_cast<void *>(-(vtableNumber * sizeof (void *)));
     464             : #if ENABLE_RUNTIME_OPTIMIZATIONS
     465         905 :     slots[-1].fn = 0;
     466             :     (void)type;
     467             : #else
     468             :     slots[-1].fn = x86_64::getRtti(type->aBase);
     469             : #endif
     470         905 :     return slots + slotCount;
     471             : }
     472             : 
     473             : 
     474             : 
     475        1998 : unsigned char * bridges::cpp_uno::shared::VtableFactory::addLocalFunctions(
     476             :     Slot ** slots, unsigned char * code, sal_PtrDiff writetoexecdiff,
     477             :     typelib_InterfaceTypeDescription const * type, sal_Int32 nFunctionOffset,
     478             :     sal_Int32 functionCount, sal_Int32 nVtableOffset )
     479             : {
     480        1998 :     (*slots) -= functionCount;
     481        1998 :     Slot * s = *slots;
     482        9061 :     for ( sal_Int32 nPos = 0; nPos < type->nMembers; ++nPos )
     483             :     {
     484        7063 :         typelib_TypeDescription * pTD = 0;
     485             : 
     486        7063 :         TYPELIB_DANGER_GET( &pTD, type->ppMembers[ nPos ] );
     487             :         OSL_ASSERT( pTD );
     488             : 
     489        7063 :         if ( typelib_TypeClass_INTERFACE_ATTRIBUTE == pTD->eTypeClass )
     490             :         {
     491             :             typelib_InterfaceAttributeTypeDescription *pAttrTD =
     492         182 :                 reinterpret_cast<typelib_InterfaceAttributeTypeDescription *>( pTD );
     493             : 
     494             :             // get method
     495         182 :             (s++)->fn = code + writetoexecdiff;
     496             :             code = codeSnippet( code, nFunctionOffset++, nVtableOffset,
     497         182 :                                 x86_64::return_in_hidden_param( pAttrTD->pAttributeTypeRef ) );
     498             : 
     499         182 :             if ( ! pAttrTD->bReadOnly )
     500             :             {
     501             :                 // set method
     502         124 :                 (s++)->fn = code + writetoexecdiff;
     503         124 :                 code = codeSnippet( code, nFunctionOffset++, nVtableOffset, false );
     504             :             }
     505             :         }
     506        6881 :         else if ( typelib_TypeClass_INTERFACE_METHOD == pTD->eTypeClass )
     507             :         {
     508             :             typelib_InterfaceMethodTypeDescription *pMethodTD =
     509        6881 :                 reinterpret_cast<typelib_InterfaceMethodTypeDescription *>( pTD );
     510             : 
     511        6881 :             (s++)->fn = code + writetoexecdiff;
     512             :             code = codeSnippet( code, nFunctionOffset++, nVtableOffset,
     513        6881 :                                 x86_64::return_in_hidden_param( pMethodTD->pReturnTypeRef ) );
     514             :         }
     515             :         else
     516             :             OSL_ASSERT( false );
     517             : 
     518        7063 :         TYPELIB_DANGER_RELEASE( pTD );
     519             :     }
     520        1998 :     return code;
     521             : }
     522             : 
     523         905 : void bridges::cpp_uno::shared::VtableFactory::flushCode(
     524             :     SAL_UNUSED_PARAMETER unsigned char const *,
     525             :     SAL_UNUSED_PARAMETER unsigned char const * )
     526         905 : {}
     527             : 
     528             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10