19#include <com/sun/star/uno/genfunc.hxx>
21#include <typelib/typedescription.hxx>
23#include <osl/endian.h>
40#include <rtl/strbuf.hxx>
41#include <rtl/ustrbuf.hxx>
48#include <sys/sysmips.h>
59 const typelib_CompoundTypeDescription *
p
60 =
reinterpret_cast< const typelib_CompoundTypeDescription *
>(
type);
61 for (sal_Int32 i = 0;
i <
p->nMembers; ++
i)
63 if (
p->ppTypeRefs[i]->eTypeClass == typelib_TypeClass_STRUCT ||
64 p->ppTypeRefs[i]->eTypeClass == typelib_TypeClass_EXCEPTION)
67 TYPELIB_DANGER_GET(&t,
p->ppTypeRefs[i]);
69 TYPELIB_DANGER_RELEASE(t);
77 if (
p->pBaseTypeDescription != 0)
86 else if (pTypeRef->eTypeClass == typelib_TypeClass_STRUCT ||
87 pTypeRef->eTypeClass == typelib_TypeClass_EXCEPTION)
90 TYPELIB_DANGER_GET( &pTypeDescr, pTypeRef );
95 TYPELIB_DANGER_RELEASE( pTypeDescr );
108 typelib_TypeDescriptionReference * pReturnTypeRef,
109 sal_Int32 nParams, typelib_MethodParameter * pParams,
110 void ** gpreg,
void ** fpreg,
void ** ovrflw,
111 sal_uInt64 * pRegisterReturn )
120 unsigned int nREG = 0;
123 fprintf(stderr,
"cpp2uno_call:begin\n");
129 TYPELIB_DANGER_GET( &pReturnTypeDescr, pReturnTypeRef );
131 void * pUnoReturn = 0;
132 void * pCppReturn = 0;
134 if (pReturnTypeDescr)
138 pCppReturn = gpreg[nREG];
142 ? alloca( pReturnTypeDescr->nSize )
145 fprintf(stderr,
"cpp2uno_call:complexreturn\n");
150 pUnoReturn = pRegisterReturn;
152 fprintf(stderr,
"cpp2uno_call:simplereturn\n");
161 static_assert(
sizeof(
void *) ==
sizeof(sal_Int64),
"### unexpected size!");
163 void ** pUnoArgs = (
void **)alloca( 4 *
sizeof(
void *) * nParams );
164 void ** pCppArgs = pUnoArgs + nParams;
166 sal_Int32 * pTempIndices = (sal_Int32 *)(pUnoArgs + (2 * nParams));
170 sal_Int32 nTempIndices = 0;
173 fprintf(stderr,
"cpp2uno_call:nParams=%d\n", nParams);
175 for ( sal_Int32 nPos = 0;
nPos < nParams; ++
nPos )
177 const typelib_MethodParameter & rParam = pParams[
nPos];
180 TYPELIB_DANGER_GET( &pParamTypeDescr, rParam.pTypeRef );
185 fprintf(stderr,
"cpp2uno_call:Param %u, type %u\n", nPos, pParamTypeDescr->eTypeClass);
187 switch (pParamTypeDescr->eTypeClass)
189 case typelib_TypeClass_FLOAT:
190 case typelib_TypeClass_DOUBLE:
193 fprintf(stderr,
"cpp2uno_call:fpr=%p\n", fpreg[nREG]);
195 pCppArgs[
nPos] = &(fpreg[nREG]);
196 pUnoArgs[
nPos] = &(fpreg[nREG]);
199 fprintf(stderr,
"cpp2uno_call:fpr=%p\n", ovrflw[nREG -
MAX_FP_REGS]);
211 fprintf(stderr,
"cpp2uno_call:gpr=%p\n", gpreg[nREG]);
213 pCppArgs[
nPos] = &(gpreg[nREG]);
214 pUnoArgs[
nPos] = &(gpreg[nREG]);
217 fprintf(stderr,
"cpp2uno_call:gpr=%p\n", ovrflw[nREG -
MAX_GP_REGS]);
227 TYPELIB_DANGER_RELEASE( pParamTypeDescr );
232 fprintf(stderr,
"cpp2uno_call:ptr|ref\n");
236 pCppArgs[
nPos] = pCppStack = gpreg[nREG];
242 fprintf(stderr,
"cpp2uno_call:pCppStack=%p\n", pCppStack);
248 pUnoArgs[
nPos] = alloca( pParamTypeDescr->nSize );
249 pTempIndices[nTempIndices] =
nPos;
251 ppTempParamTypeDescr[nTempIndices++] = pParamTypeDescr;
257 pCppStack, pParamTypeDescr,
259 pTempIndices[nTempIndices] =
nPos;
261 ppTempParamTypeDescr[nTempIndices++] = pParamTypeDescr;
263 fprintf(stderr,
"cpp2uno_call:related to interface,%p,%d,pUnoargs[%d]=%p\n",
264 pCppStack, pParamTypeDescr->nSize, nPos, pUnoArgs[nPos]);
269 pUnoArgs[
nPos] = pCppStack;
271 fprintf(stderr,
"cpp2uno_call:direct,pUnoArgs[%d]=%p\n", nPos, pUnoArgs[nPos]);
274 TYPELIB_DANGER_RELEASE( pParamTypeDescr );
279 fprintf(stderr,
"cpp2uno_call2,%p,unoargs=%p\n", pThis->
getUnoI()->pDispatcher, pUnoArgs);
287 (*pThis->
getUnoI()->pDispatcher)( pThis->
getUnoI(), pMemberTypeDescr, pUnoReturn, pUnoArgs, &pUnoExc );
289 fprintf(stderr,
"cpp2uno_call2,after dispatch\n");
296 for ( ; nTempIndices--; )
298 sal_Int32
nIndex = pTempIndices[nTempIndices];
300 if (pParams[nIndex].bIn)
301 uno_destructData( pUnoArgs[nIndex], ppTempParamTypeDescr[nTempIndices], 0 );
302 TYPELIB_DANGER_RELEASE( ppTempParamTypeDescr[nTempIndices] );
304 if (pReturnTypeDescr)
305 TYPELIB_DANGER_RELEASE( pReturnTypeDescr );
310 return typelib_TypeClass_VOID;
315 for ( ; nTempIndices--; )
317 sal_Int32
nIndex = pTempIndices[nTempIndices];
320 if (pParams[nIndex].bOut)
330 TYPELIB_DANGER_RELEASE( pParamTypeDescr );
335 if (pUnoReturn != pCppReturn)
343 *(
void **)pRegisterReturn = pCppReturn;
345 if (pReturnTypeDescr)
347 typelib_TypeClass eRet = (typelib_TypeClass)pReturnTypeDescr->eTypeClass;
348 TYPELIB_DANGER_RELEASE( pReturnTypeDescr );
352 return typelib_TypeClass_VOID;
362 sal_Int32 nFunctionIndex,
363 sal_Int32 nVtableOffset,
364 void ** gpreg,
void ** fpreg,
void ** ovrflw,
365 sal_uInt64 * pRegisterReturn )
367 static_assert(
sizeof(sal_Int64)==
sizeof(
void *),
"### unexpected!" );
370 fprintf(stderr,
"in cpp_vtable_call nFunctionIndex is %d\n", nFunctionIndex);
371 fprintf(stderr,
"in cpp_vtable_call nVtableOffset is %d\n", nVtableOffset);
372 fprintf(stderr,
"in cpp_vtable_call gp=%p, fp=%p, ov=%p\n", gpreg, fpreg, ovrflw);
379 if (nFunctionIndex & 0x80000000 )
381 nFunctionIndex &= 0x7fffffff;
389 fprintf(stderr,
"cpp_vtable_call, pThis=%p, nFunctionIndex=%d, nVtableOffset=%d\n",
390 pThis, nFunctionIndex, nVtableOffset);
393 pThis =
static_cast< char *
>(pThis) - nVtableOffset;
397 fprintf(stderr,
"cpp_vtable_call, pCppI=%p\n", pCppI);
400 typelib_InterfaceTypeDescription * pTypeDescr = pCppI->
getTypeDescr();
402 if (nFunctionIndex >= pTypeDescr->nMapFunctionIndexToMemberIndex)
406 "illegal " << OUString::unacquired(&pTypeDescr->aBase.pTypeName)
407 <<
" vtable index " << nFunctionIndex <<
"/"
408 << pTypeDescr->nMapFunctionIndexToMemberIndex);
410 (
"illegal " + OUString::unacquired(&pTypeDescr->aBase.pTypeName)
411 +
" vtable index " + OUString::number(nFunctionIndex) +
"/"
412 + OUString::number(pTypeDescr->nMapFunctionIndexToMemberIndex)),
417 sal_Int32 nMemberPos = pTypeDescr->pMapFunctionIndexToMemberIndex[nFunctionIndex];
418 assert(nMemberPos < pTypeDescr->nAllMembers);
420 TypeDescription aMemberDescr( pTypeDescr->ppAllMembers[nMemberPos] );
423 OString cstr(
OUStringToOString( aMemberDescr.get()->pTypeName, RTL_TEXTENCODING_ASCII_US ) );
424 fprintf(stderr,
"calling %s, nFunctionIndex=%d\n", cstr.getStr(), nFunctionIndex );
426 typelib_TypeClass eRet;
427 switch (aMemberDescr.get()->eTypeClass)
429 case typelib_TypeClass_INTERFACE_ATTRIBUTE:
432 fprintf(stderr,
"cpp_vtable_call interface attribute\n");
434 typelib_TypeDescriptionReference *pAttrTypeRef =
435 reinterpret_cast<typelib_InterfaceAttributeTypeDescription *
>( aMemberDescr.get() )->pAttributeTypeRef;
437 if (pTypeDescr->pMapMemberIndexToFunctionIndex[nMemberPos] == nFunctionIndex)
440 eRet =
cpp2uno_call( pCppI, aMemberDescr.get(), pAttrTypeRef,
442 gpreg, fpreg, ovrflw, pRegisterReturn );
447 typelib_MethodParameter aParam;
448 aParam.pTypeRef = pAttrTypeRef;
455 gpreg, fpreg, ovrflw, pRegisterReturn );
459 case typelib_TypeClass_INTERFACE_METHOD:
462 fprintf(stderr,
"cpp_vtable_call interface method\n");
465 switch (nFunctionIndex)
469 fprintf(stderr,
"cpp_vtable_call method acquire\n");
472 eRet = typelib_TypeClass_VOID;
476 fprintf(stderr,
"cpp_vtable_call method release\n");
479 eRet = typelib_TypeClass_VOID;
484 fprintf(stderr,
"cpp_vtable_call method query interface opt\n");
487 TYPELIB_DANGER_GET( &pTD,
reinterpret_cast< Type *
>( gpreg[2] )->getTypeLibType() );
493 (
void **)&pInterface,
495 reinterpret_cast<typelib_InterfaceTypeDescription *
>( pTD ) );
499 ::uno_any_construct(
reinterpret_cast< uno_Any *
>( gpreg[0] ),
500 &pInterface, pTD, cpp_acquire );
502 pInterface->release();
503 TYPELIB_DANGER_RELEASE( pTD );
505 reinterpret_cast<void **
>( pRegisterReturn )[0] = gpreg[0];
506 eRet = typelib_TypeClass_ANY;
509 TYPELIB_DANGER_RELEASE( pTD );
514 fprintf(stderr,
"cpp_vtable_call method query interface\n");
516 typelib_InterfaceMethodTypeDescription *pMethodTD =
517 reinterpret_cast<typelib_InterfaceMethodTypeDescription *
>( aMemberDescr.get() );
520 pMethodTD->pReturnTypeRef,
523 gpreg, fpreg, ovrflw, pRegisterReturn );
530 fprintf(stderr,
"cpp_vtable_call no member\n");
544 sal_Int32 functionIndex, sal_Int32 vtableOffset,
545 bool bHasHiddenParam )
548 fprintf(stderr,
"in codeSnippet functionIndex is %d\n", functionIndex);
549 fprintf(stderr,
"in codeSnippet vtableOffset is %d\n", vtableOffset);
553 if ( bHasHiddenParam )
554 functionIndex |= 0x80000000;
556 unsigned int *
p = (
unsigned int *) code;
558 assert((((
unsigned long)code) & 0x3) == 0 );
585 *
p++ = 0x3c020000 | ((functionIndex>>16) & 0x0000ffff);
586 *
p++ = 0x34420000 | (functionIndex & 0x0000ffff);
593 *
p++ = 0x3c190000 | ((((
unsigned long)
cpp_vtable_call) >> 48) & 0x0000ffff);
594 *
p++ = 0x37390000 | ((((
unsigned long)
cpp_vtable_call) >> 32) & 0x0000ffff);
596 *
p++ = 0x37390000 | ((((
unsigned long)
cpp_vtable_call) >> 16) & 0x0000ffff);
599 *
p++ = 0x3c030000 | ((vtableOffset>>16) & 0x0000ffff);
601 *
p++ = 0x34630000 | (vtableOffset & 0x0000ffff);
614 sysmips(FLUSH_CACHE, 0, 0, 0);
616 cacheflush((
long) bptr, (
long) eptr, 0);
625 return static_cast< Slot *
>(block) + 2;
643 void * block, sal_Int32 slotCount, sal_Int32,
644 typelib_InterfaceTypeDescription *)
646 Slot * slots = mapBlockToVtable(block);
648 slots[-1].fn = &
typeid(ProxyRtti);
649 return slots + slotCount;
653 Slot ** slots,
unsigned char * code, sal_PtrDiff writetoexecdiff,
654 typelib_InterfaceTypeDescription
const * type, sal_Int32 functionOffset,
655 sal_Int32 functionCount, sal_Int32 vtableOffset)
657 (*slots) -= functionCount;
661 fprintf(stderr,
"in addLocalFunctions functionOffset is %d\n", functionOffset);
662 fprintf(stderr,
"in addLocalFunctions vtableOffset is %d\n", vtableOffset);
663 fprintf(stderr,
"nMembers=%d\n",
type->nMembers);
667 for (sal_Int32 i = 0;
i <
type->nMembers; ++
i) {
669 TYPELIB_DANGER_GET(&member,
type->ppMembers[i]);
671 switch (member->eTypeClass) {
672 case typelib_TypeClass_INTERFACE_ATTRIBUTE:
674 (s++)->fn = code + writetoexecdiff;
676 code, functionOffset++, vtableOffset,
679 typelib_InterfaceAttributeTypeDescription *
>(
680 member)->pAttributeTypeRef));
683 if (!
reinterpret_cast<
684 typelib_InterfaceAttributeTypeDescription *
>(
687 (s++)->fn = code + writetoexecdiff;
692 case typelib_TypeClass_INTERFACE_METHOD:
693 (s++)->fn = code + writetoexecdiff;
695 code, functionOffset++, vtableOffset,
698 typelib_InterfaceMethodTypeDescription *
>(
699 member)->pReturnTypeRef));
706 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)
void(* privateSnippetExecutor)()
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
bool return_in_hidden_param(typelib_TypeDescriptionReference *pTypeRef)
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,...
OString OUStringToOString(std::u16string_view str, ConnectionSettings const *settings)