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>
54 namespace CPPU_CURRENT_NAMESPACE
56 bool is_complex_struct(const typelib_TypeDescription
* type
)
58 const typelib_CompoundTypeDescription
* p
59 = reinterpret_cast< const typelib_CompoundTypeDescription
* >(type
);
60 for (sal_Int32 i
= 0; i
< p
->nMembers
; ++i
)
62 if (p
->ppTypeRefs
[i
]->eTypeClass
== typelib_TypeClass_STRUCT
||
63 p
->ppTypeRefs
[i
]->eTypeClass
== typelib_TypeClass_EXCEPTION
)
65 typelib_TypeDescription
* t
= 0;
66 TYPELIB_DANGER_GET(&t
, p
->ppTypeRefs
[i
]);
67 bool b
= is_complex_struct(t
);
68 TYPELIB_DANGER_RELEASE(t
);
73 else if (!bridges::cpp_uno::shared::isSimpleType(p
->ppTypeRefs
[i
]->eTypeClass
))
76 if (p
->pBaseTypeDescription
!= 0)
77 return is_complex_struct(&p
->pBaseTypeDescription
->aBase
);
81 bool return_in_hidden_param( typelib_TypeDescriptionReference
*pTypeRef
)
83 if (bridges::cpp_uno::shared::isSimpleType(pTypeRef
))
85 else if (pTypeRef
->eTypeClass
== typelib_TypeClass_STRUCT
||
86 pTypeRef
->eTypeClass
== typelib_TypeClass_EXCEPTION
)
88 typelib_TypeDescription
* pTypeDescr
= 0;
89 TYPELIB_DANGER_GET( &pTypeDescr
, pTypeRef
);
91 //A Composite Type not larger than 16 bytes is returned in up to two GPRs
92 bool bRet
= pTypeDescr
->nSize
> 16 || is_complex_struct(pTypeDescr
);
94 TYPELIB_DANGER_RELEASE( pTypeDescr
);
104 static typelib_TypeClass
cpp2uno_call(
105 bridges::cpp_uno::shared::CppInterfaceProxy
* pThis
,
106 const typelib_TypeDescription
* pMemberTypeDescr
,
107 typelib_TypeDescriptionReference
* pReturnTypeRef
, // 0 indicates void return
108 sal_Int32 nParams
, typelib_MethodParameter
* pParams
,
109 void ** gpreg
, void ** fpreg
, void ** ovrflw
,
110 sal_uInt64
* pRegisterReturn
/* space for register return */ )
112 /* Most MIPS ABIs view the arguments as a struct, of which the
113 first N words go in registers and the rest go on the stack. If I < N, the
114 With word might go in With integer argument register or the With
115 floating-point one. For these ABIs, we only need to remember the number
116 of words passed so far. We are interested only in n64 ABI,so it is the
119 unsigned int nREG
= 0;
122 fprintf(stderr
, "cpp2uno_call:begin\n");
126 typelib_TypeDescription
* pReturnTypeDescr
= 0;
128 TYPELIB_DANGER_GET( &pReturnTypeDescr
, pReturnTypeRef
);
130 void * pUnoReturn
= 0;
131 void * pCppReturn
= 0; // complex return ptr: if != 0 && != pUnoReturn, reconversion need
133 if (pReturnTypeDescr
)
135 if (CPPU_CURRENT_NAMESPACE::return_in_hidden_param( pReturnTypeRef
) )
137 pCppReturn
= gpreg
[nREG
]; // complex return via ptr (pCppReturn)
140 pUnoReturn
= ( bridges::cpp_uno::shared::relatesToInterfaceType( pReturnTypeDescr
)
141 ? alloca( pReturnTypeDescr
->nSize
)
142 : pCppReturn
); // direct way
144 fprintf(stderr
, "cpp2uno_call:complexreturn\n");
149 pUnoReturn
= pRegisterReturn
; // direct way for simple types
151 fprintf(stderr
, "cpp2uno_call:simplereturn\n");
160 static_assert(sizeof(void *) == sizeof(sal_Int64
), "### unexpected size!");
162 void ** pUnoArgs
= (void **)alloca( 4 * sizeof(void *) * nParams
);
163 void ** pCppArgs
= pUnoArgs
+ nParams
;
164 // indices of values this have to be converted (interface conversion cpp<=>uno)
165 sal_Int32
* pTempIndices
= (sal_Int32
*)(pUnoArgs
+ (2 * nParams
));
166 // type descriptions for reconversions
167 typelib_TypeDescription
** ppTempParamTypeDescr
= (typelib_TypeDescription
**)(pUnoArgs
+ (3 * nParams
));
169 sal_Int32 nTempIndices
= 0;
172 fprintf(stderr
, "cpp2uno_call:nParams=%d\n", nParams
);
174 for ( sal_Int32 nPos
= 0; nPos
< nParams
; ++nPos
)
176 const typelib_MethodParameter
& rParam
= pParams
[nPos
];
178 typelib_TypeDescription
* pParamTypeDescr
= 0;
179 TYPELIB_DANGER_GET( &pParamTypeDescr
, rParam
.pTypeRef
);
181 if (!rParam
.bOut
&& bridges::cpp_uno::shared::isSimpleType( pParamTypeDescr
)) // value
184 fprintf(stderr
, "cpp2uno_call:Param %u, type %u\n", nPos
, pParamTypeDescr
->eTypeClass
);
186 switch (pParamTypeDescr
->eTypeClass
)
188 case typelib_TypeClass_FLOAT
:
189 case typelib_TypeClass_DOUBLE
:
190 if (nREG
< MAX_FP_REGS
) {
192 fprintf(stderr
, "cpp2uno_call:fpr=%p\n", fpreg
[nREG
]);
194 pCppArgs
[nPos
] = &(fpreg
[nREG
]);
195 pUnoArgs
[nPos
] = &(fpreg
[nREG
]);
198 fprintf(stderr
, "cpp2uno_call:fpr=%p\n", ovrflw
[nREG
- MAX_FP_REGS
]);
200 pCppArgs
[nPos
] = &(ovrflw
[nREG
- MAX_FP_REGS
]);
201 pUnoArgs
[nPos
] = &(ovrflw
[nREG
- MAX_FP_REGS
]);
208 if (nREG
< MAX_GP_REGS
) {
210 fprintf(stderr
, "cpp2uno_call:gpr=%p\n", gpreg
[nREG
]);
212 pCppArgs
[nPos
] = &(gpreg
[nREG
]);
213 pUnoArgs
[nPos
] = &(gpreg
[nREG
]);
216 fprintf(stderr
, "cpp2uno_call:gpr=%p\n", ovrflw
[nREG
- MAX_GP_REGS
]);
218 pCppArgs
[nPos
] = &(ovrflw
[nREG
- MAX_GP_REGS
]);
219 pUnoArgs
[nPos
] = &(ovrflw
[nREG
- MAX_GP_REGS
]);
226 TYPELIB_DANGER_RELEASE( pParamTypeDescr
);
228 else // ptr to complex value | ref
231 fprintf(stderr
,"cpp2uno_call:ptr|ref\n");
234 if (nREG
< MAX_GP_REGS
) {
235 pCppArgs
[nPos
] = pCppStack
= gpreg
[nREG
];
237 pCppArgs
[nPos
] = pCppStack
= ovrflw
[nREG
- MAX_GP_REGS
];
241 fprintf(stderr
, "cpp2uno_call:pCppStack=%p\n", pCppStack
);
244 if (! rParam
.bIn
) // is pure out
246 // uno out is unconstructed mem!
247 pUnoArgs
[nPos
] = alloca( pParamTypeDescr
->nSize
);
248 pTempIndices
[nTempIndices
] = nPos
;
249 // will be released at reconversion
250 ppTempParamTypeDescr
[nTempIndices
++] = pParamTypeDescr
;
253 else if (bridges::cpp_uno::shared::relatesToInterfaceType( pParamTypeDescr
))
255 uno_copyAndConvertData( pUnoArgs
[nPos
] = alloca( pParamTypeDescr
->nSize
),
256 pCppStack
, pParamTypeDescr
,
257 pThis
->getBridge()->getCpp2Uno() );
258 pTempIndices
[nTempIndices
] = nPos
; // has to be reconverted
259 // will be released at reconversion
260 ppTempParamTypeDescr
[nTempIndices
++] = pParamTypeDescr
;
262 fprintf(stderr
, "cpp2uno_call:related to interface,%p,%d,pUnoargs[%d]=%p\n",
263 pCppStack
, pParamTypeDescr
->nSize
, nPos
, pUnoArgs
[nPos
]);
268 pUnoArgs
[nPos
] = pCppStack
;
270 fprintf(stderr
, "cpp2uno_call:direct,pUnoArgs[%d]=%p\n", nPos
, pUnoArgs
[nPos
]);
273 TYPELIB_DANGER_RELEASE( pParamTypeDescr
);
278 fprintf(stderr
, "cpp2uno_call2,%p,unoargs=%p\n", pThis
->getUnoI()->pDispatcher
, pUnoArgs
);
282 uno_Any aUnoExc
; // Any will be constructed by callee
283 uno_Any
* pUnoExc
= &aUnoExc
;
285 // invoke uno dispatch call
286 (*pThis
->getUnoI()->pDispatcher
)( pThis
->getUnoI(), pMemberTypeDescr
, pUnoReturn
, pUnoArgs
, &pUnoExc
);
288 fprintf(stderr
, "cpp2uno_call2,after dispatch\n");
291 // in case an exception occurred...
294 // destruct temporary in/inout params
295 for ( ; nTempIndices
--; )
297 sal_Int32 nIndex
= pTempIndices
[nTempIndices
];
299 if (pParams
[nIndex
].bIn
) // is in/inout => was constructed
300 uno_destructData( pUnoArgs
[nIndex
], ppTempParamTypeDescr
[nTempIndices
], 0 );
301 TYPELIB_DANGER_RELEASE( ppTempParamTypeDescr
[nTempIndices
] );
303 if (pReturnTypeDescr
)
304 TYPELIB_DANGER_RELEASE( pReturnTypeDescr
);
306 CPPU_CURRENT_NAMESPACE::raiseException( &aUnoExc
, pThis
->getBridge()->getUno2Cpp() );
307 // has to destruct the any
309 return typelib_TypeClass_VOID
;
311 else // else no exception occurred...
314 for ( ; nTempIndices
--; )
316 sal_Int32 nIndex
= pTempIndices
[nTempIndices
];
317 typelib_TypeDescription
* pParamTypeDescr
= ppTempParamTypeDescr
[nTempIndices
];
319 if (pParams
[nIndex
].bOut
) // inout/out
321 // convert and assign
322 uno_destructData( pCppArgs
[nIndex
], pParamTypeDescr
, cpp_release
);
323 uno_copyAndConvertData( pCppArgs
[nIndex
], pUnoArgs
[nIndex
], pParamTypeDescr
,
324 pThis
->getBridge()->getUno2Cpp() );
326 // destroy temp uno param
327 uno_destructData( pUnoArgs
[nIndex
], pParamTypeDescr
, 0 );
329 TYPELIB_DANGER_RELEASE( pParamTypeDescr
);
332 if (pCppReturn
) // has complex return
334 if (pUnoReturn
!= pCppReturn
) // needs reconversion
336 uno_copyAndConvertData( pCppReturn
, pUnoReturn
, pReturnTypeDescr
,
337 pThis
->getBridge()->getUno2Cpp() );
338 // destroy temp uno return
339 uno_destructData( pUnoReturn
, pReturnTypeDescr
, 0 );
341 // complex return ptr is set to return reg
342 *(void **)pRegisterReturn
= pCppReturn
;
344 if (pReturnTypeDescr
)
346 typelib_TypeClass eRet
= (typelib_TypeClass
)pReturnTypeDescr
->eTypeClass
;
347 TYPELIB_DANGER_RELEASE( pReturnTypeDescr
);
351 return typelib_TypeClass_VOID
;
357 * is called on incoming vtable calls
358 * (called by asm snippets)
360 typelib_TypeClass
cpp_vtable_call(
361 sal_Int32 nFunctionIndex
,
362 sal_Int32 nVtableOffset
,
363 void ** gpreg
, void ** fpreg
, void ** ovrflw
,
364 sal_uInt64
* pRegisterReturn
/* space for register return */ )
366 static_assert( sizeof(sal_Int64
)==sizeof(void *), "### unexpected!" );
369 fprintf(stderr
, "in cpp_vtable_call nFunctionIndex is %d\n", nFunctionIndex
);
370 fprintf(stderr
, "in cpp_vtable_call nVtableOffset is %d\n", nVtableOffset
);
371 fprintf(stderr
, "in cpp_vtable_call gp=%p, fp=%p, ov=%p\n", gpreg
, fpreg
, ovrflw
);
374 // gpreg: [ret *], this, [other gpr params]
375 // fpreg: [fpr params]
376 // ovrflw: [gpr or fpr params (properly aligned)]
378 if (nFunctionIndex
& 0x80000000 )
380 nFunctionIndex
&= 0x7fffffff;
388 fprintf(stderr
, "cpp_vtable_call, pThis=%p, nFunctionIndex=%d, nVtableOffset=%d\n",
389 pThis
, nFunctionIndex
, nVtableOffset
);
392 pThis
= static_cast< char * >(pThis
) - nVtableOffset
;
393 bridges::cpp_uno::shared::CppInterfaceProxy
* pCppI
=
394 bridges::cpp_uno::shared::CppInterfaceProxy::castInterfaceToProxy( pThis
);
396 fprintf(stderr
, "cpp_vtable_call, pCppI=%p\n", pCppI
);
399 typelib_InterfaceTypeDescription
* pTypeDescr
= pCppI
->getTypeDescr();
401 if (nFunctionIndex
>= pTypeDescr
->nMapFunctionIndexToMemberIndex
)
405 "illegal " << OUString::unacquired(&pTypeDescr
->aBase
.pTypeName
)
406 << " vtable index " << nFunctionIndex
<< "/"
407 << pTypeDescr
->nMapFunctionIndexToMemberIndex
);
408 throw RuntimeException(
409 ("illegal " + OUString::unacquired(&pTypeDescr
->aBase
.pTypeName
)
410 + " vtable index " + OUString::number(nFunctionIndex
) + "/"
411 + OUString::number(pTypeDescr
->nMapFunctionIndexToMemberIndex
)),
412 (XInterface
*)pThis
);
415 // determine called method
416 sal_Int32 nMemberPos
= pTypeDescr
->pMapFunctionIndexToMemberIndex
[nFunctionIndex
];
417 assert(nMemberPos
< pTypeDescr
->nAllMembers
);
419 TypeDescription
aMemberDescr( pTypeDescr
->ppAllMembers
[nMemberPos
] );
422 OString
cstr( OUStringToOString( aMemberDescr
.get()->pTypeName
, RTL_TEXTENCODING_ASCII_US
) );
423 fprintf(stderr
, "calling %s, nFunctionIndex=%d\n", cstr
.getStr(), nFunctionIndex
);
425 typelib_TypeClass eRet
;
426 switch (aMemberDescr
.get()->eTypeClass
)
428 case typelib_TypeClass_INTERFACE_ATTRIBUTE
:
431 fprintf(stderr
, "cpp_vtable_call interface attribute\n");
433 typelib_TypeDescriptionReference
*pAttrTypeRef
=
434 reinterpret_cast<typelib_InterfaceAttributeTypeDescription
*>( aMemberDescr
.get() )->pAttributeTypeRef
;
436 if (pTypeDescr
->pMapMemberIndexToFunctionIndex
[nMemberPos
] == nFunctionIndex
)
439 eRet
= cpp2uno_call( pCppI
, aMemberDescr
.get(), pAttrTypeRef
,
441 gpreg
, fpreg
, ovrflw
, pRegisterReturn
);
446 typelib_MethodParameter aParam
;
447 aParam
.pTypeRef
= pAttrTypeRef
;
448 aParam
.bIn
= sal_True
;
449 aParam
.bOut
= sal_False
;
451 eRet
= cpp2uno_call( pCppI
, aMemberDescr
.get(),
452 0, // indicates void return
454 gpreg
, fpreg
, ovrflw
, pRegisterReturn
);
458 case typelib_TypeClass_INTERFACE_METHOD
:
461 fprintf(stderr
, "cpp_vtable_call interface method\n");
464 switch (nFunctionIndex
)
468 fprintf(stderr
, "cpp_vtable_call method acquire\n");
470 pCppI
->acquireProxy(); // non virtual call!
471 eRet
= typelib_TypeClass_VOID
;
475 fprintf(stderr
, "cpp_vtable_call method release\n");
477 pCppI
->releaseProxy(); // non virtual call!
478 eRet
= typelib_TypeClass_VOID
;
480 case 0: // queryInterface() opt
483 fprintf(stderr
, "cpp_vtable_call method query interface opt\n");
485 typelib_TypeDescription
* pTD
= 0;
486 TYPELIB_DANGER_GET( &pTD
, reinterpret_cast< Type
* >( gpreg
[2] )->getTypeLibType() );
489 XInterface
* pInterface
= 0;
490 (*pCppI
->getBridge()->getCppEnv()->getRegisteredInterface
)
491 ( pCppI
->getBridge()->getCppEnv(),
492 (void **)&pInterface
,
493 pCppI
->getOid().pData
,
494 reinterpret_cast<typelib_InterfaceTypeDescription
*>( pTD
) );
498 ::uno_any_construct( reinterpret_cast< uno_Any
* >( gpreg
[0] ),
499 &pInterface
, pTD
, cpp_acquire
);
501 pInterface
->release();
502 TYPELIB_DANGER_RELEASE( pTD
);
504 reinterpret_cast<void **>( pRegisterReturn
)[0] = gpreg
[0];
505 eRet
= typelib_TypeClass_ANY
;
508 TYPELIB_DANGER_RELEASE( pTD
);
510 } // else perform queryInterface()
513 fprintf(stderr
, "cpp_vtable_call method query interface\n");
515 typelib_InterfaceMethodTypeDescription
*pMethodTD
=
516 reinterpret_cast<typelib_InterfaceMethodTypeDescription
*>( aMemberDescr
.get() );
518 eRet
= cpp2uno_call( pCppI
, aMemberDescr
.get(),
519 pMethodTD
->pReturnTypeRef
,
522 gpreg
, fpreg
, ovrflw
, pRegisterReturn
);
529 fprintf(stderr
, "cpp_vtable_call no member\n");
531 throw RuntimeException( "no member description found!", (XInterface
*)pThis
);
538 extern "C" void privateSnippetExecutor( ... );
540 int const codeSnippetSize
= 0x44;
542 unsigned char * codeSnippet( unsigned char * code
,
543 sal_Int32 functionIndex
, sal_Int32 vtableOffset
,
544 bool bHasHiddenParam
)
547 fprintf(stderr
,"in codeSnippet functionIndex is %d\n", functionIndex
);
548 fprintf(stderr
,"in codeSnippet vtableOffset is %d\n", vtableOffset
);
552 if ( bHasHiddenParam
)
553 functionIndex
|= 0x80000000;
555 unsigned int * p
= (unsigned int *) code
;
557 assert((((unsigned long)code
) & 0x3) == 0 ); //aligned to 4 otherwise a mistake
559 /* generate this code */
562 0: 3c020000 lui v0,0x0
563 4: 34420000 ori v0,v0,0x0
564 # privateSnippetExecutor
565 8: 3c0c0000 lui t0,0x0
566 c: 358c0000 ori t0,t0,0x0
567 10: 000c6438 dsll t0,t0,0x10
568 14: 358c0000 ori t0,t0,0x0
569 18: 000c6438 dsll t0,t0,0x10
570 1c: 358c0000 ori t0,t0,0x0
572 20: 3c190000 lui t9,0x0
573 24: 37390000 ori t9,t9,0x0
574 28: 0019cc38 dsll t9,t9,0x10
575 2c: 37390000 ori t9,t9,0x0
576 30: 0019cc38 dsll t9,t9,0x10
577 34: 37390000 ori t9,t9,0x0
579 38: 3c030000 lui v1,0x0
581 40: 34630000 ori v1,v1,0x0
584 * p
++ = 0x3c020000 | ((functionIndex
>>16) & 0x0000ffff);
585 * p
++ = 0x34420000 | (functionIndex
& 0x0000ffff);
586 * p
++ = 0x3c0c0000 | ((((unsigned long)privateSnippetExecutor
) >> 48) & 0x0000ffff);
587 * p
++ = 0x358c0000 | ((((unsigned long)privateSnippetExecutor
) >> 32) & 0x0000ffff);
589 * p
++ = 0x358c0000 | ((((unsigned long)privateSnippetExecutor
) >> 16) & 0x0000ffff);
591 * p
++ = 0x358c0000 | (((unsigned long)privateSnippetExecutor
) & 0x0000ffff);
592 * p
++ = 0x3c190000 | ((((unsigned long)cpp_vtable_call
) >> 48) & 0x0000ffff);
593 * p
++ = 0x37390000 | ((((unsigned long)cpp_vtable_call
) >> 32) & 0x0000ffff);
595 * p
++ = 0x37390000 | ((((unsigned long)cpp_vtable_call
) >> 16) & 0x0000ffff);
597 * p
++ = 0x37390000 | (((unsigned long)cpp_vtable_call
) & 0x0000ffff);
598 * p
++ = 0x3c030000 | ((vtableOffset
>>16) & 0x0000ffff);
600 * p
++ = 0x34630000 | (vtableOffset
& 0x0000ffff);
601 return (code
+ codeSnippetSize
);
608 void bridges::cpp_uno::shared::VtableFactory::flushCode(unsigned char const *bptr
, unsigned char const *eptr
)
613 sysmips(FLUSH_CACHE
, 0, 0, 0);
615 cacheflush((long) bptr
, (long) eptr
, 0);
619 struct bridges::cpp_uno::shared::VtableFactory::Slot
{ void * fn
; };
621 bridges::cpp_uno::shared::VtableFactory::Slot
*
622 bridges::cpp_uno::shared::VtableFactory::mapBlockToVtable(void * block
)
624 return static_cast< Slot
* >(block
) + 2;
628 std::size_t bridges::cpp_uno::shared::VtableFactory::getBlockSize(
631 return (slotCount
+ 2) * sizeof (Slot
) + slotCount
* codeSnippetSize
;
634 bridges::cpp_uno::shared::VtableFactory::Slot
*
635 bridges::cpp_uno::shared::VtableFactory::initializeBlock(
636 void * block
, sal_Int32 slotCount
, sal_Int32
,
637 typelib_InterfaceTypeDescription
*)
639 Slot
* slots
= mapBlockToVtable(block
);
640 slots
[-2].fn
= 0; //null
641 slots
[-1].fn
= 0; //destructor
642 return slots
+ slotCount
;
645 unsigned char * bridges::cpp_uno::shared::VtableFactory::addLocalFunctions(
646 Slot
** slots
, unsigned char * code
, sal_PtrDiff writetoexecdiff
,
647 typelib_InterfaceTypeDescription
const * type
, sal_Int32 functionOffset
,
648 sal_Int32 functionCount
, sal_Int32 vtableOffset
)
650 (*slots
) -= functionCount
;
654 fprintf(stderr
, "in addLocalFunctions functionOffset is %d\n", functionOffset
);
655 fprintf(stderr
, "in addLocalFunctions vtableOffset is %d\n", vtableOffset
);
656 fprintf(stderr
, "nMembers=%d\n", type
->nMembers
);
660 for (sal_Int32 i
= 0; i
< type
->nMembers
; ++i
) {
661 typelib_TypeDescription
* member
= 0;
662 TYPELIB_DANGER_GET(&member
, type
->ppMembers
[i
]);
664 switch (member
->eTypeClass
) {
665 case typelib_TypeClass_INTERFACE_ATTRIBUTE
:
667 (s
++)->fn
= code
+ writetoexecdiff
;
669 code
, functionOffset
++, vtableOffset
,
670 CPPU_CURRENT_NAMESPACE::return_in_hidden_param(
672 typelib_InterfaceAttributeTypeDescription
* >(
673 member
)->pAttributeTypeRef
));
676 if (!reinterpret_cast<
677 typelib_InterfaceAttributeTypeDescription
* >(
680 (s
++)->fn
= code
+ writetoexecdiff
;
681 code
= codeSnippet(code
, functionOffset
++, vtableOffset
, false);
685 case typelib_TypeClass_INTERFACE_METHOD
:
686 (s
++)->fn
= code
+ writetoexecdiff
;
688 code
, functionOffset
++, vtableOffset
,
689 CPPU_CURRENT_NAMESPACE::return_in_hidden_param(
691 typelib_InterfaceMethodTypeDescription
* >(
692 member
)->pReturnTypeRef
));
699 TYPELIB_DANGER_RELEASE(member
);
704 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */