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