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