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