26#include <com/sun/star/uno/genfunc.hxx>
27#include <com/sun/star/uno/RuntimeException.hpp>
29#include <typelib/typedescription.hxx>
54 typelib_TypeDescriptionReference * pReturnTypeRef,
55 sal_Int32 nParams, typelib_MethodParameter * pParams,
57 sal_Int64 * pRegisterReturn )
60 char * pTopStack =
reinterpret_cast<char *
>(pCallStack + 0);
61 char * pCppStack = pTopStack;
65 char * pFloatArgs =
reinterpret_cast<char *
>(pCppStack - 64);
70 TYPELIB_DANGER_GET( &pReturnTypeDescr, pReturnTypeRef );
72 void * pUnoReturn =
nullptr;
74 void * pCppReturn =
nullptr;
79 pUnoReturn = pRegisterReturn;
82 pCppReturn = *
reinterpret_cast<void **
>(pCppStack);
83 pCppStack +=
sizeof(
void *);
87 ? alloca( pReturnTypeDescr->nSize )
92 pCppStack +=
sizeof(
void* );
95 static_assert(
sizeof(
void *) ==
sizeof(sal_Int32),
96 "### unexpected size!");
98 void ** pUnoArgs =
static_cast<void **
>(alloca( 4 *
sizeof(
void *) * nParams ));
99 void ** pCppArgs = pUnoArgs + nParams;
102 sal_Int32 * pTempIndices =
reinterpret_cast<sal_Int32 *
>(pUnoArgs + (2 * nParams));
107 sal_Int32 nTempIndices = 0;
109 for ( sal_Int32 nPos = 0;
nPos < nParams; ++
nPos )
111 const typelib_MethodParameter & rParam = pParams[
nPos];
113 TYPELIB_DANGER_GET( &pParamTypeDescr, rParam.pTypeRef );
119 switch (pParamTypeDescr->eTypeClass)
121 case typelib_TypeClass_HYPER:
122 case typelib_TypeClass_UNSIGNED_HYPER:
124 case typelib_TypeClass_DOUBLE:
126 if ((pCppStack - pTopStack) % 8) pCppStack+=
sizeof(sal_Int32);
135 if (pParamTypeDescr->eTypeClass == typelib_TypeClass_FLOAT)
137 pCppArgs[
nPos] = pUnoArgs[
nPos] = pFloatArgs;
138 pFloatArgs +=
sizeof(float);
140 if (pParamTypeDescr->eTypeClass == typelib_TypeClass_DOUBLE)
142 if ((pFloatArgs - pTopStack) % 8) pFloatArgs+=
sizeof(
float);
143 pCppArgs[
nPos] = pUnoArgs[
nPos] = pFloatArgs;
144 pFloatArgs +=
sizeof(double);
146 if (pCppStack - pTopStack < 16)
147 pCppStack = pTopStack + 16;
148 pFloatArgs = pCppStack;
152 pCppArgs[
nPos] = pUnoArgs[
nPos] = pCppStack;
154 switch (pParamTypeDescr->eTypeClass)
156 case typelib_TypeClass_HYPER:
157 case typelib_TypeClass_UNSIGNED_HYPER:
159 case typelib_TypeClass_DOUBLE:
161 pCppStack +=
sizeof(sal_Int32);
167 TYPELIB_DANGER_RELEASE( pParamTypeDescr );
171 pCppArgs[
nPos] = *
reinterpret_cast<void **
>(pCppStack);
176 pUnoArgs[
nPos] = alloca( pParamTypeDescr->nSize );
177 pTempIndices[nTempIndices] =
nPos;
179 ppTempParamTypeDescr[nTempIndices++] = pParamTypeDescr;
186 alloca( pParamTypeDescr->nSize ),
187 *
reinterpret_cast<void **
>(pCppStack), pParamTypeDescr,
189 pTempIndices[nTempIndices] =
nPos;
191 ppTempParamTypeDescr[nTempIndices++] = pParamTypeDescr;
195 pUnoArgs[
nPos] = *
reinterpret_cast<void **
>(pCppStack);
197 TYPELIB_DANGER_RELEASE( pParamTypeDescr );
203 ((pParamTypeDescr->eTypeClass != typelib_TypeClass_DOUBLE)
204 && (pParamTypeDescr->eTypeClass != typelib_TypeClass_FLOAT))
207 pCppStack +=
sizeof(sal_Int32);
215 (*pThis->
getUnoI()->pDispatcher)(
216 pThis->
getUnoI(), pMemberTypeDescr, pUnoReturn, pUnoArgs, &pUnoExc );
222 for ( ; nTempIndices--; )
224 sal_Int32
nIndex = pTempIndices[nTempIndices];
226 if (pParams[nIndex].bIn)
228 ppTempParamTypeDescr[nTempIndices],
nullptr );
229 TYPELIB_DANGER_RELEASE( ppTempParamTypeDescr[nTempIndices] );
231 if (pReturnTypeDescr)
232 TYPELIB_DANGER_RELEASE( pReturnTypeDescr );
237 return typelib_TypeClass_VOID;
242 for ( ; nTempIndices--; )
244 sal_Int32
nIndex = pTempIndices[nTempIndices];
246 ppTempParamTypeDescr[nTempIndices];
248 if (pParams[nIndex].bOut)
259 TYPELIB_DANGER_RELEASE( pParamTypeDescr );
264 if (pUnoReturn != pCppReturn)
272 *
reinterpret_cast<void **
>(pRegisterReturn) = pCppReturn;
274 if (pReturnTypeDescr)
276 typelib_TypeClass eRet = pReturnTypeDescr->eTypeClass;
277 TYPELIB_DANGER_RELEASE( pReturnTypeDescr );
281 return typelib_TypeClass_VOID;
287 sal_Int32 nFunctionIndex, sal_Int32 nVtableOffset,
289 sal_Int64 * pRegisterReturn )
291 static_assert(
sizeof(sal_Int32)==
sizeof(
void *),
"### unexpected!");
296 if( nFunctionIndex & 0x80000000 )
298 nFunctionIndex &= 0x7fffffff;
299 pThis = pCallStack[1];
303 pThis = pCallStack[0];
306 pThis =
static_cast< char *
>(pThis) - nVtableOffset;
311 typelib_InterfaceTypeDescription * pTypeDescr = pCppI->
getTypeDescr();
313 if (nFunctionIndex >= pTypeDescr->nMapFunctionIndexToMemberIndex)
317 "illegal " << OUString::unacquired(&pTypeDescr->aBase.pTypeName)
318 <<
" vtable index " << nFunctionIndex <<
"/"
319 << pTypeDescr->nMapFunctionIndexToMemberIndex);
321 (
"illegal " + OUString::unacquired(&pTypeDescr->aBase.pTypeName)
322 +
" vtable index " + OUString::number(nFunctionIndex) +
"/"
323 + OUString::number(pTypeDescr->nMapFunctionIndexToMemberIndex)),
328 assert(nFunctionIndex < pTypeDescr->nMapFunctionIndexToMemberIndex);
329 sal_Int32 nMemberPos =
330 pTypeDescr->pMapFunctionIndexToMemberIndex[nFunctionIndex];
331 assert(nMemberPos < pTypeDescr->nAllMembers);
333 TypeDescription aMemberDescr( pTypeDescr->ppAllMembers[nMemberPos] );
335 typelib_TypeClass eRet;
336 switch (aMemberDescr.get()->eTypeClass)
338 case typelib_TypeClass_INTERFACE_ATTRIBUTE:
340 if (pTypeDescr->pMapMemberIndexToFunctionIndex[nMemberPos] ==
345 pCppI, aMemberDescr.get(),
346 reinterpret_cast<typelib_InterfaceAttributeTypeDescription *
>(aMemberDescr.get())->pAttributeTypeRef,
348 pCallStack, pRegisterReturn );
353 typelib_MethodParameter aParam;
355 reinterpret_cast<typelib_InterfaceAttributeTypeDescription *
>(aMemberDescr.get())->pAttributeTypeRef;
360 pCppI, aMemberDescr.get(),
363 pCallStack, pRegisterReturn );
367 case typelib_TypeClass_INTERFACE_METHOD:
370 switch (nFunctionIndex)
374 eRet = typelib_TypeClass_VOID;
378 eRet = typelib_TypeClass_VOID;
383 TYPELIB_DANGER_GET(&pTD,
384 static_cast<Type *
>(pCallStack[2])->getTypeLibType());
390 reinterpret_cast<void **
>(&pInterface), pCppI->
getOid().pData,
391 reinterpret_cast<typelib_InterfaceTypeDescription *
>(pTD) );
396 static_cast< uno_Any *
>( pCallStack[0] ),
397 &pInterface, pTD, cpp_acquire );
398 pInterface->release();
399 TYPELIB_DANGER_RELEASE( pTD );
400 *
reinterpret_cast<void **
>(pRegisterReturn) = pCallStack[0];
401 eRet = typelib_TypeClass_ANY;
404 TYPELIB_DANGER_RELEASE( pTD );
409 pCppI, aMemberDescr.get(),
410 reinterpret_cast<typelib_InterfaceMethodTypeDescription *
>(aMemberDescr.get())->pReturnTypeRef,
411 reinterpret_cast<typelib_InterfaceMethodTypeDescription *
>(aMemberDescr.get())->nParams,
412 reinterpret_cast<typelib_InterfaceMethodTypeDescription *
>(aMemberDescr.get())->pParams,
413 pCallStack, pRegisterReturn );
435 sal_Int64 nRegReturn;
436 typelib_TypeClass aType =
cpp_mediate( pFunctionAndOffset[0], pFunctionAndOffset[1], pCallStack,
441 case typelib_TypeClass_BOOLEAN:
442 case typelib_TypeClass_BYTE:
443 nRegReturn =
static_cast<unsigned long>(*
reinterpret_cast<unsigned char *
>(&nRegReturn));
445 case typelib_TypeClass_CHAR:
446 case typelib_TypeClass_UNSIGNED_SHORT:
447 case typelib_TypeClass_SHORT:
448 nRegReturn =
static_cast<unsigned long>(*
reinterpret_cast<unsigned short *
>(&nRegReturn));
450 case typelib_TypeClass_ENUM:
451 case typelib_TypeClass_UNSIGNED_LONG:
452 case typelib_TypeClass_LONG:
453 nRegReturn =
static_cast<unsigned long>(*
reinterpret_cast<unsigned int *
>(&nRegReturn));
455 case typelib_TypeClass_VOID:
467 unsigned char *
codeSnippet(
unsigned char* code, sal_Int32 functionIndex,
468 sal_Int32 vtableOffset,
bool bHasHiddenParam)
471 functionIndex |= 0x80000000;
473 unsigned long *
p =
reinterpret_cast<unsigned long *
>(
code);
480 *
p++ =
static_cast<unsigned long>(functionIndex);
481 *
p++ =
static_cast<unsigned long>(vtableOffset);
493 return static_cast< Slot *
>(block) + 2;
510 void * block, sal_Int32 slotCount, sal_Int32,
511 typelib_InterfaceTypeDescription *)
513 Slot * slots = mapBlockToVtable(block);
514 slots[-2].fn =
nullptr;
515 slots[-1].fn = &
typeid(ProxyRtti);
516 return slots + slotCount;
520 Slot ** slots,
unsigned char * code,
522 sal_PtrDiff writetoexecdiff,
524 typelib_InterfaceTypeDescription
const * type, sal_Int32 functionOffset,
525 sal_Int32 functionCount, sal_Int32 vtableOffset)
527#ifndef USE_DOUBLE_MMAP
528 const sal_PtrDiff writetoexecdiff = 0;
530 (*slots) -= functionCount;
532 for (sal_Int32 i = 0;
i <
type->nMembers; ++
i)
535 TYPELIB_DANGER_GET(&member,
type->ppMembers[i]);
537 switch (member->eTypeClass)
539 case typelib_TypeClass_INTERFACE_ATTRIBUTE:
541 typelib_InterfaceAttributeTypeDescription *pAttrTD =
542 reinterpret_cast<typelib_InterfaceAttributeTypeDescription *
>( member );
545 (s++)->fn = code + writetoexecdiff;
547 code, functionOffset++, vtableOffset,
551 if (!pAttrTD->bReadOnly)
553 (s++)->fn = code + writetoexecdiff;
555 code, functionOffset++, vtableOffset,
false);
559 case typelib_TypeClass_INTERFACE_METHOD:
561 (s++)->fn = code + writetoexecdiff;
563 typelib_InterfaceMethodTypeDescription *pMethodTD =
565 typelib_InterfaceMethodTypeDescription *
>(member);
575 TYPELIB_DANGER_RELEASE(member);
581 unsigned char const *beg,
unsigned char const *end)
584 static void (*clear_cache)(
unsigned char const*,
unsigned char const*)
585 =
reinterpret_cast<void (*)(
unsigned char const*,
unsigned char const*)
>
586 (dlsym(RTLD_DEFAULT,
"__clear_cache"));
587 (*clear_cache)(beg,
end);
589 cacheflush((
long) beg, (
long) end, 0);
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()
sal_Int64 cpp_vtable_call(long *pFunctionAndOffset, void **pCallStack)
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
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 return_in_hidden_param(typelib_TypeDescriptionReference *pTypeRef)
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,...