1 /**************************************************************
2 *
3 * Licensed to the Apache Software Foundation (ASF) under one
4 * or more contributor license agreements. See the NOTICE file
5 * distributed with this work for additional information
6 * regarding copyright ownership. The ASF licenses this file
7 * to you under the Apache License, Version 2.0 (the
8 * "License"); you may not use this file except in compliance
9 * with the License. You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing,
14 * software distributed under the License is distributed on an
15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16 * KIND, either express or implied. See the License for the
17 * specific language governing permissions and limitations
18 * under the License.
19 *
20 *************************************************************/
21
22
23
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_bridges.hxx"
26
27 #include <stdlib.h>
28
29 #include <exception>
30 #include <malloc.h>
31 #include <typeinfo>
32
33 #include <com/sun/star/uno/Exception.hpp>
34 #include <com/sun/star/uno/RuntimeException.hpp>
35 #include <com/sun/star/uno/genfunc.hxx>
36 #include <osl/endian.h>
37 #include <uno/data.h>
38
39 #include "bridges/cpp_uno/shared/bridge.hxx"
40 #include "bridges/cpp_uno/shared/types.hxx"
41 #include "bridges/cpp_uno/shared/unointerfaceproxy.hxx"
42 #include "bridges/cpp_uno/shared/vtables.hxx"
43
44 #include "share.hxx"
45
46 #include <stdio.h>
47 #include <string.h>
48
49
50 using namespace ::rtl;
51 using namespace ::com::sun::star::uno;
52 #ifdef __GLIBCXX__
53 using CPPU_CURRENT_NAMESPACE::__cxa_exception;
54 using CPPU_CURRENT_NAMESPACE::__cxa_get_globals;
55 #else
56 using __cxxabiv1::__cxa_exception;
57 using __cxxabiv1::__cxa_current_primary_exception;
58 using __cxxabiv1::__cxa_decrement_exception_refcount;
59 #endif
60
61 namespace ppc64
62 {
63 #if defined(_CALL_ELF) && _CALL_ELF == 2
is_complex_struct(const typelib_TypeDescription * type)64 bool is_complex_struct(const typelib_TypeDescription * type)
65 {
66 const typelib_CompoundTypeDescription * p
67 = reinterpret_cast< const typelib_CompoundTypeDescription * >(type);
68 for (sal_Int32 i = 0; i < p->nMembers; ++i)
69 {
70 if (p->ppTypeRefs[i]->eTypeClass == typelib_TypeClass_STRUCT ||
71 p->ppTypeRefs[i]->eTypeClass == typelib_TypeClass_EXCEPTION)
72 {
73 typelib_TypeDescription * t = 0;
74 TYPELIB_DANGER_GET(&t, p->ppTypeRefs[i]);
75 bool b = is_complex_struct(t);
76 TYPELIB_DANGER_RELEASE(t);
77 if (b) {
78 return true;
79 }
80 }
81 else if (!bridges::cpp_uno::shared::isSimpleType(p->ppTypeRefs[i]->eTypeClass))
82 return true;
83 }
84 if (p->pBaseTypeDescription != 0)
85 return is_complex_struct(&p->pBaseTypeDescription->aBase);
86 return false;
87 }
88
collect_fpr_members(const typelib_TypeDescription * type,typelib_TypeClass & eBase,sal_Int32 & nMembers)89 static bool collect_fpr_members(const typelib_TypeDescription * type,
90 typelib_TypeClass & eBase, sal_Int32 & nMembers)
91 {
92 const typelib_CompoundTypeDescription * p
93 = reinterpret_cast< const typelib_CompoundTypeDescription * >(type);
94 if (p->pBaseTypeDescription != 0
95 && !collect_fpr_members(&p->pBaseTypeDescription->aBase, eBase, nMembers))
96 return false;
97 for (sal_Int32 i = 0; i < p->nMembers; ++i)
98 {
99 typelib_TypeClass eClass = p->ppTypeRefs[i]->eTypeClass;
100 if (eClass == typelib_TypeClass_STRUCT)
101 {
102 typelib_TypeDescription * t = 0;
103 TYPELIB_DANGER_GET(&t, p->ppTypeRefs[i]);
104 bool b = collect_fpr_members(t, eBase, nMembers);
105 TYPELIB_DANGER_RELEASE(t);
106 if (!b)
107 return false;
108 }
109 else if (eClass == typelib_TypeClass_FLOAT || eClass == typelib_TypeClass_DOUBLE)
110 {
111 if (eBase == typelib_TypeClass_VOID)
112 eBase = eClass;
113 else if (eBase != eClass)
114 return false;
115 ++nMembers;
116 }
117 else
118 return false;
119 }
120 return true;
121 }
122 #endif
123
return_in_fprs(typelib_TypeDescriptionReference * pTypeRef,typelib_TypeClass & eBase)124 sal_Int32 return_in_fprs( typelib_TypeDescriptionReference *pTypeRef, typelib_TypeClass & eBase )
125 {
126 eBase = typelib_TypeClass_VOID;
127 #if defined(_CALL_ELF) && _CALL_ELF == 2
128 if (pTypeRef->eTypeClass == typelib_TypeClass_STRUCT)
129 {
130 typelib_TypeDescription * pTypeDescr = 0;
131 TYPELIB_DANGER_GET( &pTypeDescr, pTypeRef );
132 sal_Int32 nMembers = 0;
133 if (!collect_fpr_members(pTypeDescr, eBase, nMembers) || nMembers > 8)
134 nMembers = 0;
135 TYPELIB_DANGER_RELEASE( pTypeDescr );
136 return nMembers;
137 }
138 #else
139 (void)pTypeRef;
140 #endif
141 return 0;
142 }
143
return_in_hidden_param(typelib_TypeDescriptionReference * pTypeRef)144 bool return_in_hidden_param( typelib_TypeDescriptionReference *pTypeRef )
145 {
146 if (bridges::cpp_uno::shared::isSimpleType(pTypeRef))
147 return false;
148 #if defined(_CALL_ELF) && _CALL_ELF == 2
149 else if (pTypeRef->eTypeClass == typelib_TypeClass_STRUCT || pTypeRef->eTypeClass == typelib_TypeClass_EXCEPTION)
150 {
151 typelib_TypeClass eBase;
152 if (return_in_fprs(pTypeRef, eBase) != 0)
153 return false;
154
155 typelib_TypeDescription * pTypeDescr = 0;
156 TYPELIB_DANGER_GET( &pTypeDescr, pTypeRef );
157
158 //A Composite Type not larger than 16 bytes is returned in up to two GPRs
159 bool bRet = pTypeDescr->nSize > 16 || is_complex_struct(pTypeDescr);
160
161 TYPELIB_DANGER_RELEASE( pTypeDescr );
162 return bRet;
163 }
164 #endif
165 return true;
166 }
167 }
168
MapReturn(long r3,long r4,typelib_TypeDescriptionReference * pReturnType,void * pRegisterReturn,double dret,double f2,double f3,double f4,double f5,double f6,double f7,double f8)169 extern "C" void MapReturn(long r3, long r4, typelib_TypeDescriptionReference* pReturnType, void *pRegisterReturn,
170 double dret, double f2, double f3, double f4, double f5, double f6, double f7, double f8)
171 {
172 switch (pReturnType->eTypeClass)
173 {
174 case typelib_TypeClass_HYPER:
175 case typelib_TypeClass_UNSIGNED_HYPER:
176 *reinterpret_cast<sal_uInt64 *>( pRegisterReturn ) = r3;
177 break;
178 case typelib_TypeClass_LONG:
179 case typelib_TypeClass_UNSIGNED_LONG:
180 case typelib_TypeClass_ENUM:
181 *reinterpret_cast<sal_uInt32 *>( pRegisterReturn ) = r3;
182 break;
183 case typelib_TypeClass_CHAR:
184 case typelib_TypeClass_SHORT:
185 case typelib_TypeClass_UNSIGNED_SHORT:
186 *reinterpret_cast<sal_uInt16 *>( pRegisterReturn ) = (unsigned short)r3;
187 break;
188 case typelib_TypeClass_BOOLEAN:
189 case typelib_TypeClass_BYTE:
190 *reinterpret_cast<sal_uInt8 *>( pRegisterReturn ) = (unsigned char)r3;
191 break;
192 case typelib_TypeClass_FLOAT:
193 *reinterpret_cast<float *>( pRegisterReturn ) = dret;
194 break;
195 case typelib_TypeClass_DOUBLE:
196 *reinterpret_cast<double *>( pRegisterReturn ) = dret;
197 break;
198 #if defined(_CALL_ELF) && _CALL_ELF == 2
199 case typelib_TypeClass_STRUCT:
200 case typelib_TypeClass_EXCEPTION:
201 {
202 typelib_TypeClass eBase;
203 sal_Int32 nMembers = ppc64::return_in_fprs(pReturnType, eBase);
204 if (nMembers != 0)
205 {
206 const double fpr[8] = { dret, f2, f3, f4, f5, f6, f7, f8 };
207 for (sal_Int32 i = 0; i < nMembers; ++i)
208 {
209 if (eBase == typelib_TypeClass_FLOAT)
210 reinterpret_cast<float *>( pRegisterReturn )[i] = fpr[i];
211 else
212 reinterpret_cast<double *>( pRegisterReturn )[i] = fpr[i];
213 }
214 }
215 else if (!ppc64::return_in_hidden_param(pReturnType))
216 {
217 char *p = reinterpret_cast<char *>(pRegisterReturn);
218 sal_Int32 nSize = pReturnType->pType->nSize;
219 if (nSize > 8)
220 {
221 memcpy(p, &r3, 8);
222 memcpy(p + 8, &r4, nSize - 8);
223 }
224 else
225 #ifdef OSL_BIGENDIAN
226 memcpy(p, reinterpret_cast<char *>(&r3) + 8 - nSize, nSize);
227 #else
228 memcpy(p, &r3, nSize);
229 #endif
230 }
231 }
232 break;
233 #else
234 (void)r4;
235 (void)f2; (void)f3; (void)f4; (void)f5; (void)f6; (void)f7; (void)f8;
236 #endif
237 default:
238 break;
239 }
240 }
241
242 namespace
243 {
244 //==================================================================================================
245 extern "C" void callVirtualMethod(void * pThis, sal_uInt32 nVtableIndex,
246 void * pRegisterReturn, typelib_TypeDescription * pReturnTypeDescr,
247 sal_uInt64 *pStack, sal_uInt32 nStack,
248 sal_uInt64 *pGPR, sal_uInt32 nGPR,
249 double *pFPR, sal_uInt32 nFPR);
250
251 #if 0
252 {
253 // Stack, if used, must be 16-bytes aligned
254 if ( nStack )
255 nStack = ( nStack + 1 ) & ~1;
256
257 // Should not happen, but...
258 if ( nFPR > ppc64::MAX_SSE_REGS )
259 nFPR = ppc64::MAX_SSE_REGS;
260 if ( nGPR > ppc64::MAX_GPR_REGS )
261 nGPR = ppc64::MAX_GPR_REGS;
262
263 #ifdef CMC_DEBUG
264 // Let's figure out what is really going on here
265 {
266 fprintf( stderr, "= callVirtualMethod() =\nGPR's (%d): ", nGPR );
267 for ( sal_uInt32 i = 0; i < nGPR; ++i )
268 fprintf( stderr, "0x%lx, ", pGPR[i] );
269 fprintf( stderr, "\nFPR's (%d): ", nFPR );
270 for ( sal_uInt32 i = 0; i < nFPR; ++i )
271 fprintf( stderr, "0x%lx (%lf), ", (sal_Int64)pFPR[i], pFPR[i] );
272 fprintf( stderr, "\nStack (%d): ", nStack );
273 for ( sal_uInt32 i = 0; i < nStack; ++i )
274 fprintf( stderr, "0x%lx, ", pStack[i] );
275 fprintf( stderr, "\n" );
276 }
277 #endif
278
279 // Load parameters to stack, if necessary
280 sal_uInt64 *stack = (sal_uInt64 *) __builtin_alloca( nStack * 8 );
281 memcpy( stack, pStack, nStack * 8 );
282
283 // Get pointer to method
284 sal_uInt64 pMethod = *((sal_uInt64 *)pThis);
285 pMethod += 8 * nVtableIndex;
286 pMethod = *((sal_uInt64 *)pMethod);
287
288 #if defined(_CALL_ELF) && _CALL_ELF == 2
289 typedef void (* FunctionCall )(...);
290 #else
291 typedef void (* FunctionCall )( sal_uInt64, sal_uInt64, sal_uInt64, sal_uInt64, sal_uInt64, sal_uInt64, sal_uInt64, sal_uInt64 );
292 #endif
293 FunctionCall pFunc = (FunctionCall)pMethod;
294
295 volatile double dret;
296
297 // fill registers
298 __asm__ __volatile__ (
299 "lfd 1, 0(%0)\n\t"
300 "lfd 2, 8(%0)\n\t"
301 "lfd 3, 16(%0)\n\t"
302 "lfd 4, 24(%0)\n\t"
303 "lfd 5, 32(%0)\n\t"
304 "lfd 6, 40(%0)\n\t"
305 "lfd 7, 48(%0)\n\t"
306 "lfd 8, 56(%0)\n\t"
307 "lfd 9, 64(%0)\n\t"
308 "lfd 10, 72(%0)\n\t"
309 "lfd 11, 80(%0)\n\t"
310 "lfd 12, 88(%0)\n\t"
311 "lfd 13, 96(%0)\n\t"
312 : : "r" (pFPR)
313 : "fr1", "fr2", "fr3", "fr4", "fr5", "fr6", "fr7", "fr8", "fr9",
314 "fr10", "fr11", "fr12", "fr13"
315 );
316
317 // tell gcc that r3 to r11 are not available to it for doing the TOC and exception munge on the func call
318 register sal_uInt64 r3 asm("r3");
319 register sal_uInt64 r4 asm("r4");
320
321 (*pFunc)(pGPR[0], pGPR[1], pGPR[2], pGPR[3], pGPR[4], pGPR[5], pGPR[6], pGPR[7]);
322
323 // get return value
324 __asm__ __volatile__ (
325 "mr %1, 3\n\t"
326 "mr %2, 4\n\t"
327 "fmr %0, 1\n\t"
328 : "=f" (dret), "=r" (r3), "=r" (r4) : );
329
330 MapReturn(r3, r4, dret, reinterpret_cast<typelib_TypeDescriptionReference *>(pReturnTypeDescr), pRegisterReturn);
331 }
332 #endif
333
334 // Macros for easier insertion of values to registers or stack
335 // pSV - pointer to the source
336 // nr - order of the value [will be increased if stored to register]
337 // pFPR, pGPR - pointer to the registers
338 // pDS - pointer to the stack [will be increased if stored here]
339
340 // The value in %xmm register is already prepared to be retrieved as a float,
341 // thus we treat float and double the same
342 #define INSERT_FLOAT( pSV, nr, pFPR, nGPR, pDS, bOverFlow ) \
343 if ( nGPR < ppc64::MAX_GPR_REGS ) \
344 ++nGPR; \
345 if ( nr < ppc64::MAX_SSE_REGS ) \
346 pFPR[nr++] = *reinterpret_cast<float *>( pSV ); \
347 else \
348 bOverFlow = true; \
349 if (bOverFlow) \
350 *pDS++ = *reinterpret_cast<sal_uInt64 *>( pSV ); // verbatim!
351
352 #define INSERT_DOUBLE( pSV, nr, pFPR, nGPR, pDS, bOverFlow ) \
353 if ( nGPR < ppc64::MAX_GPR_REGS ) \
354 ++nGPR; \
355 if ( nr < ppc64::MAX_SSE_REGS ) \
356 pFPR[nr++] = *reinterpret_cast<double *>( pSV ); \
357 else \
358 bOverFlow = true; \
359 if (bOverFlow) \
360 *pDS++ = *reinterpret_cast<sal_uInt64 *>( pSV ); // verbatim!
361
362 #define INSERT_INT64( pSV, nr, pGPR, pDS, bOverFlow ) \
363 if ( nr < ppc64::MAX_GPR_REGS ) \
364 pGPR[nr++] = *reinterpret_cast<sal_Int64 *>( pSV ); \
365 else \
366 bOverFlow = true; \
367 if (bOverFlow) \
368 *pDS++ = *reinterpret_cast<sal_Int64 *>( pSV );
369
370 #define INSERT_UINT64( pSV, nr, pGPR, pDS, bOverFlow ) \
371 if ( nr < ppc64::MAX_GPR_REGS ) \
372 pGPR[nr++] = *reinterpret_cast<sal_uInt64 *>( pSV ); \
373 else \
374 bOverFlow = true; \
375 if (bOverFlow) \
376 *pDS++ = *reinterpret_cast<sal_uInt64 *>( pSV );
377
378 #define INSERT_INT32( pSV, nr, pGPR, pDS, bOverFlow ) \
379 if ( nr < ppc64::MAX_GPR_REGS ) \
380 pGPR[nr++] = *reinterpret_cast<sal_Int32 *>( pSV ); \
381 else \
382 bOverFlow = true; \
383 if (bOverFlow) \
384 *pDS++ = *reinterpret_cast<sal_Int32 *>( pSV );
385
386 #define INSERT_UINT32( pSV, nr, pGPR, pDS, bOverFlow ) \
387 if ( nr < ppc64::MAX_GPR_REGS ) \
388 pGPR[nr++] = *reinterpret_cast<sal_uInt32 *>( pSV ); \
389 else \
390 bOverFlow = true; \
391 if (bOverFlow) \
392 *pDS++ = *reinterpret_cast<sal_uInt32 *>( pSV );
393
394 #define INSERT_INT16( pSV, nr, pGPR, pDS, bOverFlow ) \
395 if ( nr < ppc64::MAX_GPR_REGS ) \
396 pGPR[nr++] = *reinterpret_cast<sal_Int16 *>( pSV ); \
397 else \
398 bOverFlow = true; \
399 if (bOverFlow) \
400 *pDS++ = *reinterpret_cast<sal_Int16 *>( pSV );
401
402 #define INSERT_UINT16( pSV, nr, pGPR, pDS, bOverFlow ) \
403 if ( nr < ppc64::MAX_GPR_REGS ) \
404 pGPR[nr++] = *reinterpret_cast<sal_uInt16 *>( pSV ); \
405 else \
406 bOverFlow = true; \
407 if (bOverFlow) \
408 *pDS++ = *reinterpret_cast<sal_uInt16 *>( pSV );
409
410 #define INSERT_INT8( pSV, nr, pGPR, pDS, bOverFlow ) \
411 if ( nr < ppc64::MAX_GPR_REGS ) \
412 pGPR[nr++] = *reinterpret_cast<sal_Int8 *>( pSV ); \
413 else \
414 bOverFlow = true; \
415 if (bOverFlow) \
416 *pDS++ = *reinterpret_cast<sal_Int8 *>( pSV );
417
418 #define INSERT_UINT8( pSV, nr, pGPR, pDS, bOverFlow ) \
419 if ( nr < ppc64::MAX_GPR_REGS ) \
420 pGPR[nr++] = *reinterpret_cast<sal_uInt8 *>( pSV ); \
421 else \
422 bOverFlow = true; \
423 if (bOverFlow) \
424 *pDS++ = *reinterpret_cast<sal_uInt8 *>( pSV );
425
426 //==================================================================================================
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)427 static void cpp_call(
428 bridges::cpp_uno::shared::UnoInterfaceProxy * pThis,
429 bridges::cpp_uno::shared::VtableSlot aVtableSlot,
430 typelib_TypeDescriptionReference * pReturnTypeRef,
431 sal_Int32 nParams, typelib_MethodParameter * pParams,
432 void * pUnoReturn, void * pUnoArgs[], uno_Any ** ppUnoExc )
433 {
434 // max space for: [complex ret ptr], values|ptr ...
435 sal_uInt64 * pStack = (sal_uInt64 *)alloca( (nParams+3) * sizeof(sal_Int64) );
436 sal_uInt64 * pStackStart = pStack;
437
438 sal_uInt64 pGPR[ppc64::MAX_GPR_REGS];
439 sal_uInt32 nGPR = 0;
440
441 double pFPR[ppc64::MAX_SSE_REGS];
442 sal_uInt32 nFPR = 0;
443
444 // return
445 typelib_TypeDescription * pReturnTypeDescr = 0;
446 TYPELIB_DANGER_GET( &pReturnTypeDescr, pReturnTypeRef );
447 OSL_ENSURE( pReturnTypeDescr, "### expected return type description!" );
448
449 void * pCppReturn = 0; // if != 0 && != pUnoReturn, needs reconversion
450
451 bool bOverFlow = false;
452
453 if (pReturnTypeDescr)
454 {
455 #ifdef CMC_DEBUG
456 fprintf(stderr, "return type is %d\n", pReturnTypeDescr->eTypeClass);
457 #endif
458 if (!ppc64::return_in_hidden_param( pReturnTypeRef ))
459 {
460 pCppReturn = pUnoReturn; // direct way for simple types
461 #ifdef CMC_DEBUG
462 fprintf(stderr, "simple return\n");
463 #endif
464 }
465 else
466 {
467 // complex return via ptr
468 pCppReturn = (bridges::cpp_uno::shared::relatesToInterfaceType( pReturnTypeDescr )
469 ? alloca( pReturnTypeDescr->nSize ) : pUnoReturn);
470 #ifdef CMC_DEBUG
471 fprintf(stderr, "pCppReturn/pUnoReturn is %lx/%lx", pCppReturn, pUnoReturn);
472 #endif
473 INSERT_INT64( &pCppReturn, nGPR, pGPR, pStack, bOverFlow );
474 }
475 }
476 // push "this" pointer
477 void * pAdjustedThisPtr = reinterpret_cast< void ** >( pThis->getCppI() ) + aVtableSlot.offset;
478 #ifdef CMC_DEBUG
479 fprintf(stderr, "this pointer is %p\n", pAdjustedThisPtr);
480 #endif
481 INSERT_INT64( &pAdjustedThisPtr, nGPR, pGPR, pStack, bOverFlow );
482
483 // Args
484 void ** pCppArgs = (void **)alloca( 3 * sizeof(void *) * nParams );
485 // indizes of values this have to be converted (interface conversion cpp<=>uno)
486 sal_Int32 * pTempIndizes = (sal_Int32 *)(pCppArgs + nParams);
487 // type descriptions for reconversions
488 typelib_TypeDescription ** ppTempParamTypeDescr = (typelib_TypeDescription **)(pCppArgs + (2 * nParams));
489
490 sal_Int32 nTempIndizes = 0;
491
492 #ifdef CMC_DEBUG
493 fprintf(stderr, "n params is %d\n", nParams);
494 #endif
495
496 for ( sal_Int32 nPos = 0; nPos < nParams; ++nPos )
497 {
498 const typelib_MethodParameter & rParam = pParams[nPos];
499 typelib_TypeDescription * pParamTypeDescr = 0;
500 TYPELIB_DANGER_GET( &pParamTypeDescr, rParam.pTypeRef );
501
502 #ifdef CMC_DEBUG
503 fprintf(stderr, "param %d is %d %d %d\n", nPos, rParam.bOut, bridges::cpp_uno::shared::isSimpleType( pParamTypeDescr ),
504 pParamTypeDescr->eTypeClass);
505 #endif
506
507 if (!rParam.bOut && bridges::cpp_uno::shared::isSimpleType( pParamTypeDescr ))
508 {
509 // uno_copyAndConvertData( pCppArgs[nPos] = alloca( 8 ), pUnoArgs[nPos], pParamTypeDescr,
510 uno_copyAndConvertData( pCppArgs[nPos] = pStack, pUnoArgs[nPos], pParamTypeDescr,
511 pThis->getBridge()->getUno2Cpp() );
512 switch (pParamTypeDescr->eTypeClass)
513 {
514 case typelib_TypeClass_HYPER:
515 case typelib_TypeClass_UNSIGNED_HYPER:
516 #ifdef CMC_DEBUG
517 fprintf(stderr, "hyper is %lx\n", pCppArgs[nPos]);
518 #endif
519 INSERT_INT64( pCppArgs[nPos], nGPR, pGPR, pStack, bOverFlow );
520 break;
521 case typelib_TypeClass_LONG:
522 case typelib_TypeClass_UNSIGNED_LONG:
523 case typelib_TypeClass_ENUM:
524 #ifdef CMC_DEBUG
525 fprintf(stderr, "long is %x\n", pCppArgs[nPos]);
526 #endif
527 INSERT_INT32( pCppArgs[nPos], nGPR, pGPR, pStack, bOverFlow );
528 break;
529 case typelib_TypeClass_SHORT:
530 INSERT_INT16( pCppArgs[nPos], nGPR, pGPR, pStack, bOverFlow );
531 break;
532 case typelib_TypeClass_CHAR:
533 case typelib_TypeClass_UNSIGNED_SHORT:
534 INSERT_INT16( pCppArgs[nPos], nGPR, pGPR, pStack, bOverFlow );
535 break;
536 case typelib_TypeClass_BOOLEAN:
537 INSERT_UINT8( pCppArgs[nPos], nGPR, pGPR, pStack, bOverFlow );
538 break;
539 case typelib_TypeClass_BYTE:
540 INSERT_INT8( pCppArgs[nPos], nGPR, pGPR, pStack, bOverFlow );
541 break;
542 case typelib_TypeClass_FLOAT:
543 INSERT_FLOAT( pCppArgs[nPos], nFPR, pFPR, nGPR, pStack, bOverFlow );
544 break;
545 case typelib_TypeClass_DOUBLE:
546 INSERT_DOUBLE( pCppArgs[nPos], nFPR, pFPR, nGPR, pStack, bOverFlow );
547 break;
548 }
549
550 // no longer needed
551 TYPELIB_DANGER_RELEASE( pParamTypeDescr );
552
553 }
554 else // ptr to complex value | ref
555 {
556 #ifdef CMC_DEBUG
557 fprintf(stderr, "complex type again %d\n", rParam.bIn);
558 #endif
559 if (! rParam.bIn) // is pure out
560 {
561 #ifdef CMC_DEBUG
562 fprintf(stderr, "complex size is %d\n", pParamTypeDescr->nSize );
563 #endif
564 // cpp out is constructed mem, uno out is not!
565 uno_constructData(
566 pCppArgs[nPos] = alloca( pParamTypeDescr->nSize ),
567 pParamTypeDescr );
568 pTempIndizes[nTempIndizes] = nPos; // default constructed for cpp call
569 // will be released at reconversion
570 ppTempParamTypeDescr[nTempIndizes++] = pParamTypeDescr;
571 }
572 // is in/inout
573 else if (bridges::cpp_uno::shared::relatesToInterfaceType( pParamTypeDescr ))
574 {
575 #ifdef CMC_DEBUG
576 fprintf(stderr, "this one\n");
577 #endif
578 uno_copyAndConvertData(
579 pCppArgs[nPos] = alloca( pParamTypeDescr->nSize ),
580 pUnoArgs[nPos], pParamTypeDescr, pThis->getBridge()->getUno2Cpp() );
581
582 pTempIndizes[nTempIndizes] = nPos; // has to be reconverted
583 // will be released at reconversion
584 ppTempParamTypeDescr[nTempIndizes++] = pParamTypeDescr;
585 }
586 else // direct way
587 {
588 #ifdef CMC_DEBUG
589 fprintf(stderr, "that one, passing %lx through\n", pUnoArgs[nPos]);
590 #endif
591 pCppArgs[nPos] = pUnoArgs[nPos];
592 // no longer needed
593 TYPELIB_DANGER_RELEASE( pParamTypeDescr );
594 }
595 INSERT_INT64( &(pCppArgs[nPos]), nGPR, pGPR, pStack, bOverFlow );
596 }
597 }
598
599 try
600 {
601 callVirtualMethod(
602 pAdjustedThisPtr, aVtableSlot.index,
603 pCppReturn, pReturnTypeDescr,
604 pStackStart, ( pStack - pStackStart ),
605 pGPR, nGPR,
606 pFPR, nFPR );
607 // NO exception occurred...
608 *ppUnoExc = 0;
609
610 // reconvert temporary params
611 for ( ; nTempIndizes--; )
612 {
613 sal_Int32 nIndex = pTempIndizes[nTempIndizes];
614 typelib_TypeDescription * pParamTypeDescr = ppTempParamTypeDescr[nTempIndizes];
615
616 if (pParams[nIndex].bIn)
617 {
618 if (pParams[nIndex].bOut) // inout
619 {
620 uno_destructData( pUnoArgs[nIndex], pParamTypeDescr, 0 ); // destroy uno value
621 uno_copyAndConvertData( pUnoArgs[nIndex], pCppArgs[nIndex], pParamTypeDescr,
622 pThis->getBridge()->getCpp2Uno() );
623 }
624 }
625 else // pure out
626 {
627 uno_copyAndConvertData( pUnoArgs[nIndex], pCppArgs[nIndex], pParamTypeDescr,
628 pThis->getBridge()->getCpp2Uno() );
629 }
630 // destroy temp cpp param => cpp: every param was constructed
631 uno_destructData( pCppArgs[nIndex], pParamTypeDescr, cpp_release );
632
633 TYPELIB_DANGER_RELEASE( pParamTypeDescr );
634 }
635 // return value
636 if (pCppReturn && pUnoReturn != pCppReturn)
637 {
638 uno_copyAndConvertData( pUnoReturn, pCppReturn, pReturnTypeDescr,
639 pThis->getBridge()->getCpp2Uno() );
640 uno_destructData( pCppReturn, pReturnTypeDescr, cpp_release );
641 }
642 }
643 catch (...)
644 {
645 __cxa_exception *header;
646 #ifdef __GLIBCXX__
647 header = __cxa_get_globals()->caughtExceptions;
648 #else
649 header = reinterpret_cast<__cxa_exception *>( __cxa_current_primary_exception() );
650 if (header) {
651 __cxa_decrement_exception_refcount( header );
652 header--;
653 }
654 #endif
655 // fill uno exception
656 CPPU_CURRENT_NAMESPACE::fillUnoException( header, *ppUnoExc, pThis->getBridge()->getCpp2Uno() );
657
658 // temporary params
659 for ( ; nTempIndizes--; )
660 {
661 sal_Int32 nIndex = pTempIndizes[nTempIndizes];
662 // destroy temp cpp param => cpp: every param was constructed
663 uno_destructData( pCppArgs[nIndex], ppTempParamTypeDescr[nTempIndizes], cpp_release );
664 TYPELIB_DANGER_RELEASE( ppTempParamTypeDescr[nTempIndizes] );
665 }
666 // return type
667 if (pReturnTypeDescr)
668 TYPELIB_DANGER_RELEASE( pReturnTypeDescr );
669 }
670 }
671
672 }
673
674 namespace bridges { namespace cpp_uno { namespace shared {
675
unoInterfaceProxyDispatch(uno_Interface * pUnoI,const typelib_TypeDescription * pMemberDescr,void * pReturn,void * pArgs[],uno_Any ** ppException)676 void unoInterfaceProxyDispatch(
677 uno_Interface * pUnoI, const typelib_TypeDescription * pMemberDescr,
678 void * pReturn, void * pArgs[], uno_Any ** ppException )
679 {
680 // is my surrogate
681 ::bridges::cpp_uno::shared::UnoInterfaceProxy * pThis
682 = static_cast< ::bridges::cpp_uno::shared::UnoInterfaceProxy *> (pUnoI);
683 typelib_InterfaceTypeDescription * pTypeDescr = pThis->pTypeDescr;
684
685 switch (pMemberDescr->eTypeClass)
686 {
687 case typelib_TypeClass_INTERFACE_ATTRIBUTE:
688 {
689
690 ::bridges::cpp_uno::shared::VtableSlot aVtableSlot(
691 ::bridges::cpp_uno::shared::getVtableSlot(
692 reinterpret_cast<
693 typelib_InterfaceAttributeTypeDescription const * >(
694 pMemberDescr)));
695
696 if (pReturn)
697 {
698 // dependent dispatch
699 cpp_call(
700 pThis, aVtableSlot,
701 ((typelib_InterfaceAttributeTypeDescription *)pMemberDescr)->pAttributeTypeRef,
702 0, 0, // no params
703 pReturn, pArgs, ppException );
704 }
705 else
706 {
707 // is SET
708 typelib_MethodParameter aParam;
709 aParam.pTypeRef =
710 ((typelib_InterfaceAttributeTypeDescription *)pMemberDescr)->pAttributeTypeRef;
711 aParam.bIn = sal_True;
712 aParam.bOut = sal_False;
713
714 typelib_TypeDescriptionReference * pReturnTypeRef = 0;
715 OUString aVoidName( RTL_CONSTASCII_USTRINGPARAM("void") );
716 typelib_typedescriptionreference_new(
717 &pReturnTypeRef, typelib_TypeClass_VOID, aVoidName.pData );
718
719 // dependent dispatch
720 aVtableSlot.index += 1; //get then set method
721 cpp_call(
722 pThis, aVtableSlot,
723 pReturnTypeRef,
724 1, &aParam,
725 pReturn, pArgs, ppException );
726
727 typelib_typedescriptionreference_release( pReturnTypeRef );
728 }
729
730 break;
731 }
732 case typelib_TypeClass_INTERFACE_METHOD:
733 {
734
735 ::bridges::cpp_uno::shared::VtableSlot aVtableSlot(
736 ::bridges::cpp_uno::shared::getVtableSlot(
737 reinterpret_cast<
738 typelib_InterfaceMethodTypeDescription const * >(
739 pMemberDescr)));
740 switch (aVtableSlot.index)
741 {
742 // standard calls
743 case 1: // acquire uno interface
744 (*pUnoI->acquire)( pUnoI );
745 *ppException = 0;
746 break;
747 case 2: // release uno interface
748 (*pUnoI->release)( pUnoI );
749 *ppException = 0;
750 break;
751 case 0: // queryInterface() opt
752 {
753 typelib_TypeDescription * pTD = 0;
754 TYPELIB_DANGER_GET( &pTD, reinterpret_cast< Type * >( pArgs[0] )->getTypeLibType() );
755 if (pTD)
756 {
757 uno_Interface * pInterface = 0;
758 (*pThis->pBridge->getUnoEnv()->getRegisteredInterface)(
759 pThis->pBridge->getUnoEnv(),
760 (void **)&pInterface, pThis->oid.pData, (typelib_InterfaceTypeDescription *)pTD );
761
762 if (pInterface)
763 {
764 ::uno_any_construct(
765 reinterpret_cast< uno_Any * >( pReturn ),
766 &pInterface, pTD, 0 );
767 (*pInterface->release)( pInterface );
768 TYPELIB_DANGER_RELEASE( pTD );
769 *ppException = 0;
770 break;
771 }
772 TYPELIB_DANGER_RELEASE( pTD );
773 }
774 } // else perform queryInterface()
775 default:
776 // dependent dispatch
777 cpp_call(
778 pThis, aVtableSlot,
779 ((typelib_InterfaceMethodTypeDescription *)pMemberDescr)->pReturnTypeRef,
780 ((typelib_InterfaceMethodTypeDescription *)pMemberDescr)->nParams,
781 ((typelib_InterfaceMethodTypeDescription *)pMemberDescr)->pParams,
782 pReturn, pArgs, ppException );
783 }
784 break;
785 }
786 default:
787 {
788 ::com::sun::star::uno::RuntimeException aExc(
789 OUString( RTL_CONSTASCII_USTRINGPARAM("illegal member type description!") ),
790 ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >() );
791
792 Type const & rExcType = ::getCppuType( &aExc );
793 // binary identical null reference
794 ::uno_type_any_construct( *ppException, &aExc, rExcType.getTypeLibType(), 0 );
795 }
796 }
797 }
798
799 } } }
800