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