merge the formfield patch from ooo-build
[ooovba.git] / bridges / source / cpp_uno / gcc3_macosx_powerpc / cpp2uno.cxx
blob62a129143936c7ce1f13da54a5bdcff155a36266
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: cpp2uno.cxx,v $
10 * $Revision: 1.11 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_bridges.hxx"
34 #include <com/sun/star/uno/genfunc.hxx>
35 #include <uno/data.h>
36 #include <typelib/typedescription.hxx>
38 #include "bridges/cpp_uno/shared/bridge.hxx"
39 #include "bridges/cpp_uno/shared/cppinterfaceproxy.hxx"
40 #include "bridges/cpp_uno/shared/types.hxx"
41 #include "bridges/cpp_uno/shared/vtablefactory.hxx"
43 #include "share.hxx"
45 using namespace ::com::sun::star::uno;
47 namespace
50 //==================================================================================================
51 static typelib_TypeClass cpp2uno_call(
52 bridges::cpp_uno::shared::CppInterfaceProxy * pThis,
53 const typelib_TypeDescription * pMemberTypeDescr,
54 typelib_TypeDescriptionReference * pReturnTypeRef, // 0 indicates void return
55 sal_Int32 nParams, typelib_MethodParameter * pParams,
56 void ** gpreg, void ** fpreg, void ** ovrflw,
57 sal_Int64 * pRegisterReturn /* space for register return */ )
60 // gpreg: [ret *], this, [gpr params]
61 // fpreg: [fpr params]
62 // ovrflw: [gpr or fpr params (space for entire parameter list in structure format properly aligned)]
64 // return
65 typelib_TypeDescription * pReturnTypeDescr = 0;
66 if (pReturnTypeRef)
67 TYPELIB_DANGER_GET( &pReturnTypeDescr, pReturnTypeRef );
69 void * pUnoReturn = 0;
70 void * pCppReturn = 0; // complex return ptr: if != 0 && != pUnoReturn, reconversion need
72 sal_Int32 ngpreg = 0;
73 sal_Int32 nfpreg = 0;
76 if (pReturnTypeDescr)
78 if (bridges::cpp_uno::shared::isSimpleType( pReturnTypeDescr ))
79 pUnoReturn = pRegisterReturn; // direct way for simple types
80 else // complex return via ptr (pCppReturn)
82 pCppReturn = *gpreg;
83 ngpreg++;
84 ++ovrflw;
86 pUnoReturn = (bridges::cpp_uno::shared::relatesToInterfaceType( pReturnTypeDescr )
87 ? alloca( pReturnTypeDescr->nSize )
88 : pCppReturn); // direct way
91 // pop this
92 ngpreg++;
93 ++ovrflw;
95 // after handling optional return pointer and "this"
96 // make use of the space that is allocated to store all parameters in the callers stack
97 // by comying the proper registers filled with parameters to that space
98 char * pCppStack = (char *)ovrflw;
101 sal_Int32 nPos;
103 for ( nPos = 0; nPos < nParams; ++nPos )
105 const typelib_MethodParameter & rParam = pParams[nPos];
106 if (rParam.bOut)
108 if (ngpreg < 8)
110 *(sal_Int32 *)pCppStack = ((sal_Int32 *)gpreg)[ngpreg++];
112 pCppStack += sizeof (sal_Int32);
114 else
116 switch (rParam.pTypeRef->eTypeClass)
118 case typelib_TypeClass_FLOAT:
119 if (nfpreg < 13)
121 *(float *)pCppStack = ((double *)fpreg)[nfpreg++];
123 pCppStack += sizeof (float);
124 ngpreg += 1;
125 break;
126 case typelib_TypeClass_DOUBLE:
127 if (nfpreg < 13)
129 *(double *)pCppStack = ((double *)fpreg)[nfpreg++];
131 pCppStack += sizeof (double);
132 ngpreg += 2;
133 break;
134 case typelib_TypeClass_UNSIGNED_HYPER:
135 case typelib_TypeClass_HYPER:
136 if (ngpreg < 8)
138 *(sal_Int32 *)pCppStack = ((sal_Int32 *)gpreg)[ngpreg++];
140 pCppStack += sizeof (sal_Int32);
141 // fall through on purpose
142 default:
143 if (ngpreg < 8)
145 *(sal_Int32 *)pCppStack = ((sal_Int32 *)gpreg)[ngpreg++];
147 pCppStack += sizeof (sal_Int32);
152 // now the stack has all of the paramters stored in it ready to be processed
153 // so we are ready to build the uno call stack
154 pCppStack = (char *)ovrflw;
156 // stack space
157 OSL_ENSURE( sizeof(void *) == sizeof(sal_Int32), "### unexpected size!" );
159 // parameters
160 void ** pUnoArgs = (void **)alloca( 4 * sizeof(void *) * nParams );
161 void ** pCppArgs = pUnoArgs + nParams;
163 // indizes of values this have to be converted (interface conversion cpp<=>uno)
164 sal_Int32 * pTempIndizes = (sal_Int32 *)(pUnoArgs + (2 * nParams));
166 // type descriptions for reconversions
167 typelib_TypeDescription ** ppTempParamTypeDescr = (typelib_TypeDescription **)(pUnoArgs + (3 * nParams));
169 sal_Int32 nTempIndizes = 0;
171 for ( nPos = 0; nPos < nParams; ++nPos )
173 const typelib_MethodParameter & rParam = pParams[nPos];
174 typelib_TypeDescription * pParamTypeDescr = 0;
175 TYPELIB_DANGER_GET( &pParamTypeDescr, rParam.pTypeRef );
177 if (!rParam.bOut && bridges::cpp_uno::shared::isSimpleType( pParamTypeDescr ))
178 // value
180 switch (pParamTypeDescr->eTypeClass)
182 case typelib_TypeClass_BOOLEAN:
183 case typelib_TypeClass_BYTE:
184 pCppArgs[nPos] = pCppStack +3;
185 pUnoArgs[nPos] = pCppStack +3;
186 break;
187 case typelib_TypeClass_CHAR:
188 case typelib_TypeClass_SHORT:
189 case typelib_TypeClass_UNSIGNED_SHORT:
190 pCppArgs[nPos] = pCppStack +2;
191 pUnoArgs[nPos] = pCppStack +2;
192 break;
193 case typelib_TypeClass_HYPER:
194 case typelib_TypeClass_UNSIGNED_HYPER:
195 case typelib_TypeClass_DOUBLE:
196 pCppArgs[nPos] = pCppStack;
197 pUnoArgs[nPos] = pCppStack;
198 pCppStack += sizeof(sal_Int32); // extra long (two regs)
199 break;
200 default:
201 pCppArgs[nPos] = pCppStack;
202 pUnoArgs[nPos] = pCppStack;
204 // no longer needed
205 TYPELIB_DANGER_RELEASE( pParamTypeDescr );
207 else // ptr to complex value | ref
209 pCppArgs[nPos] = *(void **)pCppStack;
211 if (! rParam.bIn) // is pure out
213 // uno out is unconstructed mem!
214 pUnoArgs[nPos] = alloca( pParamTypeDescr->nSize );
215 pTempIndizes[nTempIndizes] = nPos;
216 // will be released at reconversion
217 ppTempParamTypeDescr[nTempIndizes++] = pParamTypeDescr;
219 // is in/inout
220 else if (bridges::cpp_uno::shared::relatesToInterfaceType( pParamTypeDescr ))
222 uno_copyAndConvertData( pUnoArgs[nPos] = alloca( pParamTypeDescr->nSize ),
223 *(void **)pCppStack, pParamTypeDescr,
224 pThis->getBridge()->getCpp2Uno() );
225 pTempIndizes[nTempIndizes] = nPos; // has to be reconverted
226 // will be released at reconversion
227 ppTempParamTypeDescr[nTempIndizes++] = pParamTypeDescr;
229 else // direct way
231 pUnoArgs[nPos] = *(void **)pCppStack;
232 // no longer needed
233 TYPELIB_DANGER_RELEASE( pParamTypeDescr );
236 pCppStack += sizeof(sal_Int32); // standard parameter length
240 // ExceptionHolder
241 uno_Any aUnoExc; // Any will be constructed by callee
242 uno_Any * pUnoExc = &aUnoExc;
244 // invoke uno dispatch call
245 (*pThis->getUnoI()->pDispatcher)(
246 pThis->getUnoI(), pMemberTypeDescr, pUnoReturn, pUnoArgs, &pUnoExc );
248 // in case an exception occured...
249 if (pUnoExc)
251 // destruct temporary in/inout params
252 for ( ; nTempIndizes--; )
254 sal_Int32 nIndex = pTempIndizes[nTempIndizes];
256 if (pParams[nIndex].bIn) // is in/inout => was constructed
257 uno_destructData( pUnoArgs[nIndex], ppTempParamTypeDescr[nTempIndizes], 0 );
258 TYPELIB_DANGER_RELEASE( ppTempParamTypeDescr[nTempIndizes] );
260 if (pReturnTypeDescr)
261 TYPELIB_DANGER_RELEASE( pReturnTypeDescr );
263 CPPU_CURRENT_NAMESPACE::raiseException(
264 &aUnoExc, pThis->getBridge()->getUno2Cpp() );
265 // has to destruct the any
266 // is here for dummy
267 return typelib_TypeClass_VOID;
269 else // else no exception occured...
271 // temporary params
272 for ( ; nTempIndizes--; )
274 sal_Int32 nIndex = pTempIndizes[nTempIndizes];
275 typelib_TypeDescription * pParamTypeDescr = ppTempParamTypeDescr[nTempIndizes];
277 if (pParams[nIndex].bOut) // inout/out
279 // convert and assign
280 uno_destructData( pCppArgs[nIndex], pParamTypeDescr, cpp_release );
281 uno_copyAndConvertData( pCppArgs[nIndex], pUnoArgs[nIndex], pParamTypeDescr,
282 pThis->getBridge()->getUno2Cpp() );
284 // destroy temp uno param
285 uno_destructData( pUnoArgs[nIndex], pParamTypeDescr, 0 );
287 TYPELIB_DANGER_RELEASE( pParamTypeDescr );
289 // return
290 if (pCppReturn) // has complex return
292 if (pUnoReturn != pCppReturn) // needs reconversion
294 uno_copyAndConvertData( pCppReturn, pUnoReturn, pReturnTypeDescr,
295 pThis->getBridge()->getUno2Cpp() );
296 // destroy temp uno return
297 uno_destructData( pUnoReturn, pReturnTypeDescr, 0 );
299 // complex return ptr is set to return reg
300 *(void **)pRegisterReturn = pCppReturn;
302 if (pReturnTypeDescr)
304 typelib_TypeClass eRet = (typelib_TypeClass)pReturnTypeDescr->eTypeClass;
305 TYPELIB_DANGER_RELEASE( pReturnTypeDescr );
306 return eRet;
308 else
309 return typelib_TypeClass_VOID;
314 //==================================================================================================
315 static typelib_TypeClass cpp_mediate(
316 sal_Int32 nFunctionIndex,
317 sal_Int32 nVtableOffset,
318 void ** gpreg, void ** fpreg, void ** ovrflw,
319 sal_Int64 * pRegisterReturn /* space for register return */ )
321 OSL_ENSURE( sizeof(sal_Int32)==sizeof(void *), "### unexpected!" );
323 // gpreg: [ret *], this, [other gpr params]
324 // fpreg: [fpr params]
325 // ovrflw: [gpr or fpr params (in space allocated for all params properly aligned)]
327 void * pThis;
328 if( nFunctionIndex & 0x80000000 )
330 nFunctionIndex &= 0x7fffffff;
331 pThis = gpreg[1];
333 else
335 pThis = gpreg[0];
338 pThis = static_cast< char * >(pThis) - nVtableOffset;
339 bridges::cpp_uno::shared::CppInterfaceProxy * pCppI
340 = bridges::cpp_uno::shared::CppInterfaceProxy::castInterfaceToProxy(pThis);
343 typelib_InterfaceTypeDescription * pTypeDescr = pCppI->getTypeDescr();
345 OSL_ENSURE( nFunctionIndex < pTypeDescr->nMapFunctionIndexToMemberIndex, "### illegal vtable index!" );
346 if (nFunctionIndex >= pTypeDescr->nMapFunctionIndexToMemberIndex)
348 throw RuntimeException(
349 rtl::OUString::createFromAscii("illegal vtable index!"),
350 (XInterface *)pThis );
353 // determine called method
354 sal_Int32 nMemberPos = pTypeDescr->pMapFunctionIndexToMemberIndex[nFunctionIndex];
355 OSL_ENSURE( nMemberPos < pTypeDescr->nAllMembers, "### illegal member index!" );
357 TypeDescription aMemberDescr( pTypeDescr->ppAllMembers[nMemberPos] );
359 typelib_TypeClass eRet;
360 switch (aMemberDescr.get()->eTypeClass)
362 case typelib_TypeClass_INTERFACE_ATTRIBUTE:
364 if (pTypeDescr->pMapMemberIndexToFunctionIndex[nMemberPos] == nFunctionIndex)
366 // is GET method
367 eRet = cpp2uno_call(
368 pCppI, aMemberDescr.get(),
369 ((typelib_InterfaceAttributeTypeDescription *)aMemberDescr.get())->pAttributeTypeRef,
370 0, 0, // no params
371 gpreg, fpreg, ovrflw, pRegisterReturn );
373 else
375 // is SET method
376 typelib_MethodParameter aParam;
377 aParam.pTypeRef =
378 ((typelib_InterfaceAttributeTypeDescription *)aMemberDescr.get())->pAttributeTypeRef;
379 aParam.bIn = sal_True;
380 aParam.bOut = sal_False;
382 eRet = cpp2uno_call(
383 pCppI, aMemberDescr.get(),
384 0, // indicates void return
385 1, &aParam,
386 gpreg, fpreg, ovrflw, pRegisterReturn );
388 break;
390 case typelib_TypeClass_INTERFACE_METHOD:
392 // is METHOD
393 switch (nFunctionIndex)
395 case 1: // acquire()
396 pCppI->acquireProxy(); // non virtual call!
397 eRet = typelib_TypeClass_VOID;
398 break;
399 case 2: // release()
400 pCppI->releaseProxy(); // non virtual call!
401 eRet = typelib_TypeClass_VOID;
402 break;
403 case 0: // queryInterface() opt
405 typelib_TypeDescription * pTD = 0;
406 TYPELIB_DANGER_GET( &pTD, reinterpret_cast< Type * >( gpreg[2] )->getTypeLibType() );
407 if (pTD)
409 XInterface * pInterface = 0;
410 (*pCppI->getBridge()->getCppEnv()->getRegisteredInterface)(
411 pCppI->getBridge()->getCppEnv(),
412 (void **)&pInterface, pCppI->getOid().pData, (typelib_InterfaceTypeDescription *)pTD );
414 if (pInterface)
416 ::uno_any_construct(
417 reinterpret_cast< uno_Any * >( gpreg[0] ),
418 &pInterface, pTD, cpp_acquire );
419 pInterface->release();
420 TYPELIB_DANGER_RELEASE( pTD );
421 *(void **)pRegisterReturn = gpreg[0];
422 eRet = typelib_TypeClass_ANY;
423 break;
425 TYPELIB_DANGER_RELEASE( pTD );
427 } // else perform queryInterface()
428 default:
429 eRet = cpp2uno_call(
430 pCppI, aMemberDescr.get(),
431 ((typelib_InterfaceMethodTypeDescription *)aMemberDescr.get())->pReturnTypeRef,
432 ((typelib_InterfaceMethodTypeDescription *)aMemberDescr.get())->nParams,
433 ((typelib_InterfaceMethodTypeDescription *)aMemberDescr.get())->pParams,
434 gpreg, fpreg, ovrflw, pRegisterReturn );
436 break;
438 default:
440 throw RuntimeException(
441 rtl::OUString::createFromAscii("no member description found!"),
442 (XInterface *)pThis );
443 // is here for dummy
444 eRet = typelib_TypeClass_VOID;
448 return eRet;
451 //==================================================================================================
453 * is called on incoming vtable calls
454 * (called by asm snippets)
456 static void cpp_vtable_call( int nFunctionIndex, int nVtableOffset, void** gpregptr, void** fpregptr, void** ovrflw)
458 sal_Int32 gpreg[8];
459 double fpreg[13];
461 // FIXME: why are we restoring the volatile ctr register here
462 sal_Int32 ctrsave = ((sal_Int32*)gpregptr)[-1];
464 memcpy( gpreg, gpregptr, 32);
465 memcpy( fpreg, fpregptr, 104);
467 volatile long nRegReturn[2];
469 // sal_Bool bComplex = nFunctionIndex & 0x80000000 ? sal_True : sal_False;
471 typelib_TypeClass aType =
472 cpp_mediate( nFunctionIndex, nVtableOffset, (void**)gpreg, (void**)fpreg, ovrflw, (sal_Int64*)nRegReturn );
474 // FIXME: why are we restoring the volatile ctr register here
475 // FIXME: and why are we putting back the values for r4, r5, and r6 as well
476 // FIXME: this makes no sense to me, all of these registers are volatile!
477 __asm__( "lwz r4, %0\n\t"
478 "mtctr r4\n\t"
479 "lwz r4, %1\n\t"
480 "lwz r5, %2\n\t"
481 "lwz r6, %3\n\t"
482 : : "m"(ctrsave), "m"(gpreg[1]), "m"(gpreg[2]), "m"(gpreg[3]) );
484 switch( aType )
487 // move return value into register space
488 // (will be loaded by machine code snippet)
490 case typelib_TypeClass_BOOLEAN:
491 case typelib_TypeClass_BYTE:
492 __asm__( "lbz r3,%0\n\t" : :
493 "m"(nRegReturn[0]) );
494 break;
496 case typelib_TypeClass_CHAR:
497 case typelib_TypeClass_SHORT:
498 case typelib_TypeClass_UNSIGNED_SHORT:
499 __asm__( "lhz r3,%0\n\t" : :
500 "m"(nRegReturn[0]) );
501 break;
503 case typelib_TypeClass_FLOAT:
504 __asm__( "lfs f1,%0\n\t" : :
505 "m" (*((float*)nRegReturn)) );
506 break;
508 case typelib_TypeClass_DOUBLE:
509 __asm__( "lfd f1,%0\n\t" : :
510 "m" (*((double*)nRegReturn)) );
511 break;
513 case typelib_TypeClass_HYPER:
514 case typelib_TypeClass_UNSIGNED_HYPER:
515 __asm__( "lwz r4,%0\n\t" : :
516 "m"(nRegReturn[1]) ); // fall through
518 default:
519 __asm__( "lwz r3,%0\n\t" : :
520 "m"(nRegReturn[0]) );
521 break;
526 int const codeSnippetSize = 136;
528 unsigned char * codeSnippet( unsigned char * code, sal_Int32 functionIndex,
529 sal_Int32 vtableOffset, bool simpleRetType )
531 if (! simpleRetType )
532 functionIndex |= 0x80000000;
534 // OSL_ASSERT( sizeof (long) == 4 );
536 // FIXME: why are we leaving an 8k gap in the stack here
537 // FIXME: is this to allow room for signal handling frames?
538 // FIXME: seems like overkill here but this is what was done for Mac OSX for gcc2
539 // FIXME: also why no saving of the non-volatile CR pieces here, to be safe
540 // FIXME: we probably should
542 /* generate this code */
544 // # so first save gpr 3 to gpr 10 (aligned to 4)
545 // stw r3, -8000(r1)
546 // stw r4, -7996(r1)
547 // stw r5, -7992(r1)
548 // stw r6, -7988(r1)
549 // stw r7, -7984(r1)
550 // stw r8, -7980(r1)
551 // stw r9, -7976(r1)
552 // stw r10,-7972(r1)
554 // # next save fpr 1 to fpr 13 (aligned to 8)
555 // stfd f1, -7968(r1)
556 // stfd f2, -7960(r1)
557 // stfd f3, -7952(r1)
558 // stfd f4, -7944(r1)
559 // stfd f5, -7936(r1)
560 // stfd f6, -7928(r1)
561 // stfd f7, -7920(r1)
562 // stfd f8, -7912(r1)
563 // stfd f9, -7904(r1)
564 // stfd f10,-7896(r1)
565 // stfd f11,-7888(r1)
566 // stfd f12,-7880(r1)
567 // stfd f13,-7872(r1)
569 // FIXME: ctr is volatile, while are we saving it and not CR?
570 // mfctr r3
571 // stw r3, -8004(r1)
573 // # now here is where cpp_vtable_call must go
574 // lis r3,0xdead
575 // ori r3,r3,0xbeef
576 // mtctr r3
578 // # now load up the functionIndex number
579 // lis r3, 0xdead
580 // ori r3,r3,0xbeef
582 // # now load up the vtableOffset
583 // lis r4, 0xdead
584 // ori r4,r4,0xbeef
586 // #now load up the pointer to the saved gpr registers
587 // addi r5,r1,-8000
589 // #now load up the pointer to the saved fpr registers
590 // addi r6,r1,-7968
592 // #now load up the pointer to the overflow call stack
593 // addi r7,r1,24 # frame pointer plus 24
595 // bctr
597 unsigned long * p = (unsigned long *) code;
599 * p++ = 0x9061e0c0;
600 * p++ = 0x9081e0c4;
601 * p++ = 0x90a1e0c8;
602 * p++ = 0x90c1e0cc;
603 * p++ = 0x90e1e0d0;
604 * p++ = 0x9101e0d4;
605 * p++ = 0x9121e0d8;
606 * p++ = 0x9141e0dc;
607 * p++ = 0xd821e0e0;
608 * p++ = 0xd841e0e8;
609 * p++ = 0xd861e0f0;
610 * p++ = 0xd881e0f8;
611 * p++ = 0xd8a1e100;
612 * p++ = 0xd8c1e108;
613 * p++ = 0xd8e1e110;
614 * p++ = 0xd901e118;
615 * p++ = 0xd921e120;
616 * p++ = 0xd941e128;
617 * p++ = 0xd961e130;
618 * p++ = 0xd981e138;
619 * p++ = 0xd9a1e140;
620 * p++ = 0x7c6902a6;
621 * p++ = 0x9061e0bc;
622 * p++ = 0x3c600000 | (((unsigned long)cpp_vtable_call) >> 16);
623 * p++ = 0x60630000 | (((unsigned long)cpp_vtable_call) & 0x0000FFFF);
624 * p++ = 0x7c6903a6;
625 * p++ = 0x3c600000 | (((unsigned long)functionIndex) >> 16);
626 * p++ = 0x60630000 | (((unsigned long)functionIndex) & 0x0000FFFF);
627 * p++ = 0x3c800000 | (((unsigned long)vtableOffset) >> 16);
628 * p++ = 0x60840000 | (((unsigned long)vtableOffset) & 0x0000FFFF);
629 * p++ = 0x38a1e0c0;
630 * p++ = 0x38c1e0e0;
631 * p++ = 0x38e10018;
632 * p++ = 0x4e800420;
634 return (code + codeSnippetSize);
641 void bridges::cpp_uno::shared::VtableFactory::flushCode(unsigned char const * bptr, unsigned char const * eptr)
643 int const lineSize = 32;
644 for (unsigned char const * p = bptr; p < eptr + lineSize; p += lineSize) {
645 __asm__ volatile ("dcbst 0, %0" : : "r"(p) : "memory");
647 __asm__ volatile ("sync" : : : "memory");
648 for (unsigned char const * p = bptr; p < eptr + lineSize; p += lineSize) {
649 __asm__ volatile ("icbi 0, %0" : : "r"(p) : "memory");
651 __asm__ volatile ("isync" : : : "memory");
654 struct bridges::cpp_uno::shared::VtableFactory::Slot { void * fn; };
656 bridges::cpp_uno::shared::VtableFactory::Slot *
657 bridges::cpp_uno::shared::VtableFactory::mapBlockToVtable(void * block)
659 return static_cast< Slot * >(block) + 2;
662 sal_Size bridges::cpp_uno::shared::VtableFactory::getBlockSize(
663 sal_Int32 slotCount)
665 return (slotCount + 2) * sizeof (Slot) + slotCount * codeSnippetSize;
668 bridges::cpp_uno::shared::VtableFactory::Slot *
669 bridges::cpp_uno::shared::VtableFactory::initializeBlock(
670 void * block, sal_Int32 slotCount)
672 Slot * slots = mapBlockToVtable(block);
673 slots[-2].fn = 0;
674 slots[-1].fn = 0;
675 return slots + slotCount;
678 unsigned char * bridges::cpp_uno::shared::VtableFactory::addLocalFunctions(
679 Slot ** slots, unsigned char * code,
680 typelib_InterfaceTypeDescription const * type, sal_Int32 functionOffset,
681 sal_Int32 functionCount, sal_Int32 vtableOffset)
683 (*slots) -= functionCount;
684 Slot * s = *slots;
686 // fprintf(stderr, "in addLocalFunctions functionOffset is %x\n",functionOffset);
687 // fprintf(stderr, "in addLocalFunctions vtableOffset is %x\n",vtableOffset);
688 // fflush(stderr);
690 for (sal_Int32 i = 0; i < type->nMembers; ++i) {
691 typelib_TypeDescription * member = 0;
692 TYPELIB_DANGER_GET(&member, type->ppMembers[i]);
693 OSL_ASSERT(member != 0);
694 switch (member->eTypeClass) {
695 case typelib_TypeClass_INTERFACE_ATTRIBUTE:
696 // Getter:
697 (s++)->fn = code;
698 code = codeSnippet(
699 code, functionOffset++, vtableOffset,
700 bridges::cpp_uno::shared::isSimpleType(
701 reinterpret_cast<
702 typelib_InterfaceAttributeTypeDescription * >(
703 member)->pAttributeTypeRef));
705 // Setter:
706 if (!reinterpret_cast<
707 typelib_InterfaceAttributeTypeDescription * >(
708 member)->bReadOnly)
710 (s++)->fn = code;
711 code = codeSnippet(code, functionOffset++, vtableOffset, true);
713 break;
715 case typelib_TypeClass_INTERFACE_METHOD:
716 (s++)->fn = code;
717 code = codeSnippet(
718 code, functionOffset++, vtableOffset,
719 bridges::cpp_uno::shared::isSimpleType(
720 reinterpret_cast<
721 typelib_InterfaceMethodTypeDescription * >(
722 member)->pReturnTypeRef));
723 break;
725 default:
726 OSL_ASSERT(false);
727 break;
729 TYPELIB_DANGER_RELEASE(member);
731 return code;