19#include <com/sun/star/uno/genfunc.hxx>
21#include <typelib/typedescription.hxx>
23#include <osl/endian.h>
42#include <rtl/strbuf.hxx>
43#include <rtl/ustrbuf.hxx>
53 const typelib_CompoundTypeDescription*
p
54 =
reinterpret_cast<const typelib_CompoundTypeDescription*
>(
type);
55 for (sal_Int32 i = 0;
i <
p->nMembers; ++
i)
57 if (
p->ppTypeRefs[i]->eTypeClass == typelib_TypeClass_STRUCT
58 ||
p->ppTypeRefs[i]->eTypeClass == typelib_TypeClass_EXCEPTION)
61 TYPELIB_DANGER_GET(&t,
p->ppTypeRefs[i]);
63 TYPELIB_DANGER_RELEASE(t);
72 if (
p->pBaseTypeDescription != 0)
81 else if (pTypeRef->eTypeClass == typelib_TypeClass_STRUCT
82 || pTypeRef->eTypeClass == typelib_TypeClass_EXCEPTION)
85 TYPELIB_DANGER_GET(&pTypeDescr, pTypeRef);
90 TYPELIB_DANGER_RELEASE(pTypeDescr);
102 typelib_TypeDescriptionReference* pReturnTypeRef,
103 sal_Int32 nParams, typelib_MethodParameter* pParams,
void** gpreg,
void** fpreg,
104 void** ovrflw, sal_uInt64* pRegisterReturn )
107 printf(
"In cpp2uno_call, pThis = %p, pMemberTypeDescr = %p, pReturnTypeRef = %p\n", pThis,
108 pMemberTypeDescr, pReturnTypeRef);
109 printf(
"In cpp2uno_call, nParams = %d, pParams = %p, pRegisterReturn = %p\n", nParams, pParams,
111 printf(
"In cpp2uno_call, gpreg = %p, fpreg = %p, ovrflw = %p\n", gpreg, fpreg, ovrflw);
113 unsigned int nr_gpr = 0;
114 unsigned int nr_fpr = 0;
116 char* gpreg_t =
reinterpret_cast<char*
>(gpreg);
117 char* fpreg_t =
reinterpret_cast<char*
>(fpreg);
120 fprintf(stdout,
"cpp2uno_call:begin\n");
125 TYPELIB_DANGER_GET(&pReturnTypeDescr, pReturnTypeRef);
127 void* pUnoReturn = 0;
128 void* pCppReturn = 0;
130 if (pReturnTypeDescr)
134 pCppReturn = *gpreg++;
138 ? alloca(pReturnTypeDescr->nSize)
141 fprintf(stdout,
"cpp2uno_call:complexreturn\n");
146 pUnoReturn = pRegisterReturn;
148 fprintf(stdout,
"cpp2uno_call:simplereturn\n");
158 static_assert(
sizeof(
void*) ==
sizeof(sal_Int64),
"### unexpected size!");
160 void** pUnoArgs = (
void**)alloca(4 *
sizeof(
void*) * nParams);
161 void** pCppArgs = pUnoArgs + nParams;
163 sal_Int32* pTempIndices = (sal_Int32*)(pUnoArgs + (2 * nParams));
168 sal_Int32 nTempIndices = 0;
171 fprintf(stdout,
"cpp2uno_call:nParams=%d\n", nParams);
173 for (sal_Int32 nPos = 0;
nPos < nParams; ++
nPos)
175 const typelib_MethodParameter& rParam = pParams[
nPos];
178 TYPELIB_DANGER_GET(&pParamTypeDescr, rParam.pTypeRef);
183 fprintf(stdout,
"cpp2uno_call:Param %u, type %u\n", nPos, pParamTypeDescr->eTypeClass);
185 switch (pParamTypeDescr->eTypeClass)
187 case typelib_TypeClass_FLOAT:
188 case typelib_TypeClass_DOUBLE:
192 fprintf(stdout,
"cpp2uno_call:fpr=%p\n", *fpreg);
194 pCppArgs[
nPos] = pUnoArgs[
nPos] = fpreg++;
200 fprintf(stdout,
"cpp2uno_call:fpr=%p\n", *gpreg);
202 pCppArgs[
nPos] = pUnoArgs[
nPos] = gpreg++;
208 fprintf(stdout,
"cpp2uno_call:fpr=%p\n", *ovrflw);
210 pCppArgs[
nPos] = pUnoArgs[
nPos] = ovrflw++;
219 fprintf(stdout,
"cpp2uno_call:gpr=%p\n", *gpreg);
221 pCppArgs[
nPos] = pUnoArgs[
nPos] = gpreg++;
227 fprintf(stdout,
"cpp2uno_call:gpr=%p\n", *ovrflw);
229 pCppArgs[
nPos] = pUnoArgs[
nPos] = ovrflw++;
234 TYPELIB_DANGER_RELEASE(pParamTypeDescr);
239 fprintf(stdout,
"cpp2uno_call:ptr|ref\n");
244 pCppArgs[
nPos] = pCppStack = *gpreg++;
249 pCppArgs[
nPos] = pCppStack = *ovrflw++;
252 fprintf(stdout,
"cpp2uno_call:pCppStack=%p\n", pCppStack);
258 pUnoArgs[
nPos] = alloca(pParamTypeDescr->nSize);
259 pTempIndices[nTempIndices] =
nPos;
261 ppTempParamTypeDescr[nTempIndices++] = pParamTypeDescr;
268 pTempIndices[nTempIndices] =
nPos;
270 ppTempParamTypeDescr[nTempIndices++] = pParamTypeDescr;
272 fprintf(stdout,
"cpp2uno_call:related to interface,%p,%d,pUnoargs[%d]=%p\n",
273 pCppStack, pParamTypeDescr->nSize, nPos, pUnoArgs[nPos]);
278 pUnoArgs[
nPos] = pCppStack;
280 fprintf(stdout,
"cpp2uno_call:direct,pUnoArgs[%d]=%p\n", nPos, pUnoArgs[nPos]);
283 TYPELIB_DANGER_RELEASE(pParamTypeDescr);
288 fprintf(stdout,
"cpp2uno_call2,%p,unoargs=%p\n", pThis->
getUnoI()->pDispatcher, pUnoArgs);
289 printf(
"pMemberTypeDescr=%p,pUnoReturn=%p\n", pMemberTypeDescr, pUnoReturn);
296 printf(
"pThis=%p,pThis->getUnoI()=%p,pMemberTypeDescr=%p\npUnoReturn=%p,pUnoArgs=%p", pThis,
297 pThis->
getUnoI(), pMemberTypeDescr, pUnoReturn, pUnoArgs);
300 (*pThis->
getUnoI()->pDispatcher)(pThis->
getUnoI(), pMemberTypeDescr, pUnoReturn, pUnoArgs,
303 fprintf(stdout,
"cpp2uno_call2,after dispatch\n");
311 for (; nTempIndices--;)
313 sal_Int32
nIndex = pTempIndices[nTempIndices];
315 if (pParams[nIndex].bIn)
317 TYPELIB_DANGER_RELEASE(ppTempParamTypeDescr[nTempIndices]);
319 if (pReturnTypeDescr)
320 TYPELIB_DANGER_RELEASE(pReturnTypeDescr);
325 return typelib_TypeClass_VOID;
330 for (; nTempIndices--;)
332 sal_Int32
nIndex = pTempIndices[nTempIndices];
335 if (pParams[nIndex].bOut)
345 TYPELIB_DANGER_RELEASE(pParamTypeDescr);
347 void* retout =
nullptr;
349 sal_Int32 returnType = 0;
350 if (pReturnTypeDescr)
352 char* pReturn =
reinterpret_cast<char*
>(pRegisterReturn);
355 switch (pReturnTypeDescr ==
nullptr ? typelib_TypeClass_VOID
356 : pReturnTypeDescr->eTypeClass)
358 case typelib_TypeClass_HYPER:
359 case typelib_TypeClass_UNSIGNED_HYPER:
360 case typelib_TypeClass_LONG:
361 case typelib_TypeClass_UNSIGNED_LONG:
362 case typelib_TypeClass_ENUM:
363 case typelib_TypeClass_CHAR:
364 case typelib_TypeClass_SHORT:
365 case typelib_TypeClass_UNSIGNED_SHORT:
366 case typelib_TypeClass_BOOLEAN:
367 case typelib_TypeClass_BYTE:
368 std::memcpy(pReturn, pUnoReturn, 8);
370 case typelib_TypeClass_FLOAT:
371 std::memcpy(pReturn, pUnoReturn, 4);
372 std::memset(pReturn + 4, 0xFF, 4);
374 case typelib_TypeClass_DOUBLE:
375 std::memcpy(pReturn, pUnoReturn, 8);
377 case typelib_TypeClass_STRUCT:
378 case typelib_TypeClass_EXCEPTION:
380 std::memcpy(pReturn, pUnoReturn, 16);
385 reinterpret_cast<typelib_CompoundTypeDescription const*
>(
387 if (pReturnTypeDescr->nSize <= 8 && nFreg == 2 && nGreg == 0)
389 std::memcpy(pReturn + 8, pReturn + 4, 4);
390 std::memset(pReturn + 4, 0xFF, 4);
391 std::memset(pReturn + 12, 0xFF, 4);
393 else if (nGreg == 1 && nFreg == 1)
396 if (pReturnTypeDescr->nSize <= 8)
398 std::memcpy(pReturn + 8, pReturn + 4, 4);
399 std::memset(pReturn + 12, 0xFF, 4);
404 case typelib_TypeClass_VOID:
409 std::memcpy(pRegisterReturn, pUnoReturn, 16);
412 printf(
"Unhandled Type: %d\n", pReturnTypeDescr->eTypeClass);
423 *(
void**)pRegisterReturn = pCppReturn;
425 TYPELIB_DANGER_RELEASE(pReturnTypeDescr);
435sal_Int32
cpp_vtable_call(sal_Int32 nFunctionIndex, sal_Int32 nVtableOffset,
void** gpreg,
436 void** fpreg,
void** ovrflw,
437 sal_uInt64* pRegisterReturn )
439 static_assert(
sizeof(sal_Int64) ==
sizeof(
void*),
"### unexpected!");
442 fprintf(stdout,
"in cpp_vtable_call nFunctionIndex is %d\n", nFunctionIndex);
443 fprintf(stdout,
"in cpp_vtable_call nVtableOffset is %d\n", nVtableOffset);
444 fprintf(stdout,
"in cpp_vtable_call gp=%p, fp=%p, ov=%p\n", gpreg, fpreg, ovrflw);
451 if (nFunctionIndex & 0x80000000)
453 nFunctionIndex &= 0x7fffffff;
461 fprintf(stdout,
"cpp_vtable_call, pThis=%p, nFunctionIndex=%d, nVtableOffset=%d\n", pThis,
462 nFunctionIndex, nVtableOffset);
465 pThis =
static_cast<char*
>(pThis) - nVtableOffset;
469 fprintf(stdout,
"cpp_vtable_call, pCppI=%p\n", pCppI);
472 typelib_InterfaceTypeDescription* pTypeDescr = pCppI->
getTypeDescr();
474 if (nFunctionIndex >= pTypeDescr->nMapFunctionIndexToMemberIndex)
476 SAL_WARN(
"bridges",
"illegal " << OUString::unacquired(&pTypeDescr->aBase.pTypeName)
477 <<
" vtable index " << nFunctionIndex <<
"/"
478 << pTypeDescr->nMapFunctionIndexToMemberIndex);
479 throw RuntimeException((
"illegal " + OUString::unacquired(&pTypeDescr->aBase.pTypeName)
480 +
" vtable index " + OUString::number(nFunctionIndex) +
"/"
481 + OUString::number(pTypeDescr->nMapFunctionIndexToMemberIndex)),
486 sal_Int32 nMemberPos = pTypeDescr->pMapFunctionIndexToMemberIndex[nFunctionIndex];
487 assert(nMemberPos < pTypeDescr->nAllMembers);
489 TypeDescription aMemberDescr(pTypeDescr->ppAllMembers[nMemberPos]);
496 switch (aMemberDescr.get()->eTypeClass)
498 case typelib_TypeClass_INTERFACE_ATTRIBUTE:
501 fprintf(stdout,
"cpp_vtable_call interface attribute\n");
503 typelib_TypeDescriptionReference* pAttrTypeRef
504 =
reinterpret_cast<typelib_InterfaceAttributeTypeDescription*
>(aMemberDescr.get())
507 if (pTypeDescr->pMapMemberIndexToFunctionIndex[nMemberPos] == nFunctionIndex)
510 eRet =
cpp2uno_call(pCppI, aMemberDescr.get(), pAttrTypeRef, 0, 0,
511 gpreg, fpreg, ovrflw, pRegisterReturn);
516 typelib_MethodParameter aParam;
517 aParam.pTypeRef = pAttrTypeRef;
523 1, &aParam, gpreg, fpreg, ovrflw, pRegisterReturn);
527 case typelib_TypeClass_INTERFACE_METHOD:
530 fprintf(stdout,
"cpp_vtable_call interface method\n");
533 switch (nFunctionIndex)
537 fprintf(stdout,
"cpp_vtable_call method acquire\n");
544 fprintf(stdout,
"cpp_vtable_call method release\n");
552 fprintf(stdout,
"cpp_vtable_call method query interface opt\n");
555 TYPELIB_DANGER_GET(&pTD,
reinterpret_cast<Type*
>(gpreg[2])->getTypeLibType());
562 reinterpret_cast<typelib_InterfaceTypeDescription*
>(pTD));
566 ::uno_any_construct(
reinterpret_cast<uno_Any*
>(gpreg[0]), &pInterface,
569 pInterface->release();
570 TYPELIB_DANGER_RELEASE(pTD);
572 reinterpret_cast<void**
>(pRegisterReturn)[0] = gpreg[0];
576 TYPELIB_DANGER_RELEASE(pTD);
581 fprintf(stdout,
"cpp_vtable_call method query interface\n");
583 typelib_InterfaceMethodTypeDescription* pMethodTD
584 =
reinterpret_cast<typelib_InterfaceMethodTypeDescription*
>(
587 eRet =
cpp2uno_call(pCppI, aMemberDescr.get(), pMethodTD->pReturnTypeRef,
588 pMethodTD->nParams, pMethodTD->pParams, gpreg, fpreg,
589 ovrflw, pRegisterReturn);
596 fprintf(stdout,
"cpp_vtable_call no member\n");
609unsigned char*
codeSnippet(
unsigned char* code, sal_Int32 functionIndex, sal_Int32 vtableOffset,
610 bool bHasHiddenParam)
613 fprintf(stdout,
"in codeSnippet functionIndex is %d\n", functionIndex);
614 fprintf(stdout,
"in codeSnippet vtableOffset is %d\n", vtableOffset);
615 fprintf(stdout,
"in codeSnippet privateSnippetExecutor is %lx\n",
617 fprintf(stdout,
"in codeSnippet cpp_vtable_call is %lx\n", (
unsigned long)
cpp_vtable_call);
623 functionIndex |= 0x80000000;
625 unsigned int*
p = (
unsigned int*)code;
627 assert((((
unsigned long)code) & 0x3) == 0);
667 *
p++ = 0x00000eb7 | ((functionIndex)&0xfffff000);
668 *
p++ = 0x000eee93 | ((functionIndex << 20) & 0xfff00000);
672 *
p++ = 0x000002b7 | ((functionEntry >> 36) & 0x000000000ffff000);
674 *
p++ = 0x00000337 | ((functionEntry >> 20) & 0x000000000ffff000);
677 *
p++ = 0x00000337 | ((functionEntry >> 4) & 0x000000000ffff000);
680 *
p++ = 0x00000337 | ((functionEntry << 12) & 0x000000000ffff000);
685 *
p++ = 0x00000fb7 | ((functionEntry >> 36) & 0x000000000ffff000);
687 *
p++ = 0x00000337 | ((functionEntry >> 20) & 0x000000000ffff000);
690 *
p++ = 0x00000337 | ((functionEntry >> 4) & 0x000000000ffff000);
693 *
p++ = 0x00000337 | ((functionEntry << 12) & 0x000000000ffff000);
697 *
p++ = 0x00000f37 | ((vtableOffset)&0xfffff000);
698 *
p++ = 0x000f6f13 | ((vtableOffset << 20) & 0xfff00000);
706 unsigned char const* eptr)
708 asm volatile(
"fence" :::);
719 return static_cast<Slot*
>(block) + 2;
739 typelib_InterfaceTypeDescription*)
741 Slot* slots = mapBlockToVtable(block);
743 slots[-1].fn = &
typeid(ProxyRtti);
744 return slots + slotCount;
748 Slot** slots,
unsigned char* code, sal_PtrDiff writetoexecdiff,
749 typelib_InterfaceTypeDescription
const* type, sal_Int32 functionOffset, sal_Int32 functionCount,
750 sal_Int32 vtableOffset)
752 (*slots) -= functionCount;
756 fprintf(stdout,
"in addLocalFunctions functionOffset is %d\n", functionOffset);
757 fprintf(stdout,
"in addLocalFunctions vtableOffset is %d\n", vtableOffset);
758 fprintf(stdout,
"nMembers=%d\n",
type->nMembers);
762 for (sal_Int32 i = 0;
i <
type->nMembers; ++
i)
765 TYPELIB_DANGER_GET(&member,
type->ppMembers[i]);
767 switch (member->eTypeClass)
769 case typelib_TypeClass_INTERFACE_ATTRIBUTE:
771 (s++)->fn = code + writetoexecdiff;
773 code, functionOffset++, vtableOffset,
775 reinterpret_cast<typelib_InterfaceAttributeTypeDescription*
>(member)
776 ->pAttributeTypeRef));
779 if (!
reinterpret_cast<typelib_InterfaceAttributeTypeDescription*
>(member)
782 (s++)->fn = code + writetoexecdiff;
787 case typelib_TypeClass_INTERFACE_METHOD:
788 (s++)->fn = code + writetoexecdiff;
790 code, functionOffset++, vtableOffset,
792 reinterpret_cast<typelib_InterfaceMethodTypeDescription*
>(member)
800 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)
void countnGreg(sal_Int32 &nGreg, sal_Int32 &nFreg, const typelib_CompoundTypeDescription *pTypeDescr)
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,...