24#include <com/sun/star/uno/genfunc.hxx> 
   26#include <typelib/typedescription.hxx> 
   42    typelib_TypeDescriptionReference * pReturnTypeRef, 
 
   43    sal_Int32 nParams, typelib_MethodParameter * pParams,
 
   45    sal_Int64 * pRegisterReturn  )
 
   48    char * pCppStack = (
char *)pCallStack;
 
   53        TYPELIB_DANGER_GET( &pReturnTypeDescr, pReturnTypeRef );
 
   55    void * pUnoReturn = 0;
 
   56    void * pCppReturn = 0; 
 
   61            pUnoReturn = pRegisterReturn; 
 
   64            pCppReturn = *(
void**)pCppStack;
 
   67                          ? alloca( pReturnTypeDescr->nSize )
 
   69            pCppStack += 
sizeof( 
void* );
 
   73    pCppStack += 
sizeof( 
void* );
 
   76    static_assert(
sizeof(
void *) == 
sizeof(sal_Int32), 
"### unexpected size!");
 
   78    void ** pUnoArgs = (
void **)alloca( 4 * 
sizeof(
void *) * nParams );
 
   79    void ** pCppArgs = pUnoArgs + nParams;
 
   81    sal_Int32 * pTempIndices = (sal_Int32 *)(pUnoArgs + (2 * nParams));
 
   85    sal_Int32 nTempIndices   = 0;
 
   87    for ( sal_Int32 nPos = 0; 
nPos < nParams; ++
nPos )
 
   89        const typelib_MethodParameter & rParam = pParams[
nPos];
 
   91        TYPELIB_DANGER_GET( &pParamTypeDescr, rParam.pTypeRef );
 
   96            switch (pParamTypeDescr->eTypeClass)
 
   98            case typelib_TypeClass_HYPER:
 
   99            case typelib_TypeClass_UNSIGNED_HYPER:
 
  100                    case typelib_TypeClass_DOUBLE:
 
  102            if ((
reinterpret_cast< long >(pCppStack) & 7) != 0)
 
  104                   static_assert(
sizeof (double) == 
sizeof (sal_Int64), 
"boo");
 
  105                           void * pDest = alloca( 
sizeof (sal_Int64) );
 
  106                           *
reinterpret_cast< sal_Int32 * 
>(pDest) =
 
  107                           *
reinterpret_cast< sal_Int32 
const * 
>(pCppStack);
 
  108                           *(
reinterpret_cast< sal_Int32 * 
>(pDest) + 1) =
 
  109                           *(
reinterpret_cast< sal_Int32 
const * 
>(pCppStack) + 1);
 
  110                           pCppArgs[
nPos] = pUnoArgs[
nPos] = pDest;
 
  112               pCppStack += 
sizeof (sal_Int32); 
 
  119            TYPELIB_DANGER_RELEASE( pParamTypeDescr );
 
  123            pCppArgs[
nPos] = *(
void **)pCppStack;
 
  128                pUnoArgs[
nPos] = alloca( pParamTypeDescr->nSize );
 
  129                pTempIndices[nTempIndices] = 
nPos;
 
  131                ppTempParamTypeDescr[nTempIndices++] = pParamTypeDescr;
 
  138                                        *(
void **)pCppStack, pParamTypeDescr,
 
  140                pTempIndices[nTempIndices] = 
nPos; 
 
  142                ppTempParamTypeDescr[nTempIndices++] = pParamTypeDescr;
 
  146                pUnoArgs[
nPos] = *(
void **)pCppStack;
 
  148                TYPELIB_DANGER_RELEASE( pParamTypeDescr );
 
  151        pCppStack += 
sizeof(sal_Int32); 
 
  159    (*pThis->
getUnoI()->pDispatcher)(pThis->
getUnoI(), pMemberTypeDescr, pUnoReturn, pUnoArgs, &pUnoExc );
 
  165        for ( ; nTempIndices--; )
 
  167            sal_Int32 
nIndex = pTempIndices[nTempIndices];
 
  169            if (pParams[nIndex].bIn) 
 
  170                uno_destructData( pUnoArgs[nIndex], ppTempParamTypeDescr[nTempIndices], 0 );
 
  171            TYPELIB_DANGER_RELEASE( ppTempParamTypeDescr[nTempIndices] );
 
  173        if (pReturnTypeDescr)
 
  174            TYPELIB_DANGER_RELEASE( pReturnTypeDescr );
 
  178        return typelib_TypeClass_VOID;
 
  183        for ( ; nTempIndices--; )
 
  185            sal_Int32 
nIndex = pTempIndices[nTempIndices];
 
  188            if (pParams[nIndex].bOut) 
 
  198            TYPELIB_DANGER_RELEASE( pParamTypeDescr );
 
  203            if (pUnoReturn != pCppReturn) 
 
  211            *(
void **)pRegisterReturn = pCppReturn;
 
  213        if (pReturnTypeDescr)
 
  215            typelib_TypeClass eRet = (typelib_TypeClass)pReturnTypeDescr->eTypeClass;
 
  216            TYPELIB_DANGER_RELEASE( pReturnTypeDescr );
 
  220            return typelib_TypeClass_VOID;
 
  226    sal_Int32   nFunctionIndex,
 
  227    sal_Int32   nVtableOffset,
 
  229    sal_Int64 * pRegisterReturn  )
 
  231    static_assert(
sizeof(sal_Int32)==
sizeof(
void *), 
"### unexpected!");
 
  241    static_cast< char * 
>(*pCallStack) - nVtableOffset);
 
  242    if ((nFunctionIndex & 0x80000000) != 0) {
 
  243        nFunctionIndex &= 0x7FFFFFFF;
 
  247    typelib_InterfaceTypeDescription * pTypeDescr = pCppI->
getTypeDescr();
 
  249    if (nFunctionIndex >= pTypeDescr->nMapFunctionIndexToMemberIndex)
 
  253            "illegal " << OUString::unacquired(&pTypeDescr->aBase.pTypeName)
 
  254                << 
" vtable index " << nFunctionIndex << 
"/" 
  255                << pTypeDescr->nMapFunctionIndexToMemberIndex);
 
  257            (
"illegal " + OUString::unacquired(&pTypeDescr->aBase.pTypeName)
 
  258             + 
" vtable index " + OUString::number(nFunctionIndex) + 
"/" 
  259             + OUString::number(pTypeDescr->nMapFunctionIndexToMemberIndex)),
 
  264    sal_Int32 nMemberPos = pTypeDescr->pMapFunctionIndexToMemberIndex[nFunctionIndex];
 
  265    assert(nMemberPos < pTypeDescr->nAllMembers);
 
  267    TypeDescription aMemberDescr( pTypeDescr->ppAllMembers[nMemberPos] );
 
  269#if defined BRIDGES_DEBUG 
  270    OString cstr( 
OUStringToOString( aMemberDescr.get()->pTypeName, RTL_TEXTENCODING_ASCII_US ) );
 
  271    fprintf( stderr, 
"calling %s, nFunctionIndex=%d\n", cstr.getStr(), nFunctionIndex );
 
  274    typelib_TypeClass eRet;
 
  275    switch (aMemberDescr.get()->eTypeClass)
 
  277    case typelib_TypeClass_INTERFACE_ATTRIBUTE:
 
  279        if (pTypeDescr->pMapMemberIndexToFunctionIndex[nMemberPos] == nFunctionIndex)
 
  283                pCppI, aMemberDescr.get(),
 
  284                ((typelib_InterfaceAttributeTypeDescription *)aMemberDescr.get())->pAttributeTypeRef,
 
  286                pCallStack, pRegisterReturn );
 
  291            typelib_MethodParameter aParam;
 
  293                ((typelib_InterfaceAttributeTypeDescription *)aMemberDescr.get())->pAttributeTypeRef;
 
  298                pCppI, aMemberDescr.get(),
 
  301                pCallStack, pRegisterReturn );
 
  305    case typelib_TypeClass_INTERFACE_METHOD:
 
  308        switch (nFunctionIndex)
 
  312            eRet = typelib_TypeClass_VOID;
 
  316            eRet = typelib_TypeClass_VOID;
 
  321            TYPELIB_DANGER_GET( &pTD, 
reinterpret_cast< Type * 
>( pCallStack[2] )->getTypeLibType() );
 
  327            (
void **)&pInterface, pCppI->
getOid().pData, (typelib_InterfaceTypeDescription *)pTD );
 
  332                        reinterpret_cast< uno_Any * 
>( pCallStack[0] ),
 
  333                        &pInterface, pTD, cpp_acquire );
 
  334                    pInterface->release();
 
  335                    TYPELIB_DANGER_RELEASE( pTD );
 
  336                    *(
void **)pRegisterReturn = pCallStack[0];
 
  337                    eRet = typelib_TypeClass_ANY;
 
  340                TYPELIB_DANGER_RELEASE( pTD );
 
  345                pCppI, aMemberDescr.get(),
 
  346                ((typelib_InterfaceMethodTypeDescription *)aMemberDescr.get())->pReturnTypeRef,
 
  347                ((typelib_InterfaceMethodTypeDescription *)aMemberDescr.get())->nParams,
 
  348                ((typelib_InterfaceMethodTypeDescription *)aMemberDescr.get())->pParams,
 
  349                pCallStack, pRegisterReturn );
 
  368    sal_Int64 nRegReturn;
 
  373void * pRegReturn = &nRegReturn;
 
  378            : : 
"m"(nFunctionIndex), 
"m"(pCallStack), 
"m"(vTableOffset) );
 
  383    const sal_Bool bComplex = (nFunctionIndex & 0x80000000) ? sal_True : sal_False;
 
  384    typelib_TypeClass aType =
 
  385        cpp_mediate( nFunctionIndex, vTableOffset, pCallStack+17, (sal_Int64*)&nRegReturn );
 
  389        case typelib_TypeClass_BOOLEAN:
 
  390        case typelib_TypeClass_BYTE:
 
  392                     "ldsb [%%l0], %%i0\n" 
  393                     : : 
"m"(pRegReturn) );
 
  395        case typelib_TypeClass_CHAR:
 
  396        case typelib_TypeClass_SHORT:
 
  397        case typelib_TypeClass_UNSIGNED_SHORT:
 
  399                     "ldsh [%%l0], %%i0\n" 
  400                     : : 
"m"(pRegReturn) );
 
  402        case typelib_TypeClass_HYPER:
 
  403        case typelib_TypeClass_UNSIGNED_HYPER:
 
  405                     "ld [%%l0], %%i0\n\t" 
  406                     "add %%l0, 4, %%l0\n\t" 
  407                     "ld [%%l0], %%i1\n\t" 
  408                      : : 
"m"(pRegReturn) );
 
  411        case typelib_TypeClass_FLOAT:
 
  414                     : : 
"m"(pRegReturn) );
 
  416        case typelib_TypeClass_DOUBLE:
 
  419                     : : 
"m"(pRegReturn) );
 
  421        case typelib_TypeClass_VOID:
 
  426                     : : 
"m"(pRegReturn) );
 
  432        __asm__( 
"add %i7, 4, %i7\n\t" );
 
  441    unsigned char * code, sal_Int32 functionIndex, sal_Int32 vtableOffset,
 
  444    sal_uInt32 
index = functionIndex;
 
  445    if (!simpleRetType) {
 
  448    unsigned int * 
p = 
reinterpret_cast< unsigned int * 
>(
code);
 
  449    static_assert(
sizeof (
unsigned int) == 4, 
"boo");
 
  463    *
p++ = 0x11000000 | (
index >> 10);
 
  465    *
p++ = 0x90122000 | (
index & 0x3FF);
 
  467    *
p++ = 0x15000000 | (vtableOffset >> 10);
 
  469    *
p++ = 0x9412A000 | (vtableOffset & 0x3FF);
 
  471    *
p++ = 0x17000000 | (
reinterpret_cast< unsigned int >(
cpp_vtable_call) >> 10);
 
  473    *
p++ = 0x9612E000 | (
reinterpret_cast< unsigned int >(
cpp_vtable_call) & 0x3FF);
 
  489    return static_cast< Slot * 
>(block) + 2;
 
  506    void * block, sal_Int32 slotCount, sal_Int32,
 
  507    typelib_InterfaceTypeDescription *)
 
  509    Slot * slots = mapBlockToVtable(block);
 
  511    slots[-1].fn = &
typeid(ProxyRtti);
 
  512    return slots + slotCount;
 
  516    Slot ** slots, 
unsigned char * code, sal_PtrDiff writetoexecdiff,
 
  517    typelib_InterfaceTypeDescription 
const * type, sal_Int32 functionOffset,
 
  518    sal_Int32 functionCount, sal_Int32 vTableOffset)
 
  520    (*slots) -= functionCount;
 
  522    for (sal_Int32 i = 0; 
i < 
type->nMembers; ++
i) {
 
  524        TYPELIB_DANGER_GET(&member, 
type->ppMembers[i]);
 
  526        switch (member->eTypeClass) {
 
  527        case typelib_TypeClass_INTERFACE_ATTRIBUTE:
 
  529            (s++)->fn = code + writetoexecdiff;
 
  531                code, functionOffset++, vTableOffset,
 
  534            typelib_InterfaceAttributeTypeDescription * 
>(
 
  535            member)->pAttributeTypeRef));
 
  537            if (!
reinterpret_cast< 
  538                typelib_InterfaceAttributeTypeDescription * 
>(
 
  541                (s++)->fn = code + writetoexecdiff;
 
  546        case typelib_TypeClass_INTERFACE_METHOD:
 
  547            (s++)->fn = code + writetoexecdiff;
 
  549                code, functionOffset++, vTableOffset,
 
  552                    typelib_InterfaceMethodTypeDescription * 
>(
 
  553                        member)->pReturnTypeRef));
 
  560        TYPELIB_DANGER_RELEASE(member);
 
  567extern "C" void doFlushCode(
unsigned long address, 
unsigned long count);
 
  570    unsigned char const * begin, 
