24#include <com/sun/star/uno/genfunc.hxx>
26#include <typelib/typedescription.hxx>
35 __asm__( "ldx %0, %%l0\n\t" \
36 "std %%f" #n ", [%%l0]\n" \
45 for (
const typelib_CompoundTypeDescription *
p
46 =
reinterpret_cast< const typelib_CompoundTypeDescription *
>(
type);
47 p !=
NULL;
p =
p->pBaseTypeDescription)
49 for (sal_Int32
i = 0;
i <
p->nMembers; ++
i)
51 if (
p->ppTypeRefs[
i]->eTypeClass == typelib_TypeClass_STRUCT ||
52 p->ppTypeRefs[
i]->eTypeClass == typelib_TypeClass_EXCEPTION)
55 TYPELIB_DANGER_GET(&
t,
p->ppTypeRefs[
i]);
57 TYPELIB_DANGER_RELEASE(
t);
73 else if (pTypeRef->eTypeClass == typelib_TypeClass_STRUCT ||
74 pTypeRef->eTypeClass == typelib_TypeClass_EXCEPTION)
77 TYPELIB_DANGER_GET( &pTypeDescr, pTypeRef );
82 TYPELIB_DANGER_RELEASE( pTypeDescr );
96 typelib_TypeDescriptionReference * pReturnTypeRef,
97 sal_Int32 nParams, typelib_MethodParameter * pParams,
99 sal_Int64 * pRegisterReturn )
102 char * pCppStack = (
char *)pCallStack;
107 TYPELIB_DANGER_GET( &pReturnTypeDescr, pReturnTypeRef );
109 void * pUnoReturn = 0;
110 void * pCppReturn = 0;
113 if (pReturnTypeDescr)
117 pCppReturn = *(
void**)pCppStack;
120 ? alloca( pReturnTypeDescr->nSize )
122 pCppStack +=
sizeof(
void* );
127 pUnoReturn = pRegisterReturn;
136 pCppStack +=
sizeof(
void* );
139 static_assert(
sizeof(
void *) ==
sizeof(sal_Int64),
"### unexpected size!");
141 void ** pUnoArgs = (
void **)alloca( 4 *
sizeof(
void *) * nParams );
142 void ** pCppArgs = pUnoArgs + nParams;
144 sal_Int32 * pTempIndices = (sal_Int32 *)(pUnoArgs + (2 * nParams));
148 sal_Int32 nTempIndices = 0;
150 for ( sal_Int32 nPos = 0;
nPos < nParams; ++
nPos )
152 const typelib_MethodParameter & rParam = pParams[
nPos];
154 TYPELIB_DANGER_GET( &pParamTypeDescr, rParam.pTypeRef );
159 switch (pParamTypeDescr->eTypeClass) {
160 case typelib_TypeClass_FLOAT:
161 case typelib_TypeClass_DOUBLE:
163 int paramArrayIdx =
nPos + paramsOffset;
164 assert(paramArrayIdx < nParams + paramsOffset);
165 switch (paramArrayIdx) {
220 TYPELIB_DANGER_RELEASE( pParamTypeDescr );
224 pCppArgs[
nPos] = *(
void **)pCppStack;
229 pUnoArgs[
nPos] = alloca( pParamTypeDescr->nSize );
230 pTempIndices[nTempIndices] =
nPos;
232 ppTempParamTypeDescr[nTempIndices++] = pParamTypeDescr;
239 *(
void **)pCppStack, pParamTypeDescr,
241 pTempIndices[nTempIndices] =
nPos;
243 ppTempParamTypeDescr[nTempIndices++] = pParamTypeDescr;
247 pUnoArgs[
nPos] = *(
void **)pCppStack;
249 TYPELIB_DANGER_RELEASE( pParamTypeDescr );
252 pCppStack +=
sizeof(sal_Int64);
260 (*pThis->
getUnoI()->pDispatcher)(pThis->
getUnoI(), pMemberTypeDescr, pUnoReturn, pUnoArgs, &pUnoExc );
266 for ( ; nTempIndices--; )
268 sal_Int32
nIndex = pTempIndices[nTempIndices];
270 if (pParams[nIndex].bIn)
271 uno_destructData( pUnoArgs[nIndex], ppTempParamTypeDescr[nTempIndices], 0 );
272 TYPELIB_DANGER_RELEASE( ppTempParamTypeDescr[nTempIndices] );
274 if (pReturnTypeDescr)
275 TYPELIB_DANGER_RELEASE( pReturnTypeDescr );
279 return typelib_TypeClass_VOID;
284 for ( ; nTempIndices--; )
286 sal_Int32
nIndex = pTempIndices[nTempIndices];
289 if (pParams[nIndex].bOut)
299 TYPELIB_DANGER_RELEASE( pParamTypeDescr );
304 if (pUnoReturn != pCppReturn)
312 *(
void **)pRegisterReturn = pCppReturn;
314 if (pReturnTypeDescr)
316 typelib_TypeClass eRet = (typelib_TypeClass)pReturnTypeDescr->eTypeClass;
317 TYPELIB_DANGER_RELEASE( pReturnTypeDescr );
321 return typelib_TypeClass_VOID;
327 sal_Int32 nFunctionIndex,
328 sal_Int32 nVtableOffset,
330 sal_Int64 * pRegisterReturn )
332 static_assert(
sizeof(sal_Int64)==
sizeof(
void *),
"### unexpected!");
336 if (nFunctionIndex & 0x80000000)
338 nFunctionIndex &= 0x7fffffff;
339 pThis = pCallStack[1];
343 pThis = pCallStack[0];
346 pThis =
static_cast< char *
>(pThis) - nVtableOffset;
350 typelib_InterfaceTypeDescription * pTypeDescr = pCppI->
getTypeDescr();
352 if (nFunctionIndex >= pTypeDescr->nMapFunctionIndexToMemberIndex)
356 "illegal " << OUString::unacquired(&pTypeDescr->aBase.pTypeName)
357 <<
" vtable index " << nFunctionIndex <<
"/"
358 << pTypeDescr->nMapFunctionIndexToMemberIndex);
360 (
"illegal " + OUString::unacquired(&pTypeDescr->aBase.pTypeName)
361 +
" vtable index " + OUString::number(nFunctionIndex) +
"/"
362 + OUString::number(pTypeDescr->nMapFunctionIndexToMemberIndex)),
367 sal_Int32 nMemberPos = pTypeDescr->pMapFunctionIndexToMemberIndex[nFunctionIndex];
368 assert(nMemberPos < pTypeDescr->nAllMembers);
370 TypeDescription aMemberDescr( pTypeDescr->ppAllMembers[nMemberPos] );
372 typelib_TypeClass eRet;
373 switch (aMemberDescr.get()->eTypeClass)
375 case typelib_TypeClass_INTERFACE_ATTRIBUTE:
377 if (pTypeDescr->pMapMemberIndexToFunctionIndex[nMemberPos] == nFunctionIndex)
381 pCppI, aMemberDescr.get(),
382 ((typelib_InterfaceAttributeTypeDescription *)aMemberDescr.get())->pAttributeTypeRef,
384 pCallStack, pRegisterReturn );
389 typelib_MethodParameter aParam;
391 ((typelib_InterfaceAttributeTypeDescription *)aMemberDescr.get())->pAttributeTypeRef;
396 pCppI, aMemberDescr.get(),
399 pCallStack, pRegisterReturn );
403 case typelib_TypeClass_INTERFACE_METHOD:
406 switch (nFunctionIndex)
410 eRet = typelib_TypeClass_VOID;
414 eRet = typelib_TypeClass_VOID;
419 TYPELIB_DANGER_GET( &pTD,
reinterpret_cast< Type *
>( pCallStack[2] )->getTypeLibType() );
425 (
void **)&pInterface, pCppI->
getOid().pData, (typelib_InterfaceTypeDescription *)pTD );
430 reinterpret_cast< uno_Any *
>( pCallStack[0] ),
431 &pInterface, pTD, cpp_acquire );
432 pInterface->release();
433 TYPELIB_DANGER_RELEASE( pTD );
434 *(
void **)pRegisterReturn = pCallStack[0];
435 eRet = typelib_TypeClass_ANY;
438 TYPELIB_DANGER_RELEASE( pTD );
443 pCppI, aMemberDescr.get(),
444 ((typelib_InterfaceMethodTypeDescription *)aMemberDescr.get())->pReturnTypeRef,
445 ((typelib_InterfaceMethodTypeDescription *)aMemberDescr.get())->nParams,
446 ((typelib_InterfaceMethodTypeDescription *)aMemberDescr.get())->pParams,
447 pCallStack, pRegisterReturn );
465static void cpp_vtable_call(
int nFunctionIndex,
void** pCallStack,
int vTableOffset)
467 sal_Int64 nRegReturn[4] = { 0 };
468 void * pRegReturn = &nRegReturn[0];
479 typelib_TypeClass aType =
480 cpp_mediate( nFunctionIndex, vTableOffset, pCallStack+16, (sal_Int64*)&nRegReturn );
484 case typelib_TypeClass_BOOLEAN:
485 case typelib_TypeClass_BYTE:
487 "ldsb [%%l0], %%i0\n"
488 : :
"m"(pRegReturn) );
490 case typelib_TypeClass_CHAR:
491 case typelib_TypeClass_SHORT:
492 case typelib_TypeClass_UNSIGNED_SHORT:
494 "ldsh [%%l0], %%i0\n"
495 : :
"m"(pRegReturn) );
497 case typelib_TypeClass_ENUM:
498 case typelib_TypeClass_LONG:
499 case typelib_TypeClass_UNSIGNED_LONG:
502 : :
"m"(pRegReturn) );
504 case typelib_TypeClass_HYPER:
505 case typelib_TypeClass_UNSIGNED_HYPER:
507 "ldx [%%l0], %%i0\n\t"
508 : :
"m"(pRegReturn) );
510 case typelib_TypeClass_FLOAT:
513 : :
"m"(pRegReturn) );
515 case typelib_TypeClass_DOUBLE:
518 : :
"m"(pRegReturn) );
520 case typelib_TypeClass_VOID:
522 case typelib_TypeClass_STRUCT:
523 case typelib_TypeClass_EXCEPTION:
525 "ldx [%%l0 ], %%i0\n\t"
526 "ldx [%%l0+ 8], %%i1\n\t"
527 "ldx [%%l0+16], %%i2\n\t"
528 "ldx [%%l0+24], %%i3\n\t"
529 "ldd [%%l0 ], %%f0\n\t"
530 "ldd [%%l0+ 8], %%f2\n\t"
531 "ldd [%%l0+16], %%f4\n\t"
532 "ldd [%%l0+24], %%f6\n\t"
533 : :
"m"(pRegReturn) );
551 unsigned char * code, sal_Int32 functionIndex, sal_Int32 vtableOffset,
552 bool bHasHiddenParam, sal_Int32 nParams)
554 sal_uInt32
index = functionIndex;
555 if (bHasHiddenParam) {
558 unsigned int *
p =
reinterpret_cast< unsigned int *
>(
code);
559 static_assert(
sizeof (
unsigned int) == 4,
"boo");
560 static_assert(
sizeof (
unsigned long long) == 8,
"boo");
562 if (bHasHiddenParam) {
567 frameSize = 128 + nParams * 8;
571 assert(frameSize <= 4096);
572 frameSize = -frameSize;
575 assert(nParams >= 6);
597 *
p++ = 0x11000000 | (
index >> 10);
599 *
p++ = 0x90122000 | (
index & 0x3FF);
601 *
p++ = 0x17000000 | (
reinterpret_cast< unsigned long long >(
cpp_vtable_call) >> 42);
603 *
p++ = 0x9612E000 | ((
reinterpret_cast< unsigned long long >(
cpp_vtable_call) >> 32) & 0x3FF);
607 *
p++ = 0x15000000 | ((
reinterpret_cast< unsigned long long >(
cpp_vtable_call) >> 10) & 0x3FFFFF);
609 *
p++ = 0x9412A000 | (
reinterpret_cast< unsigned long long >(
cpp_vtable_call) & 0x3FF);
625 *
p++ = 0x19000000 | (*
reinterpret_cast< unsigned long long *
>(&frameSize) >> 42);
627 *
p++ = 0x98132000 | ((*
reinterpret_cast< unsigned long long *
>(&frameSize) >> 32) & 0x3FF);
631 *
p++ = 0x15000000 | ((*
reinterpret_cast< unsigned long long *
>(&frameSize) >> 10) & 0x3FFFFF);
633 *
p++ = 0x9412A000 | (*
reinterpret_cast< unsigned long long *
>(&frameSize) & 0x3FF);
637 *
p++ = 0x15000000 | (vtableOffset >> 10);
639 *
p++ = 0x9412A000 | (vtableOffset & 0x3FF);
657 return static_cast< Slot *
>(block) + 2;
674 void * block, sal_Int32 slotCount, sal_Int32,
675 typelib_InterfaceTypeDescription *)
677 Slot * slots = mapBlockToVtable(block);
679 slots[-1].fn = &
typeid(ProxyRtti);
680 return slots + slotCount;
684 Slot ** slots,
unsigned char * code, sal_PtrDiff writetoexecdiff,
685 typelib_InterfaceTypeDescription
const * type, sal_Int32 functionOffset,
686 sal_Int32 functionCount, sal_Int32 vTableOffset)
688 (*slots) -= functionCount;
690 for (sal_Int32 i = 0;
i <
type->nMembers; ++
i) {
692 TYPELIB_DANGER_GET(&member,
type->ppMembers[i]);
694 switch (member->eTypeClass) {
695 case typelib_TypeClass_INTERFACE_ATTRIBUTE:
697 (s++)->fn = code + writetoexecdiff;
699 code, functionOffset++, vTableOffset,
702 typelib_InterfaceAttributeTypeDescription *
>(
703 member)->pAttributeTypeRef), 0);
705 if (!
reinterpret_cast<
706 typelib_InterfaceAttributeTypeDescription *
>(
709 (s++)->fn = code + writetoexecdiff;
714 case typelib_TypeClass_INTERFACE_METHOD:
715 (s++)->fn = code + writetoexecdiff;
717 code, functionOffset++, vTableOffset,
720 typelib_InterfaceMethodTypeDescription *
>(
721 member)->pReturnTypeRef),
723 typelib_InterfaceMethodTypeDescription *
>(
731 TYPELIB_DANGER_RELEASE(member);
738extern "C" void doFlushCode(
unsigned long address,
unsigned long count);
741 unsigned char const * begin,
unsigned char const * end)
745 unsigned long adr =
reinterpret_cast< unsigned long >(
begin);
746 unsigned long off = adr & 7;
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")
void(* privateSnippetExecutor)()
void doFlushCode(unsigned long address, unsigned long count)
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)
bool return_in_hidden_param(typelib_TypeDescriptionReference *pTypeRef)
char * adjustPointer(char *pIn, typelib_TypeDescription *pType)
void raiseException(uno_Any *pUnoExc, uno_Mapping *pUno2Cpp)
bool is_complex_struct(const typelib_TypeDescription *type)
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,...
enumrange< T >::Iterator begin(enumrange< T >)
const wchar_t *typedef int(__stdcall *DllNativeUnregProc)(int