25#include <com/sun/star/uno/genfunc.hxx>
26#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 ** gpreg,
double *fpreg,
void ** ovrflw,
53 sal_Int64 * pRegisterReturn )
55 void ** startovrflw = ovrflw;
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 via r8\n");
84 pCppReturn = (
void *)r8;
87 ? alloca( pReturnTypeDescr->nSize )
97 static_assert(
sizeof(
void *) ==
sizeof(sal_Int32),
"### unexpected size!");
99 void ** pUnoArgs = (
void **)alloca( 4 *
sizeof(
void *) * nParams );
100 void ** pCppArgs = pUnoArgs + nParams;
103 sal_Int32 * pTempIndices = (sal_Int32 *)(pUnoArgs + (2 * nParams));
108 sal_Int32 nTempIndices = 0;
109 bool bOverflowUsed =
false;
110 for ( sal_Int32 nPos = 0;
nPos < nParams; ++
nPos )
112 const typelib_MethodParameter & rParam = pParams[
nPos];
114 TYPELIB_DANGER_GET( &pParamTypeDescr, rParam.pTypeRef );
118 switch (pParamTypeDescr->eTypeClass)
120 case typelib_TypeClass_DOUBLE:
130 pCppArgs[
nPos] = pUnoArgs[
nPos] = fpreg;
137 if ((startovrflw-ovrflw) & 1)
139 pCppArgs[
nPos] = pUnoArgs[
nPos] = ((
char*)ovrflw - 4);
140 bOverflowUsed =
true;
142 if (bOverflowUsed) ovrflw-=2;
144 case typelib_TypeClass_FLOAT:
147 pCppArgs[
nPos] = pUnoArgs[
nPos] = fpreg;
154 pCppArgs[
nPos] = pUnoArgs[
nPos] = ovrflw;
155 bOverflowUsed =
true;
157 if (bOverflowUsed) ovrflw--;
159 case typelib_TypeClass_HYPER:
160 case typelib_TypeClass_UNSIGNED_HYPER:
169 pCppArgs[
nPos] = pUnoArgs[
nPos] = gpreg;
176 if ((startovrflw-ovrflw) & 1)
178 pCppArgs[
nPos] = pUnoArgs[
nPos] = ((
char*)ovrflw - 4);
179 bOverflowUsed =
true;
181 if (bOverflowUsed) ovrflw-=2;
183 case typelib_TypeClass_BYTE:
184 case typelib_TypeClass_BOOLEAN:
187 pCppArgs[
nPos] = pUnoArgs[
nPos] = ((
char*)gpreg + 3);
194 pCppArgs[
nPos] = pUnoArgs[
nPos] = ((
char*)ovrflw+3);
195 bOverflowUsed =
true;
197 if (bOverflowUsed) ovrflw--;
199 case typelib_TypeClass_CHAR:
200 case typelib_TypeClass_SHORT:
201 case typelib_TypeClass_UNSIGNED_SHORT:
204 pCppArgs[
nPos] = pUnoArgs[
nPos] = ((
char*)gpreg+2);
211 pCppArgs[
nPos] = pUnoArgs[
nPos] = ((
char*)ovrflw+2);
212 bOverflowUsed =
true;
214 if (bOverflowUsed) ovrflw--;
216 case typelib_TypeClass_ENUM:
217 case typelib_TypeClass_LONG:
218 case typelib_TypeClass_UNSIGNED_LONG:
222 pCppArgs[
nPos] = pUnoArgs[
nPos] = gpreg;
229 pCppArgs[
nPos] = pUnoArgs[
nPos] = ovrflw;
230 bOverflowUsed =
true;
232 if (bOverflowUsed) ovrflw--;
236 TYPELIB_DANGER_RELEASE( pParamTypeDescr );
244 pCppArgs[
nPos] = pCppStack = *gpreg;
251 pCppArgs[
nPos] = pCppStack = *ovrflw;
252 bOverflowUsed =
true;
254 if (bOverflowUsed) ovrflw--;
259 pUnoArgs[
nPos] = alloca( pParamTypeDescr->nSize );
260 pTempIndices[nTempIndices] =
nPos;
262 ppTempParamTypeDescr[nTempIndices++] = pParamTypeDescr;
269 pCppStack, pParamTypeDescr,
271 pTempIndices[nTempIndices] =
nPos;
273 ppTempParamTypeDescr[nTempIndices++] = pParamTypeDescr;
277 pUnoArgs[
nPos] = pCppStack;
279 TYPELIB_DANGER_RELEASE( pParamTypeDescr );
288#if OSL_DEBUG_LEVEL > 2
289 fprintf(stderr,
"before dispatch\n");
292 (*pThis->
getUnoI()->pDispatcher)(
293 pThis->
getUnoI(), pMemberTypeDescr, pUnoReturn, pUnoArgs, &pUnoExc );
295#if OSL_DEBUG_LEVEL > 2
296 fprintf(stderr,
"after dispatch\n");
303 for ( ; nTempIndices--; )
305 sal_Int32
nIndex = pTempIndices[nTempIndices];
307 if (pParams[nIndex].bIn)
309 ppTempParamTypeDescr[nTempIndices], 0 );
310 TYPELIB_DANGER_RELEASE( ppTempParamTypeDescr[nTempIndices] );
312 if (pReturnTypeDescr)
313 TYPELIB_DANGER_RELEASE( pReturnTypeDescr );
318 return typelib_TypeClass_VOID;
323 for ( ; nTempIndices--; )
325 sal_Int32
nIndex = pTempIndices[nTempIndices];
327 ppTempParamTypeDescr[nTempIndices];
329 if (pParams[nIndex].bOut)
340 TYPELIB_DANGER_RELEASE( pParamTypeDescr );
345 if (pUnoReturn != pCppReturn)
353 *(
void **)pRegisterReturn = pCppReturn;
355 if (pReturnTypeDescr)
357 typelib_TypeClass eRet =
358 (typelib_TypeClass)pReturnTypeDescr->eTypeClass;
359 TYPELIB_DANGER_RELEASE( pReturnTypeDescr );
363 return typelib_TypeClass_VOID;
369 sal_Int32 nFunctionIndex, sal_Int32 nVtableOffset,
370 void ** gpreg,
double* fpreg,
372 sal_Int64 * pRegisterReturn )
375 void ** ovrflw = (
void**)(sp);
376#if OSL_DEBUG_LEVEL > 2
377 fprintf(stderr,
"cpp_mediate with\n");
378 fprintf(stderr,
"%x %x\n", nFunctionIndex, nVtableOffset);
379 fprintf(stderr,
"and %x %x\n", (
long)(ovrflw[0]), (
long)(ovrflw[-1]));
380 fprintf(stderr,
"and %x %x\n", (
long)(ovrflw[-2]), (
long)(ovrflw[-3]));
381 fprintf(stderr,
"and %x %x\n", (
long)(ovrflw[-4]), (
long)(ovrflw[-5]));
382 fprintf(stderr,
"and %x %x\n", (
long)(ovrflw[-6]), (
long)(ovrflw[-7]));
383 fprintf(stderr,
"and %x %x\n", (
long)(ovrflw[-8]), (
long)(ovrflw[-9]));
384 fprintf(stderr,
"and %x %x\n", (
long)(ovrflw[-10]), (
long)(ovrflw[-11]));
385 fprintf(stderr,
"and %x %x\n", (
long)(ovrflw[-12]), (
long)(ovrflw[-13]));
386 fprintf(stderr,
"and %x %x\n", (
long)(ovrflw[-14]), (
long)(ovrflw[-15]));
388 static_assert(
sizeof(sal_Int32)==
sizeof(
void *),
"### unexpected!");
395 if (nFunctionIndex & 0x80000000 )
397 nFunctionIndex &= 0x7fffffff;
399#if OSL_DEBUG_LEVEL > 2
400 fprintf(stderr,
"pThis is gpreg[1]\n");
406#if OSL_DEBUG_LEVEL > 2
407 fprintf(stderr,
"pThis is gpreg[0]\n");
411 pThis =
static_cast< char *
>(pThis) - nVtableOffset;
417 typelib_InterfaceTypeDescription * pTypeDescr = pCppI->
getTypeDescr();
419 if (nFunctionIndex >= pTypeDescr->nMapFunctionIndexToMemberIndex)
423 "illegal " << OUString::unacquired(&pTypeDescr->aBase.pTypeName)
424 <<
" vtable index " << nFunctionIndex <<
"/"
425 << pTypeDescr->nMapFunctionIndexToMemberIndex);
427 (
"illegal " + OUString::unacquired(&pTypeDescr->aBase.pTypeName)
428 +
" vtable index " + OUString::number(nFunctionIndex) +
"/"
429 + OUString::number(pTypeDescr->nMapFunctionIndexToMemberIndex)),
434 assert(nFunctionIndex < pTypeDescr->nMapFunctionIndexToMemberIndex);
435 sal_Int32 nMemberPos =
436 pTypeDescr->pMapFunctionIndexToMemberIndex[nFunctionIndex];
437 assert(nMemberPos < pTypeDescr->nAllMembers);
439 TypeDescription aMemberDescr( pTypeDescr->ppAllMembers[nMemberPos] );
441 typelib_TypeClass eRet;
442 switch (aMemberDescr.get()->eTypeClass)
444 case typelib_TypeClass_INTERFACE_ATTRIBUTE:
446 if (pTypeDescr->pMapMemberIndexToFunctionIndex[nMemberPos] ==
451 pCppI, aMemberDescr.get(),
452 ((typelib_InterfaceAttributeTypeDescription *)aMemberDescr.get())->pAttributeTypeRef,
454 r8, gpreg, fpreg, ovrflw, pRegisterReturn );
459 typelib_MethodParameter aParam;
461 ((typelib_InterfaceAttributeTypeDescription *)aMemberDescr.get())->pAttributeTypeRef;
466 pCppI, aMemberDescr.get(),
469 r8, gpreg, fpreg, ovrflw, pRegisterReturn );
473 case typelib_TypeClass_INTERFACE_METHOD:
476 switch (nFunctionIndex)
480 eRet = typelib_TypeClass_VOID;
484 eRet = typelib_TypeClass_VOID;
489 TYPELIB_DANGER_GET(&pTD,
490 reinterpret_cast<Type *
>(gpreg[1])->getTypeLibType());
496 (
void **)&pInterface, pCppI->
getOid().pData,
497 (typelib_InterfaceTypeDescription *)pTD );
502 reinterpret_cast< uno_Any *
>( r8 ),
503 &pInterface, pTD, cpp_acquire );
504 pInterface->release();
505 TYPELIB_DANGER_RELEASE( pTD );
506 *(
void **)pRegisterReturn = (
void*)r8;
507 eRet = typelib_TypeClass_ANY;
510 TYPELIB_DANGER_RELEASE( pTD );
515 pCppI, aMemberDescr.get(),
516 ((typelib_InterfaceMethodTypeDescription *)aMemberDescr.get())->pReturnTypeRef,
517 ((typelib_InterfaceMethodTypeDescription *)aMemberDescr.get())->nParams,
518 ((typelib_InterfaceMethodTypeDescription *)aMemberDescr.get())->pParams,
519 r8, gpreg, fpreg, ovrflw, pRegisterReturn );
538sal_Int64
cpp_vtable_call( sal_uInt32 in0, sal_uInt32 in1, sal_uInt32 in2, sal_uInt32 in3, sal_uInt32 firstonstack )
540 register sal_Int32 r21
asm(
"r21");
541 register sal_Int32 r22
asm(
"r22");
542 register sal_Int32 r28
asm(
"r28");
543 sal_Int32 functionIndex = r21;
544 sal_Int32 vtableOffset = r22;
547 long sp = (long)&firstonstack;
556 register float f0
asm(
"fr4"); fpreg[0] = f0;
557 register float f1
asm(
"fr5"); fpreg[1] = f1;
558 register float f2
asm(
"fr6"); fpreg[2] = f2;
559 register float f3
asm(
"fr7"); fpreg[3] = f3;
562 register double d0
asm(
"fr4"); dpreg[0] = d0;
563 register double d1
asm(
"fr5"); dpreg[1] = d1;
564 register double d2
asm(
"fr6"); dpreg[2] = d2;
565 register double d3
asm(
"fr7"); dpreg[3] = d3;
568#if OSL_DEBUG_LEVEL > 2
569 fprintf(stderr,
"got to cpp_vtable_call with %x %x\n", functionIndex, vtableOffset);
571 fprintf(stderr,
"reg %d is %d %x\n",
i, gpreg[
i], gpreg[
i]);
573 fprintf(stderr,
"float reg %d is %f %x\n",
i, fpreg[
i], ((
long*)fpreg)[
i]);
574 for (
int i = 0;
i < 4; ++
i)
575 fprintf(stderr,
"double reg %d is %f %llx\n",
i, dpreg[
i], ((
long long*)dpreg)[
i]);
578 sal_Int64 nRegReturn;
580 typelib_TypeClass aType =
581 cpp_mediate( functionIndex, vtableOffset, (
void**)gpreg, dpreg, sp, r8, &nRegReturn);
585 case typelib_TypeClass_FLOAT:
586 f0 = (*((
float*)&nRegReturn));
588 case typelib_TypeClass_DOUBLE:
589 d0 = (*((
double*)&nRegReturn));
603# define unldil(v) (((v & 0x7c) << 14) | ((v & 0x180) << 7) | ((v & 0x3) << 12) | ((v & 0xffe00) >> 8) | ((v & 0x100000) >> 20))
604# define L21(v) unldil(((unsigned long)(v) >> 11) & 0x1fffff)
605# define R11(v) (((unsigned long)(v) & 0x7FF) << 1)
607 unsigned char *
codeSnippet(
unsigned char* code, sal_Int32 functionIndex,
608 sal_Int32 vtableOffset,
bool bHasHiddenParam)
611 functionIndex |= 0x80000000;
613 unsigned char *
p =
code;
614 *(
unsigned long*)&
p[0] = 0xeaa00000;
615 *(
unsigned long*)&
p[4] = 0xd6a01c1e;
616 *(
unsigned long*)&
p[8] = 0x4aa10040;
618 *(
unsigned long*)&
p[12] = 0x22A00000 |
L21(functionIndex);
619 *(
unsigned long*)&
p[16] = 0x36B50000 |
R11(functionIndex);
621 *(
unsigned long*)&
p[20] = 0x22C00000 |
L21(vtableOffset);
622 *(
unsigned long*)&
p[24] = 0x36D60000 |
R11(vtableOffset);
624 *(
unsigned long*)&
p[28] = 0x0c201094;
625 *(
unsigned long*)&
p[32] = 0xea80c000;
626 *(
unsigned long*)&
p[36] = 0x0c281093;
638 return static_cast< Slot *
>(block) + 2;
655 void * block, sal_Int32 slotCount, sal_Int32,
656 typelib_InterfaceTypeDescription *)
658 Slot * slots = mapBlockToVtable(block);
660 slots[-1].fn = &
typeid(ProxyRtti);
661 return slots + slotCount;
665 Slot ** slots,
unsigned char * code, sal_PtrDiff writetoexecdiff,
666 typelib_InterfaceTypeDescription
const * type, sal_Int32 functionOffset,
667 sal_Int32 functionCount, sal_Int32 vtableOffset)
669 (*slots) -= functionCount;
671 for (sal_Int32 i = 0;
i <
type->nMembers; ++
i)
674 TYPELIB_DANGER_GET(&member,
type->ppMembers[i]);
676 switch (member->eTypeClass)
678 case typelib_TypeClass_INTERFACE_ATTRIBUTE:
680 (s++)->fn = code + writetoexecdiff;
683 if (!
reinterpret_cast<
684 typelib_InterfaceAttributeTypeDescription *
>(
687 (s++)->fn = code + writetoexecdiff;
691 case typelib_TypeClass_INTERFACE_METHOD:
693 (s++)->fn = code + writetoexecdiff;
701 TYPELIB_DANGER_RELEASE(member);
707 unsigned char const *beg,
unsigned char const *end)
709 void *
p = (
void*)((
size_t)beg & ~31);
713 asm volatile(
"fdc (%0)\n\t"
715 "fic,m %1(%%sr4, %0)\n\t"
716 "sync" :
"+r"(
p) :
"r"(stride) :
"memory");
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(sal_uInt32 in0, sal_uInt32 in1, sal_uInt32 in2, sal_uInt32 in3, sal_uInt32 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,...
bool isRegisterReturn(typelib_TypeDescriptionReference *pTypeRef)