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