21#include <com/sun/star/uno/genfunc.hxx> 
   24#include <typelib/typedescription.hxx> 
   47    typelib_TypeDescriptionReference * pReturnTypeRef, 
 
   48    sal_Int32 nParams, typelib_MethodParameter * pParams,
 
   49        void ** gpreg, 
void ** fpreg, 
void ** ovrflw,
 
   50    sal_Int64 * pRegisterReturn  )
 
   52#if OSL_DEBUG_LEVEL > 2 
   53    fprintf(stderr, 
"as far as cpp2uno_call\n");
 
   64        TYPELIB_DANGER_GET( &pReturnTypeDescr, pReturnTypeRef );
 
   66    void * pUnoReturn = 0;
 
   67    void * pCppReturn = 0; 
 
   73            pUnoReturn = pRegisterReturn; 
 
   77            pCppReturn = *(
void **)gpreg;
 
   83                          ? alloca( pReturnTypeDescr->nSize )
 
   93    static_assert(
sizeof(
void *) == 
sizeof(sal_Int64), 
"### unexpected size!");
 
   95    void ** pUnoArgs = (
void **)alloca( 4 * 
sizeof(
void *) * nParams );
 
   96    void ** pCppArgs = pUnoArgs + nParams;
 
   98    sal_Int32 * pTempIndices = (sal_Int32 *)(pUnoArgs + (2 * nParams));
 
  102    sal_Int32 nTempIndices   = 0;
 
  103    for ( sal_Int32 nPos = 0; 
nPos < nParams; ++
nPos )
 
  105        const typelib_MethodParameter & rParam = pParams[
nPos];
 
  107        TYPELIB_DANGER_GET( &pParamTypeDescr, rParam.pTypeRef );
 
  109#if OSL_DEBUG_LEVEL > 2 
  110        fprintf(stderr, 
"arg %d of %d\n", nPos, nParams);
 
  115#if OSL_DEBUG_LEVEL > 2 
  116            fprintf(stderr, 
"simple type is %d\n", pParamTypeDescr->eTypeClass);
 
  119            switch (pParamTypeDescr->eTypeClass)
 
  121                case typelib_TypeClass_FLOAT:
 
  122                case typelib_TypeClass_DOUBLE:
 
  125                        if (pParamTypeDescr->eTypeClass == typelib_TypeClass_FLOAT)
 
  127                            float tmp = (float) (*((
double *)fpreg));
 
  128                            (*((
float *) fpreg)) = tmp;
 
  131                        pCppArgs[
nPos] = pUnoArgs[
nPos] = fpreg;
 
  138                        pCppArgs[
nPos] = pUnoArgs[
nPos] = ovrflw;
 
  142                case typelib_TypeClass_BYTE:
 
  143                case typelib_TypeClass_BOOLEAN:
 
  146                        pCppArgs[
nPos] = pUnoArgs[
nPos] = gpreg;
 
  153                        pCppArgs[
nPos] = pUnoArgs[
nPos] = ovrflw;
 
  157                case typelib_TypeClass_CHAR:
 
  158                case typelib_TypeClass_SHORT:
 
  159                case typelib_TypeClass_UNSIGNED_SHORT:
 
  162                        pCppArgs[
nPos] = pUnoArgs[
nPos] = gpreg;
 
  169                        pCppArgs[
nPos] = pUnoArgs[
nPos] = ovrflw;
 
  173                case typelib_TypeClass_ENUM:
 
  174                case typelib_TypeClass_LONG:
 
  175                case typelib_TypeClass_UNSIGNED_LONG:
 
  178                        pCppArgs[
nPos] = pUnoArgs[
nPos] = gpreg;
 
  185                        pCppArgs[
nPos] = pUnoArgs[
nPos] = ovrflw;
 
  192                        pCppArgs[
nPos] = pUnoArgs[
nPos] = gpreg;
 
  199                        pCppArgs[
nPos] = pUnoArgs[
nPos] = ovrflw;
 
  206            TYPELIB_DANGER_RELEASE( pParamTypeDescr );
 
  210#if OSL_DEBUG_LEVEL > 2 
  211            fprintf(stderr, 
"complex, nregs is %d\n", nregs);
 
  218                pCppArgs[
nPos] = pCppStack = *gpreg;
 
  225                pCppArgs[
nPos] = pCppStack = *ovrflw;
 
  232                pUnoArgs[
nPos] = alloca( pParamTypeDescr->nSize );
 
  233                pTempIndices[nTempIndices] = 
