tdf#130857 qt weld: Support mail merge "Server Auth" dialog
[LibreOffice.git] / bridges / source / cpp_uno / gcc3_linux_mips64 / cpp2uno.cxx
blob7dbf0022e963eddcef3d02ff67d6b05ab0ff1d46
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
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"
31 #include <stdio.h>
32 #include <string.h>
33 #include <typeinfo>
35 using namespace com::sun::star::uno;
37 //#define BRDEBUG
39 #ifdef BRDEBUG
40 #include <rtl/strbuf.hxx>
41 #include <rtl/ustrbuf.hxx>
42 using namespace ::std;
43 using namespace ::osl;
44 using namespace ::rtl;
45 #endif
47 #ifndef ANDROID
48 #include <sys/sysmips.h>
49 #endif
51 #ifdef ANDROID
52 #include <unistd.h>
53 #endif
55 namespace CPPU_CURRENT_NAMESPACE
57 bool is_complex_struct(const typelib_TypeDescription * type)
59 const typelib_CompoundTypeDescription * p
60 = reinterpret_cast< const typelib_CompoundTypeDescription * >(type);
61 for (sal_Int32 i = 0; i < p->nMembers; ++i)
63 if (p->ppTypeRefs[i]->eTypeClass == typelib_TypeClass_STRUCT ||
64 p->ppTypeRefs[i]->eTypeClass == typelib_TypeClass_EXCEPTION)
66 typelib_TypeDescription * t = 0;
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;
74 else if (!bridges::cpp_uno::shared::isSimpleType(p->ppTypeRefs[i]->eTypeClass))
75 return true;
77 if (p->pBaseTypeDescription != 0)
78 return is_complex_struct(&p->pBaseTypeDescription->aBase);
79 return false;
82 bool return_in_hidden_param( typelib_TypeDescriptionReference *pTypeRef )
84 if (bridges::cpp_uno::shared::isSimpleType(pTypeRef))
85 return false;
86 else if (pTypeRef->eTypeClass == typelib_TypeClass_STRUCT ||
87 pTypeRef->eTypeClass == typelib_TypeClass_EXCEPTION)
89 typelib_TypeDescription * pTypeDescr = 0;
90 TYPELIB_DANGER_GET( &pTypeDescr, pTypeRef );
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);
95 TYPELIB_DANGER_RELEASE( pTypeDescr );
96 return bRet;
98 return true;
102 namespace
105 static typelib_TypeClass cpp2uno_call(
106 bridges::cpp_uno::shared::CppInterfaceProxy * pThis,
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 */ )
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.
120 unsigned int nREG = 0;
122 #ifdef BRDEBUG
123 fprintf(stderr, "cpp2uno_call:begin\n");
124 #endif
126 // return
127 typelib_TypeDescription * pReturnTypeDescr = 0;
128 if (pReturnTypeRef)
129 TYPELIB_DANGER_GET( &pReturnTypeDescr, pReturnTypeRef );
131 void * pUnoReturn = 0;
132 void * pCppReturn = 0; // complex return ptr: if != 0 && != pUnoReturn, reconversion need
134 if (pReturnTypeDescr)
136 if (CPPU_CURRENT_NAMESPACE::return_in_hidden_param( pReturnTypeRef ) )
138 pCppReturn = gpreg[nREG]; // complex return via ptr (pCppReturn)
139 nREG++;
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
148 else
150 pUnoReturn = pRegisterReturn; // direct way for simple types
151 #ifdef BRDEBUG
152 fprintf(stderr, "cpp2uno_call:simplereturn\n");
153 #endif
157 // pop this
158 nREG++;
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));
170 sal_Int32 nTempIndices = 0;
172 #ifdef BRDEBUG
173 fprintf(stderr, "cpp2uno_call:nParams=%d\n", nParams);
174 #endif
175 for ( sal_Int32 nPos = 0; nPos < nParams; ++nPos )
177 const typelib_MethodParameter & rParam = pParams[nPos];
179 typelib_TypeDescription * pParamTypeDescr = 0;
180 TYPELIB_DANGER_GET( &pParamTypeDescr, rParam.pTypeRef );
182 if (!rParam.bOut && bridges::cpp_uno::shared::isSimpleType( pParamTypeDescr )) // value
184 #ifdef BRDEBUG
185 fprintf(stderr, "cpp2uno_call:Param %u, type %u\n", nPos, pParamTypeDescr->eTypeClass);
186 #endif
187 switch (pParamTypeDescr->eTypeClass)
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]);
204 nREG++;
205 break;
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]);
222 nREG++;
223 break;
226 // no longer needed
227 TYPELIB_DANGER_RELEASE( pParamTypeDescr );
229 else // ptr to complex value | ref
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];
240 nREG++;
241 #ifdef BRDEBUG
242 fprintf(stderr, "cpp2uno_call:pCppStack=%p\n", pCppStack);
243 #endif
245 if (! rParam.bIn) // is pure out
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;
253 // is in/inout
254 else if (bridges::cpp_uno::shared::relatesToInterfaceType( pParamTypeDescr ))
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
267 else // direct way
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 );
278 #ifdef BRDEBUG
279 fprintf(stderr, "cpp2uno_call2,%p,unoargs=%p\n", pThis->getUnoI()->pDispatcher, pUnoArgs);
280 #endif
282 // ExceptionHolder
283 uno_Any aUnoExc; // Any will be constructed by callee
284 uno_Any * pUnoExc = &aUnoExc;
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
292 // in case an exception occurred...
293 if (pUnoExc)
295 // destruct temporary in/inout params
296 for ( ; nTempIndices--; )
298 sal_Int32 nIndex = pTempIndices[nTempIndices];
300 if (pParams[nIndex].bIn) // is in/inout => was constructed
301 uno_destructData( pUnoArgs[nIndex], ppTempParamTypeDescr[nTempIndices], 0 );
302 TYPELIB_DANGER_RELEASE( ppTempParamTypeDescr[nTempIndices] );
304 if (pReturnTypeDescr)
305 TYPELIB_DANGER_RELEASE( pReturnTypeDescr );
307 CPPU_CURRENT_NAMESPACE::raiseException( &aUnoExc, pThis->getBridge()->getUno2Cpp() );
308 // has to destruct the any
309 // is here for dummy
310 return typelib_TypeClass_VOID;
312 else // else no exception occurred...
314 // temporary params
315 for ( ; nTempIndices--; )
317 sal_Int32 nIndex = pTempIndices[nTempIndices];
318 typelib_TypeDescription * pParamTypeDescr = ppTempParamTypeDescr[nTempIndices];
320 if (pParams[nIndex].bOut) // inout/out
322 // convert and assign
323 uno_destructData( pCppArgs[nIndex], pParamTypeDescr, cpp_release );
324 uno_copyAndConvertData( pCppArgs[nIndex], pUnoArgs[nIndex], pParamTypeDescr,
325 pThis->getBridge()->getUno2Cpp() );
327 // destroy temp uno param
328 uno_destructData( pUnoArgs[nIndex], pParamTypeDescr, 0 );
330 TYPELIB_DANGER_RELEASE( pParamTypeDescr );
332 // return
333 if (pCppReturn) // has complex return
335 if (pUnoReturn != pCppReturn) // needs reconversion
337 uno_copyAndConvertData( pCppReturn, pUnoReturn, pReturnTypeDescr,
338 pThis->getBridge()->getUno2Cpp() );
339 // destroy temp uno return
340 uno_destructData( pUnoReturn, pReturnTypeDescr, 0 );
342 // complex return ptr is set to return reg
343 *(void **)pRegisterReturn = pCppReturn;
345 if (pReturnTypeDescr)
347 typelib_TypeClass eRet = (typelib_TypeClass)pReturnTypeDescr->eTypeClass;
348 TYPELIB_DANGER_RELEASE( pReturnTypeDescr );
349 return eRet;
351 else
352 return typelib_TypeClass_VOID;
358 * is called on incoming vtable calls
359 * (called by asm snippets)
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 */ )
367 static_assert( sizeof(sal_Int64)==sizeof(void *), "### unexpected!" );
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
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 )
381 nFunctionIndex &= 0x7fffffff;
382 pThis = gpreg[1];
384 else
386 pThis = gpreg[0];
388 #ifdef BRDEBUG
389 fprintf(stderr, "cpp_vtable_call, pThis=%p, nFunctionIndex=%d, nVtableOffset=%d\n",
390 pThis, nFunctionIndex, nVtableOffset);
391 #endif
393 pThis = static_cast< char * >(pThis) - nVtableOffset;
394 bridges::cpp_uno::shared::CppInterfaceProxy * pCppI =
395 bridges::cpp_uno::shared::CppInterfaceProxy::castInterfaceToProxy( pThis );
396 #ifdef BRDEBUG
397 fprintf(stderr, "cpp_vtable_call, pCppI=%p\n", pCppI);
398 #endif
400 typelib_InterfaceTypeDescription * pTypeDescr = pCppI->getTypeDescr();
402 if (nFunctionIndex >= pTypeDescr->nMapFunctionIndexToMemberIndex)
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);
416 // determine called method
417 sal_Int32 nMemberPos = pTypeDescr->pMapFunctionIndexToMemberIndex[nFunctionIndex];
418 assert(nMemberPos < pTypeDescr->nAllMembers);
420 TypeDescription aMemberDescr( pTypeDescr->ppAllMembers[nMemberPos] );
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)
429 case typelib_TypeClass_INTERFACE_ATTRIBUTE:
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;
437 if (pTypeDescr->pMapMemberIndexToFunctionIndex[nMemberPos] == nFunctionIndex)
439 // is GET method
440 eRet = cpp2uno_call( pCppI, aMemberDescr.get(), pAttrTypeRef,
441 0, 0, // no params
442 gpreg, fpreg, ovrflw, pRegisterReturn );
444 else
446 // is SET method
447 typelib_MethodParameter aParam;
448 aParam.pTypeRef = pAttrTypeRef;
449 aParam.bIn = sal_True;
450 aParam.bOut = sal_False;
452 eRet = cpp2uno_call( pCppI, aMemberDescr.get(),
453 0, // indicates void return
454 1, &aParam,
455 gpreg, fpreg, ovrflw, pRegisterReturn );
457 break;
459 case typelib_TypeClass_INTERFACE_METHOD:
461 #ifdef BRDEBUG
462 fprintf(stderr, "cpp_vtable_call interface method\n");
463 #endif
464 // is METHOD
465 switch (nFunctionIndex)
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
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)
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 ) );
497 if (pInterface)
499 ::uno_any_construct( reinterpret_cast< uno_Any * >( gpreg[0] ),
500 &pInterface, pTD, cpp_acquire );
502 pInterface->release();
503 TYPELIB_DANGER_RELEASE( pTD );
505 reinterpret_cast<void **>( pRegisterReturn )[0] = gpreg[0];
506 eRet = typelib_TypeClass_ANY;
507 break;
509 TYPELIB_DANGER_RELEASE( pTD );
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() );
519 eRet = cpp2uno_call( pCppI, aMemberDescr.get(),
520 pMethodTD->pReturnTypeRef,
521 pMethodTD->nParams,
522 pMethodTD->pParams,
523 gpreg, fpreg, ovrflw, pRegisterReturn );
525 break;
527 default:
529 #ifdef BRDEBUG
530 fprintf(stderr, "cpp_vtable_call no member\n");
531 #endif
532 throw RuntimeException( "no member description found!", (XInterface *)pThis );
536 return eRet;
539 extern "C" void privateSnippetExecutor( ... );
541 int const codeSnippetSize = 0x44;
543 unsigned char * codeSnippet( unsigned char * code,
544 sal_Int32 functionIndex, sal_Int32 vtableOffset,
545 bool bHasHiddenParam )
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
553 if ( bHasHiddenParam )
554 functionIndex |= 0x80000000;
556 unsigned int * p = (unsigned int *) code;
558 assert((((unsigned long)code) & 0x3) == 0 ); //aligned to 4 otherwise a mistake
560 /* generate this code */
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
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);
609 void bridges::cpp_uno::shared::VtableFactory::flushCode(unsigned char const *bptr, unsigned char const *eptr)
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
620 struct bridges::cpp_uno::shared::VtableFactory::Slot { void const * fn; };
622 bridges::cpp_uno::shared::VtableFactory::Slot *
623 bridges::cpp_uno::shared::VtableFactory::mapBlockToVtable(void * block)
625 return static_cast< Slot * >(block) + 2;
629 std::size_t bridges::cpp_uno::shared::VtableFactory::getBlockSize(
630 sal_Int32 slotCount)
632 return (slotCount + 2) * sizeof (Slot) + slotCount * codeSnippetSize;
635 namespace {
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:
638 struct ProxyRtti {};
641 bridges::cpp_uno::shared::VtableFactory::Slot *
642 bridges::cpp_uno::shared::VtableFactory::initializeBlock(
643 void * block, sal_Int32 slotCount, sal_Int32,
644 typelib_InterfaceTypeDescription *)
646 Slot * slots = mapBlockToVtable(block);
647 slots[-2].fn = 0; //null
648 slots[-1].fn = &typeid(ProxyRtti);
649 return slots + slotCount;
652 unsigned char * bridges::cpp_uno::shared::VtableFactory::addLocalFunctions(
653 Slot ** slots, unsigned char * code, sal_PtrDiff writetoexecdiff,
654 typelib_InterfaceTypeDescription const * type, sal_Int32 functionOffset,
655 sal_Int32 functionCount, sal_Int32 vtableOffset)
657 (*slots) -= functionCount;
658 Slot * s = *slots;
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
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;
675 code = codeSnippet(
676 code, functionOffset++, vtableOffset,
677 CPPU_CURRENT_NAMESPACE::return_in_hidden_param(
678 reinterpret_cast<
679 typelib_InterfaceAttributeTypeDescription * >(
680 member)->pAttributeTypeRef));
682 // Setter:
683 if (!reinterpret_cast<
684 typelib_InterfaceAttributeTypeDescription * >(
685 member)->bReadOnly)
687 (s++)->fn = code + writetoexecdiff;
688 code = codeSnippet(code, functionOffset++, vtableOffset, false);
690 break;
692 case typelib_TypeClass_INTERFACE_METHOD:
693 (s++)->fn = code + writetoexecdiff;
694 code = codeSnippet(
695 code, functionOffset++, vtableOffset,
696 CPPU_CURRENT_NAMESPACE::return_in_hidden_param(
697 reinterpret_cast<
698 typelib_InterfaceMethodTypeDescription * >(
699 member)->pReturnTypeRef));
700 break;
702 default:
703 assert(false);
704 break;
706 TYPELIB_DANGER_RELEASE(member);
708 return code;
711 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */