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 .
20 #include <sal/config.h>
24 #include <com/sun/star/uno/genfunc.hxx>
25 #include <sal/log.hxx>
26 #include <typelib/typedescription.hxx>
29 #include "cppinterfaceproxy.hxx"
31 #include "vtablefactory.hxx"
34 #define GET_FP(n, p) \
35 __asm__( "ldx %0, %%l0\n\t" \
36 "std %%f" #n ", [%%l0]\n" \
39 using namespace com::sun::star::uno
;
41 namespace CPPU_CURRENT_NAMESPACE
43 bool is_complex_struct(const typelib_TypeDescription
* type
)
45 for (const typelib_CompoundTypeDescription
* p
46 = reinterpret_cast< const typelib_CompoundTypeDescription
* >(type
);
47 p
!= NULL
; p
= p
->pBaseTypeDescription
)
49 for (sal_Int32 i
= 0; i
< p
->nMembers
; ++i
)
51 if (p
->ppTypeRefs
[i
]->eTypeClass
== typelib_TypeClass_STRUCT
||
52 p
->ppTypeRefs
[i
]->eTypeClass
== typelib_TypeClass_EXCEPTION
)
54 typelib_TypeDescription
* t
= 0;
55 TYPELIB_DANGER_GET(&t
, p
->ppTypeRefs
[i
]);
56 bool b
= is_complex_struct(t
);
57 TYPELIB_DANGER_RELEASE(t
);
62 else if (!bridges::cpp_uno::shared::isSimpleType(p
->ppTypeRefs
[i
]->eTypeClass
))
69 bool return_in_hidden_param( typelib_TypeDescriptionReference
*pTypeRef
)
71 if (bridges::cpp_uno::shared::isSimpleType(pTypeRef
))
73 else if (pTypeRef
->eTypeClass
== typelib_TypeClass_STRUCT
||
74 pTypeRef
->eTypeClass
== typelib_TypeClass_EXCEPTION
)
76 typelib_TypeDescription
* pTypeDescr
= 0;
77 TYPELIB_DANGER_GET( &pTypeDescr
, pTypeRef
);
79 //A Composite Type not larger than 32 bytes is returned in up to two GPRs
80 bool bRet
= pTypeDescr
->nSize
> 32 || is_complex_struct(pTypeDescr
);
82 TYPELIB_DANGER_RELEASE( pTypeDescr
);
93 static typelib_TypeClass
cpp2uno_call(
94 bridges::cpp_uno::shared::CppInterfaceProxy
* pThis
,
95 const typelib_TypeDescription
* pMemberTypeDescr
,
96 typelib_TypeDescriptionReference
* pReturnTypeRef
, // 0 indicates void return
97 sal_Int32 nParams
, typelib_MethodParameter
* pParams
,
99 sal_Int64
* pRegisterReturn
/* space for register return */ )
101 // pCallStack: [ret ptr], this, params
102 char * pCppStack
= (char *)pCallStack
;
105 typelib_TypeDescription
* pReturnTypeDescr
= 0;
107 TYPELIB_DANGER_GET( &pReturnTypeDescr
, pReturnTypeRef
);
109 void * pUnoReturn
= 0;
110 void * pCppReturn
= 0; // complex return ptr: if != 0 && != pUnoReturn, reconversion need
113 if (pReturnTypeDescr
)
115 if (CPPU_CURRENT_NAMESPACE::return_in_hidden_param( pReturnTypeRef
) )
117 pCppReturn
= *(void**)pCppStack
; // complex return via ptr (pCppReturn)
118 pUnoReturn
= (bridges::cpp_uno::shared::relatesToInterfaceType(
120 ? alloca( pReturnTypeDescr
->nSize
)
121 : pCppReturn
); // direct way
122 pCppStack
+= sizeof( void* );
127 pUnoReturn
= pRegisterReturn
; // direct way for simple types
136 pCppStack
+= sizeof( void* );
139 static_assert(sizeof(void *) == sizeof(sal_Int64
), "### unexpected size!");
141 void ** pUnoArgs
= (void **)alloca( 4 * sizeof(void *) * nParams
);
142 void ** pCppArgs
= pUnoArgs
+ nParams
;
143 // indices of values this have to be converted (interface conversion cpp<=>uno)
144 sal_Int32
* pTempIndices
= (sal_Int32
*)(pUnoArgs
+ (2 * nParams
));
145 // type descriptions for reconversions
146 typelib_TypeDescription
** ppTempParamTypeDescr
= (typelib_TypeDescription
**)(pUnoArgs
+ (3 * nParams
));
148 sal_Int32 nTempIndices
= 0;
150 for ( sal_Int32 nPos
= 0; nPos
< nParams
; ++nPos
)
152 const typelib_MethodParameter
& rParam
= pParams
[nPos
];
153 typelib_TypeDescription
* pParamTypeDescr
= 0;
154 TYPELIB_DANGER_GET( &pParamTypeDescr
, rParam
.pTypeRef
);
156 if (!rParam
.bOut
&& bridges::cpp_uno::shared::isSimpleType( pParamTypeDescr
)) // value
158 pCppArgs
[nPos
] = pUnoArgs
[nPos
] = CPPU_CURRENT_NAMESPACE::adjustPointer(pCppStack
, pParamTypeDescr
);
159 switch (pParamTypeDescr
->eTypeClass
) {
160 case typelib_TypeClass_FLOAT
:
161 case typelib_TypeClass_DOUBLE
:
163 int paramArrayIdx
= nPos
+ paramsOffset
;
164 assert(paramArrayIdx
< nParams
+ paramsOffset
);
165 switch (paramArrayIdx
) {
166 // Cannot be 0 - paramsOffset >= 1
168 GET_FP(2, pCppStack
);
171 GET_FP(4, pCppStack
);
174 GET_FP(6, pCppStack
);
177 GET_FP(8, pCppStack
);
180 GET_FP(10, pCppStack
);
183 GET_FP(12, pCppStack
);
186 GET_FP(14, pCppStack
);
189 GET_FP(16, pCppStack
);
192 GET_FP(18, pCppStack
);
195 GET_FP(20, pCppStack
);
198 GET_FP(22, pCppStack
);
201 GET_FP(24, pCppStack
);
204 GET_FP(26, pCppStack
);
207 GET_FP(28, pCppStack
);
210 GET_FP(30, pCppStack
);
212 // Anything larger is passed on the stack
220 TYPELIB_DANGER_RELEASE( pParamTypeDescr
);
222 else // ptr to complex value | ref
224 pCppArgs
[nPos
] = *(void **)pCppStack
;
226 if (! rParam
.bIn
) // is pure out
228 // uno out is unconstructed mem!
229 pUnoArgs
[nPos
] = alloca( pParamTypeDescr
->nSize
);
230 pTempIndices
[nTempIndices
] = nPos
;
231 // will be released at reconversion
232 ppTempParamTypeDescr
[nTempIndices
++] = pParamTypeDescr
;
235 else if (bridges::cpp_uno::shared::relatesToInterfaceType(
238 uno_copyAndConvertData( pUnoArgs
[nPos
] = alloca( pParamTypeDescr
->nSize
),
239 *(void **)pCppStack
, pParamTypeDescr
,
240 pThis
->getBridge()->getCpp2Uno() );
241 pTempIndices
[nTempIndices
] = nPos
; // has to be reconverted
242 // will be released at reconversion
243 ppTempParamTypeDescr
[nTempIndices
++] = pParamTypeDescr
;
247 pUnoArgs
[nPos
] = *(void **)pCppStack
;
249 TYPELIB_DANGER_RELEASE( pParamTypeDescr
);
252 pCppStack
+= sizeof(sal_Int64
); // standard parameter length
256 uno_Any aUnoExc
; // Any will be constructed by callee
257 uno_Any
* pUnoExc
= &aUnoExc
;
259 // invoke uno dispatch call
260 (*pThis
->getUnoI()->pDispatcher
)(pThis
->getUnoI(), pMemberTypeDescr
, pUnoReturn
, pUnoArgs
, &pUnoExc
);
262 // in case an exception occurred...
265 // destruct temporary in/inout params
266 for ( ; nTempIndices
--; )
268 sal_Int32 nIndex
= pTempIndices
[nTempIndices
];
270 if (pParams
[nIndex
].bIn
) // is in/inout => was constructed
271 uno_destructData( pUnoArgs
[nIndex
], ppTempParamTypeDescr
[nTempIndices
], 0 );
272 TYPELIB_DANGER_RELEASE( ppTempParamTypeDescr
[nTempIndices
] );
274 if (pReturnTypeDescr
)
275 TYPELIB_DANGER_RELEASE( pReturnTypeDescr
);
276 CPPU_CURRENT_NAMESPACE::raiseException(&aUnoExc
, pThis
->getBridge()->getUno2Cpp() );
277 // has to destruct the any
279 return typelib_TypeClass_VOID
;
281 else // else no exception occurred...
284 for ( ; nTempIndices
--; )
286 sal_Int32 nIndex
= pTempIndices
[nTempIndices
];
287 typelib_TypeDescription
* pParamTypeDescr
= ppTempParamTypeDescr
[nTempIndices
];
289 if (pParams
[nIndex
].bOut
) // inout/out
291 // convert and assign
292 uno_destructData( pCppArgs
[nIndex
], pParamTypeDescr
, cpp_release
);
293 uno_copyAndConvertData( pCppArgs
[nIndex
], pUnoArgs
[nIndex
], pParamTypeDescr
,
294 pThis
->getBridge()->getUno2Cpp() );
296 // destroy temp uno param
297 uno_destructData( pUnoArgs
[nIndex
], pParamTypeDescr
, 0 );
299 TYPELIB_DANGER_RELEASE( pParamTypeDescr
);
302 if (pCppReturn
) // has complex return
304 if (pUnoReturn
!= pCppReturn
) // needs reconversion
306 uno_copyAndConvertData( pCppReturn
, pUnoReturn
, pReturnTypeDescr
,
307 pThis
->getBridge()->getUno2Cpp() );
308 // destroy temp uno return
309 uno_destructData( pUnoReturn
, pReturnTypeDescr
, 0 );
311 // complex return ptr is set to eax
312 *(void **)pRegisterReturn
= pCppReturn
;
314 if (pReturnTypeDescr
)
316 typelib_TypeClass eRet
= (typelib_TypeClass
)pReturnTypeDescr
->eTypeClass
;
317 TYPELIB_DANGER_RELEASE( pReturnTypeDescr
);
321 return typelib_TypeClass_VOID
;
326 static typelib_TypeClass
cpp_mediate(
327 sal_Int32 nFunctionIndex
,
328 sal_Int32 nVtableOffset
,
330 sal_Int64
* pRegisterReturn
/* space for register return */ )
332 static_assert(sizeof(sal_Int64
)==sizeof(void *), "### unexpected!");
334 // pCallStack: [ret*], this, params
336 if (nFunctionIndex
& 0x80000000)
338 nFunctionIndex
&= 0x7fffffff;
339 pThis
= pCallStack
[1];
343 pThis
= pCallStack
[0];
346 pThis
= static_cast< char * >(pThis
) - nVtableOffset
;
347 bridges::cpp_uno::shared::CppInterfaceProxy
* pCppI
=
348 bridges::cpp_uno::shared::CppInterfaceProxy::castInterfaceToProxy( pThis
);
350 typelib_InterfaceTypeDescription
* pTypeDescr
= pCppI
->getTypeDescr();
352 if (nFunctionIndex
>= pTypeDescr
->nMapFunctionIndexToMemberIndex
)
356 "illegal " << OUString::unacquired(&pTypeDescr
->aBase
.pTypeName
)
357 << " vtable index " << nFunctionIndex
<< "/"
358 << pTypeDescr
->nMapFunctionIndexToMemberIndex
);
359 throw RuntimeException(
360 ("illegal " + OUString::unacquired(&pTypeDescr
->aBase
.pTypeName
)
361 + " vtable index " + OUString::number(nFunctionIndex
) + "/"
362 + OUString::number(pTypeDescr
->nMapFunctionIndexToMemberIndex
)),
363 (XInterface
*)pCppI
);
366 // determine called method
367 sal_Int32 nMemberPos
= pTypeDescr
->pMapFunctionIndexToMemberIndex
[nFunctionIndex
];
368 assert(nMemberPos
< pTypeDescr
->nAllMembers
);
370 TypeDescription
aMemberDescr( pTypeDescr
->ppAllMembers
[nMemberPos
] );
372 typelib_TypeClass eRet
;
373 switch (aMemberDescr
.get()->eTypeClass
)
375 case typelib_TypeClass_INTERFACE_ATTRIBUTE
:
377 if (pTypeDescr
->pMapMemberIndexToFunctionIndex
[nMemberPos
] == nFunctionIndex
)
381 pCppI
, aMemberDescr
.get(),
382 ((typelib_InterfaceAttributeTypeDescription
*)aMemberDescr
.get())->pAttributeTypeRef
,
384 pCallStack
, pRegisterReturn
);
389 typelib_MethodParameter aParam
;
391 ((typelib_InterfaceAttributeTypeDescription
*)aMemberDescr
.get())->pAttributeTypeRef
;
392 aParam
.bIn
= sal_True
;
393 aParam
.bOut
= sal_False
;
396 pCppI
, aMemberDescr
.get(),
397 0, // indicates void return
399 pCallStack
, pRegisterReturn
);
403 case typelib_TypeClass_INTERFACE_METHOD
:
406 switch (nFunctionIndex
)
409 pCppI
->acquireProxy(); // non virtual call!
410 eRet
= typelib_TypeClass_VOID
;
413 pCppI
->releaseProxy(); // non virtual call!
414 eRet
= typelib_TypeClass_VOID
;
416 case 0: // queryInterface() opt
418 typelib_TypeDescription
* pTD
= 0;
419 TYPELIB_DANGER_GET( &pTD
, reinterpret_cast< Type
* >( pCallStack
[2] )->getTypeLibType() );
422 XInterface
* pInterface
= 0;
423 (*pCppI
->getBridge()->getCppEnv()->getRegisteredInterface
)(
424 pCppI
->getBridge()->getCppEnv(),
425 (void **)&pInterface
, pCppI
->getOid().pData
, (typelib_InterfaceTypeDescription
*)pTD
);
430 reinterpret_cast< uno_Any
* >( pCallStack
[0] ),
431 &pInterface
, pTD
, cpp_acquire
);
432 pInterface
->release();
433 TYPELIB_DANGER_RELEASE( pTD
);
434 *(void **)pRegisterReturn
= pCallStack
[0];
435 eRet
= typelib_TypeClass_ANY
;
438 TYPELIB_DANGER_RELEASE( pTD
);
440 } // else perform queryInterface()
443 pCppI
, aMemberDescr
.get(),
444 ((typelib_InterfaceMethodTypeDescription
*)aMemberDescr
.get())->pReturnTypeRef
,
445 ((typelib_InterfaceMethodTypeDescription
*)aMemberDescr
.get())->nParams
,
446 ((typelib_InterfaceMethodTypeDescription
*)aMemberDescr
.get())->pParams
,
447 pCallStack
, pRegisterReturn
);
453 throw RuntimeException( "no member description found!", (XInterface
*)pCppI
);
462 * is called on incoming vtable calls
463 * (called by asm snippets)
465 static void cpp_vtable_call(int nFunctionIndex
, void** pCallStack
, int vTableOffset
)
467 sal_Int64 nRegReturn
[4] = { 0 };
468 void * pRegReturn
= &nRegReturn
[0];
470 //__asm__( "st %%i0, %0\n\t"
471 // "stx %%i1, %1\n\t"
473 // : : "m"(nFunctionIndex), "m"(pCallStack), "m"(vTableOffset) );
475 // fprintf(stderr,"cpp_mediate nFunctionIndex=%x\n",nFunctionIndex);
478 //const sal_Bool bComplex = (nFunctionIndex & 0x80000000) ? sal_True : sal_False;
479 typelib_TypeClass aType
=
480 cpp_mediate( nFunctionIndex
, vTableOffset
, pCallStack
+16, (sal_Int64
*)&nRegReturn
);
484 case typelib_TypeClass_BOOLEAN
:
485 case typelib_TypeClass_BYTE
:
486 __asm__( "ldx %0, %%l0\n\t"
487 "ldsb [%%l0], %%i0\n"
488 : : "m"(pRegReturn
) );
490 case typelib_TypeClass_CHAR
:
491 case typelib_TypeClass_SHORT
:
492 case typelib_TypeClass_UNSIGNED_SHORT
:
493 __asm__( "ldx %0, %%l0\n\t"
494 "ldsh [%%l0], %%i0\n"
495 : : "m"(pRegReturn
) );
497 case typelib_TypeClass_ENUM
:
498 case typelib_TypeClass_LONG
:
499 case typelib_TypeClass_UNSIGNED_LONG
:
500 __asm__( "ldx %0, %%l0\n\t"
502 : : "m"(pRegReturn
) );
504 case typelib_TypeClass_HYPER
:
505 case typelib_TypeClass_UNSIGNED_HYPER
:
506 __asm__( "ldx %0, %%l0\n\t"
507 "ldx [%%l0], %%i0\n\t"
508 : : "m"(pRegReturn
) );
510 case typelib_TypeClass_FLOAT
:
511 __asm__( "ldx %0, %%l0\n\t"
513 : : "m"(pRegReturn
) );
515 case typelib_TypeClass_DOUBLE
:
516 __asm__( "ldx %0, %%l0\n\t"
518 : : "m"(pRegReturn
) );
520 case typelib_TypeClass_VOID
:
522 case typelib_TypeClass_STRUCT
:
523 case typelib_TypeClass_EXCEPTION
:
524 __asm__( "ldx %0, %%l0\n\t"
525 "ldx [%%l0 ], %%i0\n\t"
526 "ldx [%%l0+ 8], %%i1\n\t"
527 "ldx [%%l0+16], %%i2\n\t"
528 "ldx [%%l0+24], %%i3\n\t"
529 "ldd [%%l0 ], %%f0\n\t"
530 "ldd [%%l0+ 8], %%f2\n\t"
531 "ldd [%%l0+16], %%f4\n\t"
532 "ldd [%%l0+24], %%f6\n\t"
533 : : "m"(pRegReturn
) );
541 // __asm__( "add %i7, 4, %i7\n\t" );
542 // // after call to complex return valued function there is an unimp instruction
547 extern "C" void privateSnippetExecutor(...);
549 int const codeSnippetSize
= 120;
550 unsigned char * codeSnippet(
551 unsigned char * code
, sal_Int32 functionIndex
, sal_Int32 vtableOffset
,
552 bool bHasHiddenParam
, sal_Int32 nParams
)
554 sal_uInt32 index
= functionIndex
;
555 if (bHasHiddenParam
) {
558 unsigned int * p
= reinterpret_cast< unsigned int * >(code
);
559 static_assert(sizeof (unsigned int) == 4, "boo");
560 static_assert(sizeof (unsigned long long) == 8, "boo");
561 ++nParams
; // implicit this ptr
562 if (bHasHiddenParam
) {
567 frameSize
= 128 + nParams
* 8;
571 assert(frameSize
<= 4096);
572 frameSize
= -frameSize
;
575 assert(nParams
>= 6);
576 // stx %o5, [%sp+168+2047]:
579 // stx %o4, [%sp+160+2047]:
582 // stx %o3, [%sp+152+2047]:
585 // stx %o2, [%sp+144+2047]:
588 // stx %o1, [%sp+136+2047]:
591 // stx %o0, [%sp+128+2047]:
596 // sethi %hi(index), %o0:
597 *p
++ = 0x11000000 | (index
>> 10);
598 // or %o0, %lo(index), %o0:
599 *p
++ = 0x90122000 | (index
& 0x3FF);
600 // sethi %hh(cpp_vtable_call), %o3:
601 *p
++ = 0x17000000 | (reinterpret_cast< unsigned long long >(cpp_vtable_call
) >> 42);
602 // or %o3, %hm(cpp_vtable_call), %o3:
603 *p
++ = 0x9612E000 | ((reinterpret_cast< unsigned long long >(cpp_vtable_call
) >> 32) & 0x3FF);
606 // sethi %lm(cpp_vtable_call), %o2:
607 *p
++ = 0x15000000 | ((reinterpret_cast< unsigned long long >(cpp_vtable_call
) >> 10) & 0x3FFFFF);
608 // or %o2, %lo(cpp_vtable_call), %o2:
609 *p
++ = 0x9412A000 | (reinterpret_cast< unsigned long long >(cpp_vtable_call
) & 0x3FF);
612 // sethi %hh(privateSnippetExecutor), %o1:
613 *p
++ = 0x13000000 | (reinterpret_cast< unsigned long long >(privateSnippetExecutor
) >> 42);
614 // or %o1, %hm(privateSnippetExecutor), %o1:
615 *p
++ = 0x92126000 | ((reinterpret_cast< unsigned long long >(privateSnippetExecutor
) >> 32) & 0x3FF);
616 // sllx %o1, 32, %o1:
618 // sethi %lm(privateSnippetExecutor), %o2:
619 *p
++ = 0x15000000 | ((reinterpret_cast< unsigned long long >(privateSnippetExecutor
) >> 10) & 0x3FFFFF);
620 // or %o2, %lo(privateSnippetExecutor), %o2:
621 *p
++ = 0x9412A000 | (reinterpret_cast< unsigned long long >(privateSnippetExecutor
) & 0x3FF);
624 // sethi %hh(frameSize), %o4:
625 *p
++ = 0x19000000 | (*reinterpret_cast< unsigned long long * >(&frameSize
) >> 42);
626 // or %o4, %hm(frameSize), %o4:
627 *p
++ = 0x98132000 | ((*reinterpret_cast< unsigned long long * >(&frameSize
) >> 32) & 0x3FF);
630 // sethi %lm(frameSize), %o2:
631 *p
++ = 0x15000000 | ((*reinterpret_cast< unsigned long long * >(&frameSize
) >> 10) & 0x3FFFFF);
632 // or %o2, %lo(frameSize), %o2:
633 *p
++ = 0x9412A000 | (*reinterpret_cast< unsigned long long * >(&frameSize
) & 0x3FF);
636 // sethi %hi(vtableOffset), %o2:
637 *p
++ = 0x15000000 | (vtableOffset
>> 10);
638 // or %o2, %lo(vtableOffset), %o2:
639 *p
++ = 0x9412A000 | (vtableOffset
& 0x3FF);
640 // save %sp, -frameSize, %sp
641 //*p++ = 0x9DE3A000 | (*reinterpret_cast< unsigned int * >(&frameSize) & 0x1FFF);
644 // add %sp, 2047, %o1:
646 assert(reinterpret_cast< unsigned char * >(p
) - code
<= codeSnippetSize
);
647 return code
+ codeSnippetSize
;
652 struct bridges::cpp_uno::shared::VtableFactory::Slot
{ void const * fn
; };
654 bridges::cpp_uno::shared::VtableFactory::Slot
*
655 bridges::cpp_uno::shared::VtableFactory::mapBlockToVtable(void * block
)
657 return static_cast< Slot
* >(block
) + 2;
660 std::size_t bridges::cpp_uno::shared::VtableFactory::getBlockSize(
663 return (slotCount
+ 2) * sizeof (Slot
) + slotCount
* codeSnippetSize
;
667 // Some dummy type whose RTTI is used in the synthesized proxy vtables to make uses of dynamic_cast
668 // on such proxy objects not crash:
672 bridges::cpp_uno::shared::VtableFactory::Slot
*
673 bridges::cpp_uno::shared::VtableFactory::initializeBlock(
674 void * block
, sal_Int32 slotCount
, sal_Int32
,
675 typelib_InterfaceTypeDescription
*)
677 Slot
* slots
= mapBlockToVtable(block
);
678 slots
[-2].fn
= 0; //null
679 slots
[-1].fn
= &typeid(ProxyRtti
);
680 return slots
+ slotCount
;
683 unsigned char * bridges::cpp_uno::shared::VtableFactory::addLocalFunctions(
684 Slot
** slots
, unsigned char * code
, sal_PtrDiff writetoexecdiff
,
685 typelib_InterfaceTypeDescription
const * type
, sal_Int32 functionOffset
,
686 sal_Int32 functionCount
, sal_Int32 vTableOffset
)
688 (*slots
) -= functionCount
;
690 for (sal_Int32 i
= 0; i
< type
->nMembers
; ++i
) {
691 typelib_TypeDescription
* member
= 0;
692 TYPELIB_DANGER_GET(&member
, type
->ppMembers
[i
]);
694 switch (member
->eTypeClass
) {
695 case typelib_TypeClass_INTERFACE_ATTRIBUTE
:
697 (s
++)->fn
= code
+ writetoexecdiff
;
699 code
, functionOffset
++, vTableOffset
,
700 CPPU_CURRENT_NAMESPACE::return_in_hidden_param(
702 typelib_InterfaceAttributeTypeDescription
* >(
703 member
)->pAttributeTypeRef
), 0);
705 if (!reinterpret_cast<
706 typelib_InterfaceAttributeTypeDescription
* >(
709 (s
++)->fn
= code
+ writetoexecdiff
;
710 code
= codeSnippet(code
, functionOffset
++, vTableOffset
, false, 1);
714 case typelib_TypeClass_INTERFACE_METHOD
:
715 (s
++)->fn
= code
+ writetoexecdiff
;
717 code
, functionOffset
++, vTableOffset
,
718 CPPU_CURRENT_NAMESPACE::return_in_hidden_param(
720 typelib_InterfaceMethodTypeDescription
* >(
721 member
)->pReturnTypeRef
),
723 typelib_InterfaceMethodTypeDescription
* >(
731 TYPELIB_DANGER_RELEASE(member
);
736 // use flush code from cc50_solaris_sparc
738 extern "C" void doFlushCode(unsigned long address
, unsigned long count
);
740 void bridges::cpp_uno::shared::VtableFactory::flushCode(
741 unsigned char const * begin
, unsigned char const * end
)
743 unsigned long n
= end
- begin
;
745 unsigned long adr
= reinterpret_cast< unsigned long >(begin
);
746 unsigned long off
= adr
& 7;
747 doFlushCode(adr
- off
, (n
+ off
+ 7) >> 3);
751 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */