20 #include <com/sun/star/uno/genfunc.hxx>
23 #include <typelib/typedescription.hxx>
43 typelib_TypeDescriptionReference * pReturnTypeRef,
44 sal_Int32 nParams, typelib_MethodParameter * pParams,
45 void ** gpreg,
double * fpreg,
void ** ovrflw,
46 sal_uInt64 * pRegisterReturn )
55 TYPELIB_DANGER_GET( &pReturnTypeDescr, pReturnTypeRef );
57 void * pUnoReturn = 0;
58 void * pCppReturn = 0;
68 pUnoReturn = pRegisterReturn;
77 ? __builtin_alloca( pReturnTypeDescr->nSize )
87 static_assert(
sizeof(
void *) ==
sizeof(sal_Int32),
"### unexpected size!");
89 void ** pUnoArgs = (
void **)__builtin_alloca( 4 *
sizeof(
void *) * nParams );
90 void ** pCppArgs = pUnoArgs + nParams;
93 sal_Int32 * pTempIndices = (sal_Int32 *)(pUnoArgs + (2 * nParams));
98 sal_Int32 nTempIndices = 0;
100 for ( sal_Int32 nPos = 0;
nPos < nParams; ++
nPos )
102 const typelib_MethodParameter & rParam = pParams[
nPos];
104 TYPELIB_DANGER_GET( &pParamTypeDescr, rParam.pTypeRef );
109 switch (pParamTypeDescr->eTypeClass)
111 case typelib_TypeClass_BOOLEAN:
112 case typelib_TypeClass_BYTE:
118 pCppArgs[
nPos] = pUnoArgs[
nPos] = (((
char *)ovrflw) + (
sizeof(
void*)-1));
121 case typelib_TypeClass_CHAR:
122 case typelib_TypeClass_SHORT:
123 case typelib_TypeClass_UNSIGNED_SHORT:
129 pCppArgs[
nPos] = pUnoArgs[
nPos] = (((
char *)ovrflw) + (
sizeof(
void*)-2));
132 case typelib_TypeClass_HYPER:
133 case typelib_TypeClass_UNSIGNED_HYPER:
134 pCppArgs[
nPos] = pUnoArgs[
nPos] = ovrflw;
135 for (
int i = 0;
i < 2; ++
i)
145 case typelib_TypeClass_DOUBLE:
148 pCppArgs[
nPos] = pUnoArgs[
nPos] = fpreg;
154 pCppArgs[
nPos] = pUnoArgs[
nPos] = ovrflw;
163 case typelib_TypeClass_FLOAT:
166 pCppArgs[
nPos] = pUnoArgs[
nPos] = fpreg;
172 pCppArgs[
nPos] = pUnoArgs[
nPos] = ovrflw;
187 pCppArgs[
nPos] = pUnoArgs[
nPos] = ovrflw;
193 TYPELIB_DANGER_RELEASE( pParamTypeDescr );
204 pCppArgs[
nPos] = pCppStack = *ovrflw++;
209 pUnoArgs[
nPos] = __builtin_alloca( pParamTypeDescr->nSize );
210 pTempIndices[nTempIndices] =
nPos;
212 ppTempParamTypeDescr[nTempIndices++] = pParamTypeDescr;
218 pCppStack, pParamTypeDescr,
220 pTempIndices[nTempIndices] =
nPos;
222 ppTempParamTypeDescr[nTempIndices++] = pParamTypeDescr;
226 pUnoArgs[
nPos] = pCppStack;
228 TYPELIB_DANGER_RELEASE( pParamTypeDescr );
238 (*pThis->
getUnoI()->pDispatcher)(
239 pThis->
getUnoI(), pMemberTypeDescr, pUnoReturn, pUnoArgs, &pUnoExc );
245 for ( ; nTempIndices--; )
247 sal_Int32
nIndex = pTempIndices[nTempIndices];
249 if (pParams[nIndex].bIn)
250 uno_destructData( pUnoArgs[nIndex], ppTempParamTypeDescr[nTempIndices], 0 );
251 TYPELIB_DANGER_RELEASE( ppTempParamTypeDescr[nTempIndices] );
253 if (pReturnTypeDescr)
254 TYPELIB_DANGER_RELEASE( pReturnTypeDescr );
260 return typelib_TypeClass_VOID;
265 for ( ; nTempIndices--; )
267 sal_Int32 nIndex = pTempIndices[nTempIndices];
270 if (pParams[nIndex].bOut)
280 TYPELIB_DANGER_RELEASE( pParamTypeDescr );
285 if (pUnoReturn != pCppReturn)
293 *(
void **)pRegisterReturn = pCppReturn;
295 if (pReturnTypeDescr)
297 typelib_TypeClass eRet = (typelib_TypeClass)pReturnTypeDescr->eTypeClass;
298 TYPELIB_DANGER_RELEASE( pReturnTypeDescr );
302 return typelib_TypeClass_VOID;
308 sal_Int32 nFunctionIndex,
309 sal_Int32 nVtableOffset,
310 void ** gpreg,
double * fpreg,
void ** ovrflw,
311 sal_uInt64 * pRegisterReturn )
313 static_assert(
sizeof(sal_Int32)==
sizeof(
void *),
"### unexpected!");
320 if( nFunctionIndex & 0x8000 )
322 nFunctionIndex &= 0x7fff;
330 pThis =
static_cast< char *
>(pThis) - nVtableOffset;
335 typelib_InterfaceTypeDescription * pTypeDescr = pCppI->
getTypeDescr();
337 if (nFunctionIndex >= pTypeDescr->nMapFunctionIndexToMemberIndex)
341 "illegal " << OUString::unacquired(&pTypeDescr->aBase.pTypeName)
342 <<
" vtable index " << nFunctionIndex <<
"/"
343 << pTypeDescr->nMapFunctionIndexToMemberIndex);
345 (
"illegal " + OUString::unacquired(&pTypeDescr->aBase.pTypeName)
346 +
" vtable index " + OUString::number(nFunctionIndex) +
"/"
347 + OUString::number(pTypeDescr->nMapFunctionIndexToMemberIndex)),
352 sal_Int32 nMemberPos = pTypeDescr->pMapFunctionIndexToMemberIndex[nFunctionIndex];
353 assert(nMemberPos < pTypeDescr->nAllMembers);
355 TypeDescription aMemberDescr( pTypeDescr->ppAllMembers[nMemberPos] );
357 typelib_TypeClass eRet;
358 switch (aMemberDescr.get()->eTypeClass)
360 case typelib_TypeClass_INTERFACE_ATTRIBUTE:
362 if (pTypeDescr->pMapMemberIndexToFunctionIndex[nMemberPos] == nFunctionIndex)
366 pCppI, aMemberDescr.get(),
367 ((typelib_InterfaceAttributeTypeDescription *)aMemberDescr.get())->pAttributeTypeRef,
369 gpreg, fpreg, ovrflw, pRegisterReturn );
374 typelib_MethodParameter aParam;
376 ((typelib_InterfaceAttributeTypeDescription *)aMemberDescr.get())->pAttributeTypeRef;
381 pCppI, aMemberDescr.get(),
384 gpreg, fpreg, ovrflw, pRegisterReturn );
388 case typelib_TypeClass_INTERFACE_METHOD:
391 switch (nFunctionIndex)
395 eRet = typelib_TypeClass_VOID;
399 eRet = typelib_TypeClass_VOID;
404 TYPELIB_DANGER_GET( &pTD, reinterpret_cast< Type * >( gpreg[2] )->getTypeLibType() );
410 (
void **)&pInterface, pCppI->
getOid().pData, (typelib_InterfaceTypeDescription *)pTD );
415 reinterpret_cast< uno_Any * >( gpreg[0] ),
416 &pInterface, pTD, cpp_acquire );
417 pInterface->release();
418 TYPELIB_DANGER_RELEASE( pTD );
419 *(
void **)pRegisterReturn = gpreg[0];
420 eRet = typelib_TypeClass_ANY;
423 TYPELIB_DANGER_RELEASE( pTD );
428 pCppI, aMemberDescr.get(),
429 ((typelib_InterfaceMethodTypeDescription *)aMemberDescr.get())->pReturnTypeRef,
430 ((typelib_InterfaceMethodTypeDescription *)aMemberDescr.get())->nParams,
431 ((typelib_InterfaceMethodTypeDescription *)aMemberDescr.get())->pParams,
432 gpreg, fpreg, ovrflw, pRegisterReturn );
450 static sal_uInt64
cpp_vtable_call(sal_Int32 r3, sal_Int32 r4, sal_Int32 r5,
451 sal_Int32 r6, sal_Int32 r7, sal_Int32 r8, sal_Int32 r9,
452 sal_Int32 r10, sal_Int32 firstonstack)
454 volatile unsigned long nOffsetAndIndex;
458 :
"=r" (nOffsetAndIndex) : );
460 sal_Int32 nVtableOffset = (nOffsetAndIndex >> 16);
461 sal_Int32 nFunctionIndex = (nOffsetAndIndex & 0xFFFF);
463 void ** ovrflw = (
void**)&firstonstack;
476 register double d0
asm(
"fr1"); fpreg[0] = d0;
477 register double d1
asm(
"fr2"); fpreg[1] = d1;
478 register double d2
asm(
"fr3"); fpreg[2] = d2;
479 register double d3
asm(
"fr4"); fpreg[3] = d3;
480 register double d4
asm(
"fr5"); fpreg[4] = d4;
481 register double d5
asm(
"fr6"); fpreg[5] = d5;
482 register double d6
asm(
"fr7"); fpreg[6] = d6;
483 register double d7
asm(
"fr8"); fpreg[7] = d7;
484 register double d8
asm(
"fr9"); fpreg[8] = d8;
485 register double d9
asm(
"fr10"); fpreg[9] = d9;
486 register double d10
asm(
"fr11"); fpreg[10] = d10;
487 register double d11
asm(
"fr12"); fpreg[11] = d11;
488 register double d12
asm(
"fr13"); fpreg[12] = d12;
490 #if OSL_DEBUG_LEVEL > 2
491 for(
int i = 0;
i < 8; ++
i)
493 fprintf(stderr,
"general reg %d is %x\n", i, gpreg[i]);
495 for(
int i = 0;
i < 13; ++
i)
497 fprintf(stderr,
"sse reg %d is %f\n", i, fpreg[i]);
498 fprintf(stderr,
"sse reg %d is %llx\n", i, fpreg[i]);
500 for(
int i = -8;
i < 8; ++
i)
502 fprintf(stderr,
"overflow arg %d is %x\n", i, ovrflw[i]);
505 sal_uInt64 nRegReturn=0;
507 typelib_TypeClass aType =
508 cpp_mediate( nFunctionIndex, nVtableOffset, (
void**)gpreg, fpreg, ovrflw, &nRegReturn );
510 sal_uInt32 *pRegReturn = (sal_uInt32*)&nRegReturn;
513 case typelib_TypeClass_BOOLEAN:
514 pRegReturn[0] = (sal_uInt32)(*(
char *)pRegReturn);
516 case typelib_TypeClass_BYTE:
517 pRegReturn[0] = (sal_Int32)(*(
unsigned char *)pRegReturn);
519 case typelib_TypeClass_SHORT:
520 pRegReturn[0] = (sal_Int32)(*(
short *)pRegReturn);
522 case typelib_TypeClass_CHAR:
523 case typelib_TypeClass_UNSIGNED_SHORT:
524 pRegReturn[0] = (sal_uInt32)(*(
unsigned short *)pRegReturn);
526 case typelib_TypeClass_FLOAT:
527 __asm__(
"lfs 1,%0\n\t" : :
"m"(*((
float*)&nRegReturn)));
529 case typelib_TypeClass_DOUBLE:
530 __asm__(
"lfd 1,%0\n\t" : :
"m"(*((
double*)&nRegReturn)));
532 case typelib_TypeClass_HYPER:
533 case typelib_TypeClass_UNSIGNED_HYPER:
536 pRegReturn[0] = (sal_uInt32)(*(
unsigned int*)pRegReturn);
545 unsigned char *
codeSnippet(
unsigned char * code, sal_Int16 functionIndex,
546 sal_Int16 vtableOffset,
bool simpleRetType )
548 sal_uInt32 nOffsetAndIndex = ( ( vtableOffset ) << 16 ) | (functionIndex );
549 if (! simpleRetType )
550 nOffsetAndIndex |= 0x8000;
552 void **raw = (
void**)&code[0];
554 raw[2] = (
void*)nOffsetAndIndex;
556 return (code + codeSnippetSize);
563 int const lineSize = 32;
564 for (
unsigned char const *
p = bptr;
p < eptr + lineSize;
p += lineSize) {
565 __asm__ volatile (
"dcbst 0, %0" : :
"r"(
p) :
"memory");
567 __asm__ volatile (
"sync" : : :
"memory");
568 for (
unsigned char const *
p = bptr;
p < eptr + lineSize;
p += lineSize) {
569 __asm__ volatile (
"icbi 0, %0" : :
"r"(
p) :
"memory");
571 __asm__ volatile (
"isync" : : :
"memory");
579 return static_cast< Slot *
>(block) + 2;
585 return (slotCount + 2) *
sizeof (
Slot) + slotCount * codeSnippetSize;
590 void * block, sal_Int32 slotCount, sal_Int32,
591 typelib_InterfaceTypeDescription *)
593 Slot * slots = mapBlockToVtable(block);
596 return slots + slotCount;
600 Slot ** slots,
unsigned char * code,
601 typelib_InterfaceTypeDescription
const * type, sal_Int32 functionOffset,
602 sal_Int32 functionCount, sal_Int32 vtableOffset)
604 (*slots) -= functionCount;
607 for (sal_Int32
i = 0;
i < type->nMembers; ++
i) {
609 TYPELIB_DANGER_GET(&member, type->ppMembers[
i]);
611 switch (member->eTypeClass) {
612 case typelib_TypeClass_INTERFACE_ATTRIBUTE:
616 code, functionOffset++, vtableOffset,
619 typelib_InterfaceAttributeTypeDescription *
>(
620 member)->pAttributeTypeRef));
623 if (!
reinterpret_cast<
624 typelib_InterfaceAttributeTypeDescription *
>(
628 code =
codeSnippet(code, functionOffset++, vtableOffset,
true);
632 case typelib_TypeClass_INTERFACE_METHOD:
635 code, functionOffset++, vtableOffset,
638 typelib_InterfaceMethodTypeDescription *
>(
639 member)->pReturnTypeRef));
646 TYPELIB_DANGER_RELEASE(member);
static typelib_TypeClass 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)
void SAL_CALL uno_destructData(void *pValue, typelib_TypeDescription *pTypeDescr, uno_ReleaseFunc release) SAL_THROW_EXTERN_C()
bool isSimpleType(typelib_TypeClass typeClass)
Determines whether a type is a "simple" type (VOID, BOOLEAN, BYTE, SHORT, UNSIGNED SHORT...
static std::size_t getBlockSize(sal_Int32 slotCount)
Calculate the size of a raw vtable block.
const int codeSnippetSize
bool relatesToInterfaceType(typelib_TypeDescription const *type)
Determines whether a type relates to an interface type (is itself an interface type, or might contain entities of interface type).
const BorderLinePrimitive2D *pCandidateB assert(pCandidateA)
static Slot * initializeBlock(void *block, sal_Int32 slotCount, sal_Int32 vtableNumber, typelib_InterfaceTypeDescription *type)
Initialize a raw vtable block.
typelib_TypeClass __cdecl cpp_mediate(void **pCallStack, const sal_Int32 nFunctionIndex, const sal_Int32 nVtableOffset, sal_Int64 *const pRegisterReturn)
static Slot * mapBlockToVtable(void *block)
Given a pointer to a block, turn it into a vtable pointer.
uno_Mapping * getUno2Cpp()
uno_ExtEnvironment * getCppEnv()
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...
typelib_InterfaceTypeDescription * getTypeDescr()
A cpp proxy wrapping a uno interface.
void SAL_CALL uno_copyAndConvertData(void *pDest, void *pSource, typelib_TypeDescription *pTypeDescr, uno_Mapping *mapping) SAL_THROW_EXTERN_C()
uno_Interface * getUnoI()
struct _typelib_TypeDescription typelib_TypeDescription
uno_Mapping * getCpp2Uno()
register sal_uInt32 r28 __asm__("%r28")
void raiseException(uno_Any *pUnoExc, uno_Mapping *pUno2Cpp)
static unsigned char * codeSnippet(unsigned char *code, sal_Int32 nFunctionIndex, sal_Int32 nVtableOffset, bool bHasHiddenParam)
void cpp_vtable_call(sal_Int32 func, sal_Int32 offset, void **pStack)
is called on incoming vtable calls (called by asm snippets)
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.
#define SAL_WARN(area, stream)
static CppInterfaceProxy * castInterfaceToProxy(void *pInterface)
const OUString & getOid() const