21 #include <rtl/alloc.h>
23 #include <com/sun/star/uno/genfunc.hxx>
24 #include <com/sun/star/uno/Exception.hpp>
25 #include <com/sun/star/uno/RuntimeException.hpp>
51 #if !defined(__ARM_EABI__) && !defined(__SOFTFP__)
52 #error Not Implemented
58 #include <sys/types.h>
64 #define HWCAP_ARM_VFP 64
68 int fd = open (
"/proc/self/auxv", O_RDONLY);
74 Elf32_auxv_t buf[128];
76 while ((ret == -1) && ((n = read(fd, buf,
sizeof (buf))) > 0))
78 for (
int i = 0;
i < 128; ++
i)
80 if (buf[
i].a_type == AT_HWCAP)
85 else if (buf[
i].a_type == AT_NULL)
105 const typelib_CompoundTypeDescription *
p
106 =
reinterpret_cast< const typelib_CompoundTypeDescription *
>(type);
107 for (sal_Int32
i = 0;
i < p->nMembers; ++
i)
109 if (p->ppTypeRefs[
i]->eTypeClass == typelib_TypeClass_STRUCT ||
110 p->ppTypeRefs[
i]->eTypeClass == typelib_TypeClass_EXCEPTION)
113 TYPELIB_DANGER_GET(&t, p->ppTypeRefs[
i]);
115 TYPELIB_DANGER_RELEASE(t);
123 if (p->pBaseTypeDescription !=
nullptr)
131 const typelib_CompoundTypeDescription *
p
132 =
reinterpret_cast< const typelib_CompoundTypeDescription *
>(type);
133 for (sal_Int32 i = 0;
i < p->nMembers; ++
i)
135 if (p->ppTypeRefs[i]->eTypeClass != typelib_TypeClass_FLOAT &&
136 p->ppTypeRefs[i]->eTypeClass != typelib_TypeClass_DOUBLE)
146 else if (pTypeRef->eTypeClass == typelib_TypeClass_STRUCT || pTypeRef->eTypeClass == typelib_TypeClass_EXCEPTION)
149 TYPELIB_DANGER_GET( &pTypeDescr, pTypeRef );
157 if( pTypeDescr->nSize <= 16 && is_float_only_struct(pTypeDescr))
161 TYPELIB_DANGER_RELEASE( pTypeDescr );
168 static void MapReturn(sal_uInt32 r0, sal_uInt32 r1, typelib_TypeDescriptionReference * pReturnType, sal_uInt32* pRegisterReturn)
170 switch( pReturnType->eTypeClass )
172 case typelib_TypeClass_HYPER:
173 case typelib_TypeClass_UNSIGNED_HYPER:
174 pRegisterReturn[1] = r1;
176 case typelib_TypeClass_LONG:
177 case typelib_TypeClass_UNSIGNED_LONG:
178 case typelib_TypeClass_ENUM:
179 case typelib_TypeClass_CHAR:
180 case typelib_TypeClass_SHORT:
181 case typelib_TypeClass_UNSIGNED_SHORT:
182 case typelib_TypeClass_BOOLEAN:
183 case typelib_TypeClass_BYTE:
184 pRegisterReturn[0] = r0;
186 case typelib_TypeClass_FLOAT:
187 #if !defined(__ARM_PCS_VFP) && (defined(__ARM_EABI__) || defined(__SOFTFP__))
188 pRegisterReturn[0] = r0;
190 #pragma clang diagnostic push
191 #pragma clang diagnostic ignored "-Wuninitialized"
192 register float fret
asm(
"s0");
193 *
reinterpret_cast<float *
>(pRegisterReturn) = fret;
194 #pragma clang diagnostic pop
197 case typelib_TypeClass_DOUBLE:
198 #if !defined(__ARM_PCS_VFP) && (defined(__ARM_EABI__) || defined(__SOFTFP__))
199 pRegisterReturn[1] = r1;
200 pRegisterReturn[0] = r0;
202 #pragma clang diagnostic push
203 #pragma clang diagnostic ignored "-Wuninitialized"
204 register double dret
asm(
"d0");
205 *
reinterpret_cast<double *
>(pRegisterReturn) = dret;
206 #pragma clang diagnostic pop
209 case typelib_TypeClass_STRUCT:
210 case typelib_TypeClass_EXCEPTION:
213 pRegisterReturn[0] = r0;
226 sal_Int32 nVtableIndex,
227 void * pRegisterReturn,
228 typelib_TypeDescriptionReference * pReturnType,
237 sal_Int32 nVtableIndex,
238 void * pRegisterReturn,
239 typelib_TypeDescriptionReference * pReturnType,
253 sal_uInt32 nStackBytes = ( ( nStack + 1 ) >> 1 ) * 8;
254 sal_uInt32 *stack =
static_cast<sal_uInt32 *
>(__builtin_alloca( nStackBytes *
sizeof(sal_uInt32)));
255 memcpy( stack, pStack, nStackBytes );
262 sal_uInt32 pMethod = *
static_cast<sal_uInt32 *
>(pThis);
263 pMethod += 4 * nVtableIndex;
264 pMethod = *
reinterpret_cast<sal_uInt32 *
>(pMethod);
272 "ldr r4, %[pgpr]\n\t"
273 "ldmia r4, {r0-r3}\n\t"
277 "ldr r4, %[pfpr]\n\t"
278 "vldmia r4, {d0-d7}\n\t"
281 "ldr r5, %[pmethod]\n\t"
282 #ifndef __ARM_ARCH_4T__
285 "mov lr, pc ; bx r5\n\t"
291 : [r0]
"=r" (r0), [r1]
"=r" (r1)
292 : [pmethod]
"m" (pMethod), [pgpr]
"m" (pGPR), [pfpr]
"m" (pFPR)
293 :
"r0",
"r1",
"r2",
"r3",
"r4",
"r5");
295 MapReturn(r0, r1, pReturnType, static_cast<sal_uInt32*>(pRegisterReturn));
299 #define INSERT_INT32( pSV, nr, pGPR, pDS ) \
300 if ( nr < arm::MAX_GPR_REGS ) \
301 pGPR[nr++] = reinterpret_cast<sal_uInt32>( pSV ); \
303 *pDS++ = reinterpret_cast<sal_uInt32>( pSV );
306 #define INSERT_INT64( pSV, nr, pGPR, pDS, pStart ) \
307 if ( (nr < arm::MAX_GPR_REGS) && (nr % 2) ) \
311 if ( nr < arm::MAX_GPR_REGS ) \
313 *reinterpret_cast<sal_uInt32 *>(pGPR[nr++]) = *static_cast<sal_uInt32 *>( pSV ); \
314 *reinterpret_cast<sal_uInt32 *>(pGPR[nr++]) = *(static_cast<sal_uInt32 *>( pSV ) + 1); \
318 if ( (pDS - pStart) % 2) \
322 *reinterpret_cast<sal_uInt32 *>(*pDS++) = static_cast<sal_uInt32 *>( pSV )[0]; \
323 *reinterpret_cast<sal_uInt32 *>(*pDS++) = static_cast<sal_uInt32 *>( pSV )[1]; \
326 #define INSERT_INT64( pSV, nr, pGPR, pDS, pStart ) \
327 INSERT_INT32( pSV, nr, pGPR, pDS ) \
328 INSERT_INT32( ((sal_uInt32*)pSV)+1, nr, pGPR, pDS )
341 #define INSERT_FLOAT( pSV, nr, pGPR, pDS ) \
345 if ( nSR < arm::MAX_FPR_REGS*2 ) {\
346 pSPR[nSR++] = *static_cast<float const *>( pSV ); \
347 if ((nSR % 2 == 1) && (nSR > 2*nDR)) {\
353 *pDS++ = *static_cast<float const *>( pSV );\
355 #define INSERT_DOUBLE( pSV, nr, pGPR, pDS, pStart ) \
356 if ( nDR < arm::MAX_FPR_REGS ) { \
357 pFPR[nDR++] = *static_cast<double const *>( pSV ); \
361 if ( (pDS - pStart) % 2) \
365 *reinterpret_cast<double *>(pDS) = *static_cast<double const *>( pSV );\
369 #define INSERT_FLOAT( pSV, nr, pFPR, pDS ) \
370 INSERT_INT32( pSV, nr, pGPR, pDS )
372 #define INSERT_DOUBLE( pSV, nr, pFPR, pDS, pStart ) \
373 INSERT_INT64( pSV, nr, pGPR, pDS, pStart )
376 #define INSERT_INT16( pSV, nr, pGPR, pDS ) \
377 if ( nr < arm::MAX_GPR_REGS ) \
378 pGPR[nr++] = *static_cast<sal_uInt16 const *>( pSV ); \
380 *pDS++ = *static_cast<sal_uInt16 const *>( pSV );
382 #define INSERT_INT8( pSV, nr, pGPR, pDS ) \
383 if ( nr < arm::MAX_GPR_REGS ) \
384 pGPR[nr++] = *static_cast<sal_uInt8 const *>( pSV ); \
386 *pDS++ = *static_cast<sal_uInt8 const *>( pSV );
393 typelib_TypeDescriptionReference * pReturnTypeRef,
394 sal_Int32 nParams, typelib_MethodParameter * pParams,
395 void * pUnoReturn,
void * pUnoArgs[],
uno_Any ** ppUnoExc )
398 sal_uInt32 * pStack =
static_cast<sal_uInt32 *
>(__builtin_alloca(
399 sizeof(sal_Int32) + ((nParams+2) *
sizeof(sal_Int64)) ));
400 sal_uInt32 * pStackStart = pStack;
409 float *pSPR =
reinterpret_cast< float *
>(&pFPR);
415 TYPELIB_DANGER_GET( &pReturnTypeDescr, pReturnTypeRef );
418 void * pCppReturn =
nullptr;
420 if (pReturnTypeDescr)
425 pCppReturn = pUnoReturn;
430 ? __builtin_alloca( pReturnTypeDescr->nSize )
437 void * pAdjustedThisPtr =
reinterpret_cast< void **
>(pThis->
getCppI())
442 static_assert(
sizeof(
void *) ==
sizeof(sal_Int32),
"### unexpected size!");
444 void ** pCppArgs =
static_cast<void **
>(alloca( 3 *
sizeof(
void *) * nParams ));
446 sal_Int32 * pTempIndices =
reinterpret_cast<sal_Int32 *
>(pCppArgs + nParams);
450 sal_Int32 nTempIndices = 0;
454 const typelib_MethodParameter & rParam = pParams[
nPos];
456 TYPELIB_DANGER_GET( &pParamTypeDescr, rParam.pTypeRef );
464 switch (pParamTypeDescr->eTypeClass)
466 case typelib_TypeClass_HYPER:
467 case typelib_TypeClass_UNSIGNED_HYPER:
468 #if OSL_DEBUG_LEVEL > 2
469 fprintf(stderr,
"hyper is %p\n", pCppArgs[nPos]);
471 INSERT_INT64( pCppArgs[nPos], nGPR, pGPR, pStack, pStackStart );
473 case typelib_TypeClass_LONG:
474 case typelib_TypeClass_UNSIGNED_LONG:
475 case typelib_TypeClass_ENUM:
476 #if OSL_DEBUG_LEVEL > 2
477 fprintf(stderr,
"long is %p\n", pCppArgs[nPos]);
481 case typelib_TypeClass_SHORT:
482 case typelib_TypeClass_CHAR:
483 case typelib_TypeClass_UNSIGNED_SHORT:
486 case typelib_TypeClass_BOOLEAN:
487 case typelib_TypeClass_BYTE:
490 case typelib_TypeClass_FLOAT:
493 case typelib_TypeClass_DOUBLE:
494 INSERT_DOUBLE( pCppArgs[nPos], nGPR, pGPR, pStack, pStackStart );
500 TYPELIB_DANGER_RELEASE( pParamTypeDescr );
508 pCppArgs[
nPos] = alloca( pParamTypeDescr->nSize ),
510 pTempIndices[nTempIndices] =
nPos;
512 ppTempParamTypeDescr[nTempIndices++] = pParamTypeDescr;
518 pCppArgs[
nPos] = alloca( pParamTypeDescr->nSize ),
521 pTempIndices[nTempIndices] = nPos;
523 ppTempParamTypeDescr[nTempIndices++] = pParamTypeDescr;
529 TYPELIB_DANGER_RELEASE( pParamTypeDescr );
539 pAdjustedThisPtr, aVtableSlot.
index,
540 pCppReturn, pReturnTypeRef,
542 (pStack - pStackStart),
545 }
catch (css::uno::Exception &) {
547 }
catch (std::exception & e) {
548 throw css::uno::RuntimeException(
552 throw css::uno::RuntimeException(
"C++ code threw unknown exception");
559 for ( ; nTempIndices--; )
561 sal_Int32
nIndex = pTempIndices[nTempIndices];
564 if (pParams[nIndex].bIn)
566 if (pParams[nIndex].bOut)
581 TYPELIB_DANGER_RELEASE( pParamTypeDescr );
584 if (pCppReturn && pUnoReturn != pCppReturn)
597 for ( ; nTempIndices--; )
599 sal_Int32
nIndex = pTempIndices[nTempIndices];
601 uno_destructData( pCppArgs[nIndex], ppTempParamTypeDescr[nTempIndices], cpp_release );
602 TYPELIB_DANGER_RELEASE( ppTempParamTypeDescr[nTempIndices] );
606 if (pReturnTypeDescr)
607 TYPELIB_DANGER_RELEASE( pReturnTypeDescr );
616 void * pReturn,
void * pArgs[],
uno_Any ** ppException )
621 #if OSL_DEBUG_LEVEL > 0
622 typelib_InterfaceTypeDescription * pTypeDescr = pThis->
pTypeDescr;
625 switch (pMemberDescr->eTypeClass)
627 case typelib_TypeClass_INTERFACE_ATTRIBUTE:
629 #if OSL_DEBUG_LEVEL > 0
631 sal_Int32 nMemberPos = ((typelib_InterfaceMemberTypeDescription *)pMemberDescr)->nPosition;
632 assert(nMemberPos < pTypeDescr->nAllMembers);
635 VtableSlot aVtableSlot(
637 reinterpret_cast<typelib_InterfaceAttributeTypeDescription const *>
645 reinterpret_cast<typelib_InterfaceAttributeTypeDescription const *>(pMemberDescr)->pAttributeTypeRef,
647 pReturn, pArgs, ppException );
652 typelib_MethodParameter aParam;
654 reinterpret_cast<typelib_InterfaceAttributeTypeDescription
const *
>(pMemberDescr)->pAttributeTypeRef;
658 typelib_TypeDescriptionReference * pReturnTypeRef =
nullptr;
659 OUString aVoidName(
"void");
661 &pReturnTypeRef, typelib_TypeClass_VOID, aVoidName.pData );
664 aVtableSlot.index += 1;
669 pReturn, pArgs, ppException );
676 case typelib_TypeClass_INTERFACE_METHOD:
678 #if OSL_DEBUG_LEVEL > 0
680 sal_Int32 nMemberPos = ((typelib_InterfaceMemberTypeDescription *)pMemberDescr)->nPosition;
681 assert(nMemberPos < pTypeDescr->nAllMembers);
684 VtableSlot aVtableSlot(
686 reinterpret_cast<typelib_InterfaceMethodTypeDescription const *>
689 switch (aVtableSlot.index)
693 (*pUnoI->acquire)( pUnoI );
694 *ppException =
nullptr;
697 (*pUnoI->release)( pUnoI );
698 *ppException =
nullptr;
703 TYPELIB_DANGER_GET( &pTD, static_cast< Type * >( pArgs[0] )->getTypeLibType() );
706 uno_Interface * pInterface =
nullptr;
709 reinterpret_cast<void **
>(&pInterface), pThis->
oid.pData, reinterpret_cast<typelib_InterfaceTypeDescription *>(pTD) );
714 static_cast< uno_Any * >( pReturn ),
715 &pInterface, pTD,
nullptr );
716 (*pInterface->release)( pInterface );
717 TYPELIB_DANGER_RELEASE( pTD );
718 *ppException =
nullptr;
721 TYPELIB_DANGER_RELEASE( pTD );
728 reinterpret_cast<typelib_InterfaceMethodTypeDescription const *>(pMemberDescr)->pReturnTypeRef,
729 reinterpret_cast<typelib_InterfaceMethodTypeDescription const *>(pMemberDescr)->nParams,
730 reinterpret_cast<typelib_InterfaceMethodTypeDescription const *>(pMemberDescr)->pParams,
731 pReturn, pArgs, ppException );
737 ::com::sun::star::uno::RuntimeException aExc(
738 "illegal member type description!",
743 ::uno_type_any_construct( *ppException, &aExc, rExcType.getTypeLibType(), nullptr );
void SAL_CALL uno_destructData(void *pValue, typelib_TypeDescription *pTypeDescr, uno_ReleaseFunc release) SAL_THROW_EXTERN_C()
static bool is_complex_struct(const typelib_TypeDescription *type)
Represents a vtable slot of a C++ class.
void fillUnoException(uno_Any *pExc, uno_Mapping *pCpp2Uno)
bool isSimpleType(typelib_TypeClass typeClass)
Determines whether a type is a "simple" type (VOID, BOOLEAN, BYTE, SHORT, UNSIGNED SHORT...
sal_Int32 index
The index within the vtable.
#define INSERT_INT64(pSV, nr, pGPR, pDS, pStart)
A uno proxy wrapping a cpp interface.
void callVirtualMethod(void *pThis, sal_uInt32 nVtableIndex, void *pRegisterReturn, typelib_TypeDescription *pReturnTypeDescr, bool bRegisterReturn, sal_uInt32 *pStack, sal_uInt32 nStack, sal_uInt32 *pGPR, double *pFPR) __attribute__((noinline))
bool relatesToInterfaceType(typelib_TypeDescription const *type)
Determines whether a type relates to an interface type (is itself an interface type, or might contain entities of interface type).
void unoInterfaceProxyDispatch(uno_Interface *pUnoI, const typelib_TypeDescription *pMemberDescr, void *pReturn, void *pArgs[], uno_Any **ppException)
const BorderLinePrimitive2D *pCandidateB assert(pCandidateA)
#define INSERT_INT32(pSV, nr, pGPR, pDS)
uno_ExtEnvironment * getUnoEnv()
uno_Mapping * getUno2Cpp()
#define INSERT_FLOAT(pSV, nr, pFPR, pDS)
static void cpp_call(bridges::cpp_uno::shared::UnoInterfaceProxy *pThis, bridges::cpp_uno::shared::VtableSlot aVtableSlot, typelib_TypeDescriptionReference *pReturnTypeRef, sal_Int32 nParams, typelib_MethodParameter *pParams, void *pUnoReturn, void *pUnoArgs[], uno_Any **ppUnoExc)
unsigned _Unwind_Word __attribute__((__mode__(__word__)))
#define INSERT_INT16(pSV, nr, pGPR, pDS)
sal_Int32 offset
The offset of the vtable.
#define INSERT_DOUBLE(pSV, nr, pFPR, pDS, pStart)
typelib_InterfaceTypeDescription * pTypeDescr
void SAL_CALL uno_constructData(void *pMem, typelib_TypeDescription *pTypeDescr) SAL_THROW_EXTERN_C()
void SAL_CALL uno_copyAndConvertData(void *pDest, void *pSource, typelib_TypeDescription *pTypeDescr, uno_Mapping *mapping) SAL_THROW_EXTERN_C()
void SAL_CALL typelib_typedescriptionreference_release(typelib_TypeDescriptionReference *pRef) SAL_THROW_EXTERN_C()
struct _typelib_TypeDescription typelib_TypeDescription
uno_Mapping * getCpp2Uno()
VtableSlot getVtableSlot(typelib_InterfaceAttributeTypeDescription const *ifcMember)
Calculates the vtable slot associated with an interface attribute member.
void SAL_CALL typelib_typedescriptionreference_new(typelib_TypeDescriptionReference **ppTDR, typelib_TypeClass eTypeClass, rtl_uString *pTypeName) SAL_THROW_EXTERN_C()
register sal_uInt32 r28 __asm__("%r28")
bool return_in_hidden_param(typelib_TypeDescriptionReference *pTypeRef)
Does function that returns this type use a hidden parameter, or registers?
#define INSERT_INT8(pSV, nr, pGPR, pDS)
OUString runtimeToOUString(char const *runtimeString)
void dummy_can_throw_anything(char const *)
static void MapReturn(sal_uInt32 r0, sal_uInt32 r1, typelib_TypeDescriptionReference *pReturnType, sal_uInt32 *pRegisterReturn)
com::sun::star::uno::XInterface * getCppI()