1*61dff127SAndrew Rist /**************************************************************
2cdf0e10cSrcweir *
3*61dff127SAndrew Rist * Licensed to the Apache Software Foundation (ASF) under one
4*61dff127SAndrew Rist * or more contributor license agreements. See the NOTICE file
5*61dff127SAndrew Rist * distributed with this work for additional information
6*61dff127SAndrew Rist * regarding copyright ownership. The ASF licenses this file
7*61dff127SAndrew Rist * to you under the Apache License, Version 2.0 (the
8*61dff127SAndrew Rist * "License"); you may not use this file except in compliance
9*61dff127SAndrew Rist * with the License. You may obtain a copy of the License at
10cdf0e10cSrcweir *
11*61dff127SAndrew Rist * http://www.apache.org/licenses/LICENSE-2.0
12cdf0e10cSrcweir *
13*61dff127SAndrew Rist * Unless required by applicable law or agreed to in writing,
14*61dff127SAndrew Rist * software distributed under the License is distributed on an
15*61dff127SAndrew Rist * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16*61dff127SAndrew Rist * KIND, either express or implied. See the License for the
17*61dff127SAndrew Rist * specific language governing permissions and limitations
18*61dff127SAndrew Rist * under the License.
19cdf0e10cSrcweir *
20*61dff127SAndrew Rist *************************************************************/
21*61dff127SAndrew Rist
22*61dff127SAndrew Rist
23cdf0e10cSrcweir
24cdf0e10cSrcweir #include <malloc.h>
25cdf0e10cSrcweir #include <rtl/alloc.h>
26cdf0e10cSrcweir
27cdf0e10cSrcweir #include <com/sun/star/uno/genfunc.hxx>
28cdf0e10cSrcweir #include "com/sun/star/uno/RuntimeException.hpp"
29cdf0e10cSrcweir #include <uno/data.h>
30cdf0e10cSrcweir
31cdf0e10cSrcweir #include <bridges/cpp_uno/shared/bridge.hxx>
32cdf0e10cSrcweir #include <bridges/cpp_uno/shared/types.hxx>
33cdf0e10cSrcweir #include <bridges/cpp_uno/shared/unointerfaceproxy.hxx>
34cdf0e10cSrcweir #include <bridges/cpp_uno/shared/vtables.hxx>
35cdf0e10cSrcweir
36cdf0e10cSrcweir #include "share.hxx"
37cdf0e10cSrcweir
38cdf0e10cSrcweir #include <stdio.h>
39cdf0e10cSrcweir #include <string.h>
40cdf0e10cSrcweir
41cdf0e10cSrcweir /*
42cdf0e10cSrcweir * Based on http://gcc.gnu.org/PR41443
43cdf0e10cSrcweir * References to __SOFTFP__ are incorrect for EABI; the __SOFTFP__ code
44cdf0e10cSrcweir * should be used for *soft-float ABI* whether or not VFP is enabled,
45cdf0e10cSrcweir * and __SOFTFP__ does specifically mean soft-float not soft-float ABI.
46cdf0e10cSrcweir *
47cdf0e10cSrcweir * Changing the conditionals to __SOFTFP__ || __ARM_EABI__ then
48cdf0e10cSrcweir * -mfloat-abi=softfp should work. -mfloat-abi=hard won't; that would
49cdf0e10cSrcweir * need both a new macro to identify the hard-VFP ABI.
50cdf0e10cSrcweir */
51cdf0e10cSrcweir #if !defined(__ARM_EABI__) && !defined(__SOFTFP__)
52cdf0e10cSrcweir #error Not Implemented
53cdf0e10cSrcweir
54cdf0e10cSrcweir /*
55cdf0e10cSrcweir some possibly handy code to detect that we have VFP registers
56cdf0e10cSrcweir */
57cdf0e10cSrcweir
58cdf0e10cSrcweir #include <sys/types.h>
59cdf0e10cSrcweir #include <sys/stat.h>
60cdf0e10cSrcweir #include <fcntl.h>
61cdf0e10cSrcweir #include <unistd.h>
62cdf0e10cSrcweir #include <elf.h>
63cdf0e10cSrcweir
64cdf0e10cSrcweir #define HWCAP_ARM_VFP 64
65cdf0e10cSrcweir
hasVFP(void)66cdf0e10cSrcweir int hasVFP(void)
67cdf0e10cSrcweir {
68cdf0e10cSrcweir int fd = open ("/proc/self/auxv", O_RDONLY);
69cdf0e10cSrcweir if (fd == -1)
70cdf0e10cSrcweir return -1;
71cdf0e10cSrcweir
72cdf0e10cSrcweir int ret = -1;
73cdf0e10cSrcweir
74cdf0e10cSrcweir Elf32_auxv_t buf[128];
75cdf0e10cSrcweir ssize_t n;
76cdf0e10cSrcweir while ((ret == -1) && ((n = read(fd, buf, sizeof (buf))) > 0))
77cdf0e10cSrcweir {
78cdf0e10cSrcweir for (int i = 0; i < 128; ++i)
79cdf0e10cSrcweir {
80cdf0e10cSrcweir if (buf[i].a_type == AT_HWCAP)
81cdf0e10cSrcweir {
82cdf0e10cSrcweir ret = (buf[i].a_un.a_val & HWCAP_ARM_VFP) ? true : false;
83cdf0e10cSrcweir break;
84cdf0e10cSrcweir }
85cdf0e10cSrcweir else if (buf[i].a_type == AT_NULL)
86cdf0e10cSrcweir {
87cdf0e10cSrcweir ret = -2;
88cdf0e10cSrcweir break;
89cdf0e10cSrcweir }
90cdf0e10cSrcweir }
91cdf0e10cSrcweir }
92cdf0e10cSrcweir
93cdf0e10cSrcweir close (fd);
94cdf0e10cSrcweir return ret;
95cdf0e10cSrcweir }
96cdf0e10cSrcweir
97cdf0e10cSrcweir #endif
98cdf0e10cSrcweir
99cdf0e10cSrcweir using namespace ::rtl;
100cdf0e10cSrcweir using namespace ::com::sun::star::uno;
101cdf0e10cSrcweir
102cdf0e10cSrcweir namespace arm
103cdf0e10cSrcweir {
is_complex_struct(const typelib_TypeDescription * type)104cdf0e10cSrcweir bool is_complex_struct(const typelib_TypeDescription * type)
105cdf0e10cSrcweir {
106cdf0e10cSrcweir const typelib_CompoundTypeDescription * p
107cdf0e10cSrcweir = reinterpret_cast< const typelib_CompoundTypeDescription * >(type);
108cdf0e10cSrcweir for (sal_Int32 i = 0; i < p->nMembers; ++i)
109cdf0e10cSrcweir {
110cdf0e10cSrcweir if (p->ppTypeRefs[i]->eTypeClass == typelib_TypeClass_STRUCT ||
111cdf0e10cSrcweir p->ppTypeRefs[i]->eTypeClass == typelib_TypeClass_EXCEPTION)
112cdf0e10cSrcweir {
113cdf0e10cSrcweir typelib_TypeDescription * t = 0;
114cdf0e10cSrcweir TYPELIB_DANGER_GET(&t, p->ppTypeRefs[i]);
115cdf0e10cSrcweir bool b = is_complex_struct(t);
116cdf0e10cSrcweir TYPELIB_DANGER_RELEASE(t);
117cdf0e10cSrcweir if (b) {
118cdf0e10cSrcweir return true;
119cdf0e10cSrcweir }
120cdf0e10cSrcweir }
121cdf0e10cSrcweir else if (!bridges::cpp_uno::shared::isSimpleType(p->ppTypeRefs[i]->eTypeClass))
122cdf0e10cSrcweir return true;
123cdf0e10cSrcweir }
124cdf0e10cSrcweir if (p->pBaseTypeDescription != 0)
125cdf0e10cSrcweir return is_complex_struct(&p->pBaseTypeDescription->aBase);
126cdf0e10cSrcweir return false;
127cdf0e10cSrcweir }
128cdf0e10cSrcweir
return_in_hidden_param(typelib_TypeDescriptionReference * pTypeRef)129cdf0e10cSrcweir bool return_in_hidden_param( typelib_TypeDescriptionReference *pTypeRef )
130cdf0e10cSrcweir {
131cdf0e10cSrcweir if (bridges::cpp_uno::shared::isSimpleType(pTypeRef))
132cdf0e10cSrcweir return false;
133cdf0e10cSrcweir else if (pTypeRef->eTypeClass == typelib_TypeClass_STRUCT || pTypeRef->eTypeClass == typelib_TypeClass_EXCEPTION)
134cdf0e10cSrcweir {
135cdf0e10cSrcweir typelib_TypeDescription * pTypeDescr = 0;
136cdf0e10cSrcweir TYPELIB_DANGER_GET( &pTypeDescr, pTypeRef );
137cdf0e10cSrcweir
138cdf0e10cSrcweir //A Composite Type not larger than 4 bytes is returned in r0
139cdf0e10cSrcweir bool bRet = pTypeDescr->nSize > 4 || is_complex_struct(pTypeDescr);
140cdf0e10cSrcweir
141cdf0e10cSrcweir TYPELIB_DANGER_RELEASE( pTypeDescr );
142cdf0e10cSrcweir return bRet;
143cdf0e10cSrcweir }
144cdf0e10cSrcweir return true;
145cdf0e10cSrcweir }
146cdf0e10cSrcweir }
147cdf0e10cSrcweir
MapReturn(sal_uInt32 r0,sal_uInt32 r1,typelib_TypeDescriptionReference * pReturnType,sal_uInt32 * pRegisterReturn)148cdf0e10cSrcweir void MapReturn(sal_uInt32 r0, sal_uInt32 r1, typelib_TypeDescriptionReference * pReturnType, sal_uInt32* pRegisterReturn)
149cdf0e10cSrcweir {
150cdf0e10cSrcweir #if !defined(__ARM_EABI__) && !defined(__SOFTFP__)
151cdf0e10cSrcweir register float fret asm("f0");
152cdf0e10cSrcweir register double dret asm("f0");
153cdf0e10cSrcweir #endif
154cdf0e10cSrcweir
155cdf0e10cSrcweir switch( pReturnType->eTypeClass )
156cdf0e10cSrcweir {
157cdf0e10cSrcweir case typelib_TypeClass_HYPER:
158cdf0e10cSrcweir case typelib_TypeClass_UNSIGNED_HYPER:
159cdf0e10cSrcweir pRegisterReturn[1] = r1;
160cdf0e10cSrcweir case typelib_TypeClass_LONG:
161cdf0e10cSrcweir case typelib_TypeClass_UNSIGNED_LONG:
162cdf0e10cSrcweir case typelib_TypeClass_ENUM:
163cdf0e10cSrcweir case typelib_TypeClass_CHAR:
164cdf0e10cSrcweir case typelib_TypeClass_SHORT:
165cdf0e10cSrcweir case typelib_TypeClass_UNSIGNED_SHORT:
166cdf0e10cSrcweir case typelib_TypeClass_BOOLEAN:
167cdf0e10cSrcweir case typelib_TypeClass_BYTE:
168cdf0e10cSrcweir pRegisterReturn[0] = r0;
169cdf0e10cSrcweir break;
170cdf0e10cSrcweir case typelib_TypeClass_FLOAT:
171cdf0e10cSrcweir #if defined(__ARM_EABI__) || defined(__SOFTFP__)
172cdf0e10cSrcweir pRegisterReturn[0] = r0;
173cdf0e10cSrcweir #else
174cdf0e10cSrcweir *(float*)pRegisterReturn = fret;
175cdf0e10cSrcweir #endif
176cdf0e10cSrcweir break;
177cdf0e10cSrcweir case typelib_TypeClass_DOUBLE:
178cdf0e10cSrcweir #if defined(__ARM_EABI__) || defined(__SOFTFP__)
179cdf0e10cSrcweir pRegisterReturn[1] = r1;
180cdf0e10cSrcweir pRegisterReturn[0] = r0;
181cdf0e10cSrcweir #else
182cdf0e10cSrcweir *(double*)pRegisterReturn = dret;
183cdf0e10cSrcweir #endif
184cdf0e10cSrcweir break;
185cdf0e10cSrcweir case typelib_TypeClass_STRUCT:
186cdf0e10cSrcweir case typelib_TypeClass_EXCEPTION:
187cdf0e10cSrcweir {
188cdf0e10cSrcweir if (!arm::return_in_hidden_param(pReturnType))
189cdf0e10cSrcweir pRegisterReturn[0] = r0;
190cdf0e10cSrcweir break;
191cdf0e10cSrcweir }
192cdf0e10cSrcweir default:
193cdf0e10cSrcweir break;
194cdf0e10cSrcweir }
195cdf0e10cSrcweir }
196cdf0e10cSrcweir
197cdf0e10cSrcweir namespace
198cdf0e10cSrcweir {
199cdf0e10cSrcweir //================================================================
200cdf0e10cSrcweir
201cdf0e10cSrcweir void callVirtualMethod(
202cdf0e10cSrcweir void * pThis,
203cdf0e10cSrcweir sal_Int32 nVtableIndex,
204cdf0e10cSrcweir void * pRegisterReturn,
205cdf0e10cSrcweir typelib_TypeDescriptionReference * pReturnType,
206cdf0e10cSrcweir sal_uInt32 *pStack,
207cdf0e10cSrcweir sal_uInt32 nStack,
208cdf0e10cSrcweir sal_uInt32 *pGPR,
209cdf0e10cSrcweir sal_uInt32 nGPR) __attribute__((noinline));
210cdf0e10cSrcweir
callVirtualMethod(void * pThis,sal_Int32 nVtableIndex,void * pRegisterReturn,typelib_TypeDescriptionReference * pReturnType,sal_uInt32 * pStack,sal_uInt32 nStack,sal_uInt32 * pGPR,sal_uInt32 nGPR)211cdf0e10cSrcweir void callVirtualMethod(
212cdf0e10cSrcweir void * pThis,
213cdf0e10cSrcweir sal_Int32 nVtableIndex,
214cdf0e10cSrcweir void * pRegisterReturn,
215cdf0e10cSrcweir typelib_TypeDescriptionReference * pReturnType,
216cdf0e10cSrcweir sal_uInt32 *pStack,
217cdf0e10cSrcweir sal_uInt32 nStack,
218cdf0e10cSrcweir sal_uInt32 *pGPR,
219cdf0e10cSrcweir sal_uInt32 nGPR)
220cdf0e10cSrcweir {
221cdf0e10cSrcweir // never called
222cdf0e10cSrcweir if (! pThis)
223cdf0e10cSrcweir CPPU_CURRENT_NAMESPACE::dummy_can_throw_anything("xxx"); // address something
224cdf0e10cSrcweir
225cdf0e10cSrcweir if ( nStack )
226cdf0e10cSrcweir {
227cdf0e10cSrcweir // 8-bytes aligned
228cdf0e10cSrcweir sal_uInt32 nStackBytes = ( ( nStack + 1 ) >> 1 ) * 8;
229cdf0e10cSrcweir sal_uInt32 *stack = (sal_uInt32 *) __builtin_alloca( nStackBytes );
230cdf0e10cSrcweir memcpy( stack, pStack, nStackBytes );
231cdf0e10cSrcweir }
232cdf0e10cSrcweir
233cdf0e10cSrcweir // Should not happen, but...
234cdf0e10cSrcweir if ( nGPR > arm::MAX_GPR_REGS )
235cdf0e10cSrcweir nGPR = arm::MAX_GPR_REGS;
236cdf0e10cSrcweir
237cdf0e10cSrcweir sal_uInt32 pMethod = *((sal_uInt32*)pThis);
238cdf0e10cSrcweir pMethod += 4 * nVtableIndex;
239cdf0e10cSrcweir pMethod = *((sal_uInt32 *)pMethod);
240cdf0e10cSrcweir
241cdf0e10cSrcweir typedef void (*FunctionCall )( sal_uInt32, sal_uInt32, sal_uInt32, sal_uInt32);
242cdf0e10cSrcweir FunctionCall pFunc = (FunctionCall)pMethod;
243cdf0e10cSrcweir
244cdf0e10cSrcweir (*pFunc)(pGPR[0], pGPR[1], pGPR[2], pGPR[3]);
245cdf0e10cSrcweir
246cdf0e10cSrcweir sal_uInt32 r0;
247cdf0e10cSrcweir sal_uInt32 r1;
248cdf0e10cSrcweir
249cdf0e10cSrcweir // get return value
250cdf0e10cSrcweir __asm__ __volatile__ (
251cdf0e10cSrcweir "mov %0, r0\n\t"
252cdf0e10cSrcweir "mov %1, r1\n\t"
253cdf0e10cSrcweir : "=r" (r0), "=r" (r1) : );
254cdf0e10cSrcweir
255cdf0e10cSrcweir MapReturn(r0, r1, pReturnType, (sal_uInt32*)pRegisterReturn);
256cdf0e10cSrcweir }
257cdf0e10cSrcweir }
258cdf0e10cSrcweir
259cdf0e10cSrcweir #define INSERT_INT32( pSV, nr, pGPR, pDS, bOverflow ) \
260cdf0e10cSrcweir if ( nr < arm::MAX_GPR_REGS ) \
261cdf0e10cSrcweir pGPR[nr++] = *reinterpret_cast<sal_uInt32 *>( pSV ); \
262cdf0e10cSrcweir else \
263cdf0e10cSrcweir bOverFlow = true; \
264cdf0e10cSrcweir if (bOverFlow) \
265cdf0e10cSrcweir *pDS++ = *reinterpret_cast<sal_uInt32 *>( pSV );
266cdf0e10cSrcweir
267cdf0e10cSrcweir #ifdef __ARM_EABI__
268cdf0e10cSrcweir #define INSERT_INT64( pSV, nr, pGPR, pDS, pStart, bOverflow ) \
269cdf0e10cSrcweir if ( (nr < arm::MAX_GPR_REGS) && (nr % 2) ) \
270cdf0e10cSrcweir { \
271cdf0e10cSrcweir ++nr; \
272cdf0e10cSrcweir } \
273cdf0e10cSrcweir if ( nr < arm::MAX_GPR_REGS ) \
274cdf0e10cSrcweir { \
275cdf0e10cSrcweir pGPR[nr++] = *reinterpret_cast<sal_uInt32 *>( pSV ); \
276cdf0e10cSrcweir pGPR[nr++] = *(reinterpret_cast<sal_uInt32 *>( pSV ) + 1); \
277cdf0e10cSrcweir } \
278cdf0e10cSrcweir else \
279cdf0e10cSrcweir bOverFlow = true; \
280cdf0e10cSrcweir if (bOverFlow) \
281cdf0e10cSrcweir { \
282cdf0e10cSrcweir if ( (pDS - pStart) % 2) \
283cdf0e10cSrcweir { \
284cdf0e10cSrcweir ++pDS; \
285cdf0e10cSrcweir } \
286cdf0e10cSrcweir *pDS++ = reinterpret_cast<sal_uInt32 *>( pSV )[0]; \
287cdf0e10cSrcweir *pDS++ = reinterpret_cast<sal_uInt32 *>( pSV )[1]; \
288cdf0e10cSrcweir }
289cdf0e10cSrcweir #else
290cdf0e10cSrcweir #define INSERT_INT64( pSV, nr, pGPR, pDS, pStart, bOverflow ) \
291cdf0e10cSrcweir INSERT_INT32( pSV, nr, pGPR, pDS, bOverflow) \
292cdf0e10cSrcweir INSERT_INT32( ((sal_uInt32*)pSV)+1, nr, pGPR, pDS, bOverflow)
293cdf0e10cSrcweir #endif
294cdf0e10cSrcweir
295cdf0e10cSrcweir #define INSERT_FLOAT( pSV, nr, pFPR, pDS, bOverflow ) \
296cdf0e10cSrcweir INSERT_INT32( pSV, nr, pGPR, pDS, bOverflow)
297cdf0e10cSrcweir
298cdf0e10cSrcweir #define INSERT_DOUBLE( pSV, nr, pFPR, pDS, pStart, bOverflow ) \
299cdf0e10cSrcweir INSERT_INT64( pSV, nr, pGPR, pDS, pStart, bOverflow )
300cdf0e10cSrcweir
301cdf0e10cSrcweir #define INSERT_INT16( pSV, nr, pGPR, pDS, bOverflow ) \
302cdf0e10cSrcweir if ( nr < arm::MAX_GPR_REGS ) \
303cdf0e10cSrcweir pGPR[nr++] = *reinterpret_cast<sal_uInt16 *>( pSV ); \
304cdf0e10cSrcweir else \
305cdf0e10cSrcweir bOverFlow = true; \
306cdf0e10cSrcweir if (bOverFlow) \
307cdf0e10cSrcweir *pDS++ = *reinterpret_cast<sal_uInt16 *>( pSV );
308cdf0e10cSrcweir
309cdf0e10cSrcweir #define INSERT_INT8( pSV, nr, pGPR, pDS, bOverflow ) \
310cdf0e10cSrcweir if ( nr < arm::MAX_GPR_REGS ) \
311cdf0e10cSrcweir pGPR[nr++] = *reinterpret_cast<sal_uInt8 *>( pSV ); \
312cdf0e10cSrcweir else \
313cdf0e10cSrcweir bOverFlow = true; \
314cdf0e10cSrcweir if (bOverFlow) \
315cdf0e10cSrcweir *pDS++ = *reinterpret_cast<sal_uInt8 *>( pSV );
316cdf0e10cSrcweir
317cdf0e10cSrcweir namespace {
318cdf0e10cSrcweir //=======================================================================
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)319cdf0e10cSrcweir static void cpp_call(
320cdf0e10cSrcweir bridges::cpp_uno::shared::UnoInterfaceProxy * pThis,
321cdf0e10cSrcweir bridges::cpp_uno::shared::VtableSlot aVtableSlot,
322cdf0e10cSrcweir typelib_TypeDescriptionReference * pReturnTypeRef,
323cdf0e10cSrcweir sal_Int32 nParams, typelib_MethodParameter * pParams,
324cdf0e10cSrcweir void * pUnoReturn, void * pUnoArgs[], uno_Any ** ppUnoExc )
325cdf0e10cSrcweir {
326cdf0e10cSrcweir // max space for: [complex ret ptr], values|ptr ...
327cdf0e10cSrcweir sal_uInt32 * pStack = (sal_uInt32 *)__builtin_alloca(
328cdf0e10cSrcweir sizeof(sal_Int32) + ((nParams+2) * sizeof(sal_Int64)) );
329cdf0e10cSrcweir sal_uInt32 * pStackStart = pStack;
330cdf0e10cSrcweir
331cdf0e10cSrcweir sal_uInt32 pGPR[arm::MAX_GPR_REGS];
332cdf0e10cSrcweir sal_uInt32 nGPR = 0;
333cdf0e10cSrcweir
334cdf0e10cSrcweir // return
335cdf0e10cSrcweir typelib_TypeDescription * pReturnTypeDescr = 0;
336cdf0e10cSrcweir TYPELIB_DANGER_GET( &pReturnTypeDescr, pReturnTypeRef );
337cdf0e10cSrcweir OSL_ENSURE( pReturnTypeDescr, "### expected return type description!" );
338cdf0e10cSrcweir
339cdf0e10cSrcweir void * pCppReturn = 0; // if != 0 && != pUnoReturn, needs reconversion
340cdf0e10cSrcweir
341cdf0e10cSrcweir bool bOverFlow = false;
342cdf0e10cSrcweir bool bSimpleReturn = true;
343cdf0e10cSrcweir if (pReturnTypeDescr)
344cdf0e10cSrcweir {
345cdf0e10cSrcweir if (arm::return_in_hidden_param( pReturnTypeRef ) )
346cdf0e10cSrcweir bSimpleReturn = false;
347cdf0e10cSrcweir
348cdf0e10cSrcweir if (bSimpleReturn)
349cdf0e10cSrcweir pCppReturn = pUnoReturn; // direct way for simple types
350cdf0e10cSrcweir else
351cdf0e10cSrcweir {
352cdf0e10cSrcweir // complex return via ptr
353cdf0e10cSrcweir pCppReturn = (bridges::cpp_uno::shared::relatesToInterfaceType( pReturnTypeDescr )
354cdf0e10cSrcweir ? __builtin_alloca( pReturnTypeDescr->nSize )
355cdf0e10cSrcweir : pUnoReturn); // direct way
356cdf0e10cSrcweir
357cdf0e10cSrcweir INSERT_INT32( &pCppReturn, nGPR, pGPR, pStack, bOverFlow );
358cdf0e10cSrcweir }
359cdf0e10cSrcweir }
360cdf0e10cSrcweir // push this
361cdf0e10cSrcweir void * pAdjustedThisPtr = reinterpret_cast< void ** >(pThis->getCppI())
362cdf0e10cSrcweir + aVtableSlot.offset;
363cdf0e10cSrcweir INSERT_INT32( &pAdjustedThisPtr, nGPR, pGPR, pStack, bOverFlow );
364cdf0e10cSrcweir
365cdf0e10cSrcweir // stack space
366cdf0e10cSrcweir OSL_ENSURE( sizeof(void *) == sizeof(sal_Int32), "### unexpected size!" );
367cdf0e10cSrcweir // args
368cdf0e10cSrcweir void ** pCppArgs = (void **)alloca( 3 * sizeof(void *) * nParams );
369cdf0e10cSrcweir // indizes of values this have to be converted (interface conversion cpp<=>uno)
370cdf0e10cSrcweir sal_Int32 * pTempIndizes = (sal_Int32 *)(pCppArgs + nParams);
371cdf0e10cSrcweir // type descriptions for reconversions
372cdf0e10cSrcweir typelib_TypeDescription ** ppTempParamTypeDescr = (typelib_TypeDescription **)(pCppArgs + (2 * nParams));
373cdf0e10cSrcweir
374cdf0e10cSrcweir sal_Int32 nTempIndizes = 0;
375cdf0e10cSrcweir
376cdf0e10cSrcweir for ( sal_Int32 nPos = 0; nPos < nParams; ++nPos )
377cdf0e10cSrcweir {
378cdf0e10cSrcweir const typelib_MethodParameter & rParam = pParams[nPos];
379cdf0e10cSrcweir typelib_TypeDescription * pParamTypeDescr = 0;
380cdf0e10cSrcweir TYPELIB_DANGER_GET( &pParamTypeDescr, rParam.pTypeRef );
381cdf0e10cSrcweir
382cdf0e10cSrcweir if (!rParam.bOut && bridges::cpp_uno::shared::isSimpleType( pParamTypeDescr ))
383cdf0e10cSrcweir {
384cdf0e10cSrcweir // uno_copyAndConvertData( pCppArgs[nPos] = pStack, pUnoArgs[nPos],
385cdf0e10cSrcweir uno_copyAndConvertData( pCppArgs[nPos] = alloca(8), pUnoArgs[nPos],
386cdf0e10cSrcweir pParamTypeDescr, pThis->getBridge()->getUno2Cpp() );
387cdf0e10cSrcweir
388cdf0e10cSrcweir switch (pParamTypeDescr->eTypeClass)
389cdf0e10cSrcweir {
390cdf0e10cSrcweir case typelib_TypeClass_HYPER:
391cdf0e10cSrcweir case typelib_TypeClass_UNSIGNED_HYPER:
392cdf0e10cSrcweir #ifdef CMC_DEBUG
393cdf0e10cSrcweir fprintf(stderr, "hyper is %lx\n", pCppArgs[nPos]);
394cdf0e10cSrcweir #endif
395cdf0e10cSrcweir INSERT_INT64( pCppArgs[nPos], nGPR, pGPR, pStack, pStackStart, bOverFlow );
396cdf0e10cSrcweir break;
397cdf0e10cSrcweir case typelib_TypeClass_LONG:
398cdf0e10cSrcweir case typelib_TypeClass_UNSIGNED_LONG:
399cdf0e10cSrcweir case typelib_TypeClass_ENUM:
400cdf0e10cSrcweir #ifdef CMC_DEBUG
401cdf0e10cSrcweir fprintf(stderr, "long is %x\n", pCppArgs[nPos]);
402cdf0e10cSrcweir #endif
403cdf0e10cSrcweir INSERT_INT32( pCppArgs[nPos], nGPR, pGPR, pStack, bOverFlow );
404cdf0e10cSrcweir break;
405cdf0e10cSrcweir case typelib_TypeClass_SHORT:
406cdf0e10cSrcweir case typelib_TypeClass_CHAR:
407cdf0e10cSrcweir case typelib_TypeClass_UNSIGNED_SHORT:
408cdf0e10cSrcweir INSERT_INT16( pCppArgs[nPos], nGPR, pGPR, pStack, bOverFlow );
409cdf0e10cSrcweir break;
410cdf0e10cSrcweir case typelib_TypeClass_BOOLEAN:
411cdf0e10cSrcweir case typelib_TypeClass_BYTE:
412cdf0e10cSrcweir INSERT_INT8( pCppArgs[nPos], nGPR, pGPR, pStack, bOverFlow );
413cdf0e10cSrcweir break;
414cdf0e10cSrcweir case typelib_TypeClass_FLOAT:
415cdf0e10cSrcweir INSERT_FLOAT( pCppArgs[nPos], nGPR, pGPR, pStack, bOverFlow );
416cdf0e10cSrcweir break;
417cdf0e10cSrcweir case typelib_TypeClass_DOUBLE:
418cdf0e10cSrcweir INSERT_DOUBLE( pCppArgs[nPos], nGPR, pGPR, pStack, pStackStart, bOverFlow );
419cdf0e10cSrcweir break;
420cdf0e10cSrcweir default:
421cdf0e10cSrcweir break;
422cdf0e10cSrcweir }
423cdf0e10cSrcweir // no longer needed
424cdf0e10cSrcweir TYPELIB_DANGER_RELEASE( pParamTypeDescr );
425cdf0e10cSrcweir }
426cdf0e10cSrcweir else // ptr to complex value | ref
427cdf0e10cSrcweir {
428cdf0e10cSrcweir if (! rParam.bIn) // is pure out
429cdf0e10cSrcweir {
430cdf0e10cSrcweir // cpp out is constructed mem, uno out is not!
431cdf0e10cSrcweir uno_constructData(
432cdf0e10cSrcweir pCppArgs[nPos] = alloca( pParamTypeDescr->nSize ),
433cdf0e10cSrcweir pParamTypeDescr );
434cdf0e10cSrcweir pTempIndizes[nTempIndizes] = nPos; // default constructed for cpp call
435cdf0e10cSrcweir // will be released at reconversion
436cdf0e10cSrcweir ppTempParamTypeDescr[nTempIndizes++] = pParamTypeDescr;
437cdf0e10cSrcweir }
438cdf0e10cSrcweir // is in/inout
439cdf0e10cSrcweir else if (bridges::cpp_uno::shared::relatesToInterfaceType( pParamTypeDescr ))
440cdf0e10cSrcweir {
441cdf0e10cSrcweir uno_copyAndConvertData(
442cdf0e10cSrcweir pCppArgs[nPos] = alloca( pParamTypeDescr->nSize ),
443cdf0e10cSrcweir pUnoArgs[nPos], pParamTypeDescr, pThis->getBridge()->getUno2Cpp() );
444cdf0e10cSrcweir
445cdf0e10cSrcweir pTempIndizes[nTempIndizes] = nPos; // has to be reconverted
446cdf0e10cSrcweir // will be released at reconversion
447cdf0e10cSrcweir ppTempParamTypeDescr[nTempIndizes++] = pParamTypeDescr;
448cdf0e10cSrcweir }
449cdf0e10cSrcweir else // direct way
450cdf0e10cSrcweir {
451cdf0e10cSrcweir pCppArgs[nPos] = pUnoArgs[nPos];
452cdf0e10cSrcweir // no longer needed
453cdf0e10cSrcweir TYPELIB_DANGER_RELEASE( pParamTypeDescr );
454cdf0e10cSrcweir }
455cdf0e10cSrcweir INSERT_INT32( &(pCppArgs[nPos]), nGPR, pGPR, pStack, bOverFlow );
456cdf0e10cSrcweir }
457cdf0e10cSrcweir }
458cdf0e10cSrcweir
459cdf0e10cSrcweir try
460cdf0e10cSrcweir {
461cdf0e10cSrcweir callVirtualMethod(
462cdf0e10cSrcweir pAdjustedThisPtr, aVtableSlot.index,
463cdf0e10cSrcweir pCppReturn, pReturnTypeRef,
464cdf0e10cSrcweir pStackStart,
465cdf0e10cSrcweir (pStack - pStackStart),
466cdf0e10cSrcweir pGPR, nGPR);
467cdf0e10cSrcweir
468cdf0e10cSrcweir // NO exception occured...
469cdf0e10cSrcweir *ppUnoExc = 0;
470cdf0e10cSrcweir
471cdf0e10cSrcweir // reconvert temporary params
472cdf0e10cSrcweir for ( ; nTempIndizes--; )
473cdf0e10cSrcweir {
474cdf0e10cSrcweir sal_Int32 nIndex = pTempIndizes[nTempIndizes];
475cdf0e10cSrcweir typelib_TypeDescription * pParamTypeDescr = ppTempParamTypeDescr[nTempIndizes];
476cdf0e10cSrcweir
477cdf0e10cSrcweir if (pParams[nIndex].bIn)
478cdf0e10cSrcweir {
479cdf0e10cSrcweir if (pParams[nIndex].bOut) // inout
480cdf0e10cSrcweir {
481cdf0e10cSrcweir uno_destructData( pUnoArgs[nIndex], pParamTypeDescr, 0 ); // destroy uno value
482cdf0e10cSrcweir uno_copyAndConvertData( pUnoArgs[nIndex], pCppArgs[nIndex], pParamTypeDescr,
483cdf0e10cSrcweir pThis->getBridge()->getCpp2Uno() );
484cdf0e10cSrcweir }
485cdf0e10cSrcweir }
486cdf0e10cSrcweir else // pure out
487cdf0e10cSrcweir {
488cdf0e10cSrcweir uno_copyAndConvertData( pUnoArgs[nIndex], pCppArgs[nIndex], pParamTypeDescr,
489cdf0e10cSrcweir pThis->getBridge()->getCpp2Uno() );
490cdf0e10cSrcweir }
491cdf0e10cSrcweir // destroy temp cpp param => cpp: every param was constructed
492cdf0e10cSrcweir uno_destructData( pCppArgs[nIndex], pParamTypeDescr, cpp_release );
493cdf0e10cSrcweir
494cdf0e10cSrcweir TYPELIB_DANGER_RELEASE( pParamTypeDescr );
495cdf0e10cSrcweir }
496cdf0e10cSrcweir // return value
497cdf0e10cSrcweir if (pCppReturn && pUnoReturn != pCppReturn)
498cdf0e10cSrcweir {
499cdf0e10cSrcweir uno_copyAndConvertData( pUnoReturn, pCppReturn, pReturnTypeDescr,
500cdf0e10cSrcweir pThis->getBridge()->getCpp2Uno() );
501cdf0e10cSrcweir uno_destructData( pCppReturn, pReturnTypeDescr, cpp_release );
502cdf0e10cSrcweir }
503cdf0e10cSrcweir }
504cdf0e10cSrcweir catch (...)
505cdf0e10cSrcweir {
506cdf0e10cSrcweir // __asm__ __volatile__ ("sub sp, sp, #2048\n");
507cdf0e10cSrcweir
508cdf0e10cSrcweir // fill uno exception
509cdf0e10cSrcweir fillUnoException( CPPU_CURRENT_NAMESPACE::__cxa_get_globals()->caughtExceptions, *ppUnoExc, pThis->getBridge()->getCpp2Uno() );
510cdf0e10cSrcweir
511cdf0e10cSrcweir // temporary params
512cdf0e10cSrcweir for ( ; nTempIndizes--; )
513cdf0e10cSrcweir {
514cdf0e10cSrcweir sal_Int32 nIndex = pTempIndizes[nTempIndizes];
515cdf0e10cSrcweir // destroy temp cpp param => cpp: every param was constructed
516cdf0e10cSrcweir uno_destructData( pCppArgs[nIndex], ppTempParamTypeDescr[nTempIndizes], cpp_release );
517cdf0e10cSrcweir TYPELIB_DANGER_RELEASE( ppTempParamTypeDescr[nTempIndizes] );
518cdf0e10cSrcweir }
519cdf0e10cSrcweir
520cdf0e10cSrcweir // return type
521cdf0e10cSrcweir if (pReturnTypeDescr)
522cdf0e10cSrcweir TYPELIB_DANGER_RELEASE( pReturnTypeDescr );
523cdf0e10cSrcweir }
524cdf0e10cSrcweir }
525cdf0e10cSrcweir }
526cdf0e10cSrcweir
527cdf0e10cSrcweir namespace bridges { namespace cpp_uno { namespace shared {
528cdf0e10cSrcweir
unoInterfaceProxyDispatch(uno_Interface * pUnoI,const typelib_TypeDescription * pMemberDescr,void * pReturn,void * pArgs[],uno_Any ** ppException)529cdf0e10cSrcweir void unoInterfaceProxyDispatch(
530cdf0e10cSrcweir uno_Interface * pUnoI, const typelib_TypeDescription * pMemberDescr,
531cdf0e10cSrcweir void * pReturn, void * pArgs[], uno_Any ** ppException )
532cdf0e10cSrcweir {
533cdf0e10cSrcweir // is my surrogate
534cdf0e10cSrcweir bridges::cpp_uno::shared::UnoInterfaceProxy * pThis
535cdf0e10cSrcweir = static_cast< bridges::cpp_uno::shared::UnoInterfaceProxy * >(pUnoI);
536cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 0
537cdf0e10cSrcweir typelib_InterfaceTypeDescription * pTypeDescr = pThis->pTypeDescr;
538cdf0e10cSrcweir #endif
539cdf0e10cSrcweir
540cdf0e10cSrcweir switch (pMemberDescr->eTypeClass)
541cdf0e10cSrcweir {
542cdf0e10cSrcweir case typelib_TypeClass_INTERFACE_ATTRIBUTE:
543cdf0e10cSrcweir {
544cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 0
545cdf0e10cSrcweir // determine vtable call index
546cdf0e10cSrcweir sal_Int32 nMemberPos = ((typelib_InterfaceMemberTypeDescription *)pMemberDescr)->nPosition;
547cdf0e10cSrcweir OSL_ENSURE( nMemberPos < pTypeDescr->nAllMembers, "### member pos out of range!" );
548cdf0e10cSrcweir #endif
549cdf0e10cSrcweir
550cdf0e10cSrcweir VtableSlot aVtableSlot(
551cdf0e10cSrcweir getVtableSlot(
552cdf0e10cSrcweir reinterpret_cast<typelib_InterfaceAttributeTypeDescription const *>
553cdf0e10cSrcweir (pMemberDescr)));
554cdf0e10cSrcweir
555cdf0e10cSrcweir if (pReturn)
556cdf0e10cSrcweir {
557cdf0e10cSrcweir // dependent dispatch
558cdf0e10cSrcweir cpp_call(
559cdf0e10cSrcweir pThis, aVtableSlot,
560cdf0e10cSrcweir ((typelib_InterfaceAttributeTypeDescription *)pMemberDescr)->pAttributeTypeRef,
561cdf0e10cSrcweir 0, 0, // no params
562cdf0e10cSrcweir pReturn, pArgs, ppException );
563cdf0e10cSrcweir }
564cdf0e10cSrcweir else
565cdf0e10cSrcweir {
566cdf0e10cSrcweir // is SET
567cdf0e10cSrcweir typelib_MethodParameter aParam;
568cdf0e10cSrcweir aParam.pTypeRef =
569cdf0e10cSrcweir ((typelib_InterfaceAttributeTypeDescription *)pMemberDescr)->pAttributeTypeRef;
570cdf0e10cSrcweir aParam.bIn = sal_True;
571cdf0e10cSrcweir aParam.bOut = sal_False;
572cdf0e10cSrcweir
573cdf0e10cSrcweir typelib_TypeDescriptionReference * pReturnTypeRef = 0;
574cdf0e10cSrcweir OUString aVoidName( RTL_CONSTASCII_USTRINGPARAM("void") );
575cdf0e10cSrcweir typelib_typedescriptionreference_new(
576cdf0e10cSrcweir &pReturnTypeRef, typelib_TypeClass_VOID, aVoidName.pData );
577cdf0e10cSrcweir
578cdf0e10cSrcweir // dependent dispatch
579cdf0e10cSrcweir aVtableSlot.index += 1;
580cdf0e10cSrcweir cpp_call(
581cdf0e10cSrcweir pThis, aVtableSlot, // get, then set method
582cdf0e10cSrcweir pReturnTypeRef,
583cdf0e10cSrcweir 1, &aParam,
584cdf0e10cSrcweir pReturn, pArgs, ppException );
585cdf0e10cSrcweir
586cdf0e10cSrcweir typelib_typedescriptionreference_release( pReturnTypeRef );
587cdf0e10cSrcweir }
588cdf0e10cSrcweir
589cdf0e10cSrcweir break;
590cdf0e10cSrcweir }
591cdf0e10cSrcweir case typelib_TypeClass_INTERFACE_METHOD:
592cdf0e10cSrcweir {
593cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 0
594cdf0e10cSrcweir // determine vtable call index
595cdf0e10cSrcweir sal_Int32 nMemberPos = ((typelib_InterfaceMemberTypeDescription *)pMemberDescr)->nPosition;
596cdf0e10cSrcweir OSL_ENSURE( nMemberPos < pTypeDescr->nAllMembers, "### member pos out of range!" );
597cdf0e10cSrcweir #endif
598cdf0e10cSrcweir
599cdf0e10cSrcweir VtableSlot aVtableSlot(
600cdf0e10cSrcweir getVtableSlot(
601cdf0e10cSrcweir reinterpret_cast<typelib_InterfaceMethodTypeDescription const *>
602cdf0e10cSrcweir (pMemberDescr)));
603cdf0e10cSrcweir
604cdf0e10cSrcweir switch (aVtableSlot.index)
605cdf0e10cSrcweir {
606cdf0e10cSrcweir // standard calls
607cdf0e10cSrcweir case 1: // acquire uno interface
608cdf0e10cSrcweir (*pUnoI->acquire)( pUnoI );
609cdf0e10cSrcweir *ppException = 0;
610cdf0e10cSrcweir break;
611cdf0e10cSrcweir case 2: // release uno interface
612cdf0e10cSrcweir (*pUnoI->release)( pUnoI );
613cdf0e10cSrcweir *ppException = 0;
614cdf0e10cSrcweir break;
615cdf0e10cSrcweir case 0: // queryInterface() opt
616cdf0e10cSrcweir {
617cdf0e10cSrcweir typelib_TypeDescription * pTD = 0;
618cdf0e10cSrcweir TYPELIB_DANGER_GET( &pTD, reinterpret_cast< Type * >( pArgs[0] )->getTypeLibType() );
619cdf0e10cSrcweir if (pTD)
620cdf0e10cSrcweir {
621cdf0e10cSrcweir uno_Interface * pInterface = 0;
622cdf0e10cSrcweir (*pThis->getBridge()->getUnoEnv()->getRegisteredInterface)(
623cdf0e10cSrcweir pThis->getBridge()->getUnoEnv(),
624cdf0e10cSrcweir (void **)&pInterface, pThis->oid.pData, (typelib_InterfaceTypeDescription *)pTD );
625cdf0e10cSrcweir
626cdf0e10cSrcweir if (pInterface)
627cdf0e10cSrcweir {
628cdf0e10cSrcweir ::uno_any_construct(
629cdf0e10cSrcweir reinterpret_cast< uno_Any * >( pReturn ),
630cdf0e10cSrcweir &pInterface, pTD, 0 );
631cdf0e10cSrcweir (*pInterface->release)( pInterface );
632cdf0e10cSrcweir TYPELIB_DANGER_RELEASE( pTD );
633cdf0e10cSrcweir *ppException = 0;
634cdf0e10cSrcweir break;
635cdf0e10cSrcweir }
636cdf0e10cSrcweir TYPELIB_DANGER_RELEASE( pTD );
637cdf0e10cSrcweir }
638cdf0e10cSrcweir } // else perform queryInterface()
639cdf0e10cSrcweir default:
640cdf0e10cSrcweir // dependent dispatch
641cdf0e10cSrcweir cpp_call(
642cdf0e10cSrcweir pThis, aVtableSlot,
643cdf0e10cSrcweir ((typelib_InterfaceMethodTypeDescription *)pMemberDescr)->pReturnTypeRef,
644cdf0e10cSrcweir ((typelib_InterfaceMethodTypeDescription *)pMemberDescr)->nParams,
645cdf0e10cSrcweir ((typelib_InterfaceMethodTypeDescription *)pMemberDescr)->pParams,
646cdf0e10cSrcweir pReturn, pArgs, ppException );
647cdf0e10cSrcweir }
648cdf0e10cSrcweir break;
649cdf0e10cSrcweir }
650cdf0e10cSrcweir default:
651cdf0e10cSrcweir {
652cdf0e10cSrcweir ::com::sun::star::uno::RuntimeException aExc(
653cdf0e10cSrcweir OUString( RTL_CONSTASCII_USTRINGPARAM("illegal member type description!") ),
654cdf0e10cSrcweir ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >() );
655cdf0e10cSrcweir
656cdf0e10cSrcweir Type const & rExcType = ::getCppuType( &aExc );
657cdf0e10cSrcweir // binary identical null reference
658cdf0e10cSrcweir ::uno_type_any_construct( *ppException, &aExc, rExcType.getTypeLibType(), 0 );
659cdf0e10cSrcweir }
660cdf0e10cSrcweir }
661cdf0e10cSrcweir }
662cdf0e10cSrcweir
663cdf0e10cSrcweir } } }
664cdf0e10cSrcweir
665cdf0e10cSrcweir /* vi:set tabstop=4 shiftwidth=4 expandtab: */
666