26#include <com/sun/star/uno/genfunc.hxx> 
   27#include "com/sun/star/uno/RuntimeException.hpp" 
   29#include <typelib/typedescription.hxx> 
   50        typelib_TypeDescriptionReference * pReturnTypeRef,
 
   51        sal_Int32 nParams, typelib_MethodParameter * pParams,
 
   52        long r8, 
void ** pCallStack,
 
   53        sal_Int64 * pRegisterReturn  )
 
   56        char * pTopStack = (
char *)(pCallStack + 0);
 
   57        char * pCppStack = pTopStack;
 
   58#if OSL_DEBUG_LEVEL > 2 
   59    fprintf(stderr, 
"cpp2uno_call\n");
 
   64            TYPELIB_DANGER_GET( &pReturnTypeDescr, pReturnTypeRef );
 
   66        void * pUnoReturn = 0;
 
   68        void * pCppReturn = 0;
 
   74#if OSL_DEBUG_LEVEL > 2 
   75        fprintf(stderr, 
"simple return\n");
 
   77                pUnoReturn = pRegisterReturn; 
 
   81#if OSL_DEBUG_LEVEL > 2 
   82        fprintf(stderr, 
"complex return\n");
 
   84                pCppReturn = (
void *)r8;
 
   87                    ? alloca( pReturnTypeDescr->nSize )
 
   92        pCppStack += 
sizeof( 
void* );
 
   95        static_assert( 
sizeof(
void *) == 
sizeof(sal_Int32),
 
   96            "### unexpected size!" );
 
   98        void ** pUnoArgs = (
void **)alloca( 4 * 
sizeof(
void *) * nParams );
 
   99        void ** pCppArgs = pUnoArgs + nParams;
 
  102        sal_Int32 * pTempIndices = (sal_Int32 *)(pUnoArgs + (2 * nParams));
 
  107        sal_Int32 nTempIndices   = 0;
 
  109        for ( sal_Int32 nPos = 0; 
nPos < nParams; ++
nPos )
 
  111            const typelib_MethodParameter & rParam = pParams[
nPos];
 
  113            TYPELIB_DANGER_GET( &pParamTypeDescr, rParam.pTypeRef );
 
  118                switch (pParamTypeDescr->eTypeClass)
 
  120                    case typelib_TypeClass_BYTE:
 
  121                    case typelib_TypeClass_BOOLEAN:
 
  122                        pCppArgs[
nPos] = pCppStack + 3;
 
  123                        pUnoArgs[
nPos] = pCppStack + 3;
 
  125                    case typelib_TypeClass_CHAR:
 
  126                    case typelib_TypeClass_SHORT:
 
  127                    case typelib_TypeClass_UNSIGNED_SHORT:
 
  128                        pCppArgs[
nPos] = pCppStack + 2;
 
  129                        pUnoArgs[
nPos] = pCppStack + 2;
 
  131                    case typelib_TypeClass_HYPER:
 
  132                    case typelib_TypeClass_UNSIGNED_HYPER:
 
  133                    case typelib_TypeClass_DOUBLE:
 
  134                        pCppArgs[
nPos] = pCppStack;
 
  135                        pUnoArgs[
nPos] = pCppStack;
 
  136                        pCppStack += 
sizeof(sal_Int32); 
 
  139                        pCppArgs[
nPos] = pCppStack;
 
  140                        pUnoArgs[
nPos] = pCppStack;
 
  144                TYPELIB_DANGER_RELEASE( pParamTypeDescr );
 
  148                pCppArgs[
nPos] = *(
void **)pCppStack;
 
  153                    pUnoArgs[
nPos] = alloca( pParamTypeDescr->nSize );
 
  154                    pTempIndices[nTempIndices] = 
nPos;
 
  156                    ppTempParamTypeDescr[nTempIndices++] = pParamTypeDescr;
 
  163                        *(
void **)pCppStack, pParamTypeDescr,
 
  165                    pTempIndices[nTempIndices] = 
nPos; 
 
  167                    ppTempParamTypeDescr[nTempIndices++] = pParamTypeDescr;
 
  171                    pUnoArgs[
nPos] = *(
void **)pCppStack;
 
  173                    TYPELIB_DANGER_RELEASE( pParamTypeDescr );
 
  176            pCppStack += 
sizeof(sal_Int32); 
 
  183#if OSL_DEBUG_LEVEL > 2 
  184    fprintf(stderr, 
"before dispatch\n");
 
  187        (*pThis->
getUnoI()->pDispatcher)(
 
  188          pThis->
getUnoI(), pMemberTypeDescr, pUnoReturn, pUnoArgs, &pUnoExc );
 
  190#if OSL_DEBUG_LEVEL > 2 
  191    fprintf(stderr, 
"after dispatch\n");
 
  198            for ( ; nTempIndices--; )
 
  200                sal_Int32 
nIndex = pTempIndices[nTempIndices];
 
  202                if (pParams[nIndex].bIn) 
 
  204                        ppTempParamTypeDescr[nTempIndices], 0 );
 
  205                TYPELIB_DANGER_RELEASE( ppTempParamTypeDescr[nTempIndices] );
 
  207            if (pReturnTypeDescr)
 
  208                TYPELIB_DANGER_RELEASE( pReturnTypeDescr );
 
  213            return typelib_TypeClass_VOID;
 
  218            for ( ; nTempIndices--; )
 
  220                sal_Int32 
nIndex = pTempIndices[nTempIndices];
 
  222                    ppTempParamTypeDescr[nTempIndices];
 
  224                if (pParams[nIndex].bOut) 
 
  235                TYPELIB_DANGER_RELEASE( pParamTypeDescr );
 
  240                if (pUnoReturn != pCppReturn) 
 
  248                *(
void **)pRegisterReturn = pCppReturn;
 
  250            if (pReturnTypeDescr)
 
  252                typelib_TypeClass eRet =
 
  253                    (typelib_TypeClass)pReturnTypeDescr->eTypeClass;
 
  254                TYPELIB_DANGER_RELEASE( pReturnTypeDescr );
 
  258                return typelib_TypeClass_VOID;
 
  264        sal_Int32 nFunctionIndex, sal_Int32 nVtableOffset,
 
  266        sal_Int64 * pRegisterReturn  )
 
  268    void ** pCallStack = (
void**)(sp);
 
  269#if OSL_DEBUG_LEVEL > 2 
  270    fprintf(stderr, 
"cpp_mediate with\n");
 
  271    fprintf(stderr, 
"%x %x\n", nFunctionIndex, nVtableOffset);
 
  272    fprintf(stderr, 
"and %x %x\n", pCallStack, pRegisterReturn);
 
  273    fprintf(stderr, 
"and %x %x\n", pCallStack[0], pCallStack[1]);
 
  275        static_assert( 
sizeof(sal_Int32)==
sizeof(
void *), 
"### unexpected!" );
 
  277        void *pThis = pCallStack[0];
 
  279        pThis = 
static_cast< char * 
>(pThis) - nVtableOffset;
 
  285        typelib_InterfaceTypeDescription * pTypeDescr = pCppI->
getTypeDescr();
 
  287        if (nFunctionIndex >= pTypeDescr->nMapFunctionIndexToMemberIndex)
 
  291                "illegal " << OUString::unacquired(&pTypeDescr->aBase.pTypeName)
 
  292                    << 
" vtable index " << nFunctionIndex << 
"/" 
  293                    << pTypeDescr->nMapFunctionIndexToMemberIndex);
 
  295                (
"illegal " + OUString::unacquired(&pTypeDescr->aBase.pTypeName)
 
  296                 + 
" vtable index " + OUString::number(nFunctionIndex) + 
"/" 
  297                 + OUString::number(pTypeDescr->nMapFunctionIndexToMemberIndex)),
 
  302        assert(nFunctionIndex < pTypeDescr->nMapFunctionIndexToMemberIndex);
 
  303        sal_Int32 nMemberPos =
 
  304            pTypeDescr->pMapFunctionIndexToMemberIndex[nFunctionIndex];
 
  305        assert(nMemberPos < pTypeDescr->nAllMembers);
 
  307        TypeDescription aMemberDescr( pTypeDescr->ppAllMembers[nMemberPos] );
 
  309        typelib_TypeClass eRet;
 
  310        switch (aMemberDescr.get()->eTypeClass)
 
  312        case typelib_TypeClass_INTERFACE_ATTRIBUTE:
 
  314            if (pTypeDescr->pMapMemberIndexToFunctionIndex[nMemberPos] ==
 
  319                    pCppI, aMemberDescr.get(),
 
  320                    ((typelib_InterfaceAttributeTypeDescription *)aMemberDescr.get())->pAttributeTypeRef,
 
  322                    r8, pCallStack, pRegisterReturn );
 
  327                typelib_MethodParameter aParam;
 
  329                    ((typelib_InterfaceAttributeTypeDescription *)aMemberDescr.get())->pAttributeTypeRef;
 
  334                    pCppI, aMemberDescr.get(),
 
  337                    r8, pCallStack, pRegisterReturn );
 
  341        case typelib_TypeClass_INTERFACE_METHOD:
 
  344            switch (nFunctionIndex)
 
  348                eRet = typelib_TypeClass_VOID;
 
  352                eRet = typelib_TypeClass_VOID;
 
  357                TYPELIB_DANGER_GET(&pTD,
 
  358                    reinterpret_cast<Type *
>(pCallStack[1])->getTypeLibType());
 
  364                        (
void **)&pInterface, pCppI->
getOid().pData,
 
  365                        (typelib_InterfaceTypeDescription *)pTD );
 
  370                            reinterpret_cast< uno_Any * 
