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>
41 using namespace ::
std;
42 using namespace ::
osl;
43 using namespace ::
rtl;
47 #include <sys/sysmips.h>
58 const typelib_CompoundTypeDescription *
p
59 =
reinterpret_cast< const typelib_CompoundTypeDescription *
>(type);
60 for (sal_Int32
i = 0;
i < p->nMembers; ++
i)
62 if (p->ppTypeRefs[
i]->eTypeClass == typelib_TypeClass_STRUCT ||
63 p->ppTypeRefs[
i]->eTypeClass == typelib_TypeClass_EXCEPTION)
66 TYPELIB_DANGER_GET(&t, p->ppTypeRefs[
i]);
68 TYPELIB_DANGER_RELEASE(t);
76 if (p->pBaseTypeDescription != 0)
85 else if (pTypeRef->eTypeClass == typelib_TypeClass_STRUCT ||
86 pTypeRef->eTypeClass == typelib_TypeClass_EXCEPTION)
89 TYPELIB_DANGER_GET( &pTypeDescr, pTypeRef );
94 TYPELIB_DANGER_RELEASE( pTypeDescr );
107 typelib_TypeDescriptionReference * pReturnTypeRef,
108 sal_Int32 nParams, typelib_MethodParameter * pParams,
109 void ** gpreg,
void ** fpreg,
void ** ovrflw,
110 sal_uInt64 * pRegisterReturn )
119 unsigned int nREG = 0;
122 fprintf(stderr,
"cpp2uno_call:begin\n");
128 TYPELIB_DANGER_GET( &pReturnTypeDescr, pReturnTypeRef );
130 void * pUnoReturn = 0;
131 void * pCppReturn = 0;
133 if (pReturnTypeDescr)
137 pCppReturn = gpreg[nREG];
141 ? alloca( pReturnTypeDescr->nSize )
144 fprintf(stderr,
"cpp2uno_call:complexreturn\n");
149 pUnoReturn = pRegisterReturn;
151 fprintf(stderr,
"cpp2uno_call:simplereturn\n");
160 static_assert(
sizeof(
void *) ==
sizeof(sal_Int64),
"### unexpected size!");
162 void ** pUnoArgs = (
void **)alloca( 4 *
sizeof(
void *) * nParams );
163 void ** pCppArgs = pUnoArgs + nParams;
165 sal_Int32 * pTempIndices = (sal_Int32 *)(pUnoArgs + (2 * nParams));
169 sal_Int32 nTempIndices = 0;
172 fprintf(stderr,
"cpp2uno_call:nParams=%d\n", nParams);
174 for ( sal_Int32 nPos = 0;
nPos < nParams; ++
nPos )
176 const typelib_MethodParameter & rParam = pParams[
nPos];
179 TYPELIB_DANGER_GET( &pParamTypeDescr, rParam.pTypeRef );
184 fprintf(stderr,
"cpp2uno_call:Param %u, type %u\n", nPos, pParamTypeDescr->eTypeClass);
186 switch (pParamTypeDescr->eTypeClass)
188 case typelib_TypeClass_FLOAT:
189 case typelib_TypeClass_DOUBLE:
192 fprintf(stderr,
"cpp2uno_call:fpr=%p\n", fpreg[nREG]);
194 pCppArgs[
nPos] = &(fpreg[nREG]);
195 pUnoArgs[
nPos] = &(fpreg[nREG]);
198 fprintf(stderr,
"cpp2uno_call:fpr=%p\n", ovrflw[nREG -
MAX_FP_REGS]);
210 fprintf(stderr,
"cpp2uno_call:gpr=%p\n", gpreg[nREG]);
212 pCppArgs[
nPos] = &(gpreg[nREG]);
213 pUnoArgs[
nPos] = &(gpreg[nREG]);
216 fprintf(stderr,
"cpp2uno_call:gpr=%p\n", ovrflw[nREG -
MAX_GP_REGS]);
226 TYPELIB_DANGER_RELEASE( pParamTypeDescr );
231 fprintf(stderr,
"cpp2uno_call:ptr|ref\n");
235 pCppArgs[
nPos] = pCppStack = gpreg[nREG];
241 fprintf(stderr,
"cpp2uno_call:pCppStack=%p\n", pCppStack);
247 pUnoArgs[
nPos] = alloca( pParamTypeDescr->nSize );
248 pTempIndices[nTempIndices] =
nPos;
250 ppTempParamTypeDescr[nTempIndices++] = pParamTypeDescr;
256 pCppStack, pParamTypeDescr,
258 pTempIndices[nTempIndices] =
nPos;
260 ppTempParamTypeDescr[nTempIndices++] = pParamTypeDescr;
262 fprintf(stderr,
"cpp2uno_call:related to interface,%p,%d,pUnoargs[%d]=%p\n",
263 pCppStack, pParamTypeDescr->nSize, nPos, pUnoArgs[nPos]);
268 pUnoArgs[
nPos] = pCppStack;
270 fprintf(stderr,
"cpp2uno_call:direct,pUnoArgs[%d]=%p\n", nPos, pUnoArgs[nPos]);
273 TYPELIB_DANGER_RELEASE( pParamTypeDescr );
278 fprintf(stderr,
"cpp2uno_call2,%p,unoargs=%p\n", pThis->
getUnoI()->pDispatcher, pUnoArgs);
286 (*pThis->
getUnoI()->pDispatcher)( pThis->
getUnoI(), pMemberTypeDescr, pUnoReturn, pUnoArgs, &pUnoExc );
288 fprintf(stderr,
"cpp2uno_call2,after dispatch\n");
295 for ( ; nTempIndices--; )
297 sal_Int32
nIndex = pTempIndices[nTempIndices];
299 if (pParams[nIndex].bIn)
300 uno_destructData( pUnoArgs[nIndex], ppTempParamTypeDescr[nTempIndices], 0 );
301 TYPELIB_DANGER_RELEASE( ppTempParamTypeDescr[nTempIndices] );
303 if (pReturnTypeDescr)
304 TYPELIB_DANGER_RELEASE( pReturnTypeDescr );
309 return typelib_TypeClass_VOID;
314 for ( ; nTempIndices--; )
316 sal_Int32 nIndex = pTempIndices[nTempIndices];
319 if (pParams[nIndex].bOut)
329 TYPELIB_DANGER_RELEASE( pParamTypeDescr );
334 if (pUnoReturn != pCppReturn)
342 *(
void **)pRegisterReturn = pCppReturn;
344 if (pReturnTypeDescr)
346 typelib_TypeClass eRet = (typelib_TypeClass)pReturnTypeDescr->eTypeClass;
347 TYPELIB_DANGER_RELEASE( pReturnTypeDescr );
351 return typelib_TypeClass_VOID;
361 sal_Int32 nFunctionIndex,
362 sal_Int32 nVtableOffset,
363 void ** gpreg,
void ** fpreg,
void ** ovrflw,
364 sal_uInt64 * pRegisterReturn )
366 static_assert(
sizeof(sal_Int64)==
sizeof(
void *),
"### unexpected!" );
369 fprintf(stderr,
"in cpp_vtable_call nFunctionIndex is %d\n", nFunctionIndex);
370 fprintf(stderr,
"in cpp_vtable_call nVtableOffset is %d\n", nVtableOffset);
371 fprintf(stderr,
"in cpp_vtable_call gp=%p, fp=%p, ov=%p\n", gpreg, fpreg, ovrflw);
378 if (nFunctionIndex & 0x80000000 )
380 nFunctionIndex &= 0x7fffffff;
388 fprintf(stderr,
"cpp_vtable_call, pThis=%p, nFunctionIndex=%d, nVtableOffset=%d\n",
389 pThis, nFunctionIndex, nVtableOffset);
392 pThis =
static_cast< char *
>(pThis) - nVtableOffset;
396 fprintf(stderr,
"cpp_vtable_call, pCppI=%p\n", pCppI);
399 typelib_InterfaceTypeDescription * pTypeDescr = pCppI->
getTypeDescr();
401 if (nFunctionIndex >= pTypeDescr->nMapFunctionIndexToMemberIndex)
405 "illegal " << OUString::unacquired(&pTypeDescr->aBase.pTypeName)
406 <<
" vtable index " << nFunctionIndex <<
"/"
407 << pTypeDescr->nMapFunctionIndexToMemberIndex);
409 (
"illegal " + OUString::unacquired(&pTypeDescr->aBase.pTypeName)
410 +
" vtable index " + OUString::number(nFunctionIndex) +
"/"
411 + OUString::number(pTypeDescr->nMapFunctionIndexToMemberIndex)),
416 sal_Int32 nMemberPos = pTypeDescr->pMapFunctionIndexToMemberIndex[nFunctionIndex];
417 assert(nMemberPos < pTypeDescr->nAllMembers);
419 TypeDescription aMemberDescr( pTypeDescr->ppAllMembers[nMemberPos] );
422 OString cstr(
OUStringToOString( aMemberDescr.get()->pTypeName, RTL_TEXTENCODING_ASCII_US ) );
423 fprintf(stderr,
"calling %s, nFunctionIndex=%d\n", cstr.getStr(), nFunctionIndex );
425 typelib_TypeClass eRet;
426 switch (aMemberDescr.get()->eTypeClass)
428 case typelib_TypeClass_INTERFACE_ATTRIBUTE:
431 fprintf(stderr,
"cpp_vtable_call interface attribute\n");
433 typelib_TypeDescriptionReference *pAttrTypeRef =
434 reinterpret_cast<typelib_InterfaceAttributeTypeDescription *
>( aMemberDescr.get() )->pAttributeTypeRef;
436 if (pTypeDescr->pMapMemberIndexToFunctionIndex[nMemberPos] == nFunctionIndex)
439 eRet =
cpp2uno_call( pCppI, aMemberDescr.get(), pAttrTypeRef,
441 gpreg, fpreg, ovrflw, pRegisterReturn );
446 typelib_MethodParameter aParam;
447 aParam.pTypeRef = pAttrTypeRef;
454 gpreg, fpreg, ovrflw, pRegisterReturn );
458 case typelib_TypeClass_INTERFACE_METHOD:
461 fprintf(stderr,
"cpp_vtable_call interface method\n");
464 switch (nFunctionIndex)
468 fprintf(stderr,
"cpp_vtable_call method acquire\n");
471 eRet = typelib_TypeClass_VOID;
475 fprintf(stderr,
"cpp_vtable_call method release\n");
478 eRet = typelib_TypeClass_VOID;
483 fprintf(stderr,
"cpp_vtable_call method query interface opt\n");
486 TYPELIB_DANGER_GET( &pTD, reinterpret_cast< Type * >( gpreg[2] )->getTypeLibType() );
492 (
void **)&pInterface,
494 reinterpret_cast<typelib_InterfaceTypeDescription *
>( pTD ) );
498 ::uno_any_construct( reinterpret_cast< uno_Any * >( gpreg[0] ),
499 &pInterface, pTD, cpp_acquire );
501 pInterface->release();
502 TYPELIB_DANGER_RELEASE( pTD );
504 reinterpret_cast<void **
>( pRegisterReturn )[0] = gpreg[0];
505 eRet = typelib_TypeClass_ANY;
508 TYPELIB_DANGER_RELEASE( pTD );
513 fprintf(stderr,
"cpp_vtable_call method query interface\n");
515 typelib_InterfaceMethodTypeDescription *pMethodTD =
516 reinterpret_cast<typelib_InterfaceMethodTypeDescription *
>( aMemberDescr.get() );
519 pMethodTD->pReturnTypeRef,
522 gpreg, fpreg, ovrflw, pRegisterReturn );
529 fprintf(stderr,
"cpp_vtable_call no member\n");
543 sal_Int32 functionIndex, sal_Int32 vtableOffset,
544 bool bHasHiddenParam )
547 fprintf(stderr,
"in codeSnippet functionIndex is %d\n", functionIndex);
548 fprintf(stderr,
"in codeSnippet vtableOffset is %d\n", vtableOffset);
552 if ( bHasHiddenParam )
553 functionIndex |= 0x80000000;
555 unsigned int *
p = (
unsigned int *) code;
557 assert((((
unsigned long)code) & 0x3) == 0 );
584 * p++ = 0x3c020000 | ((functionIndex>>16) & 0x0000ffff);
585 * p++ = 0x34420000 | (functionIndex & 0x0000ffff);
592 * p++ = 0x3c190000 | ((((
unsigned long)
cpp_vtable_call) >> 48) & 0x0000ffff);
593 * p++ = 0x37390000 | ((((
unsigned long)
cpp_vtable_call) >> 32) & 0x0000ffff);
595 * p++ = 0x37390000 | ((((
unsigned long)
cpp_vtable_call) >> 16) & 0x0000ffff);
598 * p++ = 0x3c030000 | ((vtableOffset>>16) & 0x0000ffff);
600 * p++ = 0x34630000 | (vtableOffset & 0x0000ffff);
601 return (code + codeSnippetSize);
613 sysmips(FLUSH_CACHE, 0, 0, 0);
615 cacheflush((
long) bptr, (
long) eptr, 0);
624 return static_cast< Slot *
>(block) + 2;
631 return (slotCount + 2) *
sizeof (
Slot) + slotCount * codeSnippetSize;
636 void * block, sal_Int32 slotCount, sal_Int32,
637 typelib_InterfaceTypeDescription *)
639 Slot * slots = mapBlockToVtable(block);
642 return slots + slotCount;
646 Slot ** slots,
unsigned char * code, sal_PtrDiff writetoexecdiff,
647 typelib_InterfaceTypeDescription
const * type, sal_Int32 functionOffset,
648 sal_Int32 functionCount, sal_Int32 vtableOffset)
650 (*slots) -= functionCount;
654 fprintf(stderr,
"in addLocalFunctions functionOffset is %d\n", functionOffset);
655 fprintf(stderr,
"in addLocalFunctions vtableOffset is %d\n", vtableOffset);
656 fprintf(stderr,
"nMembers=%d\n", type->nMembers);
660 for (sal_Int32 i = 0;
i < type->nMembers; ++
i) {
662 TYPELIB_DANGER_GET(&member, type->ppMembers[i]);
664 switch (member->eTypeClass) {
665 case typelib_TypeClass_INTERFACE_ATTRIBUTE:
667 (s++)->fn = code + writetoexecdiff;
669 code, functionOffset++, vtableOffset,
672 typelib_InterfaceAttributeTypeDescription *
>(
673 member)->pAttributeTypeRef));
676 if (!
reinterpret_cast<
677 typelib_InterfaceAttributeTypeDescription *
>(
680 (s++)->fn = code + writetoexecdiff;
681 code =
codeSnippet(code, functionOffset++, vtableOffset,
false);
685 case typelib_TypeClass_INTERFACE_METHOD:
686 (s++)->fn = code + writetoexecdiff;
688 code, functionOffset++, vtableOffset,
691 typelib_InterfaceMethodTypeDescription *
>(
692 member)->pReturnTypeRef));
699 TYPELIB_DANGER_RELEASE(member);
void(* privateSnippetExecutor)()
void SAL_CALL uno_destructData(void *pValue, typelib_TypeDescription *pTypeDescr, uno_ReleaseFunc release) SAL_THROW_EXTERN_C()
bool isSimpleType(typelib_TypeClass typeClass)
Determines whether a type is a "simple" type (VOID, BOOLEAN, BYTE, SHORT, UNSIGNED SHORT...
static std::size_t getBlockSize(sal_Int32 slotCount)
Calculate the size of a raw vtable block.
const int codeSnippetSize
bool relatesToInterfaceType(typelib_TypeDescription const *type)
Determines whether a type relates to an interface type (is itself an interface type, or might contain entities of interface type).
bool return_in_hidden_param(typelib_TypeDescriptionReference *pTypeRef)
Does function that returns this type use a hidden parameter, or registers?
static Slot * initializeBlock(void *block, sal_Int32 slotCount, sal_Int32 vtableNumber, typelib_InterfaceTypeDescription *type)
Initialize a raw vtable block.
static Slot * mapBlockToVtable(void *block)
Given a pointer to a block, turn it into a vtable pointer.
OString OUStringToOString(std::u16string_view str, ConnectionSettings const *settings)
uno_Mapping * getUno2Cpp()
uno_ExtEnvironment * getCppEnv()
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...
typelib_InterfaceTypeDescription * getTypeDescr()
A cpp proxy wrapping a uno interface.
void SAL_CALL uno_copyAndConvertData(void *pDest, void *pSource, typelib_TypeDescription *pTypeDescr, uno_Mapping *mapping) SAL_THROW_EXTERN_C()
uno_Interface * getUnoI()
struct _typelib_TypeDescription typelib_TypeDescription
uno_Mapping * getCpp2Uno()
void raiseException(uno_Any *pUnoExc, uno_Mapping *pUno2Cpp)
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)
bool is_complex_struct(const typelib_TypeDescription *type)
static unsigned char * codeSnippet(unsigned char *code, sal_Int32 nFunctionIndex, sal_Int32 nVtableOffset, bool bHasHiddenParam)
void cpp_vtable_call(sal_Int32 func, sal_Int32 offset, void **pStack)
is called on incoming vtable calls (called by asm snippets)
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.
#define SAL_WARN(area, stream)
static CppInterfaceProxy * castInterfaceToProxy(void *pInterface)
const OUString & getOid() const