21#include <com/sun/star/uno/genfunc.hxx>
24#include <typelib/typedescription.hxx>
25#include <osl/endian.h>
37#define IS_BIG_ENDIAN 1
39#define IS_BIG_ENDIAN 0
51 typelib_TypeDescriptionReference * pReturnTypeRef,
52 sal_Int32 nParams, typelib_MethodParameter * pParams,
53 void ** gpreg,
void ** fpreg,
void ** ovrflw,
54 sal_Int64 * pRegisterReturn )
56#if OSL_DEBUG_LEVEL > 2
57 fprintf(stderr,
"as far as cpp2uno_call\n");
70 TYPELIB_DANGER_GET( &pReturnTypeDescr, pReturnTypeRef );
72 void * pUnoReturn = 0;
73 void * pCppReturn = 0;
79 pUnoReturn = pRegisterReturn;
83 pCppReturn = *(
void **)gpreg;
88 ? alloca( pReturnTypeDescr->nSize )
97 static_assert(
sizeof(
void *) ==
sizeof(sal_Int64),
"### unexpected size!");
99 void ** pUnoArgs = (
void **)alloca( 4 *
sizeof(
void *) * nParams );
100 void ** pCppArgs = pUnoArgs + nParams;
102 sal_Int32 * pTempIndices = (sal_Int32 *)(pUnoArgs + (2 * nParams));
106 sal_Int32 nTempIndices = 0;
107 bool bOverflowUsed =
false;
110 const typelib_MethodParameter & rParam = pParams[
nPos];
112 TYPELIB_DANGER_GET( &pParamTypeDescr, rParam.pTypeRef );
114#if OSL_DEBUG_LEVEL > 2
115 fprintf(stderr,
"arg %d of %d\n",
nPos, nParams);
120#if OSL_DEBUG_LEVEL > 2
121 fprintf(stderr,
"simple\n");
124 switch (pParamTypeDescr->eTypeClass)
126 case typelib_TypeClass_FLOAT:
127 case typelib_TypeClass_DOUBLE:
130 if (pParamTypeDescr->eTypeClass == typelib_TypeClass_FLOAT)
132 float tmp = (float) (*((
double *)fpreg));
133 (*((
float *) fpreg)) = tmp;
135 pCppArgs[
nPos] = pUnoArgs[
nPos] = fpreg++;
146 pCppArgs[
nPos] = pUnoArgs[
nPos] = ovrflw;
147 bOverflowUsed =
true;
149 if (bOverflowUsed) ovrflw++;
151 case typelib_TypeClass_BYTE:
152 case typelib_TypeClass_BOOLEAN:
162 bOverflowUsed =
true;
164 if (bOverflowUsed) ovrflw++;
166 case typelib_TypeClass_CHAR:
167 case typelib_TypeClass_SHORT:
168 case typelib_TypeClass_UNSIGNED_SHORT:
178 bOverflowUsed =
true;
180 if (bOverflowUsed) ovrflw++;
182 case typelib_TypeClass_ENUM:
183 case typelib_TypeClass_LONG:
184 case typelib_TypeClass_UNSIGNED_LONG:
194 bOverflowUsed =
true;
196 if (bOverflowUsed) ovrflw++;
201 pCppArgs[
nPos] = pUnoArgs[
nPos] = gpreg++;
206 pCppArgs[
nPos] = pUnoArgs[
nPos] = ovrflw;
207 bOverflowUsed =
true;
209 if (bOverflowUsed) ovrflw++;
214 TYPELIB_DANGER_RELEASE( pParamTypeDescr );
218#if OSL_DEBUG_LEVEL > 2
219 fprintf(stderr,
"complex, ng is %d\n", ng);
225 pCppArgs[
nPos] = pCppStack = *gpreg++;
230 pCppArgs[
nPos] = pCppStack = *ovrflw;
231 bOverflowUsed =
true;
233 if (bOverflowUsed) ovrflw++;
238 pUnoArgs[
nPos] = alloca( pParamTypeDescr->nSize );
239 pTempIndices[nTempIndices] =
nPos;
241 ppTempParamTypeDescr[nTempIndices++] = pParamTypeDescr;
247 pCppStack, pParamTypeDescr,
249 pTempIndices[nTempIndices] =
nPos;
251 ppTempParamTypeDescr[nTempIndices++] = pParamTypeDescr;
255 pUnoArgs[
nPos] = pCppStack;
257 TYPELIB_DANGER_RELEASE( pParamTypeDescr );
262#if OSL_DEBUG_LEVEL > 2
263 fprintf(stderr,
"end of params\n");
271 (*pThis->
getUnoI()->pDispatcher)( pThis->
getUnoI(), pMemberTypeDescr, pUnoReturn, pUnoArgs, &pUnoExc );
277 for ( ; nTempIndices--; )
279 sal_Int32
nIndex = pTempIndices[nTempIndices];
283 TYPELIB_DANGER_RELEASE( ppTempParamTypeDescr[nTempIndices] );
285 if (pReturnTypeDescr)
286 TYPELIB_DANGER_RELEASE( pReturnTypeDescr );
291 return typelib_TypeClass_VOID;
296 for ( ; nTempIndices--; )
298 sal_Int32
nIndex = pTempIndices[nTempIndices];
311 TYPELIB_DANGER_RELEASE( pParamTypeDescr );
316 if (pUnoReturn != pCppReturn)
324 *(
void **)pRegisterReturn = pCppReturn;
326 if (pReturnTypeDescr)
328 typelib_TypeClass eRet = (typelib_TypeClass)pReturnTypeDescr->eTypeClass;
329 TYPELIB_DANGER_RELEASE( pReturnTypeDescr );
333 return typelib_TypeClass_VOID;
337#if defined(_CALL_ELF) && _CALL_ELF == 2
344 sal_uInt64 nOffsetAndIndex,
345 void ** gpreg,
void ** fpreg,
long sp,
346 sal_Int64 * pRegisterReturn )
348 static_assert(
sizeof(sal_Int64)==
sizeof(
void *),
"### unexpected!");
350 sal_Int32 nVtableOffset = (nOffsetAndIndex >> 32);
351 sal_Int32 nFunctionIndex = (nOffsetAndIndex & 0xFFFFFFFF);
353 long sf = *(
long*)sp;
354 void ** ovrflw = (
void**)(sf +
PARAMSAVE + 64);
361 if (nFunctionIndex & 0x80000000 )
363 nFunctionIndex &= 0x7fffffff;
365#if OSL_DEBUG_LEVEL > 2
366 fprintf(stderr,
"pThis is gpreg[1]\n");
372#if OSL_DEBUG_LEVEL > 2
373 fprintf(stderr,
"pThis is gpreg[0]\n");
377#if OSL_DEBUG_LEVEL > 2
378 fprintf(stderr,
"pThis is %lx\n", pThis);
381 pThis =
static_cast< char *
>(pThis) - nVtableOffset;
383#if OSL_DEBUG_LEVEL > 2
384 fprintf(stderr,
"pThis is now %lx\n", pThis);
391 typelib_InterfaceTypeDescription * pTypeDescr = pCppI->
getTypeDescr();
393#if OSL_DEBUG_LEVEL > 2
394 fprintf(stderr,
"indexes are %d %d\n", nFunctionIndex, pTypeDescr->nMapFunctionIndexToMemberIndex);
397 if (nFunctionIndex >= pTypeDescr->nMapFunctionIndexToMemberIndex)
401 "illegal " << OUString::unacquired(&pTypeDescr->aBase.pTypeName)
402 <<
" vtable index " << nFunctionIndex <<
"/"
403 << pTypeDescr->nMapFunctionIndexToMemberIndex);
405 (
"illegal " + OUString::unacquired(&pTypeDescr->aBase.pTypeName)
406 +
" vtable index " + OUString::number(nFunctionIndex) +
"/"
407 + OUString::number(pTypeDescr->nMapFunctionIndexToMemberIndex)),
412 sal_Int32 nMemberPos = pTypeDescr->pMapFunctionIndexToMemberIndex[nFunctionIndex];
413 assert(nMemberPos < pTypeDescr->nAllMembers);
415#if OSL_DEBUG_LEVEL > 2
416 fprintf(stderr,
"members are %d %d\n", nMemberPos, pTypeDescr->nAllMembers);
419 TypeDescription aMemberDescr( pTypeDescr->ppAllMembers[nMemberPos] );
421 typelib_TypeClass eRet;
422 switch (aMemberDescr.get()->eTypeClass)
424 case typelib_TypeClass_INTERFACE_ATTRIBUTE:
426 if (pTypeDescr->pMapMemberIndexToFunctionIndex[nMemberPos] == nFunctionIndex)
430 pCppI, aMemberDescr.get(),
431 ((typelib_InterfaceAttributeTypeDescription *)aMemberDescr.get())->pAttributeTypeRef,
433 gpreg, fpreg, ovrflw, pRegisterReturn );
438 typelib_MethodParameter aParam;
440 ((typelib_InterfaceAttributeTypeDescription *)aMemberDescr.get())->pAttributeTypeRef;
445 pCppI, aMemberDescr.get(),
448 gpreg, fpreg, ovrflw, pRegisterReturn );
452 case typelib_TypeClass_INTERFACE_METHOD:
455 switch (nFunctionIndex)
459 eRet = typelib_TypeClass_VOID;
463 eRet = typelib_TypeClass_VOID;
468 TYPELIB_DANGER_GET( &pTD,
reinterpret_cast< Type *
>( gpreg[2] )->getTypeLibType() );
474 (
void **)&pInterface, pCppI->
getOid().pData,
475 (typelib_InterfaceTypeDescription *)pTD );
480 reinterpret_cast< uno_Any *
>( gpreg[0] ),
481 &pInterface, pTD, cpp_acquire );
482 pInterface->release();
483 TYPELIB_DANGER_RELEASE( pTD );
484 *(
void **)pRegisterReturn = gpreg[0];
485 eRet = typelib_TypeClass_ANY;
488 TYPELIB_DANGER_RELEASE( pTD );
493 pCppI, aMemberDescr.get(),
494 ((typelib_InterfaceMethodTypeDescription *)aMemberDescr.get())->pReturnTypeRef,
495 ((typelib_InterfaceMethodTypeDescription *)aMemberDescr.get())->nParams,
496 ((typelib_InterfaceMethodTypeDescription *)aMemberDescr.get())->pParams,
497 gpreg, fpreg, ovrflw, pRegisterReturn );
503#if OSL_DEBUG_LEVEL > 2
504 fprintf(stderr,
"screwed\n");
511#if OSL_DEBUG_LEVEL > 2
512 fprintf(stderr,
"end of cpp_mediate\n");
521 register long r3
asm(
"r3"); gpreg[0] = r3;
522 register long r4
asm(
"r4"); gpreg[1] = r4;
523 register long r5
asm(
"r5"); gpreg[2] = r5;
524 register long r6
asm(
"r6"); gpreg[3] = r6;
525 register long r7
asm(
"r7"); gpreg[4] = r7;
526 register long r8
asm(
"r8"); gpreg[5] = r8;
527 register long r9
asm(
"r9"); gpreg[6] = r9;
528 register long r10
asm(
"r10"); gpreg[7] = r10;
542 "stfd 10, 72(%0)\t\n"
543 "stfd 11, 80(%0)\t\n"
544 "stfd 12, 88(%0)\t\n"
545 "stfd 13, 96(%0)\t\n"
547 :
"fr1",
"fr2",
"fr3",
"fr4",
"fr5",
"fr6",
"fr7",
"fr8",
"fr9",
548 "fr10",
"fr11",
"fr12",
"fr13"
551 register long r11
asm(
"r11");
552 const long nOffsetAndIndex = r11;
554 register long r1
asm(
"r1");
557#if defined(_CALL_ELF) && _CALL_ELF == 2
558 volatile long nRegReturn[2];
560 volatile long nRegReturn[1];
563 typelib_TypeClass aType =
564 cpp_mediate( nOffsetAndIndex, (
void**)gpreg, (
void**)fpreg, sp, (sal_Int64*)nRegReturn);
568 case typelib_TypeClass_VOID:
570 case typelib_TypeClass_BOOLEAN:
571 case typelib_TypeClass_BYTE:
573 : :
"m" (nRegReturn[0]) );
575 case typelib_TypeClass_CHAR:
576 case typelib_TypeClass_UNSIGNED_SHORT:
578 : :
"m" (nRegReturn[0]) );
580 case typelib_TypeClass_SHORT:
582 : :
"m" (nRegReturn[0]) );
584 case typelib_TypeClass_ENUM:
585 case typelib_TypeClass_UNSIGNED_LONG:
587 : :
"m"(nRegReturn[0]) );
589 case typelib_TypeClass_LONG:
591 : :
"m"(nRegReturn[0]) );
593 case typelib_TypeClass_FLOAT:
595 : :
"m" (*((
float*)nRegReturn)) );
597 case typelib_TypeClass_DOUBLE:
599 : :
"m" (*((
double*)nRegReturn)) );
603 : :
"m" (nRegReturn[0]) );
604#if defined(_CALL_ELF) && _CALL_ELF == 2
606 : :
"m" (nRegReturn[1]) );
612#if defined(_CALL_ELF) && _CALL_ELF == 2
618unsigned char *
codeSnippet(
unsigned char * code, sal_Int32 nFunctionIndex, sal_Int32 nVtableOffset,
619 bool bHasHiddenParam)
621#if OSL_DEBUG_LEVEL > 2
622 fprintf(stderr,
"in codeSnippet functionIndex is %x\n", nFunctionIndex);
623 fprintf(stderr,
"in codeSnippet vtableOffset is %x\n", nVtableOffset);
626 sal_uInt64 nOffsetAndIndex = ( ( (sal_uInt64) nVtableOffset ) << 32 ) | ( (sal_uInt64) nFunctionIndex );
628 if ( bHasHiddenParam )
629 nOffsetAndIndex |= 0x80000000;
630#if defined(_CALL_ELF) && _CALL_ELF == 2
631 unsigned int *raw = (
unsigned int *)&code[0];
640 *(
void **)&raw[6] = (
void*)nOffsetAndIndex;
642 void ** raw = (
void **)&code[0];
644 raw[2] = (
void*) nOffsetAndIndex;
646#if OSL_DEBUG_LEVEL > 2
647 fprintf(stderr,
"in: offset/index is %x %x %d, %lx\n",
648 nFunctionIndex, nVtableOffset, bHasHiddenParam, raw[2]);
657 int const lineSize = 32;
658 for (
unsigned char const *
p = bptr;
p < eptr + lineSize;
p += lineSize) {
659 __asm__ volatile (
"dcbst 0, %0" : :
"r"(
p) :
"memory");
661 __asm__ volatile (
"sync" : : :
"memory");
662 for (
unsigned char const *
p = bptr;
p < eptr + lineSize;
p += lineSize) {
663 __asm__ volatile (
"icbi 0, %0" : :
"r"(
p) :
"memory");
665 __asm__ volatile (
"isync" : : :
"memory");
673 return static_cast< Slot *
>(block) + 2;
690 void * block, sal_Int32 slotCount, sal_Int32,
691 typelib_InterfaceTypeDescription *)
693 Slot * slots = mapBlockToVtable(block);
695 slots[-1].fn = &
typeid(ProxyRtti);
696 return slots + slotCount;
700 Slot ** slots,
unsigned char * code, sal_PtrDiff writetoexecdiff,
701 typelib_InterfaceTypeDescription
const * type, sal_Int32 functionOffset,
702 sal_Int32 functionCount, sal_Int32 vtableOffset)
704 (*slots) -= functionCount;
706#if OSL_DEBUG_LEVEL > 2
707 fprintf(stderr,
"in addLocalFunctions functionOffset is %x\n",functionOffset);
708 fprintf(stderr,
"in addLocalFunctions vtableOffset is %x\n",vtableOffset);
711 for (sal_Int32 i = 0;
i <
type->nMembers; ++
i) {
713 TYPELIB_DANGER_GET(&member,
type->ppMembers[i]);
715 switch (member->eTypeClass) {
716 case typelib_TypeClass_INTERFACE_ATTRIBUTE:
718 (s++)->fn = code + writetoexecdiff;
720 code, functionOffset++, vtableOffset,
723 typelib_InterfaceAttributeTypeDescription *
>(
724 member)->pAttributeTypeRef));
727 if (!
reinterpret_cast<
728 typelib_InterfaceAttributeTypeDescription *
>(
731 (s++)->fn = code + writetoexecdiff;
736 case typelib_TypeClass_INTERFACE_METHOD:
737 (s++)->fn = code + writetoexecdiff;
739 code, functionOffset++, vtableOffset,
742 typelib_InterfaceMethodTypeDescription *
>(
743 member)->pReturnTypeRef));
750 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()
register sal_uInt32 r28 __asm__("%r28")
void(* privateSnippetExecutor)()
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,...
bool return_in_hidden_param(typelib_TypeDescriptionReference *pTypeRef)