17a46fbe4Spfg /**************************************************************
27a46fbe4Spfg *
37a46fbe4Spfg * Licensed to the Apache Software Foundation (ASF) under one
47a46fbe4Spfg * or more contributor license agreements. See the NOTICE file
57a46fbe4Spfg * distributed with this work for additional information
67a46fbe4Spfg * regarding copyright ownership. The ASF licenses this file
77a46fbe4Spfg * to you under the Apache License, Version 2.0 (the
87a46fbe4Spfg * "License"); you may not use this file except in compliance
97a46fbe4Spfg * with the License. You may obtain a copy of the License at
107a46fbe4Spfg *
117a46fbe4Spfg * http://www.apache.org/licenses/LICENSE-2.0
127a46fbe4Spfg *
137a46fbe4Spfg * Unless required by applicable law or agreed to in writing,
147a46fbe4Spfg * software distributed under the License is distributed on an
157a46fbe4Spfg * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
167a46fbe4Spfg * KIND, either express or implied. See the License for the
177a46fbe4Spfg * specific language governing permissions and limitations
187a46fbe4Spfg * under the License.
197a46fbe4Spfg *
207a46fbe4Spfg *************************************************************/
217a46fbe4Spfg
227a46fbe4Spfg
237a46fbe4Spfg
24*7ddd8e27Spfg #include <stdlib.h>
257a46fbe4Spfg #include <rtl/alloc.h>
267a46fbe4Spfg
277a46fbe4Spfg #include <com/sun/star/uno/genfunc.hxx>
287a46fbe4Spfg #include "com/sun/star/uno/RuntimeException.hpp"
297a46fbe4Spfg #include <uno/data.h>
307a46fbe4Spfg
317a46fbe4Spfg #include <bridges/cpp_uno/shared/bridge.hxx>
327a46fbe4Spfg #include <bridges/cpp_uno/shared/types.hxx>
337a46fbe4Spfg #include <bridges/cpp_uno/shared/unointerfaceproxy.hxx>
347a46fbe4Spfg #include <bridges/cpp_uno/shared/vtables.hxx>
357a46fbe4Spfg
367a46fbe4Spfg #include "share.hxx"
377a46fbe4Spfg
387a46fbe4Spfg #include <stdio.h>
397a46fbe4Spfg #include <string.h>
407a46fbe4Spfg
417a46fbe4Spfg /*
427a46fbe4Spfg * Based on http://gcc.gnu.org/PR41443
437a46fbe4Spfg * References to __SOFTFP__ are incorrect for EABI; the __SOFTFP__ code
447a46fbe4Spfg * should be used for *soft-float ABI* whether or not VFP is enabled,
457a46fbe4Spfg * and __SOFTFP__ does specifically mean soft-float not soft-float ABI.
467a46fbe4Spfg *
477a46fbe4Spfg * Changing the conditionals to __SOFTFP__ || __ARM_EABI__ then
487a46fbe4Spfg * -mfloat-abi=softfp should work. -mfloat-abi=hard won't; that would
497a46fbe4Spfg * need both a new macro to identify the hard-VFP ABI.
507a46fbe4Spfg */
517a46fbe4Spfg #if !defined(__ARM_EABI__) && !defined(__SOFTFP__)
527a46fbe4Spfg #error Not Implemented
537a46fbe4Spfg
547a46fbe4Spfg /*
557a46fbe4Spfg some possibly handy code to detect that we have VFP registers
567a46fbe4Spfg */
577a46fbe4Spfg
587a46fbe4Spfg #include <sys/types.h>
597a46fbe4Spfg #include <sys/stat.h>
607a46fbe4Spfg #include <fcntl.h>
617a46fbe4Spfg #include <unistd.h>
627a46fbe4Spfg #include <elf.h>
637a46fbe4Spfg
647a46fbe4Spfg #define HWCAP_ARM_VFP 64
657a46fbe4Spfg
hasVFP(void)667a46fbe4Spfg int hasVFP(void)
677a46fbe4Spfg {
687a46fbe4Spfg int fd = open ("/proc/self/auxv", O_RDONLY);
697a46fbe4Spfg if (fd == -1)
707a46fbe4Spfg return -1;
717a46fbe4Spfg
727a46fbe4Spfg int ret = -1;
737a46fbe4Spfg
747a46fbe4Spfg Elf32_auxv_t buf[128];
757a46fbe4Spfg ssize_t n;
767a46fbe4Spfg while ((ret == -1) && ((n = read(fd, buf, sizeof (buf))) > 0))
777a46fbe4Spfg {
787a46fbe4Spfg for (int i = 0; i < 128; ++i)
797a46fbe4Spfg {
807a46fbe4Spfg if (buf[i].a_type == AT_HWCAP)
817a46fbe4Spfg {
827a46fbe4Spfg ret = (buf[i].a_un.a_val & HWCAP_ARM_VFP) ? true : false;
837a46fbe4Spfg break;
847a46fbe4Spfg }
857a46fbe4Spfg else if (buf[i].a_type == AT_NULL)
867a46fbe4Spfg {
877a46fbe4Spfg ret = -2;
887a46fbe4Spfg break;
897a46fbe4Spfg }
907a46fbe4Spfg }
917a46fbe4Spfg }
927a46fbe4Spfg
937a46fbe4Spfg close (fd);
947a46fbe4Spfg return ret;
957a46fbe4Spfg }
967a46fbe4Spfg
977a46fbe4Spfg #endif
987a46fbe4Spfg
997a46fbe4Spfg using namespace ::rtl;
1007a46fbe4Spfg using namespace ::com::sun::star::uno;
1017a46fbe4Spfg
1027a46fbe4Spfg namespace arm
1037a46fbe4Spfg {
is_complex_struct(const typelib_TypeDescription * type)1047a46fbe4Spfg bool is_complex_struct(const typelib_TypeDescription * type)
1057a46fbe4Spfg {
1067a46fbe4Spfg const typelib_CompoundTypeDescription * p
1077a46fbe4Spfg = reinterpret_cast< const typelib_CompoundTypeDescription * >(type);
1087a46fbe4Spfg for (sal_Int32 i = 0; i < p->nMembers; ++i)
1097a46fbe4Spfg {
1107a46fbe4Spfg if (p->ppTypeRefs[i]->eTypeClass == typelib_TypeClass_STRUCT ||
1117a46fbe4Spfg p->ppTypeRefs[i]->eTypeClass == typelib_TypeClass_EXCEPTION)
1127a46fbe4Spfg {
1137a46fbe4Spfg typelib_TypeDescription * t = 0;
1147a46fbe4Spfg TYPELIB_DANGER_GET(&t, p->ppTypeRefs[i]);
1157a46fbe4Spfg bool b = is_complex_struct(t);
1167a46fbe4Spfg TYPELIB_DANGER_RELEASE(t);
1177a46fbe4Spfg if (b) {
1187a46fbe4Spfg return true;
1197a46fbe4Spfg }
1207a46fbe4Spfg }
1217a46fbe4Spfg else if (!bridges::cpp_uno::shared::isSimpleType(p->ppTypeRefs[i]->eTypeClass))
1227a46fbe4Spfg return true;
1237a46fbe4Spfg }
1247a46fbe4Spfg if (p->pBaseTypeDescription != 0)
1257a46fbe4Spfg return is_complex_struct(&p->pBaseTypeDescription->aBase);
1267a46fbe4Spfg return false;
1277a46fbe4Spfg }
1287a46fbe4Spfg
return_in_hidden_param(typelib_TypeDescriptionReference * pTypeRef)1297a46fbe4Spfg bool return_in_hidden_param( typelib_TypeDescriptionReference *pTypeRef )
1307a46fbe4Spfg {
1317a46fbe4Spfg if (bridges::cpp_uno::shared::isSimpleType(pTypeRef))
1327a46fbe4Spfg return false;
1337a46fbe4Spfg else if (pTypeRef->eTypeClass == typelib_TypeClass_STRUCT || pTypeRef->eTypeClass == typelib_TypeClass_EXCEPTION)
1347a46fbe4Spfg {
1357a46fbe4Spfg typelib_TypeDescription * pTypeDescr = 0;
1367a46fbe4Spfg TYPELIB_DANGER_GET( &pTypeDescr, pTypeRef );
1377a46fbe4Spfg
1387a46fbe4Spfg //A Composite Type not larger than 4 bytes is returned in r0
1397a46fbe4Spfg bool bRet = pTypeDescr->nSize > 4 || is_complex_struct(pTypeDescr);
1407a46fbe4Spfg
1417a46fbe4Spfg TYPELIB_DANGER_RELEASE( pTypeDescr );
1427a46fbe4Spfg return bRet;
1437a46fbe4Spfg }
1447a46fbe4Spfg return true;
1457a46fbe4Spfg }
1467a46fbe4Spfg }
1477a46fbe4Spfg
MapReturn(sal_uInt32 r0,sal_uInt32 r1,typelib_TypeDescriptionReference * pReturnType,sal_uInt32 * pRegisterReturn)1487a46fbe4Spfg void MapReturn(sal_uInt32 r0, sal_uInt32 r1, typelib_TypeDescriptionReference * pReturnType, sal_uInt32* pRegisterReturn)
1497a46fbe4Spfg {
1507a46fbe4Spfg #if !defined(__ARM_EABI__) && !defined(__SOFTFP__)
1517a46fbe4Spfg register float fret asm("f0");
1527a46fbe4Spfg register double dret asm("f0");
1537a46fbe4Spfg #endif
1547a46fbe4Spfg
1557a46fbe4Spfg switch( pReturnType->eTypeClass )
1567a46fbe4Spfg {
1577a46fbe4Spfg case typelib_TypeClass_HYPER:
1587a46fbe4Spfg case typelib_TypeClass_UNSIGNED_HYPER:
1597a46fbe4Spfg pRegisterReturn[1] = r1;
1607a46fbe4Spfg case typelib_TypeClass_LONG:
1617a46fbe4Spfg case typelib_TypeClass_UNSIGNED_LONG:
1627a46fbe4Spfg case typelib_TypeClass_ENUM:
1637a46fbe4Spfg case typelib_TypeClass_CHAR:
1647a46fbe4Spfg case typelib_TypeClass_SHORT:
1657a46fbe4Spfg case typelib_TypeClass_UNSIGNED_SHORT:
1667a46fbe4Spfg case typelib_TypeClass_BOOLEAN:
1677a46fbe4Spfg case typelib_TypeClass_BYTE:
1687a46fbe4Spfg pRegisterReturn[0] = r0;
1697a46fbe4Spfg break;
1707a46fbe4Spfg case typelib_TypeClass_FLOAT:
1717a46fbe4Spfg #if defined(__ARM_EABI__) || defined(__SOFTFP__)
1727a46fbe4Spfg pRegisterReturn[0] = r0;
1737a46fbe4Spfg #else
1747a46fbe4Spfg *(float*)pRegisterReturn = fret;
1757a46fbe4Spfg #endif
1767a46fbe4Spfg break;
1777a46fbe4Spfg case typelib_TypeClass_DOUBLE:
1787a46fbe4Spfg #if defined(__ARM_EABI__) || defined(__SOFTFP__)
1797a46fbe4Spfg pRegisterReturn[1] = r1;
1807a46fbe4Spfg pRegisterReturn[0] = r0;
1817a46fbe4Spfg #else
1827a46fbe4Spfg *(double*)pRegisterReturn = dret;
1837a46fbe4Spfg #endif
1847a46fbe4Spfg break;
1857a46fbe4Spfg case typelib_TypeClass_STRUCT:
1867a46fbe4Spfg case typelib_TypeClass_EXCEPTION:
1877a46fbe4Spfg {
1887a46fbe4Spfg if (!arm::return_in_hidden_param(pReturnType))
1897a46fbe4Spfg pRegisterReturn[0] = r0;
1907a46fbe4Spfg break;
1917a46fbe4Spfg }
1927a46fbe4Spfg default:
1937a46fbe4Spfg break;
1947a46fbe4Spfg }
1957a46fbe4Spfg }
1967a46fbe4Spfg
1977a46fbe4Spfg namespace
1987a46fbe4Spfg {
1997a46fbe4Spfg //================================================================
2007a46fbe4Spfg
2017a46fbe4Spfg void callVirtualMethod(
2027a46fbe4Spfg void * pThis,
2037a46fbe4Spfg sal_Int32 nVtableIndex,
2047a46fbe4Spfg void * pRegisterReturn,
2057a46fbe4Spfg typelib_TypeDescriptionReference * pReturnType,
2067a46fbe4Spfg sal_uInt32 *pStack,
2077a46fbe4Spfg sal_uInt32 nStack,
2087a46fbe4Spfg sal_uInt32 *pGPR,
2097a46fbe4Spfg sal_uInt32 nGPR) __attribute__((noinline));
2107a46fbe4Spfg
callVirtualMethod(void * pThis,sal_Int32 nVtableIndex,void * pRegisterReturn,typelib_TypeDescriptionReference * pReturnType,sal_uInt32 * pStack,sal_uInt32 nStack,sal_uInt32 * pGPR,sal_uInt32 nGPR)2117a46fbe4Spfg void callVirtualMethod(
2127a46fbe4Spfg void * pThis,
2137a46fbe4Spfg sal_Int32 nVtableIndex,
2147a46fbe4Spfg void * pRegisterReturn,
2157a46fbe4Spfg typelib_TypeDescriptionReference * pReturnType,
2167a46fbe4Spfg sal_uInt32 *pStack,
2177a46fbe4Spfg sal_uInt32 nStack,
2187a46fbe4Spfg sal_uInt32 *pGPR,
2197a46fbe4Spfg sal_uInt32 nGPR)
2207a46fbe4Spfg {
2217a46fbe4Spfg // never called
2227a46fbe4Spfg if (! pThis)
2237a46fbe4Spfg CPPU_CURRENT_NAMESPACE::dummy_can_throw_anything("xxx"); // address something
2247a46fbe4Spfg
2257a46fbe4Spfg if ( nStack )
2267a46fbe4Spfg {
2277a46fbe4Spfg // 8-bytes aligned
2287a46fbe4Spfg sal_uInt32 nStackBytes = ( ( nStack + 1 ) >> 1 ) * 8;
2297a46fbe4Spfg sal_uInt32 *stack = (sal_uInt32 *) __builtin_alloca( nStackBytes );
2307a46fbe4Spfg memcpy( stack, pStack, nStackBytes );
2317a46fbe4Spfg }
2327a46fbe4Spfg
2337a46fbe4Spfg // Should not happen, but...
2347a46fbe4Spfg if ( nGPR > arm::MAX_GPR_REGS )
2357a46fbe4Spfg nGPR = arm::MAX_GPR_REGS;
2367a46fbe4Spfg
2377a46fbe4Spfg sal_uInt32 pMethod = *((sal_uInt32*)pThis);
2387a46fbe4Spfg pMethod += 4 * nVtableIndex;
2397a46fbe4Spfg pMethod = *((sal_uInt32 *)pMethod);
2407a46fbe4Spfg
2417a46fbe4Spfg typedef void (*FunctionCall )( sal_uInt32, sal_uInt32, sal_uInt32, sal_uInt32);
2427a46fbe4Spfg FunctionCall pFunc = (FunctionCall)pMethod;
2437a46fbe4Spfg
2447a46fbe4Spfg (*pFunc)(pGPR[0], pGPR[1], pGPR[2], pGPR[3]);
2457a46fbe4Spfg
2467a46fbe4Spfg sal_uInt32 r0;
2477a46fbe4Spfg sal_uInt32 r1;
2487a46fbe4Spfg
2497a46fbe4Spfg // get return value
2507a46fbe4Spfg __asm__ __volatile__ (
2517a46fbe4Spfg "mov %0, r0\n\t"
2527a46fbe4Spfg "mov %1, r1\n\t"
2537a46fbe4Spfg : "=r" (r0), "=r" (r1) : );
2547a46fbe4Spfg
2557a46fbe4Spfg MapReturn(r0, r1, pReturnType, (sal_uInt32*)pRegisterReturn);
2567a46fbe4Spfg }
2577a46fbe4Spfg }
2587a46fbe4Spfg
2597a46fbe4Spfg #define INSERT_INT32( pSV, nr, pGPR, pDS, bOverflow ) \
2607a46fbe4Spfg if ( nr < arm::MAX_GPR_REGS ) \
2617a46fbe4Spfg pGPR[nr++] = *reinterpret_cast<sal_uInt32 *>( pSV ); \
2627a46fbe4Spfg else \
2637a46fbe4Spfg bOverFlow = true; \
2647a46fbe4Spfg if (bOverFlow) \
2657a46fbe4Spfg *pDS++ = *reinterpret_cast<sal_uInt32 *>( pSV );
2667a46fbe4Spfg
2677a46fbe4Spfg #ifdef __ARM_EABI__
2687a46fbe4Spfg #define INSERT_INT64( pSV, nr, pGPR, pDS, pStart, bOverflow ) \
2697a46fbe4Spfg if ( (nr < arm::MAX_GPR_REGS) && (nr % 2) ) \
2707a46fbe4Spfg { \
2717a46fbe4Spfg ++nr; \
2727a46fbe4Spfg } \
2737a46fbe4Spfg if ( nr < arm::MAX_GPR_REGS ) \
2747a46fbe4Spfg { \
2757a46fbe4Spfg pGPR[nr++] = *reinterpret_cast<sal_uInt32 *>( pSV ); \
2767a46fbe4Spfg pGPR[nr++] = *(reinterpret_cast<sal_uInt32 *>( pSV ) + 1); \
2777a46fbe4Spfg } \
2787a46fbe4Spfg else \
2797a46fbe4Spfg bOverFlow = true; \
2807a46fbe4Spfg if (bOverFlow) \
2817a46fbe4Spfg { \
2827a46fbe4Spfg if ( (pDS - pStart) % 2) \
2837a46fbe4Spfg { \
2847a46fbe4Spfg ++pDS; \
2857a46fbe4Spfg } \
2867a46fbe4Spfg *pDS++ = reinterpret_cast<sal_uInt32 *>( pSV )[0]; \
2877a46fbe4Spfg *pDS++ = reinterpret_cast<sal_uInt32 *>( pSV )[1]; \
2887a46fbe4Spfg }
2897a46fbe4Spfg #else
2907a46fbe4Spfg #define INSERT_INT64( pSV, nr, pGPR, pDS, pStart, bOverflow ) \
2917a46fbe4Spfg INSERT_INT32( pSV, nr, pGPR, pDS, bOverflow) \
2927a46fbe4Spfg INSERT_INT32( ((sal_uInt32*)pSV)+1, nr, pGPR, pDS, bOverflow)
2937a46fbe4Spfg #endif
2947a46fbe4Spfg
2957a46fbe4Spfg #define INSERT_FLOAT( pSV, nr, pFPR, pDS, bOverflow ) \
2967a46fbe4Spfg INSERT_INT32( pSV, nr, pGPR, pDS, bOverflow)
2977a46fbe4Spfg
2987a46fbe4Spfg #define INSERT_DOUBLE( pSV, nr, pFPR, pDS, pStart, bOverflow ) \
2997a46fbe4Spfg INSERT_INT64( pSV, nr, pGPR, pDS, pStart, bOverflow )
3007a46fbe4Spfg
3017a46fbe4Spfg #define INSERT_INT16( pSV, nr, pGPR, pDS, bOverflow ) \
3027a46fbe4Spfg if ( nr < arm::MAX_GPR_REGS ) \
3037a46fbe4Spfg pGPR[nr++] = *reinterpret_cast<sal_uInt16 *>( pSV ); \
3047a46fbe4Spfg else \
3057a46fbe4Spfg bOverFlow = true; \
3067a46fbe4Spfg if (bOverFlow) \
3077a46fbe4Spfg *pDS++ = *reinterpret_cast<sal_uInt16 *>( pSV );
3087a46fbe4Spfg
3097a46fbe4Spfg #define INSERT_INT8( pSV, nr, pGPR, pDS, bOverflow ) \
3107a46fbe4Spfg if ( nr < arm::MAX_GPR_REGS ) \
3117a46fbe4Spfg pGPR[nr++] = *reinterpret_cast<sal_uInt8 *>( pSV ); \
3127a46fbe4Spfg else \
3137a46fbe4Spfg bOverFlow = true; \
3147a46fbe4Spfg if (bOverFlow) \
3157a46fbe4Spfg *pDS++ = *reinterpret_cast<sal_uInt8 *>( pSV );
3167a46fbe4Spfg
3177a46fbe4Spfg namespace {
3187a46fbe4Spfg //=======================================================================
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)3197a46fbe4Spfg static void cpp_call(
3207a46fbe4Spfg bridges::cpp_uno::shared::UnoInterfaceProxy * pThis,
3217a46fbe4Spfg bridges::cpp_uno::shared::VtableSlot aVtableSlot,
3227a46fbe4Spfg typelib_TypeDescriptionReference * pReturnTypeRef,
3237a46fbe4Spfg sal_Int32 nParams, typelib_MethodParameter * pParams,
3247a46fbe4Spfg void * pUnoReturn, void * pUnoArgs[], uno_Any ** ppUnoExc )
3257a46fbe4Spfg {
3267a46fbe4Spfg // max space for: [complex ret ptr], values|ptr ...
3277a46fbe4Spfg sal_uInt32 * pStack = (sal_uInt32 *)__builtin_alloca(
3287a46fbe4Spfg sizeof(sal_Int32) + ((nParams+2) * sizeof(sal_Int64)) );
3297a46fbe4Spfg sal_uInt32 * pStackStart = pStack;
3307a46fbe4Spfg
3317a46fbe4Spfg sal_uInt32 pGPR[arm::MAX_GPR_REGS];
3327a46fbe4Spfg sal_uInt32 nGPR = 0;
3337a46fbe4Spfg
3347a46fbe4Spfg // return
3357a46fbe4Spfg typelib_TypeDescription * pReturnTypeDescr = 0;
3367a46fbe4Spfg TYPELIB_DANGER_GET( &pReturnTypeDescr, pReturnTypeRef );
3377a46fbe4Spfg OSL_ENSURE( pReturnTypeDescr, "### expected return type description!" );
3387a46fbe4Spfg
3397a46fbe4Spfg void * pCppReturn = 0; // if != 0 && != pUnoReturn, needs reconversion
3407a46fbe4Spfg
3417a46fbe4Spfg bool bOverFlow = false;
3427a46fbe4Spfg bool bSimpleReturn = true;
3437a46fbe4Spfg if (pReturnTypeDescr)
3447a46fbe4Spfg {
3457a46fbe4Spfg if (arm::return_in_hidden_param( pReturnTypeRef ) )
3467a46fbe4Spfg bSimpleReturn = false;
3477a46fbe4Spfg
3487a46fbe4Spfg if (bSimpleReturn)
3497a46fbe4Spfg pCppReturn = pUnoReturn; // direct way for simple types
3507a46fbe4Spfg else
3517a46fbe4Spfg {
3527a46fbe4Spfg // complex return via ptr
3537a46fbe4Spfg pCppReturn = (bridges::cpp_uno::shared::relatesToInterfaceType( pReturnTypeDescr )
3547a46fbe4Spfg ? __builtin_alloca( pReturnTypeDescr->nSize )
3557a46fbe4Spfg : pUnoReturn); // direct way
3567a46fbe4Spfg
3577a46fbe4Spfg INSERT_INT32( &pCppReturn, nGPR, pGPR, pStack, bOverFlow );
3587a46fbe4Spfg }
3597a46fbe4Spfg }
3607a46fbe4Spfg // push this
3617a46fbe4Spfg void * pAdjustedThisPtr = reinterpret_cast< void ** >(pThis->getCppI())
3627a46fbe4Spfg + aVtableSlot.offset;
3637a46fbe4Spfg INSERT_INT32( &pAdjustedThisPtr, nGPR, pGPR, pStack, bOverFlow );
3647a46fbe4Spfg
3657a46fbe4Spfg // stack space
3667a46fbe4Spfg OSL_ENSURE( sizeof(void *) == sizeof(sal_Int32), "### unexpected size!" );
3677a46fbe4Spfg // args
3687a46fbe4Spfg void ** pCppArgs = (void **)alloca( 3 * sizeof(void *) * nParams );
3697a46fbe4Spfg // indizes of values this have to be converted (interface conversion cpp<=>uno)
3707a46fbe4Spfg sal_Int32 * pTempIndizes = (sal_Int32 *)(pCppArgs + nParams);
3717a46fbe4Spfg // type descriptions for reconversions
3727a46fbe4Spfg typelib_TypeDescription ** ppTempParamTypeDescr = (typelib_TypeDescription **)(pCppArgs + (2 * nParams));
3737a46fbe4Spfg
3747a46fbe4Spfg sal_Int32 nTempIndizes = 0;
3757a46fbe4Spfg
3767a46fbe4Spfg for ( sal_Int32 nPos = 0; nPos < nParams; ++nPos )
3777a46fbe4Spfg {
3787a46fbe4Spfg const typelib_MethodParameter & rParam = pParams[nPos];
3797a46fbe4Spfg typelib_TypeDescription * pParamTypeDescr = 0;
3807a46fbe4Spfg TYPELIB_DANGER_GET( &pParamTypeDescr, rParam.pTypeRef );
3817a46fbe4Spfg
3827a46fbe4Spfg if (!rParam.bOut && bridges::cpp_uno::shared::isSimpleType( pParamTypeDescr ))
3837a46fbe4Spfg {
3847a46fbe4Spfg // uno_copyAndConvertData( pCppArgs[nPos] = pStack, pUnoArgs[nPos],
3857a46fbe4Spfg uno_copyAndConvertData( pCppArgs[nPos] = alloca(8), pUnoArgs[nPos],
3867a46fbe4Spfg pParamTypeDescr, pThis->getBridge()->getUno2Cpp() );
3877a46fbe4Spfg
3887a46fbe4Spfg switch (pParamTypeDescr->eTypeClass)
3897a46fbe4Spfg {
3907a46fbe4Spfg case typelib_TypeClass_HYPER:
3917a46fbe4Spfg case typelib_TypeClass_UNSIGNED_HYPER:
3927a46fbe4Spfg #ifdef CMC_DEBUG
3937a46fbe4Spfg fprintf(stderr, "hyper is %lx\n", pCppArgs[nPos]);
3947a46fbe4Spfg #endif
3957a46fbe4Spfg INSERT_INT64( pCppArgs[nPos], nGPR, pGPR, pStack, pStackStart, bOverFlow );
3967a46fbe4Spfg break;
3977a46fbe4Spfg case typelib_TypeClass_LONG:
3987a46fbe4Spfg case typelib_TypeClass_UNSIGNED_LONG:
3997a46fbe4Spfg case typelib_TypeClass_ENUM:
4007a46fbe4Spfg #ifdef CMC_DEBUG
4017a46fbe4Spfg fprintf(stderr, "long is %x\n", pCppArgs[nPos]);
4027a46fbe4Spfg #endif
4037a46fbe4Spfg INSERT_INT32( pCppArgs[nPos], nGPR, pGPR, pStack, bOverFlow );
4047a46fbe4Spfg break;
4057a46fbe4Spfg case typelib_TypeClass_SHORT:
4067a46fbe4Spfg case typelib_TypeClass_CHAR:
4077a46fbe4Spfg case typelib_TypeClass_UNSIGNED_SHORT:
4087a46fbe4Spfg INSERT_INT16( pCppArgs[nPos], nGPR, pGPR, pStack, bOverFlow );
4097a46fbe4Spfg break;
4107a46fbe4Spfg case typelib_TypeClass_BOOLEAN:
4117a46fbe4Spfg case typelib_TypeClass_BYTE:
4127a46fbe4Spfg INSERT_INT8( pCppArgs[nPos], nGPR, pGPR, pStack, bOverFlow );
4137a46fbe4Spfg break;
4147a46fbe4Spfg case typelib_TypeClass_FLOAT:
4157a46fbe4Spfg INSERT_FLOAT( pCppArgs[nPos], nGPR, pGPR, pStack, bOverFlow );
4167a46fbe4Spfg break;
4177a46fbe4Spfg case typelib_TypeClass_DOUBLE:
4187a46fbe4Spfg INSERT_DOUBLE( pCppArgs[nPos], nGPR, pGPR, pStack, pStackStart, bOverFlow );
4197a46fbe4Spfg break;
4207a46fbe4Spfg default:
4217a46fbe4Spfg break;
4227a46fbe4Spfg }
4237a46fbe4Spfg // no longer needed
4247a46fbe4Spfg TYPELIB_DANGER_RELEASE( pParamTypeDescr );
4257a46fbe4Spfg }
4267a46fbe4Spfg else // ptr to complex value | ref
4277a46fbe4Spfg {
4287a46fbe4Spfg if (! rParam.bIn) // is pure out
4297a46fbe4Spfg {
4307a46fbe4Spfg // cpp out is constructed mem, uno out is not!
4317a46fbe4Spfg uno_constructData(
4327a46fbe4Spfg pCppArgs[nPos] = alloca( pParamTypeDescr->nSize ),
4337a46fbe4Spfg pParamTypeDescr );
4347a46fbe4Spfg pTempIndizes[nTempIndizes] = nPos; // default constructed for cpp call
4357a46fbe4Spfg // will be released at reconversion
4367a46fbe4Spfg ppTempParamTypeDescr[nTempIndizes++] = pParamTypeDescr;
4377a46fbe4Spfg }
4387a46fbe4Spfg // is in/inout
4397a46fbe4Spfg else if (bridges::cpp_uno::shared::relatesToInterfaceType( pParamTypeDescr ))
4407a46fbe4Spfg {
4417a46fbe4Spfg uno_copyAndConvertData(
4427a46fbe4Spfg pCppArgs[nPos] = alloca( pParamTypeDescr->nSize ),
4437a46fbe4Spfg pUnoArgs[nPos], pParamTypeDescr, pThis->getBridge()->getUno2Cpp() );
4447a46fbe4Spfg
4457a46fbe4Spfg pTempIndizes[nTempIndizes] = nPos; // has to be reconverted
4467a46fbe4Spfg // will be released at reconversion
4477a46fbe4Spfg ppTempParamTypeDescr[nTempIndizes++] = pParamTypeDescr;
4487a46fbe4Spfg }
4497a46fbe4Spfg else // direct way
4507a46fbe4Spfg {
4517a46fbe4Spfg pCppArgs[nPos] = pUnoArgs[nPos];
4527a46fbe4Spfg // no longer needed
4537a46fbe4Spfg TYPELIB_DANGER_RELEASE( pParamTypeDescr );
4547a46fbe4Spfg }
4557a46fbe4Spfg INSERT_INT32( &(pCppArgs[nPos]), nGPR, pGPR, pStack, bOverFlow );
4567a46fbe4Spfg }
4577a46fbe4Spfg }
4587a46fbe4Spfg
4597a46fbe4Spfg try
4607a46fbe4Spfg {
4617a46fbe4Spfg callVirtualMethod(
4627a46fbe4Spfg pAdjustedThisPtr, aVtableSlot.index,
4637a46fbe4Spfg pCppReturn, pReturnTypeRef,
4647a46fbe4Spfg pStackStart,
4657a46fbe4Spfg (pStack - pStackStart),
4667a46fbe4Spfg pGPR, nGPR);
4677a46fbe4Spfg
4687a46fbe4Spfg // NO exception occurred...
4697a46fbe4Spfg *ppUnoExc = 0;
4707a46fbe4Spfg
4717a46fbe4Spfg // reconvert temporary params
4727a46fbe4Spfg for ( ; nTempIndizes--; )
4737a46fbe4Spfg {
4747a46fbe4Spfg sal_Int32 nIndex = pTempIndizes[nTempIndizes];
4757a46fbe4Spfg typelib_TypeDescription * pParamTypeDescr = ppTempParamTypeDescr[nTempIndizes];
4767a46fbe4Spfg
4777a46fbe4Spfg if (pParams[nIndex].bIn)
4787a46fbe4Spfg {
4797a46fbe4Spfg if (pParams[nIndex].bOut) // inout
4807a46fbe4Spfg {
4817a46fbe4Spfg uno_destructData( pUnoArgs[nIndex], pParamTypeDescr, 0 ); // destroy uno value
4827a46fbe4Spfg uno_copyAndConvertData( pUnoArgs[nIndex], pCppArgs[nIndex], pParamTypeDescr,
4837a46fbe4Spfg pThis->getBridge()->getCpp2Uno() );
4847a46fbe4Spfg }
4857a46fbe4Spfg }
4867a46fbe4Spfg else // pure out
4877a46fbe4Spfg {
4887a46fbe4Spfg uno_copyAndConvertData( pUnoArgs[nIndex], pCppArgs[nIndex], pParamTypeDescr,
4897a46fbe4Spfg pThis->getBridge()->getCpp2Uno() );
4907a46fbe4Spfg }
4917a46fbe4Spfg // destroy temp cpp param => cpp: every param was constructed
4927a46fbe4Spfg uno_destructData( pCppArgs[nIndex], pParamTypeDescr, cpp_release );
4937a46fbe4Spfg
4947a46fbe4Spfg TYPELIB_DANGER_RELEASE( pParamTypeDescr );
4957a46fbe4Spfg }
4967a46fbe4Spfg // return value
4977a46fbe4Spfg if (pCppReturn && pUnoReturn != pCppReturn)
4987a46fbe4Spfg {
4997a46fbe4Spfg uno_copyAndConvertData( pUnoReturn, pCppReturn, pReturnTypeDescr,
5007a46fbe4Spfg pThis->getBridge()->getCpp2Uno() );
5017a46fbe4Spfg uno_destructData( pCppReturn, pReturnTypeDescr, cpp_release );
5027a46fbe4Spfg }
5037a46fbe4Spfg }
5047a46fbe4Spfg catch (...)
5057a46fbe4Spfg {
5067a46fbe4Spfg // __asm__ __volatile__ ("sub sp, sp, #2048\n");
5077a46fbe4Spfg
5087a46fbe4Spfg // fill uno exception
5097a46fbe4Spfg fillUnoException( CPPU_CURRENT_NAMESPACE::__cxa_get_globals()->caughtExceptions, *ppUnoExc, pThis->getBridge()->getCpp2Uno() );
5107a46fbe4Spfg
5117a46fbe4Spfg // temporary params
5127a46fbe4Spfg for ( ; nTempIndizes--; )
5137a46fbe4Spfg {
5147a46fbe4Spfg sal_Int32 nIndex = pTempIndizes[nTempIndizes];
5157a46fbe4Spfg // destroy temp cpp param => cpp: every param was constructed
5167a46fbe4Spfg uno_destructData( pCppArgs[nIndex], ppTempParamTypeDescr[nTempIndizes], cpp_release );
5177a46fbe4Spfg TYPELIB_DANGER_RELEASE( ppTempParamTypeDescr[nTempIndizes] );
5187a46fbe4Spfg }
5197a46fbe4Spfg
5207a46fbe4Spfg // return type
5217a46fbe4Spfg if (pReturnTypeDescr)
5227a46fbe4Spfg TYPELIB_DANGER_RELEASE( pReturnTypeDescr );
5237a46fbe4Spfg }
5247a46fbe4Spfg }
5257a46fbe4Spfg }
5267a46fbe4Spfg
5277a46fbe4Spfg namespace bridges { namespace cpp_uno { namespace shared {
5287a46fbe4Spfg
unoInterfaceProxyDispatch(uno_Interface * pUnoI,const typelib_TypeDescription * pMemberDescr,void * pReturn,void * pArgs[],uno_Any ** ppException)5297a46fbe4Spfg void unoInterfaceProxyDispatch(
5307a46fbe4Spfg uno_Interface * pUnoI, const typelib_TypeDescription * pMemberDescr,
5317a46fbe4Spfg void * pReturn, void * pArgs[], uno_Any ** ppException )
5327a46fbe4Spfg {
5337a46fbe4Spfg // is my surrogate
5347a46fbe4Spfg bridges::cpp_uno::shared::UnoInterfaceProxy * pThis
5357a46fbe4Spfg = static_cast< bridges::cpp_uno::shared::UnoInterfaceProxy * >(pUnoI);
5367a46fbe4Spfg #if OSL_DEBUG_LEVEL > 0
5377a46fbe4Spfg typelib_InterfaceTypeDescription * pTypeDescr = pThis->pTypeDescr;
5387a46fbe4Spfg #endif
5397a46fbe4Spfg
5407a46fbe4Spfg switch (pMemberDescr->eTypeClass)
5417a46fbe4Spfg {
5427a46fbe4Spfg case typelib_TypeClass_INTERFACE_ATTRIBUTE:
5437a46fbe4Spfg {
5447a46fbe4Spfg #if OSL_DEBUG_LEVEL > 0
5457a46fbe4Spfg // determine vtable call index
5467a46fbe4Spfg sal_Int32 nMemberPos = ((typelib_InterfaceMemberTypeDescription *)pMemberDescr)->nPosition;
5477a46fbe4Spfg OSL_ENSURE( nMemberPos < pTypeDescr->nAllMembers, "### member pos out of range!" );
5487a46fbe4Spfg #endif
5497a46fbe4Spfg
5507a46fbe4Spfg VtableSlot aVtableSlot(
5517a46fbe4Spfg getVtableSlot(
5527a46fbe4Spfg reinterpret_cast<typelib_InterfaceAttributeTypeDescription const *>
5537a46fbe4Spfg (pMemberDescr)));
5547a46fbe4Spfg
5557a46fbe4Spfg if (pReturn)
5567a46fbe4Spfg {
5577a46fbe4Spfg // dependent dispatch
5587a46fbe4Spfg cpp_call(
5597a46fbe4Spfg pThis, aVtableSlot,
5607a46fbe4Spfg ((typelib_InterfaceAttributeTypeDescription *)pMemberDescr)->pAttributeTypeRef,
5617a46fbe4Spfg 0, 0, // no params
5627a46fbe4Spfg pReturn, pArgs, ppException );
5637a46fbe4Spfg }
5647a46fbe4Spfg else
5657a46fbe4Spfg {
5667a46fbe4Spfg // is SET
5677a46fbe4Spfg typelib_MethodParameter aParam;
5687a46fbe4Spfg aParam.pTypeRef =
5697a46fbe4Spfg ((typelib_InterfaceAttributeTypeDescription *)pMemberDescr)->pAttributeTypeRef;
5707a46fbe4Spfg aParam.bIn = sal_True;
5717a46fbe4Spfg aParam.bOut = sal_False;
5727a46fbe4Spfg
5737a46fbe4Spfg typelib_TypeDescriptionReference * pReturnTypeRef = 0;
5747a46fbe4Spfg OUString aVoidName( RTL_CONSTASCII_USTRINGPARAM("void") );
5757a46fbe4Spfg typelib_typedescriptionreference_new(
5767a46fbe4Spfg &pReturnTypeRef, typelib_TypeClass_VOID, aVoidName.pData );
5777a46fbe4Spfg
5787a46fbe4Spfg // dependent dispatch
5797a46fbe4Spfg aVtableSlot.index += 1;
5807a46fbe4Spfg cpp_call(
5817a46fbe4Spfg pThis, aVtableSlot, // get, then set method
5827a46fbe4Spfg pReturnTypeRef,
5837a46fbe4Spfg 1, &aParam,
5847a46fbe4Spfg pReturn, pArgs, ppException );
5857a46fbe4Spfg
5867a46fbe4Spfg typelib_typedescriptionreference_release( pReturnTypeRef );
5877a46fbe4Spfg }
5887a46fbe4Spfg
5897a46fbe4Spfg break;
5907a46fbe4Spfg }
5917a46fbe4Spfg case typelib_TypeClass_INTERFACE_METHOD:
5927a46fbe4Spfg {
5937a46fbe4Spfg #if OSL_DEBUG_LEVEL > 0
5947a46fbe4Spfg // determine vtable call index
5957a46fbe4Spfg sal_Int32 nMemberPos = ((typelib_InterfaceMemberTypeDescription *)pMemberDescr)->nPosition;
5967a46fbe4Spfg OSL_ENSURE( nMemberPos < pTypeDescr->nAllMembers, "### member pos out of range!" );
5977a46fbe4Spfg #endif
5987a46fbe4Spfg
5997a46fbe4Spfg VtableSlot aVtableSlot(
6007a46fbe4Spfg getVtableSlot(
6017a46fbe4Spfg reinterpret_cast<typelib_InterfaceMethodTypeDescription const *>
6027a46fbe4Spfg (pMemberDescr)));
6037a46fbe4Spfg
6047a46fbe4Spfg switch (aVtableSlot.index)
6057a46fbe4Spfg {
6067a46fbe4Spfg // standard calls
6077a46fbe4Spfg case 1: // acquire uno interface
6087a46fbe4Spfg (*pUnoI->acquire)( pUnoI );
6097a46fbe4Spfg *ppException = 0;
6107a46fbe4Spfg break;
6117a46fbe4Spfg case 2: // release uno interface
6127a46fbe4Spfg (*pUnoI->release)( pUnoI );
6137a46fbe4Spfg *ppException = 0;
6147a46fbe4Spfg break;
6157a46fbe4Spfg case 0: // queryInterface() opt
6167a46fbe4Spfg {
6177a46fbe4Spfg typelib_TypeDescription * pTD = 0;
6187a46fbe4Spfg TYPELIB_DANGER_GET( &pTD, reinterpret_cast< Type * >( pArgs[0] )->getTypeLibType() );
6197a46fbe4Spfg if (pTD)
6207a46fbe4Spfg {
6217a46fbe4Spfg uno_Interface * pInterface = 0;
6227a46fbe4Spfg (*pThis->getBridge()->getUnoEnv()->getRegisteredInterface)(
6237a46fbe4Spfg pThis->getBridge()->getUnoEnv(),
6247a46fbe4Spfg (void **)&pInterface, pThis->oid.pData, (typelib_InterfaceTypeDescription *)pTD );
6257a46fbe4Spfg
6267a46fbe4Spfg if (pInterface)
6277a46fbe4Spfg {
6287a46fbe4Spfg ::uno_any_construct(
6297a46fbe4Spfg reinterpret_cast< uno_Any * >( pReturn ),
6307a46fbe4Spfg &pInterface, pTD, 0 );
6317a46fbe4Spfg (*pInterface->release)( pInterface );
6327a46fbe4Spfg TYPELIB_DANGER_RELEASE( pTD );
6337a46fbe4Spfg *ppException = 0;
6347a46fbe4Spfg break;
6357a46fbe4Spfg }
6367a46fbe4Spfg TYPELIB_DANGER_RELEASE( pTD );
6377a46fbe4Spfg }
6387a46fbe4Spfg } // else perform queryInterface()
6397a46fbe4Spfg default:
6407a46fbe4Spfg // dependent dispatch
6417a46fbe4Spfg cpp_call(
6427a46fbe4Spfg pThis, aVtableSlot,
6437a46fbe4Spfg ((typelib_InterfaceMethodTypeDescription *)pMemberDescr)->pReturnTypeRef,
6447a46fbe4Spfg ((typelib_InterfaceMethodTypeDescription *)pMemberDescr)->nParams,
6457a46fbe4Spfg ((typelib_InterfaceMethodTypeDescription *)pMemberDescr)->pParams,
6467a46fbe4Spfg pReturn, pArgs, ppException );
6477a46fbe4Spfg }
6487a46fbe4Spfg break;
6497a46fbe4Spfg }
6507a46fbe4Spfg default:
6517a46fbe4Spfg {
6527a46fbe4Spfg ::com::sun::star::uno::RuntimeException aExc(
6537a46fbe4Spfg OUString( RTL_CONSTASCII_USTRINGPARAM("illegal member type description!") ),
6547a46fbe4Spfg ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >() );
6557a46fbe4Spfg
6567a46fbe4Spfg Type const & rExcType = ::getCppuType( &aExc );
6577a46fbe4Spfg // binary identical null reference
6587a46fbe4Spfg ::uno_type_any_construct( *ppException, &aExc, rExcType.getTypeLibType(), 0 );
6597a46fbe4Spfg }
6607a46fbe4Spfg }
6617a46fbe4Spfg }
6627a46fbe4Spfg
6637a46fbe4Spfg } } }
6647a46fbe4Spfg
6657a46fbe4Spfg /* vi:set tabstop=4 shiftwidth=4 expandtab: */
666