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,...