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 #include <malloc.h> 25 #include <rtl/alloc.h> 26 27 #include <com/sun/star/uno/genfunc.hxx> 28 #include "com/sun/star/uno/RuntimeException.hpp" 29 #include <uno/data.h> 30 31 #include <bridges/cpp_uno/shared/bridge.hxx> 32 #include <bridges/cpp_uno/shared/types.hxx> 33 #include <bridges/cpp_uno/shared/unointerfaceproxy.hxx> 34 #include <bridges/cpp_uno/shared/vtables.hxx> 35 36 #include "share.hxx" 37 38 #include <stdio.h> 39 #include <string.h> 40 41 /* 42 * Based on http://gcc.gnu.org/PR41443 43 * References to __SOFTFP__ are incorrect for EABI; the __SOFTFP__ code 44 * should be used for *soft-float ABI* whether or not VFP is enabled, 45 * and __SOFTFP__ does specifically mean soft-float not soft-float ABI. 46 * 47 * Changing the conditionals to __SOFTFP__ || __ARM_EABI__ then 48 * -mfloat-abi=softfp should work. -mfloat-abi=hard won't; that would 49 * need both a new macro to identify the hard-VFP ABI. 50 */ 51 #if !defined(__ARM_EABI__) && !defined(__SOFTFP__) 52 #error Not Implemented 53 54 /* 55 some possibly handy code to detect that we have VFP registers 56 */ 57 58 #include <sys/types.h> 59 #include <sys/stat.h> 60 #include <fcntl.h> 61 #include <unistd.h> 62 #include <elf.h> 63 64 #define HWCAP_ARM_VFP 64 65 66 int hasVFP(void) 67 { 68 int fd = open ("/proc/self/auxv", O_RDONLY); 69 if (fd == -1) 70 return -1; 71 72 int ret = -1; 73 74 Elf32_auxv_t buf[128]; 75 ssize_t n; 76 while ((ret == -1) && ((n = read(fd, buf, sizeof (buf))) > 0)) 77 { 78 for (int i = 0; i < 128; ++i) 79 { 80 if (buf[i].a_type == AT_HWCAP) 81 { 82 ret = (buf[i].a_un.a_val & HWCAP_ARM_VFP) ? true : false; 83 break; 84 } 85 else if (buf[i].a_type == AT_NULL) 86 { 87 ret = -2; 88 break; 89 } 90 } 91 } 92 93 close (fd); 94 return ret; 95 } 96 97 #endif 98 99 using namespace ::rtl; 100 using namespace ::com::sun::star::uno; 101 102 namespace arm 103 { 104 bool is_complex_struct(const typelib_TypeDescription * type) 105 { 106 const typelib_CompoundTypeDescription * p 107 = reinterpret_cast< const typelib_CompoundTypeDescription * >(type); 108 for (sal_Int32 i = 0; i < p->nMembers; ++i) 109 { 110 if (p->ppTypeRefs[i]->eTypeClass == typelib_TypeClass_STRUCT || 111 p->ppTypeRefs[i]->eTypeClass == typelib_TypeClass_EXCEPTION) 112 { 113 typelib_TypeDescription * t = 0; 114 TYPELIB_DANGER_GET(&t, p->ppTypeRefs[i]); 115 bool b = is_complex_struct(t); 116 TYPELIB_DANGER_RELEASE(t); 117 if (b) { 118 return true; 119 } 120 } 121 else if (!bridges::cpp_uno::shared::isSimpleType(p->ppTypeRefs[i]->eTypeClass)) 122 return true; 123 } 124 if (p->pBaseTypeDescription != 0) 125 return is_complex_struct(&p->pBaseTypeDescription->aBase); 126 return false; 127 } 128 129 bool return_in_hidden_param( typelib_TypeDescriptionReference *pTypeRef ) 130 { 131 if (bridges::cpp_uno::shared::isSimpleType(pTypeRef)) 132 return false; 133 else if (pTypeRef->eTypeClass == typelib_TypeClass_STRUCT || pTypeRef->eTypeClass == typelib_TypeClass_EXCEPTION) 134 { 135 typelib_TypeDescription * pTypeDescr = 0; 136 TYPELIB_DANGER_GET( &pTypeDescr, pTypeRef ); 137 138 //A Composite Type not larger than 4 bytes is returned in r0 139 bool bRet = pTypeDescr->nSize > 4 || is_complex_struct(pTypeDescr); 140 141 TYPELIB_DANGER_RELEASE( pTypeDescr ); 142 return bRet; 143 } 144 return true; 145 } 146 } 147 148 void MapReturn(sal_uInt32 r0, sal_uInt32 r1, typelib_TypeDescriptionReference * pReturnType, sal_uInt32* pRegisterReturn) 149 { 150 #if !defined(__ARM_EABI__) && !defined(__SOFTFP__) 151 register float fret asm("f0"); 152 register double dret asm("f0"); 153 #endif 154 155 switch( pReturnType->eTypeClass ) 156 { 157 case typelib_TypeClass_HYPER: 158 case typelib_TypeClass_UNSIGNED_HYPER: 159 pRegisterReturn[1] = r1; 160 case typelib_TypeClass_LONG: 161 case typelib_TypeClass_UNSIGNED_LONG: 162 case typelib_TypeClass_ENUM: 163 case typelib_TypeClass_CHAR: 164 case typelib_TypeClass_SHORT: 165 case typelib_TypeClass_UNSIGNED_SHORT: 166 case typelib_TypeClass_BOOLEAN: 167 case typelib_TypeClass_BYTE: 168 pRegisterReturn[0] = r0; 169 break; 170 case typelib_TypeClass_FLOAT: 171 #if defined(__ARM_EABI__) || defined(__SOFTFP__) 172 pRegisterReturn[0] = r0; 173 #else 174 *(float*)pRegisterReturn = fret; 175 #endif 176 break; 177 case typelib_TypeClass_DOUBLE: 178 #if defined(__ARM_EABI__) || defined(__SOFTFP__) 179 pRegisterReturn[1] = r1; 180 pRegisterReturn[0] = r0; 181 #else 182 *(double*)pRegisterReturn = dret; 183 #endif 184 break; 185 case typelib_TypeClass_STRUCT: 186 case typelib_TypeClass_EXCEPTION: 187 { 188 if (!arm::return_in_hidden_param(pReturnType)) 189 pRegisterReturn[0] = r0; 190 break; 191 } 192 default: 193 break; 194 } 195 } 196 197 namespace 198 { 199 //================================================================ 200 201 void callVirtualMethod( 202 void * pThis, 203 sal_Int32 nVtableIndex, 204 void * pRegisterReturn, 205 typelib_TypeDescriptionReference * pReturnType, 206 sal_uInt32 *pStack, 207 sal_uInt32 nStack, 208 sal_uInt32 *pGPR, 209 sal_uInt32 nGPR) __attribute__((noinline)); 210 211 void callVirtualMethod( 212 void * pThis, 213 sal_Int32 nVtableIndex, 214 void * pRegisterReturn, 215 typelib_TypeDescriptionReference * pReturnType, 216 sal_uInt32 *pStack, 217 sal_uInt32 nStack, 218 sal_uInt32 *pGPR, 219 sal_uInt32 nGPR) 220 { 221 // never called 222 if (! pThis) 223 CPPU_CURRENT_NAMESPACE::dummy_can_throw_anything("xxx"); // address something 224 225 if ( nStack ) 226 { 227 // 8-bytes aligned 228 sal_uInt32 nStackBytes = ( ( nStack + 1 ) >> 1 ) * 8; 229 sal_uInt32 *stack = (sal_uInt32 *) __builtin_alloca( nStackBytes ); 230 memcpy( stack, pStack, nStackBytes ); 231 } 232 233 // Should not happen, but... 234 if ( nGPR > arm::MAX_GPR_REGS ) 235 nGPR = arm::MAX_GPR_REGS; 236 237 sal_uInt32 pMethod = *((sal_uInt32*)pThis); 238 pMethod += 4 * nVtableIndex; 239 pMethod = *((sal_uInt32 *)pMethod); 240 241 typedef void (*FunctionCall )( sal_uInt32, sal_uInt32, sal_uInt32, sal_uInt32); 242 FunctionCall pFunc = (FunctionCall)pMethod; 243 244 (*pFunc)(pGPR[0], pGPR[1], pGPR[2], pGPR[3]); 245 246 sal_uInt32 r0; 247 sal_uInt32 r1; 248 249 // get return value 250 __asm__ __volatile__ ( 251 "mov %0, r0\n\t" 252 "mov %1, r1\n\t" 253 : "=r" (r0), "=r" (r1) : ); 254 255 MapReturn(r0, r1, pReturnType, (sal_uInt32*)pRegisterReturn); 256 } 257 } 258 259 #define INSERT_INT32( pSV, nr, pGPR, pDS, bOverflow ) \ 260 if ( nr < arm::MAX_GPR_REGS ) \ 261 pGPR[nr++] = *reinterpret_cast<sal_uInt32 *>( pSV ); \ 262 else \ 263 bOverFlow = true; \ 264 if (bOverFlow) \ 265 *pDS++ = *reinterpret_cast<sal_uInt32 *>( pSV ); 266 267 #ifdef __ARM_EABI__ 268 #define INSERT_INT64( pSV, nr, pGPR, pDS, pStart, bOverflow ) \ 269 if ( (nr < arm::MAX_GPR_REGS) && (nr % 2) ) \ 270 { \ 271 ++nr; \ 272 } \ 273 if ( nr < arm::MAX_GPR_REGS ) \ 274 { \ 275 pGPR[nr++] = *reinterpret_cast<sal_uInt32 *>( pSV ); \ 276 pGPR[nr++] = *(reinterpret_cast<sal_uInt32 *>( pSV ) + 1); \ 277 } \ 278 else \ 279 bOverFlow = true; \ 280 if (bOverFlow) \ 281 { \ 282 if ( (pDS - pStart) % 2) \ 283 { \ 284 ++pDS; \ 285 } \ 286 *pDS++ = reinterpret_cast<sal_uInt32 *>( pSV )[0]; \ 287 *pDS++ = reinterpret_cast<sal_uInt32 *>( pSV )[1]; \ 288 } 289 #else 290 #define INSERT_INT64( pSV, nr, pGPR, pDS, pStart, bOverflow ) \ 291 INSERT_INT32( pSV, nr, pGPR, pDS, bOverflow) \ 292 INSERT_INT32( ((sal_uInt32*)pSV)+1, nr, pGPR, pDS, bOverflow) 293 #endif 294 295 #define INSERT_FLOAT( pSV, nr, pFPR, pDS, bOverflow ) \ 296 INSERT_INT32( pSV, nr, pGPR, pDS, bOverflow) 297 298 #define INSERT_DOUBLE( pSV, nr, pFPR, pDS, pStart, bOverflow ) \ 299 INSERT_INT64( pSV, nr, pGPR, pDS, pStart, bOverflow ) 300 301 #define INSERT_INT16( pSV, nr, pGPR, pDS, bOverflow ) \ 302 if ( nr < arm::MAX_GPR_REGS ) \ 303 pGPR[nr++] = *reinterpret_cast<sal_uInt16 *>( pSV ); \ 304 else \ 305 bOverFlow = true; \ 306 if (bOverFlow) \ 307 *pDS++ = *reinterpret_cast<sal_uInt16 *>( pSV ); 308 309 #define INSERT_INT8( pSV, nr, pGPR, pDS, bOverflow ) \ 310 if ( nr < arm::MAX_GPR_REGS ) \ 311 pGPR[nr++] = *reinterpret_cast<sal_uInt8 *>( pSV ); \ 312 else \ 313 bOverFlow = true; \ 314 if (bOverFlow) \ 315 *pDS++ = *reinterpret_cast<sal_uInt8 *>( pSV ); 316 317 namespace { 318 //======================================================================= 319 static void cpp_call( 320 bridges::cpp_uno::shared::UnoInterfaceProxy * pThis, 321 bridges::cpp_uno::shared::VtableSlot aVtableSlot, 322 typelib_TypeDescriptionReference * pReturnTypeRef, 323 sal_Int32 nParams, typelib_MethodParameter * pParams, 324 void * pUnoReturn, void * pUnoArgs[], uno_Any ** ppUnoExc ) 325 { 326 // max space for: [complex ret ptr], values|ptr ... 327 sal_uInt32 * pStack = (sal_uInt32 *)__builtin_alloca( 328 sizeof(sal_Int32) + ((nParams+2) * sizeof(sal_Int64)) ); 329 sal_uInt32 * pStackStart = pStack; 330 331 sal_uInt32 pGPR[arm::MAX_GPR_REGS]; 332 sal_uInt32 nGPR = 0; 333 334 // return 335 typelib_TypeDescription * pReturnTypeDescr = 0; 336 TYPELIB_DANGER_GET( &pReturnTypeDescr, pReturnTypeRef ); 337 OSL_ENSURE( pReturnTypeDescr, "### expected return type description!" ); 338 339 void * pCppReturn = 0; // if != 0 && != pUnoReturn, needs reconversion 340 341 bool bOverFlow = false; 342 bool bSimpleReturn = true; 343 if (pReturnTypeDescr) 344 { 345 if (arm::return_in_hidden_param( pReturnTypeRef ) ) 346 bSimpleReturn = false; 347 348 if (bSimpleReturn) 349 pCppReturn = pUnoReturn; // direct way for simple types 350 else 351 { 352 // complex return via ptr 353 pCppReturn = (bridges::cpp_uno::shared::relatesToInterfaceType( pReturnTypeDescr ) 354 ? __builtin_alloca( pReturnTypeDescr->nSize ) 355 : pUnoReturn); // direct way 356 357 INSERT_INT32( &pCppReturn, nGPR, pGPR, pStack, bOverFlow ); 358 } 359 } 360 // push this 361 void * pAdjustedThisPtr = reinterpret_cast< void ** >(pThis->getCppI()) 362 + aVtableSlot.offset; 363 INSERT_INT32( &pAdjustedThisPtr, nGPR, pGPR, pStack, bOverFlow ); 364 365 // stack space 366 OSL_ENSURE( sizeof(void *) == sizeof(sal_Int32), "### unexpected size!" ); 367 // args 368 void ** pCppArgs = (void **)alloca( 3 * sizeof(void *) * nParams ); 369 // indizes of values this have to be converted (interface conversion cpp<=>uno) 370 sal_Int32 * pTempIndizes = (sal_Int32 *)(pCppArgs + nParams); 371 // type descriptions for reconversions 372 typelib_TypeDescription ** ppTempParamTypeDescr = (typelib_TypeDescription **)(pCppArgs + (2 * nParams)); 373 374 sal_Int32 nTempIndizes = 0; 375 376 for ( sal_Int32 nPos = 0; nPos < nParams; ++nPos ) 377 { 378 const typelib_MethodParameter & rParam = pParams[nPos]; 379 typelib_TypeDescription * pParamTypeDescr = 0; 380 TYPELIB_DANGER_GET( &pParamTypeDescr, rParam.pTypeRef ); 381 382 if (!rParam.bOut && bridges::cpp_uno::shared::isSimpleType( pParamTypeDescr )) 383 { 384 // uno_copyAndConvertData( pCppArgs[nPos] = pStack, pUnoArgs[nPos], 385 uno_copyAndConvertData( pCppArgs[nPos] = alloca(8), pUnoArgs[nPos], 386 pParamTypeDescr, pThis->getBridge()->getUno2Cpp() ); 387 388 switch (pParamTypeDescr->eTypeClass) 389 { 390 case typelib_TypeClass_HYPER: 391 case typelib_TypeClass_UNSIGNED_HYPER: 392 #ifdef CMC_DEBUG 393 fprintf(stderr, "hyper is %lx\n", pCppArgs[nPos]); 394 #endif 395 INSERT_INT64( pCppArgs[nPos], nGPR, pGPR, pStack, pStackStart, bOverFlow ); 396 break; 397 case typelib_TypeClass_LONG: 398 case typelib_TypeClass_UNSIGNED_LONG: 399 case typelib_TypeClass_ENUM: 400 #ifdef CMC_DEBUG 401 fprintf(stderr, "long is %x\n", pCppArgs[nPos]); 402 #endif 403 INSERT_INT32( pCppArgs[nPos], nGPR, pGPR, pStack, bOverFlow ); 404 break; 405 case typelib_TypeClass_SHORT: 406 case typelib_TypeClass_CHAR: 407 case typelib_TypeClass_UNSIGNED_SHORT: 408 INSERT_INT16( pCppArgs[nPos], nGPR, pGPR, pStack, bOverFlow ); 409 break; 410 case typelib_TypeClass_BOOLEAN: 411 case typelib_TypeClass_BYTE: 412 INSERT_INT8( pCppArgs[nPos], nGPR, pGPR, pStack, bOverFlow ); 413 break; 414 case typelib_TypeClass_FLOAT: 415 INSERT_FLOAT( pCppArgs[nPos], nGPR, pGPR, pStack, bOverFlow ); 416 break; 417 case typelib_TypeClass_DOUBLE: 418 INSERT_DOUBLE( pCppArgs[nPos], nGPR, pGPR, pStack, pStackStart, bOverFlow ); 419 break; 420 default: 421 break; 422 } 423 // no longer needed 424 TYPELIB_DANGER_RELEASE( pParamTypeDescr ); 425 } 426 else // ptr to complex value | ref 427 { 428 if (! rParam.bIn) // is pure out 429 { 430 // cpp out is constructed mem, uno out is not! 431 uno_constructData( 432 pCppArgs[nPos] = alloca( pParamTypeDescr->nSize ), 433 pParamTypeDescr ); 434 pTempIndizes[nTempIndizes] = nPos; // default constructed for cpp call 435 // will be released at reconversion 436 ppTempParamTypeDescr[nTempIndizes++] = pParamTypeDescr; 437 } 438 // is in/inout 439 else if (bridges::cpp_uno::shared::relatesToInterfaceType( pParamTypeDescr )) 440 { 441 uno_copyAndConvertData( 442 pCppArgs[nPos] = alloca( pParamTypeDescr->nSize ), 443 pUnoArgs[nPos], pParamTypeDescr, pThis->getBridge()->getUno2Cpp() ); 444 445 pTempIndizes[nTempIndizes] = nPos; // has to be reconverted 446 // will be released at reconversion 447 ppTempParamTypeDescr[nTempIndizes++] = pParamTypeDescr; 448 } 449 else // direct way 450 { 451 pCppArgs[nPos] = pUnoArgs[nPos]; 452 // no longer needed 453 TYPELIB_DANGER_RELEASE( pParamTypeDescr ); 454 } 455 INSERT_INT32( &(pCppArgs[nPos]), nGPR, pGPR, pStack, bOverFlow ); 456 } 457 } 458 459 try 460 { 461 callVirtualMethod( 462 pAdjustedThisPtr, aVtableSlot.index, 463 pCppReturn, pReturnTypeRef, 464 pStackStart, 465 (pStack - pStackStart), 466 pGPR, nGPR); 467 468 // NO exception occurred... 469 *ppUnoExc = 0; 470 471 // reconvert temporary params 472 for ( ; nTempIndizes--; ) 473 { 474 sal_Int32 nIndex = pTempIndizes[nTempIndizes]; 475 typelib_TypeDescription * pParamTypeDescr = ppTempParamTypeDescr[nTempIndizes]; 476 477 if (pParams[nIndex].bIn) 478 { 479 if (pParams[nIndex].bOut) // inout 480 { 481 uno_destructData( pUnoArgs[nIndex], pParamTypeDescr, 0 ); // destroy uno value 482 uno_copyAndConvertData( pUnoArgs[nIndex], pCppArgs[nIndex], pParamTypeDescr, 483 pThis->getBridge()->getCpp2Uno() ); 484 } 485 } 486 else // pure out 487 { 488 uno_copyAndConvertData( pUnoArgs[nIndex], pCppArgs[nIndex], pParamTypeDescr, 489 pThis->getBridge()->getCpp2Uno() ); 490 } 491 // destroy temp cpp param => cpp: every param was constructed 492 uno_destructData( pCppArgs[nIndex], pParamTypeDescr, cpp_release ); 493 494 TYPELIB_DANGER_RELEASE( pParamTypeDescr ); 495 } 496 // return value 497 if (pCppReturn && pUnoReturn != pCppReturn) 498 { 499 uno_copyAndConvertData( pUnoReturn, pCppReturn, pReturnTypeDescr, 500 pThis->getBridge()->getCpp2Uno() ); 501 uno_destructData( pCppReturn, pReturnTypeDescr, cpp_release ); 502 } 503 } 504 catch (...) 505 { 506 // __asm__ __volatile__ ("sub sp, sp, #2048\n"); 507 508 // fill uno exception 509 fillUnoException( CPPU_CURRENT_NAMESPACE::__cxa_get_globals()->caughtExceptions, *ppUnoExc, pThis->getBridge()->getCpp2Uno() ); 510 511 // temporary params 512 for ( ; nTempIndizes--; ) 513 { 514 sal_Int32 nIndex = pTempIndizes[nTempIndizes]; 515 // destroy temp cpp param => cpp: every param was constructed 516 uno_destructData( pCppArgs[nIndex], ppTempParamTypeDescr[nTempIndizes], cpp_release ); 517 TYPELIB_DANGER_RELEASE( ppTempParamTypeDescr[nTempIndizes] ); 518 } 519 520 // return type 521 if (pReturnTypeDescr) 522 TYPELIB_DANGER_RELEASE( pReturnTypeDescr ); 523 } 524 } 525 } 526 527 namespace bridges { namespace cpp_uno { namespace shared { 528 529 void unoInterfaceProxyDispatch( 530 uno_Interface * pUnoI, const typelib_TypeDescription * pMemberDescr, 531 void * pReturn, void * pArgs[], uno_Any ** ppException ) 532 { 533 // is my surrogate 534 bridges::cpp_uno::shared::UnoInterfaceProxy * pThis 535 = static_cast< bridges::cpp_uno::shared::UnoInterfaceProxy * >(pUnoI); 536 #if OSL_DEBUG_LEVEL > 0 537 typelib_InterfaceTypeDescription * pTypeDescr = pThis->pTypeDescr; 538 #endif 539 540 switch (pMemberDescr->eTypeClass) 541 { 542 case typelib_TypeClass_INTERFACE_ATTRIBUTE: 543 { 544 #if OSL_DEBUG_LEVEL > 0 545 // determine vtable call index 546 sal_Int32 nMemberPos = ((typelib_InterfaceMemberTypeDescription *)pMemberDescr)->nPosition; 547 OSL_ENSURE( nMemberPos < pTypeDescr->nAllMembers, "### member pos out of range!" ); 548 #endif 549 550 VtableSlot aVtableSlot( 551 getVtableSlot( 552 reinterpret_cast<typelib_InterfaceAttributeTypeDescription const *> 553 (pMemberDescr))); 554 555 if (pReturn) 556 { 557 // dependent dispatch 558 cpp_call( 559 pThis, aVtableSlot, 560 ((typelib_InterfaceAttributeTypeDescription *)pMemberDescr)->pAttributeTypeRef, 561 0, 0, // no params 562 pReturn, pArgs, ppException ); 563 } 564 else 565 { 566 // is SET 567 typelib_MethodParameter aParam; 568 aParam.pTypeRef = 569 ((typelib_InterfaceAttributeTypeDescription *)pMemberDescr)->pAttributeTypeRef; 570 aParam.bIn = sal_True; 571 aParam.bOut = sal_False; 572 573 typelib_TypeDescriptionReference * pReturnTypeRef = 0; 574 OUString aVoidName( RTL_CONSTASCII_USTRINGPARAM("void") ); 575 typelib_typedescriptionreference_new( 576 &pReturnTypeRef, typelib_TypeClass_VOID, aVoidName.pData ); 577 578 // dependent dispatch 579 aVtableSlot.index += 1; 580 cpp_call( 581 pThis, aVtableSlot, // get, then set method 582 pReturnTypeRef, 583 1, &aParam, 584 pReturn, pArgs, ppException ); 585 586 typelib_typedescriptionreference_release( pReturnTypeRef ); 587 } 588 589 break; 590 } 591 case typelib_TypeClass_INTERFACE_METHOD: 592 { 593 #if OSL_DEBUG_LEVEL > 0 594 // determine vtable call index 595 sal_Int32 nMemberPos = ((typelib_InterfaceMemberTypeDescription *)pMemberDescr)->nPosition; 596 OSL_ENSURE( nMemberPos < pTypeDescr->nAllMembers, "### member pos out of range!" ); 597 #endif 598 599 VtableSlot aVtableSlot( 600 getVtableSlot( 601 reinterpret_cast<typelib_InterfaceMethodTypeDescription const *> 602 (pMemberDescr))); 603 604 switch (aVtableSlot.index) 605 { 606 // standard calls 607 case 1: // acquire uno interface 608 (*pUnoI->acquire)( pUnoI ); 609 *ppException = 0; 610 break; 611 case 2: // release uno interface 612 (*pUnoI->release)( pUnoI ); 613 *ppException = 0; 614 break; 615 case 0: // queryInterface() opt 616 { 617 typelib_TypeDescription * pTD = 0; 618 TYPELIB_DANGER_GET( &pTD, reinterpret_cast< Type * >( pArgs[0] )->getTypeLibType() ); 619 if (pTD) 620 { 621 uno_Interface * pInterface = 0; 622 (*pThis->getBridge()->getUnoEnv()->getRegisteredInterface)( 623 pThis->getBridge()->getUnoEnv(), 624 (void **)&pInterface, pThis->oid.pData, (typelib_InterfaceTypeDescription *)pTD ); 625 626 if (pInterface) 627 { 628 ::uno_any_construct( 629 reinterpret_cast< uno_Any * >( pReturn ), 630 &pInterface, pTD, 0 ); 631 (*pInterface->release)( pInterface ); 632 TYPELIB_DANGER_RELEASE( pTD ); 633 *ppException = 0; 634 break; 635 } 636 TYPELIB_DANGER_RELEASE( pTD ); 637 } 638 } // else perform queryInterface() 639 default: 640 // dependent dispatch 641 cpp_call( 642 pThis, aVtableSlot, 643 ((typelib_InterfaceMethodTypeDescription *)pMemberDescr)->pReturnTypeRef, 644 ((typelib_InterfaceMethodTypeDescription *)pMemberDescr)->nParams, 645 ((typelib_InterfaceMethodTypeDescription *)pMemberDescr)->pParams, 646 pReturn, pArgs, ppException ); 647 } 648 break; 649 } 650 default: 651 { 652 ::com::sun::star::uno::RuntimeException aExc( 653 OUString( RTL_CONSTASCII_USTRINGPARAM("illegal member type description!") ), 654 ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >() ); 655 656 Type const & rExcType = ::getCppuType( &aExc ); 657 // binary identical null reference 658 ::uno_type_any_construct( *ppException, &aExc, rExcType.getTypeLibType(), 0 ); 659 } 660 } 661 } 662 663 } } } 664 665 /* vi:set tabstop=4 shiftwidth=4 expandtab: */ 666