>( r8 ),
 
  371                            &pInterface, pTD, cpp_acquire );
 
  372                        pInterface->release();
 
  373                        TYPELIB_DANGER_RELEASE( pTD );
 
  374                        *(
void **)pRegisterReturn = (
void*)r8;
 
  375                        eRet = typelib_TypeClass_ANY;
 
  378                    TYPELIB_DANGER_RELEASE( pTD );
 
  383                    pCppI, aMemberDescr.get(),
 
  384                    ((typelib_InterfaceMethodTypeDescription *)aMemberDescr.get())->pReturnTypeRef,
 
  385                    ((typelib_InterfaceMethodTypeDescription *)aMemberDescr.get())->nParams,
 
  386                    ((typelib_InterfaceMethodTypeDescription *)aMemberDescr.get())->pParams,
 
  387                    r8, pCallStack, pRegisterReturn );
 
  408    register long d0 
asm(
"d0");
 
  409    long functionIndex = d0;
 
  411    register long a1 
asm(
"a1");
 
  414    register long d1 
asm(
"d1");
 
  415    long vtableOffset = d1;
 
  417    long sp = (long)&firstonstack;
 
  419    sal_Int64 nRegReturn;
 
  420    cpp_mediate( functionIndex, vtableOffset, sp, r8, &nRegReturn );
 
  430    unsigned char *
codeSnippet(
unsigned char* code, sal_Int32 functionIndex,
 
  431        sal_Int32 vtableOffset)
 
  433        unsigned char * 
p = 
code;
 
  434        *(
short *)&
p[0] = 0x203C;       
 
  435        *(
long *)&
p[2] = functionIndex;
 
  436        *(
short *)&
p[6] = 0x223C;       
 
  437        *(
long *)&
p[8] = vtableOffset;
 
  438        *(
short *)&
p[12] = 0x4EF9;      
 
  440        *(
short *)&
p[18] = 0x4E71;      
 
  450    return static_cast< Slot * 
>(block) + 2;
 
  467    void * block, sal_Int32 slotCount, sal_Int32,
 
  468    typelib_InterfaceTypeDescription *)
 
  470    Slot * slots = mapBlockToVtable(block);
 
  472    slots[-1].fn = &
typeid(ProxyRtti);
 
  473    return slots + slotCount;
 
  477    Slot ** slots, 
unsigned char * code, sal_PtrDiff writetoexecdiff,
 
  478    typelib_InterfaceTypeDescription 
const * type, sal_Int32 functionOffset,
 
  479    sal_Int32 functionCount, sal_Int32 vtableOffset)
 
  481    (*slots) -= functionCount;
 
  483    for (sal_Int32 i = 0; 
i < 
type->nMembers; ++
i)
 
  486        TYPELIB_DANGER_GET(&member, 
type->ppMembers[i]);
 
  488        switch (member->eTypeClass)
 
  490            case typelib_TypeClass_INTERFACE_ATTRIBUTE:
 
  492                (s++)->fn = code + writetoexecdiff;
 
  495                if (!
reinterpret_cast< 
  496                    typelib_InterfaceAttributeTypeDescription * 
>(
 
  499                    (s++)->fn = code + writetoexecdiff;
 
  503            case typelib_TypeClass_INTERFACE_METHOD:
 
  505                (s++)->fn = code + writetoexecdiff;
 
  507                typelib_InterfaceMethodTypeDescription *pMethodTD =
 
  509                        typelib_InterfaceMethodTypeDescription * 
>(member);
 
  518        TYPELIB_DANGER_RELEASE(member);
 
  524    unsigned char const * , 
unsigned char const * )
 
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()
 
sal_Int64 cpp_vtable_call(long firstonstack)
is called on incoming vtable calls (called by asm snippets)
 
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)
 
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,...