19#include <com/sun/star/uno/genfunc.hxx>
21#include <typelib/typedescription.hxx>
23#include <osl/endian.h>
39#include <rtl/strbuf.hxx>
40#include <rtl/ustrbuf.hxx>
47#include <sys/sysmips.h>
55#define IS_BIG_ENDIAN 1
57#define IS_BIG_ENDIAN 0
66 typelib_TypeDescriptionReference * pReturnTypeRef,
67 sal_Int32 nParams, typelib_MethodParameter * pParams,
68 void ** gpreg,
void ** ,
void ** ovrflw,
69 sal_Int64 * pRegisterReturn )
81 fprintf(stderr,
"cpp2uno_call1\n");
98 TYPELIB_DANGER_GET( &pReturnTypeDescr, pReturnTypeRef );
100 void * pUnoReturn = 0;
101 void * pCppReturn = 0;
103 if (pReturnTypeDescr)
107 pUnoReturn = pRegisterReturn;
109 fprintf(stderr,
"cpp2uno_call:simplereturn\n");
114 pCppReturn = *(
void **)gpreg;
119 ? alloca( pReturnTypeDescr->nSize )
122 fprintf(stderr,
"cpp2uno_call:complexreturn\n");
132 static_assert(
sizeof(
void *) ==
sizeof(sal_Int32),
"### unexpected size!");
134 void ** pUnoArgs = (
void **)alloca( 4 *
sizeof(
void *) * nParams );
135 void ** pCppArgs = pUnoArgs + nParams;
137 sal_Int32 * pTempIndices = (sal_Int32 *)(pUnoArgs + (2 * nParams));
141 sal_Int32 nTempIndices = 0;
144 fprintf(stderr,
"cpp2uno_call:nParams=%d\n",nParams);
149 const typelib_MethodParameter & rParam = pParams[
nPos];
151 TYPELIB_DANGER_GET( &pParamTypeDescr, rParam.pTypeRef );
157 switch (pParamTypeDescr->eTypeClass)
159 case typelib_TypeClass_DOUBLE:
160 case typelib_TypeClass_HYPER:
161 case typelib_TypeClass_UNSIGNED_HYPER:
163 fprintf(stderr,
"cpp2uno_call:hyper=%d,%p\n",pParamTypeDescr->eTypeClass,gpreg[0]);
171 fprintf(stderr,
"cpp2uno_call:gpreg=%p,%p\n",gpreg[0],gpreg[1]);
173 pCppArgs[
nPos] = gpreg;
174 pUnoArgs[
nPos] = gpreg;
178 if (((
long)ovrflw) & 4) ovrflw++;
180 fprintf(stderr,
"cpp2uno_call:overflw=%p,%p\n",ovrflw[0],ovrflw[1]);
182 pCppArgs[
nPos] = ovrflw;
183 pUnoArgs[
nPos] = ovrflw;
188 case typelib_TypeClass_BYTE:
189 case typelib_TypeClass_BOOLEAN:
191 fprintf(stderr,
"cpp2uno_call:byte=%p,%p\n",gpreg[0],ovrflw[0]);
206 case typelib_TypeClass_CHAR:
207 case typelib_TypeClass_SHORT:
208 case typelib_TypeClass_UNSIGNED_SHORT:
210 fprintf(stderr,
"cpp2uno_call:char=%p,%p\n",gpreg[0],ovrflw[0]);
227 fprintf(stderr,
"cpp2uno_call:def=%p,%p\n",gpreg[0],ovrflw[0]);
230 pCppArgs[
nPos] = gpreg;
231 pUnoArgs[
nPos] = gpreg;
235 pCppArgs[
nPos] = ovrflw;
236 pUnoArgs[
nPos] = ovrflw;
243 TYPELIB_DANGER_RELEASE( pParamTypeDescr );
249 fprintf(stderr,
"cpp2uno_call:ptr|ref\n");
252 pCppArgs[
nPos] = *(
void **)gpreg;
257 pCppArgs[
nPos] = *(
void **)ovrflw;
262 fprintf(stderr,
"cpp2uno_call:pCppStack=%p\n",pCppStack);
268 pUnoArgs[
nPos] = alloca( pParamTypeDescr->nSize );
269 pTempIndices[nTempIndices] =
nPos;
271 ppTempParamTypeDescr[nTempIndices++] = pParamTypeDescr;
277 *(
void **)pCppStack, pParamTypeDescr,
279 pTempIndices[nTempIndices] =
nPos;
281 ppTempParamTypeDescr[nTempIndices++] = pParamTypeDescr;
283 fprintf(stderr,
"cpp2uno_call:related to interface,%p,%d,pUnoargs[%d]=%p\n",*(
void**)pCppStack,pParamTypeDescr->nSize,
nPos,pUnoArgs[
nPos]);
288 pUnoArgs[
nPos] = *(
void **)pCppStack;
290 fprintf(stderr,
"cpp2uno_call:direct,pUnoArgs[%d]=%p\n",
nPos,pUnoArgs[
nPos]);
293 TYPELIB_DANGER_RELEASE( pParamTypeDescr );
298 fprintf(stderr,
"cpp2uno_call2,%p,unoargs=%p\n",pThis->
getUnoI()->pDispatcher,pUnoArgs);
306 (*pThis->
getUnoI()->pDispatcher)( pThis->
getUnoI(), pMemberTypeDescr, pUnoReturn, pUnoArgs, &pUnoExc );
308 fprintf(stderr,
"cpp2uno_call2,after dispatch\n");
315 for ( ; nTempIndices--; )
317 sal_Int32
nIndex = pTempIndices[nTempIndices];
321 TYPELIB_DANGER_RELEASE( ppTempParamTypeDescr[nTempIndices] );
323 if (pReturnTypeDescr)
324 TYPELIB_DANGER_RELEASE( pReturnTypeDescr );
329 return typelib_TypeClass_VOID;
334 for ( ; nTempIndices--; )
336 sal_Int32
nIndex = pTempIndices[nTempIndices];
349 TYPELIB_DANGER_RELEASE( pParamTypeDescr );
354 if (pUnoReturn != pCppReturn)
362 *(
void **)pRegisterReturn = pCppReturn;
364 if (pReturnTypeDescr)
366 typelib_TypeClass eRet = (typelib_TypeClass)pReturnTypeDescr->eTypeClass;
367 TYPELIB_DANGER_RELEASE( pReturnTypeDescr );
371 return typelib_TypeClass_VOID;
377 sal_Int32 nFunctionIndex,
378 sal_Int32 nVtableOffset,
379 void ** gpreg,
void ** fpreg,
void ** ovrflw,
380 sal_Int64 * pRegisterReturn )
382 static_assert(
sizeof(sal_Int32)==
sizeof(
void *),
"### unexpected!");
385 fprintf(stderr,
"cpp_mediate1 gp=%p,fp=%p,ov=%p\n",gpreg,fpreg,ovrflw);
386 fprintf(stderr,
"gp=%p,%p,%p,%p\n",gpreg[0],gpreg[1],gpreg[2],gpreg[3]);
394 if (nFunctionIndex & 0x80000000 )
396 nFunctionIndex &= 0x7fffffff;
404 fprintf(stderr,
"cpp_mediate12,pThis=%p, nFunctionIndex=%d,nVtableOffset=%d\n",pThis,nFunctionIndex,nVtableOffset);
407 pThis =
static_cast< char *
>(pThis) - nVtableOffset;
412 fprintf(stderr,
"cpp_mediate13,pCppI=%p\n",pCppI);
415 typelib_InterfaceTypeDescription * pTypeDescr = pCppI->
getTypeDescr();
418 fprintf(stderr,
"cpp_mediate2\n");
420 if (nFunctionIndex >= pTypeDescr->nMapFunctionIndexToMemberIndex)
424 "illegal " << OUString::unacquired(&pTypeDescr->aBase.pTypeName)
425 <<
" vtable index " << nFunctionIndex <<
"/"
426 << pTypeDescr->nMapFunctionIndexToMemberIndex);
428 (
"illegal " + OUString::unacquired(&pTypeDescr->aBase.pTypeName)
429 +
" vtable index " + OUString::number(nFunctionIndex) +
"/"
430 + OUString::number(pTypeDescr->nMapFunctionIndexToMemberIndex)),
435 sal_Int32 nMemberPos = pTypeDescr->pMapFunctionIndexToMemberIndex[nFunctionIndex];
436 assert(nMemberPos < pTypeDescr->nAllMembers);
438 TypeDescription aMemberDescr( pTypeDescr->ppAllMembers[nMemberPos] );
441 fprintf(stderr,
"cpp_mediate3\n");
442 OString cstr(
OUStringToOString( aMemberDescr.get()->pTypeName, RTL_TEXTENCODING_ASCII_US ) );
443 fprintf( stderr,
"calling %s, nFunctionIndex=%d\n", cstr.getStr(), nFunctionIndex );
445 typelib_TypeClass eRet;
446 switch (aMemberDescr.get()->eTypeClass)
448 case typelib_TypeClass_INTERFACE_ATTRIBUTE:
451 fprintf(stderr,
"cpp_mediate4\n");
453 if (pTypeDescr->pMapMemberIndexToFunctionIndex[nMemberPos] == nFunctionIndex)
457 pCppI, aMemberDescr.get(),
458 ((typelib_InterfaceAttributeTypeDescription *)aMemberDescr.get())->pAttributeTypeRef,
460 gpreg, fpreg, ovrflw, pRegisterReturn );
465 typelib_MethodParameter aParam;
467 ((typelib_InterfaceAttributeTypeDescription *)aMemberDescr.get())->pAttributeTypeRef;
472 pCppI, aMemberDescr.get(),
475 gpreg, fpreg, ovrflw, pRegisterReturn );
479 case typelib_TypeClass_INTERFACE_METHOD:
482 fprintf(stderr,
"cpp_mediate5\n");
485 switch (nFunctionIndex)
489 eRet = typelib_TypeClass_VOID;
493 fprintf(stderr,
"cpp_mediate51\n");
496 eRet = typelib_TypeClass_VOID;
498 fprintf(stderr,
"cpp_mediate52\n");
504 TYPELIB_DANGER_GET( &pTD,
reinterpret_cast< Type *
>( gpreg[2] )->getTypeLibType() );
510 (
void **)&pInterface, pCppI->
getOid().pData,
511 (typelib_InterfaceTypeDescription *)pTD );
516 reinterpret_cast< uno_Any *
>( gpreg[0] ),
517 &pInterface, pTD, cpp_acquire );
518 pInterface->release();
519 TYPELIB_DANGER_RELEASE( pTD );
520 *(
void **)pRegisterReturn = gpreg[0];
521 eRet = typelib_TypeClass_ANY;
524 TYPELIB_DANGER_RELEASE( pTD );
529 pCppI, aMemberDescr.get(),
530 ((typelib_InterfaceMethodTypeDescription *)aMemberDescr.get())->pReturnTypeRef,
531 ((typelib_InterfaceMethodTypeDescription *)aMemberDescr.get())->nParams,
532 ((typelib_InterfaceMethodTypeDescription *)aMemberDescr.get())->pParams,
533 gpreg, fpreg, ovrflw, pRegisterReturn );
540 fprintf(stderr,
"cpp_mediate6\n");
567 volatile long nRegReturn[2];
573 ::
"m"(nFunctionIndex),
"m"(vTableOffset),
"m"(pCallStack),
"m"(ovrflw) );
575 memcpy( gpreg, pCallStack, 16);
578 fprintf(stderr,
"in cpp_vtable_call nFunctionIndex is %d\n",nFunctionIndex);
579 fprintf(stderr,
"in cpp_vtable_call nVtableOffset is %d\n",vTableOffset);
580 fprintf(stderr,
"gp=%x,%x,%x,%x\n",gpreg[0],gpreg[1],gpreg[2],gpreg[3]);
585 typelib_TypeClass aType =
586 cpp_mediate( nFunctionIndex, vTableOffset, (
void**)gpreg, (
void**)fpreg, ovrflw, (sal_Int64*)nRegReturn );
594 case typelib_TypeClass_BOOLEAN:
595 case typelib_TypeClass_BYTE:
597 "m"(nRegReturn[0]) );
600 case typelib_TypeClass_CHAR:
601 case typelib_TypeClass_UNSIGNED_SHORT:
603 "m"(nRegReturn[0]) );
606 case typelib_TypeClass_SHORT:
608 "m"(nRegReturn[0]) );
612 case typelib_TypeClass_FLOAT:
614 "m" (*((
float*)nRegReturn)) );
617 case typelib_TypeClass_DOUBLE:
618 {
register double dret
asm(
"$f0");
619 dret = (*((
double*)nRegReturn));
624 case typelib_TypeClass_HYPER:
625 case typelib_TypeClass_UNSIGNED_HYPER:
627 "m"(nRegReturn[1]) );
631 "m"(nRegReturn[0]) );
639 unsigned char *
codeSnippet(
unsigned char *
code, sal_Int32 functionIndex, sal_Int32 vtableOffset,
644 fprintf(stderr,
"in codeSnippet functionIndex is %d\n", functionIndex);
645 fprintf(stderr,
"in codeSnippet vtableOffset is %d\n", vtableOffset);
649 if (! simpleRetType )
650 functionIndex |= 0x80000000;
652 unsigned long *
p = (
unsigned long *)
code;
655 assert((((
unsigned long)
code) & 0x3) == 0 );
694 *
p++ = 0x3c040000 | ((functionIndex>>16) & 0x0000ffff);
695 *
p++ = 0x34840000 | (functionIndex & 0x0000ffff);
696 *
p++ = 0x3c050000 | ((vtableOffset>>16) & 0x0000ffff);
697 *
p++ = 0x34a50000 | (vtableOffset & 0x0000ffff);
700 *
p++ = 0x3c190000 | ((((
unsigned long)
cpp_vtable_call) >> 16) & 0x0000ffff);
717 sysmips(FLUSH_CACHE,0,0,0);
719 cacheflush((
long) bptr, (
long) eptr, 0);
728 return static_cast< Slot *
>(block) + 2;
746 void * block, sal_Int32 slotCount, sal_Int32,
747 typelib_InterfaceTypeDescription *)
749 Slot * slots = mapBlockToVtable(block);
751 slots[-1].fn = &
typeid(ProxyRtti);
752 return slots + slotCount;
756 Slot ** slots,
unsigned char * code, sal_PtrDiff writetoexecdiff,
757 typelib_InterfaceTypeDescription
const * type, sal_Int32 functionOffset,
758 sal_Int32 functionCount, sal_Int32 vtableOffset)
760 (*slots) -= functionCount;
763 fprintf(stderr,
"in addLocalFunctions functionOffset is %d\n",functionOffset);
764 fprintf(stderr,
"in addLocalFunctions vtableOffset is %d\n",vtableOffset);
765 fprintf(stderr,
"nMembers=%d\n",
type->nMembers);
769 for (sal_Int32 i = 0;
i <
type->nMembers; ++
i) {
771 TYPELIB_DANGER_GET(&member,
type->ppMembers[i]);
773 switch (member->eTypeClass) {
774 case typelib_TypeClass_INTERFACE_ATTRIBUTE:
776 (s++)->fn = code + writetoexecdiff;
778 code, functionOffset++, vtableOffset,
781 typelib_InterfaceAttributeTypeDescription *
>(
782 member)->pAttributeTypeRef));
785 if (!
reinterpret_cast<
786 typelib_InterfaceAttributeTypeDescription *
>(
789 (s++)->fn = code + writetoexecdiff;
794 case typelib_TypeClass_INTERFACE_METHOD:
795 (s++)->fn = code + writetoexecdiff;
797 code, functionOffset++, vtableOffset,
800 typelib_InterfaceMethodTypeDescription *
>(
801 member)->pReturnTypeRef));
808 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,...
OString OUStringToOString(std::u16string_view str, ConnectionSettings const *settings)