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