1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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>
23 #include <osl/endian.h>
25 #include "cppinterfaceproxy.hxx"
27 #include "vtablefactory.hxx"
34 using namespace com::sun::star::uno
;
39 #include <rtl/strbuf.hxx>
40 #include <rtl/ustrbuf.hxx>
41 using namespace ::std
;
42 using namespace ::osl
;
43 using namespace ::rtl
;
47 #include <sys/sysmips.h>
55 #define IS_BIG_ENDIAN 1
57 #define IS_BIG_ENDIAN 0
63 static typelib_TypeClass
cpp2uno_call(
64 bridges::cpp_uno::shared::CppInterfaceProxy
* pThis
,
65 const typelib_TypeDescription
* pMemberTypeDescr
,
66 typelib_TypeDescriptionReference
* pReturnTypeRef
, // 0 indicates void return
67 sal_Int32 nParams
, typelib_MethodParameter
* pParams
,
68 void ** gpreg
, void ** /*fpreg*/, void ** ovrflw
,
69 sal_Int64
* pRegisterReturn
/* space for register return */ )
71 /* Most MIPS ABIs view the arguments as a struct, of which the
72 first N words go in registers and the rest go on the stack. If I < N, the
73 Ith word might go in Ith integer argument register or the Ith
74 floating-point one. For these ABIs, we only need to remember the number
75 of words passed so far. We are interested only in o32 ABI,so it is the
78 int nw
= 0; // number of words used by arguments
81 fprintf(stderr
,"cpp2uno_call1\n");
84 /* C++ has [ret *] or this as the first arguments, so no arguments will
85 * be passed in floating-point registers?
87 //int int_seen = 0; // have we seen integer arguments?
89 void ** pCppStack
; //temporary stack pointer
91 // gpreg: [ret *], this, [gpr params]
92 // fpreg: [fpr params]
93 // ovrflw: [gpr or fpr params (properly aligned)]
96 typelib_TypeDescription
* pReturnTypeDescr
= 0;
98 TYPELIB_DANGER_GET( &pReturnTypeDescr
, pReturnTypeRef
);
100 void * pUnoReturn
= 0;
101 void * pCppReturn
= 0; // complex return ptr: if != 0 && != pUnoReturn, reconversion need
103 if (pReturnTypeDescr
)
105 if (bridges::cpp_uno::shared::isSimpleType( pReturnTypeDescr
))
107 pUnoReturn
= pRegisterReturn
; // direct way for simple types
109 fprintf(stderr
,"cpp2uno_call:simplereturn\n");
112 else // complex return via ptr (pCppReturn)
114 pCppReturn
= *(void **)gpreg
;
118 pUnoReturn
= (bridges::cpp_uno::shared::relatesToInterfaceType( pReturnTypeDescr
)
119 ? alloca( pReturnTypeDescr
->nSize
)
120 : pCppReturn
); // direct way
122 fprintf(stderr
,"cpp2uno_call:complexreturn\n");
132 static_assert(sizeof(void *) == sizeof(sal_Int32
), "### unexpected size!");
134 void ** pUnoArgs
= (void **)alloca( 4 * sizeof(void *) * nParams
);
135 void ** pCppArgs
= pUnoArgs
+ nParams
;
136 // indices of values this have to be converted (interface conversion cpp<=>uno)
137 sal_Int32
* pTempIndices
= (sal_Int32
*)(pUnoArgs
+ (2 * nParams
));
138 // type descriptions for reconversions
139 typelib_TypeDescription
** ppTempParamTypeDescr
= (typelib_TypeDescription
**)(pUnoArgs
+ (3 * nParams
));
141 sal_Int32 nTempIndices
= 0;
144 fprintf(stderr
,"cpp2uno_call:nParams=%d\n",nParams
);
147 for ( sal_Int32 nPos
= 0; nPos
< nParams
; ++nPos
)
149 const typelib_MethodParameter
& rParam
= pParams
[nPos
];
150 typelib_TypeDescription
* pParamTypeDescr
= 0;
151 TYPELIB_DANGER_GET( &pParamTypeDescr
, rParam
.pTypeRef
);
153 if (!rParam
.bOut
&& bridges::cpp_uno::shared::isSimpleType( pParamTypeDescr
))
157 switch (pParamTypeDescr
->eTypeClass
)
159 case typelib_TypeClass_DOUBLE
:
160 case typelib_TypeClass_HYPER
:
161 case typelib_TypeClass_UNSIGNED_HYPER
:
163 fprintf(stderr
,"cpp2uno_call:hyper=%d,%p\n",pParamTypeDescr
->eTypeClass
,gpreg
[0]);
171 fprintf(stderr
,"cpp2uno_call:gpreg=%p,%p\n",gpreg
[0],gpreg
[1]);
173 pCppArgs
[nPos
] = gpreg
;
174 pUnoArgs
[nPos
] = gpreg
;
178 if (((long)ovrflw
) & 4) ovrflw
++;
180 fprintf(stderr
,"cpp2uno_call:overflw=%p,%p\n",ovrflw
[0],ovrflw
[1]);
182 pCppArgs
[nPos
] = ovrflw
;
183 pUnoArgs
[nPos
] = ovrflw
;
188 case typelib_TypeClass_BYTE
:
189 case typelib_TypeClass_BOOLEAN
:
191 fprintf(stderr
,"cpp2uno_call:byte=%p,%p\n",gpreg
[0],ovrflw
[0]);
194 pCppArgs
[nPos
] = ((char *)gpreg
+ 3*IS_BIG_ENDIAN
);
195 pUnoArgs
[nPos
] = ((char *)gpreg
+ 3*IS_BIG_ENDIAN
);
199 pCppArgs
[nPos
] = ((char *)ovrflw
+ 3*IS_BIG_ENDIAN
);
200 pUnoArgs
[nPos
] = ((char *)ovrflw
+ 3*IS_BIG_ENDIAN
);
206 case typelib_TypeClass_CHAR
:
207 case typelib_TypeClass_SHORT
:
208 case typelib_TypeClass_UNSIGNED_SHORT
:
210 fprintf(stderr
,"cpp2uno_call:char=%p,%p\n",gpreg
[0],ovrflw
[0]);
213 pCppArgs
[nPos
] = ((char *)gpreg
+ 2*IS_BIG_ENDIAN
);
214 pUnoArgs
[nPos
] = ((char *)gpreg
+ 2*IS_BIG_ENDIAN
);
218 pCppArgs
[nPos
] = ((char *)ovrflw
+ 2*IS_BIG_ENDIAN
);
219 pUnoArgs
[nPos
] = ((char *)ovrflw
+ 2*IS_BIG_ENDIAN
);
227 fprintf(stderr
,"cpp2uno_call:def=%p,%p\n",gpreg
[0],ovrflw
[0]);
230 pCppArgs
[nPos
] = gpreg
;
231 pUnoArgs
[nPos
] = gpreg
;
235 pCppArgs
[nPos
] = ovrflw
;
236 pUnoArgs
[nPos
] = ovrflw
;
243 TYPELIB_DANGER_RELEASE( pParamTypeDescr
);
245 else // ptr to complex value | ref
249 fprintf(stderr
,"cpp2uno_call:ptr|ref\n");
252 pCppArgs
[nPos
] = *(void **)gpreg
;
257 pCppArgs
[nPos
] = *(void **)ovrflw
;
262 fprintf(stderr
,"cpp2uno_call:pCppStack=%p\n",pCppStack
);
265 if (! rParam
.bIn
) // is pure out
267 // uno out is unconstructed mem!
268 pUnoArgs
[nPos
] = alloca( pParamTypeDescr
->nSize
);
269 pTempIndices
[nTempIndices
] = nPos
;
270 // will be released at reconversion
271 ppTempParamTypeDescr
[nTempIndices
++] = pParamTypeDescr
;
274 else if (bridges::cpp_uno::shared::relatesToInterfaceType( pParamTypeDescr
))
276 uno_copyAndConvertData( pUnoArgs
[nPos
] = alloca( pParamTypeDescr
->nSize
),
277 *(void **)pCppStack
, pParamTypeDescr
,
278 pThis
->getBridge()->getCpp2Uno() );
279 pTempIndices
[nTempIndices
] = nPos
; // has to be reconverted
280 // will be released at reconversion
281 ppTempParamTypeDescr
[nTempIndices
++] = pParamTypeDescr
;
283 fprintf(stderr
,"cpp2uno_call:related to interface,%p,%d,pUnoargs[%d]=%p\n",*(void**)pCppStack
,pParamTypeDescr
->nSize
,nPos
,pUnoArgs
[nPos
]);
288 pUnoArgs
[nPos
] = *(void **)pCppStack
;
290 fprintf(stderr
,"cpp2uno_call:direct,pUnoArgs[%d]=%p\n",nPos
,pUnoArgs
[nPos
]);
293 TYPELIB_DANGER_RELEASE( pParamTypeDescr
);
298 fprintf(stderr
,"cpp2uno_call2,%p,unoargs=%p\n",pThis
->getUnoI()->pDispatcher
,pUnoArgs
);
302 uno_Any aUnoExc
; // Any will be constructed by callee
303 uno_Any
* pUnoExc
= &aUnoExc
;
305 // invoke uno dispatch call
306 (*pThis
->getUnoI()->pDispatcher
)( pThis
->getUnoI(), pMemberTypeDescr
, pUnoReturn
, pUnoArgs
, &pUnoExc
);
308 fprintf(stderr
,"cpp2uno_call2,after dispatch\n");
311 // in case an exception occurred...
314 // destruct temporary in/inout params
315 for ( ; nTempIndices
--; )
317 sal_Int32 nIndex
= pTempIndices
[nTempIndices
];
319 if (pParams
[nIndex
].bIn
) // is in/inout => was constructed
320 uno_destructData( pUnoArgs
[nIndex
], ppTempParamTypeDescr
[nTempIndices
], 0 );
321 TYPELIB_DANGER_RELEASE( ppTempParamTypeDescr
[nTempIndices
] );
323 if (pReturnTypeDescr
)
324 TYPELIB_DANGER_RELEASE( pReturnTypeDescr
);
326 CPPU_CURRENT_NAMESPACE::raiseException( &aUnoExc
, pThis
->getBridge()->getUno2Cpp() );
327 // has to destruct the any
329 return typelib_TypeClass_VOID
;
331 else // else no exception occurred...
334 for ( ; nTempIndices
--; )
336 sal_Int32 nIndex
= pTempIndices
[nTempIndices
];
337 typelib_TypeDescription
* pParamTypeDescr
= ppTempParamTypeDescr
[nTempIndices
];
339 if (pParams
[nIndex
].bOut
) // inout/out
341 // convert and assign
342 uno_destructData( pCppArgs
[nIndex
], pParamTypeDescr
, cpp_release
);
343 uno_copyAndConvertData( pCppArgs
[nIndex
], pUnoArgs
[nIndex
], pParamTypeDescr
,
344 pThis
->getBridge()->getUno2Cpp() );
346 // destroy temp uno param
347 uno_destructData( pUnoArgs
[nIndex
], pParamTypeDescr
, 0 );
349 TYPELIB_DANGER_RELEASE( pParamTypeDescr
);
352 if (pCppReturn
) // has complex return
354 if (pUnoReturn
!= pCppReturn
) // needs reconversion
356 uno_copyAndConvertData( pCppReturn
, pUnoReturn
, pReturnTypeDescr
,
357 pThis
->getBridge()->getUno2Cpp() );
358 // destroy temp uno return
359 uno_destructData( pUnoReturn
, pReturnTypeDescr
, 0 );
361 // complex return ptr is set to return reg
362 *(void **)pRegisterReturn
= pCppReturn
;
364 if (pReturnTypeDescr
)
366 typelib_TypeClass eRet
= (typelib_TypeClass
)pReturnTypeDescr
->eTypeClass
;
367 TYPELIB_DANGER_RELEASE( pReturnTypeDescr
);
371 return typelib_TypeClass_VOID
;
376 static typelib_TypeClass
cpp_mediate(
377 sal_Int32 nFunctionIndex
,
378 sal_Int32 nVtableOffset
,
379 void ** gpreg
, void ** fpreg
, void ** ovrflw
,
380 sal_Int64
* pRegisterReturn
/* space for register return */ )
382 static_assert(sizeof(sal_Int32
)==sizeof(void *), "### unexpected!");
385 fprintf(stderr
,"cpp_mediate1 gp=%p,fp=%p,ov=%p\n",gpreg
,fpreg
,ovrflw
);
386 fprintf(stderr
,"gp=%p,%p,%p,%p\n",gpreg
[0],gpreg
[1],gpreg
[2],gpreg
[3]);
389 // gpreg: [ret *], this, [other gpr params]
390 // fpreg: [fpr params]
391 // ovrflw: [gpr or fpr params (properly aligned)]
394 if (nFunctionIndex
& 0x80000000 )
396 nFunctionIndex
&= 0x7fffffff;
404 fprintf(stderr
,"cpp_mediate12,pThis=%p, nFunctionIndex=%d,nVtableOffset=%d\n",pThis
,nFunctionIndex
,nVtableOffset
);
407 pThis
= static_cast< char * >(pThis
) - nVtableOffset
;
408 bridges::cpp_uno::shared::CppInterfaceProxy
* pCppI
409 = bridges::cpp_uno::shared::CppInterfaceProxy::castInterfaceToProxy(
412 fprintf(stderr
,"cpp_mediate13,pCppI=%p\n",pCppI
);
415 typelib_InterfaceTypeDescription
* pTypeDescr
= pCppI
->getTypeDescr();
418 fprintf(stderr
,"cpp_mediate2\n");
420 if (nFunctionIndex
>= pTypeDescr
->nMapFunctionIndexToMemberIndex
)
424 "illegal " << OUString::unacquired(&pTypeDescr
->aBase
.pTypeName
)
425 << " vtable index " << nFunctionIndex
<< "/"
426 << pTypeDescr
->nMapFunctionIndexToMemberIndex
);
427 throw RuntimeException(
428 ("illegal " + OUString::unacquired(&pTypeDescr
->aBase
.pTypeName
)
429 + " vtable index " + OUString::number(nFunctionIndex
) + "/"
430 + OUString::number(pTypeDescr
->nMapFunctionIndexToMemberIndex
)),
431 (XInterface
*)pThis
);
434 // determine called method
435 sal_Int32 nMemberPos
= pTypeDescr
->pMapFunctionIndexToMemberIndex
[nFunctionIndex
];
436 assert(nMemberPos
< pTypeDescr
->nAllMembers
);
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( "no member description found!", (XInterface
*)pThis
);
550 * is called on incoming vtable calls
551 * (called by asm snippets)
553 // static void cpp_vtable_call( int nFunctionIndex, int nVtableOffset, void** gpregptr, void** fpregptr, void** ovrflw)
554 // static void cpp_vtable_call( int nFunctionIndex, int nVtableOffset, void** gpregptr, void** ovrflw)
555 static void cpp_vtable_call()
565 //memcpy( fpreg, fpregptr, 16);
567 volatile long nRegReturn
[2];
569 __asm__( "sw $4, %0\n\t"
573 ::"m"(nFunctionIndex
), "m"(vTableOffset
), "m"(pCallStack
), "m"(ovrflw
) );
575 memcpy( gpreg
, pCallStack
, 16);
578 fprintf(stderr
,"in cpp_vtable_call nFunctionIndex is %d\n",nFunctionIndex
);
579 fprintf(stderr
,"in cpp_vtable_call nVtableOffset is %d\n",vTableOffset
);
580 fprintf(stderr
,"gp=%x,%x,%x,%x\n",gpreg
[0],gpreg
[1],gpreg
[2],gpreg
[3]);
583 //sal_Bool bComplex = nFunctionIndex & 0x80000000 ? sal_True : sal_False;
585 typelib_TypeClass aType
=
586 cpp_mediate( nFunctionIndex
, vTableOffset
, (void**)gpreg
, (void**)fpreg
, ovrflw
, (sal_Int64
*)nRegReturn
);
591 // move return value into register space
592 // (will be loaded by machine code snippet)
594 case typelib_TypeClass_BOOLEAN
:
595 case typelib_TypeClass_BYTE
:
596 __asm__( "lbu $2,%0\n\t" : :
597 "m"(nRegReturn
[0]) );
600 case typelib_TypeClass_CHAR
:
601 case typelib_TypeClass_UNSIGNED_SHORT
:
602 __asm__( "lhu $2,%0\n\t" : :
603 "m"(nRegReturn
[0]) );
606 case typelib_TypeClass_SHORT
:
607 __asm__( "lh $2,%0\n\t" : :
608 "m"(nRegReturn
[0]) );
612 case typelib_TypeClass_FLOAT
:
613 __asm__( "lwc1 $f0,%0\n\t" : :
614 "m" (*((float*)nRegReturn
)) );
617 case typelib_TypeClass_DOUBLE
:
618 { register double dret
asm("$f0");
619 dret
= (*((double*)nRegReturn
));
624 case typelib_TypeClass_HYPER
:
625 case typelib_TypeClass_UNSIGNED_HYPER
:
626 __asm__( "lw $3,%0\n\t" : :
627 "m"(nRegReturn
[1]) ); // fall through
630 __asm__( "lw $2,%0\n\t" : :
631 "m"(nRegReturn
[0]) );
637 int const codeSnippetSize
= 56;
639 unsigned char * codeSnippet( unsigned char * code
, sal_Int32 functionIndex
, sal_Int32 vtableOffset
,
644 fprintf(stderr
,"in codeSnippet functionIndex is %d\n", functionIndex
);
645 fprintf(stderr
,"in codeSnippet vtableOffset is %d\n", vtableOffset
);
649 if (! simpleRetType
)
650 functionIndex
|= 0x80000000;
652 unsigned long * p
= (unsigned long *) code
;
654 // static_assert( sizeof (long) == 4 );
655 assert((((unsigned long)code
) & 0x3) == 0 ); //aligned to 4 otherwise a mistake
657 /* generate this code */
659 #save regs into argument space required by mips abi
660 c: afa40000 sw a0,0(sp)
661 10: afa50004 sw a1,4(sp)
662 14: afa60008 sw a2,8(sp)
663 18: afa7000c sw a3,12(sp)
665 1c: 3c040000 lui a0,0x0
666 20: 34840000 ori a0,a0,0x0
668 24: 3c050000 lui a1,0x0
669 28: 34a50000 ori a1,a1,0x0
671 2c: 27a60000 addiu a2,sp,0
673 30: 27a70010 addiu a3,sp,16
674 #load cpp_vtable_call addr
675 34: 3c190000 lui t9,0x0
676 38: 37390000 ori t9,t9,0
677 #jmp to the function,note: we don't use jalr, that will destroy $ra
678 #but be sure to use t9! gp calculation depends on it
682 be careful, we use the argument space reserved by the caller to
683 write down regs. This can avoid the need to make use of arbitrary far away
684 stack space or to allocate a function frame for this code snippet itself.
685 Since only functions with variable arguments will overwrite the space,
686 cpp_vtable_call should be safe.
687 ??? gcc seems change this behavior! cpp_vtable_call overwrite the space!
694 * p
++ = 0x3c040000 | ((functionIndex
>>16) & 0x0000ffff);
695 * p
++ = 0x34840000 | (functionIndex
& 0x0000ffff);
696 * p
++ = 0x3c050000 | ((vtableOffset
>>16) & 0x0000ffff);
697 * p
++ = 0x34a50000 | (vtableOffset
& 0x0000ffff);
700 * p
++ = 0x3c190000 | ((((unsigned long)cpp_vtable_call
) >> 16) & 0x0000ffff);
701 * p
++ = 0x37390000 | (((unsigned long)cpp_vtable_call
) & 0x0000FFFF);
704 return (code
+ codeSnippetSize
);
712 void bridges::cpp_uno::shared::VtableFactory::flushCode(unsigned char const *bptr
, unsigned char const *eptr
)
717 sysmips(FLUSH_CACHE
,0,0,0);
719 cacheflush((long) bptr
, (long) eptr
, 0);
723 struct bridges::cpp_uno::shared::VtableFactory::Slot
{ void const * fn
; };
725 bridges::cpp_uno::shared::VtableFactory::Slot
*
726 bridges::cpp_uno::shared::VtableFactory::mapBlockToVtable(void * block
)
728 return static_cast< Slot
* >(block
) + 2;
732 std::size_t bridges::cpp_uno::shared::VtableFactory::getBlockSize(
735 return (slotCount
+ 2) * sizeof (Slot
) + slotCount
* codeSnippetSize
;
739 // Some dummy type whose RTTI is used in the synthesized proxy vtables to make uses of dynamic_cast
740 // on such proxy objects not crash:
744 bridges::cpp_uno::shared::VtableFactory::Slot
*
745 bridges::cpp_uno::shared::VtableFactory::initializeBlock(
746 void * block
, sal_Int32 slotCount
, sal_Int32
,
747 typelib_InterfaceTypeDescription
*)
749 Slot
* slots
= mapBlockToVtable(block
);
750 slots
[-2].fn
= 0; //null
751 slots
[-1].fn
= &typeid(ProxyRtti
);
752 return slots
+ slotCount
;
755 unsigned char * bridges::cpp_uno::shared::VtableFactory::addLocalFunctions(
756 Slot
** slots
, unsigned char * code
, sal_PtrDiff writetoexecdiff
,
757 typelib_InterfaceTypeDescription
const * type
, sal_Int32 functionOffset
,
758 sal_Int32 functionCount
, sal_Int32 vtableOffset
)
760 (*slots
) -= functionCount
;
763 fprintf(stderr
, "in addLocalFunctions functionOffset is %d\n",functionOffset
);
764 fprintf(stderr
, "in addLocalFunctions vtableOffset is %d\n",vtableOffset
);
765 fprintf(stderr
, "nMembers=%d\n",type
->nMembers
);
769 for (sal_Int32 i
= 0; i
< type
->nMembers
; ++i
) {
770 typelib_TypeDescription
* member
= 0;
771 TYPELIB_DANGER_GET(&member
, type
->ppMembers
[i
]);
773 switch (member
->eTypeClass
) {
774 case typelib_TypeClass_INTERFACE_ATTRIBUTE
:
776 (s
++)->fn
= code
+ writetoexecdiff
;
778 code
, functionOffset
++, vtableOffset
,
779 bridges::cpp_uno::shared::isSimpleType(
781 typelib_InterfaceAttributeTypeDescription
* >(
782 member
)->pAttributeTypeRef
));
785 if (!reinterpret_cast<
786 typelib_InterfaceAttributeTypeDescription
* >(
789 (s
++)->fn
= code
+ writetoexecdiff
;
790 code
= codeSnippet(code
, functionOffset
++, vtableOffset
, true);
794 case typelib_TypeClass_INTERFACE_METHOD
:
795 (s
++)->fn
= code
+ writetoexecdiff
;
797 code
, functionOffset
++, vtableOffset
,
798 bridges::cpp_uno::shared::isSimpleType(
800 typelib_InterfaceMethodTypeDescription
* >(
801 member
)->pReturnTypeRef
));
808 TYPELIB_DANGER_RELEASE(member
);
813 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */