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