1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: cpp2uno.cxx,v $
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 ************************************************************************/
30 #include <com/sun/star/uno/genfunc.hxx>
31 #include <typelib/typedescription.hxx>
33 #include <osl/endian.h>
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"
43 using namespace com::sun::star::uno
;
48 #include <rtl/strbuf.hxx>
49 #include <rtl/ustrbuf.hxx>
50 #include <osl/diagnose.h>
51 #include <osl/mutex.hxx>
52 using namespace ::std
;
53 using namespace ::osl
;
54 using namespace ::rtl
;
56 #include <sys/sysmips.h>
59 #define IS_BIG_ENDIAN 1
61 #define IS_BIG_ENDIAN 0
64 using namespace ::com::sun::star::uno
;
69 //==================================================================================================
70 static typelib_TypeClass
cpp2uno_call(
71 bridges::cpp_uno::shared::CppInterfaceProxy
* pThis
,
72 const typelib_TypeDescription
* pMemberTypeDescr
,
73 typelib_TypeDescriptionReference
* pReturnTypeRef
, // 0 indicates void return
74 sal_Int32 nParams
, typelib_MethodParameter
* pParams
,
75 void ** gpreg
, void ** /*fpreg*/, void ** ovrflw
,
76 sal_Int64
* pRegisterReturn
/* space for register return */ )
78 /* Most MIPS ABIs view the arguments as a struct, of which the
79 first N words go in registers and the rest go on the stack. If I < N, the
80 Ith word might go in Ith integer argument register or the Ith
81 floating-point one. For these ABIs, we only need to remember the number
82 of words passed so far. We are interested only in o32 ABI,so it is the
85 int nw
= 0; // number of words used by arguments
88 fprintf(stderr
,"cpp2uno_call1\n");
91 /* C++ has [ret *] or this as the first arguments, so no arguments will
92 * be passed in floating-point registers?
94 //int int_seen = 0; // have we seen integer arguments?
96 void ** pCppStack
; //temporary stack pointer
98 // gpreg: [ret *], this, [gpr params]
99 // fpreg: [fpr params]
100 // ovrflw: [gpr or fpr params (properly aligned)]
103 typelib_TypeDescription
* pReturnTypeDescr
= 0;
105 TYPELIB_DANGER_GET( &pReturnTypeDescr
, pReturnTypeRef
);
107 void * pUnoReturn
= 0;
108 void * pCppReturn
= 0; // complex return ptr: if != 0 && != pUnoReturn, reconversion need
110 if (pReturnTypeDescr
)
112 if (bridges::cpp_uno::shared::isSimpleType( pReturnTypeDescr
))
114 pUnoReturn
= pRegisterReturn
; // direct way for simple types
116 fprintf(stderr
,"cpp2uno_call:simplereturn\n");
119 else // complex return via ptr (pCppReturn)
121 pCppReturn
= *(void **)gpreg
;
125 pUnoReturn
= (bridges::cpp_uno::shared::relatesToInterfaceType( pReturnTypeDescr
)
126 ? alloca( pReturnTypeDescr
->nSize
)
127 : pCppReturn
); // direct way
129 fprintf(stderr
,"cpp2uno_call:complexreturn\n");
139 OSL_ENSURE( sizeof(void *) == sizeof(sal_Int32
), "### unexpected size!" );
141 void ** pUnoArgs
= (void **)alloca( 4 * sizeof(void *) * nParams
);
142 void ** pCppArgs
= pUnoArgs
+ nParams
;
143 // indizes of values this have to be converted (interface conversion cpp<=>uno)
144 sal_Int32
* pTempIndizes
= (sal_Int32
*)(pUnoArgs
+ (2 * nParams
));
145 // type descriptions for reconversions
146 typelib_TypeDescription
** ppTempParamTypeDescr
= (typelib_TypeDescription
**)(pUnoArgs
+ (3 * nParams
));
148 sal_Int32 nTempIndizes
= 0;
151 fprintf(stderr
,"cpp2uno_call:nParams=%d\n",nParams
);
154 for ( sal_Int32 nPos
= 0; nPos
< nParams
; ++nPos
)
156 const typelib_MethodParameter
& rParam
= pParams
[nPos
];
157 typelib_TypeDescription
* pParamTypeDescr
= 0;
158 TYPELIB_DANGER_GET( &pParamTypeDescr
, rParam
.pTypeRef
);
160 if (!rParam
.bOut
&& bridges::cpp_uno::shared::isSimpleType( pParamTypeDescr
))
164 switch (pParamTypeDescr
->eTypeClass
)
166 case typelib_TypeClass_DOUBLE
:
167 case typelib_TypeClass_HYPER
:
168 case typelib_TypeClass_UNSIGNED_HYPER
:
170 fprintf(stderr
,"cpp2uno_call:hyper=%d,%p\n",pParamTypeDescr
->eTypeClass
,gpreg
[0]);
178 fprintf(stderr
,"cpp2uno_call:gpreg=%p,%p\n",gpreg
[0],gpreg
[1]);
180 pCppArgs
[nPos
] = gpreg
;
181 pUnoArgs
[nPos
] = gpreg
;
185 if (((long)ovrflw
) & 4) ovrflw
++;
187 fprintf(stderr
,"cpp2uno_call:overflw=%p,%p\n",ovrflw
[0],ovrflw
[1]);
189 pCppArgs
[nPos
] = ovrflw
;
190 pUnoArgs
[nPos
] = ovrflw
;
195 case typelib_TypeClass_BYTE
:
196 case typelib_TypeClass_BOOLEAN
:
198 fprintf(stderr
,"cpp2uno_call:byte=%p,%p\n",gpreg
[0],ovrflw
[0]);
201 pCppArgs
[nPos
] = ((char *)gpreg
+ 3*IS_BIG_ENDIAN
);
202 pUnoArgs
[nPos
] = ((char *)gpreg
+ 3*IS_BIG_ENDIAN
);
206 pCppArgs
[nPos
] = ((char *)ovrflw
+ 3*IS_BIG_ENDIAN
);
207 pUnoArgs
[nPos
] = ((char *)ovrflw
+ 3*IS_BIG_ENDIAN
);
213 case typelib_TypeClass_CHAR
:
214 case typelib_TypeClass_SHORT
:
215 case typelib_TypeClass_UNSIGNED_SHORT
:
217 fprintf(stderr
,"cpp2uno_call:char=%p,%p\n",gpreg
[0],ovrflw
[0]);
220 pCppArgs
[nPos
] = ((char *)gpreg
+ 2*IS_BIG_ENDIAN
);
221 pUnoArgs
[nPos
] = ((char *)gpreg
+ 2*IS_BIG_ENDIAN
);
225 pCppArgs
[nPos
] = ((char *)ovrflw
+ 2*IS_BIG_ENDIAN
);
226 pUnoArgs
[nPos
] = ((char *)ovrflw
+ 2*IS_BIG_ENDIAN
);
234 fprintf(stderr
,"cpp2uno_call:def=%p,%p\n",gpreg
[0],ovrflw
[0]);
237 pCppArgs
[nPos
] = gpreg
;
238 pUnoArgs
[nPos
] = gpreg
;
242 pCppArgs
[nPos
] = ovrflw
;
243 pUnoArgs
[nPos
] = ovrflw
;
250 TYPELIB_DANGER_RELEASE( pParamTypeDescr
);
252 else // ptr to complex value | ref
256 fprintf(stderr
,"cpp2uno_call:ptr|ref\n");
259 pCppArgs
[nPos
] = *(void **)gpreg
;
264 pCppArgs
[nPos
] = *(void **)ovrflw
;
269 fprintf(stderr
,"cpp2uno_call:pCppStack=%p\n",pCppStack
);
272 if (! rParam
.bIn
) // is pure out
274 // uno out is unconstructed mem!
275 pUnoArgs
[nPos
] = alloca( pParamTypeDescr
->nSize
);
276 pTempIndizes
[nTempIndizes
] = nPos
;
277 // will be released at reconversion
278 ppTempParamTypeDescr
[nTempIndizes
++] = pParamTypeDescr
;
281 else if (bridges::cpp_uno::shared::relatesToInterfaceType( pParamTypeDescr
))
283 uno_copyAndConvertData( pUnoArgs
[nPos
] = alloca( pParamTypeDescr
->nSize
),
284 *(void **)pCppStack
, pParamTypeDescr
,
285 pThis
->getBridge()->getCpp2Uno() );
286 pTempIndizes
[nTempIndizes
] = nPos
; // has to be reconverted
287 // will be released at reconversion
288 ppTempParamTypeDescr
[nTempIndizes
++] = pParamTypeDescr
;
290 fprintf(stderr
,"cpp2uno_call:related to interface,%p,%d,pUnoargs[%d]=%p\n",*(void**)pCppStack
,pParamTypeDescr
->nSize
,nPos
,pUnoArgs
[nPos
]);
295 pUnoArgs
[nPos
] = *(void **)pCppStack
;
297 fprintf(stderr
,"cpp2uno_call:direct,pUnoArgs[%d]=%p\n",nPos
,pUnoArgs
[nPos
]);
300 TYPELIB_DANGER_RELEASE( pParamTypeDescr
);
305 fprintf(stderr
,"cpp2uno_call2,%p,unoargs=%p\n",pThis
->getUnoI()->pDispatcher
,pUnoArgs
);
309 uno_Any aUnoExc
; // Any will be constructed by callee
310 uno_Any
* pUnoExc
= &aUnoExc
;
312 // invoke uno dispatch call
313 (*pThis
->getUnoI()->pDispatcher
)( pThis
->getUnoI(), pMemberTypeDescr
, pUnoReturn
, pUnoArgs
, &pUnoExc
);
315 fprintf(stderr
,"cpp2uno_call2,after dispatch\n");
318 // in case an exception occured...
321 // destruct temporary in/inout params
322 for ( ; nTempIndizes
--; )
324 sal_Int32 nIndex
= pTempIndizes
[nTempIndizes
];
326 if (pParams
[nIndex
].bIn
) // is in/inout => was constructed
327 uno_destructData( pUnoArgs
[nIndex
], ppTempParamTypeDescr
[nTempIndizes
], 0 );
328 TYPELIB_DANGER_RELEASE( ppTempParamTypeDescr
[nTempIndizes
] );
330 if (pReturnTypeDescr
)
331 TYPELIB_DANGER_RELEASE( pReturnTypeDescr
);
333 CPPU_CURRENT_NAMESPACE::raiseException( &aUnoExc
, pThis
->getBridge()->getUno2Cpp() );
334 // has to destruct the any
336 return typelib_TypeClass_VOID
;
338 else // else no exception occured...
341 for ( ; nTempIndizes
--; )
343 sal_Int32 nIndex
= pTempIndizes
[nTempIndizes
];
344 typelib_TypeDescription
* pParamTypeDescr
= ppTempParamTypeDescr
[nTempIndizes
];
346 if (pParams
[nIndex
].bOut
) // inout/out
348 // convert and assign
349 uno_destructData( pCppArgs
[nIndex
], pParamTypeDescr
, cpp_release
);
350 uno_copyAndConvertData( pCppArgs
[nIndex
], pUnoArgs
[nIndex
], pParamTypeDescr
,
351 pThis
->getBridge()->getUno2Cpp() );
353 // destroy temp uno param
354 uno_destructData( pUnoArgs
[nIndex
], pParamTypeDescr
, 0 );
356 TYPELIB_DANGER_RELEASE( pParamTypeDescr
);
359 if (pCppReturn
) // has complex return
361 if (pUnoReturn
!= pCppReturn
) // needs reconversion
363 uno_copyAndConvertData( pCppReturn
, pUnoReturn
, pReturnTypeDescr
,
364 pThis
->getBridge()->getUno2Cpp() );
365 // destroy temp uno return
366 uno_destructData( pUnoReturn
, pReturnTypeDescr
, 0 );
368 // complex return ptr is set to return reg
369 *(void **)pRegisterReturn
= pCppReturn
;
371 if (pReturnTypeDescr
)
373 typelib_TypeClass eRet
= (typelib_TypeClass
)pReturnTypeDescr
->eTypeClass
;
374 TYPELIB_DANGER_RELEASE( pReturnTypeDescr
);
378 return typelib_TypeClass_VOID
;
383 //==================================================================================================
384 static typelib_TypeClass
cpp_mediate(
385 sal_Int32 nFunctionIndex
,
386 sal_Int32 nVtableOffset
,
387 void ** gpreg
, void ** fpreg
, void ** ovrflw
,
388 sal_Int64
* pRegisterReturn
/* space for register return */ )
390 OSL_ENSURE( sizeof(sal_Int32
)==sizeof(void *), "### unexpected!" );
393 fprintf(stderr
,"cpp_mediate1 gp=%p,fp=%p,ov=%p\n",gpreg
,fpreg
,ovrflw
);
394 fprintf(stderr
,"gp=%x,%x,%x,%x\n",gpreg
[0],gpreg
[1],gpreg
[2],gpreg
[3]);
397 // gpreg: [ret *], this, [other gpr params]
398 // fpreg: [fpr params]
399 // ovrflw: [gpr or fpr params (properly aligned)]
402 if (nFunctionIndex
& 0x80000000 )
404 nFunctionIndex
&= 0x7fffffff;
412 fprintf(stderr
,"cpp_mediate12,pThis=%p, nFunctionIndex=%d,nVtableOffset=%d\n",pThis
,nFunctionIndex
,nVtableOffset
);
415 pThis
= static_cast< char * >(pThis
) - nVtableOffset
;
416 bridges::cpp_uno::shared::CppInterfaceProxy
* pCppI
417 = bridges::cpp_uno::shared::CppInterfaceProxy::castInterfaceToProxy(
420 fprintf(stderr
,"cpp_mediate13,pCppI=%p\n",pCppI
);
423 typelib_InterfaceTypeDescription
* pTypeDescr
= pCppI
->getTypeDescr();
426 fprintf(stderr
,"cpp_mediate2\n");
428 OSL_ENSURE( nFunctionIndex
< pTypeDescr
->nMapFunctionIndexToMemberIndex
, "### illegal vtable index!" );
429 if (nFunctionIndex
>= pTypeDescr
->nMapFunctionIndexToMemberIndex
)
431 throw RuntimeException(
432 rtl::OUString::createFromAscii("illegal vtable index!"),
433 (XInterface
*)pThis
);
436 // determine called method
437 sal_Int32 nMemberPos
= pTypeDescr
->pMapFunctionIndexToMemberIndex
[nFunctionIndex
];
438 OSL_ENSURE( nMemberPos
< pTypeDescr
->nAllMembers
, "### illegal member index!" );
440 TypeDescription
aMemberDescr( pTypeDescr
->ppAllMembers
[nMemberPos
] );
443 fprintf(stderr
,"cpp_mediate3\n");
444 OString
cstr( OUStringToOString( aMemberDescr
.get()->pTypeName
, RTL_TEXTENCODING_ASCII_US
) );
445 fprintf( stderr
, "calling %s, nFunctionIndex=%d\n", cstr
.getStr(), nFunctionIndex
);
447 typelib_TypeClass eRet
;
448 switch (aMemberDescr
.get()->eTypeClass
)
450 case typelib_TypeClass_INTERFACE_ATTRIBUTE
:
453 fprintf(stderr
,"cpp_mediate4\n");
455 if (pTypeDescr
->pMapMemberIndexToFunctionIndex
[nMemberPos
] == nFunctionIndex
)
459 pCppI
, aMemberDescr
.get(),
460 ((typelib_InterfaceAttributeTypeDescription
*)aMemberDescr
.get())->pAttributeTypeRef
,
462 gpreg
, fpreg
, ovrflw
, pRegisterReturn
);
467 typelib_MethodParameter aParam
;
469 ((typelib_InterfaceAttributeTypeDescription
*)aMemberDescr
.get())->pAttributeTypeRef
;
470 aParam
.bIn
= sal_True
;
471 aParam
.bOut
= sal_False
;
474 pCppI
, aMemberDescr
.get(),
475 0, // indicates void return
477 gpreg
, fpreg
, ovrflw
, pRegisterReturn
);
481 case typelib_TypeClass_INTERFACE_METHOD
:
484 fprintf(stderr
,"cpp_mediate5\n");
487 switch (nFunctionIndex
)
490 pCppI
->acquireProxy(); // non virtual call!
491 eRet
= typelib_TypeClass_VOID
;
495 fprintf(stderr
,"cpp_mediate51\n");
497 pCppI
->releaseProxy(); // non virtual call!
498 eRet
= typelib_TypeClass_VOID
;
500 fprintf(stderr
,"cpp_mediate52\n");
503 case 0: // queryInterface() opt
505 typelib_TypeDescription
* pTD
= 0;
506 TYPELIB_DANGER_GET( &pTD
, reinterpret_cast< Type
* >( gpreg
[2] )->getTypeLibType() );
509 XInterface
* pInterface
= 0;
510 (*pCppI
->getBridge()->getCppEnv()->getRegisteredInterface
)(
511 pCppI
->getBridge()->getCppEnv(),
512 (void **)&pInterface
, pCppI
->getOid().pData
,
513 (typelib_InterfaceTypeDescription
*)pTD
);
518 reinterpret_cast< uno_Any
* >( gpreg
[0] ),
519 &pInterface
, pTD
, cpp_acquire
);
520 pInterface
->release();
521 TYPELIB_DANGER_RELEASE( pTD
);
522 *(void **)pRegisterReturn
= gpreg
[0];
523 eRet
= typelib_TypeClass_ANY
;
526 TYPELIB_DANGER_RELEASE( pTD
);
528 } // else perform queryInterface()
531 pCppI
, aMemberDescr
.get(),
532 ((typelib_InterfaceMethodTypeDescription
*)aMemberDescr
.get())->pReturnTypeRef
,
533 ((typelib_InterfaceMethodTypeDescription
*)aMemberDescr
.get())->nParams
,
534 ((typelib_InterfaceMethodTypeDescription
*)aMemberDescr
.get())->pParams
,
535 gpreg
, fpreg
, ovrflw
, pRegisterReturn
);
542 fprintf(stderr
,"cpp_mediate6\n");
544 throw RuntimeException(
545 rtl::OUString::createFromAscii("no member description found!"),
546 (XInterface
*)pThis
);
548 eRet
= typelib_TypeClass_VOID
;
555 //==================================================================================================
557 * is called on incoming vtable calls
558 * (called by asm snippets)
560 // static void cpp_vtable_call( int nFunctionIndex, int nVtableOffset, void** gpregptr, void** fpregptr, void** ovrflw)
561 // static void cpp_vtable_call( int nFunctionIndex, int nVtableOffset, void** gpregptr, void** ovrflw)
562 static void cpp_vtable_call(void)
572 //memcpy( fpreg, fpregptr, 16);
574 volatile long nRegReturn
[2];
576 __asm__( "sw $4, %0\n\t"
580 ::"m"(nFunctionIndex
), "m"(vTableOffset
), "m"(pCallStack
), "m"(ovrflw
) );
582 memcpy( gpreg
, pCallStack
, 16);
585 fprintf(stderr
,"in cpp_vtable_call nFunctionIndex is %d\n",nFunctionIndex
);
586 fprintf(stderr
,"in cpp_vtable_call nVtableOffset is %d\n",vTableOffset
);
587 fprintf(stderr
,"gp=%x,%x,%x,%x\n",gpreg
[0],gpreg
[1],gpreg
[2],gpreg
[3]);
590 //sal_Bool bComplex = nFunctionIndex & 0x80000000 ? sal_True : sal_False;
592 typelib_TypeClass aType
=
593 cpp_mediate( nFunctionIndex
, vTableOffset
, (void**)gpreg
, (void**)fpreg
, ovrflw
, (sal_Int64
*)nRegReturn
);
598 // move return value into register space
599 // (will be loaded by machine code snippet)
601 case typelib_TypeClass_BOOLEAN
:
602 case typelib_TypeClass_BYTE
:
603 __asm__( "lbu $2,%0\n\t" : :
604 "m"(nRegReturn
[0]) );
607 case typelib_TypeClass_CHAR
:
608 case typelib_TypeClass_UNSIGNED_SHORT
:
609 __asm__( "lhu $2,%0\n\t" : :
610 "m"(nRegReturn
[0]) );
613 case typelib_TypeClass_SHORT
:
614 __asm__( "lh $2,%0\n\t" : :
615 "m"(nRegReturn
[0]) );
619 case typelib_TypeClass_FLOAT
:
620 __asm__( "lwc1 $f0,%0\n\t" : :
621 "m" (*((float*)nRegReturn
)) );
624 case typelib_TypeClass_DOUBLE
:
625 { register double dret
asm("$f0");
626 dret
= (*((double*)nRegReturn
)); }
629 case typelib_TypeClass_HYPER
:
630 case typelib_TypeClass_UNSIGNED_HYPER
:
631 __asm__( "lw $3,%0\n\t" : :
632 "m"(nRegReturn
[1]) ); // fall through
635 __asm__( "lw $2,%0\n\t" : :
636 "m"(nRegReturn
[0]) );
642 int const codeSnippetSize
= 56;
644 unsigned char * codeSnippet( unsigned char * code
, sal_Int32 functionIndex
, sal_Int32 vtableOffset
,
649 fprintf(stderr
,"in codeSnippet functionIndex is %d\n", functionIndex
);
650 fprintf(stderr
,"in codeSnippet vtableOffset is %d\n", vtableOffset
);
654 if (! simpleRetType
)
655 functionIndex
|= 0x80000000;
657 unsigned long * p
= (unsigned long *) code
;
659 // OSL_ASSERT( sizeof (long) == 4 );
660 OSL_ASSERT((((unsigned long)code
) & 0x3) == 0 ); //aligned to 4 otherwise a mistake
662 /* generate this code */
664 #save regs into argument space required by mips abi
665 c: afa40000 sw a0,0(sp)
666 10: afa50004 sw a1,4(sp)
667 14: afa60008 sw a2,8(sp)
668 18: afa7000c sw a3,12(sp)
670 1c: 3c040000 lui a0,0x0
671 20: 34840000 ori a0,a0,0x0
673 24: 3c050000 lui a1,0x0
674 28: 34a50000 ori a1,a1,0x0
676 2c: 27a60000 addiu a2,sp,0
678 30: 27a70010 addiu a3,sp,16
679 #load cpp_vtable_call addr
680 34: 3c190000 lui t9,0x0
681 38: 37390000 ori t9,t9,0
682 #jmp to the function,note: we don't use jalr, that will destroy $ra
683 #but be sure to use t9! gp calculation depends on it
687 be careful, we use the argument space reserved by the caller to
688 write down regs. This can avoid the need to make use of arbitary far away
689 stack space or to allocate a function frame for this code snippet itself.
690 Since only functions with variable arguments will overwrite the space,
691 cpp_vtable_call should be safe.
692 ??? gcc seems change this behavior! cpp_vtable_call overwrite the space!
699 * p
++ = 0x3c040000 | ((functionIndex
>>16) & 0x0000ffff);
700 * p
++ = 0x34840000 | (functionIndex
& 0x0000ffff);
701 * p
++ = 0x3c050000 | ((vtableOffset
>>16) & 0x0000ffff);
702 * p
++ = 0x34a50000 | (vtableOffset
& 0x0000ffff);
705 * p
++ = 0x3c190000 | ((((unsigned long)cpp_vtable_call
) >> 16) & 0x0000ffff);
706 * p
++ = 0x37390000 | (((unsigned long)cpp_vtable_call
) & 0x0000FFFF);
709 return (code
+ codeSnippetSize
);
717 #define MIN_LINE_SIZE 32
719 void bridges::cpp_uno::shared::VtableFactory::flushCode(unsigned char const * /*bptr*/, unsigned char const * /*eptr*/)
721 sysmips(FLUSH_CACHE
,0,0,0);
724 struct bridges::cpp_uno::shared::VtableFactory::Slot
{ void * fn
; };
726 bridges::cpp_uno::shared::VtableFactory::Slot
*
727 bridges::cpp_uno::shared::VtableFactory::mapBlockToVtable(void * block
)
729 return static_cast< Slot
* >(block
) + 2;
733 sal_Size
bridges::cpp_uno::shared::VtableFactory::getBlockSize(
736 return (slotCount
+ 2) * sizeof (Slot
) + slotCount
* codeSnippetSize
;
739 bridges::cpp_uno::shared::VtableFactory::Slot
*
740 bridges::cpp_uno::shared::VtableFactory::initializeBlock(
741 void * block
, sal_Int32 slotCount
)
743 Slot
* slots
= mapBlockToVtable(block
);
744 slots
[-2].fn
= 0; //null
745 slots
[-1].fn
= 0; //destructor
746 return slots
+ slotCount
;
749 unsigned char * bridges::cpp_uno::shared::VtableFactory::addLocalFunctions(
750 Slot
** slots
, unsigned char * code
, sal_PtrDiff writetoexecdiff
,
751 typelib_InterfaceTypeDescription
const * type
, sal_Int32 functionOffset
,
752 sal_Int32 functionCount
, sal_Int32 vtableOffset
)
754 (*slots
) -= functionCount
;
757 fprintf(stderr
, "in addLocalFunctions functionOffset is %d\n",functionOffset
);
758 fprintf(stderr
, "in addLocalFunctions vtableOffset is %d\n",vtableOffset
);
759 fprintf(stderr
, "nMembers=%d\n",type
->nMembers
);
763 for (sal_Int32 i
= 0; i
< type
->nMembers
; ++i
) {
764 typelib_TypeDescription
* member
= 0;
765 TYPELIB_DANGER_GET(&member
, type
->ppMembers
[i
]);
766 OSL_ASSERT(member
!= 0);
767 switch (member
->eTypeClass
) {
768 case typelib_TypeClass_INTERFACE_ATTRIBUTE
:
770 (s
++)->fn
= code
+ writetoexecdiff
;
772 code
, functionOffset
++, vtableOffset
,
773 bridges::cpp_uno::shared::isSimpleType(
775 typelib_InterfaceAttributeTypeDescription
* >(
776 member
)->pAttributeTypeRef
));
779 if (!reinterpret_cast<
780 typelib_InterfaceAttributeTypeDescription
* >(
783 (s
++)->fn
= code
+ writetoexecdiff
;
784 code
= codeSnippet(code
, functionOffset
++, vtableOffset
, true);
788 case typelib_TypeClass_INTERFACE_METHOD
:
789 (s
++)->fn
= code
+ writetoexecdiff
;
791 code
, functionOffset
++, vtableOffset
,
792 bridges::cpp_uno::shared::isSimpleType(
794 typelib_InterfaceMethodTypeDescription
* >(
795 member
)->pReturnTypeRef
));
802 TYPELIB_DANGER_RELEASE(member
);