nPos;
 
  235                ppTempParamTypeDescr[nTempIndices++] = pParamTypeDescr;
 
  241                                        pCppStack, pParamTypeDescr,
 
  243                pTempIndices[nTempIndices] = 
nPos; 
 
  245                ppTempParamTypeDescr[nTempIndices++] = pParamTypeDescr;
 
  249                pUnoArgs[
nPos] = pCppStack;
 
  251                TYPELIB_DANGER_RELEASE( pParamTypeDescr );
 
  256#if OSL_DEBUG_LEVEL > 2 
  257    fprintf(stderr, 
"end of params\n");
 
  265    (*pThis->
getUnoI()->pDispatcher)( pThis->
getUnoI(), pMemberTypeDescr, pUnoReturn, pUnoArgs, &pUnoExc );
 
  271        for ( ; nTempIndices--; )
 
  273            sal_Int32 
nIndex = pTempIndices[nTempIndices];
 
  275            if (pParams[nIndex].bIn) 
 
  276                uno_destructData( pUnoArgs[nIndex], ppTempParamTypeDescr[nTempIndices], 0 );
 
  277            TYPELIB_DANGER_RELEASE( ppTempParamTypeDescr[nTempIndices] );
 
  279        if (pReturnTypeDescr)
 
  280            TYPELIB_DANGER_RELEASE( pReturnTypeDescr );
 
  284        return typelib_TypeClass_VOID;
 
  289        for ( ; nTempIndices--; )
 
  291            sal_Int32 
nIndex = pTempIndices[nTempIndices];
 
  294            if (pParams[nIndex].bOut) 
 
  304            TYPELIB_DANGER_RELEASE( pParamTypeDescr );
 
  309            if (pUnoReturn != pCppReturn) 
 
  317            *(
void **)pRegisterReturn = pCppReturn;
 
  319        if (pReturnTypeDescr)
 
  321            typelib_TypeClass eRet = (typelib_TypeClass)pReturnTypeDescr->eTypeClass;
 
  322            TYPELIB_DANGER_RELEASE( pReturnTypeDescr );
 
  326            return typelib_TypeClass_VOID;
 
  332    sal_uInt64 nOffsetAndIndex,
 
  333    void ** gpreg, 
void ** fpreg, 
void ** ovrflw,
 
  334    sal_Int64 * pRegisterReturn  )
 
  336    static_assert(
sizeof(sal_Int64)==
sizeof(
void *), 
"### unexpected!");
 
  338    sal_Int32 nVtableOffset = (nOffsetAndIndex >> 32);
 
  339    sal_Int32 nFunctionIndex = (nOffsetAndIndex & 0xFFFFFFFF);
 
  341#if OSL_DEBUG_LEVEL > 2 
  342    fprintf(stderr, 
"nVTableOffset, nFunctionIndex are %x %x\n", nVtableOffset, nFunctionIndex);
 
  345#if OSL_DEBUG_LEVEL > 2 
  348            fprintf( stderr, 
"= cpp_mediate () =\nGPR's (%d): ", 6 );
 
  349            for ( 
unsigned int i = 0; 
i < 6; ++
i )
 
  350                fprintf( stderr, 
"0x%lx, ", gpreg[i] );
 
  351            fprintf( stderr, 
"\n");
 
  352            fprintf( stderr, 
"\nFPR's (%d): ", 6 );
 
  353            for ( 
unsigned int i = 0; 
i < 6; ++
i )
 
  354                fprintf( stderr, 
"0x%lx (%f), ", fpreg[i], fpreg[i] );
 
  355            fprintf( stderr, 
"\n");
 
  366    if( nFunctionIndex & 0x80000000 )
 
  368        nFunctionIndex &= 0x7fffffff;
 
  376    pThis = 
static_cast< char * 
>(pThis) - nVtableOffset;
 
  382    typelib_InterfaceTypeDescription * pTypeDescr = pCppI->
getTypeDescr();
 
  385    if (nFunctionIndex >= pTypeDescr->nMapFunctionIndexToMemberIndex)
 
  389            "illegal " << OUString::unacquired(&pTypeDescr->aBase.pTypeName)
 
  390                << 
