24#include <com/sun/star/uno/genfunc.hxx>
26#include <typelib/typedescription.hxx>
42 typelib_TypeDescriptionReference * pReturnTypeRef,
43 sal_Int32 nParams, typelib_MethodParameter * pParams,
45 sal_Int64 * pRegisterReturn )
48 char * pCppStack = (
char *)pCallStack;
53 TYPELIB_DANGER_GET( &pReturnTypeDescr, pReturnTypeRef );
55 void * pUnoReturn = 0;
56 void * pCppReturn = 0;
61 pUnoReturn = pRegisterReturn;
64 pCppReturn = *(
void**)pCppStack;
67 ? alloca( pReturnTypeDescr->nSize )
69 pCppStack +=
sizeof(
void* );
73 pCppStack +=
sizeof(
void* );
76 static_assert(
sizeof(
void *) ==
sizeof(sal_Int32),
"### unexpected size!");
78 void ** pUnoArgs = (
void **)alloca( 4 *
sizeof(
void *) * nParams );
79 void ** pCppArgs = pUnoArgs + nParams;
81 sal_Int32 * pTempIndices = (sal_Int32 *)(pUnoArgs + (2 * nParams));
85 sal_Int32 nTempIndices = 0;
87 for ( sal_Int32 nPos = 0;
nPos < nParams; ++
nPos )
89 const typelib_MethodParameter & rParam = pParams[
nPos];
91 TYPELIB_DANGER_GET( &pParamTypeDescr, rParam.pTypeRef );
96 switch (pParamTypeDescr->eTypeClass)
98 case typelib_TypeClass_HYPER:
99 case typelib_TypeClass_UNSIGNED_HYPER:
100 case typelib_TypeClass_DOUBLE:
102 if ((
reinterpret_cast< long >(pCppStack) & 7) != 0)
104 static_assert(
sizeof (double) ==
sizeof (sal_Int64),
"boo");
105 void * pDest = alloca(
sizeof (sal_Int64) );
106 *
reinterpret_cast< sal_Int32 *
>(pDest) =
107 *
reinterpret_cast< sal_Int32
const *
>(pCppStack);
108 *(
reinterpret_cast< sal_Int32 *
>(pDest) + 1) =
109 *(
reinterpret_cast< sal_Int32
const *
>(pCppStack) + 1);
110 pCppArgs[
nPos] = pUnoArgs[
nPos] = pDest;
112 pCppStack +=
sizeof (sal_Int32);
119 TYPELIB_DANGER_RELEASE( pParamTypeDescr );
123 pCppArgs[
nPos] = *(
void **)pCppStack;
128 pUnoArgs[
nPos] = alloca( pParamTypeDescr->nSize );
129 pTempIndices[nTempIndices] =
nPos;
131 ppTempParamTypeDescr[nTempIndices++] = pParamTypeDescr;
138 *(
void **)pCppStack, pParamTypeDescr,
140 pTempIndices[nTempIndices] =
nPos;
142 ppTempParamTypeDescr[nTempIndices++] = pParamTypeDescr;
146 pUnoArgs[
nPos] = *(
void **)pCppStack;
148 TYPELIB_DANGER_RELEASE( pParamTypeDescr );
151 pCppStack +=
sizeof(sal_Int32);
159 (*pThis->
getUnoI()->pDispatcher)(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], 0 );
171 TYPELIB_DANGER_RELEASE( ppTempParamTypeDescr[nTempIndices] );
173 if (pReturnTypeDescr)
174 TYPELIB_DANGER_RELEASE( pReturnTypeDescr );
178 return typelib_TypeClass_VOID;
183 for ( ; nTempIndices--; )
185 sal_Int32
nIndex = pTempIndices[nTempIndices];
188 if (pParams[nIndex].bOut)
198 TYPELIB_DANGER_RELEASE( pParamTypeDescr );
203 if (pUnoReturn != pCppReturn)
211 *(
void **)pRegisterReturn = pCppReturn;
213 if (pReturnTypeDescr)
215 typelib_TypeClass eRet = (typelib_TypeClass)pReturnTypeDescr->eTypeClass;
216 TYPELIB_DANGER_RELEASE( pReturnTypeDescr );
220 return typelib_TypeClass_VOID;
226 sal_Int32 nFunctionIndex,
227 sal_Int32 nVtableOffset,
229 sal_Int64 * pRegisterReturn )
231 static_assert(
sizeof(sal_Int32)==
sizeof(
void *),
"### unexpected!");
241 static_cast< char *
>(*pCallStack) - nVtableOffset);
242 if ((nFunctionIndex & 0x80000000) != 0) {
243 nFunctionIndex &= 0x7FFFFFFF;
247 typelib_InterfaceTypeDescription * pTypeDescr = pCppI->
getTypeDescr();
249 if (nFunctionIndex >= pTypeDescr->nMapFunctionIndexToMemberIndex)
253 "illegal " << OUString::unacquired(&pTypeDescr->aBase.pTypeName)
254 <<
" vtable index " << nFunctionIndex <<
"/"
255 << pTypeDescr->nMapFunctionIndexToMemberIndex);
257 (
"illegal " + OUString::unacquired(&pTypeDescr->aBase.pTypeName)
258 +
" vtable index " + OUString::number(nFunctionIndex) +
"/"
259 + OUString::number(pTypeDescr->nMapFunctionIndexToMemberIndex)),
264 sal_Int32 nMemberPos = pTypeDescr->pMapFunctionIndexToMemberIndex[nFunctionIndex];
265 assert(nMemberPos < pTypeDescr->nAllMembers);
267 TypeDescription aMemberDescr( pTypeDescr->ppAllMembers[nMemberPos] );
269#if defined BRIDGES_DEBUG
270 OString cstr(
OUStringToOString( aMemberDescr.get()->pTypeName, RTL_TEXTENCODING_ASCII_US ) );
271 fprintf( stderr,
"calling %s, nFunctionIndex=%d\n", cstr.getStr(), nFunctionIndex );
274 typelib_TypeClass eRet;
275 switch (aMemberDescr.get()->eTypeClass)
277 case typelib_TypeClass_INTERFACE_ATTRIBUTE:
279 if (pTypeDescr->pMapMemberIndexToFunctionIndex[nMemberPos] == nFunctionIndex)
283 pCppI, aMemberDescr.get(),
284 ((typelib_InterfaceAttributeTypeDescription *)aMemberDescr.get())->pAttributeTypeRef,
286 pCallStack, pRegisterReturn );
291 typelib_MethodParameter aParam;
293 ((typelib_InterfaceAttributeTypeDescription *)aMemberDescr.get())->pAttributeTypeRef;
298 pCppI, aMemberDescr.get(),
301 pCallStack, pRegisterReturn );
305 case typelib_TypeClass_INTERFACE_METHOD:
308 switch (nFunctionIndex)
312 eRet = typelib_TypeClass_VOID;
316 eRet = typelib_TypeClass_VOID;
321 TYPELIB_DANGER_GET( &pTD,
reinterpret_cast< Type *
>( pCallStack[2] )->getTypeLibType() );
327 (
void **)&pInterface, pCppI->
getOid().pData, (typelib_InterfaceTypeDescription *)pTD );
332 reinterpret_cast< uno_Any *
>( pCallStack[0] ),
333 &pInterface, pTD, cpp_acquire );
334 pInterface->release();
335 TYPELIB_DANGER_RELEASE( pTD );
336 *(
void **)pRegisterReturn = pCallStack[0];
337 eRet = typelib_TypeClass_ANY;
340 TYPELIB_DANGER_RELEASE( pTD );
345 pCppI, aMemberDescr.get(),
346 ((typelib_InterfaceMethodTypeDescription *)aMemberDescr.get())->pReturnTypeRef,
347 ((typelib_InterfaceMethodTypeDescription *)aMemberDescr.get())->nParams,
348 ((typelib_InterfaceMethodTypeDescription *)aMemberDescr.get())->pParams,
349 pCallStack, pRegisterReturn );
368 sal_Int64 nRegReturn;
373void * pRegReturn = &nRegReturn;
378 : :
"m"(nFunctionIndex),
"m"(pCallStack),
"m"(vTableOffset) );
383 const sal_Bool bComplex = (nFunctionIndex & 0x80000000) ? sal_True : sal_False;
384 typelib_TypeClass aType =
385 cpp_mediate( nFunctionIndex, vTableOffset, pCallStack+17, (sal_Int64*)&nRegReturn );
389 case typelib_TypeClass_BOOLEAN:
390 case typelib_TypeClass_BYTE:
392 "ldsb [%%l0], %%i0\n"
393 : :
"m"(pRegReturn) );
395 case typelib_TypeClass_CHAR:
396 case typelib_TypeClass_SHORT:
397 case typelib_TypeClass_UNSIGNED_SHORT:
399 "ldsh [%%l0], %%i0\n"
400 : :
"m"(pRegReturn) );
402 case typelib_TypeClass_HYPER:
403 case typelib_TypeClass_UNSIGNED_HYPER:
405 "ld [%%l0], %%i0\n\t"
406 "add %%l0, 4, %%l0\n\t"
407 "ld [%%l0], %%i1\n\t"
408 : :
"m"(pRegReturn) );
411 case typelib_TypeClass_FLOAT:
414 : :
"m"(pRegReturn) );
416 case typelib_TypeClass_DOUBLE:
419 : :
"m"(pRegReturn) );
421 case typelib_TypeClass_VOID:
426 : :
"m"(pRegReturn) );
432 __asm__(
"add %i7, 4, %i7\n\t" );
441 unsigned char * code, sal_Int32 functionIndex, sal_Int32 vtableOffset,
444 sal_uInt32
index = functionIndex;
445 if (!simpleRetType) {
448 unsigned int *
p =
reinterpret_cast< unsigned int *
>(
code);
449 static_assert(
sizeof (
unsigned int) == 4,
"boo");
463 *
p++ = 0x11000000 | (
index >> 10);
465 *
p++ = 0x90122000 | (
index & 0x3FF);
467 *
p++ = 0x15000000 | (vtableOffset >> 10);
469 *
p++ = 0x9412A000 | (vtableOffset & 0x3FF);
471 *
p++ = 0x17000000 | (
reinterpret_cast< unsigned int >(
cpp_vtable_call) >> 10);
473 *
p++ = 0x9612E000 | (
reinterpret_cast< unsigned int >(
cpp_vtable_call) & 0x3FF);
489 return static_cast< Slot *
>(block) + 2;
506 void * block, sal_Int32 slotCount, sal_Int32,
507 typelib_InterfaceTypeDescription *)
509 Slot * slots = mapBlockToVtable(block);
511 slots[-1].fn = &
typeid(ProxyRtti);
512 return slots + slotCount;
516 Slot ** slots,
unsigned char * code, sal_PtrDiff writetoexecdiff,
517 typelib_InterfaceTypeDescription
const * type, sal_Int32 functionOffset,
518 sal_Int32 functionCount, sal_Int32 vTableOffset)
520 (*slots) -= functionCount;
522 for (sal_Int32 i = 0;
i <
type->nMembers; ++
i) {
524 TYPELIB_DANGER_GET(&member,
type->ppMembers[i]);
526 switch (member->eTypeClass) {
527 case typelib_TypeClass_INTERFACE_ATTRIBUTE:
529 (s++)->fn = code + writetoexecdiff;
531 code, functionOffset++, vTableOffset,
534 typelib_InterfaceAttributeTypeDescription *
>(
535 member)->pAttributeTypeRef));
537 if (!
reinterpret_cast<
538 typelib_InterfaceAttributeTypeDescription *
>(
541 (s++)->fn = code + writetoexecdiff;
546 case typelib_TypeClass_INTERFACE_METHOD:
547 (s++)->fn = code + writetoexecdiff;
549 code, functionOffset++, vTableOffset,
552 typelib_InterfaceMethodTypeDescription *
>(
553 member)->pReturnTypeRef));
560 TYPELIB_DANGER_RELEASE(member);
567extern "C" void doFlushCode(
unsigned long address,
unsigned long count);
570 unsigned char const * begin,
unsigned char const * end)
574 unsigned long adr =
reinterpret_cast< unsigned long >(
begin);
575 unsigned long off = adr & 7;
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)
register sal_uInt32 r28 __asm__("%r28")
void doFlushCode(unsigned long address, unsigned long count)
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)
char * adjustPointer(char *pIn, typelib_TypeDescription *pType)
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,...
enumrange< T >::Iterator begin(enumrange< T >)
OString OUStringToOString(std::u16string_view str, ConnectionSettings const *settings)
const wchar_t *typedef int(__stdcall *DllNativeUnregProc)(int