bump product version to 6.3.0.0.beta1
[LibreOffice.git] / bridges / source / cpp_uno / gcc3_linux_mips64 / cpp2uno.cxx
blobebde9821eab2aca9e637c1521a7be2e557359359
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>
34 using namespace com::sun::star::uno;
36 //#define BRDEBUG
38 #ifdef BRDEBUG
39 #include <rtl/strbuf.hxx>
40 #include <rtl/ustrbuf.hxx>
41 using namespace ::std;
42 using namespace ::osl;
43 using namespace ::rtl;
44 #endif
46 #ifndef ANDROID
47 #include <sys/sysmips.h>
48 #endif
50 #ifdef ANDROID
51 #include <unistd.h>
52 #endif
54 namespace CPPU_CURRENT_NAMESPACE
56 bool is_complex_struct(const typelib_TypeDescription * type)
58 const typelib_CompoundTypeDescription * p
59 = reinterpret_cast< const typelib_CompoundTypeDescription * >(type);
60 for (sal_Int32 i = 0; i < p->nMembers; ++i)
62 if (p->ppTypeRefs[i]->eTypeClass == typelib_TypeClass_STRUCT ||
63 p->ppTypeRefs[i]->eTypeClass == typelib_TypeClass_EXCEPTION)
65 typelib_TypeDescription * t = 0;
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;
73 else if (!bridges::cpp_uno::shared::isSimpleType(p->ppTypeRefs[i]->eTypeClass))
74 return true;
76 if (p->pBaseTypeDescription != 0)
77 return is_complex_struct(&p->pBaseTypeDescription->aBase);
78 return false;
81 bool return_in_hidden_param( typelib_TypeDescriptionReference *pTypeRef )
83 if (bridges::cpp_uno::shared::isSimpleType(pTypeRef))
84 return false;
85 else if (pTypeRef->eTypeClass == typelib_TypeClass_STRUCT ||
86 pTypeRef->eTypeClass == typelib_TypeClass_EXCEPTION)
88 typelib_TypeDescription * pTypeDescr = 0;
89 TYPELIB_DANGER_GET( &pTypeDescr, pTypeRef );
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);
94 TYPELIB_DANGER_RELEASE( pTypeDescr );
95 return bRet;
97 return true;
101 namespace
104 static typelib_TypeClass cpp2uno_call(
105 bridges::cpp_uno::shared::CppInterfaceProxy * pThis,
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 */ )
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.
119 unsigned int nREG = 0;
121 #ifdef BRDEBUG
122 fprintf(stderr, "cpp2uno_call:begin\n");
123 #endif
125 // return
126 typelib_TypeDescription * pReturnTypeDescr = 0;
127 if (pReturnTypeRef)
128 TYPELIB_DANGER_GET( &pReturnTypeDescr, pReturnTypeRef );
130 void * pUnoReturn = 0;
131 void * pCppReturn = 0; // complex return ptr: if != 0 && != pUnoReturn, reconversion need
133 if (pReturnTypeDescr)
135 if (CPPU_CURRENT_NAMESPACE::return_in_hidden_param( pReturnTypeRef ) )
137 pCppReturn = gpreg[nREG]; // complex return via ptr (pCppReturn)
138 nREG++;
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
147 else
149 pUnoReturn = pRegisterReturn; // direct way for simple types
150 #ifdef BRDEBUG
151 fprintf(stderr, "cpp2uno_call:simplereturn\n");
152 #endif
156 // pop this
157 nREG++;
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));
169 sal_Int32 nTempIndices = 0;
171 #ifdef BRDEBUG
172 fprintf(stderr, "cpp2uno_call:nParams=%d\n", nParams);
173 #endif
174 for ( sal_Int32 nPos = 0; nPos < nParams; ++nPos )
176 const typelib_MethodParameter & rParam = pParams[nPos];
178 typelib_TypeDescription * pParamTypeDescr = 0;
179 TYPELIB_DANGER_GET( &pParamTypeDescr, rParam.pTypeRef );
181 if (!rParam.bOut && bridges::cpp_uno::shared::isSimpleType( pParamTypeDescr )) // value
183 #ifdef BRDEBUG
184 fprintf(stderr, "cpp2uno_call:Param %u, type %u\n", nPos, pParamTypeDescr->eTypeClass);
185 #endif
186 switch (pParamTypeDescr->eTypeClass)
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]);
203 nREG++;
204 break;
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]);
221 nREG++;
222 break;
225 // no longer needed
226 TYPELIB_DANGER_RELEASE( pParamTypeDescr );
228 else // ptr to complex value | ref
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];
239 nREG++;
240 #ifdef BRDEBUG
241 fprintf(stderr, "cpp2uno_call:pCppStack=%p\n", pCppStack);
242 #endif
244 if (! rParam.bIn) // is pure out
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;
252 // is in/inout
253 else if (bridges::cpp_uno::shared::relatesToInterfaceType( pParamTypeDescr ))
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
266 else // direct way
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 );
277 #ifdef BRDEBUG
278 fprintf(stderr, "cpp2uno_call2,%p,unoargs=%p\n", pThis->getUnoI()->pDispatcher, pUnoArgs);
279 #endif
281 // ExceptionHolder
282 uno_Any aUnoExc; // Any will be constructed by callee
283 uno_Any * pUnoExc = &aUnoExc;
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
291 // in case an exception occurred...
292 if (pUnoExc)
294 // destruct temporary in/inout params
295 for ( ; nTempIndices--; )
297 sal_Int32 nIndex = pTempIndices[nTempIndices];
299 if (pParams[nIndex].bIn) // is in/inout => was constructed
300 uno_destructData( pUnoArgs[nIndex], ppTempParamTypeDescr[nTempIndices], 0 );
301 TYPELIB_DANGER_RELEASE( ppTempParamTypeDescr[nTempIndices] );
303 if (pReturnTypeDescr)
304 TYPELIB_DANGER_RELEASE( pReturnTypeDescr );
306 CPPU_CURRENT_NAMESPACE::raiseException( &aUnoExc, pThis->getBridge()->getUno2Cpp() );
307 // has to destruct the any
308 // is here for dummy
309 return typelib_TypeClass_VOID;
311 else // else no exception occurred...
313 // temporary params
314 for ( ; nTempIndices--; )
316 sal_Int32 nIndex = pTempIndices[nTempIndices];
317 typelib_TypeDescription * pParamTypeDescr = ppTempParamTypeDescr[nTempIndices];
319 if (pParams[nIndex].bOut) // inout/out
321 // convert and assign
322 uno_destructData( pCppArgs[nIndex], pParamTypeDescr, cpp_release );
323 uno_copyAndConvertData( pCppArgs[nIndex], pUnoArgs[nIndex], pParamTypeDescr,
324 pThis->getBridge()->getUno2Cpp() );
326 // destroy temp uno param
327 uno_destructData( pUnoArgs[nIndex], pParamTypeDescr, 0 );
329 TYPELIB_DANGER_RELEASE( pParamTypeDescr );
331 // return
332 if (pCppReturn) // has complex return
334 if (pUnoReturn != pCppReturn) // needs reconversion
336 uno_copyAndConvertData( pCppReturn, pUnoReturn, pReturnTypeDescr,
337 pThis->getBridge()->getUno2Cpp() );
338 // destroy temp uno return
339 uno_destructData( pUnoReturn, pReturnTypeDescr, 0 );
341 // complex return ptr is set to return reg
342 *(void **)pRegisterReturn = pCppReturn;
344 if (pReturnTypeDescr)
346 typelib_TypeClass eRet = (typelib_TypeClass)pReturnTypeDescr->eTypeClass;
347 TYPELIB_DANGER_RELEASE( pReturnTypeDescr );
348 return eRet;
350 else
351 return typelib_TypeClass_VOID;
357 * is called on incoming vtable calls
358 * (called by asm snippets)
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 */ )
366 static_assert( sizeof(sal_Int64)==sizeof(void *), "### unexpected!" );
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
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 )
380 nFunctionIndex &= 0x7fffffff;
381 pThis = gpreg[1];
383 else
385 pThis = gpreg[0];
387 #ifdef BRDEBUG
388 fprintf(stderr, "cpp_vtable_call, pThis=%p, nFunctionIndex=%d, nVtableOffset=%d\n",
389 pThis, nFunctionIndex, nVtableOffset);
390 #endif
392 pThis = static_cast< char * >(pThis) - nVtableOffset;
393 bridges::cpp_uno::shared::CppInterfaceProxy * pCppI =
394 bridges::cpp_uno::shared::CppInterfaceProxy::castInterfaceToProxy( pThis );
395 #ifdef BRDEBUG
396 fprintf(stderr, "cpp_vtable_call, pCppI=%p\n", pCppI);
397 #endif
399 typelib_InterfaceTypeDescription * pTypeDescr = pCppI->getTypeDescr();
401 if (nFunctionIndex >= pTypeDescr->nMapFunctionIndexToMemberIndex)
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);
415 // determine called method
416 sal_Int32 nMemberPos = pTypeDescr->pMapFunctionIndexToMemberIndex[nFunctionIndex];
417 assert(nMemberPos < pTypeDescr->nAllMembers);
419 TypeDescription aMemberDescr( pTypeDescr->ppAllMembers[nMemberPos] );
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)
428 case typelib_TypeClass_INTERFACE_ATTRIBUTE:
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;
436 if (pTypeDescr->pMapMemberIndexToFunctionIndex[nMemberPos] == nFunctionIndex)
438 // is GET method
439 eRet = cpp2uno_call( pCppI, aMemberDescr.get(), pAttrTypeRef,
440 0, 0, // no params
441 gpreg, fpreg, ovrflw, pRegisterReturn );
443 else
445 // is SET method
446 typelib_MethodParameter aParam;
447 aParam.pTypeRef = pAttrTypeRef;
448 aParam.bIn = sal_True;
449 aParam.bOut = sal_False;
451 eRet = cpp2uno_call( pCppI, aMemberDescr.get(),
452 0, // indicates void return
453 1, &aParam,
454 gpreg, fpreg, ovrflw, pRegisterReturn );
456 break;
458 case typelib_TypeClass_INTERFACE_METHOD:
460 #ifdef BRDEBUG
461 fprintf(stderr, "cpp_vtable_call interface method\n");
462 #endif
463 // is METHOD
464 switch (nFunctionIndex)
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
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)
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 ) );
496 if (pInterface)
498 ::uno_any_construct( reinterpret_cast< uno_Any * >( gpreg[0] ),
499 &pInterface, pTD, cpp_acquire );
501 pInterface->release();
502 TYPELIB_DANGER_RELEASE( pTD );
504 reinterpret_cast<void **>( pRegisterReturn )[0] = gpreg[0];
505 eRet = typelib_TypeClass_ANY;
506 break;
508 TYPELIB_DANGER_RELEASE( pTD );
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() );
518 eRet = cpp2uno_call( pCppI, aMemberDescr.get(),
519 pMethodTD->pReturnTypeRef,
520 pMethodTD->nParams,
521 pMethodTD->pParams,
522 gpreg, fpreg, ovrflw, pRegisterReturn );
524 break;
526 default:
528 #ifdef BRDEBUG
529 fprintf(stderr, "cpp_vtable_call no member\n");
530 #endif
531 throw RuntimeException( "no member description found!", (XInterface *)pThis );
535 return eRet;
538 extern "C" void privateSnippetExecutor( ... );
540 int const codeSnippetSize = 0x44;
542 unsigned char * codeSnippet( unsigned char * code,
543 sal_Int32 functionIndex, sal_Int32 vtableOffset,
544 bool bHasHiddenParam )
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
552 if ( bHasHiddenParam )
553 functionIndex |= 0x80000000;
555 unsigned int * p = (unsigned int *) code;
557 assert((((unsigned long)code) & 0x3) == 0 ); //aligned to 4 otherwise a mistake
559 /* generate this code */
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
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);
608 void bridges::cpp_uno::shared::VtableFactory::flushCode(unsigned char const *bptr, unsigned char const *eptr)
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
619 struct bridges::cpp_uno::shared::VtableFactory::Slot { void * fn; };
621 bridges::cpp_uno::shared::VtableFactory::Slot *
622 bridges::cpp_uno::shared::VtableFactory::mapBlockToVtable(void * block)
624 return static_cast< Slot * >(block) + 2;
628 std::size_t bridges::cpp_uno::shared::VtableFactory::getBlockSize(
629 sal_Int32 slotCount)
631 return (slotCount + 2) * sizeof (Slot) + slotCount * codeSnippetSize;
634 bridges::cpp_uno::shared::VtableFactory::Slot *
635 bridges::cpp_uno::shared::VtableFactory::initializeBlock(
636 void * block, sal_Int32 slotCount, sal_Int32,
637 typelib_InterfaceTypeDescription *)
639 Slot * slots = mapBlockToVtable(block);
640 slots[-2].fn = 0; //null
641 slots[-1].fn = 0; //destructor
642 return slots + slotCount;
645 unsigned char * bridges::cpp_uno::shared::VtableFactory::addLocalFunctions(
646 Slot ** slots, unsigned char * code, sal_PtrDiff writetoexecdiff,
647 typelib_InterfaceTypeDescription const * type, sal_Int32 functionOffset,
648 sal_Int32 functionCount, sal_Int32 vtableOffset)
650 (*slots) -= functionCount;
651 Slot * s = *slots;
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
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;
668 code = codeSnippet(
669 code, functionOffset++, vtableOffset,
670 CPPU_CURRENT_NAMESPACE::return_in_hidden_param(
671 reinterpret_cast<
672 typelib_InterfaceAttributeTypeDescription * >(
673 member)->pAttributeTypeRef));
675 // Setter:
676 if (!reinterpret_cast<
677 typelib_InterfaceAttributeTypeDescription * >(
678 member)->bReadOnly)
680 (s++)->fn = code + writetoexecdiff;
681 code = codeSnippet(code, functionOffset++, vtableOffset, false);
683 break;
685 case typelib_TypeClass_INTERFACE_METHOD:
686 (s++)->fn = code + writetoexecdiff;
687 code = codeSnippet(
688 code, functionOffset++, vtableOffset,
689 CPPU_CURRENT_NAMESPACE::return_in_hidden_param(
690 reinterpret_cast<
691 typelib_InterfaceMethodTypeDescription * >(
692 member)->pReturnTypeRef));
693 break;
695 default:
696 assert(false);
697 break;
699 TYPELIB_DANGER_RELEASE(member);
701 return code;
704 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */