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 <typeinfo> 28 #include <exception> 29 #include <cstddef> 30 #include <cxxabi.h> 31 #include <stdio.h> 32 #include <stdlib.h> 33 #include <string.h> 34 35 #include "rtl/alloc.h" 36 #include "rtl/ustrbuf.hxx" 37 38 #include <com/sun/star/uno/genfunc.hxx> 39 #include "com/sun/star/uno/RuntimeException.hpp" 40 #include <uno/data.h> 41 42 #include <bridges/cpp_uno/shared/bridge.hxx> 43 #include <bridges/cpp_uno/shared/types.hxx> 44 #include "bridges/cpp_uno/shared/unointerfaceproxy.hxx" 45 #include "bridges/cpp_uno/shared/vtables.hxx" 46 47 #include "abi.hxx" 48 #include "share.hxx" 49 50 using namespace ::rtl; 51 using namespace ::com::sun::star::uno; 52 #ifdef __GLIBCXX__ 53 using CPPU_CURRENT_NAMESPACE::__cxa_get_globals; 54 #else 55 using __cxxabiv1::__cxa_get_globals; 56 #endif 57 58 //================================================================================================== 59 static void callVirtualMethod(void * pThis, sal_uInt32 nVtableIndex, 60 void * pRegisterReturn, typelib_TypeDescriptionReference * pReturnTypeRef, bool bSimpleReturn, 61 sal_uInt64 *pStack, sal_uInt32 nStack, 62 sal_uInt64 *pGPR, sal_uInt32 nGPR, 63 double *pFPR, sal_uInt32 nFPR) __attribute__((noinline)); 64 65 static void callVirtualMethod(void * pThis, sal_uInt32 nVtableIndex, 66 void * pRegisterReturn, typelib_TypeDescriptionReference * pReturnTypeRef, bool bSimpleReturn, 67 sal_uInt64 *pStack, sal_uInt32 nStack, 68 sal_uInt64 *pGPR, sal_uInt32 nGPR, 69 double *pFPR, sal_uInt32 nFPR) 70 { 71 #if OSL_DEBUG_LEVEL > 1 72 // Let's figure out what is really going on here 73 { 74 fprintf( stderr, "= callVirtualMethod() =\nGPR's (%d): ", nGPR ); 75 for ( unsigned int i = 0; i < nGPR; ++i ) 76 fprintf( stderr, "0x%lx, ", pGPR[i] ); 77 fprintf( stderr, "\nFPR's (%d): ", nFPR ); 78 for ( unsigned int i = 0; i < nFPR; ++i ) 79 fprintf( stderr, "%f, ", pFPR[i] ); 80 fprintf( stderr, "\nStack (%d): ", nStack ); 81 for ( unsigned int i = 0; i < nStack; ++i ) 82 fprintf( stderr, "0x%lx, ", pStack[i] ); 83 fprintf( stderr, "\n" ); 84 } 85 #endif 86 87 // The call instruction within the asm section of callVirtualMethod may throw 88 // exceptions. So that the compiler handles this correctly, it is important 89 // that (a) callVirtualMethod might call dummy_can_throw_anything (although this 90 // never happens at runtime), which in turn can throw exceptions, and (b) 91 // callVirtualMethod is not inlined at its call site (so that any exceptions are 92 // caught which are thrown from the instruction calling callVirtualMethod): 93 if ( !pThis ) 94 CPPU_CURRENT_NAMESPACE::dummy_can_throw_anything( "xxx" ); // address something 95 96 // Should not happen, but... 97 if ( nFPR > x86_64::MAX_SSE_REGS ) 98 nFPR = x86_64::MAX_SSE_REGS; 99 if ( nGPR > x86_64::MAX_GPR_REGS ) 100 nGPR = x86_64::MAX_GPR_REGS; 101 102 // Get pointer to method 103 sal_uInt64 pMethod = *((sal_uInt64 *)pThis); 104 pMethod += 8 * nVtableIndex; 105 pMethod = *((sal_uInt64 *)pMethod); 106 107 // Load parameters to stack, if necessary 108 sal_uInt64* pCallStack = NULL; 109 if ( nStack ) 110 { 111 // 16-bytes aligned 112 sal_uInt32 nStackBytes = ( ( nStack + 1 ) >> 1 ) * 16; 113 pCallStack = (sal_uInt64*) __builtin_alloca( nStackBytes ); 114 memcpy( pCallStack, pStack, nStackBytes ); 115 } 116 117 // Return values 118 sal_uInt64 rax; 119 sal_uInt64 rdx; 120 double xmm0; 121 double xmm1; 122 123 asm volatile ( 124 // Fill the xmm registers 125 "movq %2, %%rax\n\t" 126 127 "movsd (%%rax), %%xmm0\n\t" 128 "movsd 8(%%rax), %%xmm1\n\t" 129 "movsd 16(%%rax), %%xmm2\n\t" 130 "movsd 24(%%rax), %%xmm3\n\t" 131 "movsd 32(%%rax), %%xmm4\n\t" 132 "movsd 40(%%rax), %%xmm5\n\t" 133 "movsd 48(%%rax), %%xmm6\n\t" 134 "movsd 56(%%rax), %%xmm7\n\t" 135 136 // Fill the general purpose registers 137 "movq %1, %%rax\n\t" 138 139 "movq (%%rax), %%rdi\n\t" 140 "movq 8(%%rax), %%rsi\n\t" 141 "movq 16(%%rax), %%rdx\n\t" 142 "movq 24(%%rax), %%rcx\n\t" 143 "movq 32(%%rax), %%r8\n\t" 144 "movq 40(%%rax), %%r9\n\t" 145 146 // Perform the call 147 "movq %0, %%r11\n\t" 148 "movq %3, %%rax\n\t" 149 "call *%%r11\n\t" 150 151 // Fill the return values 152 "movq %%rax, %4\n\t" 153 "movq %%rdx, %5\n\t" 154 "movsd %%xmm0, %6\n\t" 155 "movsd %%xmm1, %7\n\t" 156 : 157 : "m" ( pMethod ), "m" ( pGPR ), "m" ( pFPR ), "m" ( nFPR ), 158 "m" ( rax ), "m" ( rdx ), "m" ( xmm0 ), "m" ( xmm1 ), 159 "m" (pCallStack) // dummy input to prevent the compiler from optimizing the alloca out 160 : "rax", "rdi", "rsi", "rdx", "rcx", "r8", "r9", "r11" 161 ); 162 163 switch (pReturnTypeRef->eTypeClass) 164 { 165 case typelib_TypeClass_HYPER: 166 case typelib_TypeClass_UNSIGNED_HYPER: 167 *reinterpret_cast<sal_uInt64 *>( pRegisterReturn ) = rax; 168 break; 169 case typelib_TypeClass_LONG: 170 case typelib_TypeClass_UNSIGNED_LONG: 171 case typelib_TypeClass_ENUM: 172 *reinterpret_cast<sal_uInt32 *>( pRegisterReturn ) = *reinterpret_cast<sal_uInt32*>( &rax ); 173 break; 174 case typelib_TypeClass_CHAR: 175 case typelib_TypeClass_SHORT: 176 case typelib_TypeClass_UNSIGNED_SHORT: 177 *reinterpret_cast<sal_uInt16 *>( pRegisterReturn ) = *reinterpret_cast<sal_uInt16*>( &rax ); 178 break; 179 case typelib_TypeClass_BOOLEAN: 180 case typelib_TypeClass_BYTE: 181 *reinterpret_cast<sal_uInt8 *>( pRegisterReturn ) = *reinterpret_cast<sal_uInt8*>( &rax ); 182 break; 183 case typelib_TypeClass_FLOAT: 184 case typelib_TypeClass_DOUBLE: 185 *reinterpret_cast<double *>( pRegisterReturn ) = xmm0; 186 break; 187 default: 188 { 189 sal_Int32 const nRetSize = pReturnTypeRef->pType->nSize; 190 if (bSimpleReturn && nRetSize <= 16 && nRetSize > 0) 191 { 192 sal_uInt64 longs[2]; 193 longs[0] = rax; 194 longs[1] = rdx; 195 196 double doubles[2]; 197 doubles[0] = xmm0; 198 doubles[1] = xmm1; 199 x86_64::fill_struct( pReturnTypeRef, &longs[0], &doubles[0], pRegisterReturn); 200 } 201 break; 202 } 203 } 204 } 205 206 //================================================================================================== 207 208 // Macros for easier insertion of values to registers or stack 209 // pSV - pointer to the source 210 // nr - order of the value [will be increased if stored to register] 211 // pFPR, pGPR - pointer to the registers 212 // pDS - pointer to the stack [will be increased if stored here] 213 214 // The value in %xmm register is already prepared to be retrieved as a float, 215 // thus we treat float and double the same 216 #define INSERT_FLOAT_DOUBLE( pSV, nr, pFPR, pDS ) \ 217 if ( nr < x86_64::MAX_SSE_REGS ) \ 218 pFPR[nr++] = *reinterpret_cast<double *>( pSV ); \ 219 else \ 220 *pDS++ = *reinterpret_cast<sal_uInt64 *>( pSV ); // verbatim! 221 222 #define INSERT_INT64( pSV, nr, pGPR, pDS ) \ 223 if ( nr < x86_64::MAX_GPR_REGS ) \ 224 pGPR[nr++] = *reinterpret_cast<sal_uInt64 *>( pSV ); \ 225 else \ 226 *pDS++ = *reinterpret_cast<sal_uInt64 *>( pSV ); 227 228 #define INSERT_INT32( pSV, nr, pGPR, pDS ) \ 229 if ( nr < x86_64::MAX_GPR_REGS ) \ 230 pGPR[nr++] = *reinterpret_cast<sal_uInt32 *>( pSV ); \ 231 else \ 232 *pDS++ = *reinterpret_cast<sal_uInt32 *>( pSV ); 233 234 #define INSERT_INT16( pSV, nr, pGPR, pDS ) \ 235 if ( nr < x86_64::MAX_GPR_REGS ) \ 236 pGPR[nr++] = *reinterpret_cast<sal_uInt16 *>( pSV ); \ 237 else \ 238 *pDS++ = *reinterpret_cast<sal_uInt16 *>( pSV ); 239 240 #define INSERT_INT8( pSV, nr, pGPR, pDS ) \ 241 if ( nr < x86_64::MAX_GPR_REGS ) \ 242 pGPR[nr++] = *reinterpret_cast<sal_uInt8 *>( pSV ); \ 243 else \ 244 *pDS++ = *reinterpret_cast<sal_uInt8 *>( pSV ); 245 246 //================================================================================================== 247 248 namespace { 249 250 void appendCString(OUStringBuffer & buffer, char const * text) { 251 if (text != 0) { 252 buffer.append( 253 OStringToOUString(OString(text), RTL_TEXTENCODING_ISO_8859_1)); 254 // use 8859-1 to avoid conversion failure 255 } 256 } 257 258 } 259 260 static void cpp_call( 261 bridges::cpp_uno::shared::UnoInterfaceProxy * pThis, 262 bridges::cpp_uno::shared::VtableSlot aVtableSlot, 263 typelib_TypeDescriptionReference * pReturnTypeRef, 264 sal_Int32 nParams, typelib_MethodParameter * pParams, 265 void * pUnoReturn, void * pUnoArgs[], uno_Any ** ppUnoExc ) 266 { 267 // Maxium space for [complex ret ptr], values | ptr ... 268 // (but will be used less - some of the values will be in pGPR and pFPR) 269 sal_uInt64 *pStack = (sal_uInt64 *)__builtin_alloca( (nParams + 3) * sizeof(sal_uInt64) ); 270 sal_uInt64 *pStackStart = pStack; 271 272 sal_uInt64 pGPR[x86_64::MAX_GPR_REGS]; 273 sal_uInt32 nGPR = 0; 274 275 double pFPR[x86_64::MAX_SSE_REGS]; 276 sal_uInt32 nFPR = 0; 277 278 // Return 279 typelib_TypeDescription * pReturnTypeDescr = 0; 280 TYPELIB_DANGER_GET( &pReturnTypeDescr, pReturnTypeRef ); 281 OSL_ENSURE( pReturnTypeDescr, "### expected return type description!" ); 282 283 void * pCppReturn = 0; // if != 0 && != pUnoReturn, needs reconversion (see below) 284 285 bool bSimpleReturn = true; 286 if ( pReturnTypeDescr ) 287 { 288 if ( x86_64::return_in_hidden_param( pReturnTypeRef ) ) 289 bSimpleReturn = false; 290 291 if ( bSimpleReturn ) 292 pCppReturn = pUnoReturn; // direct way for simple types 293 else 294 { 295 // complex return via ptr 296 pCppReturn = bridges::cpp_uno::shared::relatesToInterfaceType( pReturnTypeDescr )? 297 __builtin_alloca( pReturnTypeDescr->nSize ) : pUnoReturn; 298 INSERT_INT64( &pCppReturn, nGPR, pGPR, pStack ); 299 } 300 } 301 302 // Push "this" pointer 303 void * pAdjustedThisPtr = reinterpret_cast< void ** >( pThis->getCppI() ) + aVtableSlot.offset; 304 INSERT_INT64( &pAdjustedThisPtr, nGPR, pGPR, pStack ); 305 306 // Args 307 void ** pCppArgs = (void **)alloca( 3 * sizeof(void *) * nParams ); 308 // Indizes of values this have to be converted (interface conversion cpp<=>uno) 309 sal_Int32 * pTempIndizes = (sal_Int32 *)(pCppArgs + nParams); 310 // Type descriptions for reconversions 311 typelib_TypeDescription ** ppTempParamTypeDescr = (typelib_TypeDescription **)(pCppArgs + (2 * nParams)); 312 313 sal_Int32 nTempIndizes = 0; 314 315 for ( sal_Int32 nPos = 0; nPos < nParams; ++nPos ) 316 { 317 const typelib_MethodParameter & rParam = pParams[nPos]; 318 typelib_TypeDescription * pParamTypeDescr = 0; 319 TYPELIB_DANGER_GET( &pParamTypeDescr, rParam.pTypeRef ); 320 321 if (!rParam.bOut && bridges::cpp_uno::shared::isSimpleType( pParamTypeDescr )) 322 { 323 uno_copyAndConvertData( pCppArgs[nPos] = alloca( 8 ), pUnoArgs[nPos], pParamTypeDescr, 324 pThis->getBridge()->getUno2Cpp() ); 325 326 switch (pParamTypeDescr->eTypeClass) 327 { 328 case typelib_TypeClass_HYPER: 329 case typelib_TypeClass_UNSIGNED_HYPER: 330 INSERT_INT64( pCppArgs[nPos], nGPR, pGPR, pStack ); 331 break; 332 case typelib_TypeClass_LONG: 333 case typelib_TypeClass_UNSIGNED_LONG: 334 case typelib_TypeClass_ENUM: 335 INSERT_INT32( pCppArgs[nPos], nGPR, pGPR, pStack ); 336 break; 337 case typelib_TypeClass_SHORT: 338 case typelib_TypeClass_CHAR: 339 case typelib_TypeClass_UNSIGNED_SHORT: 340 INSERT_INT16( pCppArgs[nPos], nGPR, pGPR, pStack ); 341 break; 342 case typelib_TypeClass_BOOLEAN: 343 case typelib_TypeClass_BYTE: 344 INSERT_INT8( pCppArgs[nPos], nGPR, pGPR, pStack ); 345 break; 346 case typelib_TypeClass_FLOAT: 347 case typelib_TypeClass_DOUBLE: 348 INSERT_FLOAT_DOUBLE( pCppArgs[nPos], nFPR, pFPR, pStack ); 349 break; 350 default: 351 break; 352 } 353 354 // no longer needed 355 TYPELIB_DANGER_RELEASE( pParamTypeDescr ); 356 } 357 else // ptr to complex value | ref 358 { 359 if (! rParam.bIn) // is pure out 360 { 361 // cpp out is constructed mem, uno out is not! 362 uno_constructData( 363 pCppArgs[nPos] = alloca( pParamTypeDescr->nSize ), 364 pParamTypeDescr ); 365 pTempIndizes[nTempIndizes] = nPos; // default constructed for cpp call 366 // will be released at reconversion 367 ppTempParamTypeDescr[nTempIndizes++] = pParamTypeDescr; 368 } 369 // is in/inout 370 else if (bridges::cpp_uno::shared::relatesToInterfaceType( pParamTypeDescr )) 371 { 372 uno_copyAndConvertData( 373 pCppArgs[nPos] = alloca( pParamTypeDescr->nSize ), 374 pUnoArgs[nPos], pParamTypeDescr, pThis->getBridge()->getUno2Cpp() ); 375 376 pTempIndizes[nTempIndizes] = nPos; // has to be reconverted 377 // will be released at reconversion 378 ppTempParamTypeDescr[nTempIndizes++] = pParamTypeDescr; 379 } 380 else // direct way 381 { 382 pCppArgs[nPos] = pUnoArgs[nPos]; 383 // no longer needed 384 TYPELIB_DANGER_RELEASE( pParamTypeDescr ); 385 } 386 INSERT_INT64( &(pCppArgs[nPos]), nGPR, pGPR, pStack ); 387 } 388 } 389 390 try 391 { 392 try { 393 callVirtualMethod( 394 pAdjustedThisPtr, aVtableSlot.index, 395 pCppReturn, pReturnTypeRef, bSimpleReturn, 396 pStackStart, ( pStack - pStackStart ), 397 pGPR, nGPR, 398 pFPR, nFPR ); 399 } catch (Exception &) { 400 throw; 401 } catch (std::exception & e) { 402 OUStringBuffer buf; 403 buf.appendAscii(RTL_CONSTASCII_STRINGPARAM("C++ code threw ")); 404 appendCString(buf, typeid(e).name()); 405 buf.appendAscii(RTL_CONSTASCII_STRINGPARAM(": ")); 406 appendCString(buf, e.what()); 407 throw RuntimeException( 408 buf.makeStringAndClear(), Reference< XInterface >()); 409 } catch (...) { 410 throw RuntimeException( 411 OUString( 412 RTL_CONSTASCII_USTRINGPARAM( 413 "C++ code threw unknown exception")), 414 Reference< XInterface >()); 415 } 416 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 CPPU_CURRENT_NAMESPACE::fillUnoException( __cxa_get_globals()->caughtExceptions, *ppUnoExc, pThis->getBridge()->getCpp2Uno() ); 457 458 // temporary params 459 for ( ; nTempIndizes--; ) 460 { 461 sal_Int32 nIndex = pTempIndizes[nTempIndizes]; 462 // destroy temp cpp param => cpp: every param was constructed 463 uno_destructData( pCppArgs[nIndex], ppTempParamTypeDescr[nTempIndizes], cpp_release ); 464 TYPELIB_DANGER_RELEASE( ppTempParamTypeDescr[nTempIndizes] ); 465 } 466 // return type 467 if (pReturnTypeDescr) 468 TYPELIB_DANGER_RELEASE( pReturnTypeDescr ); 469 } 470 } 471 472 //================================================================================================== 473 474 namespace bridges { namespace cpp_uno { namespace shared { 475 476 void unoInterfaceProxyDispatch( 477 uno_Interface * pUnoI, const typelib_TypeDescription * pMemberDescr, 478 void * pReturn, void * pArgs[], uno_Any ** ppException ) 479 { 480 // is my surrogate 481 bridges::cpp_uno::shared::UnoInterfaceProxy * pThis 482 = static_cast< bridges::cpp_uno::shared::UnoInterfaceProxy * >(pUnoI); 483 #if OSL_DEBUG_LEVEL > 0 484 typelib_InterfaceTypeDescription * pTypeDescr = pThis->pTypeDescr; 485 #endif 486 487 switch (pMemberDescr->eTypeClass) 488 { 489 case typelib_TypeClass_INTERFACE_ATTRIBUTE: 490 { 491 #if OSL_DEBUG_LEVEL > 0 492 // determine vtable call index 493 sal_Int32 nMemberPos = ((typelib_InterfaceMemberTypeDescription *)pMemberDescr)->nPosition; 494 OSL_ENSURE( nMemberPos < pTypeDescr->nAllMembers, "### member pos out of range!" ); 495 #endif 496 VtableSlot aVtableSlot( 497 getVtableSlot( 498 reinterpret_cast< 499 typelib_InterfaceAttributeTypeDescription const * >( 500 pMemberDescr))); 501 502 if (pReturn) 503 { 504 // dependent dispatch 505 cpp_call( 506 pThis, aVtableSlot, 507 ((typelib_InterfaceAttributeTypeDescription *)pMemberDescr)->pAttributeTypeRef, 508 0, 0, // no params 509 pReturn, pArgs, ppException ); 510 } 511 else 512 { 513 // is SET 514 typelib_MethodParameter aParam; 515 aParam.pTypeRef = 516 ((typelib_InterfaceAttributeTypeDescription *)pMemberDescr)->pAttributeTypeRef; 517 aParam.bIn = sal_True; 518 aParam.bOut = sal_False; 519 520 typelib_TypeDescriptionReference * pReturnTypeRef = 0; 521 OUString aVoidName( RTL_CONSTASCII_USTRINGPARAM("void") ); 522 typelib_typedescriptionreference_new( 523 &pReturnTypeRef, typelib_TypeClass_VOID, aVoidName.pData ); 524 525 // dependent dispatch 526 aVtableSlot.index += 1; // get, then set method 527 cpp_call( 528 pThis, aVtableSlot, // get, then set method 529 pReturnTypeRef, 530 1, &aParam, 531 pReturn, pArgs, ppException ); 532 533 typelib_typedescriptionreference_release( pReturnTypeRef ); 534 } 535 536 break; 537 } 538 case typelib_TypeClass_INTERFACE_METHOD: 539 { 540 #if OSL_DEBUG_LEVEL > 0 541 // determine vtable call index 542 sal_Int32 nMemberPos = ((typelib_InterfaceMemberTypeDescription *)pMemberDescr)->nPosition; 543 OSL_ENSURE( nMemberPos < pTypeDescr->nAllMembers, "### member pos out of range!" ); 544 #endif 545 VtableSlot aVtableSlot( 546 getVtableSlot( 547 reinterpret_cast< 548 typelib_InterfaceMethodTypeDescription const * >( 549 pMemberDescr))); 550 551 switch (aVtableSlot.index) 552 { 553 // standard calls 554 case 1: // acquire uno interface 555 (*pUnoI->acquire)( pUnoI ); 556 *ppException = 0; 557 break; 558 case 2: // release uno interface 559 (*pUnoI->release)( pUnoI ); 560 *ppException = 0; 561 break; 562 case 0: // queryInterface() opt 563 { 564 typelib_TypeDescription * pTD = 0; 565 TYPELIB_DANGER_GET( &pTD, reinterpret_cast< Type * >( pArgs[0] )->getTypeLibType() ); 566 if (pTD) 567 { 568 uno_Interface * pInterface = 0; 569 (*pThis->getBridge()->getUnoEnv()->getRegisteredInterface)( 570 pThis->getBridge()->getUnoEnv(), 571 (void **)&pInterface, pThis->oid.pData, (typelib_InterfaceTypeDescription *)pTD ); 572 573 if (pInterface) 574 { 575 ::uno_any_construct( 576 reinterpret_cast< uno_Any * >( pReturn ), 577 &pInterface, pTD, 0 ); 578 (*pInterface->release)( pInterface ); 579 TYPELIB_DANGER_RELEASE( pTD ); 580 *ppException = 0; 581 break; 582 } 583 TYPELIB_DANGER_RELEASE( pTD ); 584 } 585 } // else perform queryInterface() 586 default: 587 // dependent dispatch 588 cpp_call( 589 pThis, aVtableSlot, 590 ((typelib_InterfaceMethodTypeDescription *)pMemberDescr)->pReturnTypeRef, 591 ((typelib_InterfaceMethodTypeDescription *)pMemberDescr)->nParams, 592 ((typelib_InterfaceMethodTypeDescription *)pMemberDescr)->pParams, 593 pReturn, pArgs, ppException ); 594 } 595 break; 596 } 597 default: 598 { 599 ::com::sun::star::uno::RuntimeException aExc( 600 OUString( RTL_CONSTASCII_USTRINGPARAM("illegal member type description!") ), 601 ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >() ); 602 603 Type const & rExcType = ::getCppuType( &aExc ); 604 // binary identical null reference 605 ::uno_type_any_construct( *ppException, &aExc, rExcType.getTypeLibType(), 0 ); 606 } 607 } 608 } 609 610 } } } 611