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 <com/sun/star/uno/genfunc.hxx> 28 #include <uno/data.h> 29 #include <typelib/typedescription.hxx> 30 31 #include "bridges/cpp_uno/shared/bridge.hxx" 32 #include "bridges/cpp_uno/shared/cppinterfaceproxy.hxx" 33 #include "bridges/cpp_uno/shared/types.hxx" 34 #include "bridges/cpp_uno/shared/vtablefactory.hxx" 35 36 #include "share.hxx" 37 #include <stdio.h> 38 #include <string.h> 39 40 using namespace ::com::sun::star::uno; 41 42 namespace 43 { 44 45 static typelib_TypeClass cpp2uno_call( 46 bridges::cpp_uno::shared::CppInterfaceProxy * pThis, 47 const typelib_TypeDescription * pMemberTypeDescr, 48 typelib_TypeDescriptionReference * pReturnTypeRef, // 0 indicates void return 49 sal_Int32 nParams, typelib_MethodParameter * pParams, 50 void ** gpreg, void ** fpreg, void ** ovrflw, 51 sal_Int64 * pRegisterReturn /* space for register return */ ) 52 { 53 int ng = 0; //number of gpr registers used 54 int nf = 0; //number of fpr regsiters used 55 void ** pCppStack; //temporary stack pointer 56 57 // gpreg: [ret *], this, [gpr params] 58 // fpreg: [fpr params] 59 // ovrflw: [gpr or fpr params (properly aligned)] 60 61 // return 62 typelib_TypeDescription * pReturnTypeDescr = 0; 63 if (pReturnTypeRef) 64 TYPELIB_DANGER_GET( &pReturnTypeDescr, pReturnTypeRef ); 65 66 void * pUnoReturn = 0; 67 void * pCppReturn = 0; // complex return ptr: if != 0 && != pUnoReturn, reconversion need 68 69 if (pReturnTypeDescr) 70 { 71 if (bridges::cpp_uno::shared::isSimpleType( pReturnTypeDescr )) 72 { 73 pUnoReturn = pRegisterReturn; // direct way for simple types 74 } 75 else // complex return via ptr (pCppReturn) 76 { 77 pCppReturn = *(void **)gpreg; 78 gpreg++; 79 ng++; 80 81 pUnoReturn = (bridges::cpp_uno::shared::relatesToInterfaceType( pReturnTypeDescr ) 82 ? alloca( pReturnTypeDescr->nSize ) 83 : pCppReturn); // direct way 84 } 85 } 86 // pop this 87 gpreg++; 88 ng++; 89 90 // stack space 91 OSL_ENSURE( sizeof(void *) == sizeof(sal_Int32), "### unexpected size!" ); 92 // parameters 93 void ** pUnoArgs = (void **)alloca( 4 * sizeof(void *) * nParams ); 94 void ** pCppArgs = pUnoArgs + nParams; 95 // indizes of values this have to be converted (interface conversion cpp<=>uno) 96 sal_Int32 * pTempIndizes = (sal_Int32 *)(pUnoArgs + (2 * nParams)); 97 // type descriptions for reconversions 98 typelib_TypeDescription ** ppTempParamTypeDescr = (typelib_TypeDescription **)(pUnoArgs + (3 * nParams)); 99 100 sal_Int32 nTempIndizes = 0; 101 102 for ( sal_Int32 nPos = 0; nPos < nParams; ++nPos ) 103 { 104 const typelib_MethodParameter & rParam = pParams[nPos]; 105 typelib_TypeDescription * pParamTypeDescr = 0; 106 TYPELIB_DANGER_GET( &pParamTypeDescr, rParam.pTypeRef ); 107 108 if (!rParam.bOut && bridges::cpp_uno::shared::isSimpleType( pParamTypeDescr )) // value 109 { 110 111 switch (pParamTypeDescr->eTypeClass) 112 { 113 114 case typelib_TypeClass_DOUBLE: 115 if (nf < 2) { 116 pCppArgs[nPos] = fpreg; 117 pUnoArgs[nPos] = fpreg; 118 nf++; 119 fpreg += 2; 120 } else { 121 pCppArgs[nPos] = ovrflw; 122 pUnoArgs[nPos] = ovrflw; 123 ovrflw += 2; 124 } 125 break; 126 127 case typelib_TypeClass_FLOAT: 128 // fpreg are all double values so need to 129 // modify fpreg to be a single word float value 130 if (nf < 2) { 131 // float tmp = (float) (*((double *)fpreg)); 132 // (*((float *) fpreg)) = tmp; 133 pCppArgs[nPos] = fpreg; 134 pUnoArgs[nPos] = fpreg; 135 nf++; 136 fpreg += 2; 137 } else { 138 pCppArgs[nPos] = ovrflw; 139 pUnoArgs[nPos] = ovrflw; 140 ovrflw += 1; 141 } 142 break; 143 144 case typelib_TypeClass_HYPER: 145 case typelib_TypeClass_UNSIGNED_HYPER: 146 if (ng < 4) { 147 pCppArgs[nPos] = gpreg; 148 pUnoArgs[nPos] = gpreg; 149 ng += 2; 150 gpreg += 2; 151 } else { 152 pCppArgs[nPos] = ovrflw; 153 pUnoArgs[nPos] = ovrflw; 154 ovrflw += 2; 155 } 156 break; 157 158 case typelib_TypeClass_BYTE: 159 case typelib_TypeClass_BOOLEAN: 160 if (ng < 5) { 161 pCppArgs[nPos] = (((char *)gpreg) + 3); 162 pUnoArgs[nPos] = (((char *)gpreg) + 3); 163 ng++; 164 gpreg++; 165 } else { 166 pCppArgs[nPos] = (((char *)ovrflw) + 3); 167 pUnoArgs[nPos] = (((char *)ovrflw) + 3); 168 ovrflw++; 169 } 170 break; 171 172 173 case typelib_TypeClass_CHAR: 174 case typelib_TypeClass_SHORT: 175 case typelib_TypeClass_UNSIGNED_SHORT: 176 if (ng < 5) { 177 pCppArgs[nPos] = (((char *)gpreg)+ 2); 178 pUnoArgs[nPos] = (((char *)gpreg)+ 2); 179 ng++; 180 gpreg++; 181 } else { 182 pCppArgs[nPos] = (((char *)ovrflw) + 2); 183 pUnoArgs[nPos] = (((char *)ovrflw) + 2); 184 ovrflw++; 185 } 186 break; 187 188 189 default: 190 if (ng < 5) { 191 pCppArgs[nPos] = gpreg; 192 pUnoArgs[nPos] = gpreg; 193 ng++; 194 gpreg++; 195 } else { 196 pCppArgs[nPos] = ovrflw; 197 pUnoArgs[nPos] = ovrflw; 198 ovrflw++; 199 } 200 break; 201 202 } 203 // no longer needed 204 TYPELIB_DANGER_RELEASE( pParamTypeDescr ); 205 } 206 else // ptr to complex value | ref 207 { 208 209 if (ng < 5) { 210 pCppArgs[nPos] = *(void **)gpreg; 211 pCppStack = gpreg; 212 ng++; 213 gpreg++; 214 } else { 215 pCppArgs[nPos] = *(void **)ovrflw; 216 pCppStack = ovrflw; 217 ovrflw++; 218 } 219 220 if (! rParam.bIn) // is pure out 221 { 222 // uno out is unconstructed mem! 223 pUnoArgs[nPos] = alloca( pParamTypeDescr->nSize ); 224 pTempIndizes[nTempIndizes] = nPos; 225 // will be released at reconversion 226 ppTempParamTypeDescr[nTempIndizes++] = pParamTypeDescr; 227 } 228 // is in/inout 229 else if (bridges::cpp_uno::shared::relatesToInterfaceType( pParamTypeDescr )) 230 { 231 uno_copyAndConvertData( pUnoArgs[nPos] = alloca( pParamTypeDescr->nSize ), 232 *(void **)pCppStack, pParamTypeDescr, 233 pThis->getBridge()->getCpp2Uno() ); 234 pTempIndizes[nTempIndizes] = nPos; // has to be reconverted 235 // will be released at reconversion 236 ppTempParamTypeDescr[nTempIndizes++] = pParamTypeDescr; 237 } 238 else // direct way 239 { 240 pUnoArgs[nPos] = *(void **)pCppStack; 241 // no longer needed 242 TYPELIB_DANGER_RELEASE( pParamTypeDescr ); 243 } 244 } 245 } 246 247 // ExceptionHolder 248 uno_Any aUnoExc; // Any will be constructed by callee 249 uno_Any * pUnoExc = &aUnoExc; 250 251 // invoke uno dispatch call 252 (*pThis->getUnoI()->pDispatcher)( pThis->getUnoI(), pMemberTypeDescr, pUnoReturn, pUnoArgs, &pUnoExc ); 253 254 // in case an exception occured... 255 if (pUnoExc) 256 { 257 // destruct temporary in/inout params 258 for ( ; nTempIndizes--; ) 259 { 260 sal_Int32 nIndex = pTempIndizes[nTempIndizes]; 261 262 if (pParams[nIndex].bIn) // is in/inout => was constructed 263 uno_destructData( pUnoArgs[nIndex], ppTempParamTypeDescr[nTempIndizes], 0 ); 264 TYPELIB_DANGER_RELEASE( ppTempParamTypeDescr[nTempIndizes] ); 265 } 266 if (pReturnTypeDescr) 267 TYPELIB_DANGER_RELEASE( pReturnTypeDescr ); 268 269 CPPU_CURRENT_NAMESPACE::raiseException( &aUnoExc, pThis->getBridge()->getUno2Cpp() ); // has to destruct the any 270 // is here for dummy 271 return typelib_TypeClass_VOID; 272 } 273 else // else no exception occured... 274 { 275 // temporary params 276 for ( ; nTempIndizes--; ) 277 { 278 sal_Int32 nIndex = pTempIndizes[nTempIndizes]; 279 typelib_TypeDescription * pParamTypeDescr = ppTempParamTypeDescr[nTempIndizes]; 280 281 if (pParams[nIndex].bOut) // inout/out 282 { 283 // convert and assign 284 uno_destructData( pCppArgs[nIndex], pParamTypeDescr, cpp_release ); 285 uno_copyAndConvertData( pCppArgs[nIndex], pUnoArgs[nIndex], pParamTypeDescr, 286 pThis->getBridge()->getUno2Cpp() ); 287 } 288 // destroy temp uno param 289 uno_destructData( pUnoArgs[nIndex], pParamTypeDescr, 0 ); 290 291 TYPELIB_DANGER_RELEASE( pParamTypeDescr ); 292 } 293 // return 294 if (pCppReturn) // has complex return 295 { 296 if (pUnoReturn != pCppReturn) // needs reconversion 297 { 298 uno_copyAndConvertData( pCppReturn, pUnoReturn, pReturnTypeDescr, 299 pThis->getBridge()->getUno2Cpp() ); 300 // destroy temp uno return 301 uno_destructData( pUnoReturn, pReturnTypeDescr, 0 ); 302 } 303 // complex return ptr is set to return reg 304 *(void **)pRegisterReturn = pCppReturn; 305 } 306 if (pReturnTypeDescr) 307 { 308 typelib_TypeClass eRet = (typelib_TypeClass)pReturnTypeDescr->eTypeClass; 309 TYPELIB_DANGER_RELEASE( pReturnTypeDescr ); 310 return eRet; 311 } 312 else 313 return typelib_TypeClass_VOID; 314 } 315 } 316 317 318 //============================================================================ 319 static typelib_TypeClass cpp_mediate( 320 sal_uInt32 nOffsetAndIndex, 321 void ** gpreg, void ** fpreg, void ** ovrflw, 322 sal_Int64 * pRegisterReturn /* space for register return */ ) 323 { 324 OSL_ENSURE( sizeof(sal_Int32)==sizeof(void *), "### unexpected!" ); 325 326 sal_Int16 nVtableOffset = (nOffsetAndIndex >> 16); 327 sal_Int16 nFunctionIndex = (nOffsetAndIndex & 0xFFFF); 328 329 // gpreg: [ret *], this, [other gpr params] 330 // fpreg: [fpr params] 331 // ovrflw: [gpr or fpr params (properly aligned)] 332 333 // _this_ ptr is patched cppu_XInterfaceProxy object 334 void * pThis; 335 if( nFunctionIndex & 0x8000 ) 336 { 337 nFunctionIndex &= 0x7fff; 338 pThis = gpreg[1]; 339 } 340 else 341 { 342 pThis = gpreg[0]; 343 } 344 345 pThis = static_cast< char * >(pThis) - nVtableOffset; 346 347 bridges::cpp_uno::shared::CppInterfaceProxy * pCppI 348 = bridges::cpp_uno::shared::CppInterfaceProxy::castInterfaceToProxy( 349 pThis); 350 351 typelib_InterfaceTypeDescription * pTypeDescr = pCppI->getTypeDescr(); 352 353 354 OSL_ENSURE( nFunctionIndex < pTypeDescr->nMapFunctionIndexToMemberIndex, "### illegal vtable index!" ); 355 if (nFunctionIndex >= pTypeDescr->nMapFunctionIndexToMemberIndex) 356 { 357 throw RuntimeException( 358 rtl::OUString::createFromAscii("illegal vtable index!"), 359 (XInterface *)pCppI ); 360 } 361 362 // determine called method 363 OSL_ENSURE( nVtableCall < pTypeDescr->nMapFunctionIndexToMemberIndex, "### illegal vtable index!" ); 364 sal_Int32 nMemberPos = pTypeDescr->pMapFunctionIndexToMemberIndex[nFunctionIndex]; 365 OSL_ENSURE( nMemberPos < pTypeDescr->nAllMembers, "### illegal member index!" ); 366 367 TypeDescription aMemberDescr( pTypeDescr->ppAllMembers[nMemberPos] ); 368 369 typelib_TypeClass eRet; 370 switch (aMemberDescr.get()->eTypeClass) 371 { 372 case typelib_TypeClass_INTERFACE_ATTRIBUTE: 373 { 374 if (pTypeDescr->pMapMemberIndexToFunctionIndex[nMemberPos] == nFunctionIndex) 375 { 376 // is GET method 377 eRet = cpp2uno_call( 378 pCppI, aMemberDescr.get(), 379 ((typelib_InterfaceAttributeTypeDescription *)aMemberDescr.get())->pAttributeTypeRef, 380 0, 0, // no params 381 gpreg, fpreg, ovrflw, pRegisterReturn ); 382 } 383 else 384 { 385 // is SET method 386 typelib_MethodParameter aParam; 387 aParam.pTypeRef = 388 ((typelib_InterfaceAttributeTypeDescription *)aMemberDescr.get())->pAttributeTypeRef; 389 aParam.bIn = sal_True; 390 aParam.bOut = sal_False; 391 392 eRet = cpp2uno_call( 393 pCppI, aMemberDescr.get(), 394 0, // indicates void return 395 1, &aParam, 396 gpreg, fpreg, ovrflw, pRegisterReturn ); 397 } 398 break; 399 } 400 case typelib_TypeClass_INTERFACE_METHOD: 401 { 402 // is METHOD 403 switch (nFunctionIndex) 404 { 405 case 1: // acquire() 406 pCppI->acquireProxy(); // non virtual call! 407 eRet = typelib_TypeClass_VOID; 408 break; 409 case 2: // release() 410 pCppI->releaseProxy(); // non virtual call! 411 eRet = typelib_TypeClass_VOID; 412 break; 413 case 0: // queryInterface() opt 414 { 415 typelib_TypeDescription * pTD = 0; 416 TYPELIB_DANGER_GET( &pTD, reinterpret_cast< Type * >( gpreg[2] )->getTypeLibType() ); 417 if (pTD) 418 { 419 XInterface * pInterface = 0; 420 (*pCppI->getBridge()->getCppEnv()->getRegisteredInterface)( 421 pCppI->getBridge()->getCppEnv(), 422 (void **)&pInterface, pCppI->getOid().pData, 423 (typelib_InterfaceTypeDescription *)pTD ); 424 425 if (pInterface) 426 { 427 ::uno_any_construct( 428 reinterpret_cast< uno_Any * >( gpreg[0] ), 429 &pInterface, pTD, cpp_acquire ); 430 pInterface->release(); 431 TYPELIB_DANGER_RELEASE( pTD ); 432 *(void **)pRegisterReturn = gpreg[0]; 433 eRet = typelib_TypeClass_ANY; 434 break; 435 } 436 TYPELIB_DANGER_RELEASE( pTD ); 437 } 438 } // else perform queryInterface() 439 default: 440 eRet = cpp2uno_call( 441 pCppI, aMemberDescr.get(), 442 ((typelib_InterfaceMethodTypeDescription *)aMemberDescr.get())->pReturnTypeRef, 443 ((typelib_InterfaceMethodTypeDescription *)aMemberDescr.get())->nParams, 444 ((typelib_InterfaceMethodTypeDescription *)aMemberDescr.get())->pParams, 445 gpreg, fpreg, ovrflw, pRegisterReturn ); 446 } 447 break; 448 } 449 default: 450 { 451 throw RuntimeException( 452 rtl::OUString::createFromAscii("no member description found!"), 453 (XInterface *)pCppI ); 454 // is here for dummy 455 eRet = typelib_TypeClass_VOID; 456 } 457 } 458 459 return eRet; 460 } 461 462 //================================================================================================== 463 /** 464 * is called on incoming vtable calls 465 * (called by asm snippets) 466 */ 467 static void privateSnippetExecutor( sal_uInt32 nOffsetAndIndex, void** gpregptr, void** fpregptr, void** ovrflw) 468 { 469 #ifdef CMC_DEBUG 470 fprintf(stderr, "privateSnippetExecutor\n"); 471 #endif 472 473 474 sal_Int32 gpreg[8]; 475 double fpreg[8]; 476 477 memcpy( gpreg, gpregptr, 32); 478 memcpy( fpreg, fpregptr, 64); 479 480 volatile long nRegReturn[2]; 481 482 typelib_TypeClass aType = 483 cpp_mediate( nOffsetAndIndex, (void**)gpreg, (void**)fpreg, ovrflw, 484 (sal_Int64*)nRegReturn ); 485 486 switch( aType ) 487 { 488 489 // move return value into register space 490 // (will be loaded by machine code snippet) 491 492 case typelib_TypeClass_BOOLEAN: 493 { 494 unsigned long tmp = (unsigned long)(*(unsigned char *)nRegReturn); 495 __asm__ volatile ( "l 2,%0\n\t" : : 496 "m"(tmp) : "2" ); 497 break; 498 } 499 case typelib_TypeClass_BYTE: 500 { 501 long tmp = (long)(*(signed char *)nRegReturn); 502 __asm__ volatile ( "l 2,%0\n\t" : : 503 "m"(tmp) : "2" ); 504 break; 505 } 506 case typelib_TypeClass_CHAR: 507 case typelib_TypeClass_UNSIGNED_SHORT: 508 { 509 unsigned long tmp = (unsigned long)(*(unsigned short *)nRegReturn); 510 __asm__ volatile ( "l 2,%0\n\t" : : 511 "m"(tmp) : "2" ); 512 break; 513 } 514 case typelib_TypeClass_SHORT: 515 { 516 long tmp = (long)(*(short *)nRegReturn); 517 __asm__ volatile ( "l 2,%0\n\t" : : 518 "m"(tmp) : "2" ); 519 break; 520 } 521 case typelib_TypeClass_FLOAT: 522 __asm__ volatile ( "le 0,%0\n\t" : : 523 "m" (*((float*)nRegReturn)) : "16" ); 524 break; 525 526 case typelib_TypeClass_DOUBLE: 527 __asm__ volatile ( "ld 0,%0\n\t" : : 528 "m" (*((double*)nRegReturn)) : "16" ); 529 break; 530 531 case typelib_TypeClass_HYPER: 532 case typelib_TypeClass_UNSIGNED_HYPER: 533 __asm__ volatile ( "lm 2,3,%0\n\t" : : 534 "m"(nRegReturn[0]) : "2", "3" ); 535 break; 536 537 default: 538 __asm__ volatile ( "l 2,%0\n\t" : : 539 "m"(nRegReturn[0]) : "2" ); 540 break; 541 } 542 } 543 544 const int codeSnippetSize = 50; 545 546 unsigned char* codeSnippet( unsigned char * code, sal_Int16 nFunctionIndex, sal_Int16 nVtableOffset, bool simple_ret_type ) 547 { 548 sal_uInt32 nOffsetAndIndex = ( ( nVtableOffset ) << 16 ) | ( nFunctionIndex ); 549 550 if (! simple_ret_type) 551 nOffsetAndIndex |= 0x8000; 552 553 OSL_ASSERT( sizeof (long) == 4 ); 554 555 /* generate this code */ 556 // lr %r0,%r13 557 // bras %r13,0x6 558 // .long privateSnippetExecutor 559 // .long nOffsetAndIndex 560 // stm %r2,%r6,8(%r15) 561 // std %f0,64(%r15) 562 // std %f2,72(%r15) 563 564 // l %r2,4(%r13) 565 // la %r3,8(%r15) 566 // la %r4,64(%r15) 567 // la %r5,96(%r15) 568 // l %r1,0(%r13) 569 // lr %r13,%r0 570 // br %r1 571 572 unsigned char * p = code; 573 *reinterpret_cast< sal_Int16 * >(p) = 0x180d; 574 p += sizeof(sal_Int16); 575 *reinterpret_cast< sal_Int32 * >(p) = 0xa7d50006; 576 p += sizeof(sal_Int32); 577 *reinterpret_cast< sal_Int32 * >(p) = 578 reinterpret_cast< sal_Int32 >(privateSnippetExecutor); 579 p += sizeof(sal_Int32); 580 *reinterpret_cast< sal_Int32 * >(p) = nOffsetAndIndex; 581 p += sizeof(sal_Int32); 582 *reinterpret_cast< sal_Int32 * >(p) = 0x9026f008; 583 p += sizeof(sal_Int32); 584 *reinterpret_cast< sal_Int32 * >(p) = 0x6000f040; 585 p += sizeof(sal_Int32); 586 *reinterpret_cast< sal_Int32 * >(p) = 0x6020f048; 587 p += sizeof(sal_Int32); 588 *reinterpret_cast< sal_Int32 * >(p) = 0x5820d004; 589 p += sizeof(sal_Int32); 590 *reinterpret_cast< sal_Int32 * >(p) = 0x4130f008; 591 p += sizeof(sal_Int32); 592 *reinterpret_cast< sal_Int32 * >(p) = 0x4140f040; 593 p += sizeof(sal_Int32); 594 *reinterpret_cast< sal_Int32 * >(p) = 0x4150f060; 595 p += sizeof(sal_Int32); 596 *reinterpret_cast< sal_Int32 * >(p) = 0x5810d000; 597 p += sizeof(sal_Int32); 598 *reinterpret_cast< sal_Int16 * >(p) = 0x18d0; 599 p += sizeof(sal_Int16); 600 *reinterpret_cast< sal_Int16 * >(p) = 0x07f1; 601 p += sizeof(sal_Int16); 602 603 return (code + codeSnippetSize); 604 } 605 } 606 607 void bridges::cpp_uno::shared::VtableFactory::flushCode(unsigned char const *, unsigned char const *) 608 { 609 } 610 611 struct bridges::cpp_uno::shared::VtableFactory::Slot { void * fn; }; 612 613 bridges::cpp_uno::shared::VtableFactory::Slot * 614 bridges::cpp_uno::shared::VtableFactory::mapBlockToVtable(void * block) 615 { 616 return static_cast< Slot * >(block) + 2; 617 } 618 619 sal_Size bridges::cpp_uno::shared::VtableFactory::getBlockSize( 620 sal_Int32 slotCount) 621 { 622 return (slotCount + 2) * sizeof (Slot) + slotCount * codeSnippetSize; 623 } 624 625 bridges::cpp_uno::shared::VtableFactory::Slot * 626 bridges::cpp_uno::shared::VtableFactory::initializeBlock( 627 void * block, sal_Int32 slotCount) 628 { 629 Slot * slots = mapBlockToVtable(block); 630 slots[-2].fn = 0; 631 slots[-1].fn = 0; 632 return slots + slotCount; 633 } 634 635 unsigned char * bridges::cpp_uno::shared::VtableFactory::addLocalFunctions( 636 Slot ** slots, unsigned char * code, sal_PtrDiff writetoexecdiff, 637 typelib_InterfaceTypeDescription const * type, sal_Int32 functionOffset, 638 sal_Int32 functionCount, sal_Int32 vtableOffset) 639 { 640 (*slots) -= functionCount; 641 Slot * s = *slots; 642 #ifdef CMC_DEBUG 643 fprintf(stderr, "in addLocalFunctions functionOffset is %x\n",functionOffset); 644 fprintf(stderr, "in addLocalFunctions vtableOffset is %x\n",vtableOffset); 645 #endif 646 647 for (sal_Int32 i = 0; i < type->nMembers; ++i) { 648 typelib_TypeDescription * member = 0; 649 TYPELIB_DANGER_GET(&member, type->ppMembers[i]); 650 OSL_ASSERT(member != 0); 651 switch (member->eTypeClass) { 652 case typelib_TypeClass_INTERFACE_ATTRIBUTE: 653 // Getter: 654 (s++)->fn = code + writetoexecdiff; 655 code = codeSnippet( 656 code, functionOffset++, vtableOffset, 657 bridges::cpp_uno::shared::isSimpleType( 658 reinterpret_cast< 659 typelib_InterfaceAttributeTypeDescription * >( 660 member)->pAttributeTypeRef)); 661 662 // Setter: 663 if (!reinterpret_cast< 664 typelib_InterfaceAttributeTypeDescription * >( 665 member)->bReadOnly) 666 { 667 (s++)->fn = code + writetoexecdiff; 668 code = codeSnippet(code, functionOffset++, vtableOffset, true); 669 } 670 break; 671 672 case typelib_TypeClass_INTERFACE_METHOD: 673 (s++)->fn = code + writetoexecdiff; 674 code = codeSnippet( 675 code, functionOffset++, vtableOffset, 676 bridges::cpp_uno::shared::isSimpleType( 677 reinterpret_cast< 678 typelib_InterfaceMethodTypeDescription * >( 679 member)->pReturnTypeRef)); 680 break; 681 682 default: 683 OSL_ASSERT(false); 684 break; 685 } 686 TYPELIB_DANGER_RELEASE(member); 687 } 688 return code; 689 } 690 691 /* vi:set tabstop=4 shiftwidth=4 expandtab: */ 692