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 <com/sun/star/uno/genfunc.hxx>
21 #include <sal/log.hxx>
22 #include <typelib/typedescription.hxx>
25 #include "cppinterfaceproxy.hxx"
27 #include "vtablefactory.hxx"
30 #define GET_FP(n, p) \
31 __asm__( "ldx %0, %%l0\n\t" \
32 "std %%f" #n ", [%%l0]\n" \
35 using namespace com::sun::star::uno
;
37 namespace CPPU_CURRENT_NAMESPACE
39 bool is_complex_struct(const typelib_TypeDescription
* type
)
41 for (const typelib_CompoundTypeDescription
* p
42 = reinterpret_cast< const typelib_CompoundTypeDescription
* >(type
);
43 p
!= NULL
; p
= p
->pBaseTypeDescription
)
45 for (sal_Int32 i
= 0; i
< p
->nMembers
; ++i
)
47 if (p
->ppTypeRefs
[i
]->eTypeClass
== typelib_TypeClass_STRUCT
||
48 p
->ppTypeRefs
[i
]->eTypeClass
== typelib_TypeClass_EXCEPTION
)
50 typelib_TypeDescription
* t
= 0;
51 TYPELIB_DANGER_GET(&t
, p
->ppTypeRefs
[i
]);
52 bool b
= is_complex_struct(t
);
53 TYPELIB_DANGER_RELEASE(t
);
58 else if (!bridges::cpp_uno::shared::isSimpleType(p
->ppTypeRefs
[i
]->eTypeClass
))
65 bool return_in_hidden_param( typelib_TypeDescriptionReference
*pTypeRef
)
67 if (bridges::cpp_uno::shared::isSimpleType(pTypeRef
))
69 else if (pTypeRef
->eTypeClass
== typelib_TypeClass_STRUCT
||
70 pTypeRef
->eTypeClass
== typelib_TypeClass_EXCEPTION
)
72 typelib_TypeDescription
* pTypeDescr
= 0;
73 TYPELIB_DANGER_GET( &pTypeDescr
, pTypeRef
);
75 //A Composite Type not larger than 32 bytes is returned in up to two GPRs
76 bool bRet
= pTypeDescr
->nSize
> 32 || is_complex_struct(pTypeDescr
);
78 TYPELIB_DANGER_RELEASE( pTypeDescr
);
89 static typelib_TypeClass
cpp2uno_call(
90 bridges::cpp_uno::shared::CppInterfaceProxy
* pThis
,
91 const typelib_TypeDescription
* pMemberTypeDescr
,
92 typelib_TypeDescriptionReference
* pReturnTypeRef
, // 0 indicates void return
93 sal_Int32 nParams
, typelib_MethodParameter
* pParams
,
95 sal_Int64
* pRegisterReturn
/* space for register return */ )
97 // pCallStack: [ret ptr], this, params
98 char * pCppStack
= (char *)pCallStack
;
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
109 if (pReturnTypeDescr
)
111 if (CPPU_CURRENT_NAMESPACE::return_in_hidden_param( pReturnTypeRef
) )
113 pCppReturn
= *(void**)pCppStack
; // complex return via ptr (pCppReturn)
114 pUnoReturn
= (bridges::cpp_uno::shared::relatesToInterfaceType(
116 ? alloca( pReturnTypeDescr
->nSize
)
117 : pCppReturn
); // direct way
118 pCppStack
+= sizeof( void* );
123 pUnoReturn
= pRegisterReturn
; // direct way for simple types
132 pCppStack
+= sizeof( void* );
135 static_assert(sizeof(void *) == sizeof(sal_Int64
), "### unexpected size!");
137 void ** pUnoArgs
= (void **)alloca( 4 * sizeof(void *) * nParams
);
138 void ** pCppArgs
= pUnoArgs
+ nParams
;
139 // indices of values this have to be converted (interface conversion cpp<=>uno)
140 sal_Int32
* pTempIndices
= (sal_Int32
*)(pUnoArgs
+ (2 * nParams
));
141 // type descriptions for reconversions
142 typelib_TypeDescription
** ppTempParamTypeDescr
= (typelib_TypeDescription
**)(pUnoArgs
+ (3 * nParams
));
144 sal_Int32 nTempIndices
= 0;
146 for ( sal_Int32 nPos
= 0; nPos
< nParams
; ++nPos
)
148 const typelib_MethodParameter
& rParam
= pParams
[nPos
];
149 typelib_TypeDescription
* pParamTypeDescr
= 0;
150 TYPELIB_DANGER_GET( &pParamTypeDescr
, rParam
.pTypeRef
);
152 if (!rParam
.bOut
&& bridges::cpp_uno::shared::isSimpleType( pParamTypeDescr
)) // value
154 pCppArgs
[nPos
] = pUnoArgs
[nPos
] = CPPU_CURRENT_NAMESPACE::adjustPointer(pCppStack
, pParamTypeDescr
);
155 switch (pParamTypeDescr
->eTypeClass
) {
156 case typelib_TypeClass_FLOAT
:
157 case typelib_TypeClass_DOUBLE
:
159 int paramArrayIdx
= nPos
+ paramsOffset
;
160 assert(paramArrayIdx
< nParams
+ paramsOffset
);
161 switch (paramArrayIdx
) {
162 // Cannot be 0 - paramsOffset >= 1
164 GET_FP(2, pCppStack
);
167 GET_FP(4, pCppStack
);
170 GET_FP(6, pCppStack
);
173 GET_FP(8, pCppStack
);
176 GET_FP(10, pCppStack
);
179 GET_FP(12, pCppStack
);
182 GET_FP(14, pCppStack
);
185 GET_FP(16, pCppStack
);
188 GET_FP(18, pCppStack
);
191 GET_FP(20, pCppStack
);
194 GET_FP(22, pCppStack
);
197 GET_FP(24, pCppStack
);
200 GET_FP(26, pCppStack
);
203 GET_FP(28, pCppStack
);
206 GET_FP(30, pCppStack
);
208 // Anything larger is passed on the stack
216 TYPELIB_DANGER_RELEASE( pParamTypeDescr
);
218 else // ptr to complex value | ref
220 pCppArgs
[nPos
] = *(void **)pCppStack
;
222 if (! rParam
.bIn
) // is pure out
224 // uno out is unconstructed mem!
225 pUnoArgs
[nPos
] = alloca( pParamTypeDescr
->nSize
);
226 pTempIndices
[nTempIndices
] = nPos
;
227 // will be released at reconversion
228 ppTempParamTypeDescr
[nTempIndices
++] = pParamTypeDescr
;
231 else if (bridges::cpp_uno::shared::relatesToInterfaceType(
234 uno_copyAndConvertData( pUnoArgs
[nPos
] = alloca( pParamTypeDescr
->nSize
),
235 *(void **)pCppStack
, pParamTypeDescr
,
236 pThis
->getBridge()->getCpp2Uno() );
237 pTempIndices
[nTempIndices
] = nPos
; // has to be reconverted
238 // will be released at reconversion
239 ppTempParamTypeDescr
[nTempIndices
++] = pParamTypeDescr
;
243 pUnoArgs
[nPos
] = *(void **)pCppStack
;
245 TYPELIB_DANGER_RELEASE( pParamTypeDescr
);
248 pCppStack
+= sizeof(sal_Int64
); // standard parameter length
252 uno_Any aUnoExc
; // Any will be constructed by callee
253 uno_Any
* pUnoExc
= &aUnoExc
;
255 // invoke uno dispatch call
256 (*pThis
->getUnoI()->pDispatcher
)(pThis
->getUnoI(), pMemberTypeDescr
, pUnoReturn
, pUnoArgs
, &pUnoExc
);
258 // in case an exception occurred...
261 // destruct temporary in/inout params
262 for ( ; nTempIndices
--; )
264 sal_Int32 nIndex
= pTempIndices
[nTempIndices
];
266 if (pParams
[nIndex
].bIn
) // is in/inout => was constructed
267 uno_destructData( pUnoArgs
[nIndex
], ppTempParamTypeDescr
[nTempIndices
], 0 );
268 TYPELIB_DANGER_RELEASE( ppTempParamTypeDescr
[nTempIndices
] );
270 if (pReturnTypeDescr
)
271 TYPELIB_DANGER_RELEASE( pReturnTypeDescr
);
272 CPPU_CURRENT_NAMESPACE::raiseException(&aUnoExc
, pThis
->getBridge()->getUno2Cpp() );
273 // has to destruct the any
275 return typelib_TypeClass_VOID
;
277 else // else no exception occurred...
280 for ( ; nTempIndices
--; )
282 sal_Int32 nIndex
= pTempIndices
[nTempIndices
];
283 typelib_TypeDescription
* pParamTypeDescr
= ppTempParamTypeDescr
[nTempIndices
];
285 if (pParams
[nIndex
].bOut
) // inout/out
287 // convert and assign
288 uno_destructData( pCppArgs
[nIndex
], pParamTypeDescr
, cpp_release
);
289 uno_copyAndConvertData( pCppArgs
[nIndex
], pUnoArgs
[nIndex
], pParamTypeDescr
,
290 pThis
->getBridge()->getUno2Cpp() );
292 // destroy temp uno param
293 uno_destructData( pUnoArgs
[nIndex
], pParamTypeDescr
, 0 );
295 TYPELIB_DANGER_RELEASE( pParamTypeDescr
);
298 if (pCppReturn
) // has complex return
300 if (pUnoReturn
!= pCppReturn
) // needs reconversion
302 uno_copyAndConvertData( pCppReturn
, pUnoReturn
, pReturnTypeDescr
,
303 pThis
->getBridge()->getUno2Cpp() );
304 // destroy temp uno return
305 uno_destructData( pUnoReturn
, pReturnTypeDescr
, 0 );
307 // complex return ptr is set to eax
308 *(void **)pRegisterReturn
= pCppReturn
;
310 if (pReturnTypeDescr
)
312 typelib_TypeClass eRet
= (typelib_TypeClass
)pReturnTypeDescr
->eTypeClass
;
313 TYPELIB_DANGER_RELEASE( pReturnTypeDescr
);
317 return typelib_TypeClass_VOID
;
322 static typelib_TypeClass
cpp_mediate(
323 sal_Int32 nFunctionIndex
,
324 sal_Int32 nVtableOffset
,
326 sal_Int64
* pRegisterReturn
/* space for register return */ )
328 static_assert(sizeof(sal_Int64
)==sizeof(void *), "### unexpected!");
330 // pCallStack: [ret*], this, params
332 if (nFunctionIndex
& 0x80000000)
334 nFunctionIndex
&= 0x7fffffff;
335 pThis
= pCallStack
[1];
339 pThis
= pCallStack
[0];
342 pThis
= static_cast< char * >(pThis
) - nVtableOffset
;
343 bridges::cpp_uno::shared::CppInterfaceProxy
* pCppI
=
344 bridges::cpp_uno::shared::CppInterfaceProxy::castInterfaceToProxy( pThis
);
346 typelib_InterfaceTypeDescription
* pTypeDescr
= pCppI
->getTypeDescr();
348 if (nFunctionIndex
>= pTypeDescr
->nMapFunctionIndexToMemberIndex
)
352 "illegal " << OUString::unacquired(&pTypeDescr
->aBase
.pTypeName
)
353 << " vtable index " << nFunctionIndex
<< "/"
354 << pTypeDescr
->nMapFunctionIndexToMemberIndex
);
355 throw RuntimeException(
356 ("illegal " + OUString::unacquired(&pTypeDescr
->aBase
.pTypeName
)
357 + " vtable index " + OUString::number(nFunctionIndex
) + "/"
358 + OUString::number(pTypeDescr
->nMapFunctionIndexToMemberIndex
)),
359 (XInterface
*)pCppI
);
362 // determine called method
363 sal_Int32 nMemberPos
= pTypeDescr
->pMapFunctionIndexToMemberIndex
[nFunctionIndex
];
364 assert(nMemberPos
< pTypeDescr
->nAllMembers
);
366 TypeDescription
aMemberDescr( pTypeDescr
->ppAllMembers
[nMemberPos
] );
368 #if defined BRIDGES_DEBUG
369 OString
cstr( OUStringToOString( aMemberDescr
.get()->pTypeName
, RTL_TEXTENCODING_ASCII_US
) );
370 fprintf( stderr
, "calling %s, nFunctionIndex=%d\n", cstr
.getStr(), nFunctionIndex
);
373 typelib_TypeClass eRet
;
374 switch (aMemberDescr
.get()->eTypeClass
)
376 case typelib_TypeClass_INTERFACE_ATTRIBUTE
:
378 if (pTypeDescr
->pMapMemberIndexToFunctionIndex
[nMemberPos
] == nFunctionIndex
)
382 pCppI
, aMemberDescr
.get(),
383 ((typelib_InterfaceAttributeTypeDescription
*)aMemberDescr
.get())->pAttributeTypeRef
,
385 pCallStack
, pRegisterReturn
);
390 typelib_MethodParameter aParam
;
392 ((typelib_InterfaceAttributeTypeDescription
*)aMemberDescr
.get())->pAttributeTypeRef
;
393 aParam
.bIn
= sal_True
;
394 aParam
.bOut
= sal_False
;
397 pCppI
, aMemberDescr
.get(),
398 0, // indicates void return
400 pCallStack
, pRegisterReturn
);
404 case typelib_TypeClass_INTERFACE_METHOD
:
407 switch (nFunctionIndex
)
410 pCppI
->acquireProxy(); // non virtual call!
411 eRet
= typelib_TypeClass_VOID
;
414 pCppI
->releaseProxy(); // non virtual call!
415 eRet
= typelib_TypeClass_VOID
;
417 case 0: // queryInterface() opt
419 typelib_TypeDescription
* pTD
= 0;
420 TYPELIB_DANGER_GET( &pTD
, reinterpret_cast< Type
* >( pCallStack
[2] )->getTypeLibType() );
423 XInterface
* pInterface
= 0;
424 (*pCppI
->getBridge()->getCppEnv()->getRegisteredInterface
)(
425 pCppI
->getBridge()->getCppEnv(),
426 (void **)&pInterface
, pCppI
->getOid().pData
, (typelib_InterfaceTypeDescription
*)pTD
);
431 reinterpret_cast< uno_Any
* >( pCallStack
[0] ),
432 &pInterface
, pTD
, cpp_acquire
);
433 pInterface
->release();
434 TYPELIB_DANGER_RELEASE( pTD
);
435 *(void **)pRegisterReturn
= pCallStack
[0];
436 eRet
= typelib_TypeClass_ANY
;
439 TYPELIB_DANGER_RELEASE( pTD
);
441 } // else perform queryInterface()
444 pCppI
, aMemberDescr
.get(),
445 ((typelib_InterfaceMethodTypeDescription
*)aMemberDescr
.get())->pReturnTypeRef
,
446 ((typelib_InterfaceMethodTypeDescription
*)aMemberDescr
.get())->nParams
,
447 ((typelib_InterfaceMethodTypeDescription
*)aMemberDescr
.get())->pParams
,
448 pCallStack
, pRegisterReturn
);
454 throw RuntimeException( "no member description found!", (XInterface
*)pCppI
);
463 * is called on incoming vtable calls
464 * (called by asm snippets)
466 static void cpp_vtable_call(int nFunctionIndex
, void** pCallStack
, int vTableOffset
)
468 sal_Int64 nRegReturn
[4] = { 0 };
469 void * pRegReturn
= &nRegReturn
[0];
471 //__asm__( "st %%i0, %0\n\t"
472 // "stx %%i1, %1\n\t"
474 // : : "m"(nFunctionIndex), "m"(pCallStack), "m"(vTableOffset) );
476 // fprintf(stderr,"cpp_mediate nFunctionIndex=%x\n",nFunctionIndex);
479 //const sal_Bool bComplex = (nFunctionIndex & 0x80000000) ? sal_True : sal_False;
480 typelib_TypeClass aType
=
481 cpp_mediate( nFunctionIndex
, vTableOffset
, pCallStack
+16, (sal_Int64
*)&nRegReturn
);
485 case typelib_TypeClass_BOOLEAN
:
486 case typelib_TypeClass_BYTE
:
487 __asm__( "ldx %0, %%l0\n\t"
488 "ldsb [%%l0], %%i0\n"
489 : : "m"(pRegReturn
) );
491 case typelib_TypeClass_CHAR
:
492 case typelib_TypeClass_SHORT
:
493 case typelib_TypeClass_UNSIGNED_SHORT
:
494 __asm__( "ldx %0, %%l0\n\t"
495 "ldsh [%%l0], %%i0\n"
496 : : "m"(pRegReturn
) );
498 case typelib_TypeClass_ENUM
:
499 case typelib_TypeClass_LONG
:
500 case typelib_TypeClass_UNSIGNED_LONG
:
501 __asm__( "ldx %0, %%l0\n\t"
503 : : "m"(pRegReturn
) );
505 case typelib_TypeClass_HYPER
:
506 case typelib_TypeClass_UNSIGNED_HYPER
:
507 __asm__( "ldx %0, %%l0\n\t"
508 "ldx [%%l0], %%i0\n\t"
509 : : "m"(pRegReturn
) );
511 case typelib_TypeClass_FLOAT
:
512 __asm__( "ldx %0, %%l0\n\t"
514 : : "m"(pRegReturn
) );
516 case typelib_TypeClass_DOUBLE
:
517 __asm__( "ldx %0, %%l0\n\t"
519 : : "m"(pRegReturn
) );
521 case typelib_TypeClass_VOID
:
523 case typelib_TypeClass_STRUCT
:
524 case typelib_TypeClass_EXCEPTION
:
525 __asm__( "ldx %0, %%l0\n\t"
526 "ldx [%%l0 ], %%i0\n\t"
527 "ldx [%%l0+ 8], %%i1\n\t"
528 "ldx [%%l0+16], %%i2\n\t"
529 "ldx [%%l0+24], %%i3\n\t"
530 "ldd [%%l0 ], %%f0\n\t"
531 "ldd [%%l0+ 8], %%f2\n\t"
532 "ldd [%%l0+16], %%f4\n\t"
533 "ldd [%%l0+24], %%f6\n\t"
534 : : "m"(pRegReturn
) );
542 // __asm__( "add %i7, 4, %i7\n\t" );
543 // // after call to complex return valued function there is an unimp instruction
548 extern "C" void privateSnippetExecutor(...);
550 int const codeSnippetSize
= 120;
551 unsigned char * codeSnippet(
552 unsigned char * code
, sal_Int32 functionIndex
, sal_Int32 vtableOffset
,
553 bool bHasHiddenParam
, sal_Int32 nParams
)
555 sal_uInt32 index
= functionIndex
;
556 if (bHasHiddenParam
) {
559 unsigned int * p
= reinterpret_cast< unsigned int * >(code
);
560 static_assert(sizeof (unsigned int) == 4, "boo");
561 static_assert(sizeof (unsigned long long) == 8, "boo");
562 ++nParams
; // implicit this ptr
563 if (bHasHiddenParam
) {
568 frameSize
= 128 + nParams
* 8;
572 assert(frameSize
<= 4096);
573 frameSize
= -frameSize
;
576 assert(nParams
>= 6);
577 // stx %o5, [%sp+168+2047]:
580 // stx %o4, [%sp+160+2047]:
583 // stx %o3, [%sp+152+2047]:
586 // stx %o2, [%sp+144+2047]:
589 // stx %o1, [%sp+136+2047]:
592 // stx %o0, [%sp+128+2047]:
597 // sethi %hi(index), %o0:
598 *p
++ = 0x11000000 | (index
>> 10);
599 // or %o0, %lo(index), %o0:
600 *p
++ = 0x90122000 | (index
& 0x3FF);
601 // sethi %hh(cpp_vtable_call), %o3:
602 *p
++ = 0x17000000 | (reinterpret_cast< unsigned long long >(cpp_vtable_call
) >> 42);
603 // or %o3, %hm(cpp_vtable_call), %o3:
604 *p
++ = 0x9612E000 | ((reinterpret_cast< unsigned long long >(cpp_vtable_call
) >> 32) & 0x3FF);
607 // sethi %lm(cpp_vtable_call), %o2:
608 *p
++ = 0x15000000 | ((reinterpret_cast< unsigned long long >(cpp_vtable_call
) >> 10) & 0x3FFFFF);
609 // or %o2, %lo(cpp_vtable_call), %o2:
610 *p
++ = 0x9412A000 | (reinterpret_cast< unsigned long long >(cpp_vtable_call
) & 0x3FF);
613 // sethi %hh(privateSnippetExecutor), %o1:
614 *p
++ = 0x13000000 | (reinterpret_cast< unsigned long long >(privateSnippetExecutor
) >> 42);
615 // or %o1, %hm(privateSnippetExecutor), %o1:
616 *p
++ = 0x92126000 | ((reinterpret_cast< unsigned long long >(privateSnippetExecutor
) >> 32) & 0x3FF);
617 // sllx %o1, 32, %o1:
619 // sethi %lm(privateSnippetExecutor), %o2:
620 *p
++ = 0x15000000 | ((reinterpret_cast< unsigned long long >(privateSnippetExecutor
) >> 10) & 0x3FFFFF);
621 // or %o2, %lo(privateSnippetExecutor), %o2:
622 *p
++ = 0x9412A000 | (reinterpret_cast< unsigned long long >(privateSnippetExecutor
) & 0x3FF);
625 // sethi %hh(frameSize), %o4:
626 *p
++ = 0x19000000 | (*reinterpret_cast< unsigned long long * >(&frameSize
) >> 42);
627 // or %o4, %hm(frameSize), %o4:
628 *p
++ = 0x98132000 | ((*reinterpret_cast< unsigned long long * >(&frameSize
) >> 32) & 0x3FF);
631 // sethi %lm(frameSize), %o2:
632 *p
++ = 0x15000000 | ((*reinterpret_cast< unsigned long long * >(&frameSize
) >> 10) & 0x3FFFFF);
633 // or %o2, %lo(frameSize), %o2:
634 *p
++ = 0x9412A000 | (*reinterpret_cast< unsigned long long * >(&frameSize
) & 0x3FF);
637 // sethi %hi(vtableOffset), %o2:
638 *p
++ = 0x15000000 | (vtableOffset
>> 10);
639 // or %o2, %lo(vtableOffset), %o2:
640 *p
++ = 0x9412A000 | (vtableOffset
& 0x3FF);
641 // save %sp, -frameSize, %sp
642 //*p++ = 0x9DE3A000 | (*reinterpret_cast< unsigned int * >(&frameSize) & 0x1FFF);
645 // add %sp, 2047, %o1:
647 assert(reinterpret_cast< unsigned char * >(p
) - code
<= codeSnippetSize
);
648 return code
+ codeSnippetSize
;
653 struct bridges::cpp_uno::shared::VtableFactory::Slot
{ void * fn
; };
655 bridges::cpp_uno::shared::VtableFactory::Slot
*
656 bridges::cpp_uno::shared::VtableFactory::mapBlockToVtable(void * block
)
658 return static_cast< Slot
* >(block
) + 2;
661 std::size_t bridges::cpp_uno::shared::VtableFactory::getBlockSize(
664 return (slotCount
+ 2) * sizeof (Slot
) + slotCount
* codeSnippetSize
;
667 bridges::cpp_uno::shared::VtableFactory::Slot
*
668 bridges::cpp_uno::shared::VtableFactory::initializeBlock(
669 void * block
, sal_Int32 slotCount
, sal_Int32
,
670 typelib_InterfaceTypeDescription
*)
672 Slot
* slots
= mapBlockToVtable(block
);
673 slots
[-2].fn
= 0; //null
674 slots
[-1].fn
= 0; //destructor
675 return slots
+ slotCount
;
678 unsigned char * bridges::cpp_uno::shared::VtableFactory::addLocalFunctions(
679 Slot
** slots
, unsigned char * code
, sal_PtrDiff writetoexecdiff
,
680 typelib_InterfaceTypeDescription
const * type
, sal_Int32 functionOffset
,
681 sal_Int32 functionCount
, sal_Int32 vTableOffset
)
683 (*slots
) -= functionCount
;
685 for (sal_Int32 i
= 0; i
< type
->nMembers
; ++i
) {
686 typelib_TypeDescription
* member
= 0;
687 TYPELIB_DANGER_GET(&member
, type
->ppMembers
[i
]);
689 switch (member
->eTypeClass
) {
690 case typelib_TypeClass_INTERFACE_ATTRIBUTE
:
692 (s
++)->fn
= code
+ writetoexecdiff
;
694 code
, functionOffset
++, vTableOffset
,
695 CPPU_CURRENT_NAMESPACE::return_in_hidden_param(
697 typelib_InterfaceAttributeTypeDescription
* >(
698 member
)->pAttributeTypeRef
), 0);
700 if (!reinterpret_cast<
701 typelib_InterfaceAttributeTypeDescription
* >(
704 (s
++)->fn
= code
+ writetoexecdiff
;
705 code
= codeSnippet(code
, functionOffset
++, vTableOffset
, false, 1);
709 case typelib_TypeClass_INTERFACE_METHOD
:
710 (s
++)->fn
= code
+ writetoexecdiff
;
712 code
, functionOffset
++, vTableOffset
,
713 CPPU_CURRENT_NAMESPACE::return_in_hidden_param(
715 typelib_InterfaceMethodTypeDescription
* >(
716 member
)->pReturnTypeRef
),
718 typelib_InterfaceMethodTypeDescription
* >(
726 TYPELIB_DANGER_RELEASE(member
);
731 // use flush code from cc50_solaris_sparc
733 extern "C" void doFlushCode(unsigned long address
, unsigned long count
);
735 void bridges::cpp_uno::shared::VtableFactory::flushCode(
736 unsigned char const * begin
, unsigned char const * end
)
738 unsigned long n
= end
- begin
;
740 unsigned long adr
= reinterpret_cast< unsigned long >(begin
);
741 unsigned long off
= adr
& 7;
742 doFlushCode(adr
- off
, (n
+ off
+ 7) >> 3);
746 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */