21#include <com/sun/star/uno/genfunc.hxx>
24#include <typelib/typedescription.hxx>
45 typelib_TypeDescriptionReference * pReturnTypeRef,
46 sal_Int32 nParams, typelib_MethodParameter * pParams,
long r8,
47 void ** gpreg,
void ** fpreg,
void ** ovrflw,
48 sal_Int64 * pRegisterReturn )
50#if OSL_DEBUG_LEVEL > 2
51 fprintf(stderr,
"as far as cpp2uno_call\n");
64 TYPELIB_DANGER_GET( &pReturnTypeDescr, pReturnTypeRef );
66 void * pUnoReturn = 0;
67 void * pCppReturn = 0;
73 pCppReturn = *(
void **)gpreg;
78 ? alloca( pReturnTypeDescr->nSize )
83 pCppReturn = (
void *)r8;
86 ? alloca( pReturnTypeDescr->nSize )
91 pUnoReturn = pRegisterReturn;
98 static_assert(
sizeof(
void *) ==
sizeof(sal_Int64),
"### unexpected size!");
100 void ** pUnoArgs = (
void **)alloca( 4 *
sizeof(
void *) * nParams );
101 void ** pCppArgs = pUnoArgs + nParams;
103 sal_Int32 * pTempIndices = (sal_Int32 *)(pUnoArgs + (2 * nParams));
107 sal_Int32 nTempIndices = 0;
108 bool bOverflowUsed =
false;
109 for ( sal_Int32 nPos = 0;
nPos < nParams; ++
nPos )
111 const typelib_MethodParameter & rParam = pParams[
nPos];
113 TYPELIB_DANGER_GET( &pParamTypeDescr, rParam.pTypeRef );
115#if OSL_DEBUG_LEVEL > 2
116 fprintf(stderr,
"arg %d of %d\n", nPos, nParams);
122#if OSL_DEBUG_LEVEL > 2
123 fprintf(stderr,
"simple\n");
126 switch (pParamTypeDescr->eTypeClass)
128 case typelib_TypeClass_FLOAT:
131 float tmp = (float) (*((
double *)fpreg));
132 (*((
float *) fpreg)) = tmp;
133 pCppArgs[
nPos] = pUnoArgs[
nPos] = fpreg++;
140 pCppArgs[
nPos] = pUnoArgs[
nPos] = ovrflw;
141 bOverflowUsed =
true;
143 if (bOverflowUsed) ovrflw++;
145 case typelib_TypeClass_DOUBLE:
148 pCppArgs[
nPos] = pUnoArgs[
nPos] = fpreg++;
155 pCppArgs[
nPos] = pUnoArgs[
nPos] = ovrflw;
156 bOverflowUsed =
true;
158 if (bOverflowUsed) ovrflw++;
160 case typelib_TypeClass_BYTE:
161 case typelib_TypeClass_BOOLEAN:
162 case typelib_TypeClass_CHAR:
163 case typelib_TypeClass_SHORT:
164 case typelib_TypeClass_UNSIGNED_SHORT:
165 case typelib_TypeClass_ENUM:
166 case typelib_TypeClass_LONG:
167 case typelib_TypeClass_UNSIGNED_LONG:
171 pCppArgs[
nPos] = pUnoArgs[
nPos] = gpreg++;
176 pCppArgs[
nPos] = pUnoArgs[
nPos] = ovrflw;
177 bOverflowUsed =
true;
179 if (bOverflowUsed) ovrflw++;
184 TYPELIB_DANGER_RELEASE( pParamTypeDescr );
188#if OSL_DEBUG_LEVEL > 2
189 fprintf(stderr,
"complex, ng is %d\n", ng);
195 pCppArgs[
nPos] = pCppStack = *gpreg++;
200 pCppArgs[
nPos] = pCppStack = *ovrflw;
201 bOverflowUsed =
true;
203 if (bOverflowUsed) ovrflw++;
208 pUnoArgs[
nPos] = alloca( pParamTypeDescr->nSize );
209 pTempIndices[nTempIndices] =
nPos;
211 ppTempParamTypeDescr[nTempIndices++] = pParamTypeDescr;
217 pCppStack, pParamTypeDescr,
219 pTempIndices[nTempIndices] =
nPos;
221 ppTempParamTypeDescr[nTempIndices++] = pParamTypeDescr;
225 pUnoArgs[
nPos] = pCppStack;
227 TYPELIB_DANGER_RELEASE( pParamTypeDescr );
232#if OSL_DEBUG_LEVEL > 2
233 fprintf(stderr,
"end of params\n");
241 (*pThis->
getUnoI()->pDispatcher)( pThis->
getUnoI(), pMemberTypeDescr, pUnoReturn, pUnoArgs, &pUnoExc );
247 for ( ; nTempIndices--; )
249 sal_Int32
nIndex = pTempIndices[nTempIndices];
251 if (pParams[nIndex].bIn)
252 uno_destructData( pUnoArgs[nIndex], ppTempParamTypeDescr[nTempIndices], 0 );
253 TYPELIB_DANGER_RELEASE( ppTempParamTypeDescr[nTempIndices] );
255 if (pReturnTypeDescr)
256 TYPELIB_DANGER_RELEASE( pReturnTypeDescr );
261 return typelib_TypeClass_VOID;
266 for ( ; nTempIndices--; )
268 sal_Int32
nIndex = pTempIndices[nTempIndices];
271 if (pParams[nIndex].bOut)
281 TYPELIB_DANGER_RELEASE( pParamTypeDescr );
286 if (pUnoReturn != pCppReturn)
294 *(
void **)pRegisterReturn = pCppReturn;
296 if (pReturnTypeDescr)
298 typelib_TypeClass eRet =
ia64::return_via_r8_buffer(pReturnTypeRef) ? typelib_TypeClass_VOID : (typelib_TypeClass)pReturnTypeDescr->eTypeClass;
299 TYPELIB_DANGER_RELEASE( pReturnTypeDescr );
303 return typelib_TypeClass_VOID;
309 sal_uInt64 nOffsetAndIndex,
310 void ** gpreg,
void ** fpreg,
long sp,
long r8,
311 sal_Int64 * pRegisterReturn )
313 static_assert(
sizeof(sal_Int64)==
sizeof(
void *),
"### unexpected!");
315 sal_Int32 nVtableOffset = (nOffsetAndIndex >> 32);
316 sal_Int32 nFunctionIndex = (nOffsetAndIndex & 0xFFFFFFFF);
318 void ** ovrflw = (
void**)(sp);
325 if (nFunctionIndex & 0x80000000 )
327 nFunctionIndex &= 0x7fffffff;
329#if OSL_DEBUG_LEVEL > 2
330 fprintf(stderr,
"pThis is gpreg[1]\n");
336#if OSL_DEBUG_LEVEL > 2
337 fprintf(stderr,
"pThis is gpreg[0]\n");
341#if OSL_DEBUG_LEVEL > 2
342 fprintf(stderr,
"pThis is %p\n", pThis);
345 pThis =
static_cast< char *
>(pThis) - nVtableOffset;
347#if OSL_DEBUG_LEVEL > 2
348 fprintf(stderr,
"pThis is now %p\n", pThis);
355 typelib_InterfaceTypeDescription * pTypeDescr = pCppI->
getTypeDescr();
357#if OSL_DEBUG_LEVEL > 2
358 fprintf(stderr,
"indexes are %d %d\n", nFunctionIndex, pTypeDescr->nMapFunctionIndexToMemberIndex);
361 if (nFunctionIndex >= pTypeDescr->nMapFunctionIndexToMemberIndex)
365 "illegal " << OUString::unacquired(&pTypeDescr->aBase.pTypeName)
366 <<
" vtable index " << nFunctionIndex <<
"/"
367 << pTypeDescr->nMapFunctionIndexToMemberIndex);
369 (
"illegal " + OUString::unacquired(&pTypeDescr->aBase.pTypeName)
370 +
" vtable index " + OUString::number(nFunctionIndex) +
"/"
371 + OUString::number(pTypeDescr->nMapFunctionIndexToMemberIndex)),
376 sal_Int32 nMemberPos = pTypeDescr->pMapFunctionIndexToMemberIndex[nFunctionIndex];
377 assert(nMemberPos < pTypeDescr->nAllMembers);
379#if OSL_DEBUG_LEVEL > 2
380 fprintf(stderr,
"members are %d %d\n", nMemberPos, pTypeDescr->nAllMembers);
383 TypeDescription aMemberDescr( pTypeDescr->ppAllMembers[nMemberPos] );
385 typelib_TypeClass eRet;
386 switch (aMemberDescr.get()->eTypeClass)
388 case typelib_TypeClass_INTERFACE_ATTRIBUTE:
390 if (pTypeDescr->pMapMemberIndexToFunctionIndex[nMemberPos] == nFunctionIndex)
394 pCppI, aMemberDescr.get(),
395 ((typelib_InterfaceAttributeTypeDescription *)aMemberDescr.get())->pAttributeTypeRef,
397 r8, gpreg, fpreg, ovrflw, pRegisterReturn );
402 typelib_MethodParameter aParam;
404 ((typelib_InterfaceAttributeTypeDescription *)aMemberDescr.get())->pAttributeTypeRef;
409 pCppI, aMemberDescr.get(),
412 r8, gpreg, fpreg, ovrflw, pRegisterReturn );
416 case typelib_TypeClass_INTERFACE_METHOD:
419 switch (nFunctionIndex)
423 eRet = typelib_TypeClass_VOID;
427 eRet = typelib_TypeClass_VOID;
432 TYPELIB_DANGER_GET( &pTD,
reinterpret_cast< Type *
>( gpreg[2] )->getTypeLibType() );
438 (
void **)&pInterface, pCppI->
getOid().pData,
439 (typelib_InterfaceTypeDescription *)pTD );
444 reinterpret_cast< uno_Any *
>( gpreg[0] ),
445 &pInterface, pTD, cpp_acquire );
446 pInterface->release();
447 TYPELIB_DANGER_RELEASE( pTD );
448 *(
void **)pRegisterReturn = gpreg[0];
449 eRet = typelib_TypeClass_ANY;
452 TYPELIB_DANGER_RELEASE( pTD );
457 pCppI, aMemberDescr.get(),
458 ((typelib_InterfaceMethodTypeDescription *)aMemberDescr.get())->pReturnTypeRef,
459 ((typelib_InterfaceMethodTypeDescription *)aMemberDescr.get())->nParams,
460 ((typelib_InterfaceMethodTypeDescription *)aMemberDescr.get())->pParams,
461 r8, gpreg, fpreg, ovrflw, pRegisterReturn );
467#if OSL_DEBUG_LEVEL > 2
468 fprintf(stderr,
"screwed\n");
475#if OSL_DEBUG_LEVEL > 2
476 fprintf(stderr,
"end of cpp_mediate\n");
483 long in0,
long in1,
long in2,
long in3,
long in4,
long in5,
long in6,
long in7,
487 register long r15
asm(
"r15");
490 register long r14
asm(
"r14");
491 long nOffsetAndIndex = r14;
493 long sp = (long)&firstonstack;
506 register double f8
asm(
"f8"); fpreg[0] = f8;
507 register double f9
asm(
"f9"); fpreg[1] = f9;
508 register double f10
asm(
"f10"); fpreg[2] = f10;
509 register double f11
asm(
"f11"); fpreg[3] = f11;
510 register double f12
asm(
"f12"); fpreg[4] = f12;
511 register double f13
asm(
"f13"); fpreg[5] = f13;
512 register double f14
asm(
"f14"); fpreg[6] = f14;
513 register double f15
asm(
"f15"); fpreg[7] = f15;
515#if OSL_DEBUG_LEVEL > 2
516 fprintf(stderr,
"cpp_vtable_call called with %lx\n", nOffsetAndIndex);
517 fprintf(stderr,
"adump is %lx %lx %lx %lx %lx %lx %lx %lx\n", in0, in1, in2, in3, in4, in5, in6, in7);
518 fprintf(stderr,
"bdump is %f %f %f %f %f %f %f %f\n", f8, f9, f10, f11, f12, f13, f14, f15);
521 volatile long nRegReturn[4] = { 0 };
523 typelib_TypeClass aType =
524 cpp_mediate( nOffsetAndIndex, (
void**)gpreg, (
void**)fpreg, sp, r8, (sal_Int64*)&nRegReturn[0]);
529 case typelib_TypeClass_VOID:
531 case typelib_TypeClass_BOOLEAN:
532 case typelib_TypeClass_BYTE:
533 case typelib_TypeClass_CHAR:
534 case typelib_TypeClass_UNSIGNED_SHORT:
535 case typelib_TypeClass_SHORT:
536 case typelib_TypeClass_ENUM:
537 case typelib_TypeClass_UNSIGNED_LONG:
538 case typelib_TypeClass_LONG:
539 case typelib_TypeClass_UNSIGNED_HYPER:
540 case typelib_TypeClass_HYPER:
541 ret.
r8 = nRegReturn[0];
543 case typelib_TypeClass_FLOAT:
544 asm volatile(
"ldfs f8=%0" : :
"m"((*((
float*)&nRegReturn))) :
"f8");
546 case typelib_TypeClass_DOUBLE:
547 asm volatile(
"ldfd f8=%0" : :
"m"((*((
double*)&nRegReturn))) :
"f8");
549 case typelib_TypeClass_STRUCT:
550 case typelib_TypeClass_EXCEPTION:
552 ret.
r8 = nRegReturn[0];
553 ret.
r9 = nRegReturn[1];
554 ret.
r10 = nRegReturn[2];
555 ret.
r11 = nRegReturn[3];
569 bool bHasHiddenParam )
571#if OSL_DEBUG_LEVEL > 2
573 fprintf(stderr,
"in codeSnippet functionIndex is %x\n", nFunctionIndex);
574 fprintf(stderr,
"in codeSnippet vtableOffset is %x\n", nVtableOffset);
577 sal_uInt64 nOffsetAndIndex = ( ( (sal_uInt64) nVtableOffset ) << 32 ) | ( (sal_uInt64) nFunctionIndex );
579 if ( bHasHiddenParam )
580 nOffsetAndIndex |= 0x80000000;
582 long *raw = (
long *)code;
587 raw[1] = (long)&raw[2];
588 raw[2] = nOffsetAndIndex;
601 return static_cast< Slot *
>(block) + 1;
619 Slot * slots = mapBlockToVtable(block);
620 slots[-1] = {0,
reinterpret_cast<sal_uInt64
>(&
typeid(ProxyRtti))};
621 return slots + slotCount;
625 Slot ** in_slots,
unsigned char * code, sal_PtrDiff writetoexecdiff,
626 typelib_InterfaceTypeDescription
const * type, sal_Int32 functionOffset,
627 sal_Int32 functionCount, sal_Int32 vtableOffset)
629 (*in_slots) -= functionCount;
630 Slot * slots = *in_slots;
631#if OSL_DEBUG_LEVEL > 2
632 fprintf(stderr,
"in addLocalFunctions functionOffset is %x\n",functionOffset);
633 fprintf(stderr,
"in addLocalFunctions vtableOffset is %x\n",vtableOffset);
636 for (sal_Int32 i = 0;
i <
type->nMembers; ++
i) {
638 TYPELIB_DANGER_GET(&member,
type->ppMembers[i]);
640 switch (member->eTypeClass) {
641 case typelib_TypeClass_INTERFACE_ATTRIBUTE:
644 code, writetoexecdiff, functionOffset++, vtableOffset,
647 typelib_InterfaceAttributeTypeDescription *
>(
648 member)->pAttributeTypeRef));
653 if (!
reinterpret_cast<
654 typelib_InterfaceAttributeTypeDescription *
>(
657 *slots++ =
codeSnippet(code, writetoexecdiff, functionOffset++, vtableOffset,
false);
662 case typelib_TypeClass_INTERFACE_METHOD:
664 code, writetoexecdiff, functionOffset++, vtableOffset,
667 typelib_InterfaceMethodTypeDescription *
>(
668 member)->pReturnTypeRef));
676 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)