26#include <com/sun/star/uno/genfunc.hxx>
27#include <com/sun/star/uno/RuntimeException.hpp>
28#include <config_options.h>
30#include <typelib/typedescription.hxx>
61 typelib_TypeDescriptionReference * pReturnTypeRef,
62 sal_Int32 nParams, typelib_MethodParameter * pParams,
63 void ** gpreg,
void ** fpreg,
void ** ovrflw,
64 sal_uInt64 * pRegisterReturn )
66 unsigned int nr_gpr = 0;
67 unsigned int nr_fpr = 0;
72 TYPELIB_DANGER_GET( &pReturnTypeDescr, pReturnTypeRef );
74 = (pReturnTypeRef ==
nullptr || pReturnTypeRef->eTypeClass == typelib_TypeClass_VOID)
77 void * pUnoReturn =
nullptr;
78 void * pCppReturn =
nullptr;
80 if ( pReturnTypeDescr )
84 pCppReturn = *gpreg++;
88 ? alloca( pReturnTypeDescr->nSize )
92 pUnoReturn = pRegisterReturn;
101 void ** pUnoArgs =
static_cast<void **
>(alloca( 4 *
sizeof(
void *) * nParams ));
102 void ** pCppArgs = pUnoArgs + nParams;
104 sal_Int32 * pTempIndices =
reinterpret_cast<sal_Int32 *
>(pUnoArgs + (2 * nParams));
108 sal_Int32 nTempIndices = 0;
112 const typelib_MethodParameter & rParam = pParams[
nPos];
121 assert( bFitsRegisters && ( ( nUsedSSE == 1 && nUsedGPR == 0 ) || ( nUsedSSE == 0 && nUsedGPR == 1 ) ) ); (void)bFitsRegisters;
127 pCppArgs[
nPos] = pUnoArgs[
nPos] = fpreg++;
131 pCppArgs[
nPos] = pUnoArgs[
nPos] = ovrflw++;
133 else if ( nUsedGPR == 1 )
137 pCppArgs[
nPos] = pUnoArgs[
nPos] = gpreg++;
141 pCppArgs[
nPos] = pUnoArgs[
nPos] = ovrflw++;
147 TYPELIB_DANGER_GET( &pParamTypeDescr, rParam.pTypeRef );
152 pCppArgs[
nPos] = pCppStack = *gpreg++;
156 pCppArgs[
nPos] = pCppStack = *ovrflw++;
161 pUnoArgs[
nPos] = alloca( pParamTypeDescr->nSize );
162 pTempIndices[nTempIndices] =
nPos;
164 ppTempParamTypeDescr[nTempIndices++] = pParamTypeDescr;
168 pUnoArgs[
nPos] = alloca( pParamTypeDescr->nSize );
170 pCppStack, pParamTypeDescr,
172 pTempIndices[nTempIndices] =
nPos;
174 ppTempParamTypeDescr[nTempIndices++] = pParamTypeDescr;
178 pUnoArgs[
nPos] = pCppStack;
180 TYPELIB_DANGER_RELEASE( pParamTypeDescr );
190 (*pThis->
getUnoI()->pDispatcher)( pThis->
getUnoI(), pMemberTypeDescr, pUnoReturn, pUnoArgs, &pUnoExc );
196 for ( ; nTempIndices--; )
198 sal_Int32
nIndex = pTempIndices[nTempIndices];
202 TYPELIB_DANGER_RELEASE( ppTempParamTypeDescr[nTempIndices] );
204 if (pReturnTypeDescr)
205 TYPELIB_DANGER_RELEASE( pReturnTypeDescr );
214 for ( ; nTempIndices--; )
216 sal_Int32
nIndex = pTempIndices[nTempIndices];
219 if ( pParams[
nIndex].bOut )
229 TYPELIB_DANGER_RELEASE( pParamTypeDescr );
234 if ( pUnoReturn != pCppReturn )
242 *
reinterpret_cast<void **
>(pRegisterReturn) = pCppReturn;
244 if ( pReturnTypeDescr )
246 TYPELIB_DANGER_RELEASE( pReturnTypeDescr );
248 switch (returnKind) {
267 sal_Int32 nFunctionIndex, sal_Int32 nVtableOffset,
268 void ** gpreg,
void ** fpreg,
void ** ovrflw,
269 sal_uInt64 * pRegisterReturn )
275 if ( nFunctionIndex & 0x80000000 )
277 nFunctionIndex &= 0x7fffffff;
284 pThis =
static_cast<char *
>( pThis ) - nVtableOffset;
289 typelib_InterfaceTypeDescription * pTypeDescr = pCppI->
getTypeDescr();
291 if ( nFunctionIndex >= pTypeDescr->nMapFunctionIndexToMemberIndex )
295 "illegal " << OUString::unacquired(&pTypeDescr->aBase.pTypeName)
296 <<
" vtable index " << nFunctionIndex <<
"/"
297 << pTypeDescr->nMapFunctionIndexToMemberIndex);
299 (
"illegal " + OUString::unacquired(&pTypeDescr->aBase.pTypeName)
300 +
" vtable index " + OUString::number(nFunctionIndex) +
"/"
301 + OUString::number(pTypeDescr->nMapFunctionIndexToMemberIndex)),
306 sal_Int32 nMemberPos = pTypeDescr->pMapFunctionIndexToMemberIndex[nFunctionIndex];
307 assert(nMemberPos < pTypeDescr->nAllMembers);
309 TypeDescription aMemberDescr( pTypeDescr->ppAllMembers[nMemberPos] );
312 switch ( aMemberDescr.get()->eTypeClass )
314 case typelib_TypeClass_INTERFACE_ATTRIBUTE:
316 typelib_TypeDescriptionReference *pAttrTypeRef =
317 reinterpret_cast<typelib_InterfaceAttributeTypeDescription *
>( aMemberDescr.get() )->pAttributeTypeRef;
319 if ( pTypeDescr->pMapMemberIndexToFunctionIndex[nMemberPos] == nFunctionIndex )
322 eRet =
cpp2uno_call( pCppI, aMemberDescr.get(), pAttrTypeRef,
324 gpreg, fpreg, ovrflw, pRegisterReturn );
329 typelib_MethodParameter aParam;
330 aParam.pTypeRef = pAttrTypeRef;
337 gpreg, fpreg, ovrflw, pRegisterReturn );
341 case typelib_TypeClass_INTERFACE_METHOD:
344 switch ( nFunctionIndex )
357 TYPELIB_DANGER_GET( &pTD,
static_cast<Type *
>( gpreg[2] )->getTypeLibType() );
363 reinterpret_cast<void **
>(&pInterface),
365 reinterpret_cast<typelib_InterfaceTypeDescription *
>( pTD ) );
369 ::uno_any_construct(
static_cast<uno_Any *
>( gpreg[0] ),
370 &pInterface, pTD, cpp_acquire );
372 pInterface->release();
373 TYPELIB_DANGER_RELEASE( pTD );
375 reinterpret_cast<void **
>( pRegisterReturn )[0] = gpreg[0];
379 TYPELIB_DANGER_RELEASE( pTD );
385 typelib_InterfaceMethodTypeDescription *pMethodTD =
386 reinterpret_cast<typelib_InterfaceMethodTypeDescription *
>( aMemberDescr.get() );
389 pMethodTD->pReturnTypeRef,
392 gpreg, fpreg, ovrflw, pRegisterReturn );
420 sal_Int32 nFunctionIndex, sal_Int32 nVtableOffset,
421 bool bHasHiddenParam )
423 sal_uInt64 nOffsetAndIndex = (
static_cast<sal_uInt64
>(nVtableOffset) << 32 ) |
static_cast<sal_uInt64
>(nFunctionIndex);
425 if ( bHasHiddenParam )
426 nOffsetAndIndex |= 0x80000000;
429 *
reinterpret_cast<sal_uInt16 *
>(
code ) = 0xba49;
430 *
reinterpret_cast<sal_uInt16 *
>(
code + 2 ) = nOffsetAndIndex & 0xFFFF;
431 *
reinterpret_cast<sal_uInt32 *
>(
code + 4 ) = nOffsetAndIndex >> 16;
432 *
reinterpret_cast<sal_uInt16 *
>(
code + 8 ) = nOffsetAndIndex >> 48;
435 *
reinterpret_cast<sal_uInt16 *
>(
code + 10 ) = 0xbb49;
436 *
reinterpret_cast<sal_uInt32 *
>(
code + 12 )
438 *
reinterpret_cast<sal_uInt32 *
>(
code + 16 )
442 *
reinterpret_cast<sal_uInt32 *
>(
code + 20 ) = 0x00e3ff49;
452 return static_cast< Slot *
>(block) + 2;
461#if ENABLE_RUNTIME_OPTIMIZATIONS
471 void * block, sal_Int32 slotCount, sal_Int32 vtableNumber,
472 typelib_InterfaceTypeDescription * type)
474 Slot * slots = mapBlockToVtable(block);
475#if ENABLE_RUNTIME_OPTIMIZATIONS
476 slots[-2].fn =
nullptr;
477 slots[-1].fn = &
typeid(ProxyRtti);
481 slots[-2].fn =
reinterpret_cast<void *
>(-(vtableNumber *
sizeof (
void *)));
484 return slots + slotCount;
489 Slot ** slots,
unsigned char * code, sal_PtrDiff writetoexecdiff,
490 typelib_InterfaceTypeDescription
const * type, sal_Int32 nFunctionOffset,
491 sal_Int32 functionCount, sal_Int32 nVtableOffset )
493 (*slots) -= functionCount;
495 for ( sal_Int32 nPos = 0;
nPos <
type->nMembers; ++
nPos )
499 TYPELIB_DANGER_GET( &pTD,
type->ppMembers[ nPos ] );
502 if ( pTD->eTypeClass == typelib_TypeClass_INTERFACE_ATTRIBUTE )
504 typelib_InterfaceAttributeTypeDescription *pAttrTD =
505 reinterpret_cast<typelib_InterfaceAttributeTypeDescription *
>( pTD );
508 (s++)->fn = code + writetoexecdiff;
512 if ( ! pAttrTD->bReadOnly )
515 (s++)->fn = code + writetoexecdiff;
519 else if ( pTD->eTypeClass == typelib_TypeClass_INTERFACE_METHOD )
521 typelib_InterfaceMethodTypeDescription *pMethodTD =
522 reinterpret_cast<typelib_InterfaceMethodTypeDescription *
>( pTD );
524 (s++)->fn = code + writetoexecdiff;
531 TYPELIB_DANGER_RELEASE( pTD );
537 SAL_UNUSED_PARAMETER
unsigned char const *,
538 SAL_UNUSED_PARAMETER
unsigned char const * )
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(* privateSnippetExecutor)()
const int codeSnippetSize
int cpp_vtable_call(sal_Int32 nFunctionIndex, sal_Int32 nVtableOffset, void **gpreg, void **fpreg, void **ovrflw, sal_uInt64 *pRegisterReturn)
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
void raiseException(uno_Any *pUnoExc, uno_Mapping *pUno2Cpp)
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,...
std::type_info * getRtti(typelib_TypeDescription const &type)
bool examine_argument(typelib_TypeDescriptionReference *pTypeRef, int &nUsedGPR, int &nUsedSSE) noexcept
bool return_in_hidden_param(typelib_TypeDescriptionReference *pTypeRef) noexcept
Does function that returns this type use a hidden parameter, or registers?
const sal_uInt32 MAX_SSE_REGS
ReturnKind getReturnKind(typelib_TypeDescriptionReference *type) noexcept
const sal_uInt32 MAX_GPR_REGS