" vtable index " << nFunctionIndex << 
"/" 
  391                << pTypeDescr->nMapFunctionIndexToMemberIndex);
 
  393            (
"illegal " + OUString::unacquired(&pTypeDescr->aBase.pTypeName)
 
  394             + 
" vtable index " + OUString::number(nFunctionIndex) + 
"/" 
  395             + OUString::number(pTypeDescr->nMapFunctionIndexToMemberIndex)),
 
  400    assert(nVtableCall < pTypeDescr->nMapFunctionIndexToMemberIndex);
 
  401    sal_Int32 nMemberPos = pTypeDescr->pMapFunctionIndexToMemberIndex[nFunctionIndex];
 
  402    assert(nMemberPos < pTypeDescr->nAllMembers);
 
  404    TypeDescription aMemberDescr( pTypeDescr->ppAllMembers[nMemberPos] );
 
  406    typelib_TypeClass eRet;
 
  407    switch (aMemberDescr.get()->eTypeClass)
 
  409    case typelib_TypeClass_INTERFACE_ATTRIBUTE:
 
  411        if (pTypeDescr->pMapMemberIndexToFunctionIndex[nMemberPos] == nFunctionIndex)
 
  415                pCppI, aMemberDescr.get(),
 
  416                ((typelib_InterfaceAttributeTypeDescription *)aMemberDescr.get())->pAttributeTypeRef,
 
  418                gpreg, fpreg, ovrflw, pRegisterReturn );
 
  423            typelib_MethodParameter aParam;
 
  425                ((typelib_InterfaceAttributeTypeDescription *)aMemberDescr.get())->pAttributeTypeRef;
 
  430                pCppI, aMemberDescr.get(),
 
  433                gpreg, fpreg, ovrflw, pRegisterReturn );
 
  437    case typelib_TypeClass_INTERFACE_METHOD:
 
  440        switch (nFunctionIndex)
 
  444            eRet = typelib_TypeClass_VOID;
 
  448            eRet = typelib_TypeClass_VOID;
 
  453            TYPELIB_DANGER_GET( &pTD, 
reinterpret_cast< Type * 
>( gpreg[2] )->getTypeLibType() );
 
  459                    (
void **)&pInterface, pCppI->
getOid().pData,
 
  460                    (typelib_InterfaceTypeDescription *)pTD );
 
  465                        reinterpret_cast< uno_Any * 
>( gpreg[0] ),
 
  466                        &pInterface, pTD, cpp_acquire );
 
  467                    pInterface->release();
 
  468                    TYPELIB_DANGER_RELEASE( pTD );
 
  469                    *(
void **)pRegisterReturn = gpreg[0];
 
  470                    eRet = typelib_TypeClass_ANY;
 
  473                TYPELIB_DANGER_RELEASE( pTD );
 
  478                pCppI, aMemberDescr.get(),
 
  479                ((typelib_InterfaceMethodTypeDescription *)aMemberDescr.get())->pReturnTypeRef,
 
  480                ((typelib_InterfaceMethodTypeDescription *)aMemberDescr.get())->nParams,
 
  481                ((typelib_InterfaceMethodTypeDescription *)aMemberDescr.get())->pParams,
 
  482                gpreg, fpreg, ovrflw, pRegisterReturn );
 
  495long cpp_vtable_call(
long r16, 
long r17, 
long r18, 
long r19, 
long r20, 
long r21, 
long firstonstack)
 
  497    register long r1 
asm(
"$1");
 
  498    sal_uInt64 nOffsetAndIndex = r1;
 
  500    long sp = (long)&firstonstack;
 
  511    register double f16  
asm(
"$f16");  fpreg[0] = f16;
 
  512    register double f17  
asm(
"$f17");  fpreg[1] = f17;
 
  513    register double f18  
asm(
"$f18");  fpreg[2] = f18;
 
  514    register double f19  
asm(
"$f19");  fpreg[3] = f19;
 
  515    register double f20  
asm(
"$f20");  fpreg[4] = f20;
 
  516    register double f21  
asm(
"$f21");  fpreg[5] = f21;
 
  518    volatile long nRegReturn[1];
 
  519#if OSL_DEBUG_LEVEL > 2 
  520    fprintf(stderr, 
"before mediate with %lx\n",nOffsetAndIndex);
 
  521    fprintf(stderr, 
"non-doubles are %x %x %x %x %x %x\n", gpreg[0], gpreg[1], gpreg[2], gpreg[3], gpreg[4], gpreg[5]);
 
  522    fprintf(stderr, 
"doubles are %f %f %f %f %f %f\n", fpreg[0], fpreg[1], fpreg[2], fpreg[3], fpreg[4], fpreg[5]);
 
  524    typelib_TypeClass aType =
 
  525        cpp_mediate( nOffsetAndIndex, (
void**)gpreg, (
void**)fpreg, (
void**)sp,
 
  526            (sal_Int64*)nRegReturn );
 
  527#if OSL_DEBUG_LEVEL > 2 
  528    fprintf(stderr, 
"after mediate ret is %lx %ld\n", nRegReturn[0], nRegReturn[0]);
 
  533        case typelib_TypeClass_BOOLEAN:
 
  534        case typelib_TypeClass_BYTE:
 
  535            nRegReturn[0] = (
unsigned long)(*(
unsigned char *)nRegReturn);
 
  537        case typelib_TypeClass_CHAR:
 
  538        case typelib_TypeClass_UNSIGNED_SHORT:
 
  539        case typelib_TypeClass_SHORT:
 
  540            nRegReturn[0] = (
unsigned long)(*(
unsigned short *)nRegReturn);
 
  542        case typelib_TypeClass_ENUM:
 
  543        case typelib_TypeClass_UNSIGNED_LONG:
 
  544        case typelib_TypeClass_LONG:
 
  545            nRegReturn[0] = (
unsigned long)(*(
unsigned int *)nRegReturn);
 
  547        case typelib_TypeClass_VOID:
 
  550        case typelib_TypeClass_FLOAT:
 
  552                double tmp = (double) (*((
float *)nRegReturn));
 
  553                (*((
double *) nRegReturn)) = tmp;
 
  556        case typelib_TypeClass_DOUBLE:
 
  558                : : 
"m" (*((
double*)nRegReturn)) : 
"$f0");
 
  561    return nRegReturn[0];
 
  566unsigned char *
codeSnippet( 
unsigned char * code, sal_Int32 nFunctionIndex, sal_Int32 nVtableOffset, 
bool simple_ret_type )
 
  568    if (! simple_ret_type)
 
  569        nFunctionIndex |= 0x80000000;
 
  571    unsigned char * 
p = 
code;
 
  572    *(
unsigned int*)&
p[0]  = 0x47fb0401;        
 
  573    *(
unsigned int*)&
p[4]  = 0xa43b0010;        
 
  574    *(
unsigned int*)&
p[8]  = 0xa77b0018;        
 
  575    *(
unsigned int*)&
p[12] = 0x6bfb0000;        
 
  576    *(
unsigned int*)&
p[16] = nFunctionIndex;
 
  577    *(
unsigned int*)&
p[20] = nVtableOffset;
 
  586    __asm__ __volatile__(
"call_pal 0x86");
 
  594    return static_cast< Slot * 
>(block) + 2;
 
  611    void * block, sal_Int32 slotCount, sal_Int32,
 
  612    typelib_InterfaceTypeDescription *)
 
  614    Slot * slots = mapBlockToVtable(block);
 
  616    slots[-1].fn = &
typeid(ProxyRtti);
 
  617    return slots + slotCount;
 
  621    Slot ** slots, 
unsigned char * code, sal_PtrDiff writetoexecdiff,
 
  622    typelib_InterfaceTypeDescription 
const * type, sal_Int32 functionOffset,
 
  623    sal_Int32 functionCount, sal_Int32 vtableOffset)
 
  625    (*slots) -= functionCount;
 
  627#if OSL_DEBUG_LEVEL > 2 
  628    fprintf(stderr, 
"in addLocalFunctions functionOffset is %x\n",functionOffset);
 
  629    fprintf(stderr, 
"in addLocalFunctions vtableOffset is %x\n",vtableOffset);
 
  632    for (sal_Int32 i = 0; 
i < 
type->nMembers; ++
i) {
 
  634        TYPELIB_DANGER_GET(&member, 
type->ppMembers[i]);
 
  636        switch (member->eTypeClass) {
 
  637        case typelib_TypeClass_INTERFACE_ATTRIBUTE:
 
  639            (s++)->fn = code + writetoexecdiff;
 
  641                code, functionOffset++, vtableOffset,
 
  644                    typelib_InterfaceAttributeTypeDescription * 
>(
 
  645                        member)->pAttributeTypeRef));
 
  648            if (!
reinterpret_cast< 
  649                typelib_InterfaceAttributeTypeDescription * 
>(
 
  652                (s++)->fn = code + writetoexecdiff;
 
  657        case typelib_TypeClass_INTERFACE_METHOD:
 
  658            (s++)->fn = code + writetoexecdiff;
 
  660                code, functionOffset++, vtableOffset,
 
  663                    typelib_InterfaceMethodTypeDescription * 
>(
 
  664                        member)->pReturnTypeRef));
 
  671        TYPELIB_DANGER_RELEASE(member);
 
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")
 
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,...