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