Bump for 3.6-28
[LibreOffice.git] / bridges / source / cpp_uno / gcc3_macosx_powerpc / cpp2uno.cxx
blob67f236e86707ecd8f37695839d587dc47e015335
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*************************************************************************
4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
6 * Copyright 2000, 2010 Oracle and/or its affiliates.
8 * OpenOffice.org - a multi-platform office productivity suite
10 * This file is part of OpenOffice.org.
12 * OpenOffice.org is free software: you can redistribute it and/or modify
13 * it under the terms of the GNU Lesser General Public License version 3
14 * only, as published by the Free Software Foundation.
16 * OpenOffice.org is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU Lesser General Public License version 3 for more details
20 * (a copy is included in the LICENSE file that accompanied this code).
22 * You should have received a copy of the GNU Lesser General Public License
23 * version 3 along with OpenOffice.org. If not, see
24 * <http://www.openoffice.org/license.html>
25 * for a copy of the LGPLv3 License.
27 ************************************************************************/
30 #include <com/sun/star/uno/genfunc.hxx>
31 #include <uno/data.h>
32 #include <typelib/typedescription.hxx>
34 #include "bridges/cpp_uno/shared/bridge.hxx"
35 #include "bridges/cpp_uno/shared/cppinterfaceproxy.hxx"
36 #include "bridges/cpp_uno/shared/types.hxx"
37 #include "bridges/cpp_uno/shared/vtablefactory.hxx"
39 #include "share.hxx"
41 using namespace ::com::sun::star::uno;
43 namespace
46 //==================================================================================================
47 static typelib_TypeClass cpp2uno_call(
48 bridges::cpp_uno::shared::CppInterfaceProxy * pThis,
49 const typelib_TypeDescription * pMemberTypeDescr,
50 typelib_TypeDescriptionReference * pReturnTypeRef, // 0 indicates void return
51 sal_Int32 nParams, typelib_MethodParameter * pParams,
52 void ** gpreg, void ** fpreg, void ** ovrflw,
53 sal_Int64 * pRegisterReturn /* space for register return */ )
56 // gpreg: [ret *], this, [gpr params]
57 // fpreg: [fpr params]
58 // ovrflw: [gpr or fpr params (space for entire parameter list in structure format properly aligned)]
60 // return
61 typelib_TypeDescription * pReturnTypeDescr = 0;
62 if (pReturnTypeRef)
63 TYPELIB_DANGER_GET( &pReturnTypeDescr, pReturnTypeRef );
65 void * pUnoReturn = 0;
66 void * pCppReturn = 0; // complex return ptr: if != 0 && != pUnoReturn, reconversion need
68 sal_Int32 ngpreg = 0;
69 sal_Int32 nfpreg = 0;
72 if (pReturnTypeDescr)
74 if (bridges::cpp_uno::shared::isSimpleType( pReturnTypeDescr ))
75 pUnoReturn = pRegisterReturn; // direct way for simple types
76 else // complex return via ptr (pCppReturn)
78 pCppReturn = *gpreg;
79 ngpreg++;
80 ++ovrflw;
82 pUnoReturn = (bridges::cpp_uno::shared::relatesToInterfaceType( pReturnTypeDescr )
83 ? alloca( pReturnTypeDescr->nSize )
84 : pCppReturn); // direct way
87 // pop this
88 ngpreg++;
89 ++ovrflw;
91 // after handling optional return pointer and "this"
92 // make use of the space that is allocated to store all parameters in the callers stack
93 // by comying the proper registers filled with parameters to that space
94 char * pCppStack = (char *)ovrflw;
97 sal_Int32 nPos;
99 for ( nPos = 0; nPos < nParams; ++nPos )
101 const typelib_MethodParameter & rParam = pParams[nPos];
102 if (rParam.bOut)
104 if (ngpreg < 8)
106 *(sal_Int32 *)pCppStack = ((sal_Int32 *)gpreg)[ngpreg++];
108 pCppStack += sizeof (sal_Int32);
110 else
112 switch (rParam.pTypeRef->eTypeClass)
114 case typelib_TypeClass_FLOAT:
115 if (nfpreg < 13)
117 *(float *)pCppStack = ((double *)fpreg)[nfpreg++];
119 pCppStack += sizeof (float);
120 ngpreg += 1;
121 break;
122 case typelib_TypeClass_DOUBLE:
123 if (nfpreg < 13)
125 *(double *)pCppStack = ((double *)fpreg)[nfpreg++];
127 pCppStack += sizeof (double);
128 ngpreg += 2;
129 break;
130 case typelib_TypeClass_UNSIGNED_HYPER:
131 case typelib_TypeClass_HYPER:
132 if (ngpreg < 8)
134 *(sal_Int32 *)pCppStack = ((sal_Int32 *)gpreg)[ngpreg++];
136 pCppStack += sizeof (sal_Int32);
137 // fall through on purpose
138 default:
139 if (ngpreg < 8)
141 *(sal_Int32 *)pCppStack = ((sal_Int32 *)gpreg)[ngpreg++];
143 pCppStack += sizeof (sal_Int32);
148 // now the stack has all of the parameters stored in it ready to be processed
149 // so we are ready to build the uno call stack
150 pCppStack = (char *)ovrflw;
152 // stack space
153 OSL_ENSURE( sizeof(void *) == sizeof(sal_Int32), "### unexpected size!" );
155 // parameters
156 void ** pUnoArgs = (void **)alloca( 4 * sizeof(void *) * nParams );
157 void ** pCppArgs = pUnoArgs + nParams;
159 // indizes of values this have to be converted (interface conversion cpp<=>uno)
160 sal_Int32 * pTempIndizes = (sal_Int32 *)(pUnoArgs + (2 * nParams));
162 // type descriptions for reconversions
163 typelib_TypeDescription ** ppTempParamTypeDescr = (typelib_TypeDescription **)(pUnoArgs + (3 * nParams));
165 sal_Int32 nTempIndizes = 0;
167 for ( nPos = 0; nPos < nParams; ++nPos )
169 const typelib_MethodParameter & rParam = pParams[nPos];
170 typelib_TypeDescription * pParamTypeDescr = 0;
171 TYPELIB_DANGER_GET( &pParamTypeDescr, rParam.pTypeRef );
173 if (!rParam.bOut && bridges::cpp_uno::shared::isSimpleType( pParamTypeDescr ))
174 // value
176 switch (pParamTypeDescr->eTypeClass)
178 case typelib_TypeClass_BOOLEAN:
179 case typelib_TypeClass_BYTE:
180 pCppArgs[nPos] = pCppStack +3;
181 pUnoArgs[nPos] = pCppStack +3;
182 break;
183 case typelib_TypeClass_CHAR:
184 case typelib_TypeClass_SHORT:
185 case typelib_TypeClass_UNSIGNED_SHORT:
186 pCppArgs[nPos] = pCppStack +2;
187 pUnoArgs[nPos] = pCppStack +2;
188 break;
189 case typelib_TypeClass_HYPER:
190 case typelib_TypeClass_UNSIGNED_HYPER:
191 case typelib_TypeClass_DOUBLE:
192 pCppArgs[nPos] = pCppStack;
193 pUnoArgs[nPos] = pCppStack;
194 pCppStack += sizeof(sal_Int32); // extra long (two regs)
195 break;
196 default:
197 pCppArgs[nPos] = pCppStack;
198 pUnoArgs[nPos] = pCppStack;
200 // no longer needed
201 TYPELIB_DANGER_RELEASE( pParamTypeDescr );
203 else // ptr to complex value | ref
205 pCppArgs[nPos] = *(void **)pCppStack;
207 if (! rParam.bIn) // is pure out
209 // uno out is unconstructed mem!
210 pUnoArgs[nPos] = alloca( pParamTypeDescr->nSize );
211 pTempIndizes[nTempIndizes] = nPos;
212 // will be released at reconversion
213 ppTempParamTypeDescr[nTempIndizes++] = pParamTypeDescr;
215 // is in/inout
216 else if (bridges::cpp_uno::shared::relatesToInterfaceType( pParamTypeDescr ))
218 uno_copyAndConvertData( pUnoArgs[nPos] = alloca( pParamTypeDescr->nSize ),
219 *(void **)pCppStack, pParamTypeDescr,
220 pThis->getBridge()->getCpp2Uno() );
221 pTempIndizes[nTempIndizes] = nPos; // has to be reconverted
222 // will be released at reconversion
223 ppTempParamTypeDescr[nTempIndizes++] = pParamTypeDescr;
225 else // direct way
227 pUnoArgs[nPos] = *(void **)pCppStack;
228 // no longer needed
229 TYPELIB_DANGER_RELEASE( pParamTypeDescr );
232 pCppStack += sizeof(sal_Int32); // standard parameter length
236 // ExceptionHolder
237 uno_Any aUnoExc; // Any will be constructed by callee
238 uno_Any * pUnoExc = &aUnoExc;
240 // invoke uno dispatch call
241 (*pThis->getUnoI()->pDispatcher)(
242 pThis->getUnoI(), pMemberTypeDescr, pUnoReturn, pUnoArgs, &pUnoExc );
244 // in case an exception occurred...
245 if (pUnoExc)
247 // destruct temporary in/inout params
248 for ( ; nTempIndizes--; )
250 sal_Int32 nIndex = pTempIndizes[nTempIndizes];
252 if (pParams[nIndex].bIn) // is in/inout => was constructed
253 uno_destructData( pUnoArgs[nIndex], ppTempParamTypeDescr[nTempIndizes], 0 );
254 TYPELIB_DANGER_RELEASE( ppTempParamTypeDescr[nTempIndizes] );
256 if (pReturnTypeDescr)
257 TYPELIB_DANGER_RELEASE( pReturnTypeDescr );
259 CPPU_CURRENT_NAMESPACE::raiseException(
260 &aUnoExc, pThis->getBridge()->getUno2Cpp() );
261 // has to destruct the any
262 // is here for dummy
263 return typelib_TypeClass_VOID;
265 else // else no exception occurred...
267 // temporary params
268 for ( ; nTempIndizes--; )
270 sal_Int32 nIndex = pTempIndizes[nTempIndizes];
271 typelib_TypeDescription * pParamTypeDescr = ppTempParamTypeDescr[nTempIndizes];
273 if (pParams[nIndex].bOut) // inout/out
275 // convert and assign
276 uno_destructData( pCppArgs[nIndex], pParamTypeDescr, cpp_release );
277 uno_copyAndConvertData( pCppArgs[nIndex], pUnoArgs[nIndex], pParamTypeDescr,
278 pThis->getBridge()->getUno2Cpp() );
280 // destroy temp uno param
281 uno_destructData( pUnoArgs[nIndex], pParamTypeDescr, 0 );
283 TYPELIB_DANGER_RELEASE( pParamTypeDescr );
285 // return
286 if (pCppReturn) // has complex return
288 if (pUnoReturn != pCppReturn) // needs reconversion
290 uno_copyAndConvertData( pCppReturn, pUnoReturn, pReturnTypeDescr,
291 pThis->getBridge()->getUno2Cpp() );
292 // destroy temp uno return
293 uno_destructData( pUnoReturn, pReturnTypeDescr, 0 );
295 // complex return ptr is set to return reg
296 *(void **)pRegisterReturn = pCppReturn;
298 if (pReturnTypeDescr)
300 typelib_TypeClass eRet = (typelib_TypeClass)pReturnTypeDescr->eTypeClass;
301 TYPELIB_DANGER_RELEASE( pReturnTypeDescr );
302 return eRet;
304 else
305 return typelib_TypeClass_VOID;
310 //==================================================================================================
311 static typelib_TypeClass cpp_mediate(
312 sal_Int32 nFunctionIndex,
313 sal_Int32 nVtableOffset,
314 void ** gpreg, void ** fpreg, void ** ovrflw,
315 sal_Int64 * pRegisterReturn /* space for register return */ )
317 OSL_ENSURE( sizeof(sal_Int32)==sizeof(void *), "### unexpected!" );
319 // gpreg: [ret *], this, [other gpr params]
320 // fpreg: [fpr params]
321 // ovrflw: [gpr or fpr params (in space allocated for all params properly aligned)]
323 void * pThis;
324 if( nFunctionIndex & 0x80000000 )
326 nFunctionIndex &= 0x7fffffff;
327 pThis = gpreg[1];
329 else
331 pThis = gpreg[0];
334 pThis = static_cast< char * >(pThis) - nVtableOffset;
335 bridges::cpp_uno::shared::CppInterfaceProxy * pCppI
336 = bridges::cpp_uno::shared::CppInterfaceProxy::castInterfaceToProxy(pThis);
339 typelib_InterfaceTypeDescription * pTypeDescr = pCppI->getTypeDescr();
341 OSL_ENSURE( nFunctionIndex < pTypeDescr->nMapFunctionIndexToMemberIndex, "### illegal vtable index!" );
342 if (nFunctionIndex >= pTypeDescr->nMapFunctionIndexToMemberIndex)
344 throw RuntimeException(
345 rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "illegal vtable index!" )),
346 (XInterface *)pThis );
349 // determine called method
350 sal_Int32 nMemberPos = pTypeDescr->pMapFunctionIndexToMemberIndex[nFunctionIndex];
351 OSL_ENSURE( nMemberPos < pTypeDescr->nAllMembers, "### illegal member index!" );
353 TypeDescription aMemberDescr( pTypeDescr->ppAllMembers[nMemberPos] );
355 typelib_TypeClass eRet;
356 switch (aMemberDescr.get()->eTypeClass)
358 case typelib_TypeClass_INTERFACE_ATTRIBUTE:
360 if (pTypeDescr->pMapMemberIndexToFunctionIndex[nMemberPos] == nFunctionIndex)
362 // is GET method
363 eRet = cpp2uno_call(
364 pCppI, aMemberDescr.get(),
365 ((typelib_InterfaceAttributeTypeDescription *)aMemberDescr.get())->pAttributeTypeRef,
366 0, 0, // no params
367 gpreg, fpreg, ovrflw, pRegisterReturn );
369 else
371 // is SET method
372 typelib_MethodParameter aParam;
373 aParam.pTypeRef =
374 ((typelib_InterfaceAttributeTypeDescription *)aMemberDescr.get())->pAttributeTypeRef;
375 aParam.bIn = sal_True;
376 aParam.bOut = sal_False;
378 eRet = cpp2uno_call(
379 pCppI, aMemberDescr.get(),
380 0, // indicates void return
381 1, &aParam,
382 gpreg, fpreg, ovrflw, pRegisterReturn );
384 break;
386 case typelib_TypeClass_INTERFACE_METHOD:
388 // is METHOD
389 switch (nFunctionIndex)
391 case 1: // acquire()
392 pCppI->acquireProxy(); // non virtual call!
393 eRet = typelib_TypeClass_VOID;
394 break;
395 case 2: // release()
396 pCppI->releaseProxy(); // non virtual call!
397 eRet = typelib_TypeClass_VOID;
398 break;
399 case 0: // queryInterface() opt
401 typelib_TypeDescription * pTD = 0;
402 TYPELIB_DANGER_GET( &pTD, reinterpret_cast< Type * >( gpreg[2] )->getTypeLibType() );
403 if (pTD)
405 XInterface * pInterface = 0;
406 (*pCppI->getBridge()->getCppEnv()->getRegisteredInterface)(
407 pCppI->getBridge()->getCppEnv(),
408 (void **)&pInterface, pCppI->getOid().pData, (typelib_InterfaceTypeDescription *)pTD );
410 if (pInterface)
412 ::uno_any_construct(
413 reinterpret_cast< uno_Any * >( gpreg[0] ),
414 &pInterface, pTD, cpp_acquire );
415 pInterface->release();
416 TYPELIB_DANGER_RELEASE( pTD );
417 *(void **)pRegisterReturn = gpreg[0];
418 eRet = typelib_TypeClass_ANY;
419 break;
421 TYPELIB_DANGER_RELEASE( pTD );
423 } // else perform queryInterface()
424 default:
425 eRet = cpp2uno_call(
426 pCppI, aMemberDescr.get(),
427 ((typelib_InterfaceMethodTypeDescription *)aMemberDescr.get())->pReturnTypeRef,
428 ((typelib_InterfaceMethodTypeDescription *)aMemberDescr.get())->nParams,
429 ((typelib_InterfaceMethodTypeDescription *)aMemberDescr.get())->pParams,
430 gpreg, fpreg, ovrflw, pRegisterReturn );
432 break;
434 default:
436 throw RuntimeException(
437 rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "no member description found!" )),
438 (XInterface *)pThis );
442 return eRet;
445 //==================================================================================================
447 * is called on incoming vtable calls
448 * (called by asm snippets)
450 static void cpp_vtable_call( int nFunctionIndex, int nVtableOffset, void** gpregptr, void** fpregptr, void** ovrflw)
452 sal_Int32 gpreg[8];
453 double fpreg[13];
455 // FIXME: why are we restoring the volatile ctr register here
456 sal_Int32 ctrsave = ((sal_Int32*)gpregptr)[-1];
458 memcpy( gpreg, gpregptr, 32);
459 memcpy( fpreg, fpregptr, 104);
461 volatile long nRegReturn[2];
463 // sal_Bool bComplex = nFunctionIndex & 0x80000000 ? sal_True : sal_False;
465 typelib_TypeClass aType =
466 cpp_mediate( nFunctionIndex, nVtableOffset, (void**)gpreg, (void**)fpreg, ovrflw, (sal_Int64*)nRegReturn );
468 // FIXME: why are we restoring the volatile ctr register here
469 // FIXME: and why are we putting back the values for r4, r5, and r6 as well
470 // FIXME: this makes no sense to me, all of these registers are volatile!
471 __asm__( "lwz r4, %0\n\t"
472 "mtctr r4\n\t"
473 "lwz r4, %1\n\t"
474 "lwz r5, %2\n\t"
475 "lwz r6, %3\n\t"
476 : : "m"(ctrsave), "m"(gpreg[1]), "m"(gpreg[2]), "m"(gpreg[3]) );
478 switch( aType )
481 // move return value into register space
482 // (will be loaded by machine code snippet)
484 case typelib_TypeClass_BOOLEAN:
485 case typelib_TypeClass_BYTE:
486 __asm__( "lbz r3,%0\n\t" : :
487 "m"(nRegReturn[0]) );
488 break;
490 case typelib_TypeClass_CHAR:
491 case typelib_TypeClass_SHORT:
492 case typelib_TypeClass_UNSIGNED_SHORT:
493 __asm__( "lhz r3,%0\n\t" : :
494 "m"(nRegReturn[0]) );
495 break;
497 case typelib_TypeClass_FLOAT:
498 __asm__( "lfs f1,%0\n\t" : :
499 "m" (*((float*)nRegReturn)) );
500 break;
502 case typelib_TypeClass_DOUBLE:
503 __asm__( "lfd f1,%0\n\t" : :
504 "m" (*((double*)nRegReturn)) );
505 break;
507 case typelib_TypeClass_HYPER:
508 case typelib_TypeClass_UNSIGNED_HYPER:
509 __asm__( "lwz r4,%0\n\t" : :
510 "m"(nRegReturn[1]) ); // fall through
512 default:
513 __asm__( "lwz r3,%0\n\t" : :
514 "m"(nRegReturn[0]) );
515 break;
520 int const codeSnippetSize = 136;
522 unsigned char * codeSnippet( unsigned char * code, sal_Int32 functionIndex,
523 sal_Int32 vtableOffset, bool simpleRetType )
525 if (! simpleRetType )
526 functionIndex |= 0x80000000;
528 // OSL_ASSERT( sizeof (long) == 4 );
530 // FIXME: why are we leaving an 8k gap in the stack here
531 // FIXME: is this to allow room for signal handling frames?
532 // FIXME: seems like overkill here but this is what was done for Mac OSX for gcc2
533 // FIXME: also why no saving of the non-volatile CR pieces here, to be safe
534 // FIXME: we probably should
536 /* generate this code */
538 // # so first save gpr 3 to gpr 10 (aligned to 4)
539 // stw r3, -8000(r1)
540 // stw r4, -7996(r1)
541 // stw r5, -7992(r1)
542 // stw r6, -7988(r1)
543 // stw r7, -7984(r1)
544 // stw r8, -7980(r1)
545 // stw r9, -7976(r1)
546 // stw r10,-7972(r1)
548 // # next save fpr 1 to fpr 13 (aligned to 8)
549 // stfd f1, -7968(r1)
550 // stfd f2, -7960(r1)
551 // stfd f3, -7952(r1)
552 // stfd f4, -7944(r1)
553 // stfd f5, -7936(r1)
554 // stfd f6, -7928(r1)
555 // stfd f7, -7920(r1)
556 // stfd f8, -7912(r1)
557 // stfd f9, -7904(r1)
558 // stfd f10,-7896(r1)
559 // stfd f11,-7888(r1)
560 // stfd f12,-7880(r1)
561 // stfd f13,-7872(r1)
563 // FIXME: ctr is volatile, while are we saving it and not CR?
564 // mfctr r3
565 // stw r3, -8004(r1)
567 // # now here is where cpp_vtable_call must go
568 // lis r3,0xdead
569 // ori r3,r3,0xbeef
570 // mtctr r3
572 // # now load up the functionIndex number
573 // lis r3, 0xdead
574 // ori r3,r3,0xbeef
576 // # now load up the vtableOffset
577 // lis r4, 0xdead
578 // ori r4,r4,0xbeef
580 // #now load up the pointer to the saved gpr registers
581 // addi r5,r1,-8000
583 // #now load up the pointer to the saved fpr registers
584 // addi r6,r1,-7968
586 // #now load up the pointer to the overflow call stack
587 // addi r7,r1,24 # frame pointer plus 24
589 // bctr
591 unsigned long * p = (unsigned long *) code;
593 * p++ = 0x9061e0c0;
594 * p++ = 0x9081e0c4;
595 * p++ = 0x90a1e0c8;
596 * p++ = 0x90c1e0cc;
597 * p++ = 0x90e1e0d0;
598 * p++ = 0x9101e0d4;
599 * p++ = 0x9121e0d8;
600 * p++ = 0x9141e0dc;
601 * p++ = 0xd821e0e0;
602 * p++ = 0xd841e0e8;
603 * p++ = 0xd861e0f0;
604 * p++ = 0xd881e0f8;
605 * p++ = 0xd8a1e100;
606 * p++ = 0xd8c1e108;
607 * p++ = 0xd8e1e110;
608 * p++ = 0xd901e118;
609 * p++ = 0xd921e120;
610 * p++ = 0xd941e128;
611 * p++ = 0xd961e130;
612 * p++ = 0xd981e138;
613 * p++ = 0xd9a1e140;
614 * p++ = 0x7c6902a6;
615 * p++ = 0x9061e0bc;
616 * p++ = 0x3c600000 | (((unsigned long)cpp_vtable_call) >> 16);
617 * p++ = 0x60630000 | (((unsigned long)cpp_vtable_call) & 0x0000FFFF);
618 * p++ = 0x7c6903a6;
619 * p++ = 0x3c600000 | (((unsigned long)functionIndex) >> 16);
620 * p++ = 0x60630000 | (((unsigned long)functionIndex) & 0x0000FFFF);
621 * p++ = 0x3c800000 | (((unsigned long)vtableOffset) >> 16);
622 * p++ = 0x60840000 | (((unsigned long)vtableOffset) & 0x0000FFFF);
623 * p++ = 0x38a1e0c0;
624 * p++ = 0x38c1e0e0;
625 * p++ = 0x38e10018;
626 * p++ = 0x4e800420;
628 return (code + codeSnippetSize);
635 void bridges::cpp_uno::shared::VtableFactory::flushCode(unsigned char const * bptr, unsigned char const * eptr)
637 int const lineSize = 32;
638 for (unsigned char const * p = bptr; p < eptr + lineSize; p += lineSize) {
639 __asm__ volatile ("dcbst 0, %0" : : "r"(p) : "memory");
641 __asm__ volatile ("sync" : : : "memory");
642 for (unsigned char const * p = bptr; p < eptr + lineSize; p += lineSize) {
643 __asm__ volatile ("icbi 0, %0" : : "r"(p) : "memory");
645 __asm__ volatile ("isync" : : : "memory");
648 struct bridges::cpp_uno::shared::VtableFactory::Slot { void * fn; };
650 bridges::cpp_uno::shared::VtableFactory::Slot *
651 bridges::cpp_uno::shared::VtableFactory::mapBlockToVtable(void * block)
653 return static_cast< Slot * >(block) + 2;
656 sal_Size bridges::cpp_uno::shared::VtableFactory::getBlockSize(
657 sal_Int32 slotCount)
659 return (slotCount + 2) * sizeof (Slot) + slotCount * codeSnippetSize;
662 bridges::cpp_uno::shared::VtableFactory::Slot *
663 bridges::cpp_uno::shared::VtableFactory::initializeBlock(
664 void * block, sal_Int32 slotCount)
666 Slot * slots = mapBlockToVtable(block);
667 slots[-2].fn = 0;
668 slots[-1].fn = 0;
669 return slots + slotCount;
672 unsigned char * bridges::cpp_uno::shared::VtableFactory::addLocalFunctions(
673 Slot ** slots, unsigned char * code,
674 typelib_InterfaceTypeDescription const * type, sal_Int32 functionOffset,
675 sal_Int32 functionCount, sal_Int32 vtableOffset)
677 (*slots) -= functionCount;
678 Slot * s = *slots;
680 // fprintf(stderr, "in addLocalFunctions functionOffset is %x\n",functionOffset);
681 // fprintf(stderr, "in addLocalFunctions vtableOffset is %x\n",vtableOffset);
682 // fflush(stderr);
684 for (sal_Int32 i = 0; i < type->nMembers; ++i) {
685 typelib_TypeDescription * member = 0;
686 TYPELIB_DANGER_GET(&member, type->ppMembers[i]);
687 OSL_ASSERT(member != 0);
688 switch (member->eTypeClass) {
689 case typelib_TypeClass_INTERFACE_ATTRIBUTE:
690 // Getter:
691 (s++)->fn = code;
692 code = codeSnippet(
693 code, functionOffset++, vtableOffset,
694 bridges::cpp_uno::shared::isSimpleType(
695 reinterpret_cast<
696 typelib_InterfaceAttributeTypeDescription * >(
697 member)->pAttributeTypeRef));
699 // Setter:
700 if (!reinterpret_cast<
701 typelib_InterfaceAttributeTypeDescription * >(
702 member)->bReadOnly)
704 (s++)->fn = code;
705 code = codeSnippet(code, functionOffset++, vtableOffset, true);
707 break;
709 case typelib_TypeClass_INTERFACE_METHOD:
710 (s++)->fn = code;
711 code = codeSnippet(
712 code, functionOffset++, vtableOffset,
713 bridges::cpp_uno::shared::isSimpleType(
714 reinterpret_cast<
715 typelib_InterfaceMethodTypeDescription * >(
716 member)->pReturnTypeRef));
717 break;
719 default:
720 OSL_ASSERT(false);
721 break;
723 TYPELIB_DANGER_RELEASE(member);
725 return code;
728 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */