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 c8344322a7af75b84dd3ca8f78b05543a976dfd5 Lines: 177 183 96.7 %
Date: 2015-06-13 12:38:46 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             : 
      24             : #include <rtl/alloc.h>
      25             : #include <sal/log.hxx>
      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             : // Perform the UNO call
      48             : //
      49             : // We must convert the parameters stored in gpreg, fpreg and ovrflw to UNO
      50             : // arguments and call pThis->getUnoI()->pDispatcher.
      51             : //
      52             : // gpreg:  [ret *], this, [gpr params]
      53             : // fpreg:  [fpr params]
      54             : // ovrflw: [gpr or fpr params (properly aligned)]
      55             : //
      56             : // [ret *] is present when we are returning a structure bigger than 16 bytes
      57             : // Simple types are returned in rax, rdx (int), or xmm0, xmm1 (fp).
      58             : // Similarly structures <= 16 bytes are in rax, rdx, xmm0, xmm1 as necessary.
      59      380246 : static typelib_TypeClass cpp2uno_call(
      60             :     bridges::cpp_uno::shared::CppInterfaceProxy * pThis,
      61             :     const typelib_TypeDescription * pMemberTypeDescr,
      62             :     typelib_TypeDescriptionReference * pReturnTypeRef, // 0 indicates void return
      63             :     sal_Int32 nParams, typelib_MethodParameter * pParams,
      64             :     void ** gpreg, void ** fpreg, void ** ovrflw,
      65             :     sal_uInt64 * pRegisterReturn /* space for register return */ )
      66             : {
      67      380246 :     unsigned int nr_gpr = 0; //number of gpr registers used
      68      380246 :     unsigned int nr_fpr = 0; //number of fpr registers used
      69             : 
      70             :     // return
      71      380246 :     typelib_TypeDescription * pReturnTypeDescr = 0;
      72      380246 :     if (pReturnTypeRef)
      73      380223 :         TYPELIB_DANGER_GET( &pReturnTypeDescr, pReturnTypeRef );
      74             : 
      75      380246 :     void * pUnoReturn = 0;
      76      380246 :     void * pCppReturn = 0; // complex return ptr: if != 0 && != pUnoReturn, reconversion need
      77             : 
      78      380246 :     if ( pReturnTypeDescr )
      79             :     {
      80      380223 :         if ( x86_64::return_in_hidden_param( pReturnTypeRef ) )
      81             :         {
      82      185351 :             pCppReturn = *gpreg++;
      83      185351 :             nr_gpr++;
      84             : 
      85      185351 :             pUnoReturn = ( bridges::cpp_uno::shared::relatesToInterfaceType( pReturnTypeDescr )
      86      134354 :                            ? alloca( pReturnTypeDescr->nSize )
      87      319705 :                            : pCppReturn ); // direct way
      88             :         }
      89             :         else
      90      194872 :             pUnoReturn = pRegisterReturn; // direct way for simple types
      91             :     }
      92             : 
      93             :     // pop this
      94      380246 :     gpreg++;
      95      380246 :     nr_gpr++;
      96             : 
      97             :     // stack space
      98             :     // parameters
      99      380246 :     void ** pUnoArgs = static_cast<void **>(alloca( 4 * sizeof(void *) * nParams ));
     100      380246 :     void ** pCppArgs = pUnoArgs + nParams;
     101             :     // indices of values this have to be converted (interface conversion cpp<=>uno)
     102      380246 :     sal_Int32 * pTempIndices = reinterpret_cast<sal_Int32 *>(pUnoArgs + (2 * nParams));
     103             :     // type descriptions for reconversions
     104      380246 :     typelib_TypeDescription ** ppTempParamTypeDescr = reinterpret_cast<typelib_TypeDescription **>(pUnoArgs + (3 * nParams));
     105             : 
     106      380246 :     sal_Int32 nTempIndices = 0;
     107             : 
     108      663217 :     for ( sal_Int32 nPos = 0; nPos < nParams; ++nPos )
     109             :     {
     110      282971 :         const typelib_MethodParameter & rParam = pParams[nPos];
     111             : 
     112      282971 :         int nUsedGPR = 0;
     113      282971 :         int nUsedSSE = 0;
     114      282971 :         bool bFitsRegisters = x86_64::examine_argument( rParam.pTypeRef, false, nUsedGPR, nUsedSSE );
     115      282971 :         if ( !rParam.bOut && bridges::cpp_uno::shared::isSimpleType( rParam.pTypeRef ) ) // value
     116             :         {
     117             :             // Simple types must fit exactly one register on x86_64
     118             :             assert( bFitsRegisters && ( ( nUsedSSE == 1 && nUsedGPR == 0 ) || ( nUsedSSE == 0 && nUsedGPR == 1 ) ) ); (void)bFitsRegisters;
     119             : 
     120      136850 :             if ( nUsedSSE == 1 )
     121             :             {
     122          18 :                 if ( nr_fpr < x86_64::MAX_SSE_REGS )
     123             :                 {
     124          16 :                     pCppArgs[nPos] = pUnoArgs[nPos] = fpreg++;
     125          16 :                     nr_fpr++;
     126             :                 }
     127             :                 else
     128           2 :                     pCppArgs[nPos] = pUnoArgs[nPos] = ovrflw++;
     129             :             }
     130      136832 :             else if ( nUsedGPR == 1 )
     131             :             {
     132      136832 :                 if ( nr_gpr < x86_64::MAX_GPR_REGS )
     133             :                 {
     134      136818 :                     pCppArgs[nPos] = pUnoArgs[nPos] = gpreg++;
     135      136818 :                     nr_gpr++;
     136             :                 }
     137             :                 else
     138          14 :                     pCppArgs[nPos] = pUnoArgs[nPos] = ovrflw++;
     139             :             }
     140             :         }
     141             :         else // struct <= 16 bytes || ptr to complex value || ref
     142             :         {
     143      146121 :             typelib_TypeDescription * pParamTypeDescr = 0;
     144      146121 :             TYPELIB_DANGER_GET( &pParamTypeDescr, rParam.pTypeRef );
     145             : 
     146             :             void *pCppStack;
     147      146121 :             if ( nr_gpr < x86_64::MAX_GPR_REGS )
     148             :             {
     149      146053 :                 pCppArgs[nPos] = pCppStack = *gpreg++;
     150      146053 :                 nr_gpr++;
     151             :             }
     152             :             else
     153          68 :                 pCppArgs[nPos] = pCppStack = *ovrflw++;
     154             : 
     155      146121 :             if (! rParam.bIn) // is pure out
     156             :             {
     157             :                 // uno out is unconstructed mem!
     158          59 :                 pUnoArgs[nPos] = alloca( pParamTypeDescr->nSize );
     159          59 :                 pTempIndices[nTempIndices] = nPos;
     160             :                 // will be released at reconversion
     161          59 :                 ppTempParamTypeDescr[nTempIndices++] = pParamTypeDescr;
     162             :             }
     163      146062 :             else if ( bridges::cpp_uno::shared::relatesToInterfaceType( pParamTypeDescr ) ) // is in/inout
     164             :             {
     165       57514 :                 uno_copyAndConvertData( pUnoArgs[nPos] = alloca( pParamTypeDescr->nSize ),
     166             :                                         pCppStack, pParamTypeDescr,
     167       86271 :                                         pThis->getBridge()->getCpp2Uno() );
     168       28757 :                 pTempIndices[nTempIndices] = nPos; // has to be reconverted
     169             :                 // will be released at reconversion
     170       28757 :                 ppTempParamTypeDescr[nTempIndices++] = pParamTypeDescr;
     171             :             }
     172             :             else // direct way
     173             :             {
     174      117305 :                 pUnoArgs[nPos] = pCppStack;
     175             :                 // no longer needed
     176      117305 :                 TYPELIB_DANGER_RELEASE( pParamTypeDescr );
     177             :             }
     178             :         }
     179             :     }
     180             : 
     181             :     // ExceptionHolder
     182             :     uno_Any aUnoExc; // Any will be constructed by callee
     183      380246 :     uno_Any * pUnoExc = &aUnoExc;
     184             : 
     185             :     // invoke uno dispatch call
     186      380246 :     (*pThis->getUnoI()->pDispatcher)( pThis->getUnoI(), pMemberTypeDescr, pUnoReturn, pUnoArgs, &pUnoExc );
     187             : 
     188             :     // in case an exception occurred...
     189      380246 :     if ( pUnoExc )
     190             :     {
     191             :         // destruct temporary in/inout params
     192       68711 :         for ( ; nTempIndices--; )
     193             :         {
     194       22783 :             sal_Int32 nIndex = pTempIndices[nTempIndices];
     195             : 
     196       22783 :             if (pParams[nIndex].bIn) // is in/inout => was constructed
     197       22783 :                 uno_destructData( pUnoArgs[nIndex], ppTempParamTypeDescr[nTempIndices], 0 );
     198       22783 :             TYPELIB_DANGER_RELEASE( ppTempParamTypeDescr[nTempIndices] );
     199             :         }
     200       22964 :         if (pReturnTypeDescr)
     201       22962 :             TYPELIB_DANGER_RELEASE( pReturnTypeDescr );
     202             : 
     203       22964 :         CPPU_CURRENT_NAMESPACE::raiseException( &aUnoExc, pThis->getBridge()->getUno2Cpp() ); // has to destruct the any
     204             :         // is here for dummy
     205           0 :         return typelib_TypeClass_VOID;
     206             :     }
     207             :     else // else no exception occurred...
     208             :     {
     209             :         // temporary params
     210      720597 :         for ( ; nTempIndices--; )
     211             :         {
     212        6033 :             sal_Int32 nIndex = pTempIndices[nTempIndices];
     213        6033 :             typelib_TypeDescription * pParamTypeDescr = ppTempParamTypeDescr[nTempIndices];
     214             : 
     215        6033 :             if ( pParams[nIndex].bOut ) // inout/out
     216             :             {
     217             :                 // convert and assign
     218          65 :                 uno_destructData( pCppArgs[nIndex], pParamTypeDescr, cpp_release );
     219         130 :                 uno_copyAndConvertData( pCppArgs[nIndex], pUnoArgs[nIndex], pParamTypeDescr,
     220         195 :                                         pThis->getBridge()->getUno2Cpp() );
     221             :             }
     222             :             // destroy temp uno param
     223        6033 :             uno_destructData( pUnoArgs[nIndex], pParamTypeDescr, 0 );
     224             : 
     225        6033 :             TYPELIB_DANGER_RELEASE( pParamTypeDescr );
     226             :         }
     227             :         // return
     228      357282 :         if ( pCppReturn ) // has complex return
     229             :         {
     230      185350 :             if ( pUnoReturn != pCppReturn ) // needs reconversion
     231             :             {
     232             :                 uno_copyAndConvertData( pCppReturn, pUnoReturn, pReturnTypeDescr,
     233      134353 :                                         pThis->getBridge()->getUno2Cpp() );
     234             :                 // destroy temp uno return
     235      134353 :                 uno_destructData( pUnoReturn, pReturnTypeDescr, 0 );
     236             :             }
     237             :             // complex return ptr is set to return reg
     238      185350 :             *reinterpret_cast<void **>(pRegisterReturn) = pCppReturn;
     239             :         }
     240      357282 :         if ( pReturnTypeDescr )
     241             :         {
     242      357261 :             typelib_TypeClass eRet = (typelib_TypeClass)pReturnTypeDescr->eTypeClass;
     243      357261 :             TYPELIB_DANGER_RELEASE( pReturnTypeDescr );
     244      357261 :             return eRet;
     245             :         }
     246             :         else
     247          21 :             return typelib_TypeClass_VOID;
     248             :     }
     249             : }
     250             : 
     251             : 
     252      929346 : typelib_TypeClass cpp_vtable_call(
     253             :     sal_Int32 nFunctionIndex, sal_Int32 nVtableOffset,
     254             :     void ** gpreg, void ** fpreg, void ** ovrflw,
     255             :     sal_uInt64 * pRegisterReturn /* space for register return */ )
     256             : {
     257             :     // gpreg:  [ret *], this, [other gpr params]
     258             :     // fpreg:  [fpr params]
     259             :     // ovrflw: [gpr or fpr params (properly aligned)]
     260             :     void * pThis;
     261      929346 :     if ( nFunctionIndex & 0x80000000 )
     262             :     {
     263      235671 :         nFunctionIndex &= 0x7fffffff;
     264      235671 :         pThis = gpreg[1];
     265             :     }
     266             :     else
     267             :     {
     268      693675 :         pThis = gpreg[0];
     269             :     }
     270      929346 :     pThis = static_cast<char *>( pThis ) - nVtableOffset;
     271             : 
     272             :     bridges::cpp_uno::shared::CppInterfaceProxy * pCppI =
     273      929346 :         bridges::cpp_uno::shared::CppInterfaceProxy::castInterfaceToProxy( pThis );
     274             : 
     275      929346 :     typelib_InterfaceTypeDescription * pTypeDescr = pCppI->getTypeDescr();
     276             : 
     277      929346 :     if ( nFunctionIndex >= pTypeDescr->nMapFunctionIndexToMemberIndex )
     278             :     {
     279             :         SAL_WARN(
     280             :             "bridges",
     281             :             "illegal " << OUString::unacquired(&pTypeDescr->aBase.pTypeName)
     282             :                 << " vtable index " << nFunctionIndex << "/"
     283             :                 << pTypeDescr->nMapFunctionIndexToMemberIndex);
     284             :         throw RuntimeException(
     285           0 :             ("illegal " + OUString::unacquired(&pTypeDescr->aBase.pTypeName)
     286           0 :              + " vtable index " + OUString::number(nFunctionIndex) + "/"
     287           0 :              + OUString::number(pTypeDescr->nMapFunctionIndexToMemberIndex)),
     288           0 :             reinterpret_cast<XInterface *>( pCppI ) );
     289             :     }
     290             : 
     291             :     // determine called method
     292      929346 :     sal_Int32 nMemberPos = pTypeDescr->pMapFunctionIndexToMemberIndex[nFunctionIndex];
     293             :     assert(nMemberPos < pTypeDescr->nAllMembers);
     294             : 
     295      929346 :     TypeDescription aMemberDescr( pTypeDescr->ppAllMembers[nMemberPos] );
     296             : 
     297             :     typelib_TypeClass eRet;
     298      929346 :     switch ( aMemberDescr.get()->eTypeClass )
     299             :     {
     300             :         case typelib_TypeClass_INTERFACE_ATTRIBUTE:
     301             :         {
     302             :             typelib_TypeDescriptionReference *pAttrTypeRef =
     303        1827 :                 reinterpret_cast<typelib_InterfaceAttributeTypeDescription *>( aMemberDescr.get() )->pAttributeTypeRef;
     304             : 
     305        1827 :             if ( pTypeDescr->pMapMemberIndexToFunctionIndex[nMemberPos] == nFunctionIndex )
     306             :             {
     307             :                 // is GET method
     308        1804 :                 eRet = cpp2uno_call( pCppI, aMemberDescr.get(), pAttrTypeRef,
     309             :                         0, 0, // no params
     310        1804 :                         gpreg, fpreg, ovrflw, pRegisterReturn );
     311             :             }
     312             :             else
     313             :             {
     314             :                 // is SET method
     315             :                 typelib_MethodParameter aParam;
     316          23 :                 aParam.pTypeRef = pAttrTypeRef;
     317          23 :                 aParam.bIn      = sal_True;
     318          23 :                 aParam.bOut     = sal_False;
     319             : 
     320          23 :                 eRet = cpp2uno_call( pCppI, aMemberDescr.get(),
     321             :                         0, // indicates void return
     322             :                         1, &aParam,
     323          23 :                         gpreg, fpreg, ovrflw, pRegisterReturn );
     324             :             }
     325        1822 :             break;
     326             :         }
     327             :         case typelib_TypeClass_INTERFACE_METHOD:
     328             :         {
     329             :             // is METHOD
     330      927519 :             switch ( nFunctionIndex )
     331             :             {
     332             :                 case 1: // acquire()
     333      185392 :                     pCppI->acquireProxy(); // non virtual call!
     334      185392 :                     eRet = typelib_TypeClass_VOID;
     335      185392 :                     break;
     336             :                 case 2: // release()
     337      313388 :                     pCppI->releaseProxy(); // non virtual call!
     338      313388 :                     eRet = typelib_TypeClass_VOID;
     339      313388 :                     break;
     340             :                 case 0: // queryInterface() opt
     341             :                 {
     342      138223 :                     typelib_TypeDescription * pTD = 0;
     343      138223 :                     TYPELIB_DANGER_GET( &pTD, static_cast<Type *>( gpreg[2] )->getTypeLibType() );
     344      138223 :                     if ( pTD )
     345             :                     {
     346      138223 :                         XInterface * pInterface = 0;
     347      138223 :                         (*pCppI->getBridge()->getCppEnv()->getRegisteredInterface)
     348             :                             ( pCppI->getBridge()->getCppEnv(),
     349             :                               reinterpret_cast<void **>(&pInterface),
     350             :                               pCppI->getOid().pData,
     351      138223 :                               reinterpret_cast<typelib_InterfaceTypeDescription *>( pTD ) );
     352             : 
     353      138223 :                         if ( pInterface )
     354             :                         {
     355             :                             ::uno_any_construct( static_cast<uno_Any *>( gpreg[0] ),
     356       50320 :                                                  &pInterface, pTD, cpp_acquire );
     357             : 
     358       50320 :                             pInterface->release();
     359       50320 :                             TYPELIB_DANGER_RELEASE( pTD );
     360             : 
     361       50320 :                             reinterpret_cast<void **>( pRegisterReturn )[0] = gpreg[0];
     362       50320 :                             eRet = typelib_TypeClass_ANY;
     363       50320 :                             break;
     364             :                         }
     365       87903 :                         TYPELIB_DANGER_RELEASE( pTD );
     366             :                     }
     367             :                 } // else perform queryInterface()
     368             :                 default:
     369             :                 {
     370             :                     typelib_InterfaceMethodTypeDescription *pMethodTD =
     371      378419 :                         reinterpret_cast<typelib_InterfaceMethodTypeDescription *>( aMemberDescr.get() );
     372             : 
     373      378419 :                     eRet = cpp2uno_call( pCppI, aMemberDescr.get(),
     374             :                                          pMethodTD->pReturnTypeRef,
     375             :                                          pMethodTD->nParams,
     376             :                                          pMethodTD->pParams,
     377      756838 :                                          gpreg, fpreg, ovrflw, pRegisterReturn );
     378             :                 }
     379             :             }
     380      904560 :             break;
     381             :         }
     382             :         default:
     383             :         {
     384             :             throw RuntimeException("no member description found!",
     385           0 :                                     reinterpret_cast<XInterface *>( pCppI ) );
     386             :         }
     387             :     }
     388             : 
     389      929346 :     return eRet;
     390             : }
     391             : 
     392             : const int codeSnippetSize = 24;
     393             : 
     394             : // Generate a trampoline that redirects method calls to
     395             : // privateSnippetExecutor().
     396             : //
     397             : // privateSnippetExecutor() saves all the registers that are used for
     398             : // parameter passing on x86_64, and calls the cpp_vtable_call().
     399             : // When it returns, privateSnippetExecutor() sets the return value.
     400             : //
     401             : // Note: The code snippet we build here must not create a stack frame,
     402             : // otherwise the UNO exceptions stop working thanks to non-existing
     403             : // unwinding info.
     404        5566 : unsigned char * codeSnippet( unsigned char * code,
     405             :         sal_Int32 nFunctionIndex, sal_Int32 nVtableOffset,
     406             :         bool bHasHiddenParam )
     407             : {
     408        5566 :     sal_uInt64 nOffsetAndIndex = ( ( (sal_uInt64) nVtableOffset ) << 32 ) | ( (sal_uInt64) nFunctionIndex );
     409             : 
     410        5566 :     if ( bHasHiddenParam )
     411        1747 :         nOffsetAndIndex |= 0x80000000;
     412             : 
     413             :     // movq $<nOffsetAndIndex>, %r10
     414        5566 :     *reinterpret_cast<sal_uInt16 *>( code ) = 0xba49;
     415        5566 :     *reinterpret_cast<sal_uInt16 *>( code + 2 ) = nOffsetAndIndex & 0xFFFF;
     416        5566 :     *reinterpret_cast<sal_uInt32 *>( code + 4 ) = nOffsetAndIndex >> 16;
     417        5566 :     *reinterpret_cast<sal_uInt16 *>( code + 8 ) = nOffsetAndIndex >> 48;
     418             : 
     419             :     // movq $<address of the privateSnippetExecutor>, %r11
     420        5566 :     *reinterpret_cast<sal_uInt16 *>( code + 10 ) = 0xbb49;
     421             :     *reinterpret_cast<sal_uInt32 *>( code + 12 )
     422        5566 :         = reinterpret_cast<sal_uInt64>(privateSnippetExecutor);
     423             :     *reinterpret_cast<sal_uInt32 *>( code + 16 )
     424        5566 :         = reinterpret_cast<sal_uInt64>(privateSnippetExecutor) >> 32;
     425             : 
     426             :     // jmpq *%r11
     427        5566 :     *reinterpret_cast<sal_uInt32 *>( code + 20 ) = 0x00e3ff49;
     428             : 
     429             : #if OSL_DEBUG_LEVEL > 1
     430             :     fprintf(stderr,
     431             :             "==> codeSnippet, functionIndex=%d%s, vtableOffset=%d\n",
     432             :             nFunctionIndex, (bHasHiddenParam ? "|0x80000000":""), nVtableOffset);
     433             : #endif
     434             : 
     435        5566 :     return code + codeSnippetSize;
     436             : }
     437             : 
     438             : struct bridges::cpp_uno::shared::VtableFactory::Slot { void * fn; };
     439             : 
     440             : bridges::cpp_uno::shared::VtableFactory::Slot *
     441      134151 : bridges::cpp_uno::shared::VtableFactory::mapBlockToVtable(void * block)
     442             : {
     443      134151 :     return static_cast< Slot * >(block) + 2;
     444             : }
     445             : 
     446         676 : sal_Size bridges::cpp_uno::shared::VtableFactory::getBlockSize(
     447             :     sal_Int32 slotCount)
     448             : {
     449         676 :     return (slotCount + 2) * sizeof (Slot) + slotCount * codeSnippetSize;
     450             : }
     451             : 
     452             : bridges::cpp_uno::shared::VtableFactory::Slot *
     453         676 : bridges::cpp_uno::shared::VtableFactory::initializeBlock(
     454             :     void * block, sal_Int32 slotCount, sal_Int32 vtableNumber,
     455             :     typelib_InterfaceTypeDescription * type)
     456             : {
     457         676 :     Slot * slots = mapBlockToVtable(block);
     458         676 :     slots[-2].fn = reinterpret_cast<void *>(-(vtableNumber * sizeof (void *)));
     459             : #if ENABLE_RUNTIME_OPTIMIZATIONS
     460         676 :     slots[-1].fn = 0;
     461             :     (void)type;
     462             : #else
     463             :     slots[-1].fn = x86_64::getRtti(type->aBase);
     464             : #endif
     465         676 :     return slots + slotCount;
     466             : }
     467             : 
     468             : 
     469             : 
     470        1489 : unsigned char * bridges::cpp_uno::shared::VtableFactory::addLocalFunctions(
     471             :     Slot ** slots, unsigned char * code, sal_PtrDiff writetoexecdiff,
     472             :     typelib_InterfaceTypeDescription const * type, sal_Int32 nFunctionOffset,
     473             :     sal_Int32 functionCount, sal_Int32 nVtableOffset )
     474             : {
     475        1489 :     (*slots) -= functionCount;
     476        1489 :     Slot * s = *slots;
     477        6991 :     for ( sal_Int32 nPos = 0; nPos < type->nMembers; ++nPos )
     478             :     {
     479        5502 :         typelib_TypeDescription * pTD = 0;
     480             : 
     481        5502 :         TYPELIB_DANGER_GET( &pTD, type->ppMembers[ nPos ] );
     482             :         assert(pTD);
     483             : 
     484        5502 :         if ( typelib_TypeClass_INTERFACE_ATTRIBUTE == pTD->eTypeClass )
     485             :         {
     486             :             typelib_InterfaceAttributeTypeDescription *pAttrTD =
     487          95 :                 reinterpret_cast<typelib_InterfaceAttributeTypeDescription *>( pTD );
     488             : 
     489             :             // get method
     490          95 :             (s++)->fn = code + writetoexecdiff;
     491             :             code = codeSnippet( code, nFunctionOffset++, nVtableOffset,
     492          95 :                                 x86_64::return_in_hidden_param( pAttrTD->pAttributeTypeRef ) );
     493             : 
     494          95 :             if ( ! pAttrTD->bReadOnly )
     495             :             {
     496             :                 // set method
     497          64 :                 (s++)->fn = code + writetoexecdiff;
     498          64 :                 code = codeSnippet( code, nFunctionOffset++, nVtableOffset, false );
     499             :             }
     500             :         }
     501        5407 :         else if ( typelib_TypeClass_INTERFACE_METHOD == pTD->eTypeClass )
     502             :         {
     503             :             typelib_InterfaceMethodTypeDescription *pMethodTD =
     504        5407 :                 reinterpret_cast<typelib_InterfaceMethodTypeDescription *>( pTD );
     505             : 
     506        5407 :             (s++)->fn = code + writetoexecdiff;
     507             :             code = codeSnippet( code, nFunctionOffset++, nVtableOffset,
     508        5407 :                                 x86_64::return_in_hidden_param( pMethodTD->pReturnTypeRef ) );
     509             :         }
     510             :         else
     511             :             assert(false);
     512             : 
     513        5502 :         TYPELIB_DANGER_RELEASE( pTD );
     514             :     }
     515        1489 :     return code;
     516             : }
     517             : 
     518         676 : void bridges::cpp_uno::shared::VtableFactory::flushCode(
     519             :     SAL_UNUSED_PARAMETER unsigned char const *,
     520             :     SAL_UNUSED_PARAMETER unsigned char const * )
     521         676 : {}
     522             : 
     523             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.11