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 ************************************************************************/
28 #include <com/sun/star/uno/genfunc.hxx>
29 #include <typelib/typedescription.hxx>
31 #include <osl/endian.h>
32 #include "bridges/cpp_uno/shared/bridge.hxx"
33 #include "bridges/cpp_uno/shared/cppinterfaceproxy.hxx"
34 #include "bridges/cpp_uno/shared/types.hxx"
35 #include "bridges/cpp_uno/shared/vtablefactory.hxx"
41 using namespace com::sun::star::uno
;
46 #include <rtl/strbuf.hxx>
47 #include <rtl/ustrbuf.hxx>
48 #include <osl/diagnose.h>
49 #include <osl/mutex.hxx>
50 using namespace ::std
;
51 using namespace ::osl
;
52 using namespace ::rtl
;
54 #include <sys/sysmips.h>
57 #define IS_BIG_ENDIAN 1
59 #define IS_BIG_ENDIAN 0
62 using namespace ::com::sun::star::uno
;
67 //==================================================================================================
68 static typelib_TypeClass
cpp2uno_call(
69 bridges::cpp_uno::shared::CppInterfaceProxy
* pThis
,
70 const typelib_TypeDescription
* pMemberTypeDescr
,
71 typelib_TypeDescriptionReference
* pReturnTypeRef
, // 0 indicates void return
72 sal_Int32 nParams
, typelib_MethodParameter
* pParams
,
73 void ** gpreg
, void ** /*fpreg*/, void ** ovrflw
,
74 sal_Int64
* pRegisterReturn
/* space for register return */ )
76 /* Most MIPS ABIs view the arguments as a struct, of which the
77 first N words go in registers and the rest go on the stack. If I < N, the
78 Ith word might go in Ith integer argument register or the Ith
79 floating-point one. For these ABIs, we only need to remember the number
80 of words passed so far. We are interested only in o32 ABI,so it is the
83 int nw
= 0; // number of words used by arguments
86 fprintf(stderr
,"cpp2uno_call1\n");
89 /* C++ has [ret *] or this as the first arguments, so no arguments will
90 * be passed in floating-point registers?
92 //int int_seen = 0; // have we seen integer arguments?
94 void ** pCppStack
; //temporary stack pointer
96 // gpreg: [ret *], this, [gpr params]
97 // fpreg: [fpr params]
98 // ovrflw: [gpr or fpr params (properly aligned)]
101 typelib_TypeDescription
* pReturnTypeDescr
= 0;
103 TYPELIB_DANGER_GET( &pReturnTypeDescr
, pReturnTypeRef
);
105 void * pUnoReturn
= 0;
106 void * pCppReturn
= 0; // complex return ptr: if != 0 && != pUnoReturn, reconversion need
108 if (pReturnTypeDescr
)
110 if (bridges::cpp_uno::shared::isSimpleType( pReturnTypeDescr
))
112 pUnoReturn
= pRegisterReturn
; // direct way for simple types
114 fprintf(stderr
,"cpp2uno_call:simplereturn\n");
117 else // complex return via ptr (pCppReturn)
119 pCppReturn
= *(void **)gpreg
;
123 pUnoReturn
= (bridges::cpp_uno::shared::relatesToInterfaceType( pReturnTypeDescr
)
124 ? alloca( pReturnTypeDescr
->nSize
)
125 : pCppReturn
); // direct way
127 fprintf(stderr
,"cpp2uno_call:complexreturn\n");
137 OSL_ENSURE( sizeof(void *) == sizeof(sal_Int32
), "### unexpected size!" );
139 void ** pUnoArgs
= (void **)alloca( 4 * sizeof(void *) * nParams
);
140 void ** pCppArgs
= pUnoArgs
+ nParams
;
141 // indizes of values this have to be converted (interface conversion cpp<=>uno)
142 sal_Int32
* pTempIndizes
= (sal_Int32
*)(pUnoArgs
+ (2 * nParams
));
143 // type descriptions for reconversions
144 typelib_TypeDescription
** ppTempParamTypeDescr
= (typelib_TypeDescription
**)(pUnoArgs
+ (3 * nParams
));
146 sal_Int32 nTempIndizes
= 0;
149 fprintf(stderr
,"cpp2uno_call:nParams=%d\n",nParams
);
152 for ( sal_Int32 nPos
= 0; nPos
< nParams
; ++nPos
)
154 const typelib_MethodParameter
& rParam
= pParams
[nPos
];
155 typelib_TypeDescription
* pParamTypeDescr
= 0;
156 TYPELIB_DANGER_GET( &pParamTypeDescr
, rParam
.pTypeRef
);
158 if (!rParam
.bOut
&& bridges::cpp_uno::shared::isSimpleType( pParamTypeDescr
))
162 switch (pParamTypeDescr
->eTypeClass
)
164 case typelib_TypeClass_DOUBLE
:
165 case typelib_TypeClass_HYPER
:
166 case typelib_TypeClass_UNSIGNED_HYPER
:
168 fprintf(stderr
,"cpp2uno_call:hyper=%d,%p\n",pParamTypeDescr
->eTypeClass
,gpreg
[0]);
176 fprintf(stderr
,"cpp2uno_call:gpreg=%p,%p\n",gpreg
[0],gpreg
[1]);
178 pCppArgs
[nPos
] = gpreg
;
179 pUnoArgs
[nPos
] = gpreg
;
183 if (((long)ovrflw
) & 4) ovrflw
++;
185 fprintf(stderr
,"cpp2uno_call:overflw=%p,%p\n",ovrflw
[0],ovrflw
[1]);
187 pCppArgs
[nPos
] = ovrflw
;
188 pUnoArgs
[nPos
] = ovrflw
;
193 case typelib_TypeClass_BYTE
:
194 case typelib_TypeClass_BOOLEAN
:
196 fprintf(stderr
,"cpp2uno_call:byte=%p,%p\n",gpreg
[0],ovrflw
[0]);
199 pCppArgs
[nPos
] = ((char *)gpreg
+ 3*IS_BIG_ENDIAN
);
200 pUnoArgs
[nPos
] = ((char *)gpreg
+ 3*IS_BIG_ENDIAN
);
204 pCppArgs
[nPos
] = ((char *)ovrflw
+ 3*IS_BIG_ENDIAN
);
205 pUnoArgs
[nPos
] = ((char *)ovrflw
+ 3*IS_BIG_ENDIAN
);
211 case typelib_TypeClass_CHAR
:
212 case typelib_TypeClass_SHORT
:
213 case typelib_TypeClass_UNSIGNED_SHORT
:
215 fprintf(stderr
,"cpp2uno_call:char=%p,%p\n",gpreg
[0],ovrflw
[0]);
218 pCppArgs
[nPos
] = ((char *)gpreg
+ 2*IS_BIG_ENDIAN
);
219 pUnoArgs
[nPos
] = ((char *)gpreg
+ 2*IS_BIG_ENDIAN
);
223 pCppArgs
[nPos
] = ((char *)ovrflw
+ 2*IS_BIG_ENDIAN
);
224 pUnoArgs
[nPos
] = ((char *)ovrflw
+ 2*IS_BIG_ENDIAN
);
232 fprintf(stderr
,"cpp2uno_call:def=%p,%p\n",gpreg
[0],ovrflw
[0]);
235 pCppArgs
[nPos
] = gpreg
;
236 pUnoArgs
[nPos
] = gpreg
;
240 pCppArgs
[nPos
] = ovrflw
;
241 pUnoArgs
[nPos
] = ovrflw
;
248 TYPELIB_DANGER_RELEASE( pParamTypeDescr
);
250 else // ptr to complex value | ref
254 fprintf(stderr
,"cpp2uno_call:ptr|ref\n");
257 pCppArgs
[nPos
] = *(void **)gpreg
;
262 pCppArgs
[nPos
] = *(void **)ovrflw
;
267 fprintf(stderr
,"cpp2uno_call:pCppStack=%p\n",pCppStack
);
270 if (! rParam
.bIn
) // is pure out
272 // uno out is unconstructed mem!
273 pUnoArgs
[nPos
] = alloca( pParamTypeDescr
->nSize
);
274 pTempIndizes
[nTempIndizes
] = nPos
;
275 // will be released at reconversion
276 ppTempParamTypeDescr
[nTempIndizes
++] = pParamTypeDescr
;
279 else if (bridges::cpp_uno::shared::relatesToInterfaceType( pParamTypeDescr
))
281 uno_copyAndConvertData( pUnoArgs
[nPos
] = alloca( pParamTypeDescr
->nSize
),
282 *(void **)pCppStack
, pParamTypeDescr
,
283 pThis
->getBridge()->getCpp2Uno() );
284 pTempIndizes
[nTempIndizes
] = nPos
; // has to be reconverted
285 // will be released at reconversion
286 ppTempParamTypeDescr
[nTempIndizes
++] = pParamTypeDescr
;
288 fprintf(stderr
,"cpp2uno_call:related to interface,%p,%d,pUnoargs[%d]=%p\n",*(void**)pCppStack
,pParamTypeDescr
->nSize
,nPos
,pUnoArgs
[nPos
]);
293 pUnoArgs
[nPos
] = *(void **)pCppStack
;
295 fprintf(stderr
,"cpp2uno_call:direct,pUnoArgs[%d]=%p\n",nPos
,pUnoArgs
[nPos
]);
298 TYPELIB_DANGER_RELEASE( pParamTypeDescr
);
303 fprintf(stderr
,"cpp2uno_call2,%p,unoargs=%p\n",pThis
->getUnoI()->pDispatcher
,pUnoArgs
);
307 uno_Any aUnoExc
; // Any will be constructed by callee
308 uno_Any
* pUnoExc
= &aUnoExc
;
310 // invoke uno dispatch call
311 (*pThis
->getUnoI()->pDispatcher
)( pThis
->getUnoI(), pMemberTypeDescr
, pUnoReturn
, pUnoArgs
, &pUnoExc
);
313 fprintf(stderr
,"cpp2uno_call2,after dispatch\n");
316 // in case an exception occurred...
319 // destruct temporary in/inout params
320 for ( ; nTempIndizes
--; )
322 sal_Int32 nIndex
= pTempIndizes
[nTempIndizes
];
324 if (pParams
[nIndex
].bIn
) // is in/inout => was constructed
325 uno_destructData( pUnoArgs
[nIndex
], ppTempParamTypeDescr
[nTempIndizes
], 0 );
326 TYPELIB_DANGER_RELEASE( ppTempParamTypeDescr
[nTempIndizes
] );
328 if (pReturnTypeDescr
)
329 TYPELIB_DANGER_RELEASE( pReturnTypeDescr
);
331 CPPU_CURRENT_NAMESPACE::raiseException( &aUnoExc
, pThis
->getBridge()->getUno2Cpp() );
332 // has to destruct the any
334 return typelib_TypeClass_VOID
;
336 else // else no exception occurred...
339 for ( ; nTempIndizes
--; )
341 sal_Int32 nIndex
= pTempIndizes
[nTempIndizes
];
342 typelib_TypeDescription
* pParamTypeDescr
= ppTempParamTypeDescr
[nTempIndizes
];
344 if (pParams
[nIndex
].bOut
) // inout/out
346 // convert and assign
347 uno_destructData( pCppArgs
[nIndex
], pParamTypeDescr
, cpp_release
);
348 uno_copyAndConvertData( pCppArgs
[nIndex
], pUnoArgs
[nIndex
], pParamTypeDescr
,
349 pThis
->getBridge()->getUno2Cpp() );
351 // destroy temp uno param
352 uno_destructData( pUnoArgs
[nIndex
], pParamTypeDescr
, 0 );
354 TYPELIB_DANGER_RELEASE( pParamTypeDescr
);
357 if (pCppReturn
) // has complex return
359 if (pUnoReturn
!= pCppReturn
) // needs reconversion
361 uno_copyAndConvertData( pCppReturn
, pUnoReturn
, pReturnTypeDescr
,
362 pThis
->getBridge()->getUno2Cpp() );
363 // destroy temp uno return
364 uno_destructData( pUnoReturn
, pReturnTypeDescr
, 0 );
366 // complex return ptr is set to return reg
367 *(void **)pRegisterReturn
= pCppReturn
;
369 if (pReturnTypeDescr
)
371 typelib_TypeClass eRet
= (typelib_TypeClass
)pReturnTypeDescr
->eTypeClass
;
372 TYPELIB_DANGER_RELEASE( pReturnTypeDescr
);
376 return typelib_TypeClass_VOID
;
381 //==================================================================================================
382 static typelib_TypeClass
cpp_mediate(
383 sal_Int32 nFunctionIndex
,
384 sal_Int32 nVtableOffset
,
385 void ** gpreg
, void ** fpreg
, void ** ovrflw
,
386 sal_Int64
* pRegisterReturn
/* space for register return */ )
388 OSL_ENSURE( sizeof(sal_Int32
)==sizeof(void *), "### unexpected!" );
391 fprintf(stderr
,"cpp_mediate1 gp=%p,fp=%p,ov=%p\n",gpreg
,fpreg
,ovrflw
);
392 fprintf(stderr
,"gp=%x,%x,%x,%x\n",gpreg
[0],gpreg
[1],gpreg
[2],gpreg
[3]);
395 // gpreg: [ret *], this, [other gpr params]
396 // fpreg: [fpr params]
397 // ovrflw: [gpr or fpr params (properly aligned)]
400 if (nFunctionIndex
& 0x80000000 )
402 nFunctionIndex
&= 0x7fffffff;
410 fprintf(stderr
,"cpp_mediate12,pThis=%p, nFunctionIndex=%d,nVtableOffset=%d\n",pThis
,nFunctionIndex
,nVtableOffset
);
413 pThis
= static_cast< char * >(pThis
) - nVtableOffset
;
414 bridges::cpp_uno::shared::CppInterfaceProxy
* pCppI
415 = bridges::cpp_uno::shared::CppInterfaceProxy::castInterfaceToProxy(
418 fprintf(stderr
,"cpp_mediate13,pCppI=%p\n",pCppI
);
421 typelib_InterfaceTypeDescription
* pTypeDescr
= pCppI
->getTypeDescr();
424 fprintf(stderr
,"cpp_mediate2\n");
426 OSL_ENSURE( nFunctionIndex
< pTypeDescr
->nMapFunctionIndexToMemberIndex
, "### illegal vtable index!" );
427 if (nFunctionIndex
>= pTypeDescr
->nMapFunctionIndexToMemberIndex
)
429 throw RuntimeException(
430 rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "illegal vtable index!" )),
431 (XInterface
*)pThis
);
434 // determine called method
435 sal_Int32 nMemberPos
= pTypeDescr
->pMapFunctionIndexToMemberIndex
[nFunctionIndex
];
436 OSL_ENSURE( nMemberPos
< pTypeDescr
->nAllMembers
, "### illegal member index!" );
438 TypeDescription
aMemberDescr( pTypeDescr
->ppAllMembers
[nMemberPos
] );
441 fprintf(stderr
,"cpp_mediate3\n");
442 OString
cstr( OUStringToOString( aMemberDescr
.get()->pTypeName
, RTL_TEXTENCODING_ASCII_US
) );
443 fprintf( stderr
, "calling %s, nFunctionIndex=%d\n", cstr
.getStr(), nFunctionIndex
);
445 typelib_TypeClass eRet
;
446 switch (aMemberDescr
.get()->eTypeClass
)
448 case typelib_TypeClass_INTERFACE_ATTRIBUTE
:
451 fprintf(stderr
,"cpp_mediate4\n");
453 if (pTypeDescr
->pMapMemberIndexToFunctionIndex
[nMemberPos
] == nFunctionIndex
)
457 pCppI
, aMemberDescr
.get(),
458 ((typelib_InterfaceAttributeTypeDescription
*)aMemberDescr
.get())->pAttributeTypeRef
,
460 gpreg
, fpreg
, ovrflw
, pRegisterReturn
);
465 typelib_MethodParameter aParam
;
467 ((typelib_InterfaceAttributeTypeDescription
*)aMemberDescr
.get())->pAttributeTypeRef
;
468 aParam
.bIn
= sal_True
;
469 aParam
.bOut
= sal_False
;
472 pCppI
, aMemberDescr
.get(),
473 0, // indicates void return
475 gpreg
, fpreg
, ovrflw
, pRegisterReturn
);
479 case typelib_TypeClass_INTERFACE_METHOD
:
482 fprintf(stderr
,"cpp_mediate5\n");
485 switch (nFunctionIndex
)
488 pCppI
->acquireProxy(); // non virtual call!
489 eRet
= typelib_TypeClass_VOID
;
493 fprintf(stderr
,"cpp_mediate51\n");
495 pCppI
->releaseProxy(); // non virtual call!
496 eRet
= typelib_TypeClass_VOID
;
498 fprintf(stderr
,"cpp_mediate52\n");
501 case 0: // queryInterface() opt
503 typelib_TypeDescription
* pTD
= 0;
504 TYPELIB_DANGER_GET( &pTD
, reinterpret_cast< Type
* >( gpreg
[2] )->getTypeLibType() );
507 XInterface
* pInterface
= 0;
508 (*pCppI
->getBridge()->getCppEnv()->getRegisteredInterface
)(
509 pCppI
->getBridge()->getCppEnv(),
510 (void **)&pInterface
, pCppI
->getOid().pData
,
511 (typelib_InterfaceTypeDescription
*)pTD
);
516 reinterpret_cast< uno_Any
* >( gpreg
[0] ),
517 &pInterface
, pTD
, cpp_acquire
);
518 pInterface
->release();
519 TYPELIB_DANGER_RELEASE( pTD
);
520 *(void **)pRegisterReturn
= gpreg
[0];
521 eRet
= typelib_TypeClass_ANY
;
524 TYPELIB_DANGER_RELEASE( pTD
);
526 } // else perform queryInterface()
529 pCppI
, aMemberDescr
.get(),
530 ((typelib_InterfaceMethodTypeDescription
*)aMemberDescr
.get())->pReturnTypeRef
,
531 ((typelib_InterfaceMethodTypeDescription
*)aMemberDescr
.get())->nParams
,
532 ((typelib_InterfaceMethodTypeDescription
*)aMemberDescr
.get())->pParams
,
533 gpreg
, fpreg
, ovrflw
, pRegisterReturn
);
540 fprintf(stderr
,"cpp_mediate6\n");
542 throw RuntimeException(
543 rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "no member description found!" )),
544 (XInterface
*)pThis
);
551 //==================================================================================================
553 * is called on incoming vtable calls
554 * (called by asm snippets)
556 // static void cpp_vtable_call( int nFunctionIndex, int nVtableOffset, void** gpregptr, void** fpregptr, void** ovrflw)
557 // static void cpp_vtable_call( int nFunctionIndex, int nVtableOffset, void** gpregptr, void** ovrflw)
558 static void cpp_vtable_call(void)
568 //memcpy( fpreg, fpregptr, 16);
570 volatile long nRegReturn
[2];
572 __asm__( "sw $4, %0\n\t"
576 ::"m"(nFunctionIndex
), "m"(vTableOffset
), "m"(pCallStack
), "m"(ovrflw
) );
578 memcpy( gpreg
, pCallStack
, 16);
581 fprintf(stderr
,"in cpp_vtable_call nFunctionIndex is %d\n",nFunctionIndex
);
582 fprintf(stderr
,"in cpp_vtable_call nVtableOffset is %d\n",vTableOffset
);
583 fprintf(stderr
,"gp=%x,%x,%x,%x\n",gpreg
[0],gpreg
[1],gpreg
[2],gpreg
[3]);
586 //sal_Bool bComplex = nFunctionIndex & 0x80000000 ? sal_True : sal_False;
588 typelib_TypeClass aType
=
589 cpp_mediate( nFunctionIndex
, vTableOffset
, (void**)gpreg
, (void**)fpreg
, ovrflw
, (sal_Int64
*)nRegReturn
);
594 // move return value into register space
595 // (will be loaded by machine code snippet)
597 case typelib_TypeClass_BOOLEAN
:
598 case typelib_TypeClass_BYTE
:
599 __asm__( "lbu $2,%0\n\t" : :
600 "m"(nRegReturn
[0]) );
603 case typelib_TypeClass_CHAR
:
604 case typelib_TypeClass_UNSIGNED_SHORT
:
605 __asm__( "lhu $2,%0\n\t" : :
606 "m"(nRegReturn
[0]) );
609 case typelib_TypeClass_SHORT
:
610 __asm__( "lh $2,%0\n\t" : :
611 "m"(nRegReturn
[0]) );
615 case typelib_TypeClass_FLOAT
:
616 __asm__( "lwc1 $f0,%0\n\t" : :
617 "m" (*((float*)nRegReturn
)) );
620 case typelib_TypeClass_DOUBLE
:
621 { register double dret
asm("$f0");
622 dret
= (*((double*)nRegReturn
)); }
625 case typelib_TypeClass_HYPER
:
626 case typelib_TypeClass_UNSIGNED_HYPER
:
627 __asm__( "lw $3,%0\n\t" : :
628 "m"(nRegReturn
[1]) ); // fall through
631 __asm__( "lw $2,%0\n\t" : :
632 "m"(nRegReturn
[0]) );
638 int const codeSnippetSize
= 56;
640 unsigned char * codeSnippet( unsigned char * code
, sal_Int32 functionIndex
, sal_Int32 vtableOffset
,
645 fprintf(stderr
,"in codeSnippet functionIndex is %d\n", functionIndex
);
646 fprintf(stderr
,"in codeSnippet vtableOffset is %d\n", vtableOffset
);
650 if (! simpleRetType
)
651 functionIndex
|= 0x80000000;
653 unsigned long * p
= (unsigned long *) code
;
655 // OSL_ASSERT( sizeof (long) == 4 );
656 OSL_ASSERT((((unsigned long)code
) & 0x3) == 0 ); //aligned to 4 otherwise a mistake
658 /* generate this code */
660 #save regs into argument space required by mips abi
661 c: afa40000 sw a0,0(sp)
662 10: afa50004 sw a1,4(sp)
663 14: afa60008 sw a2,8(sp)
664 18: afa7000c sw a3,12(sp)
666 1c: 3c040000 lui a0,0x0
667 20: 34840000 ori a0,a0,0x0
669 24: 3c050000 lui a1,0x0
670 28: 34a50000 ori a1,a1,0x0
672 2c: 27a60000 addiu a2,sp,0
674 30: 27a70010 addiu a3,sp,16
675 #load cpp_vtable_call addr
676 34: 3c190000 lui t9,0x0
677 38: 37390000 ori t9,t9,0
678 #jmp to the function,note: we don't use jalr, that will destroy $ra
679 #but be sure to use t9! gp calculation depends on it
683 be careful, we use the argument space reserved by the caller to
684 write down regs. This can avoid the need to make use of arbitary far away
685 stack space or to allocate a function frame for this code snippet itself.
686 Since only functions with variable arguments will overwrite the space,
687 cpp_vtable_call should be safe.
688 ??? gcc seems change this behavior! cpp_vtable_call overwrite the space!
695 * p
++ = 0x3c040000 | ((functionIndex
>>16) & 0x0000ffff);
696 * p
++ = 0x34840000 | (functionIndex
& 0x0000ffff);
697 * p
++ = 0x3c050000 | ((vtableOffset
>>16) & 0x0000ffff);
698 * p
++ = 0x34a50000 | (vtableOffset
& 0x0000ffff);
701 * p
++ = 0x3c190000 | ((((unsigned long)cpp_vtable_call
) >> 16) & 0x0000ffff);
702 * p
++ = 0x37390000 | (((unsigned long)cpp_vtable_call
) & 0x0000FFFF);
705 return (code
+ codeSnippetSize
);
713 #define MIN_LINE_SIZE 32
715 void bridges::cpp_uno::shared::VtableFactory::flushCode(unsigned char const * /*bptr*/, unsigned char const * /*eptr*/)
717 sysmips(FLUSH_CACHE
,0,0,0);
720 struct bridges::cpp_uno::shared::VtableFactory::Slot
{ void * fn
; };
722 bridges::cpp_uno::shared::VtableFactory::Slot
*
723 bridges::cpp_uno::shared::VtableFactory::mapBlockToVtable(void * block
)
725 return static_cast< Slot
* >(block
) + 2;
729 sal_Size
bridges::cpp_uno::shared::VtableFactory::getBlockSize(
732 return (slotCount
+ 2) * sizeof (Slot
) + slotCount
* codeSnippetSize
;
735 bridges::cpp_uno::shared::VtableFactory::Slot
*
736 bridges::cpp_uno::shared::VtableFactory::initializeBlock(
737 void * block
, sal_Int32 slotCount
)
739 Slot
* slots
= mapBlockToVtable(block
);
740 slots
[-2].fn
= 0; //null
741 slots
[-1].fn
= 0; //destructor
742 return slots
+ slotCount
;
745 unsigned char * bridges::cpp_uno::shared::VtableFactory::addLocalFunctions(
746 Slot
** slots
, unsigned char * code
, sal_PtrDiff writetoexecdiff
,
747 typelib_InterfaceTypeDescription
const * type
, sal_Int32 functionOffset
,
748 sal_Int32 functionCount
, sal_Int32 vtableOffset
)
750 (*slots
) -= functionCount
;
753 fprintf(stderr
, "in addLocalFunctions functionOffset is %d\n",functionOffset
);
754 fprintf(stderr
, "in addLocalFunctions vtableOffset is %d\n",vtableOffset
);
755 fprintf(stderr
, "nMembers=%d\n",type
->nMembers
);
759 for (sal_Int32 i
= 0; i
< type
->nMembers
; ++i
) {
760 typelib_TypeDescription
* member
= 0;
761 TYPELIB_DANGER_GET(&member
, type
->ppMembers
[i
]);
762 OSL_ASSERT(member
!= 0);
763 switch (member
->eTypeClass
) {
764 case typelib_TypeClass_INTERFACE_ATTRIBUTE
:
766 (s
++)->fn
= code
+ writetoexecdiff
;
768 code
, functionOffset
++, vtableOffset
,
769 bridges::cpp_uno::shared::isSimpleType(
771 typelib_InterfaceAttributeTypeDescription
* >(
772 member
)->pAttributeTypeRef
));
775 if (!reinterpret_cast<
776 typelib_InterfaceAttributeTypeDescription
* >(
779 (s
++)->fn
= code
+ writetoexecdiff
;
780 code
= codeSnippet(code
, functionOffset
++, vtableOffset
, true);
784 case typelib_TypeClass_INTERFACE_METHOD
:
785 (s
++)->fn
= code
+ writetoexecdiff
;
787 code
, functionOffset
++, vtableOffset
,
788 bridges::cpp_uno::shared::isSimpleType(
790 typelib_InterfaceMethodTypeDescription
* >(
791 member
)->pReturnTypeRef
));
798 TYPELIB_DANGER_RELEASE(member
);
803 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */