21#include <com/sun/star/uno/genfunc.hxx>
24#include <typelib/typedescription.hxx>
44 typelib_TypeDescriptionReference * pReturnTypeRef,
45 sal_Int32 nParams, typelib_MethodParameter * pParams,
long r8,
46 void ** gpreg,
void ** fpreg,
void ** ovrflw,
47 sal_Int64 * pRegisterReturn )
49#if OSL_DEBUG_LEVEL > 2
50 fprintf(stderr,
"as far as cpp2uno_call\n");
63 TYPELIB_DANGER_GET( &pReturnTypeDescr, pReturnTypeRef );
65 void * pUnoReturn = 0;
66 void * pCppReturn = 0;
72 pCppReturn = *(
void **)gpreg;
77 ? alloca( pReturnTypeDescr->nSize )
82 pCppReturn = (
void *)r8;
85 ? alloca( pReturnTypeDescr->nSize )
90 pUnoReturn = pRegisterReturn;
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;
108 for ( sal_Int32 nPos = 0;
nPos < nParams; ++
nPos )
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);
121#if OSL_DEBUG_LEVEL > 2
122 fprintf(stderr,
"simple\n");
125 switch (pParamTypeDescr->eTypeClass)
127 case typelib_TypeClass_FLOAT:
130 float tmp = (float) (*((
double *)fpreg));
131 (*((
float *) fpreg)) = tmp;
132 pCppArgs[
nPos] = pUnoArgs[
nPos] = fpreg++;
139 pCppArgs[
nPos] = pUnoArgs[
nPos] = ovrflw;
140 bOverflowUsed =
true;
142 if (bOverflowUsed) ovrflw++;
144 case typelib_TypeClass_DOUBLE:
147 pCppArgs[
nPos] = pUnoArgs[
nPos] = fpreg++;
154 pCppArgs[
nPos] = pUnoArgs[
nPos] = ovrflw;
155 bOverflowUsed =
true;
157 if (bOverflowUsed) ovrflw++;
159 case typelib_TypeClass_BYTE:
160 case typelib_TypeClass_BOOLEAN:
161 case typelib_TypeClass_CHAR:
162 case typelib_TypeClass_SHORT:
163 case typelib_TypeClass_UNSIGNED_SHORT:
164 case typelib_TypeClass_ENUM:
165 case typelib_TypeClass_LONG:
166 case typelib_TypeClass_UNSIGNED_LONG:
170 pCppArgs[
nPos] = pUnoArgs[
nPos] = gpreg++;
175 pCppArgs[
nPos] = pUnoArgs[
nPos] = ovrflw;
176 bOverflowUsed =
true;
178 if (bOverflowUsed) ovrflw++;
183 TYPELIB_DANGER_RELEASE( pParamTypeDescr );
187#if OSL_DEBUG_LEVEL > 2
188 fprintf(stderr,
"complex, ng is %d\n", ng);
194 pCppArgs[
nPos] = pCppStack = *gpreg++;
199 pCppArgs[
nPos] = pCppStack = *ovrflw;
200 bOverflowUsed =
true;
202 if (bOverflowUsed) ovrflw++;
207 pUnoArgs[
nPos] = alloca( pParamTypeDescr->nSize );
208 pTempIndices[nTempIndices] =
nPos;
210 ppTempParamTypeDescr[nTempIndices++] = pParamTypeDescr;
216 pCppStack, pParamTypeDescr,
218 pTempIndices[nTempIndices] =
nPos;
220 ppTempParamTypeDescr[nTempIndices++] = pParamTypeDescr;
224 pUnoArgs[
nPos] = pCppStack;
226 TYPELIB_DANGER_RELEASE( pParamTypeDescr );
231#if OSL_DEBUG_LEVEL > 2
232 fprintf(stderr,
"end of params\n");
240 (*pThis->
getUnoI()->pDispatcher)( pThis->
getUnoI(), pMemberTypeDescr, pUnoReturn, pUnoArgs, &pUnoExc );
246 for ( ; nTempIndices--; )
248 sal_Int32
nIndex = pTempIndices[nTempIndices];
250 if (pParams[nIndex].bIn)
251 uno_destructData( pUnoArgs[nIndex], ppTempParamTypeDescr[nTempIndices], 0 );
252 TYPELIB_DANGER_RELEASE( ppTempParamTypeDescr[nTempIndices] );
254 if (pReturnTypeDescr)
255 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 =
ia64::return_via_r8_buffer(pReturnTypeRef) ? typelib_TypeClass_VOID : (typelib_TypeClass)pReturnTypeDescr->eTypeClass;
298 TYPELIB_DANGER_RELEASE( pReturnTypeDescr );
302 return typelib_TypeClass_VOID;
308 sal_uInt64 nOffsetAndIndex,
309 void ** gpreg,
void ** fpreg,
long sp,
long r8,
310 sal_Int64 * pRegisterReturn )
312 static_assert(
sizeof(sal_Int64)==
sizeof(
void *),
"### unexpected!");
314 sal_Int32 nVtableOffset = (nOffsetAndIndex >> 32);
315 sal_Int32 nFunctionIndex = (nOffsetAndIndex & 0xFFFFFFFF);
317 void ** ovrflw = (
void**)(sp);
324 if (nFunctionIndex & 0x80000000 )
326 nFunctionIndex &= 0x7fffffff;
328#if OSL_DEBUG_LEVEL > 2
329 fprintf(stderr,
"pThis is gpreg[1]\n");
335#if OSL_DEBUG_LEVEL > 2
336 fprintf(stderr,
"pThis is gpreg[0]\n");
340#if OSL_DEBUG_LEVEL > 2
341 fprintf(stderr,
"pThis is %p\n", pThis);
344 pThis =
static_cast< char *
>(pThis) - nVtableOffset;
346#if OSL_DEBUG_LEVEL > 2
347 fprintf(stderr,
"pThis is now %p\n", pThis);
354 typelib_InterfaceTypeDescription * pTypeDescr = pCppI->
getTypeDescr();
356#if OSL_DEBUG_LEVEL > 2
357 fprintf(stderr,
"indexes are %d %d\n", nFunctionIndex, pTypeDescr->nMapFunctionIndexToMemberIndex);
360 if (nFunctionIndex >= pTypeDescr->nMapFunctionIndexToMemberIndex)
364 "illegal " << OUString::unacquired(&pTypeDescr->aBase.pTypeName)
365 <<
" vtable index " << nFunctionIndex <<
"/"
366 << pTypeDescr->nMapFunctionIndexToMemberIndex);
368 (
"illegal " + OUString::unacquired(&pTypeDescr->aBase.pTypeName)
369 +
" vtable index " + OUString::number(nFunctionIndex) +
"/"
370 + OUString::number(pTypeDescr->nMapFunctionIndexToMemberIndex)),
375 sal_Int32 nMemberPos = pTypeDescr->pMapFunctionIndexToMemberIndex[nFunctionIndex];
376 assert(nMemberPos < pTypeDescr->nAllMembers);
378#if OSL_DEBUG_LEVEL > 2
379 fprintf(stderr,
"members are %d %d\n", nMemberPos, pTypeDescr->nAllMembers);
382 TypeDescription aMemberDescr( pTypeDescr->ppAllMembers[nMemberPos] );
384 typelib_TypeClass eRet;
385 switch (aMemberDescr.get()->eTypeClass)
387 case typelib_TypeClass_INTERFACE_ATTRIBUTE:
389 if (pTypeDescr->pMapMemberIndexToFunctionIndex[nMemberPos] == nFunctionIndex)
393 pCppI, aMemberDescr.get(),
394 ((typelib_InterfaceAttributeTypeDescription *)aMemberDescr.get())->pAttributeTypeRef,
396 r8, gpreg, fpreg, ovrflw, pRegisterReturn );
401 typelib_MethodParameter aParam;
403 ((typelib_InterfaceAttributeTypeDescription *)aMemberDescr.get())->pAttributeTypeRef;
408 pCppI, aMemberDescr.get(),
411 r8, gpreg, fpreg, ovrflw, pRegisterReturn );
415 case typelib_TypeClass_INTERFACE_METHOD:
418 switch (nFunctionIndex)
422 eRet = typelib_TypeClass_VOID;
426 eRet = typelib_TypeClass_VOID;
431 TYPELIB_DANGER_GET( &pTD,
reinterpret_cast< Type *
>( gpreg[2] )->getTypeLibType() );
437 (
void **)&pInterface, pCppI->
getOid().pData,
438 (typelib_InterfaceTypeDescription *)pTD );
443 reinterpret_cast< uno_Any *
>( gpreg[0] ),
444 &pInterface, pTD, cpp_acquire );
445 pInterface->release();
446 TYPELIB_DANGER_RELEASE( pTD );
447 *(
void **)pRegisterReturn = gpreg[0];
448 eRet = typelib_TypeClass_ANY;
451 TYPELIB_DANGER_RELEASE( pTD );
456 pCppI, aMemberDescr.get(),
457 ((typelib_InterfaceMethodTypeDescription *)aMemberDescr.get())->pReturnTypeRef,
458 ((typelib_InterfaceMethodTypeDescription *)aMemberDescr.get())->nParams,
459 ((typelib_InterfaceMethodTypeDescription *)aMemberDescr.get())->pParams,
460 r8, gpreg, fpreg, ovrflw, pRegisterReturn );
466#if OSL_DEBUG_LEVEL > 2
467 fprintf(stderr,
"screwed\n");
474#if OSL_DEBUG_LEVEL > 2
475 fprintf(stderr,
"end of cpp_mediate\n");
482 long in0,
long in1,
long in2,
long in3,
long in4,
long in5,
long in6,
long in7,
486 register long r15
asm(
"r15");
489 register long r14
asm(
"r14");
490 long nOffsetAndIndex = r14;
492 long sp = (long)&firstonstack;
505 register double f8
asm(
"f8"); fpreg[0] = f8;
506 register double f9
asm(
"f9"); fpreg[1] = f9;
507 register double f10
asm(
"f10"); fpreg[2] = f10;
508 register double f11
asm(
"f11"); fpreg[3] = f11;
509 register double f12
asm(
"f12"); fpreg[4] = f12;
510 register double f13
asm(
"f13"); fpreg[5] = f13;
511 register double f14
asm(
"f14"); fpreg[6] = f14;
512 register double f15
asm(
"f15"); fpreg[7] = f15;
514#if OSL_DEBUG_LEVEL > 2
515 fprintf(stderr,
"cpp_vtable_call called with %lx\n", nOffsetAndIndex);
516 fprintf(stderr,
"adump is %lx %lx %lx %lx %lx %lx %lx %lx\n", in0, in1, in2, in3, in4, in5, in6, in7);
517 fprintf(stderr,
"bdump is %f %f %f %f %f %f %f %f\n", f8, f9, f10, f11, f12, f13, f14, f15);
520 volatile long nRegReturn[4] = { 0 };
522 typelib_TypeClass aType =
523 cpp_mediate( nOffsetAndIndex, (
void**)gpreg, (
void**)fpreg, sp, r8, (sal_Int64*)&nRegReturn[0]);
528 case typelib_TypeClass_VOID:
530 case typelib_TypeClass_BOOLEAN:
531 case typelib_TypeClass_BYTE:
532 case typelib_TypeClass_CHAR:
533 case typelib_TypeClass_UNSIGNED_SHORT:
534 case typelib_TypeClass_SHORT:
535 case typelib_TypeClass_ENUM:
536 case typelib_TypeClass_UNSIGNED_LONG:
537 case typelib_TypeClass_LONG:
538 case typelib_TypeClass_UNSIGNED_HYPER:
539 case typelib_TypeClass_HYPER:
540 ret.
r8 = nRegReturn[0];
542 case typelib_TypeClass_FLOAT:
543 asm volatile(
"ldfs f8=%0" : :
"m"((*((
float*)&nRegReturn))) :
"f8");
545 case typelib_TypeClass_DOUBLE:
546 asm volatile(
"ldfd f8=%0" : :
"m"((*((
double*)&nRegReturn))) :
"f8");
548 case typelib_TypeClass_STRUCT:
549 case typelib_TypeClass_EXCEPTION:
551 ret.
r8 = nRegReturn[0];
552 ret.
r9 = nRegReturn[1];
553 ret.
r10 = nRegReturn[2];
554 ret.
r11 = nRegReturn[3];
568 bool bHasHiddenParam )
570#if OSL_DEBUG_LEVEL > 2
572 fprintf(stderr,
"in codeSnippet functionIndex is %x\n", nFunctionIndex);
573 fprintf(stderr,
"in codeSnippet vtableOffset is %x\n", nVtableOffset);
576 sal_uInt64 nOffsetAndIndex = ( ( (sal_uInt64) nVtableOffset ) << 32 ) | ( (sal_uInt64) nFunctionIndex );
578 if ( bHasHiddenParam )
579 nOffsetAndIndex |= 0x80000000;
581 long *raw = (
long *)code;
586 raw[1] = (long)&raw[2];
587 raw[2] = nOffsetAndIndex;
600 return static_cast< Slot *
>(block) + 2;
612 Slot * slots = mapBlockToVtable(block);
616 return slots + slotCount;
620 Slot ** in_slots,
unsigned char * code, sal_PtrDiff writetoexecdiff,
621 typelib_InterfaceTypeDescription
const * type, sal_Int32 functionOffset,
622 sal_Int32 functionCount, sal_Int32 vtableOffset)
624 (*in_slots) -= functionCount;
625 Slot * slots = *in_slots;
626#if OSL_DEBUG_LEVEL > 2
627 fprintf(stderr,
"in addLocalFunctions functionOffset is %x\n",functionOffset);
628 fprintf(stderr,
"in addLocalFunctions vtableOffset is %x\n",vtableOffset);
631 for (sal_Int32 i = 0;
i <
type->nMembers; ++
i) {
633 TYPELIB_DANGER_GET(&member,
type->ppMembers[i]);
635 switch (member->eTypeClass) {
636 case typelib_TypeClass_INTERFACE_ATTRIBUTE:
639 code, writetoexecdiff, functionOffset++, vtableOffset,
642 typelib_InterfaceAttributeTypeDescription *
>(
643 member)->pAttributeTypeRef));
648 if (!
reinterpret_cast<
649 typelib_InterfaceAttributeTypeDescription *
>(
652 *slots++ =
codeSnippet(code, writetoexecdiff, functionOffset++, vtableOffset,
false);
657 case typelib_TypeClass_INTERFACE_METHOD:
659 code, writetoexecdiff, functionOffset++, vtableOffset,
662 typelib_InterfaceMethodTypeDescription *
>(
663 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(* privateSnippetExecutor)()
ia64::RegReturn cpp_vtable_call(long in0, long in1, long in2, long in3, long in4, long in5, long in6, long in7, long firstonstack)
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_via_r8_buffer(typelib_TypeDescriptionReference *pTypeRef)
bool return_in_hidden_param(typelib_TypeDescriptionReference *pTypeRef)