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