20#include <com/sun/star/uno/genfunc.hxx>
22#include <typelib/typedescription.hxx>
24#include <osl/endian.h>
43 const typelib_CompoundTypeDescription*
p
44 =
reinterpret_cast<const typelib_CompoundTypeDescription*
>(
type);
45 for (sal_Int32
i = 0;
i <
p->nMembers; ++
i)
47 if (
p->ppTypeRefs[
i]->eTypeClass == typelib_TypeClass_STRUCT
48 ||
p->ppTypeRefs[
i]->eTypeClass == typelib_TypeClass_EXCEPTION)
51 TYPELIB_DANGER_GET(&
t,
p->ppTypeRefs[
i]);
53 TYPELIB_DANGER_RELEASE(
t);
62 if (
p->pBaseTypeDescription != 0)
71 else if (pTypeRef->eTypeClass == typelib_TypeClass_STRUCT
72 || pTypeRef->eTypeClass == typelib_TypeClass_EXCEPTION)
75 TYPELIB_DANGER_GET(&pTypeDescr, pTypeRef);
80 TYPELIB_DANGER_RELEASE(pTypeDescr);
91 typelib_TypeDescriptionReference* pReturnTypeRef,
92 sal_Int32 nParams, typelib_MethodParameter* pParams,
void** gpreg,
93 void** fpreg,
void** ovrflw,
94 sal_uInt64* pRegisterReturn )
103 TYPELIB_DANGER_GET(&pReturnTypeDescr, pReturnTypeRef);
105 = (pReturnTypeRef ==
nullptr || pReturnTypeRef->eTypeClass == typelib_TypeClass_VOID)
109 void* pUnoReturn = 0;
110 void* pCppReturn = 0;
112 if (pReturnTypeDescr)
116 pCppReturn = gpreg[gCount++];
118 ? alloca(pReturnTypeDescr->nSize)
123 pUnoReturn = pRegisterReturn;
131 static_assert(
sizeof(
void*) ==
sizeof(sal_Int64),
"### unexpected size!");
133 void** pUnoArgs = (
void**)alloca(4 *
sizeof(
void*) * nParams);
134 void** pCppArgs = pUnoArgs + nParams;
136 sal_Int32* pTempIndices = (sal_Int32*)(pUnoArgs + (2 * nParams));
141 sal_Int32 nTempIndices = 0;
143 for (sal_Int32 nPos = 0;
nPos < nParams; ++
nPos)
145 const typelib_MethodParameter& rParam = pParams[
nPos];
148 TYPELIB_DANGER_GET(&pParamTypeDescr, rParam.pTypeRef);
152 switch (pParamTypeDescr->eTypeClass)
154 case typelib_TypeClass_FLOAT:
155 case typelib_TypeClass_DOUBLE:
159 : (gCount !=
MAX_GP_REGS ? &(gpreg[gCount++]) : &(ovrflw[sp++]));
163 pCppArgs[
nPos] = gCount ==
MAX_GP_REGS ? &(ovrflw[sp++]) : &(gpreg[gCount++]);
168 TYPELIB_DANGER_RELEASE(pParamTypeDescr);
173 pCppStack = gCount ==
MAX_GP_REGS ? ovrflw[sp++] : gpreg[gCount++];
174 pCppArgs[
nPos] = pCppStack;
178 pUnoArgs[
nPos] = alloca(pParamTypeDescr->nSize);
179 pTempIndices[nTempIndices] =
nPos;
181 ppTempParamTypeDescr[nTempIndices++] = pParamTypeDescr;
188 pTempIndices[nTempIndices] =
nPos;
190 ppTempParamTypeDescr[nTempIndices++] = pParamTypeDescr;
194 pUnoArgs[
nPos] = pCppStack;
196 TYPELIB_DANGER_RELEASE(pParamTypeDescr);
205 (*pThis->
getUnoI()->pDispatcher)(pThis->
getUnoI(), pMemberTypeDescr, pUnoReturn, pUnoArgs,
211 for (; nTempIndices--;)
213 sal_Int32
nIndex = pTempIndices[nTempIndices];
215 if (pParams[nIndex].bIn)
217 TYPELIB_DANGER_RELEASE(ppTempParamTypeDescr[nTempIndices]);
219 if (pReturnTypeDescr)
220 TYPELIB_DANGER_RELEASE(pReturnTypeDescr);
230 for (; nTempIndices--;)
232 sal_Int32
nIndex = pTempIndices[nTempIndices];
235 if (pParams[nIndex].bOut)
245 TYPELIB_DANGER_RELEASE(pParamTypeDescr);
250 if (pUnoReturn != pCppReturn)
258 *(
void**)pRegisterReturn = pCppReturn;
260 if (pReturnTypeDescr)
262 TYPELIB_DANGER_RELEASE(pReturnTypeDescr);
280int cpp_vtable_call(sal_Int32 nFunctionIndex, sal_Int32 nVtableOffset,
void** gpreg,
void** fpreg,
281 void** ovrflw, sal_uInt64* pRegisterReturn )
283 static_assert(
sizeof(sal_Int64) ==
sizeof(
void*),
"### unexpected!");
289 if (nFunctionIndex & 0x80000000)
291 nFunctionIndex &= 0x7fffffff;
298 pThis =
static_cast<char*
>(pThis) - nVtableOffset;
301 typelib_InterfaceTypeDescription* pTypeDescr = pCppI->
getTypeDescr();
303 if (nFunctionIndex >= pTypeDescr->nMapFunctionIndexToMemberIndex)
305 SAL_WARN(
"bridges",
"illegal " << OUString::unacquired(&pTypeDescr->aBase.pTypeName)
306 <<
" vtable index " << nFunctionIndex <<
"/"
307 << pTypeDescr->nMapFunctionIndexToMemberIndex);
308 throw RuntimeException((
"illegal " + OUString::unacquired(&pTypeDescr->aBase.pTypeName)
309 +
" vtable index " + OUString::number(nFunctionIndex) +
"/"
310 + OUString::number(pTypeDescr->nMapFunctionIndexToMemberIndex)),
315 sal_Int32 nMemberPos = pTypeDescr->pMapFunctionIndexToMemberIndex[nFunctionIndex];
316 assert(nMemberPos < pTypeDescr->nAllMembers);
318 TypeDescription aMemberDescr(pTypeDescr->ppAllMembers[nMemberPos]);
321 switch (aMemberDescr.get()->eTypeClass)
323 case typelib_TypeClass_INTERFACE_ATTRIBUTE:
325 typelib_TypeDescriptionReference* pAttrTypeRef
326 =
reinterpret_cast<typelib_InterfaceAttributeTypeDescription*
>(aMemberDescr.get())
329 if (pTypeDescr->pMapMemberIndexToFunctionIndex[nMemberPos] == nFunctionIndex)
332 eRet =
cpp2uno_call(pCppI, aMemberDescr.get(), pAttrTypeRef, 0, 0,
333 gpreg, fpreg, ovrflw, pRegisterReturn);
338 typelib_MethodParameter aParam;
339 aParam.pTypeRef = pAttrTypeRef;
345 1, &aParam, gpreg, fpreg, ovrflw, pRegisterReturn);
349 case typelib_TypeClass_INTERFACE_METHOD:
352 switch (nFunctionIndex)
365 TYPELIB_DANGER_GET(&pTD,
reinterpret_cast<Type*
>(gpreg[2])->getTypeLibType());
372 reinterpret_cast<typelib_InterfaceTypeDescription*
>(pTD));
376 ::uno_any_construct(
reinterpret_cast<uno_Any*
>(gpreg[0]), &pInterface,
379 pInterface->release();
380 TYPELIB_DANGER_RELEASE(pTD);
382 reinterpret_cast<void**
>(pRegisterReturn)[0] = gpreg[0];
386 TYPELIB_DANGER_RELEASE(pTD);
390 typelib_InterfaceMethodTypeDescription* pMethodTD
391 =
reinterpret_cast<typelib_InterfaceMethodTypeDescription*
>(
394 eRet =
cpp2uno_call(pCppI, aMemberDescr.get(), pMethodTD->pReturnTypeRef,
395 pMethodTD->nParams, pMethodTD->pParams, gpreg, fpreg,
396 ovrflw, pRegisterReturn);
413unsigned char*
codeSnippet(
unsigned char* code, sal_Int32 functionIndex, sal_Int32 vtableOffset,
414 bool bHasHiddenParam)
417 functionIndex |= 0x80000000;
419 unsigned int*
p = (
unsigned int*)code;
421 assert((((
unsigned long)code) & 0x3) == 0);
444 *
p++ = 0x14000012 | (((functionIndex >> 12) & 0x000fffff) << 5);
445 *
p++ = 0x03800252 | ((functionIndex & 0x00000fff) << 10);
450 *
p++ = 0x14000011 | (((((
unsigned long)
cpp_vtable_call) >> 12) & 0x000fffff) << 5);
451 *
p++ = 0x03800231 | ((((
unsigned long)
cpp_vtable_call) & 0x00000fff) << 10);
452 *
p++ = 0x16000011 | (((((
unsigned long)
cpp_vtable_call) >> 32) & 0x000fffff) << 5);
453 *
p++ = 0x03000231 | (((((
unsigned long)
cpp_vtable_call) >> 52) & 0x00000fff) << 10);
454 *
p++ = 0x14000013 | (((vtableOffset >> 12) & 0x000fffff) << 5);
455 *
p++ = 0x03800273 | ((vtableOffset & 0x00000fff) << 10);
462 unsigned char const* eptr)
464 asm volatile(
"ibar 0" :::);
475 return static_cast<Slot*
>(block) + 2;
495 typelib_InterfaceTypeDescription*)
497 Slot* slots = mapBlockToVtable(block);
499 slots[-1].fn = &
typeid(ProxyRtti);
500 return slots + slotCount;
504 Slot** slots,
unsigned char* code, sal_PtrDiff writetoexecdiff,
505 typelib_InterfaceTypeDescription
const* type, sal_Int32 functionOffset, sal_Int32 functionCount,
506 sal_Int32 vtableOffset)
508 (*slots) -= functionCount;
511 for (sal_Int32 i = 0;
i <
type->nMembers; ++
i)
514 TYPELIB_DANGER_GET(&member,
type->ppMembers[i]);
516 switch (member->eTypeClass)
518 case typelib_TypeClass_INTERFACE_ATTRIBUTE:
520 (s++)->fn = code + writetoexecdiff;
522 code, functionOffset++, vtableOffset,
524 reinterpret_cast<typelib_InterfaceAttributeTypeDescription*
>(member)
525 ->pAttributeTypeRef));
528 if (!
reinterpret_cast<typelib_InterfaceAttributeTypeDescription*
>(member)
531 (s++)->fn = code + writetoexecdiff;
536 case typelib_TypeClass_INTERFACE_METHOD:
537 (s++)->fn = code + writetoexecdiff;
539 code, functionOffset++, vtableOffset,
541 reinterpret_cast<typelib_InterfaceMethodTypeDescription*
>(member)
549 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,...
ReturnKind getReturnKind(typelib_TypeDescriptionReference *type)