nss: upgrade to release 3.73
[LibreOffice.git] / bridges / source / cpp_uno / gcc3_linux_sparc64 / cpp2uno.cxx
blob9b157f08212023361640ae75b6ccc0d36a9e9297
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <com/sun/star/uno/genfunc.hxx>
21 #include <sal/log.hxx>
22 #include <typelib/typedescription.hxx>
23 #include <uno/data.h>
24 #include "bridge.hxx"
25 #include "cppinterfaceproxy.hxx"
26 #include "types.hxx"
27 #include "vtablefactory.hxx"
28 #include "share.hxx"
30 #define GET_FP(n, p) \
31 __asm__( "ldx %0, %%l0\n\t" \
32 "std %%f" #n ", [%%l0]\n" \
33 : : "m"(p) );
35 using namespace com::sun::star::uno;
37 namespace CPPU_CURRENT_NAMESPACE
39 bool is_complex_struct(const typelib_TypeDescription * type)
41 for (const typelib_CompoundTypeDescription * p
42 = reinterpret_cast< const typelib_CompoundTypeDescription * >(type);
43 p != NULL; p = p->pBaseTypeDescription)
45 for (sal_Int32 i = 0; i < p->nMembers; ++i)
47 if (p->ppTypeRefs[i]->eTypeClass == typelib_TypeClass_STRUCT ||
48 p->ppTypeRefs[i]->eTypeClass == typelib_TypeClass_EXCEPTION)
50 typelib_TypeDescription * t = 0;
51 TYPELIB_DANGER_GET(&t, p->ppTypeRefs[i]);
52 bool b = is_complex_struct(t);
53 TYPELIB_DANGER_RELEASE(t);
54 if (b) {
55 return true;
58 else if (!bridges::cpp_uno::shared::isSimpleType(p->ppTypeRefs[i]->eTypeClass))
59 return true;
62 return false;
65 bool return_in_hidden_param( typelib_TypeDescriptionReference *pTypeRef )
67 if (bridges::cpp_uno::shared::isSimpleType(pTypeRef))
68 return false;
69 else if (pTypeRef->eTypeClass == typelib_TypeClass_STRUCT ||
70 pTypeRef->eTypeClass == typelib_TypeClass_EXCEPTION)
72 typelib_TypeDescription * pTypeDescr = 0;
73 TYPELIB_DANGER_GET( &pTypeDescr, pTypeRef );
75 //A Composite Type not larger than 32 bytes is returned in up to two GPRs
76 bool bRet = pTypeDescr->nSize > 32 || is_complex_struct(pTypeDescr);
78 TYPELIB_DANGER_RELEASE( pTypeDescr );
79 return bRet;
81 return true;
86 namespace
89 static typelib_TypeClass cpp2uno_call(
90 bridges::cpp_uno::shared::CppInterfaceProxy * pThis,
91 const typelib_TypeDescription * pMemberTypeDescr,
92 typelib_TypeDescriptionReference * pReturnTypeRef, // 0 indicates void return
93 sal_Int32 nParams, typelib_MethodParameter * pParams,
94 void ** pCallStack,
95 sal_Int64 * pRegisterReturn /* space for register return */ )
97 // pCallStack: [ret ptr], this, params
98 char * pCppStack = (char *)pCallStack;
100 // return
101 typelib_TypeDescription * pReturnTypeDescr = 0;
102 if (pReturnTypeRef)
103 TYPELIB_DANGER_GET( &pReturnTypeDescr, pReturnTypeRef );
105 void * pUnoReturn = 0;
106 void * pCppReturn = 0; // complex return ptr: if != 0 && != pUnoReturn, reconversion need
108 int paramsOffset;
109 if (pReturnTypeDescr)
111 if (CPPU_CURRENT_NAMESPACE::return_in_hidden_param( pReturnTypeRef ) )
113 pCppReturn = *(void**)pCppStack; // complex return via ptr (pCppReturn)
114 pUnoReturn = (bridges::cpp_uno::shared::relatesToInterfaceType(
115 pReturnTypeDescr )
116 ? alloca( pReturnTypeDescr->nSize )
117 : pCppReturn); // direct way
118 pCppStack += sizeof( void* );
119 paramsOffset = 2;
121 else
123 pUnoReturn = pRegisterReturn; // direct way for simple types
124 paramsOffset = 1;
127 else
129 paramsOffset = 1;
131 // pop this
132 pCppStack += sizeof( void* );
134 // stack space
135 static_assert(sizeof(void *) == sizeof(sal_Int64), "### unexpected size!");
136 // parameters
137 void ** pUnoArgs = (void **)alloca( 4 * sizeof(void *) * nParams );
138 void ** pCppArgs = pUnoArgs + nParams;
139 // indices of values this have to be converted (interface conversion cpp<=>uno)
140 sal_Int32 * pTempIndices = (sal_Int32 *)(pUnoArgs + (2 * nParams));
141 // type descriptions for reconversions
142 typelib_TypeDescription ** ppTempParamTypeDescr = (typelib_TypeDescription **)(pUnoArgs + (3 * nParams));
144 sal_Int32 nTempIndices = 0;
146 for ( sal_Int32 nPos = 0; nPos < nParams; ++nPos )
148 const typelib_MethodParameter & rParam = pParams[nPos];
149 typelib_TypeDescription * pParamTypeDescr = 0;
150 TYPELIB_DANGER_GET( &pParamTypeDescr, rParam.pTypeRef );
152 if (!rParam.bOut && bridges::cpp_uno::shared::isSimpleType( pParamTypeDescr )) // value
154 pCppArgs[nPos] = pUnoArgs[nPos] = CPPU_CURRENT_NAMESPACE::adjustPointer(pCppStack, pParamTypeDescr);
155 switch (pParamTypeDescr->eTypeClass) {
156 case typelib_TypeClass_FLOAT:
157 case typelib_TypeClass_DOUBLE:
159 int paramArrayIdx = nPos + paramsOffset;
160 assert(paramArrayIdx < nParams + paramsOffset);
161 switch (paramArrayIdx) {
162 // Cannot be 0 - paramsOffset >= 1
163 case 1:
164 GET_FP(2, pCppStack);
165 break;
166 case 2:
167 GET_FP(4, pCppStack);
168 break;
169 case 3:
170 GET_FP(6, pCppStack);
171 break;
172 case 4:
173 GET_FP(8, pCppStack);
174 break;
175 case 5:
176 GET_FP(10, pCppStack);
177 break;
178 case 6:
179 GET_FP(12, pCppStack);
180 break;
181 case 7:
182 GET_FP(14, pCppStack);
183 break;
184 case 8:
185 GET_FP(16, pCppStack);
186 break;
187 case 9:
188 GET_FP(18, pCppStack);
189 break;
190 case 10:
191 GET_FP(20, pCppStack);
192 break;
193 case 11:
194 GET_FP(22, pCppStack);
195 break;
196 case 12:
197 GET_FP(24, pCppStack);
198 break;
199 case 13:
200 GET_FP(26, pCppStack);
201 break;
202 case 14:
203 GET_FP(28, pCppStack);
204 break;
205 case 15:
206 GET_FP(30, pCppStack);
207 break;
208 // Anything larger is passed on the stack
210 break;
212 default:
213 break;
215 // no longer needed
216 TYPELIB_DANGER_RELEASE( pParamTypeDescr );
218 else // ptr to complex value | ref
220 pCppArgs[nPos] = *(void **)pCppStack;
222 if (! rParam.bIn) // is pure out
224 // uno out is unconstructed mem!
225 pUnoArgs[nPos] = alloca( pParamTypeDescr->nSize );
226 pTempIndices[nTempIndices] = nPos;
227 // will be released at reconversion
228 ppTempParamTypeDescr[nTempIndices++] = pParamTypeDescr;
230 // is in/inout
231 else if (bridges::cpp_uno::shared::relatesToInterfaceType(
232 pParamTypeDescr ))
234 uno_copyAndConvertData( pUnoArgs[nPos] = alloca( pParamTypeDescr->nSize ),
235 *(void **)pCppStack, pParamTypeDescr,
236 pThis->getBridge()->getCpp2Uno() );
237 pTempIndices[nTempIndices] = nPos; // has to be reconverted
238 // will be released at reconversion
239 ppTempParamTypeDescr[nTempIndices++] = pParamTypeDescr;
241 else // direct way
243 pUnoArgs[nPos] = *(void **)pCppStack;
244 // no longer needed
245 TYPELIB_DANGER_RELEASE( pParamTypeDescr );
248 pCppStack += sizeof(sal_Int64); // standard parameter length
251 // ExceptionHolder
252 uno_Any aUnoExc; // Any will be constructed by callee
253 uno_Any * pUnoExc = &aUnoExc;
255 // invoke uno dispatch call
256 (*pThis->getUnoI()->pDispatcher)(pThis->getUnoI(), pMemberTypeDescr, pUnoReturn, pUnoArgs, &pUnoExc );
258 // in case an exception occurred...
259 if (pUnoExc)
261 // destruct temporary in/inout params
262 for ( ; nTempIndices--; )
264 sal_Int32 nIndex = pTempIndices[nTempIndices];
266 if (pParams[nIndex].bIn) // is in/inout => was constructed
267 uno_destructData( pUnoArgs[nIndex], ppTempParamTypeDescr[nTempIndices], 0 );
268 TYPELIB_DANGER_RELEASE( ppTempParamTypeDescr[nTempIndices] );
270 if (pReturnTypeDescr)
271 TYPELIB_DANGER_RELEASE( pReturnTypeDescr );
272 CPPU_CURRENT_NAMESPACE::raiseException(&aUnoExc, pThis->getBridge()->getUno2Cpp() );
273 // has to destruct the any
274 // is here for dummy
275 return typelib_TypeClass_VOID;
277 else // else no exception occurred...
279 // temporary params
280 for ( ; nTempIndices--; )
282 sal_Int32 nIndex = pTempIndices[nTempIndices];
283 typelib_TypeDescription * pParamTypeDescr = ppTempParamTypeDescr[nTempIndices];
285 if (pParams[nIndex].bOut) // inout/out
287 // convert and assign
288 uno_destructData( pCppArgs[nIndex], pParamTypeDescr, cpp_release );
289 uno_copyAndConvertData( pCppArgs[nIndex], pUnoArgs[nIndex], pParamTypeDescr,
290 pThis->getBridge()->getUno2Cpp() );
292 // destroy temp uno param
293 uno_destructData( pUnoArgs[nIndex], pParamTypeDescr, 0 );
295 TYPELIB_DANGER_RELEASE( pParamTypeDescr );
297 // return
298 if (pCppReturn) // has complex return
300 if (pUnoReturn != pCppReturn) // needs reconversion
302 uno_copyAndConvertData( pCppReturn, pUnoReturn, pReturnTypeDescr,
303 pThis->getBridge()->getUno2Cpp() );
304 // destroy temp uno return
305 uno_destructData( pUnoReturn, pReturnTypeDescr, 0 );
307 // complex return ptr is set to eax
308 *(void **)pRegisterReturn = pCppReturn;
310 if (pReturnTypeDescr)
312 typelib_TypeClass eRet = (typelib_TypeClass)pReturnTypeDescr->eTypeClass;
313 TYPELIB_DANGER_RELEASE( pReturnTypeDescr );
314 return eRet;
316 else
317 return typelib_TypeClass_VOID;
322 static typelib_TypeClass cpp_mediate(
323 sal_Int32 nFunctionIndex,
324 sal_Int32 nVtableOffset,
325 void ** pCallStack,
326 sal_Int64 * pRegisterReturn /* space for register return */ )
328 static_assert(sizeof(sal_Int64)==sizeof(void *), "### unexpected!");
330 // pCallStack: [ret*], this, params
331 void * pThis;
332 if (nFunctionIndex & 0x80000000)
334 nFunctionIndex &= 0x7fffffff;
335 pThis = pCallStack[1];
337 else
339 pThis = pCallStack[0];
342 pThis = static_cast< char * >(pThis) - nVtableOffset;
343 bridges::cpp_uno::shared::CppInterfaceProxy * pCppI =
344 bridges::cpp_uno::shared::CppInterfaceProxy::castInterfaceToProxy( pThis );
346 typelib_InterfaceTypeDescription * pTypeDescr = pCppI->getTypeDescr();
348 if (nFunctionIndex >= pTypeDescr->nMapFunctionIndexToMemberIndex)
350 SAL_WARN(
351 "bridges",
352 "illegal " << OUString::unacquired(&pTypeDescr->aBase.pTypeName)
353 << " vtable index " << nFunctionIndex << "/"
354 << pTypeDescr->nMapFunctionIndexToMemberIndex);
355 throw RuntimeException(
356 ("illegal " + OUString::unacquired(&pTypeDescr->aBase.pTypeName)
357 + " vtable index " + OUString::number(nFunctionIndex) + "/"
358 + OUString::number(pTypeDescr->nMapFunctionIndexToMemberIndex)),
359 (XInterface *)pCppI);
362 // determine called method
363 sal_Int32 nMemberPos = pTypeDescr->pMapFunctionIndexToMemberIndex[nFunctionIndex];
364 assert(nMemberPos < pTypeDescr->nAllMembers);
366 TypeDescription aMemberDescr( pTypeDescr->ppAllMembers[nMemberPos] );
368 #if defined BRIDGES_DEBUG
369 OString cstr( OUStringToOString( aMemberDescr.get()->pTypeName, RTL_TEXTENCODING_ASCII_US ) );
370 fprintf( stderr, "calling %s, nFunctionIndex=%d\n", cstr.getStr(), nFunctionIndex );
371 #endif
373 typelib_TypeClass eRet;
374 switch (aMemberDescr.get()->eTypeClass)
376 case typelib_TypeClass_INTERFACE_ATTRIBUTE:
378 if (pTypeDescr->pMapMemberIndexToFunctionIndex[nMemberPos] == nFunctionIndex)
380 // is GET method
381 eRet = cpp2uno_call(
382 pCppI, aMemberDescr.get(),
383 ((typelib_InterfaceAttributeTypeDescription *)aMemberDescr.get())->pAttributeTypeRef,
384 0, 0, // no params
385 pCallStack, pRegisterReturn );
387 else
389 // is SET method
390 typelib_MethodParameter aParam;
391 aParam.pTypeRef =
392 ((typelib_InterfaceAttributeTypeDescription *)aMemberDescr.get())->pAttributeTypeRef;
393 aParam.bIn = sal_True;
394 aParam.bOut = sal_False;
396 eRet = cpp2uno_call(
397 pCppI, aMemberDescr.get(),
398 0, // indicates void return
399 1, &aParam,
400 pCallStack, pRegisterReturn );
402 break;
404 case typelib_TypeClass_INTERFACE_METHOD:
406 // is METHOD
407 switch (nFunctionIndex)
409 case 1: // acquire()
410 pCppI->acquireProxy(); // non virtual call!
411 eRet = typelib_TypeClass_VOID;
412 break;
413 case 2: // release()
414 pCppI->releaseProxy(); // non virtual call!
415 eRet = typelib_TypeClass_VOID;
416 break;
417 case 0: // queryInterface() opt
419 typelib_TypeDescription * pTD = 0;
420 TYPELIB_DANGER_GET( &pTD, reinterpret_cast< Type * >( pCallStack[2] )->getTypeLibType() );
421 if (pTD)
423 XInterface * pInterface = 0;
424 (*pCppI->getBridge()->getCppEnv()->getRegisteredInterface)(
425 pCppI->getBridge()->getCppEnv(),
426 (void **)&pInterface, pCppI->getOid().pData, (typelib_InterfaceTypeDescription *)pTD );
428 if (pInterface)
430 ::uno_any_construct(
431 reinterpret_cast< uno_Any * >( pCallStack[0] ),
432 &pInterface, pTD, cpp_acquire );
433 pInterface->release();
434 TYPELIB_DANGER_RELEASE( pTD );
435 *(void **)pRegisterReturn = pCallStack[0];
436 eRet = typelib_TypeClass_ANY;
437 break;
439 TYPELIB_DANGER_RELEASE( pTD );
441 } // else perform queryInterface()
442 default:
443 eRet = cpp2uno_call(
444 pCppI, aMemberDescr.get(),
445 ((typelib_InterfaceMethodTypeDescription *)aMemberDescr.get())->pReturnTypeRef,
446 ((typelib_InterfaceMethodTypeDescription *)aMemberDescr.get())->nParams,
447 ((typelib_InterfaceMethodTypeDescription *)aMemberDescr.get())->pParams,
448 pCallStack, pRegisterReturn );
450 break;
452 default:
454 throw RuntimeException( "no member description found!", (XInterface *)pCppI );
457 return eRet;
463 * is called on incoming vtable calls
464 * (called by asm snippets)
466 static void cpp_vtable_call(int nFunctionIndex, void** pCallStack, int vTableOffset)
468 sal_Int64 nRegReturn[4] = { 0 };
469 void * pRegReturn = &nRegReturn[0];
471 //__asm__( "st %%i0, %0\n\t"
472 // "stx %%i1, %1\n\t"
473 // "st %%i2, %2\n\t"
474 // : : "m"(nFunctionIndex), "m"(pCallStack), "m"(vTableOffset) );
476 // fprintf(stderr,"cpp_mediate nFunctionIndex=%x\n",nFunctionIndex);
477 // fflush(stderr);
479 //const sal_Bool bComplex = (nFunctionIndex & 0x80000000) ? sal_True : sal_False;
480 typelib_TypeClass aType =
481 cpp_mediate( nFunctionIndex, vTableOffset, pCallStack+16, (sal_Int64*)&nRegReturn );
483 switch( aType )
485 case typelib_TypeClass_BOOLEAN:
486 case typelib_TypeClass_BYTE:
487 __asm__( "ldx %0, %%l0\n\t"
488 "ldsb [%%l0], %%i0\n"
489 : : "m"(pRegReturn) );
490 break;
491 case typelib_TypeClass_CHAR:
492 case typelib_TypeClass_SHORT:
493 case typelib_TypeClass_UNSIGNED_SHORT:
494 __asm__( "ldx %0, %%l0\n\t"
495 "ldsh [%%l0], %%i0\n"
496 : : "m"(pRegReturn) );
497 break;
498 case typelib_TypeClass_ENUM:
499 case typelib_TypeClass_LONG:
500 case typelib_TypeClass_UNSIGNED_LONG:
501 __asm__( "ldx %0, %%l0\n\t"
502 "ld [%%l0], %%i0\n"
503 : : "m"(pRegReturn) );
504 break;
505 case typelib_TypeClass_HYPER:
506 case typelib_TypeClass_UNSIGNED_HYPER:
507 __asm__( "ldx %0, %%l0\n\t"
508 "ldx [%%l0], %%i0\n\t"
509 : : "m"(pRegReturn) );
510 break;
511 case typelib_TypeClass_FLOAT:
512 __asm__( "ldx %0, %%l0\n\t"
513 "ld [%%l0], %%f0\n"
514 : : "m"(pRegReturn) );
515 break;
516 case typelib_TypeClass_DOUBLE:
517 __asm__( "ldx %0, %%l0\n\t"
518 "ldd [%%l0], %%f0\n"
519 : : "m"(pRegReturn) );
520 break;
521 case typelib_TypeClass_VOID:
522 break;
523 case typelib_TypeClass_STRUCT:
524 case typelib_TypeClass_EXCEPTION:
525 __asm__( "ldx %0, %%l0\n\t"
526 "ldx [%%l0 ], %%i0\n\t"
527 "ldx [%%l0+ 8], %%i1\n\t"
528 "ldx [%%l0+16], %%i2\n\t"
529 "ldx [%%l0+24], %%i3\n\t"
530 "ldd [%%l0 ], %%f0\n\t"
531 "ldd [%%l0+ 8], %%f2\n\t"
532 "ldd [%%l0+16], %%f4\n\t"
533 "ldd [%%l0+24], %%f6\n\t"
534 : : "m"(pRegReturn) );
535 break;
536 default:
537 break;
540 //if( bComplex )
542 // __asm__( "add %i7, 4, %i7\n\t" );
543 // // after call to complex return valued function there is an unimp instruction
548 extern "C" void privateSnippetExecutor(...);
550 int const codeSnippetSize = 120;
551 unsigned char * codeSnippet(
552 unsigned char * code, sal_Int32 functionIndex, sal_Int32 vtableOffset,
553 bool bHasHiddenParam, sal_Int32 nParams)
555 sal_uInt32 index = functionIndex;
556 if (bHasHiddenParam) {
557 index |= 0x80000000;
559 unsigned int * p = reinterpret_cast< unsigned int * >(code);
560 static_assert(sizeof (unsigned int) == 4, "boo");
561 static_assert(sizeof (unsigned long long) == 8, "boo");
562 ++nParams; // implicit this ptr
563 if (bHasHiddenParam) {
564 ++nParams;
566 long long frameSize;
567 if (nParams > 6) {
568 frameSize = 128 + nParams * 8;
569 } else {
570 frameSize = 176;
572 assert(frameSize <= 4096);
573 frameSize = -frameSize;
574 switch (nParams) {
575 default:
576 assert(nParams >= 6);
577 // stx %o5, [%sp+168+2047]:
578 *p++ = 0xDA73A8A7;
579 case 5:
580 // stx %o4, [%sp+160+2047]:
581 *p++ = 0xD873A89F;
582 case 4:
583 // stx %o3, [%sp+152+2047]:
584 *p++ = 0xD673A897;
585 case 3:
586 // stx %o2, [%sp+144+2047]:
587 *p++ = 0xD473A88F;
588 case 2:
589 // stx %o1, [%sp+136+2047]:
590 *p++ = 0xD273A887;
591 case 1:
592 // stx %o0, [%sp+128+2047]:
593 *p++ = 0xD073A87F;
594 case 0:
595 break;
597 // sethi %hi(index), %o0:
598 *p++ = 0x11000000 | (index >> 10);
599 // or %o0, %lo(index), %o0:
600 *p++ = 0x90122000 | (index & 0x3FF);
601 // sethi %hh(cpp_vtable_call), %o3:
602 *p++ = 0x17000000 | (reinterpret_cast< unsigned long long >(cpp_vtable_call) >> 42);
603 // or %o3, %hm(cpp_vtable_call), %o3:
604 *p++ = 0x9612E000 | ((reinterpret_cast< unsigned long long >(cpp_vtable_call) >> 32) & 0x3FF);
605 // sllx %o3, 32, %o3
606 *p++ = 0x972AF020;
607 // sethi %lm(cpp_vtable_call), %o2:
608 *p++ = 0x15000000 | ((reinterpret_cast< unsigned long long >(cpp_vtable_call) >> 10) & 0x3FFFFF);
609 // or %o2, %lo(cpp_vtable_call), %o2:
610 *p++ = 0x9412A000 | (reinterpret_cast< unsigned long long >(cpp_vtable_call) & 0x3FF);
611 // or %o2, %o3, %o3:
612 *p++ = 0x9612800B;
613 // sethi %hh(privateSnippetExecutor), %o1:
614 *p++ = 0x13000000 | (reinterpret_cast< unsigned long long >(privateSnippetExecutor) >> 42);
615 // or %o1, %hm(privateSnippetExecutor), %o1:
616 *p++ = 0x92126000 | ((reinterpret_cast< unsigned long long >(privateSnippetExecutor) >> 32) & 0x3FF);
617 // sllx %o1, 32, %o1:
618 *p++ = 0x932a7020;
619 // sethi %lm(privateSnippetExecutor), %o2:
620 *p++ = 0x15000000 | ((reinterpret_cast< unsigned long long >(privateSnippetExecutor) >> 10) & 0x3FFFFF);
621 // or %o2, %lo(privateSnippetExecutor), %o2:
622 *p++ = 0x9412A000 | (reinterpret_cast< unsigned long long >(privateSnippetExecutor) & 0x3FF);
623 // or %o2, %o1, %o1:
624 *p++ = 0x92128009;
625 // sethi %hh(frameSize), %o4:
626 *p++ = 0x19000000 | (*reinterpret_cast< unsigned long long * >(&frameSize) >> 42);
627 // or %o4, %hm(frameSize), %o4:
628 *p++ = 0x98132000 | ((*reinterpret_cast< unsigned long long * >(&frameSize) >> 32) & 0x3FF);
629 // sllx %o4, 32, %o4
630 *p++ = 0x992B3020;
631 // sethi %lm(frameSize), %o2:
632 *p++ = 0x15000000 | ((*reinterpret_cast< unsigned long long * >(&frameSize) >> 10) & 0x3FFFFF);
633 // or %o2, %lo(frameSize), %o2:
634 *p++ = 0x9412A000 | (*reinterpret_cast< unsigned long long * >(&frameSize) & 0x3FF);
635 // or %o2, %o4, %o4:
636 *p++ = 0x9812800C;
637 // sethi %hi(vtableOffset), %o2:
638 *p++ = 0x15000000 | (vtableOffset >> 10);
639 // or %o2, %lo(vtableOffset), %o2:
640 *p++ = 0x9412A000 | (vtableOffset & 0x3FF);
641 // save %sp, -frameSize, %sp
642 //*p++ = 0x9DE3A000 | (*reinterpret_cast< unsigned int * >(&frameSize) & 0x1FFF);
643 // jmpl %o1, %g0:
644 *p++ = 0x81C24000;
645 // add %sp, 2047, %o1:
646 *p++ = 0x9203A7FF;
647 assert(reinterpret_cast< unsigned char * >(p) - code <= codeSnippetSize);
648 return code + codeSnippetSize;
651 } //end of namespace
653 struct bridges::cpp_uno::shared::VtableFactory::Slot { void * fn; };
655 bridges::cpp_uno::shared::VtableFactory::Slot *
656 bridges::cpp_uno::shared::VtableFactory::mapBlockToVtable(void * block)
658 return static_cast< Slot * >(block) + 2;
661 std::size_t bridges::cpp_uno::shared::VtableFactory::getBlockSize(
662 sal_Int32 slotCount)
664 return (slotCount + 2) * sizeof (Slot) + slotCount * codeSnippetSize;
667 bridges::cpp_uno::shared::VtableFactory::Slot *
668 bridges::cpp_uno::shared::VtableFactory::initializeBlock(
669 void * block, sal_Int32 slotCount, sal_Int32,
670 typelib_InterfaceTypeDescription *)
672 Slot * slots = mapBlockToVtable(block);
673 slots[-2].fn = 0; //null
674 slots[-1].fn = 0; //destructor
675 return slots + slotCount;
678 unsigned char * bridges::cpp_uno::shared::VtableFactory::addLocalFunctions(
679 Slot ** slots, unsigned char * code, sal_PtrDiff writetoexecdiff,
680 typelib_InterfaceTypeDescription const * type, sal_Int32 functionOffset,
681 sal_Int32 functionCount, sal_Int32 vTableOffset)
683 (*slots) -= functionCount;
684 Slot * s = *slots;
685 for (sal_Int32 i = 0; i < type->nMembers; ++i) {
686 typelib_TypeDescription * member = 0;
687 TYPELIB_DANGER_GET(&member, type->ppMembers[i]);
688 assert(member != 0);
689 switch (member->eTypeClass) {
690 case typelib_TypeClass_INTERFACE_ATTRIBUTE:
691 // Getter:
692 (s++)->fn = code + writetoexecdiff;
693 code = codeSnippet(
694 code, functionOffset++, vTableOffset,
695 CPPU_CURRENT_NAMESPACE::return_in_hidden_param(
696 reinterpret_cast<
697 typelib_InterfaceAttributeTypeDescription * >(
698 member)->pAttributeTypeRef), 0);
699 // Setter:
700 if (!reinterpret_cast<
701 typelib_InterfaceAttributeTypeDescription * >(
702 member)->bReadOnly)
704 (s++)->fn = code + writetoexecdiff;
705 code = codeSnippet(code, functionOffset++, vTableOffset, false, 1);
707 break;
709 case typelib_TypeClass_INTERFACE_METHOD:
710 (s++)->fn = code + writetoexecdiff;
711 code = codeSnippet(
712 code, functionOffset++, vTableOffset,
713 CPPU_CURRENT_NAMESPACE::return_in_hidden_param(
714 reinterpret_cast<
715 typelib_InterfaceMethodTypeDescription * >(
716 member)->pReturnTypeRef),
717 reinterpret_cast<
718 typelib_InterfaceMethodTypeDescription * >(
719 member)->nParams);
720 break;
722 default:
723 assert(false);
724 break;
726 TYPELIB_DANGER_RELEASE(member);
728 return code;
731 // use flush code from cc50_solaris_sparc
733 extern "C" void doFlushCode(unsigned long address, unsigned long count);
735 void bridges::cpp_uno::shared::VtableFactory::flushCode(
736 unsigned char const * begin, unsigned char const * end)
738 unsigned long n = end - begin;
739 if (n != 0) {
740 unsigned long adr = reinterpret_cast< unsigned long >(begin);
741 unsigned long off = adr & 7;
742 doFlushCode(adr - off, (n + off + 7) >> 3);
746 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */