26#include <com/sun/star/uno/genfunc.hxx>
27#include "com/sun/star/uno/RuntimeException.hpp"
29#include <typelib/typedescription.hxx>
50 typelib_TypeDescriptionReference * pReturnTypeRef,
51 sal_Int32 nParams, typelib_MethodParameter * pParams,
52 long r8,
void ** pCallStack,
53 sal_Int64 * pRegisterReturn )
56 char * pTopStack = (
char *)(pCallStack + 0);
57 char * pCppStack = pTopStack;
58#if OSL_DEBUG_LEVEL > 2
59 fprintf(stderr,
"cpp2uno_call\n");
64 TYPELIB_DANGER_GET( &pReturnTypeDescr, pReturnTypeRef );
66 void * pUnoReturn = 0;
68 void * pCppReturn = 0;
74#if OSL_DEBUG_LEVEL > 2
75 fprintf(stderr,
"simple return\n");
77 pUnoReturn = pRegisterReturn;
81#if OSL_DEBUG_LEVEL > 2
82 fprintf(stderr,
"complex return\n");
84 pCppReturn = (
void *)r8;
87 ? alloca( pReturnTypeDescr->nSize )
92 pCppStack +=
sizeof(
void* );
95 static_assert(
sizeof(
void *) ==
sizeof(sal_Int32),
96 "### unexpected size!" );
98 void ** pUnoArgs = (
void **)alloca( 4 *
sizeof(
void *) * nParams );
99 void ** pCppArgs = pUnoArgs + nParams;
102 sal_Int32 * pTempIndices = (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 );
118 switch (pParamTypeDescr->eTypeClass)
120 case typelib_TypeClass_BYTE:
121 case typelib_TypeClass_BOOLEAN:
122 pCppArgs[
nPos] = pCppStack + 3;
123 pUnoArgs[
nPos] = pCppStack + 3;
125 case typelib_TypeClass_CHAR:
126 case typelib_TypeClass_SHORT:
127 case typelib_TypeClass_UNSIGNED_SHORT:
128 pCppArgs[
nPos] = pCppStack + 2;
129 pUnoArgs[
nPos] = pCppStack + 2;
131 case typelib_TypeClass_HYPER:
132 case typelib_TypeClass_UNSIGNED_HYPER:
133 case typelib_TypeClass_DOUBLE:
134 pCppArgs[
nPos] = pCppStack;
135 pUnoArgs[
nPos] = pCppStack;
136 pCppStack +=
sizeof(sal_Int32);
139 pCppArgs[
nPos] = pCppStack;
140 pUnoArgs[
nPos] = pCppStack;
144 TYPELIB_DANGER_RELEASE( pParamTypeDescr );
148 pCppArgs[
nPos] = *(
void **)pCppStack;
153 pUnoArgs[
nPos] = alloca( pParamTypeDescr->nSize );
154 pTempIndices[nTempIndices] =
nPos;
156 ppTempParamTypeDescr[nTempIndices++] = pParamTypeDescr;
163 *(
void **)pCppStack, pParamTypeDescr,
165 pTempIndices[nTempIndices] =
nPos;
167 ppTempParamTypeDescr[nTempIndices++] = pParamTypeDescr;
171 pUnoArgs[
nPos] = *(
void **)pCppStack;
173 TYPELIB_DANGER_RELEASE( pParamTypeDescr );
176 pCppStack +=
sizeof(sal_Int32);
183#if OSL_DEBUG_LEVEL > 2
184 fprintf(stderr,
"before dispatch\n");
187 (*pThis->
getUnoI()->pDispatcher)(
188 pThis->
getUnoI(), pMemberTypeDescr, pUnoReturn, pUnoArgs, &pUnoExc );
190#if OSL_DEBUG_LEVEL > 2
191 fprintf(stderr,
"after dispatch\n");
198 for ( ; nTempIndices--; )
200 sal_Int32
nIndex = pTempIndices[nTempIndices];
202 if (pParams[nIndex].bIn)
204 ppTempParamTypeDescr[nTempIndices], 0 );
205 TYPELIB_DANGER_RELEASE( ppTempParamTypeDescr[nTempIndices] );
207 if (pReturnTypeDescr)
208 TYPELIB_DANGER_RELEASE( pReturnTypeDescr );
213 return typelib_TypeClass_VOID;
218 for ( ; nTempIndices--; )
220 sal_Int32
nIndex = pTempIndices[nTempIndices];
222 ppTempParamTypeDescr[nTempIndices];
224 if (pParams[nIndex].bOut)
235 TYPELIB_DANGER_RELEASE( pParamTypeDescr );
240 if (pUnoReturn != pCppReturn)
248 *(
void **)pRegisterReturn = pCppReturn;
250 if (pReturnTypeDescr)
252 typelib_TypeClass eRet =
253 (typelib_TypeClass)pReturnTypeDescr->eTypeClass;
254 TYPELIB_DANGER_RELEASE( pReturnTypeDescr );
258 return typelib_TypeClass_VOID;
264 sal_Int32 nFunctionIndex, sal_Int32 nVtableOffset,
266 sal_Int64 * pRegisterReturn )
268 void ** pCallStack = (
void**)(sp);
269#if OSL_DEBUG_LEVEL > 2
270 fprintf(stderr,
"cpp_mediate with\n");
271 fprintf(stderr,
"%x %x\n", nFunctionIndex, nVtableOffset);
272 fprintf(stderr,
"and %x %x\n", pCallStack, pRegisterReturn);
273 fprintf(stderr,
"and %x %x\n", pCallStack[0], pCallStack[1]);
275 static_assert(
sizeof(sal_Int32)==
sizeof(
void *),
"### unexpected!" );
277 void *pThis = pCallStack[0];
279 pThis =
static_cast< char *
>(pThis) - nVtableOffset;
285 typelib_InterfaceTypeDescription * pTypeDescr = pCppI->
getTypeDescr();
287 if (nFunctionIndex >= pTypeDescr->nMapFunctionIndexToMemberIndex)
291 "illegal " << OUString::unacquired(&pTypeDescr->aBase.pTypeName)
292 <<
" vtable index " << nFunctionIndex <<
"/"
293 << pTypeDescr->nMapFunctionIndexToMemberIndex);
295 (
"illegal " + OUString::unacquired(&pTypeDescr->aBase.pTypeName)
296 +
" vtable index " + OUString::number(nFunctionIndex) +
"/"
297 + OUString::number(pTypeDescr->nMapFunctionIndexToMemberIndex)),
302 assert(nFunctionIndex < pTypeDescr->nMapFunctionIndexToMemberIndex);
303 sal_Int32 nMemberPos =
304 pTypeDescr->pMapFunctionIndexToMemberIndex[nFunctionIndex];
305 assert(nMemberPos < pTypeDescr->nAllMembers);
307 TypeDescription aMemberDescr( pTypeDescr->ppAllMembers[nMemberPos] );
309 typelib_TypeClass eRet;
310 switch (aMemberDescr.get()->eTypeClass)
312 case typelib_TypeClass_INTERFACE_ATTRIBUTE:
314 if (pTypeDescr->pMapMemberIndexToFunctionIndex[nMemberPos] ==
319 pCppI, aMemberDescr.get(),
320 ((typelib_InterfaceAttributeTypeDescription *)aMemberDescr.get())->pAttributeTypeRef,
322 r8, pCallStack, pRegisterReturn );
327 typelib_MethodParameter aParam;
329 ((typelib_InterfaceAttributeTypeDescription *)aMemberDescr.get())->pAttributeTypeRef;
334 pCppI, aMemberDescr.get(),
337 r8, pCallStack, pRegisterReturn );
341 case typelib_TypeClass_INTERFACE_METHOD:
344 switch (nFunctionIndex)
348 eRet = typelib_TypeClass_VOID;
352 eRet = typelib_TypeClass_VOID;
357 TYPELIB_DANGER_GET(&pTD,
358 reinterpret_cast<Type *
>(pCallStack[1])->getTypeLibType());
364 (
void **)&pInterface, pCppI->
getOid().pData,
365 (typelib_InterfaceTypeDescription *)pTD );
370 reinterpret_cast< uno_Any *
>( r8 ),
371 &pInterface, pTD, cpp_acquire );
372 pInterface->release();
373 TYPELIB_DANGER_RELEASE( pTD );
374 *(
void **)pRegisterReturn = (
void*)r8;
375 eRet = typelib_TypeClass_ANY;
378 TYPELIB_DANGER_RELEASE( pTD );
383 pCppI, aMemberDescr.get(),
384 ((typelib_InterfaceMethodTypeDescription *)aMemberDescr.get())->pReturnTypeRef,
385 ((typelib_InterfaceMethodTypeDescription *)aMemberDescr.get())->nParams,
386 ((typelib_InterfaceMethodTypeDescription *)aMemberDescr.get())->pParams,
387 r8, pCallStack, pRegisterReturn );
408 register long d0
asm(
"d0");
409 long functionIndex = d0;
411 register long a1
asm(
"a1");
414 register long d1
asm(
"d1");
415 long vtableOffset = d1;
417 long sp = (long)&firstonstack;
419 sal_Int64 nRegReturn;
420 cpp_mediate( functionIndex, vtableOffset, sp, r8, &nRegReturn );
430 unsigned char *
codeSnippet(
unsigned char* code, sal_Int32 functionIndex,
431 sal_Int32 vtableOffset)
433 unsigned char *
p =
code;
434 *(
short *)&
p[0] = 0x203C;
435 *(
long *)&
p[2] = functionIndex;
436 *(
short *)&
p[6] = 0x223C;
437 *(
long *)&
p[8] = vtableOffset;
438 *(
short *)&
p[12] = 0x4EF9;
440 *(
short *)&
p[18] = 0x4E71;
450 return static_cast< Slot *
>(block) + 2;
467 void * block, sal_Int32 slotCount, sal_Int32,
468 typelib_InterfaceTypeDescription *)
470 Slot * slots = mapBlockToVtable(block);
472 slots[-1].fn = &
typeid(ProxyRtti);
473 return slots + slotCount;
477 Slot ** slots,
unsigned char * code, sal_PtrDiff writetoexecdiff,
478 typelib_InterfaceTypeDescription
const * type, sal_Int32 functionOffset,
479 sal_Int32 functionCount, sal_Int32 vtableOffset)
481 (*slots) -= functionCount;
483 for (sal_Int32 i = 0;
i <
type->nMembers; ++
i)
486 TYPELIB_DANGER_GET(&member,
type->ppMembers[i]);
488 switch (member->eTypeClass)
490 case typelib_TypeClass_INTERFACE_ATTRIBUTE:
492 (s++)->fn = code + writetoexecdiff;
495 if (!
reinterpret_cast<
496 typelib_InterfaceAttributeTypeDescription *
>(
499 (s++)->fn = code + writetoexecdiff;
503 case typelib_TypeClass_INTERFACE_METHOD:
505 (s++)->fn = code + writetoexecdiff;
507 typelib_InterfaceMethodTypeDescription *pMethodTD =
509 typelib_InterfaceMethodTypeDescription *
>(member);
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()
sal_Int64 cpp_vtable_call(long firstonstack)
is called on incoming vtable calls (called by asm snippets)
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 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,...