1 /************************************************************************* 2 * 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * Copyright 2000, 2010 Oracle and/or its affiliates. 6 * 7 * OpenOffice.org - a multi-platform office productivity suite 8 * 9 * This file is part of OpenOffice.org. 10 * 11 * OpenOffice.org is free software: you can redistribute it and/or modify 12 * it under the terms of the GNU Lesser General Public License version 3 13 * only, as published by the Free Software Foundation. 14 * 15 * OpenOffice.org is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU Lesser General Public License version 3 for more details 19 * (a copy is included in the LICENSE file that accompanied this code). 20 * 21 * You should have received a copy of the GNU Lesser General Public License 22 * version 3 along with OpenOffice.org. If not, see 23 * <http://www.openoffice.org/license.html> 24 * for a copy of the LGPLv3 License. 25 * 26 ************************************************************************/ 27 28 // MARKER(update_precomp.py): autogen include statement, do not remove 29 #include "precompiled_bridges.hxx" 30 31 #include <malloc.h> 32 33 #include <com/sun/star/uno/genfunc.hxx> 34 #include <uno/data.h> 35 36 #include "bridges/cpp_uno/shared/bridge.hxx" 37 #include "bridges/cpp_uno/shared/types.hxx" 38 #include "bridges/cpp_uno/shared/unointerfaceproxy.hxx" 39 #include "bridges/cpp_uno/shared/vtables.hxx" 40 41 #include "share.hxx" 42 43 #include <stdio.h> 44 #include <string.h> 45 46 47 using namespace ::rtl; 48 using namespace ::com::sun::star::uno; 49 50 void MapReturn(long r3, double dret, typelib_TypeClass eTypeClass, void *pRegisterReturn) 51 { 52 switch (eTypeClass) 53 { 54 case typelib_TypeClass_HYPER: 55 case typelib_TypeClass_UNSIGNED_HYPER: 56 *reinterpret_cast<sal_uInt64 *>( pRegisterReturn ) = r3; 57 break; 58 case typelib_TypeClass_LONG: 59 case typelib_TypeClass_UNSIGNED_LONG: 60 case typelib_TypeClass_ENUM: 61 *reinterpret_cast<sal_uInt32 *>( pRegisterReturn ) = r3; 62 break; 63 case typelib_TypeClass_CHAR: 64 case typelib_TypeClass_SHORT: 65 case typelib_TypeClass_UNSIGNED_SHORT: 66 *reinterpret_cast<sal_uInt16 *>( pRegisterReturn ) = (unsigned short)r3; 67 break; 68 case typelib_TypeClass_BOOLEAN: 69 case typelib_TypeClass_BYTE: 70 *reinterpret_cast<sal_uInt8 *>( pRegisterReturn ) = (unsigned char)r3; 71 break; 72 case typelib_TypeClass_FLOAT: 73 *reinterpret_cast<float *>( pRegisterReturn ) = dret; 74 break; 75 case typelib_TypeClass_DOUBLE: 76 *reinterpret_cast<double *>( pRegisterReturn ) = dret; 77 break; 78 default: 79 break; 80 } 81 } 82 83 namespace 84 { 85 //================================================================================================== 86 static void callVirtualMethod(void * pThis, sal_uInt32 nVtableIndex, 87 void * pRegisterReturn, typelib_TypeDescription * pReturnTypeDescr, 88 sal_uInt64 *pStack, sal_uInt32 nStack, 89 sal_uInt64 *pGPR, sal_uInt32 nGPR, 90 double *pFPR, sal_uInt32 nFPR) 91 { 92 // Stack, if used, must be 16-bytes aligned 93 if ( nStack ) 94 nStack = ( nStack + 1 ) & ~1; 95 96 // Should not happen, but... 97 if ( nFPR > ppc64::MAX_SSE_REGS ) 98 nFPR = ppc64::MAX_SSE_REGS; 99 if ( nGPR > ppc64::MAX_GPR_REGS ) 100 nGPR = ppc64::MAX_GPR_REGS; 101 102 #ifdef CMC_DEBUG 103 // Let's figure out what is really going on here 104 { 105 fprintf( stderr, "= callVirtualMethod() =\nGPR's (%d): ", nGPR ); 106 for ( int i = 0; i < nGPR; ++i ) 107 fprintf( stderr, "0x%lx, ", pGPR[i] ); 108 fprintf( stderr, "\nFPR's (%d): ", nFPR ); 109 for ( int i = 0; i < nFPR; ++i ) 110 fprintf( stderr, "0x%lx (%f), ", pFPR[i], pFPR[i] ); 111 fprintf( stderr, "\nStack (%d): ", nStack ); 112 for ( int i = 0; i < nStack; ++i ) 113 fprintf( stderr, "0x%lx, ", pStack[i] ); 114 fprintf( stderr, "\n" ); 115 } 116 #endif 117 118 // Load parameters to stack, if necessary 119 sal_uInt64 *stack = (sal_uInt64 *) __builtin_alloca( nStack * 8 ); 120 memcpy( stack, pStack, nStack * 8 ); 121 122 // Get pointer to method 123 sal_uInt64 pMethod = *((sal_uInt64 *)pThis); 124 pMethod += 8 * nVtableIndex; 125 pMethod = *((sal_uInt64 *)pMethod); 126 127 typedef void (* FunctionCall )( sal_uInt64, sal_uInt64, sal_uInt64, sal_uInt64, sal_uInt64, sal_uInt64, sal_uInt64, sal_uInt64 ); 128 FunctionCall pFunc = (FunctionCall)pMethod; 129 130 volatile double dret; 131 132 // fill registers 133 __asm__ __volatile__ ( 134 "ld 3, 0(%0)\n\t" 135 "ld 4, 8(%0)\n\t" 136 "ld 5, 16(%0)\n\t" 137 "ld 6, 24(%0)\n\t" 138 "ld 7, 32(%0)\n\t" 139 "ld 8, 40(%0)\n\t" 140 "ld 9, 48(%0)\n\t" 141 "ld 10, 56(%0)\n\t" 142 "lfd 1, 0(%1)\n\t" 143 "lfd 2, 8(%1)\n\t" 144 "lfd 3, 16(%1)\n\t" 145 "lfd 4, 24(%1)\n\t" 146 "lfd 5, 32(%1)\n\t" 147 "lfd 6, 40(%1)\n\t" 148 "lfd 7, 48(%1)\n\t" 149 "lfd 8, 56(%1)\n\t" 150 "lfd 9, 64(%1)\n\t" 151 "lfd 10, 72(%1)\n\t" 152 "lfd 11, 80(%1)\n\t" 153 "lfd 12, 88(%1)\n\t" 154 "lfd 13, 96(%1)\n\t" 155 : : "r" (pGPR), "r" (pFPR) 156 : "r0", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", 157 "fr1", "fr2", "fr3", "fr4", "fr5", "fr6", "fr7", "fr8", "fr9", 158 "fr10", "fr11", "fr12", "fr13" 159 ); 160 161 // tell gcc that r3 to r11 are not available to it for doing the TOC and exception munge on the func call 162 register sal_uInt64 r3 asm("r3"); 163 register sal_uInt64 r4 asm("r4"); 164 register sal_uInt64 r5 asm("r5"); 165 register sal_uInt64 r6 asm("r6"); 166 register sal_uInt64 r7 asm("r7"); 167 register sal_uInt64 r8 asm("r8"); 168 register sal_uInt64 r9 asm("r9"); 169 register sal_uInt64 r10 asm("r10"); 170 register sal_uInt64 r11 asm("r11"); 171 172 (*pFunc)(r3, r4, r5, r6, r7, r8, r9, r10); 173 174 // get return value 175 __asm__ __volatile__ ( 176 "mr %1, 3\n\t" 177 "mr %2, 4\n\t" 178 "fmr %0, 1\n\t" 179 : "=f" (dret), "=r" (r3), "=r" (r4) : ); 180 181 MapReturn(r3, dret, pReturnTypeDescr->eTypeClass, pRegisterReturn); 182 } 183 184 // Macros for easier insertion of values to registers or stack 185 // pSV - pointer to the source 186 // nr - order of the value [will be increased if stored to register] 187 // pFPR, pGPR - pointer to the registers 188 // pDS - pointer to the stack [will be increased if stored here] 189 190 // The value in %xmm register is already prepared to be retrieved as a float, 191 // thus we treat float and double the same 192 #define INSERT_FLOAT( pSV, nr, pFPR, pDS, bOverflow ) \ 193 if ( nr < ppc64::MAX_SSE_REGS ) \ 194 pFPR[nr++] = *reinterpret_cast<float *>( pSV ); \ 195 else \ 196 bOverFlow = true; \ 197 if (bOverFlow) \ 198 *pDS++ = *reinterpret_cast<sal_uInt64 *>( pSV ); // verbatim! 199 200 #define INSERT_DOUBLE( pSV, nr, pFPR, pDS, bOverflow ) \ 201 if ( nr < ppc64::MAX_SSE_REGS ) \ 202 pFPR[nr++] = *reinterpret_cast<double *>( pSV ); \ 203 else \ 204 bOverFlow = true; \ 205 if (bOverFlow) \ 206 *pDS++ = *reinterpret_cast<sal_uInt64 *>( pSV ); // verbatim! 207 208 #define INSERT_INT64( pSV, nr, pGPR, pDS, bOverflow ) \ 209 if ( nr < ppc64::MAX_GPR_REGS ) \ 210 pGPR[nr++] = *reinterpret_cast<sal_uInt64 *>( pSV ); \ 211 else \ 212 bOverFlow = true; \ 213 if (bOverFlow) \ 214 *pDS++ = *reinterpret_cast<sal_uInt64 *>( pSV ); 215 216 #define INSERT_INT32( pSV, nr, pGPR, pDS, bOverflow ) \ 217 if ( nr < ppc64::MAX_GPR_REGS ) \ 218 pGPR[nr++] = *reinterpret_cast<sal_uInt32 *>( pSV ); \ 219 else \ 220 bOverFlow = true; \ 221 if (bOverFlow) \ 222 *pDS++ = *reinterpret_cast<sal_uInt32 *>( pSV ); 223 224 #define INSERT_INT16( pSV, nr, pGPR, pDS, bOverflow ) \ 225 if ( nr < ppc64::MAX_GPR_REGS ) \ 226 pGPR[nr++] = *reinterpret_cast<sal_uInt16 *>( pSV ); \ 227 else \ 228 bOverFlow = true; \ 229 if (bOverFlow) \ 230 *pDS++ = *reinterpret_cast<sal_uInt16 *>( pSV ); 231 232 #define INSERT_INT8( pSV, nr, pGPR, pDS, bOverflow ) \ 233 if ( nr < ppc64::MAX_GPR_REGS ) \ 234 pGPR[nr++] = *reinterpret_cast<sal_uInt8 *>( pSV ); \ 235 else \ 236 bOverFlow = true; \ 237 if (bOverFlow) \ 238 *pDS++ = *reinterpret_cast<sal_uInt8 *>( pSV ); 239 240 //================================================================================================== 241 static void cpp_call( 242 bridges::cpp_uno::shared::UnoInterfaceProxy * pThis, 243 bridges::cpp_uno::shared::VtableSlot aVtableSlot, 244 typelib_TypeDescriptionReference * pReturnTypeRef, 245 sal_Int32 nParams, typelib_MethodParameter * pParams, 246 void * pUnoReturn, void * pUnoArgs[], uno_Any ** ppUnoExc ) 247 { 248 // max space for: [complex ret ptr], values|ptr ... 249 sal_uInt64 * pStack = (sal_uInt64 *)alloca( (nParams+3) * sizeof(sal_Int64) ); 250 sal_uInt64 * pStackStart = pStack; 251 252 sal_uInt64 pGPR[ppc64::MAX_GPR_REGS]; 253 sal_uInt32 nGPR = 0; 254 255 double pFPR[ppc64::MAX_SSE_REGS]; 256 sal_uInt32 nFPR = 0; 257 258 // return 259 typelib_TypeDescription * pReturnTypeDescr = 0; 260 TYPELIB_DANGER_GET( &pReturnTypeDescr, pReturnTypeRef ); 261 OSL_ENSURE( pReturnTypeDescr, "### expected return type description!" ); 262 263 void * pCppReturn = 0; // if != 0 && != pUnoReturn, needs reconversion 264 265 bool bOverFlow = false; 266 267 if (pReturnTypeDescr) 268 { 269 #ifdef CMC_DEBUG 270 fprintf(stderr, "return type is %d\n", pReturnTypeDescr->eTypeClass); 271 #endif 272 if (bridges::cpp_uno::shared::isSimpleType( pReturnTypeDescr )) 273 { 274 pCppReturn = pUnoReturn; // direct way for simple types 275 #ifdef CMC_DEBUG 276 fprintf(stderr, "simple return\n"); 277 #endif 278 } 279 else 280 { 281 // complex return via ptr 282 pCppReturn = (bridges::cpp_uno::shared::relatesToInterfaceType( pReturnTypeDescr ) 283 ? alloca( pReturnTypeDescr->nSize ) : pUnoReturn); 284 #ifdef CMC_DEBUG 285 fprintf(stderr, "pCppReturn/pUnoReturn is %lx/%lx", pCppReturn, pUnoReturn); 286 #endif 287 INSERT_INT64( &pCppReturn, nGPR, pGPR, pStack, bOverFlow ); 288 } 289 } 290 // push "this" pointer 291 void * pAdjustedThisPtr = reinterpret_cast< void ** >( pThis->getCppI() ) + aVtableSlot.offset; 292 #ifdef CMC_DEBUG 293 fprintf(stderr, "this pointer is %p\n", pAdjustedThisPtr); 294 #endif 295 INSERT_INT64( &pAdjustedThisPtr, nGPR, pGPR, pStack, bOverFlow ); 296 297 // Args 298 void ** pCppArgs = (void **)alloca( 3 * sizeof(void *) * nParams ); 299 // indizes of values this have to be converted (interface conversion cpp<=>uno) 300 sal_Int32 * pTempIndizes = (sal_Int32 *)(pCppArgs + nParams); 301 // type descriptions for reconversions 302 typelib_TypeDescription ** ppTempParamTypeDescr = (typelib_TypeDescription **)(pCppArgs + (2 * nParams)); 303 304 sal_Int32 nTempIndizes = 0; 305 306 #ifdef CMC_DEBUG 307 fprintf(stderr, "n params is %d\n", nParams); 308 #endif 309 310 for ( sal_Int32 nPos = 0; nPos < nParams; ++nPos ) 311 { 312 const typelib_MethodParameter & rParam = pParams[nPos]; 313 typelib_TypeDescription * pParamTypeDescr = 0; 314 TYPELIB_DANGER_GET( &pParamTypeDescr, rParam.pTypeRef ); 315 316 #ifdef CMC_DEBUG 317 fprintf(stderr, "param %d is %d %d %d\n", nPos, rParam.bOut, bridges::cpp_uno::shared::isSimpleType( pParamTypeDescr ), 318 pParamTypeDescr->eTypeClass); 319 #endif 320 321 if (!rParam.bOut && bridges::cpp_uno::shared::isSimpleType( pParamTypeDescr )) 322 { 323 // uno_copyAndConvertData( pCppArgs[nPos] = alloca( 8 ), pUnoArgs[nPos], pParamTypeDescr, 324 uno_copyAndConvertData( pCppArgs[nPos] = pStack, pUnoArgs[nPos], pParamTypeDescr, 325 pThis->getBridge()->getUno2Cpp() ); 326 switch (pParamTypeDescr->eTypeClass) 327 { 328 case typelib_TypeClass_HYPER: 329 case typelib_TypeClass_UNSIGNED_HYPER: 330 #ifdef CMC_DEBUG 331 fprintf(stderr, "hyper is %lx\n", pCppArgs[nPos]); 332 #endif 333 INSERT_INT64( pCppArgs[nPos], nGPR, pGPR, pStack, bOverFlow ); 334 break; 335 case typelib_TypeClass_LONG: 336 case typelib_TypeClass_UNSIGNED_LONG: 337 case typelib_TypeClass_ENUM: 338 #ifdef CMC_DEBUG 339 fprintf(stderr, "long is %x\n", pCppArgs[nPos]); 340 #endif 341 INSERT_INT32( pCppArgs[nPos], nGPR, pGPR, pStack, bOverFlow ); 342 break; 343 case typelib_TypeClass_SHORT: 344 case typelib_TypeClass_CHAR: 345 case typelib_TypeClass_UNSIGNED_SHORT: 346 INSERT_INT16( pCppArgs[nPos], nGPR, pGPR, pStack, bOverFlow ); 347 break; 348 case typelib_TypeClass_BOOLEAN: 349 case typelib_TypeClass_BYTE: 350 INSERT_INT8( pCppArgs[nPos], nGPR, pGPR, pStack, bOverFlow ); 351 break; 352 case typelib_TypeClass_FLOAT: 353 INSERT_FLOAT( pCppArgs[nPos], nFPR, pFPR, pStack, bOverFlow ); 354 break; 355 case typelib_TypeClass_DOUBLE: 356 INSERT_DOUBLE( pCppArgs[nPos], nFPR, pFPR, pStack, bOverFlow ); 357 break; 358 } 359 360 // no longer needed 361 TYPELIB_DANGER_RELEASE( pParamTypeDescr ); 362 363 } 364 else // ptr to complex value | ref 365 { 366 #ifdef CMC_DEBUG 367 fprintf(stderr, "complex type again %d\n", rParam.bIn); 368 #endif 369 if (! rParam.bIn) // is pure out 370 { 371 #ifdef CMC_DEBUG 372 fprintf(stderr, "complex size is %d\n", pParamTypeDescr->nSize ); 373 #endif 374 // cpp out is constructed mem, uno out is not! 375 uno_constructData( 376 pCppArgs[nPos] = alloca( pParamTypeDescr->nSize ), 377 pParamTypeDescr ); 378 pTempIndizes[nTempIndizes] = nPos; // default constructed for cpp call 379 // will be released at reconversion 380 ppTempParamTypeDescr[nTempIndizes++] = pParamTypeDescr; 381 } 382 // is in/inout 383 else if (bridges::cpp_uno::shared::relatesToInterfaceType( pParamTypeDescr )) 384 { 385 #ifdef CMC_DEBUG 386 fprintf(stderr, "this one\n"); 387 #endif 388 uno_copyAndConvertData( 389 pCppArgs[nPos] = alloca( pParamTypeDescr->nSize ), 390 pUnoArgs[nPos], pParamTypeDescr, pThis->getBridge()->getUno2Cpp() ); 391 392 pTempIndizes[nTempIndizes] = nPos; // has to be reconverted 393 // will be released at reconversion 394 ppTempParamTypeDescr[nTempIndizes++] = pParamTypeDescr; 395 } 396 else // direct way 397 { 398 #ifdef CMC_DEBUG 399 fprintf(stderr, "that one, passing %lx through\n", pUnoArgs[nPos]); 400 #endif 401 pCppArgs[nPos] = pUnoArgs[nPos]; 402 // no longer needed 403 TYPELIB_DANGER_RELEASE( pParamTypeDescr ); 404 } 405 INSERT_INT64( &(pCppArgs[nPos]), nGPR, pGPR, pStack, bOverFlow ); 406 } 407 } 408 409 try 410 { 411 callVirtualMethod( 412 pAdjustedThisPtr, aVtableSlot.index, 413 pCppReturn, pReturnTypeDescr, 414 pStackStart, ( pStack - pStackStart ), 415 pGPR, nGPR, 416 pFPR, nFPR ); 417 // NO exception occured... 418 *ppUnoExc = 0; 419 420 // reconvert temporary params 421 for ( ; nTempIndizes--; ) 422 { 423 sal_Int32 nIndex = pTempIndizes[nTempIndizes]; 424 typelib_TypeDescription * pParamTypeDescr = ppTempParamTypeDescr[nTempIndizes]; 425 426 if (pParams[nIndex].bIn) 427 { 428 if (pParams[nIndex].bOut) // inout 429 { 430 uno_destructData( pUnoArgs[nIndex], pParamTypeDescr, 0 ); // destroy uno value 431 uno_copyAndConvertData( pUnoArgs[nIndex], pCppArgs[nIndex], pParamTypeDescr, 432 pThis->getBridge()->getCpp2Uno() ); 433 } 434 } 435 else // pure out 436 { 437 uno_copyAndConvertData( pUnoArgs[nIndex], pCppArgs[nIndex], pParamTypeDescr, 438 pThis->getBridge()->getCpp2Uno() ); 439 } 440 // destroy temp cpp param => cpp: every param was constructed 441 uno_destructData( pCppArgs[nIndex], pParamTypeDescr, cpp_release ); 442 443 TYPELIB_DANGER_RELEASE( pParamTypeDescr ); 444 } 445 // return value 446 if (pCppReturn && pUnoReturn != pCppReturn) 447 { 448 uno_copyAndConvertData( pUnoReturn, pCppReturn, pReturnTypeDescr, 449 pThis->getBridge()->getCpp2Uno() ); 450 uno_destructData( pCppReturn, pReturnTypeDescr, cpp_release ); 451 } 452 } 453 catch (...) 454 { 455 // fill uno exception 456 fillUnoException( CPPU_CURRENT_NAMESPACE::__cxa_get_globals()->caughtExceptions, 457 *ppUnoExc, pThis->getBridge()->getCpp2Uno() ); 458 459 // temporary params 460 for ( ; nTempIndizes--; ) 461 { 462 sal_Int32 nIndex = pTempIndizes[nTempIndizes]; 463 // destroy temp cpp param => cpp: every param was constructed 464 uno_destructData( pCppArgs[nIndex], ppTempParamTypeDescr[nTempIndizes], cpp_release ); 465 TYPELIB_DANGER_RELEASE( ppTempParamTypeDescr[nTempIndizes] ); 466 } 467 // return type 468 if (pReturnTypeDescr) 469 TYPELIB_DANGER_RELEASE( pReturnTypeDescr ); 470 } 471 } 472 473 } 474 475 namespace bridges { namespace cpp_uno { namespace shared { 476 477 void unoInterfaceProxyDispatch( 478 uno_Interface * pUnoI, const typelib_TypeDescription * pMemberDescr, 479 void * pReturn, void * pArgs[], uno_Any ** ppException ) 480 { 481 // is my surrogate 482 bridges::cpp_uno::shared::UnoInterfaceProxy * pThis 483 = static_cast< bridges::cpp_uno::shared::UnoInterfaceProxy *> (pUnoI); 484 typelib_InterfaceTypeDescription * pTypeDescr = pThis->pTypeDescr; 485 486 switch (pMemberDescr->eTypeClass) 487 { 488 case typelib_TypeClass_INTERFACE_ATTRIBUTE: 489 { 490 491 VtableSlot aVtableSlot( 492 getVtableSlot( 493 reinterpret_cast< 494 typelib_InterfaceAttributeTypeDescription const * >( 495 pMemberDescr))); 496 497 if (pReturn) 498 { 499 // dependent dispatch 500 cpp_call( 501 pThis, aVtableSlot, 502 ((typelib_InterfaceAttributeTypeDescription *)pMemberDescr)->pAttributeTypeRef, 503 0, 0, // no params 504 pReturn, pArgs, ppException ); 505 } 506 else 507 { 508 // is SET 509 typelib_MethodParameter aParam; 510 aParam.pTypeRef = 511 ((typelib_InterfaceAttributeTypeDescription *)pMemberDescr)->pAttributeTypeRef; 512 aParam.bIn = sal_True; 513 aParam.bOut = sal_False; 514 515 typelib_TypeDescriptionReference * pReturnTypeRef = 0; 516 OUString aVoidName( RTL_CONSTASCII_USTRINGPARAM("void") ); 517 typelib_typedescriptionreference_new( 518 &pReturnTypeRef, typelib_TypeClass_VOID, aVoidName.pData ); 519 520 // dependent dispatch 521 aVtableSlot.index += 1; //get then set method 522 cpp_call( 523 pThis, aVtableSlot, 524 pReturnTypeRef, 525 1, &aParam, 526 pReturn, pArgs, ppException ); 527 528 typelib_typedescriptionreference_release( pReturnTypeRef ); 529 } 530 531 break; 532 } 533 case typelib_TypeClass_INTERFACE_METHOD: 534 { 535 536 VtableSlot aVtableSlot( 537 getVtableSlot( 538 reinterpret_cast< 539 typelib_InterfaceMethodTypeDescription const * >( 540 pMemberDescr))); 541 switch (aVtableSlot.index) 542 { 543 // standard calls 544 case 1: // acquire uno interface 545 (*pUnoI->acquire)( pUnoI ); 546 *ppException = 0; 547 break; 548 case 2: // release uno interface 549 (*pUnoI->release)( pUnoI ); 550 *ppException = 0; 551 break; 552 case 0: // queryInterface() opt 553 { 554 typelib_TypeDescription * pTD = 0; 555 TYPELIB_DANGER_GET( &pTD, reinterpret_cast< Type * >( pArgs[0] )->getTypeLibType() ); 556 if (pTD) 557 { 558 uno_Interface * pInterface = 0; 559 (*pThis->pBridge->getUnoEnv()->getRegisteredInterface)( 560 pThis->pBridge->getUnoEnv(), 561 (void **)&pInterface, pThis->oid.pData, (typelib_InterfaceTypeDescription *)pTD ); 562 563 if (pInterface) 564 { 565 ::uno_any_construct( 566 reinterpret_cast< uno_Any * >( pReturn ), 567 &pInterface, pTD, 0 ); 568 (*pInterface->release)( pInterface ); 569 TYPELIB_DANGER_RELEASE( pTD ); 570 *ppException = 0; 571 break; 572 } 573 TYPELIB_DANGER_RELEASE( pTD ); 574 } 575 } // else perform queryInterface() 576 default: 577 // dependent dispatch 578 cpp_call( 579 pThis, aVtableSlot, 580 ((typelib_InterfaceMethodTypeDescription *)pMemberDescr)->pReturnTypeRef, 581 ((typelib_InterfaceMethodTypeDescription *)pMemberDescr)->nParams, 582 ((typelib_InterfaceMethodTypeDescription *)pMemberDescr)->pParams, 583 pReturn, pArgs, ppException ); 584 } 585 break; 586 } 587 default: 588 { 589 ::com::sun::star::uno::RuntimeException aExc( 590 OUString( RTL_CONSTASCII_USTRINGPARAM("illegal member type description!") ), 591 ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >() ); 592 593 Type const & rExcType = ::getCppuType( &aExc ); 594 // binary identical null reference 595 ::uno_type_any_construct( *ppException, &aExc, rExcType.getTypeLibType(), 0 ); 596 } 597 } 598 } 599 600 } } } 601