LibreOffice Module bridges (master) 1
gcc3_linux_sparc64/cpp2uno.cxx
Go to the documentation of this file.
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*
3 * This file is part of the LibreOffice project.
4 *
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/.
8 *
9 * This file incorporates work covered by the following license notice:
10 *
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 .
18 */
19
20#include <sal/config.h>
21
22#include <typeinfo>
23
24#include <com/sun/star/uno/genfunc.hxx>
25#include <sal/log.hxx>
26#include <typelib/typedescription.hxx>
27#include <uno/data.h>
28#include "bridge.hxx"
29#include "cppinterfaceproxy.hxx"
30#include "types.hxx"
31#include "vtablefactory.hxx"
32#include "share.hxx"
33
34#define GET_FP(n, p) \
35 __asm__( "ldx %0, %%l0\n\t" \
36 "std %%f" #n ", [%%l0]\n" \
37 : : "m"(p) );
38
39using namespace com::sun::star::uno;
40
42{
44 {
45 for (const typelib_CompoundTypeDescription * p
46 = reinterpret_cast< const typelib_CompoundTypeDescription * >(type);
47 p != NULL; p = p->pBaseTypeDescription)
48 {
49 for (sal_Int32 i = 0; i < p->nMembers; ++i)
50 {
51 if (p->ppTypeRefs[i]->eTypeClass == typelib_TypeClass_STRUCT ||
52 p->ppTypeRefs[i]->eTypeClass == typelib_TypeClass_EXCEPTION)
53 {
55 TYPELIB_DANGER_GET(&t, p->ppTypeRefs[i]);
56 bool b = is_complex_struct(t);
57 TYPELIB_DANGER_RELEASE(t);
58 if (b) {
59 return true;
60 }
61 }
62 else if (!bridges::cpp_uno::shared::isSimpleType(p->ppTypeRefs[i]->eTypeClass))
63 return true;
64 }
65 }
66 return false;
67 }
68
69 bool return_in_hidden_param( typelib_TypeDescriptionReference *pTypeRef )
70 {
72 return false;
73 else if (pTypeRef->eTypeClass == typelib_TypeClass_STRUCT ||
74 pTypeRef->eTypeClass == typelib_TypeClass_EXCEPTION)
75 {
76 typelib_TypeDescription * pTypeDescr = 0;
77 TYPELIB_DANGER_GET( &pTypeDescr, pTypeRef );
78
79 //A Composite Type not larger than 32 bytes is returned in up to two GPRs
80 bool bRet = pTypeDescr->nSize > 32 || is_complex_struct(pTypeDescr);
81
82 TYPELIB_DANGER_RELEASE( pTypeDescr );
83 return bRet;
84 }
85 return true;
86 }
87}
88
89
90namespace
91{
92
93static typelib_TypeClass cpp2uno_call(
95 const typelib_TypeDescription * pMemberTypeDescr,
96 typelib_TypeDescriptionReference * pReturnTypeRef, // 0 indicates void return
97 sal_Int32 nParams, typelib_MethodParameter * pParams,
98 void ** pCallStack,
99 sal_Int64 * pRegisterReturn /* space for register return */ )
100{
101 // pCallStack: [ret ptr], this, params
102 char * pCppStack = (char *)pCallStack;
103
104 // return
105 typelib_TypeDescription * pReturnTypeDescr = 0;
106 if (pReturnTypeRef)
107 TYPELIB_DANGER_GET( &pReturnTypeDescr, pReturnTypeRef );
108
109 void * pUnoReturn = 0;
110 void * pCppReturn = 0; // complex return ptr: if != 0 && != pUnoReturn, reconversion need
111
112 int paramsOffset;
113 if (pReturnTypeDescr)
114 {
116 {
117 pCppReturn = *(void**)pCppStack; // complex return via ptr (pCppReturn)
119 pReturnTypeDescr )
120 ? alloca( pReturnTypeDescr->nSize )
121 : pCppReturn); // direct way
122 pCppStack += sizeof( void* );
123 paramsOffset = 2;
124 }
125 else
126 {
127 pUnoReturn = pRegisterReturn; // direct way for simple types
128 paramsOffset = 1;
129 }
130 }
131 else
132 {
133 paramsOffset = 1;
134 }
135 // pop this
136 pCppStack += sizeof( void* );
137
138 // stack space
139 static_assert(sizeof(void *) == sizeof(sal_Int64), "### unexpected size!");
140 // parameters
141 void ** pUnoArgs = (void **)alloca( 4 * sizeof(void *) * nParams );
142 void ** pCppArgs = pUnoArgs + nParams;
143 // indices of values this have to be converted (interface conversion cpp<=>uno)
144 sal_Int32 * pTempIndices = (sal_Int32 *)(pUnoArgs + (2 * nParams));
145 // type descriptions for reconversions
146 typelib_TypeDescription ** ppTempParamTypeDescr = (typelib_TypeDescription **)(pUnoArgs + (3 * nParams));
147
148 sal_Int32 nTempIndices = 0;
149
150 for ( sal_Int32 nPos = 0; nPos < nParams; ++nPos )
151 {
152 const typelib_MethodParameter & rParam = pParams[nPos];
153 typelib_TypeDescription * pParamTypeDescr = 0;
154 TYPELIB_DANGER_GET( &pParamTypeDescr, rParam.pTypeRef );
155
156 if (!rParam.bOut && bridges::cpp_uno::shared::isSimpleType( pParamTypeDescr )) // value
157 {
158 pCppArgs[nPos] = pUnoArgs[nPos] = CPPU_CURRENT_NAMESPACE::adjustPointer(pCppStack, pParamTypeDescr);
159 switch (pParamTypeDescr->eTypeClass) {
160 case typelib_TypeClass_FLOAT:
161 case typelib_TypeClass_DOUBLE:
162 {
163 int paramArrayIdx = nPos + paramsOffset;
164 assert(paramArrayIdx < nParams + paramsOffset);
165 switch (paramArrayIdx) {
166 // Cannot be 0 - paramsOffset >= 1
167 case 1:
168 GET_FP(2, pCppStack);
169 break;
170 case 2:
171 GET_FP(4, pCppStack);
172 break;
173 case 3:
174 GET_FP(6, pCppStack);
175 break;
176 case 4:
177 GET_FP(8, pCppStack);
178 break;
179 case 5:
180 GET_FP(10, pCppStack);
181 break;
182 case 6:
183 GET_FP(12, pCppStack);
184 break;
185 case 7:
186 GET_FP(14, pCppStack);
187 break;
188 case 8:
189 GET_FP(16, pCppStack);
190 break;
191 case 9:
192 GET_FP(18, pCppStack);
193 break;
194 case 10:
195 GET_FP(20, pCppStack);
196 break;
197 case 11:
198 GET_FP(22, pCppStack);
199 break;
200 case 12:
201 GET_FP(24, pCppStack);
202 break;
203 case 13:
204 GET_FP(26, pCppStack);
205 break;
206 case 14:
207 GET_FP(28, pCppStack);
208 break;
209 case 15:
210 GET_FP(30, pCppStack);
211 break;
212 // Anything larger is passed on the stack
213 }
214 break;
215 }
216 default:
217 break;
218 }
219 // no longer needed
220 TYPELIB_DANGER_RELEASE( pParamTypeDescr );
221 }
222 else // ptr to complex value | ref
223 {
224 pCppArgs[nPos] = *(void **)pCppStack;
225
226 if (! rParam.bIn) // is pure out
227 {
228 // uno out is unconstructed mem!
229 pUnoArgs[nPos] = alloca( pParamTypeDescr->nSize );
230 pTempIndices[nTempIndices] = nPos;
231 // will be released at reconversion
232 ppTempParamTypeDescr[nTempIndices++] = pParamTypeDescr;
233 }
234 // is in/inout
236 pParamTypeDescr ))
237 {
238 uno_copyAndConvertData( pUnoArgs[nPos] = alloca( pParamTypeDescr->nSize ),
239 *(void **)pCppStack, pParamTypeDescr,
240 pThis->getBridge()->getCpp2Uno() );
241 pTempIndices[nTempIndices] = nPos; // has to be reconverted
242 // will be released at reconversion
243 ppTempParamTypeDescr[nTempIndices++] = pParamTypeDescr;
244 }
245 else // direct way
246 {
247 pUnoArgs[nPos] = *(void **)pCppStack;
248 // no longer needed
249 TYPELIB_DANGER_RELEASE( pParamTypeDescr );
250 }
251 }
252 pCppStack += sizeof(sal_Int64); // standard parameter length
253 }
254
255 // ExceptionHolder
256 uno_Any aUnoExc; // Any will be constructed by callee
257 uno_Any * pUnoExc = &aUnoExc;
258
259 // invoke uno dispatch call
260 (*pThis->getUnoI()->pDispatcher)(pThis->getUnoI(), pMemberTypeDescr, pUnoReturn, pUnoArgs, &pUnoExc );
261
262 // in case an exception occurred...
263 if (pUnoExc)
264 {
265 // destruct temporary in/inout params
266 for ( ; nTempIndices--; )
267 {
268 sal_Int32 nIndex = pTempIndices[nTempIndices];
269
270 if (pParams[nIndex].bIn) // is in/inout => was constructed
271 uno_destructData( pUnoArgs[nIndex], ppTempParamTypeDescr[nTempIndices], 0 );
272 TYPELIB_DANGER_RELEASE( ppTempParamTypeDescr[nTempIndices] );
273 }
274 if (pReturnTypeDescr)
275 TYPELIB_DANGER_RELEASE( pReturnTypeDescr );
277 // has to destruct the any
278 // is here for dummy
279 return typelib_TypeClass_VOID;
280 }
281 else // else no exception occurred...
282 {
283 // temporary params
284 for ( ; nTempIndices--; )
285 {
286 sal_Int32 nIndex = pTempIndices[nTempIndices];
287 typelib_TypeDescription * pParamTypeDescr = ppTempParamTypeDescr[nTempIndices];
288
289 if (pParams[nIndex].bOut) // inout/out
290 {
291 // convert and assign
292 uno_destructData( pCppArgs[nIndex], pParamTypeDescr, cpp_release );
293 uno_copyAndConvertData( pCppArgs[nIndex], pUnoArgs[nIndex], pParamTypeDescr,
294 pThis->getBridge()->getUno2Cpp() );
295 }
296 // destroy temp uno param
297 uno_destructData( pUnoArgs[nIndex], pParamTypeDescr, 0 );
298
299 TYPELIB_DANGER_RELEASE( pParamTypeDescr );
300 }
301 // return
302 if (pCppReturn) // has complex return
303 {
304 if (pUnoReturn != pCppReturn) // needs reconversion
305 {
306 uno_copyAndConvertData( pCppReturn, pUnoReturn, pReturnTypeDescr,
307 pThis->getBridge()->getUno2Cpp() );
308 // destroy temp uno return
309 uno_destructData( pUnoReturn, pReturnTypeDescr, 0 );
310 }
311 // complex return ptr is set to eax
312 *(void **)pRegisterReturn = pCppReturn;
313 }
314 if (pReturnTypeDescr)
315 {
316 typelib_TypeClass eRet = (typelib_TypeClass)pReturnTypeDescr->eTypeClass;
317 TYPELIB_DANGER_RELEASE( pReturnTypeDescr );
318 return eRet;
319 }
320 else
321 return typelib_TypeClass_VOID;
322 }
323}
324
325
326static typelib_TypeClass cpp_mediate(
327 sal_Int32 nFunctionIndex,
328 sal_Int32 nVtableOffset,
329 void ** pCallStack,
330 sal_Int64 * pRegisterReturn /* space for register return */ )
331{
332 static_assert(sizeof(sal_Int64)==sizeof(void *), "### unexpected!");
333
334 // pCallStack: [ret*], this, params
335 void * pThis;
336 if (nFunctionIndex & 0x80000000)
337 {
338 nFunctionIndex &= 0x7fffffff;
339 pThis = pCallStack[1];
340 }
341 else
342 {
343 pThis = pCallStack[0];
344 }
345
346 pThis = static_cast< char * >(pThis) - nVtableOffset;
349
350 typelib_InterfaceTypeDescription * pTypeDescr = pCppI->getTypeDescr();
351
352 if (nFunctionIndex >= pTypeDescr->nMapFunctionIndexToMemberIndex)
353 {
354 SAL_WARN(
355 "bridges",
356 "illegal " << OUString::unacquired(&pTypeDescr->aBase.pTypeName)
357 << " vtable index " << nFunctionIndex << "/"
358 << pTypeDescr->nMapFunctionIndexToMemberIndex);
359 throw RuntimeException(
360 ("illegal " + OUString::unacquired(&pTypeDescr->aBase.pTypeName)
361 + " vtable index " + OUString::number(nFunctionIndex) + "/"
362 + OUString::number(pTypeDescr->nMapFunctionIndexToMemberIndex)),
363 (XInterface *)pCppI);
364 }
365
366 // determine called method
367 sal_Int32 nMemberPos = pTypeDescr->pMapFunctionIndexToMemberIndex[nFunctionIndex];
368 assert(nMemberPos < pTypeDescr->nAllMembers);
369
370 TypeDescription aMemberDescr( pTypeDescr->ppAllMembers[nMemberPos] );
371
372 typelib_TypeClass eRet;
373 switch (aMemberDescr.get()->eTypeClass)
374 {
375 case typelib_TypeClass_INTERFACE_ATTRIBUTE:
376 {
377 if (pTypeDescr->pMapMemberIndexToFunctionIndex[nMemberPos] == nFunctionIndex)
378 {
379 // is GET method
380 eRet = cpp2uno_call(
381 pCppI, aMemberDescr.get(),
382 ((typelib_InterfaceAttributeTypeDescription *)aMemberDescr.get())->pAttributeTypeRef,
383 0, 0, // no params
384 pCallStack, pRegisterReturn );
385 }
386 else
387 {
388 // is SET method
389 typelib_MethodParameter aParam;
390 aParam.pTypeRef =
391 ((typelib_InterfaceAttributeTypeDescription *)aMemberDescr.get())->pAttributeTypeRef;
392 aParam.bIn = sal_True;
393 aParam.bOut = sal_False;
394
395 eRet = cpp2uno_call(
396 pCppI, aMemberDescr.get(),
397 0, // indicates void return
398 1, &aParam,
399 pCallStack, pRegisterReturn );
400 }
401 break;
402 }
403 case typelib_TypeClass_INTERFACE_METHOD:
404 {
405 // is METHOD
406 switch (nFunctionIndex)
407 {
408 case 1: // acquire()
409 pCppI->acquireProxy(); // non virtual call!
410 eRet = typelib_TypeClass_VOID;
411 break;
412 case 2: // release()
413 pCppI->releaseProxy(); // non virtual call!
414 eRet = typelib_TypeClass_VOID;
415 break;
416 case 0: // queryInterface() opt
417 {
418 typelib_TypeDescription * pTD = 0;
419 TYPELIB_DANGER_GET( &pTD, reinterpret_cast< Type * >( pCallStack[2] )->getTypeLibType() );
420 if (pTD)
421 {
422 XInterface * pInterface = 0;
423 (*pCppI->getBridge()->getCppEnv()->getRegisteredInterface)(
424 pCppI->getBridge()->getCppEnv(),
425 (void **)&pInterface, pCppI->getOid().pData, (typelib_InterfaceTypeDescription *)pTD );
426
427 if (pInterface)
428 {
429 ::uno_any_construct(
430 reinterpret_cast< uno_Any * >( pCallStack[0] ),
431 &pInterface, pTD, cpp_acquire );
432 pInterface->release();
433 TYPELIB_DANGER_RELEASE( pTD );
434 *(void **)pRegisterReturn = pCallStack[0];
435 eRet = typelib_TypeClass_ANY;
436 break;
437 }
438 TYPELIB_DANGER_RELEASE( pTD );
439 }
440 } // else perform queryInterface()
441 default:
442 eRet = cpp2uno_call(
443 pCppI, aMemberDescr.get(),
444 ((typelib_InterfaceMethodTypeDescription *)aMemberDescr.get())->pReturnTypeRef,
445 ((typelib_InterfaceMethodTypeDescription *)aMemberDescr.get())->nParams,
446 ((typelib_InterfaceMethodTypeDescription *)aMemberDescr.get())->pParams,
447 pCallStack, pRegisterReturn );
448 }
449 break;
450 }
451 default:
452 {
453 throw RuntimeException( "no member description found!", (XInterface *)pCppI );
454 }
455 }
456 return eRet;
457}
458
459
460
465static void cpp_vtable_call(int nFunctionIndex, void** pCallStack, int vTableOffset)
466{
467 sal_Int64 nRegReturn[4] = { 0 };
468 void * pRegReturn = &nRegReturn[0];
469
470 //__asm__( "st %%i0, %0\n\t"
471 // "stx %%i1, %1\n\t"
472 // "st %%i2, %2\n\t"
473 // : : "m"(nFunctionIndex), "m"(pCallStack), "m"(vTableOffset) );
474
475// fprintf(stderr,"cpp_mediate nFunctionIndex=%x\n",nFunctionIndex);
476// fflush(stderr);
477
478 //const sal_Bool bComplex = (nFunctionIndex & 0x80000000) ? sal_True : sal_False;
479 typelib_TypeClass aType =
480 cpp_mediate( nFunctionIndex, vTableOffset, pCallStack+16, (sal_Int64*)&nRegReturn );
481
482 switch( aType )
483 {
484 case typelib_TypeClass_BOOLEAN:
485 case typelib_TypeClass_BYTE:
486 __asm__( "ldx %0, %%l0\n\t"
487 "ldsb [%%l0], %%i0\n"
488 : : "m"(pRegReturn) );
489 break;
490 case typelib_TypeClass_CHAR:
491 case typelib_TypeClass_SHORT:
492 case typelib_TypeClass_UNSIGNED_SHORT:
493 __asm__( "ldx %0, %%l0\n\t"
494 "ldsh [%%l0], %%i0\n"
495 : : "m"(pRegReturn) );
496 break;
497 case typelib_TypeClass_ENUM:
498 case typelib_TypeClass_LONG:
499 case typelib_TypeClass_UNSIGNED_LONG:
500 __asm__( "ldx %0, %%l0\n\t"
501 "ld [%%l0], %%i0\n"
502 : : "m"(pRegReturn) );
503 break;
504 case typelib_TypeClass_HYPER:
505 case typelib_TypeClass_UNSIGNED_HYPER:
506 __asm__( "ldx %0, %%l0\n\t"
507 "ldx [%%l0], %%i0\n\t"
508 : : "m"(pRegReturn) );
509 break;
510 case typelib_TypeClass_FLOAT:
511 __asm__( "ldx %0, %%l0\n\t"
512 "ld [%%l0], %%f0\n"
513 : : "m"(pRegReturn) );
514 break;
515 case typelib_TypeClass_DOUBLE:
516 __asm__( "ldx %0, %%l0\n\t"
517 "ldd [%%l0], %%f0\n"
518 : : "m"(pRegReturn) );
519 break;
520 case typelib_TypeClass_VOID:
521 break;
522 case typelib_TypeClass_STRUCT:
523 case typelib_TypeClass_EXCEPTION:
524 __asm__( "ldx %0, %%l0\n\t"
525 "ldx [%%l0 ], %%i0\n\t"
526 "ldx [%%l0+ 8], %%i1\n\t"
527 "ldx [%%l0+16], %%i2\n\t"
528 "ldx [%%l0+24], %%i3\n\t"
529 "ldd [%%l0 ], %%f0\n\t"
530 "ldd [%%l0+ 8], %%f2\n\t"
531 "ldd [%%l0+16], %%f4\n\t"
532 "ldd [%%l0+24], %%f6\n\t"
533 : : "m"(pRegReturn) );
534 break;
535 default:
536 break;
537 }
538
539 //if( bComplex )
540 //{
541 // __asm__( "add %i7, 4, %i7\n\t" );
542 // // after call to complex return valued function there is an unimp instruction
543 //}
544
545}
546
547extern "C" void privateSnippetExecutor(...);
548
549int const codeSnippetSize = 120;
550unsigned char * codeSnippet(
551 unsigned char * code, sal_Int32 functionIndex, sal_Int32 vtableOffset,
552 bool bHasHiddenParam, sal_Int32 nParams)
553{
554 sal_uInt32 index = functionIndex;
555 if (bHasHiddenParam) {
556 index |= 0x80000000;
557 }
558 unsigned int * p = reinterpret_cast< unsigned int * >(code);
559 static_assert(sizeof (unsigned int) == 4, "boo");
560 static_assert(sizeof (unsigned long long) == 8, "boo");
561 ++nParams; // implicit this ptr
562 if (bHasHiddenParam) {
563 ++nParams;
564 }
565 long long frameSize;
566 if (nParams > 6) {
567 frameSize = 128 + nParams * 8;
568 } else {
569 frameSize = 176;
570 }
571 assert(frameSize <= 4096);
572 frameSize = -frameSize;
573 switch (nParams) {
574 default:
575 assert(nParams >= 6);
576 // stx %o5, [%sp+168+2047]:
577 *p++ = 0xDA73A8A7;
578 case 5:
579 // stx %o4, [%sp+160+2047]:
580 *p++ = 0xD873A89F;
581 case 4:
582 // stx %o3, [%sp+152+2047]:
583 *p++ = 0xD673A897;
584 case 3:
585 // stx %o2, [%sp+144+2047]:
586 *p++ = 0xD473A88F;
587 case 2:
588 // stx %o1, [%sp+136+2047]:
589 *p++ = 0xD273A887;
590 case 1:
591 // stx %o0, [%sp+128+2047]:
592 *p++ = 0xD073A87F;
593 case 0:
594 break;
595 }
596 // sethi %hi(index), %o0:
597 *p++ = 0x11000000 | (index >> 10);
598 // or %o0, %lo(index), %o0:
599 *p++ = 0x90122000 | (index & 0x3FF);
600 // sethi %hh(cpp_vtable_call), %o3:
601 *p++ = 0x17000000 | (reinterpret_cast< unsigned long long >(cpp_vtable_call) >> 42);
602 // or %o3, %hm(cpp_vtable_call), %o3:
603 *p++ = 0x9612E000 | ((reinterpret_cast< unsigned long long >(cpp_vtable_call) >> 32) & 0x3FF);
604 // sllx %o3, 32, %o3
605 *p++ = 0x972AF020;
606 // sethi %lm(cpp_vtable_call), %o2:
607 *p++ = 0x15000000 | ((reinterpret_cast< unsigned long long >(cpp_vtable_call) >> 10) & 0x3FFFFF);
608 // or %o2, %lo(cpp_vtable_call), %o2:
609 *p++ = 0x9412A000 | (reinterpret_cast< unsigned long long >(cpp_vtable_call) & 0x3FF);
610 // or %o2, %o3, %o3:
611 *p++ = 0x9612800B;
612 // sethi %hh(privateSnippetExecutor), %o1:
613 *p++ = 0x13000000 | (reinterpret_cast< unsigned long long >(privateSnippetExecutor) >> 42);
614 // or %o1, %hm(privateSnippetExecutor), %o1:
615 *p++ = 0x92126000 | ((reinterpret_cast< unsigned long long >(privateSnippetExecutor) >> 32) & 0x3FF);
616 // sllx %o1, 32, %o1:
617 *p++ = 0x932a7020;
618 // sethi %lm(privateSnippetExecutor), %o2:
619 *p++ = 0x15000000 | ((reinterpret_cast< unsigned long long >(privateSnippetExecutor) >> 10) & 0x3FFFFF);
620 // or %o2, %lo(privateSnippetExecutor), %o2:
621 *p++ = 0x9412A000 | (reinterpret_cast< unsigned long long >(privateSnippetExecutor) & 0x3FF);
622 // or %o2, %o1, %o1:
623 *p++ = 0x92128009;
624 // sethi %hh(frameSize), %o4:
625 *p++ = 0x19000000 | (*reinterpret_cast< unsigned long long * >(&frameSize) >> 42);
626 // or %o4, %hm(frameSize), %o4:
627 *p++ = 0x98132000 | ((*reinterpret_cast< unsigned long long * >(&frameSize) >> 32) & 0x3FF);
628 // sllx %o4, 32, %o4
629 *p++ = 0x992B3020;
630 // sethi %lm(frameSize), %o2:
631 *p++ = 0x15000000 | ((*reinterpret_cast< unsigned long long * >(&frameSize) >> 10) & 0x3FFFFF);
632 // or %o2, %lo(frameSize), %o2:
633 *p++ = 0x9412A000 | (*reinterpret_cast< unsigned long long * >(&frameSize) & 0x3FF);
634 // or %o2, %o4, %o4:
635 *p++ = 0x9812800C;
636 // sethi %hi(vtableOffset), %o2:
637 *p++ = 0x15000000 | (vtableOffset >> 10);
638 // or %o2, %lo(vtableOffset), %o2:
639 *p++ = 0x9412A000 | (vtableOffset & 0x3FF);
640 // save %sp, -frameSize, %sp
641 //*p++ = 0x9DE3A000 | (*reinterpret_cast< unsigned int * >(&frameSize) & 0x1FFF);
642 // jmpl %o1, %g0:
643 *p++ = 0x81C24000;
644 // add %sp, 2047, %o1:
645 *p++ = 0x9203A7FF;
646 assert(reinterpret_cast< unsigned char * >(p) - code <= codeSnippetSize);
647 return code + codeSnippetSize;
648}
649
650} //end of namespace
651
653
656{
657 return static_cast< Slot * >(block) + 2;
658}
659
661 sal_Int32 slotCount)
662{
663 return (slotCount + 2) * sizeof (Slot) + slotCount * codeSnippetSize;
664}
665
666namespace {
667// Some dummy type whose RTTI is used in the synthesized proxy vtables to make uses of dynamic_cast
668// on such proxy objects not crash:
669struct ProxyRtti {};
670}
671
674 void * block, sal_Int32 slotCount, sal_Int32,
675 typelib_InterfaceTypeDescription *)
676{
677 Slot * slots = mapBlockToVtable(block);
678 slots[-2].fn = 0; //null
679 slots[-1].fn = &typeid(ProxyRtti);
680 return slots + slotCount;
681}
682
684 Slot ** slots, unsigned char * code, sal_PtrDiff writetoexecdiff,
685 typelib_InterfaceTypeDescription const * type, sal_Int32 functionOffset,
686 sal_Int32 functionCount, sal_Int32 vTableOffset)
687{
688 (*slots) -= functionCount;
689 Slot * s = *slots;
690 for (sal_Int32 i = 0; i < type->nMembers; ++i) {
691 typelib_TypeDescription * member = 0;
692 TYPELIB_DANGER_GET(&member, type->ppMembers[i]);
693 assert(member != 0);
694 switch (member->eTypeClass) {
695 case typelib_TypeClass_INTERFACE_ATTRIBUTE:
696 // Getter:
697 (s++)->fn = code + writetoexecdiff;
699 code, functionOffset++, vTableOffset,
701 reinterpret_cast<
702 typelib_InterfaceAttributeTypeDescription * >(
703 member)->pAttributeTypeRef), 0);
704 // Setter:
705 if (!reinterpret_cast<
706 typelib_InterfaceAttributeTypeDescription * >(
707 member)->bReadOnly)
708 {
709 (s++)->fn = code + writetoexecdiff;
710 code = codeSnippet(code, functionOffset++, vTableOffset, false, 1);
711 }
712 break;
713
714 case typelib_TypeClass_INTERFACE_METHOD:
715 (s++)->fn = code + writetoexecdiff;
717 code, functionOffset++, vTableOffset,
719 reinterpret_cast<
720 typelib_InterfaceMethodTypeDescription * >(
721 member)->pReturnTypeRef),
722 reinterpret_cast<
723 typelib_InterfaceMethodTypeDescription * >(
724 member)->nParams);
725 break;
726
727 default:
728 assert(false);
729 break;
730 }
731 TYPELIB_DANGER_RELEASE(member);
732 }
733 return code;
734}
735
736// use flush code from cc50_solaris_sparc
737
738extern "C" void doFlushCode(unsigned long address, unsigned long count);
739
741 unsigned char const * begin, unsigned char const * end)
742{
743 unsigned long n = end - begin;
744 if (n != 0) {
745 unsigned long adr = reinterpret_cast< unsigned long >(begin);
746 unsigned long off = adr & 7;
747 doFlushCode(adr - off, (n + off + 7) >> 3);
748 }
749}
750
751/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
XPropertyListType t
uno_Mapping * getUno2Cpp()
Definition: bridge.hxx:73
uno_ExtEnvironment * getCppEnv()
Definition: bridge.hxx:69
uno_Mapping * getCpp2Uno()
Definition: bridge.hxx:72
A cpp proxy wrapping a uno interface.
static CppInterfaceProxy * castInterfaceToProxy(void *pInterface)
typelib_InterfaceTypeDescription * getTypeDescr()
static Slot * mapBlockToVtable(void *block)
Given a pointer to a block, turn it into a vtable pointer.
static void flushCode(unsigned char const *begin, unsigned char const *end)
Flush all the generated code snippets of a vtable, on platforms that require it.
static unsigned char * addLocalFunctions(Slot **slots, unsigned char *code, sal_PtrDiff writetoexecdiff, typelib_InterfaceTypeDescription const *type, sal_Int32 functionOffset, sal_Int32 functionCount, sal_Int32 vtableOffset)
Fill the vtable slots corresponding to all local (i.e., not inherited) functions of a given interface...
static Slot * initializeBlock(void *block, sal_Int32 slotCount, sal_Int32 vtableNumber, typelib_InterfaceTypeDescription *type)
Initialize a raw vtable block.
static std::size_t getBlockSize(sal_Int32 slotCount)
Calculate the size of a raw vtable block.
void SAL_CALL uno_destructData(void *pValue, typelib_TypeDescription *pTypeDescr, uno_ReleaseFunc release) SAL_THROW_EXTERN_C()
void SAL_CALL uno_copyAndConvertData(void *pDest, void *pSource, typelib_TypeDescription *pTypeDescr, uno_Mapping *mapping) SAL_THROW_EXTERN_C()
void cpp_vtable_call(sal_Int32 func, sal_Int32 offset, void **pStack)
is called on incoming vtable calls (called by asm snippets)
register sal_uInt32 r28 __asm__("%r28")
void(* privateSnippetExecutor)()
void doFlushCode(unsigned long address, unsigned long count)
#define GET_FP(n, p)
const int codeSnippetSize
static unsigned char * codeSnippet(unsigned char *code, sal_Int32 nFunctionIndex, sal_Int32 nVtableOffset, bool bHasHiddenParam)
static int cpp2uno_call(bridges::cpp_uno::shared::CppInterfaceProxy *pThis, const typelib_TypeDescription *pMemberTypeDescr, typelib_TypeDescriptionReference *pReturnTypeRef, sal_Int32 nParams, typelib_MethodParameter *pParams, void **gpreg, void **fpreg, void **ovrflw, sal_uInt64 *pRegisterReturn)
sal_Int32 nIndex
void * p
sal_Int64 n
sal_uInt16 nPos
#define SAL_WARN(area, stream)
return NULL
struct _typelib_TypeDescription typelib_TypeDescription
Definition: msvc/except.hxx:53
struct _uno_Any uno_Any
Definition: msvc/except.hxx:32
typelib_TypeClass __cdecl cpp_mediate(void **pCallStack, const sal_Int32 nFunctionIndex, const sal_Int32 nVtableOffset, sal_Int64 *const pRegisterReturn)
bool return_in_hidden_param(typelib_TypeDescriptionReference *pTypeRef)
char * adjustPointer(char *pIn, typelib_TypeDescription *pType)
void raiseException(uno_Any *pUnoExc, uno_Mapping *pUno2Cpp)
bool is_complex_struct(const typelib_TypeDescription *type)
bool isSimpleType(typelib_TypeClass typeClass)
Determines whether a type is a "simple" type (VOID, BOOLEAN, BYTE, SHORT, UNSIGNED SHORT,...
Definition: types.cxx:28
bool relatesToInterfaceType(typelib_TypeDescription const *type)
Determines whether a type relates to an interface type (is itself an interface type,...
Definition: types.cxx:41
Type
int i
index
enumrange< T >::Iterator begin(enumrange< T >)
end
sal_Unicode code
const wchar_t *typedef int(__stdcall *DllNativeUnregProc)(int
#define sal_True
#define sal_False
ResultType type