LibreOffice Module bridges (master) 1
gcc3_linux_mips64/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#include <com/sun/star/uno/genfunc.hxx>
20#include <sal/log.hxx>
21#include <typelib/typedescription.hxx>
22#include <uno/data.h>
23#include <osl/endian.h>
24#include "bridge.hxx"
25#include "cppinterfaceproxy.hxx"
26#include "types.hxx"
27#include "vtablefactory.hxx"
28#include "call.hxx"
29#include "share.hxx"
30
31#include <stdio.h>
32#include <string.h>
33
34using namespace com::sun::star::uno;
35
36//#define BRDEBUG
37
38#ifdef BRDEBUG
39#include <rtl/strbuf.hxx>
40#include <rtl/ustrbuf.hxx>
41using namespace ::std;
42using namespace ::osl;
43using namespace ::rtl;
44#endif
45
46#ifndef ANDROID
47#include <sys/sysmips.h>
48#endif
49
50#ifdef ANDROID
51#include <unistd.h>
52#endif
53
55{
57 {
58 const typelib_CompoundTypeDescription * p
59 = reinterpret_cast< const typelib_CompoundTypeDescription * >(type);
60 for (sal_Int32 i = 0; i < p->nMembers; ++i)
61 {
62 if (p->ppTypeRefs[i]->eTypeClass == typelib_TypeClass_STRUCT ||
63 p->ppTypeRefs[i]->eTypeClass == typelib_TypeClass_EXCEPTION)
64 {
66 TYPELIB_DANGER_GET(&t, p->ppTypeRefs[i]);
67 bool b = is_complex_struct(t);
68 TYPELIB_DANGER_RELEASE(t);
69 if (b) {
70 return true;
71 }
72 }
73 else if (!bridges::cpp_uno::shared::isSimpleType(p->ppTypeRefs[i]->eTypeClass))
74 return true;
75 }
76 if (p->pBaseTypeDescription != 0)
77 return is_complex_struct(&p->pBaseTypeDescription->aBase);
78 return false;
79 }
80
81 bool return_in_hidden_param( typelib_TypeDescriptionReference *pTypeRef )
82 {
84 return false;
85 else if (pTypeRef->eTypeClass == typelib_TypeClass_STRUCT ||
86 pTypeRef->eTypeClass == typelib_TypeClass_EXCEPTION)
87 {
88 typelib_TypeDescription * pTypeDescr = 0;
89 TYPELIB_DANGER_GET( &pTypeDescr, pTypeRef );
90
91 //A Composite Type not larger than 16 bytes is returned in up to two GPRs
92 bool bRet = pTypeDescr->nSize > 16 || is_complex_struct(pTypeDescr);
93
94 TYPELIB_DANGER_RELEASE( pTypeDescr );
95 return bRet;
96 }
97 return true;
98 }
99}
100
101namespace
102{
103
104 static typelib_TypeClass cpp2uno_call(
106 const typelib_TypeDescription * pMemberTypeDescr,
107 typelib_TypeDescriptionReference * pReturnTypeRef, // 0 indicates void return
108 sal_Int32 nParams, typelib_MethodParameter * pParams,
109 void ** gpreg, void ** fpreg, void ** ovrflw,
110 sal_uInt64 * pRegisterReturn /* space for register return */ )
111 {
112 /* Most MIPS ABIs view the arguments as a struct, of which the
113 first N words go in registers and the rest go on the stack. If I < N, the
114 With word might go in With integer argument register or the With
115 floating-point one. For these ABIs, we only need to remember the number
116 of words passed so far. We are interested only in n64 ABI,so it is the
117 case.
118 */
119 unsigned int nREG = 0;
120
121#ifdef BRDEBUG
122 fprintf(stderr, "cpp2uno_call:begin\n");
123#endif
124
125 // return
126 typelib_TypeDescription * pReturnTypeDescr = 0;
127 if (pReturnTypeRef)
128 TYPELIB_DANGER_GET( &pReturnTypeDescr, pReturnTypeRef );
129
130 void * pUnoReturn = 0;
131 void * pCppReturn = 0; // complex return ptr: if != 0 && != pUnoReturn, reconversion need
132
133 if (pReturnTypeDescr)
134 {
136 {
137 pCppReturn = gpreg[nREG]; // complex return via ptr (pCppReturn)
138 nREG++;
139
140 pUnoReturn = ( bridges::cpp_uno::shared::relatesToInterfaceType( pReturnTypeDescr )
141 ? alloca( pReturnTypeDescr->nSize )
142 : pCppReturn); // direct way
143#ifdef BRDEBUG
144 fprintf(stderr, "cpp2uno_call:complexreturn\n");
145#endif
146 }
147 else
148 {
149 pUnoReturn = pRegisterReturn; // direct way for simple types
150#ifdef BRDEBUG
151 fprintf(stderr, "cpp2uno_call:simplereturn\n");
152#endif
153 }
154 }
155
156 // pop this
157 nREG++;
158
159 // stack space
160 static_assert(sizeof(void *) == sizeof(sal_Int64), "### unexpected size!");
161 // parameters
162 void ** pUnoArgs = (void **)alloca( 4 * sizeof(void *) * nParams );
163 void ** pCppArgs = pUnoArgs + nParams;
164 // indices of values this have to be converted (interface conversion cpp<=>uno)
165 sal_Int32 * pTempIndices = (sal_Int32 *)(pUnoArgs + (2 * nParams));
166 // type descriptions for reconversions
167 typelib_TypeDescription ** ppTempParamTypeDescr = (typelib_TypeDescription **)(pUnoArgs + (3 * nParams));
168
169 sal_Int32 nTempIndices = 0;
170
171#ifdef BRDEBUG
172 fprintf(stderr, "cpp2uno_call:nParams=%d\n", nParams);
173#endif
174 for ( sal_Int32 nPos = 0; nPos < nParams; ++nPos )
175 {
176 const typelib_MethodParameter & rParam = pParams[nPos];
177
178 typelib_TypeDescription * pParamTypeDescr = 0;
179 TYPELIB_DANGER_GET( &pParamTypeDescr, rParam.pTypeRef );
180
181 if (!rParam.bOut && bridges::cpp_uno::shared::isSimpleType( pParamTypeDescr )) // value
182 {
183#ifdef BRDEBUG
184 fprintf(stderr, "cpp2uno_call:Param %u, type %u\n", nPos, pParamTypeDescr->eTypeClass);
185#endif
186 switch (pParamTypeDescr->eTypeClass)
187 {
188 case typelib_TypeClass_FLOAT:
189 case typelib_TypeClass_DOUBLE:
190 if (nREG < MAX_FP_REGS) {
191#ifdef BRDEBUG
192 fprintf(stderr, "cpp2uno_call:fpr=%p\n", fpreg[nREG]);
193#endif
194 pCppArgs[nPos] = &(fpreg[nREG]);
195 pUnoArgs[nPos] = &(fpreg[nREG]);
196 } else {
197#ifdef BRDEBUG
198 fprintf(stderr, "cpp2uno_call:fpr=%p\n", ovrflw[nREG - MAX_FP_REGS]);
199#endif
200 pCppArgs[nPos] = &(ovrflw[nREG - MAX_FP_REGS]);
201 pUnoArgs[nPos] = &(ovrflw[nREG - MAX_FP_REGS]);
202 }
203 nREG++;
204 break;
205
206
207 default:
208 if (nREG < MAX_GP_REGS) {
209#ifdef BRDEBUG
210 fprintf(stderr, "cpp2uno_call:gpr=%p\n", gpreg[nREG]);
211#endif
212 pCppArgs[nPos] = &(gpreg[nREG]);
213 pUnoArgs[nPos] = &(gpreg[nREG]);
214 } else {
215#ifdef BRDEBUG
216 fprintf(stderr, "cpp2uno_call:gpr=%p\n", ovrflw[nREG - MAX_GP_REGS]);
217#endif
218 pCppArgs[nPos] = &(ovrflw[nREG - MAX_GP_REGS]);
219 pUnoArgs[nPos] = &(ovrflw[nREG - MAX_GP_REGS]);
220 }
221 nREG++;
222 break;
223
224 }
225 // no longer needed
226 TYPELIB_DANGER_RELEASE( pParamTypeDescr );
227 }
228 else // ptr to complex value | ref
229 {
230#ifdef BRDEBUG
231 fprintf(stderr,"cpp2uno_call:ptr|ref\n");
232#endif
233 void *pCppStack;
234 if (nREG < MAX_GP_REGS) {
235 pCppArgs[nPos] = pCppStack = gpreg[nREG];
236 } else {
237 pCppArgs[nPos] = pCppStack = ovrflw[nREG - MAX_GP_REGS];
238 }
239 nREG++;
240#ifdef BRDEBUG
241 fprintf(stderr, "cpp2uno_call:pCppStack=%p\n", pCppStack);
242#endif
243
244 if (! rParam.bIn) // is pure out
245 {
246 // uno out is unconstructed mem!
247 pUnoArgs[nPos] = alloca( pParamTypeDescr->nSize );
248 pTempIndices[nTempIndices] = nPos;
249 // will be released at reconversion
250 ppTempParamTypeDescr[nTempIndices++] = pParamTypeDescr;
251 }
252 // is in/inout
253 else if (bridges::cpp_uno::shared::relatesToInterfaceType( pParamTypeDescr ))
254 {
255 uno_copyAndConvertData( pUnoArgs[nPos] = alloca( pParamTypeDescr->nSize ),
256 pCppStack, pParamTypeDescr,
257 pThis->getBridge()->getCpp2Uno() );
258 pTempIndices[nTempIndices] = nPos; // has to be reconverted
259 // will be released at reconversion
260 ppTempParamTypeDescr[nTempIndices++] = pParamTypeDescr;
261#ifdef BRDEBUG
262 fprintf(stderr, "cpp2uno_call:related to interface,%p,%d,pUnoargs[%d]=%p\n",
263 pCppStack, pParamTypeDescr->nSize, nPos, pUnoArgs[nPos]);
264#endif
265 }
266 else // direct way
267 {
268 pUnoArgs[nPos] = pCppStack;
269#ifdef BRDEBUG
270 fprintf(stderr, "cpp2uno_call:direct,pUnoArgs[%d]=%p\n", nPos, pUnoArgs[nPos]);
271#endif
272 // no longer needed
273 TYPELIB_DANGER_RELEASE( pParamTypeDescr );
274 }
275 }
276 }
277#ifdef BRDEBUG
278 fprintf(stderr, "cpp2uno_call2,%p,unoargs=%p\n", pThis->getUnoI()->pDispatcher, pUnoArgs);
279#endif
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#ifdef BRDEBUG
288 fprintf(stderr, "cpp2uno_call2,after dispatch\n");
289#endif
290
291 // in case an exception occurred...
292 if (pUnoExc)
293 {
294 // destruct temporary in/inout params
295 for ( ; nTempIndices--; )
296 {
297 sal_Int32 nIndex = pTempIndices[nTempIndices];
298
299 if (pParams[nIndex].bIn) // is in/inout => was constructed
300 uno_destructData( pUnoArgs[nIndex], ppTempParamTypeDescr[nTempIndices], 0 );
301 TYPELIB_DANGER_RELEASE( ppTempParamTypeDescr[nTempIndices] );
302 }
303 if (pReturnTypeDescr)
304 TYPELIB_DANGER_RELEASE( pReturnTypeDescr );
305
307 // has to destruct the any
308 // is here for dummy
309 return typelib_TypeClass_VOID;
310 }
311 else // else no exception occurred...
312 {
313 // temporary params
314 for ( ; nTempIndices--; )
315 {
316 sal_Int32 nIndex = pTempIndices[nTempIndices];
317 typelib_TypeDescription * pParamTypeDescr = ppTempParamTypeDescr[nTempIndices];
318
319 if (pParams[nIndex].bOut) // inout/out
320 {
321 // convert and assign
322 uno_destructData( pCppArgs[nIndex], pParamTypeDescr, cpp_release );
323 uno_copyAndConvertData( pCppArgs[nIndex], pUnoArgs[nIndex], pParamTypeDescr,
324 pThis->getBridge()->getUno2Cpp() );
325 }
326 // destroy temp uno param
327 uno_destructData( pUnoArgs[nIndex], pParamTypeDescr, 0 );
328
329 TYPELIB_DANGER_RELEASE( pParamTypeDescr );
330 }
331 // return
332 if (pCppReturn) // has complex return
333 {
334 if (pUnoReturn != pCppReturn) // needs reconversion
335 {
336 uno_copyAndConvertData( pCppReturn, pUnoReturn, pReturnTypeDescr,
337 pThis->getBridge()->getUno2Cpp() );
338 // destroy temp uno return
339 uno_destructData( pUnoReturn, pReturnTypeDescr, 0 );
340 }
341 // complex return ptr is set to return reg
342 *(void **)pRegisterReturn = pCppReturn;
343 }
344 if (pReturnTypeDescr)
345 {
346 typelib_TypeClass eRet = (typelib_TypeClass)pReturnTypeDescr->eTypeClass;
347 TYPELIB_DANGER_RELEASE( pReturnTypeDescr );
348 return eRet;
349 }
350 else
351 return typelib_TypeClass_VOID;
352 }
353 }
354
355
360 typelib_TypeClass cpp_vtable_call(
361 sal_Int32 nFunctionIndex,
362 sal_Int32 nVtableOffset,
363 void ** gpreg, void ** fpreg, void ** ovrflw,
364 sal_uInt64 * pRegisterReturn /* space for register return */ )
365 {
366 static_assert( sizeof(sal_Int64)==sizeof(void *), "### unexpected!" );
367
368#ifdef BRDEBUG
369 fprintf(stderr, "in cpp_vtable_call nFunctionIndex is %d\n", nFunctionIndex);
370 fprintf(stderr, "in cpp_vtable_call nVtableOffset is %d\n", nVtableOffset);
371 fprintf(stderr, "in cpp_vtable_call gp=%p, fp=%p, ov=%p\n", gpreg, fpreg, ovrflw);
372#endif
373
374 // gpreg: [ret *], this, [other gpr params]
375 // fpreg: [fpr params]
376 // ovrflw: [gpr or fpr params (properly aligned)]
377 void * pThis;
378 if (nFunctionIndex & 0x80000000 )
379 {
380 nFunctionIndex &= 0x7fffffff;
381 pThis = gpreg[1];
382 }
383 else
384 {
385 pThis = gpreg[0];
386 }
387#ifdef BRDEBUG
388 fprintf(stderr, "cpp_vtable_call, pThis=%p, nFunctionIndex=%d, nVtableOffset=%d\n",
389 pThis, nFunctionIndex, nVtableOffset);
390#endif
391
392 pThis = static_cast< char * >(pThis) - nVtableOffset;
395#ifdef BRDEBUG
396 fprintf(stderr, "cpp_vtable_call, pCppI=%p\n", pCppI);
397#endif
398
399 typelib_InterfaceTypeDescription * pTypeDescr = pCppI->getTypeDescr();
400
401 if (nFunctionIndex >= pTypeDescr->nMapFunctionIndexToMemberIndex)
402 {
403 SAL_WARN(
404 "bridges",
405 "illegal " << OUString::unacquired(&pTypeDescr->aBase.pTypeName)
406 << " vtable index " << nFunctionIndex << "/"
407 << pTypeDescr->nMapFunctionIndexToMemberIndex);
408 throw RuntimeException(
409 ("illegal " + OUString::unacquired(&pTypeDescr->aBase.pTypeName)
410 + " vtable index " + OUString::number(nFunctionIndex) + "/"
411 + OUString::number(pTypeDescr->nMapFunctionIndexToMemberIndex)),
412 (XInterface *)pThis);
413 }
414
415 // determine called method
416 sal_Int32 nMemberPos = pTypeDescr->pMapFunctionIndexToMemberIndex[nFunctionIndex];
417 assert(nMemberPos < pTypeDescr->nAllMembers);
418
419 TypeDescription aMemberDescr( pTypeDescr->ppAllMembers[nMemberPos] );
420
421#ifdef BRDEBUG
422 OString cstr( OUStringToOString( aMemberDescr.get()->pTypeName, RTL_TEXTENCODING_ASCII_US ) );
423 fprintf(stderr, "calling %s, nFunctionIndex=%d\n", cstr.getStr(), nFunctionIndex );
424#endif
425 typelib_TypeClass eRet;
426 switch (aMemberDescr.get()->eTypeClass)
427 {
428 case typelib_TypeClass_INTERFACE_ATTRIBUTE:
429 {
430#ifdef BRDEBUG
431 fprintf(stderr, "cpp_vtable_call interface attribute\n");
432#endif
433 typelib_TypeDescriptionReference *pAttrTypeRef =
434 reinterpret_cast<typelib_InterfaceAttributeTypeDescription *>( aMemberDescr.get() )->pAttributeTypeRef;
435
436 if (pTypeDescr->pMapMemberIndexToFunctionIndex[nMemberPos] == nFunctionIndex)
437 {
438 // is GET method
439 eRet = cpp2uno_call( pCppI, aMemberDescr.get(), pAttrTypeRef,
440 0, 0, // no params
441 gpreg, fpreg, ovrflw, pRegisterReturn );
442 }
443 else
444 {
445 // is SET method
446 typelib_MethodParameter aParam;
447 aParam.pTypeRef = pAttrTypeRef;
448 aParam.bIn = sal_True;
449 aParam.bOut = sal_False;
450
451 eRet = cpp2uno_call( pCppI, aMemberDescr.get(),
452 0, // indicates void return
453 1, &aParam,
454 gpreg, fpreg, ovrflw, pRegisterReturn );
455 }
456 break;
457 }
458 case typelib_TypeClass_INTERFACE_METHOD:
459 {
460#ifdef BRDEBUG
461 fprintf(stderr, "cpp_vtable_call interface method\n");
462#endif
463 // is METHOD
464 switch (nFunctionIndex)
465 {
466 case 1: // acquire()
467#ifdef BRDEBUG
468 fprintf(stderr, "cpp_vtable_call method acquire\n");
469#endif
470 pCppI->acquireProxy(); // non virtual call!
471 eRet = typelib_TypeClass_VOID;
472 break;
473 case 2: // release()
474#ifdef BRDEBUG
475 fprintf(stderr, "cpp_vtable_call method release\n");
476#endif
477 pCppI->releaseProxy(); // non virtual call!
478 eRet = typelib_TypeClass_VOID;
479 break;
480 case 0: // queryInterface() opt
481 {
482#ifdef BRDEBUG
483 fprintf(stderr, "cpp_vtable_call method query interface opt\n");
484#endif
485 typelib_TypeDescription * pTD = 0;
486 TYPELIB_DANGER_GET( &pTD, reinterpret_cast< Type * >( gpreg[2] )->getTypeLibType() );
487 if (pTD)
488 {
489 XInterface * pInterface = 0;
490 (*pCppI->getBridge()->getCppEnv()->getRegisteredInterface)
491 ( pCppI->getBridge()->getCppEnv(),
492 (void **)&pInterface,
493 pCppI->getOid().pData,
494 reinterpret_cast<typelib_InterfaceTypeDescription *>( pTD ) );
495
496 if (pInterface)
497 {
498 ::uno_any_construct( reinterpret_cast< uno_Any * >( gpreg[0] ),
499 &pInterface, pTD, cpp_acquire );
500
501 pInterface->release();
502 TYPELIB_DANGER_RELEASE( pTD );
503
504 reinterpret_cast<void **>( pRegisterReturn )[0] = gpreg[0];
505 eRet = typelib_TypeClass_ANY;
506 break;
507 }
508 TYPELIB_DANGER_RELEASE( pTD );
509 }
510 } // else perform queryInterface()
511 default:
512#ifdef BRDEBUG
513 fprintf(stderr, "cpp_vtable_call method query interface\n");
514#endif
515 typelib_InterfaceMethodTypeDescription *pMethodTD =
516 reinterpret_cast<typelib_InterfaceMethodTypeDescription *>( aMemberDescr.get() );
517
518 eRet = cpp2uno_call( pCppI, aMemberDescr.get(),
519 pMethodTD->pReturnTypeRef,
520 pMethodTD->nParams,
521 pMethodTD->pParams,
522 gpreg, fpreg, ovrflw, pRegisterReturn );
523 }
524 break;
525 }
526 default:
527 {
528#ifdef BRDEBUG
529 fprintf(stderr, "cpp_vtable_call no member\n");
530#endif
531 throw RuntimeException( "no member description found!", (XInterface *)pThis );
532 }
533 }
534
535 return eRet;
536 }
537
538 extern "C" void privateSnippetExecutor( ... );
539
540 int const codeSnippetSize = 0x44;
541
542 unsigned char * codeSnippet( unsigned char * code,
543 sal_Int32 functionIndex, sal_Int32 vtableOffset,
544 bool bHasHiddenParam )
545 {
546#ifdef BRDEBUG
547 fprintf(stderr,"in codeSnippet functionIndex is %d\n", functionIndex);
548 fprintf(stderr,"in codeSnippet vtableOffset is %d\n", vtableOffset);
549 fflush(stderr);
550#endif
551
552 if ( bHasHiddenParam )
553 functionIndex |= 0x80000000;
554
555 unsigned int * p = (unsigned int *) code;
556
557 assert((((unsigned long)code) & 0x3) == 0 ); //aligned to 4 otherwise a mistake
558
559 /* generate this code */
560 /*
561 # index
562 0: 3c020000 lui v0,0x0
563 4: 34420000 ori v0,v0,0x0
564 # privateSnippetExecutor
565 8: 3c0c0000 lui t0,0x0
566 c: 358c0000 ori t0,t0,0x0
567 10: 000c6438 dsll t0,t0,0x10
568 14: 358c0000 ori t0,t0,0x0
569 18: 000c6438 dsll t0,t0,0x10
570 1c: 358c0000 ori t0,t0,0x0
571 # cpp_vtable_call
572 20: 3c190000 lui t9,0x0
573 24: 37390000 ori t9,t9,0x0
574 28: 0019cc38 dsll t9,t9,0x10
575 2c: 37390000 ori t9,t9,0x0
576 30: 0019cc38 dsll t9,t9,0x10
577 34: 37390000 ori t9,t9,0x0
578 # offset
579 38: 3c030000 lui v1,0x0
580 3c: 01800008 jr t0
581 40: 34630000 ori v1,v1,0x0
582 */
583
584 * p++ = 0x3c020000 | ((functionIndex>>16) & 0x0000ffff);
585 * p++ = 0x34420000 | (functionIndex & 0x0000ffff);
586 * p++ = 0x3c0c0000 | ((((unsigned long)privateSnippetExecutor) >> 48) & 0x0000ffff);
587 * p++ = 0x358c0000 | ((((unsigned long)privateSnippetExecutor) >> 32) & 0x0000ffff);
588 * p++ = 0x000c6438;
589 * p++ = 0x358c0000 | ((((unsigned long)privateSnippetExecutor) >> 16) & 0x0000ffff);
590 * p++ = 0x000c6438;
591 * p++ = 0x358c0000 | (((unsigned long)privateSnippetExecutor) & 0x0000ffff);
592 * p++ = 0x3c190000 | ((((unsigned long)cpp_vtable_call) >> 48) & 0x0000ffff);
593 * p++ = 0x37390000 | ((((unsigned long)cpp_vtable_call) >> 32) & 0x0000ffff);
594 * p++ = 0x0019cc38;
595 * p++ = 0x37390000 | ((((unsigned long)cpp_vtable_call) >> 16) & 0x0000ffff);
596 * p++ = 0x0019cc38;
597 * p++ = 0x37390000 | (((unsigned long)cpp_vtable_call) & 0x0000ffff);
598 * p++ = 0x3c030000 | ((vtableOffset>>16) & 0x0000ffff);
599 * p++ = 0x01800008;
600 * p++ = 0x34630000 | (vtableOffset & 0x0000ffff);
601 return (code + codeSnippetSize);
602
603 }
604
605}
606
607
608void bridges::cpp_uno::shared::VtableFactory::flushCode(unsigned char const *bptr, unsigned char const *eptr)
609{
610#ifndef ANDROID
611 (void) bptr;
612 (void) eptr;
613 sysmips(FLUSH_CACHE, 0, 0, 0);
614#else
615 cacheflush((long) bptr, (long) eptr, 0);
616#endif
617}
618
620
623{
624 return static_cast< Slot * >(block) + 2;
625}
626
627
629 sal_Int32 slotCount)
630{
631 return (slotCount + 2) * sizeof (Slot) + slotCount * codeSnippetSize;
632}
633
636 void * block, sal_Int32 slotCount, sal_Int32,
637 typelib_InterfaceTypeDescription *)
638{
639 Slot * slots = mapBlockToVtable(block);
640 slots[-2].fn = 0; //null
641 slots[-1].fn = 0; //destructor
642 return slots + slotCount;
643}
644
646 Slot ** slots, unsigned char * code, sal_PtrDiff writetoexecdiff,
647 typelib_InterfaceTypeDescription const * type, sal_Int32 functionOffset,
648 sal_Int32 functionCount, sal_Int32 vtableOffset)
649{
650 (*slots) -= functionCount;
651 Slot * s = *slots;
652
653#ifdef BRDEBUG
654 fprintf(stderr, "in addLocalFunctions functionOffset is %d\n", functionOffset);
655 fprintf(stderr, "in addLocalFunctions vtableOffset is %d\n", vtableOffset);
656 fprintf(stderr, "nMembers=%d\n", type->nMembers);
657 fflush(stderr);
658#endif
659
660 for (sal_Int32 i = 0; i < type->nMembers; ++i) {
661 typelib_TypeDescription * member = 0;
662 TYPELIB_DANGER_GET(&member, type->ppMembers[i]);
663 assert(member != 0);
664 switch (member->eTypeClass) {
665 case typelib_TypeClass_INTERFACE_ATTRIBUTE:
666 // Getter:
667 (s++)->fn = code + writetoexecdiff;
669 code, functionOffset++, vtableOffset,
671 reinterpret_cast<
672 typelib_InterfaceAttributeTypeDescription * >(
673 member)->pAttributeTypeRef));
674
675 // Setter:
676 if (!reinterpret_cast<
677 typelib_InterfaceAttributeTypeDescription * >(
678 member)->bReadOnly)
679 {
680 (s++)->fn = code + writetoexecdiff;
681 code = codeSnippet(code, functionOffset++, vtableOffset, false);
682 }
683 break;
684
685 case typelib_TypeClass_INTERFACE_METHOD:
686 (s++)->fn = code + writetoexecdiff;
688 code, functionOffset++, vtableOffset,
690 reinterpret_cast<
691 typelib_InterfaceMethodTypeDescription * >(
692 member)->pReturnTypeRef));
693 break;
694
695 default:
696 assert(false);
697 break;
698 }
699 TYPELIB_DANGER_RELEASE(member);
700 }
701 return code;
702}
703
704/* 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)
void(* privateSnippetExecutor)()
#define MAX_FP_REGS
#define MAX_GP_REGS
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
bool return_in_hidden_param(typelib_TypeDescriptionReference *pTypeRef)
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
OString OUStringToOString(std::u16string_view str, ConnectionSettings const *settings)
sal_Unicode code
#define sal_True
#define sal_False
ResultType type