25#include <com/sun/star/uno/genfunc.hxx>
26#include <com/sun/star/uno/RuntimeException.hpp>
29#include <typelib/typedescription.hxx>
47 typelib_TypeDescriptionReference * pReturnTypeRef,
48 sal_Int32 nParams, typelib_MethodParameter * pParams,
53 char * pCppStack =
reinterpret_cast<char *
>(pCallStack +1);
58 TYPELIB_DANGER_GET( &pReturnTypeDescr, pReturnTypeRef );
60 void * pUnoReturn =
nullptr;
61 void * pCppReturn =
nullptr;
67 pUnoReturn = pReturnValue;
71 pCppReturn = *
reinterpret_cast<void **
>(pCppStack);
72 pCppStack +=
sizeof(
void *);
76 ? alloca( pReturnTypeDescr->nSize )
81 pCppStack +=
sizeof(
void* );
84 static_assert(
sizeof(
void *) ==
sizeof(sal_Int32),
"### unexpected size!");
86 void ** pUnoArgs =
static_cast<void **
>(alloca( 4 *
sizeof(
void *) * nParams ));
87 void ** pCppArgs = pUnoArgs + nParams;
89 sal_Int32 * pTempIndices =
reinterpret_cast<sal_Int32 *
>(pUnoArgs + (2 * nParams));
93 sal_Int32 nTempIndices = 0;
95 for ( sal_Int32 nPos = 0;
nPos < nParams; ++
nPos )
97 const typelib_MethodParameter & rParam = pParams[
nPos];
99 TYPELIB_DANGER_GET( &pParamTypeDescr, rParam.pTypeRef );
105 pCppArgs[
nPos] = pCppStack;
106 pUnoArgs[
nPos] = pCppStack;
107 switch (pParamTypeDescr->eTypeClass)
109 case typelib_TypeClass_HYPER:
110 case typelib_TypeClass_UNSIGNED_HYPER:
111 case typelib_TypeClass_DOUBLE:
112 pCppStack +=
sizeof(sal_Int32);
118 TYPELIB_DANGER_RELEASE( pParamTypeDescr );
122 pCppArgs[
nPos] = *
reinterpret_cast<void **
>(pCppStack);
127 pUnoArgs[
nPos] = alloca( pParamTypeDescr->nSize );
128 pTempIndices[nTempIndices] =
nPos;
130 ppTempParamTypeDescr[nTempIndices++] = pParamTypeDescr;
137 *
reinterpret_cast<void **
>(pCppStack), pParamTypeDescr,
139 pTempIndices[nTempIndices] =
nPos;
141 ppTempParamTypeDescr[nTempIndices++] = pParamTypeDescr;
145 pUnoArgs[
nPos] = *
reinterpret_cast<void **
>(pCppStack);
147 TYPELIB_DANGER_RELEASE( pParamTypeDescr );
150 pCppStack +=
sizeof(sal_Int32);
158 (*pThis->
getUnoI()->pDispatcher)(
159 pThis->
getUnoI(), pMemberTypeDescr, pUnoReturn, pUnoArgs, &pUnoExc );
165 for ( ; nTempIndices--; )
167 sal_Int32
nIndex = pTempIndices[nTempIndices];
169 if (pParams[nIndex].bIn)
170 uno_destructData( pUnoArgs[nIndex], ppTempParamTypeDescr[nTempIndices],
nullptr );
171 TYPELIB_DANGER_RELEASE( ppTempParamTypeDescr[nTempIndices] );
173 if (pReturnTypeDescr)
174 TYPELIB_DANGER_RELEASE( pReturnTypeDescr );
183 for ( ; nTempIndices--; )
185 sal_Int32
nIndex = pTempIndices[nTempIndices];
188 if (pParams[nIndex].bOut)
198 TYPELIB_DANGER_RELEASE( pParamTypeDescr );
203 if (pUnoReturn != pCppReturn)
211 *
static_cast< void **
>(pReturnValue) = pCppReturn;
213 if (pReturnTypeDescr)
215 TYPELIB_DANGER_RELEASE( pReturnTypeDescr );
222 int nFunctionIndex,
int nVtableOffset,
void** pCallStack,
223 void * pReturnValue )
225 static_assert(
sizeof(sal_Int32)==
sizeof(
void *),
"### unexpected!");
229 if( nFunctionIndex & 0x80000000 )
231 nFunctionIndex &= 0x7fffffff;
232 pThis = pCallStack[2];
236 pThis = pCallStack[1];
238 pThis =
static_cast< char *
>(pThis) - nVtableOffset;
243 typelib_InterfaceTypeDescription * pTypeDescr = pCppI->
getTypeDescr();
245 if (nFunctionIndex >= pTypeDescr->nMapFunctionIndexToMemberIndex)
249 "illegal " << OUString::unacquired(&pTypeDescr->aBase.pTypeName)
250 <<
" vtable index " << nFunctionIndex <<
"/"
251 << pTypeDescr->nMapFunctionIndexToMemberIndex);
253 (
"illegal " + OUString::unacquired(&pTypeDescr->aBase.pTypeName)
254 +
" vtable index " + OUString::number(nFunctionIndex) +
"/"
255 + OUString::number(pTypeDescr->nMapFunctionIndexToMemberIndex)),
260 sal_Int32 nMemberPos = pTypeDescr->pMapFunctionIndexToMemberIndex[nFunctionIndex];
261 assert(nMemberPos < pTypeDescr->nAllMembers);
263 TypeDescription aMemberDescr( pTypeDescr->ppAllMembers[nMemberPos] );
265 switch (aMemberDescr.get()->eTypeClass)
267 case typelib_TypeClass_INTERFACE_ATTRIBUTE:
269 if (pTypeDescr->pMapMemberIndexToFunctionIndex[nMemberPos] == nFunctionIndex)
273 pCppI, aMemberDescr.get(),
274 reinterpret_cast<typelib_InterfaceAttributeTypeDescription *
>(aMemberDescr.get())->pAttributeTypeRef,
276 pCallStack, pReturnValue );
281 typelib_MethodParameter aParam;
283 reinterpret_cast<typelib_InterfaceAttributeTypeDescription *
>(aMemberDescr.get())->pAttributeTypeRef;
288 pCppI, aMemberDescr.get(),
291 pCallStack, pReturnValue );
295 case typelib_TypeClass_INTERFACE_METHOD:
298 switch (nFunctionIndex)
309 TYPELIB_DANGER_GET( &pTD,
static_cast< Type *
>( pCallStack[3] )->getTypeLibType() );
315 reinterpret_cast<void **
>(&pInterface), pCppI->
getOid().pData,
316 reinterpret_cast<typelib_InterfaceTypeDescription *
>(pTD) );
321 static_cast< uno_Any *
>( pCallStack[1] ),
322 &pInterface, pTD, cpp_acquire );
323 pInterface->release();
324 TYPELIB_DANGER_RELEASE( pTD );
325 *
static_cast< void **
>(pReturnValue) = pCallStack[1];
328 TYPELIB_DANGER_RELEASE( pTD );
334 pCppI, aMemberDescr.get(),
335 reinterpret_cast<typelib_InterfaceMethodTypeDescription *
>(aMemberDescr.get())->pReturnTypeRef,
336 reinterpret_cast<typelib_InterfaceMethodTypeDescription *
>(aMemberDescr.get())->nParams,
337 reinterpret_cast<typelib_InterfaceMethodTypeDescription *
>(aMemberDescr.get())->pParams,
338 pCallStack, pReturnValue );
349extern "C" typedef void (*PrivateSnippetExecutor)();
353#if defined (FREEBSD) || defined(NETBSD) || defined(OPENBSD) || defined(MACOSX) || \
357 PrivateSnippetExecutor returnsInRegister(typelib_TypeDescriptionReference * pReturnTypeRef)
361 PrivateSnippetExecutor exec=
NULL;
364 TYPELIB_DANGER_GET( &pReturnTypeDescr, pReturnTypeRef );
366 const sal_Int32 nRetSize = pReturnTypeDescr->nSize;
367 TYPELIB_DANGER_RELEASE( pReturnTypeDescr );
368 if (bSimpleReturnStruct)
380 unsigned char * code, sal_PtrDiff writetoexecdiff, sal_Int32 functionIndex, sal_Int32 vtableOffset,
381 typelib_TypeDescriptionReference * pReturnTypeRef)
383 PrivateSnippetExecutor exec;
384 typelib_TypeClass eReturnClass = pReturnTypeRef ? pReturnTypeRef->eTypeClass : typelib_TypeClass_VOID;
385 switch (eReturnClass)
387 case typelib_TypeClass_VOID:
390 case typelib_TypeClass_HYPER:
391 case typelib_TypeClass_UNSIGNED_HYPER:
394 case typelib_TypeClass_FLOAT:
397 case typelib_TypeClass_DOUBLE:
400 case typelib_TypeClass_STRUCT:
401 case typelib_TypeClass_EXCEPTION:
402#if defined(FREEBSD) || defined(NETBSD) || defined(OPENBSD) || defined(MACOSX) || \
404 exec = returnsInRegister(pReturnTypeRef);
408 functionIndex |= 0x80000000;
412 case typelib_TypeClass_STRING:
413 case typelib_TypeClass_TYPE:
414 case typelib_TypeClass_ANY:
415 case typelib_TypeClass_SEQUENCE:
416 case typelib_TypeClass_INTERFACE:
418 functionIndex |= 0x80000000;
424 unsigned char *
p =
code;
425 assert(
sizeof (sal_Int32) == 4);
428 *
reinterpret_cast< sal_Int32 *
>(
p) = functionIndex;
429 p +=
sizeof (sal_Int32);
432 *
reinterpret_cast< sal_Int32 *
>(
p) = vtableOffset;
433 p +=
sizeof (sal_Int32);
436 *
reinterpret_cast< sal_Int32 *
>(
p)
437 =
reinterpret_cast<unsigned char *
>(exec) -
p -
sizeof (sal_Int32) - writetoexecdiff;
438 p +=
sizeof (sal_Int32);
449 return static_cast< Slot *
>(block) + 2;
466 void * block, sal_Int32 slotCount, sal_Int32,
467 typelib_InterfaceTypeDescription *)
469 Slot * slots = mapBlockToVtable(block);
470 slots[-2].fn =
nullptr;
471 slots[-1].fn = &
typeid(ProxyRtti);
472 return slots + slotCount;
476 Slot ** slots,
unsigned char * code, sal_PtrDiff writetoexecdiff,
477 typelib_InterfaceTypeDescription
const * type, sal_Int32 functionOffset,
478 sal_Int32 functionCount, sal_Int32 vtableOffset)
480 (*slots) -= functionCount;
482 for (sal_Int32 i = 0;
i <
type->nMembers; ++
i) {
484 TYPELIB_DANGER_GET(&member,
type->ppMembers[i]);
485 assert(member !=
nullptr);
486 switch (member->eTypeClass) {
487 case typelib_TypeClass_INTERFACE_ATTRIBUTE:
489 (s++)->fn = code + writetoexecdiff;
491 code, writetoexecdiff, functionOffset++, vtableOffset,
492 reinterpret_cast< typelib_InterfaceAttributeTypeDescription *
>(
493 member)->pAttributeTypeRef);
495 if (!
reinterpret_cast<
496 typelib_InterfaceAttributeTypeDescription *
>(
499 (s++)->fn = code + writetoexecdiff;
501 code, writetoexecdiff, functionOffset++, vtableOffset,
506 case typelib_TypeClass_INTERFACE_METHOD:
507 (s++)->fn = code + writetoexecdiff;
509 code, writetoexecdiff, functionOffset++, vtableOffset,
510 reinterpret_cast< typelib_InterfaceMethodTypeDescription *
>(
511 member)->pReturnTypeRef);
518 TYPELIB_DANGER_RELEASE(member);
524 unsigned char const *,
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 cpp_vtable_call(sal_Int32 func, sal_Int32 offset, void **pStack)
is called on incoming vtable calls (called by asm snippets)
void privateSnippetExecutorDouble()
void privateSnippetExecutorClass()
void privateSnippetExecutorFloat()
void privateSnippetExecutorVoid()
void privateSnippetExecutorHyper()
void privateSnippetExecutorGeneral()
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
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,...
bool isSimpleReturnType(typelib_TypeDescription *pTD, bool recursive=false)