unsigned char const * end)
 
  574        unsigned long adr = 
reinterpret_cast< unsigned long >(
begin);
 
  575        unsigned long off = adr & 7;
 
uno_Mapping * getUno2Cpp()
 
uno_ExtEnvironment * getCppEnv()
 
uno_Mapping * getCpp2Uno()
 
A cpp proxy wrapping a uno interface.
 
uno_Interface * getUnoI()
 
static CppInterfaceProxy * castInterfaceToProxy(void *pInterface)
 
typelib_InterfaceTypeDescription * getTypeDescr()
 
const OUString & getOid() const
 
static Slot * mapBlockToVtable(void *block)
Given a pointer to a block, turn it into a vtable pointer.
 
static void flushCode(unsigned char const *begin, unsigned char const *end)
Flush all the generated code snippets of a vtable, on platforms that require it.
 
static unsigned char * addLocalFunctions(Slot **slots, unsigned char *code, sal_PtrDiff writetoexecdiff, typelib_InterfaceTypeDescription const *type, sal_Int32 functionOffset, sal_Int32 functionCount, sal_Int32 vtableOffset)
Fill the vtable slots corresponding to all local (i.e., not inherited) functions of a given interface...
 
static Slot * initializeBlock(void *block, sal_Int32 slotCount, sal_Int32 vtableNumber, typelib_InterfaceTypeDescription *type)
Initialize a raw vtable block.
 
static std::size_t getBlockSize(sal_Int32 slotCount)
Calculate the size of a raw vtable block.
 
void SAL_CALL uno_destructData(void *pValue, typelib_TypeDescription *pTypeDescr, uno_ReleaseFunc release) SAL_THROW_EXTERN_C()
 
void SAL_CALL uno_copyAndConvertData(void *pDest, void *pSource, typelib_TypeDescription *pTypeDescr, uno_Mapping *mapping) SAL_THROW_EXTERN_C()
 
void cpp_vtable_call(sal_Int32 func, sal_Int32 offset, void **pStack)
is called on incoming vtable calls (called by asm snippets)
 
register sal_uInt32 r28 __asm__("%r28")
 
void doFlushCode(unsigned long address, unsigned long count)
 
const int codeSnippetSize
 
static unsigned char * codeSnippet(unsigned char *code, sal_Int32 nFunctionIndex, sal_Int32 nVtableOffset, bool bHasHiddenParam)
 
static int cpp2uno_call(bridges::cpp_uno::shared::CppInterfaceProxy *pThis, const typelib_TypeDescription *pMemberTypeDescr, typelib_TypeDescriptionReference *pReturnTypeRef, sal_Int32 nParams, typelib_MethodParameter *pParams, void **gpreg, void **fpreg, void **ovrflw, sal_uInt64 *pRegisterReturn)
 
#define SAL_WARN(area, stream)
 
struct _typelib_TypeDescription typelib_TypeDescription
 
typelib_TypeClass __cdecl cpp_mediate(void **pCallStack, const sal_Int32 nFunctionIndex, const sal_Int32 nVtableOffset, sal_Int64 *const pRegisterReturn)
 
char * adjustPointer(char *pIn, typelib_TypeDescription *pType)
 
void raiseException(uno_Any *pUnoExc, uno_Mapping *pUno2Cpp)
 
bool isSimpleType(typelib_TypeClass typeClass)
Determines whether a type is a "simple" type (VOID, BOOLEAN, BYTE, SHORT, UNSIGNED SHORT,...
 
bool relatesToInterfaceType(typelib_TypeDescription const *type)
Determines whether a type relates to an interface type (is itself an interface type,...
 
enumrange< T >::Iterator begin(enumrange< T >)
 
OString OUStringToOString(std::u16string_view str, ConnectionSettings const *settings)
 
const wchar_t *typedef int(__stdcall *DllNativeUnregProc)(int