LibreOffice Module bridges (master) 1
gcc3_linux_powerpc/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
21#include <string.h>
22#include <typeinfo>
23
24#include <com/sun/star/uno/genfunc.hxx>
25#include <sal/log.hxx>
26#include <uno/data.h>
27#include <typelib/typedescription.hxx>
28
29#include "bridge.hxx"
30#include "cppinterfaceproxy.hxx"
31#include "types.hxx"
32#include "vtablefactory.hxx"
33
34#include "share.hxx"
35
36
37using namespace ::com::sun::star::uno;
38
39namespace
40{
41
42static typelib_TypeClass cpp2uno_call(
44 const typelib_TypeDescription * pMemberTypeDescr,
45 typelib_TypeDescriptionReference * pReturnTypeRef, // 0 indicates void return
46 sal_Int32 nParams, typelib_MethodParameter * pParams,
47 void ** gpreg, void ** fpreg, void ** ovrflw,
48 sal_Int64 * pRegisterReturn /* space for register return */ )
49{
50 int ng = 0; //number of gpr registers used
51#ifndef __NO_FPRS__
52 int nf = 0; //number of fpr registers used
53#endif
54 void ** pCppStack; //temporary stack pointer
55
56 // gpreg: [ret *], this, [gpr params]
57 // fpreg: [fpr params]
58 // ovrflw: [gpr or fpr params (properly aligned)]
59
60 // return
61 typelib_TypeDescription * pReturnTypeDescr = 0;
62 if (pReturnTypeRef)
63 TYPELIB_DANGER_GET( &pReturnTypeDescr, pReturnTypeRef );
64
65 void * pUnoReturn = 0;
66 void * pCppReturn = 0; // complex return ptr: if != 0 && != pUnoReturn, reconversion need
67
68 if (pReturnTypeDescr)
69 {
70 if (bridges::cpp_uno::shared::isSimpleType( pReturnTypeDescr ))
71 {
72 pUnoReturn = pRegisterReturn; // direct way for simple types
73 }
74 else // complex return via ptr (pCppReturn)
75 {
76 pCppReturn = *(void **)gpreg;
77 gpreg++;
78 ng++;
79
80 pUnoReturn = (bridges::cpp_uno::shared::relatesToInterfaceType( pReturnTypeDescr )
81 ? alloca( pReturnTypeDescr->nSize )
82 : pCppReturn); // direct way
83 }
84 }
85 // pop this
86 gpreg++;
87 ng++;
88
89 // stack space
90 static_assert(sizeof(void *) == sizeof(sal_Int32), "### unexpected size!");
91 // parameters
92 void ** pUnoArgs = (void **)alloca( 4 * sizeof(void *) * nParams );
93 void ** pCppArgs = pUnoArgs + nParams;
94 // indices of values this have to be converted (interface conversion cpp<=>uno)
95 sal_Int32 * pTempIndices = (sal_Int32 *)(pUnoArgs + (2 * nParams));
96 // type descriptions for reconversions
97 typelib_TypeDescription ** ppTempParamTypeDescr = (typelib_TypeDescription **)(pUnoArgs + (3 * nParams));
98
99 sal_Int32 nTempIndices = 0;
100
101 for ( sal_Int32 nPos = 0; nPos < nParams; ++nPos )
102 {
103 const typelib_MethodParameter & rParam = pParams[nPos];
104 typelib_TypeDescription * pParamTypeDescr = 0;
105 TYPELIB_DANGER_GET( &pParamTypeDescr, rParam.pTypeRef );
106
107 if (!rParam.bOut && bridges::cpp_uno::shared::isSimpleType( pParamTypeDescr ))
108 // value
109 {
110
111 switch (pParamTypeDescr->eTypeClass)
112 {
113
114 case typelib_TypeClass_DOUBLE:
115#ifndef __NO_FPRS__
116 if (nf < 8) {
117 pCppArgs[nPos] = fpreg;
118 pUnoArgs[nPos] = fpreg;
119 nf++;
120 fpreg += 2;
121#else
122 if (ng & 1) {
123 ng++;
124 gpreg++;
125 }
126 if (ng < 8) {
127 pCppArgs[nPos] = gpreg;
128 pUnoArgs[nPos] = gpreg;
129 ng += 2;
130 gpreg += 2;
131#endif
132 } else {
133 if (((long)ovrflw) & 4) ovrflw++;
134 pCppArgs[nPos] = ovrflw;
135 pUnoArgs[nPos] = ovrflw;
136 ovrflw += 2;
137 }
138 break;
139
140 case typelib_TypeClass_FLOAT:
141 // fpreg are all double values so need to
142 // modify fpreg to be a single word float value
143#ifndef __NO_FPRS__
144 if (nf < 8) {
145 float tmp = (float) (*((double *)fpreg));
146 (*((float *) fpreg)) = tmp;
147 pCppArgs[nPos] = fpreg;
148 pUnoArgs[nPos] = fpreg;
149 nf++;
150 fpreg += 2;
151#else
152 if (ng < 8) {
153 pCppArgs[nPos] = gpreg;
154 pUnoArgs[nPos] = gpreg;
155 ng++;
156 gpreg++;
157#endif
158 } else {
159#if 0 /* abi is not being followed correctly */
160 if (((long)ovrflw) & 4) ovrflw++;
161 float tmp = (float) (*((double *)ovrflw));
162 (*((float *) ovrflw)) = tmp;
163 pCppArgs[nPos] = ovrflw;
164 pUnoArgs[nPos] = ovrflw;
165 ovrflw += 2;
166#else
167 pCppArgs[nPos] = ovrflw;
168 pUnoArgs[nPos] = ovrflw;
169 ovrflw += 1;
170#endif
171 }
172 break;
173
174 case typelib_TypeClass_HYPER:
175 case typelib_TypeClass_UNSIGNED_HYPER:
176 if (ng & 1) {
177 ng++;
178 gpreg++;
179 }
180 if (ng < 8) {
181 pCppArgs[nPos] = gpreg;
182 pUnoArgs[nPos] = gpreg;
183 ng += 2;
184 gpreg += 2;
185 } else {
186 if (((long)ovrflw) & 4) ovrflw++;
187 pCppArgs[nPos] = ovrflw;
188 pUnoArgs[nPos] = ovrflw;
189 ovrflw += 2;
190 }
191 break;
192
193 case typelib_TypeClass_BYTE:
194 case typelib_TypeClass_BOOLEAN:
195 if (ng < 8) {
196 pCppArgs[nPos] = (((char *)gpreg) + 3);
197 pUnoArgs[nPos] = (((char *)gpreg) + 3);
198 ng++;
199 gpreg++;
200 } else {
201 pCppArgs[nPos] = (((char *)ovrflw) + 3);
202 pUnoArgs[nPos] = (((char *)ovrflw) + 3);
203 ovrflw++;
204 }
205 break;
206
207
208 case typelib_TypeClass_CHAR:
209 case typelib_TypeClass_SHORT:
210 case typelib_TypeClass_UNSIGNED_SHORT:
211 if (ng < 8) {
212 pCppArgs[nPos] = (((char *)gpreg)+ 2);
213 pUnoArgs[nPos] = (((char *)gpreg)+ 2);
214 ng++;
215 gpreg++;
216 } else {
217 pCppArgs[nPos] = (((char *)ovrflw) + 2);
218 pUnoArgs[nPos] = (((char *)ovrflw) + 2);
219 ovrflw++;
220 }
221 break;
222
223
224 default:
225 if (ng < 8) {
226 pCppArgs[nPos] = gpreg;
227 pUnoArgs[nPos] = gpreg;
228 ng++;
229 gpreg++;
230 } else {
231 pCppArgs[nPos] = ovrflw;
232 pUnoArgs[nPos] = ovrflw;
233 ovrflw++;
234 }
235 break;
236
237 }
238 // no longer needed
239 TYPELIB_DANGER_RELEASE( pParamTypeDescr );
240 }
241 else // ptr to complex value | ref
242 {
243
244 if (ng < 8) {
245 pCppArgs[nPos] = *(void **)gpreg;
246 pCppStack = gpreg;
247 ng++;
248 gpreg++;
249 } else {
250 pCppArgs[nPos] = *(void **)ovrflw;
251 pCppStack = ovrflw;
252 ovrflw++;
253 }
254
255 if (! rParam.bIn) // is pure out
256 {
257 // uno out is unconstructed mem!
258 pUnoArgs[nPos] = alloca( pParamTypeDescr->nSize );
259 pTempIndices[nTempIndices] = nPos;
260 // will be released at reconversion
261 ppTempParamTypeDescr[nTempIndices++] = pParamTypeDescr;
262 }
263 // is in/inout
264 else if (bridges::cpp_uno::shared::relatesToInterfaceType( pParamTypeDescr ))
265 {
266 uno_copyAndConvertData( pUnoArgs[nPos] = alloca( pParamTypeDescr->nSize ),
267 *(void **)pCppStack, pParamTypeDescr,
268 pThis->getBridge()->getCpp2Uno() );
269 pTempIndices[nTempIndices] = nPos; // has to be reconverted
270 // will be released at reconversion
271 ppTempParamTypeDescr[nTempIndices++] = pParamTypeDescr;
272 }
273 else // direct way
274 {
275 pUnoArgs[nPos] = *(void **)pCppStack;
276 // no longer needed
277 TYPELIB_DANGER_RELEASE( pParamTypeDescr );
278 }
279 }
280 }
281
282 // ExceptionHolder
283 uno_Any aUnoExc; // Any will be constructed by callee
284 uno_Any * pUnoExc = &aUnoExc;
285
286 // invoke uno dispatch call
287 (*pThis->getUnoI()->pDispatcher)( pThis->getUnoI(), pMemberTypeDescr, pUnoReturn, pUnoArgs, &pUnoExc );
288
289 // in case an exception occurred...
290 if (pUnoExc)
291 {
292 // destruct temporary in/inout params
293 for ( ; nTempIndices--; )
294 {
295 sal_Int32 nIndex = pTempIndices[nTempIndices];
296
297 if (pParams[nIndex].bIn) // is in/inout => was constructed
298 uno_destructData( pUnoArgs[nIndex], ppTempParamTypeDescr[nTempIndices], 0 );
299 TYPELIB_DANGER_RELEASE( ppTempParamTypeDescr[nTempIndices] );
300 }
301 if (pReturnTypeDescr)
302 TYPELIB_DANGER_RELEASE( pReturnTypeDescr );
303
305 // has to destruct the any
306 // is here for dummy
307 return typelib_TypeClass_VOID;
308 }
309 else // else no exception occurred...
310 {
311 // temporary params
312 for ( ; nTempIndices--; )
313 {
314 sal_Int32 nIndex = pTempIndices[nTempIndices];
315 typelib_TypeDescription * pParamTypeDescr = ppTempParamTypeDescr[nTempIndices];
316
317 if (pParams[nIndex].bOut) // inout/out
318 {
319 // convert and assign
320 uno_destructData( pCppArgs[nIndex], pParamTypeDescr, cpp_release );
321 uno_copyAndConvertData( pCppArgs[nIndex], pUnoArgs[nIndex], pParamTypeDescr,
322 pThis->getBridge()->getUno2Cpp() );
323 }
324 // destroy temp uno param
325 uno_destructData( pUnoArgs[nIndex], pParamTypeDescr, 0 );
326
327 TYPELIB_DANGER_RELEASE( pParamTypeDescr );
328 }
329 // return
330 if (pCppReturn) // has complex return
331 {
332 if (pUnoReturn != pCppReturn) // needs reconversion
333 {
334 uno_copyAndConvertData( pCppReturn, pUnoReturn, pReturnTypeDescr,
335 pThis->getBridge()->getUno2Cpp() );
336 // destroy temp uno return
337 uno_destructData( pUnoReturn, pReturnTypeDescr, 0 );
338 }
339 // complex return ptr is set to return reg
340 *(void **)pRegisterReturn = pCppReturn;
341 }
342 if (pReturnTypeDescr)
343 {
344 typelib_TypeClass eRet = (typelib_TypeClass)pReturnTypeDescr->eTypeClass;
345 TYPELIB_DANGER_RELEASE( pReturnTypeDescr );
346 return eRet;
347 }
348 else
349 return typelib_TypeClass_VOID;
350 }
351}
352
353
354static typelib_TypeClass cpp_mediate(
355 sal_Int32 nFunctionIndex,
356 sal_Int32 nVtableOffset,
357 void ** gpreg, void ** fpreg, void ** ovrflw,
358 sal_Int64 * pRegisterReturn /* space for register return */ )
359{
360 static_assert(sizeof(sal_Int32)==sizeof(void *), "### unexpected!");
361
362 // gpreg: [ret *], this, [other gpr params]
363 // fpreg: [fpr params]
364 // ovrflw: [gpr or fpr params (properly aligned)]
365
366 void * pThis;
367 if (nFunctionIndex & 0x80000000 )
368 {
369 nFunctionIndex &= 0x7fffffff;
370 pThis = gpreg[1];
371 }
372 else
373 {
374 pThis = gpreg[0];
375 }
376
377 pThis = static_cast< char * >(pThis) - nVtableOffset;
380 pThis);
381
382 typelib_InterfaceTypeDescription * pTypeDescr = pCppI->getTypeDescr();
383
384 if (nFunctionIndex >= pTypeDescr->nMapFunctionIndexToMemberIndex)
385 {
386 SAL_WARN(
387 "bridges",
388 "illegal " << OUString::unacquired(&pTypeDescr->aBase.pTypeName)
389 << " vtable index " << nFunctionIndex << "/"
390 << pTypeDescr->nMapFunctionIndexToMemberIndex);
391 throw RuntimeException(
392 ("illegal " + OUString::unacquired(&pTypeDescr->aBase.pTypeName)
393 + " vtable index " + OUString::number(nFunctionIndex) + "/"
394 + OUString::number(pTypeDescr->nMapFunctionIndexToMemberIndex)),
395 (XInterface *)pThis);
396 }
397
398 // determine called method
399 sal_Int32 nMemberPos = pTypeDescr->pMapFunctionIndexToMemberIndex[nFunctionIndex];
400 assert(nMemberPos < pTypeDescr->nAllMembers);
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 throw RuntimeException( "no member description found!", (XInterface *)pThis );
487 }
488 }
489
490 return eRet;
491}
492
497static void cpp_vtable_call( int nFunctionIndex, int nVtableOffset, void** gpregptr, void** fpregptr, void** ovrflw)
498{
499 sal_Int32 gpreg[8];
500 memcpy( gpreg, gpregptr, 32);
501
502#ifndef __NO_FPRS__
503 double fpreg[8];
504 memcpy( fpreg, fpregptr, 64);
505#endif
506
507 volatile long nRegReturn[2];
508
509 // fprintf(stderr,"in cpp_vtable_call nFunctionIndex is %x\n",nFunctionIndex);
510 // fprintf(stderr,"in cpp_vtable_call nVtableOffset is %x\n",nVtableOffset);
511 // fflush(stderr);
512
513 typelib_TypeClass aType =
514 cpp_mediate( nFunctionIndex, nVtableOffset, (void**)gpreg,
515#ifndef __NO_FPRS__
516 (void**)fpreg,
517#else
518 NULL,
519#endif
520 ovrflw, (sal_Int64*)nRegReturn );
521
522 switch( aType )
523 {
524
525 // move return value into register space
526 // (will be loaded by machine code snippet)
527
528 case typelib_TypeClass_BOOLEAN:
529 case typelib_TypeClass_BYTE:
530 __asm__( "lbz 3,%0\n\t" : :
531 "m"(nRegReturn[0]) );
532 break;
533
534 case typelib_TypeClass_CHAR:
535 case typelib_TypeClass_SHORT:
536 case typelib_TypeClass_UNSIGNED_SHORT:
537 __asm__( "lhz 3,%0\n\t" : :
538 "m"(nRegReturn[0]) );
539 break;
540
541 case typelib_TypeClass_FLOAT:
542#ifndef __NO_FPRS__
543 __asm__( "lfs 1,%0\n\t" : :
544 "m" (*((float*)nRegReturn)) );
545 #else
546 __asm__( "lwz 3,%0\n\t" : :
547 "m"(nRegReturn[0]) );
548#endif
549 break;
550
551 case typelib_TypeClass_DOUBLE:
552#ifndef __NO_FPRS__
553 __asm__( "lfd 1,%0\n\t" : :
554 "m" (*((double*)nRegReturn)) );
555#else
556 __asm__( "lwz 3,%0\n\t" : :
557 "m"(nRegReturn[0]) );
558 __asm__( "lwz 4,%0\n\t" : :
559 "m"(nRegReturn[1]) );
560#endif
561 break;
562
563 case typelib_TypeClass_HYPER:
564 case typelib_TypeClass_UNSIGNED_HYPER:
565 __asm__( "lwz 4,%0\n\t" : :
566 "m"(nRegReturn[1]) ); // fall through
567
568 default:
569 __asm__( "lwz 3,%0\n\t" : :
570 "m"(nRegReturn[0]) );
571 break;
572 }
573}
574
575
576int const codeSnippetSize = 108;
577
578unsigned char * codeSnippet( unsigned char * code, sal_Int32 functionIndex, sal_Int32 vtableOffset,
579 bool simpleRetType)
580{
581
582 // fprintf(stderr,"in codeSnippet functionIndex is %x\n", functionIndex);
583 // fprintf(stderr,"in codeSnippet vtableOffset is %x\n", vtableOffset);
584 // fflush(stderr);
585
586 if (! simpleRetType )
587 functionIndex |= 0x80000000;
588
589 unsigned long * p = (unsigned long *) code;
590
591 // static_assert( sizeof (long) == 4 );
592 assert((((unsigned long)code) & 0x3) == 0 ); //aligned to 4 otherwise a mistake
593
594 /* generate this code */
595 // # so first save gpr 3 to gpr 10 (aligned to 4)
596 // stw r3,-2048(r1)
597 // stw r4,-2044(r1)
598 // stw r5,-2040(r1)
599 // stw r6,-2036(r1)
600 // stw r7,-2032(r1)
601 // stw r8,-2028(r1)
602 // stw r9,-2024(r1)
603 // stw r10,-2020(r1)
604
605
606 // # next save fpr 1 to fpr 8 (aligned to 8)
607 // if dedicated floating point registers are used
608 // stfd f1,-2016(r1)
609 // stfd f2,-2008(r1)
610 // stfd f3,-2000(r1)
611 // stfd f4,-1992(r1)
612 // stfd f5,-1984(r1)
613 // stfd f6,-1976(r1)
614 // stfd f7,-1968(r1)
615 // stfd f8,-1960(r1)
616
617 // # now here is where cpp_vtable_call must go
618 // lis r3,-8531
619 // ori r3,r3,48879
620 // mtctr r3
621
622 // # now load up the functionIndex
623 // lis r3,-8531
624 // ori r3,r3,48879
625
626 // # now load up the vtableOffset
627 // lis r4,-8531
628 // ori r4,r4,48879
629
630 // #now load up the pointer to the saved gpr registers
631 // addi r5,r1,-2048
632
633 // #now load up the pointer to the saved fpr registers
634 // addi r6,r1,-2016
635 // if no dedicated floating point registers are used then we have NULL
636 // pointer there
637 // li r6, 0
638
639 // #now load up the pointer to the overflow call stack
640 // addi r7,r1,8
641 // bctr
642
643 * p++ = 0x9061f800;
644 * p++ = 0x9081f804;
645 * p++ = 0x90a1f808;
646 * p++ = 0x90c1f80c;
647 * p++ = 0x90e1f810;
648 * p++ = 0x9101f814;
649 * p++ = 0x9121f818;
650 * p++ = 0x9141f81c;
651#ifndef __NO_FPRS__
652 * p++ = 0xd821f820;
653 * p++ = 0xd841f828;
654 * p++ = 0xd861f830;
655 * p++ = 0xd881f838;
656 * p++ = 0xd8a1f840;
657 * p++ = 0xd8c1f848;
658 * p++ = 0xd8e1f850;
659 * p++ = 0xd901f858;
660#else
661 /* these nops could be replaced with a smaller codeSnippetSize - 8 * 4 */
662 * p++ = 0x60000000;
663 * p++ = 0x60000000;
664 * p++ = 0x60000000;
665 * p++ = 0x60000000;
666 * p++ = 0x60000000;
667 * p++ = 0x60000000;
668 * p++ = 0x60000000;
669 * p++ = 0x60000000;
670#endif
671 * p++ = 0x3c600000 | (((unsigned long)cpp_vtable_call) >> 16);
672 * p++ = 0x60630000 | (((unsigned long)cpp_vtable_call) & 0x0000FFFF);
673 * p++ = 0x7c6903a6;
674 * p++ = 0x3c600000 | (((unsigned long)functionIndex) >> 16);
675 * p++ = 0x60630000 | (((unsigned long)functionIndex) & 0x0000FFFF);
676 * p++ = 0x3c800000 | (((unsigned long)vtableOffset) >> 16);
677 * p++ = 0x60840000 | (((unsigned long)vtableOffset) & 0x0000FFFF);
678 * p++ = 0x38a1f800;
679#ifndef __NO_FPRS__
680 * p++ = 0x38c1f820;
681#else
682 * p++ = 0x38c00000;
683#endif
684 * p++ = 0x38e10008;
685 * p++ = 0x4e800420;
686 return (code + codeSnippetSize);
687
688}
689
690
691}
692
693void bridges::cpp_uno::shared::VtableFactory::flushCode(unsigned char const * bptr, unsigned char const * eptr)
694{
695 int const lineSize = 32;
696 for (unsigned char const * p = bptr; p < eptr + lineSize; p += lineSize) {
697 __asm__ volatile ("dcbst 0, %0" : : "r"(p) : "memory");
698 }
699 __asm__ volatile ("sync" : : : "memory");
700 for (unsigned char const * p = bptr; p < eptr + lineSize; p += lineSize) {
701 __asm__ volatile ("icbi 0, %0" : : "r"(p) : "memory");
702 }
703 __asm__ volatile ("isync" : : : "memory");
704}
705
707
710{
711 return static_cast< Slot * >(block) + 2;
712}
713
715 sal_Int32 slotCount)
716{
717 return (slotCount + 2) * sizeof (Slot) + slotCount * codeSnippetSize;
718}
719
720namespace {
721// Some dummy type whose RTTI is used in the synthesized proxy vtables to make uses of dynamic_cast
722// on such proxy objects not crash:
723struct ProxyRtti {};
724}
725
728 void * block, sal_Int32 slotCount, sal_Int32,
729 typelib_InterfaceTypeDescription *)
730{
731 Slot * slots = mapBlockToVtable(block);
732 slots[-2].fn = 0;
733 slots[-1].fn = &typeid(ProxyRtti);
734 return slots + slotCount;
735}
736
738 Slot ** slots, unsigned char * code, sal_PtrDiff writetoexecdiff,
739 typelib_InterfaceTypeDescription const * type, sal_Int32 functionOffset,
740 sal_Int32 functionCount, sal_Int32 vtableOffset)
741{
742 (*slots) -= functionCount;
743 Slot * s = *slots;
744 // fprintf(stderr, "in addLocalFunctions functionOffset is %x\n",functionOffset);
745 // fprintf(stderr, "in addLocalFunctions vtableOffset is %x\n",vtableOffset);
746 // fflush(stderr);
747
748 for (sal_Int32 i = 0; i < type->nMembers; ++i) {
749 typelib_TypeDescription * member = 0;
750 TYPELIB_DANGER_GET(&member, type->ppMembers[i]);
751 assert(member != 0);
752 switch (member->eTypeClass) {
753 case typelib_TypeClass_INTERFACE_ATTRIBUTE:
754 // Getter:
755 (s++)->fn = code + writetoexecdiff;
757 code, functionOffset++, vtableOffset,
759 reinterpret_cast<
760 typelib_InterfaceAttributeTypeDescription * >(
761 member)->pAttributeTypeRef));
762
763 // Setter:
764 if (!reinterpret_cast<
765 typelib_InterfaceAttributeTypeDescription * >(
766 member)->bReadOnly)
767 {
768 (s++)->fn = code + writetoexecdiff;
769 code = codeSnippet(code, functionOffset++, vtableOffset, true);
770 }
771 break;
772
773 case typelib_TypeClass_INTERFACE_METHOD:
774 (s++)->fn = code + writetoexecdiff;
776 code, functionOffset++, vtableOffset,
778 reinterpret_cast<
779 typelib_InterfaceMethodTypeDescription * >(
780 member)->pReturnTypeRef));
781 break;
782
783 default:
784 assert(false);
785 break;
786 }
787 TYPELIB_DANGER_RELEASE(member);
788 }
789 return code;
790}
791
792/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
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")
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_uInt16 nPos
#define SAL_WARN(area, stream)
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)
void raiseException(uno_Any *pUnoExc, uno_Mapping *pUno2Cpp)
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
sal_Unicode code
#define sal_True
#define sal_False
ResultType type