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