21#include <com/sun/star/uno/genfunc.hxx>
24#include <typelib/typedescription.hxx>
42 typelib_TypeDescriptionReference * pReturnTypeRef,
43 sal_Int32 nParams, typelib_MethodParameter * pParams,
44 void ** gpreg,
void ** fpreg,
void ** ovrflw,
45 sal_Int64 * pRegisterReturn )
47#if OSL_DEBUG_LEVEL > 2
48 fprintf(stderr,
"as far as cpp2uno_call\n");
60 TYPELIB_DANGER_GET( &pReturnTypeDescr, pReturnTypeRef );
62 void * pUnoReturn = 0;
63 void * pCppReturn = 0;
69 pUnoReturn = pRegisterReturn;
73 pCppReturn = *(
void **)gpreg;
78 ? alloca( pReturnTypeDescr->nSize )
87 static_assert(
sizeof(
void *) ==
sizeof(sal_Int64),
"### unexpected size!");
89 void ** pUnoArgs = (
void **)alloca( 4 *
sizeof(
void *) * nParams );
90 void ** pCppArgs = pUnoArgs + nParams;
92 sal_Int32 * pTempIndices = (sal_Int32 *)(pUnoArgs + (2 * nParams));
96 sal_Int32 nTempIndices = 0;
97 for ( sal_Int32 nPos = 0;
nPos < nParams; ++
nPos )
99 const typelib_MethodParameter & rParam = pParams[
nPos];
101 TYPELIB_DANGER_GET( &pParamTypeDescr, rParam.pTypeRef );
103#if OSL_DEBUG_LEVEL > 2
104 fprintf(stderr,
"arg %d of %d\n", nPos, nParams);
109#if OSL_DEBUG_LEVEL > 2
110 fprintf(stderr,
"simple\n");
113 switch (pParamTypeDescr->eTypeClass)
115 case typelib_TypeClass_FLOAT:
116 case typelib_TypeClass_DOUBLE:
119 if (pParamTypeDescr->eTypeClass == typelib_TypeClass_FLOAT)
121 float tmp = (float) (*((
double *)fpreg));
122 (*((
float *) fpreg)) = tmp;
125 pCppArgs[
nPos] = pUnoArgs[
nPos] = fpreg++;
130 pCppArgs[
nPos] = pUnoArgs[
nPos] = ovrflw;
134 case typelib_TypeClass_BYTE:
135 case typelib_TypeClass_BOOLEAN:
138 pCppArgs[
nPos] = pUnoArgs[
nPos] = (((
char *)gpreg) + (
sizeof(
void*)-1));
144 pCppArgs[
nPos] = pUnoArgs[
nPos] = (((
char *)ovrflw) + (
sizeof(
void*)-1));
148 case typelib_TypeClass_CHAR:
149 case typelib_TypeClass_SHORT:
150 case typelib_TypeClass_UNSIGNED_SHORT:
153 pCppArgs[
nPos] = pUnoArgs[
nPos] = (((
char *)gpreg) + (
sizeof(
void*)-2));
159 pCppArgs[
nPos] = pUnoArgs[
nPos] = (((
char *)ovrflw) + (
sizeof(
void*)-2));
163 case typelib_TypeClass_ENUM:
164 case typelib_TypeClass_LONG:
165 case typelib_TypeClass_UNSIGNED_LONG:
168 pCppArgs[
nPos] = pUnoArgs[
nPos] = (((
char *)gpreg) + (
sizeof(
void*)-4));
174 pCppArgs[
nPos] = pUnoArgs[
nPos] = (((
char *)ovrflw) + (
sizeof(
void*)-4));
181 pCppArgs[
nPos] = pUnoArgs[
nPos] = gpreg++;
186 pCppArgs[
nPos] = pUnoArgs[
nPos] = ovrflw;
193 TYPELIB_DANGER_RELEASE( pParamTypeDescr );
197#if OSL_DEBUG_LEVEL > 2
198 fprintf(stderr,
"complex, ng is %d\n", ng);
205 pCppArgs[
nPos] = pCppStack = *gpreg++;
210 pCppArgs[
nPos] = pCppStack = *ovrflw;
217 pUnoArgs[
nPos] = alloca( pParamTypeDescr->nSize );
218 pTempIndices[nTempIndices] =
nPos;
220 ppTempParamTypeDescr[nTempIndices++] = pParamTypeDescr;
226 pCppStack, pParamTypeDescr,
228 pTempIndices[nTempIndices] =
nPos;
230 ppTempParamTypeDescr[nTempIndices++] = pParamTypeDescr;
234 pUnoArgs[
nPos] = pCppStack;
236 TYPELIB_DANGER_RELEASE( pParamTypeDescr );
241#if OSL_DEBUG_LEVEL > 2
242 fprintf(stderr,
"end of params\n");
250 (*pThis->
getUnoI()->pDispatcher)( pThis->
getUnoI(), pMemberTypeDescr, pUnoReturn, pUnoArgs, &pUnoExc );
256 for ( ; nTempIndices--; )
258 sal_Int32
nIndex = pTempIndices[nTempIndices];
260 if (pParams[nIndex].bIn)
261 uno_destructData( pUnoArgs[nIndex], ppTempParamTypeDescr[nTempIndices], 0 );
262 TYPELIB_DANGER_RELEASE( ppTempParamTypeDescr[nTempIndices] );
264 if (pReturnTypeDescr)
265 TYPELIB_DANGER_RELEASE( pReturnTypeDescr );
269 return typelib_TypeClass_VOID;
274 for ( ; nTempIndices--; )
276 sal_Int32
nIndex = pTempIndices[nTempIndices];
279 if (pParams[nIndex].bOut)
289 TYPELIB_DANGER_RELEASE( pParamTypeDescr );
294 if (pUnoReturn != pCppReturn)
302 *(
void **)pRegisterReturn = pCppReturn;
304 if (pReturnTypeDescr)
306 typelib_TypeClass eRet = (typelib_TypeClass)pReturnTypeDescr->eTypeClass;
307 TYPELIB_DANGER_RELEASE( pReturnTypeDescr );
311 return typelib_TypeClass_VOID;
317 sal_uInt64 nOffsetAndIndex,
318 void ** gpreg,
void ** fpreg,
void ** ovrflw,
319 sal_Int64 * pRegisterReturn )
321 static_assert(
sizeof(sal_Int64)==
sizeof(
void *),
"### unexpected!");
323 sal_Int32 nVtableOffset = (nOffsetAndIndex >> 32);
324 sal_Int32 nFunctionIndex = (nOffsetAndIndex & 0xFFFFFFFF);
326#if OSL_DEBUG_LEVEL > 2
327 fprintf(stderr,
"nVTableOffset, nFunctionIndex are %x %x\n", nVtableOffset, nFunctionIndex);
330#if OSL_DEBUG_LEVEL > 2
333 fprintf( stderr,
"= cpp_mediate () =\nGPR's (%d): ", 5 );
334 for (
unsigned int i = 0;
i < 5; ++
i )
335 fprintf( stderr,
"0x%lx, ", gpreg[i] );
336 fprintf( stderr,
"\n");
337 fprintf( stderr,
"\nFPR's (%d): ", 4 );
338 for (
unsigned int i = 0;
i < 4; ++
i )
339 fprintf( stderr,
"0x%lx (%f), ", fpreg[i], fpreg[i] );
340 fprintf( stderr,
"\n");
351 if( nFunctionIndex & 0x80000000 )
353 nFunctionIndex &= 0x7fffffff;
361 pThis =
static_cast< char *
>(pThis) - nVtableOffset;
367 typelib_InterfaceTypeDescription * pTypeDescr = pCppI->
getTypeDescr();
370 if (nFunctionIndex >= pTypeDescr->nMapFunctionIndexToMemberIndex)
374 "illegal " << OUString::unacquired(&pTypeDescr->aBase.pTypeName)
375 <<
" vtable index " << nFunctionIndex <<
"/"
376 << pTypeDescr->nMapFunctionIndexToMemberIndex);
378 (
"illegal " + OUString::unacquired(&pTypeDescr->aBase.pTypeName)
379 +
" vtable index " + OUString::number(nFunctionIndex) +
"/"
380 + OUString::number(pTypeDescr->nMapFunctionIndexToMemberIndex)),
385 sal_Int32 nMemberPos = pTypeDescr->pMapFunctionIndexToMemberIndex[nFunctionIndex];
386 assert(nMemberPos < pTypeDescr->nAllMembers);
388 TypeDescription aMemberDescr( pTypeDescr->ppAllMembers[nMemberPos] );
390 typelib_TypeClass eRet;
391 switch (aMemberDescr.get()->eTypeClass)
393 case typelib_TypeClass_INTERFACE_ATTRIBUTE:
395 if (pTypeDescr->pMapMemberIndexToFunctionIndex[nMemberPos] == nFunctionIndex)
399 pCppI, aMemberDescr.get(),
400 ((typelib_InterfaceAttributeTypeDescription *)aMemberDescr.get())->pAttributeTypeRef,
402 gpreg, fpreg, ovrflw, pRegisterReturn );
407 typelib_MethodParameter aParam;
409 ((typelib_InterfaceAttributeTypeDescription *)aMemberDescr.get())->pAttributeTypeRef;
414 pCppI, aMemberDescr.get(),
417 gpreg, fpreg, ovrflw, pRegisterReturn );
421 case typelib_TypeClass_INTERFACE_METHOD:
424 switch (nFunctionIndex)
428 eRet = typelib_TypeClass_VOID;
432 eRet = typelib_TypeClass_VOID;
437 TYPELIB_DANGER_GET( &pTD,
reinterpret_cast< Type *
>( gpreg[2] )->getTypeLibType() );
443 (
void **)&pInterface, pCppI->
getOid().pData,
444 (typelib_InterfaceTypeDescription *)pTD );
449 reinterpret_cast< uno_Any *
>( gpreg[0] ),
450 &pInterface, pTD, cpp_acquire );
451 pInterface->release();
452 TYPELIB_DANGER_RELEASE( pTD );
453 *(
void **)pRegisterReturn = gpreg[0];
454 eRet = typelib_TypeClass_ANY;
457 TYPELIB_DANGER_RELEASE( pTD );
462 pCppI, aMemberDescr.get(),
463 ((typelib_InterfaceMethodTypeDescription *)aMemberDescr.get())->pReturnTypeRef,
464 ((typelib_InterfaceMethodTypeDescription *)aMemberDescr.get())->nParams,
465 ((typelib_InterfaceMethodTypeDescription *)aMemberDescr.get())->pParams,
466 gpreg, fpreg, ovrflw, pRegisterReturn );
481 register long r0
asm(
"r0");
482 sal_uInt64 nOffsetAndIndex = r0;
484 long sp = (long)&firstonstack;
494 register double f0
asm(
"f0"); fpreg[0] = f0;
495 register double f2
asm(
"f2"); fpreg[1] = f2;
496 register double f4
asm(
"f4"); fpreg[2] = f4;
497 register double f6
asm(
"f6"); fpreg[3] = f6;
499 volatile long nRegReturn[1];
500#if OSL_DEBUG_LEVEL > 2
501 fprintf(stderr,
"before mediate with %lx\n",nOffsetAndIndex);
502 fprintf(stderr,
"doubles are %f %f %f %f\n", fpreg[0], fpreg[1], fpreg[2], fpreg[3]);
504 typelib_TypeClass aType =
505 cpp_mediate( nOffsetAndIndex, (
void**)gpreg, (
void**)fpreg, (
void**)sp,
506 (sal_Int64*)nRegReturn );
507#if OSL_DEBUG_LEVEL > 2
508 fprintf(stderr,
"after mediate ret is %lx %ld\n", nRegReturn[0], nRegReturn[0]);
513 case typelib_TypeClass_BOOLEAN:
514 case typelib_TypeClass_BYTE:
515 nRegReturn[0] = (
unsigned long)(*(
unsigned char *)nRegReturn);
517 case typelib_TypeClass_CHAR:
518 case typelib_TypeClass_UNSIGNED_SHORT:
519 case typelib_TypeClass_SHORT:
520 nRegReturn[0] = (
unsigned long)(*(
unsigned short *)nRegReturn);
522 case typelib_TypeClass_ENUM:
523 case typelib_TypeClass_UNSIGNED_LONG:
524 case typelib_TypeClass_LONG:
525 nRegReturn[0] = (
unsigned long)(*(
unsigned int *)nRegReturn);
527 case typelib_TypeClass_VOID:
530 case typelib_TypeClass_FLOAT:
532 double tmp = (double) (*((
float *)nRegReturn));
533 (*((
double *) nRegReturn)) = tmp;
536 case typelib_TypeClass_DOUBLE:
538 : :
"m" (*((
double*)nRegReturn)) );
541 return nRegReturn[0];
546unsigned char *
codeSnippet(
unsigned char * code, sal_Int32 nFunctionIndex, sal_Int32 nVtableOffset,
bool simple_ret_type )
548 sal_uInt64 nOffsetAndIndex = ( ( (sal_uInt64) nVtableOffset ) << 32 ) | ( (sal_Int64) nFunctionIndex );
550 if (! simple_ret_type)
551 nOffsetAndIndex |= 0x80000000;
553 unsigned char *
p =
code;
554 *(
short *)&
p[0] = 0x0d10;
555 *(
short *)&
p[2] = 0xeb01;
556 *(
short *)&
p[4] = 0x100e;
557 *(
short *)&
p[6] = 0x0004;
558 *(
short *)&
p[8] = 0x07f1;
559 *(
long *)&
p[16] = (
long)nOffsetAndIndex;
574 return static_cast< Slot *
>(block) + 2;
591 void * block, sal_Int32 slotCount, sal_Int32,
592 typelib_InterfaceTypeDescription *)
594 Slot * slots = mapBlockToVtable(block);
596 slots[-1].fn = &
typeid(ProxyRtti);
597 return slots + slotCount;
601 Slot ** slots,
unsigned char * code, sal_PtrDiff writetoexecdiff,
602 typelib_InterfaceTypeDescription
const * type, sal_Int32 functionOffset,
603 sal_Int32 functionCount, sal_Int32 vtableOffset)
605 (*slots) -= functionCount;
607#if OSL_DEBUG_LEVEL > 2
608 fprintf(stderr,
"in addLocalFunctions functionOffset is %x\n",functionOffset);
609 fprintf(stderr,
"in addLocalFunctions vtableOffset is %x\n",vtableOffset);
612 for (sal_Int32 i = 0;
i <
type->nMembers; ++
i) {
614 TYPELIB_DANGER_GET(&member,
type->ppMembers[i]);
616 switch (member->eTypeClass) {
617 case typelib_TypeClass_INTERFACE_ATTRIBUTE:
619 (s++)->fn = code + writetoexecdiff;
621 code, functionOffset++, vtableOffset,
624 typelib_InterfaceAttributeTypeDescription *
>(
625 member)->pAttributeTypeRef));
628 if (!
reinterpret_cast<
629 typelib_InterfaceAttributeTypeDescription *
>(
632 (s++)->fn = code + writetoexecdiff;
637 case typelib_TypeClass_INTERFACE_METHOD:
638 (s++)->fn = code + writetoexecdiff;
640 code, functionOffset++, vtableOffset,
643 typelib_InterfaceMethodTypeDescription *
>(
644 member)->pReturnTypeRef));
651 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,...