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