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