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"
35 using namespace com::sun::star::uno
;
40 #include <rtl/strbuf.hxx>
41 #include <rtl/ustrbuf.hxx>
42 using namespace ::std
;
43 using namespace ::osl
;
44 using namespace ::rtl
;
48 #include <sys/sysmips.h>
55 namespace CPPU_CURRENT_NAMESPACE
57 bool is_complex_struct(const typelib_TypeDescription
* type
)
59 const typelib_CompoundTypeDescription
* p
60 = reinterpret_cast< const typelib_CompoundTypeDescription
* >(type
);
61 for (sal_Int32 i
= 0; i
< p
->nMembers
; ++i
)
63 if (p
->ppTypeRefs
[i
]->eTypeClass
== typelib_TypeClass_STRUCT
||
64 p
->ppTypeRefs
[i
]->eTypeClass
== typelib_TypeClass_EXCEPTION
)
66 typelib_TypeDescription
* t
= 0;
67 TYPELIB_DANGER_GET(&t
, p
->ppTypeRefs
[i
]);
68 bool b
= is_complex_struct(t
);
69 TYPELIB_DANGER_RELEASE(t
);
74 else if (!bridges::cpp_uno::shared::isSimpleType(p
->ppTypeRefs
[i
]->eTypeClass
))
77 if (p
->pBaseTypeDescription
!= 0)
78 return is_complex_struct(&p
->pBaseTypeDescription
->aBase
);
82 bool return_in_hidden_param( typelib_TypeDescriptionReference
*pTypeRef
)
84 if (bridges::cpp_uno::shared::isSimpleType(pTypeRef
))
86 else if (pTypeRef
->eTypeClass
== typelib_TypeClass_STRUCT
||
87 pTypeRef
->eTypeClass
== typelib_TypeClass_EXCEPTION
)
89 typelib_TypeDescription
* pTypeDescr
= 0;
90 TYPELIB_DANGER_GET( &pTypeDescr
, pTypeRef
);
92 //A Composite Type not larger than 16 bytes is returned in up to two GPRs
93 bool bRet
= pTypeDescr
->nSize
> 16 || is_complex_struct(pTypeDescr
);
95 TYPELIB_DANGER_RELEASE( pTypeDescr
);
105 static typelib_TypeClass
cpp2uno_call(
106 bridges::cpp_uno::shared::CppInterfaceProxy
* pThis
,
107 const typelib_TypeDescription
* pMemberTypeDescr
,
108 typelib_TypeDescriptionReference
* pReturnTypeRef
, // 0 indicates void return
109 sal_Int32 nParams
, typelib_MethodParameter
* pParams
,
110 void ** gpreg
, void ** fpreg
, void ** ovrflw
,
111 sal_uInt64
* pRegisterReturn
/* space for register return */ )
113 /* Most MIPS ABIs view the arguments as a struct, of which the
114 first N words go in registers and the rest go on the stack. If I < N, the
115 With word might go in With integer argument register or the With
116 floating-point one. For these ABIs, we only need to remember the number
117 of words passed so far. We are interested only in n64 ABI,so it is the
120 unsigned int nREG
= 0;
123 fprintf(stderr
, "cpp2uno_call:begin\n");
127 typelib_TypeDescription
* pReturnTypeDescr
= 0;
129 TYPELIB_DANGER_GET( &pReturnTypeDescr
, pReturnTypeRef
);
131 void * pUnoReturn
= 0;
132 void * pCppReturn
= 0; // complex return ptr: if != 0 && != pUnoReturn, reconversion need
134 if (pReturnTypeDescr
)
136 if (CPPU_CURRENT_NAMESPACE::return_in_hidden_param( pReturnTypeRef
) )
138 pCppReturn
= gpreg
[nREG
]; // complex return via ptr (pCppReturn)
141 pUnoReturn
= ( bridges::cpp_uno::shared::relatesToInterfaceType( pReturnTypeDescr
)
142 ? alloca( pReturnTypeDescr
->nSize
)
143 : pCppReturn
); // direct way
145 fprintf(stderr
, "cpp2uno_call:complexreturn\n");
150 pUnoReturn
= pRegisterReturn
; // direct way for simple types
152 fprintf(stderr
, "cpp2uno_call:simplereturn\n");
161 static_assert(sizeof(void *) == sizeof(sal_Int64
), "### unexpected size!");
163 void ** pUnoArgs
= (void **)alloca( 4 * sizeof(void *) * nParams
);
164 void ** pCppArgs
= pUnoArgs
+ nParams
;
165 // indices of values this have to be converted (interface conversion cpp<=>uno)
166 sal_Int32
* pTempIndices
= (sal_Int32
*)(pUnoArgs
+ (2 * nParams
));
167 // type descriptions for reconversions
168 typelib_TypeDescription
** ppTempParamTypeDescr
= (typelib_TypeDescription
**)(pUnoArgs
+ (3 * nParams
));
170 sal_Int32 nTempIndices
= 0;
173 fprintf(stderr
, "cpp2uno_call:nParams=%d\n", nParams
);
175 for ( sal_Int32 nPos
= 0; nPos
< nParams
; ++nPos
)
177 const typelib_MethodParameter
& rParam
= pParams
[nPos
];
179 typelib_TypeDescription
* pParamTypeDescr
= 0;
180 TYPELIB_DANGER_GET( &pParamTypeDescr
, rParam
.pTypeRef
);
182 if (!rParam
.bOut
&& bridges::cpp_uno::shared::isSimpleType( pParamTypeDescr
)) // value
185 fprintf(stderr
, "cpp2uno_call:Param %u, type %u\n", nPos
, pParamTypeDescr
->eTypeClass
);
187 switch (pParamTypeDescr
->eTypeClass
)
189 case typelib_TypeClass_FLOAT
:
190 case typelib_TypeClass_DOUBLE
:
191 if (nREG
< MAX_FP_REGS
) {
193 fprintf(stderr
, "cpp2uno_call:fpr=%p\n", fpreg
[nREG
]);
195 pCppArgs
[nPos
] = &(fpreg
[nREG
]);
196 pUnoArgs
[nPos
] = &(fpreg
[nREG
]);
199 fprintf(stderr
, "cpp2uno_call:fpr=%p\n", ovrflw
[nREG
- MAX_FP_REGS
]);
201 pCppArgs
[nPos
] = &(ovrflw
[nREG
- MAX_FP_REGS
]);
202 pUnoArgs
[nPos
] = &(ovrflw
[nREG
- MAX_FP_REGS
]);
209 if (nREG
< MAX_GP_REGS
) {
211 fprintf(stderr
, "cpp2uno_call:gpr=%p\n", gpreg
[nREG
]);
213 pCppArgs
[nPos
] = &(gpreg
[nREG
]);
214 pUnoArgs
[nPos
] = &(gpreg
[nREG
]);
217 fprintf(stderr
, "cpp2uno_call:gpr=%p\n", ovrflw
[nREG
- MAX_GP_REGS
]);
219 pCppArgs
[nPos
] = &(ovrflw
[nREG
- MAX_GP_REGS
]);
220 pUnoArgs
[nPos
] = &(ovrflw
[nREG
- MAX_GP_REGS
]);
227 TYPELIB_DANGER_RELEASE( pParamTypeDescr
);
229 else // ptr to complex value | ref
232 fprintf(stderr
,"cpp2uno_call:ptr|ref\n");
235 if (nREG
< MAX_GP_REGS
) {
236 pCppArgs
[nPos
] = pCppStack
= gpreg
[nREG
];
238 pCppArgs
[nPos
] = pCppStack
= ovrflw
[nREG
- MAX_GP_REGS
];
242 fprintf(stderr
, "cpp2uno_call:pCppStack=%p\n", pCppStack
);
245 if (! rParam
.bIn
) // is pure out
247 // uno out is unconstructed mem!
248 pUnoArgs
[nPos
] = alloca( pParamTypeDescr
->nSize
);
249 pTempIndices
[nTempIndices
] = nPos
;
250 // will be released at reconversion
251 ppTempParamTypeDescr
[nTempIndices
++] = pParamTypeDescr
;
254 else if (bridges::cpp_uno::shared::relatesToInterfaceType( pParamTypeDescr
))
256 uno_copyAndConvertData( pUnoArgs
[nPos
] = alloca( pParamTypeDescr
->nSize
),
257 pCppStack
, pParamTypeDescr
,
258 pThis
->getBridge()->getCpp2Uno() );
259 pTempIndices
[nTempIndices
] = nPos
; // has to be reconverted
260 // will be released at reconversion
261 ppTempParamTypeDescr
[nTempIndices
++] = pParamTypeDescr
;
263 fprintf(stderr
, "cpp2uno_call:related to interface,%p,%d,pUnoargs[%d]=%p\n",
264 pCppStack
, pParamTypeDescr
->nSize
, nPos
, pUnoArgs
[nPos
]);
269 pUnoArgs
[nPos
] = pCppStack
;
271 fprintf(stderr
, "cpp2uno_call:direct,pUnoArgs[%d]=%p\n", nPos
, pUnoArgs
[nPos
]);
274 TYPELIB_DANGER_RELEASE( pParamTypeDescr
);
279 fprintf(stderr
, "cpp2uno_call2,%p,unoargs=%p\n", pThis
->getUnoI()->pDispatcher
, pUnoArgs
);
283 uno_Any aUnoExc
; // Any will be constructed by callee
284 uno_Any
* pUnoExc
= &aUnoExc
;
286 // invoke uno dispatch call
287 (*pThis
->getUnoI()->pDispatcher
)( pThis
->getUnoI(), pMemberTypeDescr
, pUnoReturn
, pUnoArgs
, &pUnoExc
);
289 fprintf(stderr
, "cpp2uno_call2,after dispatch\n");
292 // in case an exception occurred...
295 // destruct temporary in/inout params
296 for ( ; nTempIndices
--; )
298 sal_Int32 nIndex
= pTempIndices
[nTempIndices
];
300 if (pParams
[nIndex
].bIn
) // is in/inout => was constructed
301 uno_destructData( pUnoArgs
[nIndex
], ppTempParamTypeDescr
[nTempIndices
], 0 );
302 TYPELIB_DANGER_RELEASE( ppTempParamTypeDescr
[nTempIndices
] );
304 if (pReturnTypeDescr
)
305 TYPELIB_DANGER_RELEASE( pReturnTypeDescr
);
307 CPPU_CURRENT_NAMESPACE::raiseException( &aUnoExc
, pThis
->getBridge()->getUno2Cpp() );
308 // has to destruct the any
310 return typelib_TypeClass_VOID
;
312 else // else no exception occurred...
315 for ( ; nTempIndices
--; )
317 sal_Int32 nIndex
= pTempIndices
[nTempIndices
];
318 typelib_TypeDescription
* pParamTypeDescr
= ppTempParamTypeDescr
[nTempIndices
];
320 if (pParams
[nIndex
].bOut
) // inout/out
322 // convert and assign
323 uno_destructData( pCppArgs
[nIndex
], pParamTypeDescr
, cpp_release
);
324 uno_copyAndConvertData( pCppArgs
[nIndex
], pUnoArgs
[nIndex
], pParamTypeDescr
,
325 pThis
->getBridge()->getUno2Cpp() );
327 // destroy temp uno param
328 uno_destructData( pUnoArgs
[nIndex
], pParamTypeDescr
, 0 );
330 TYPELIB_DANGER_RELEASE( pParamTypeDescr
);
333 if (pCppReturn
) // has complex return
335 if (pUnoReturn
!= pCppReturn
) // needs reconversion
337 uno_copyAndConvertData( pCppReturn
, pUnoReturn
, pReturnTypeDescr
,
338 pThis
->getBridge()->getUno2Cpp() );
339 // destroy temp uno return
340 uno_destructData( pUnoReturn
, pReturnTypeDescr
, 0 );
342 // complex return ptr is set to return reg
343 *(void **)pRegisterReturn
= pCppReturn
;
345 if (pReturnTypeDescr
)
347 typelib_TypeClass eRet
= (typelib_TypeClass
)pReturnTypeDescr
->eTypeClass
;
348 TYPELIB_DANGER_RELEASE( pReturnTypeDescr
);
352 return typelib_TypeClass_VOID
;
358 * is called on incoming vtable calls
359 * (called by asm snippets)
361 typelib_TypeClass
cpp_vtable_call(
362 sal_Int32 nFunctionIndex
,
363 sal_Int32 nVtableOffset
,
364 void ** gpreg
, void ** fpreg
, void ** ovrflw
,
365 sal_uInt64
* pRegisterReturn
/* space for register return */ )
367 static_assert( sizeof(sal_Int64
)==sizeof(void *), "### unexpected!" );
370 fprintf(stderr
, "in cpp_vtable_call nFunctionIndex is %d\n", nFunctionIndex
);
371 fprintf(stderr
, "in cpp_vtable_call nVtableOffset is %d\n", nVtableOffset
);
372 fprintf(stderr
, "in cpp_vtable_call gp=%p, fp=%p, ov=%p\n", gpreg
, fpreg
, ovrflw
);
375 // gpreg: [ret *], this, [other gpr params]
376 // fpreg: [fpr params]
377 // ovrflw: [gpr or fpr params (properly aligned)]
379 if (nFunctionIndex
& 0x80000000 )
381 nFunctionIndex
&= 0x7fffffff;
389 fprintf(stderr
, "cpp_vtable_call, pThis=%p, nFunctionIndex=%d, nVtableOffset=%d\n",
390 pThis
, nFunctionIndex
, nVtableOffset
);
393 pThis
= static_cast< char * >(pThis
) - nVtableOffset
;
394 bridges::cpp_uno::shared::CppInterfaceProxy
* pCppI
=
395 bridges::cpp_uno::shared::CppInterfaceProxy::castInterfaceToProxy( pThis
);
397 fprintf(stderr
, "cpp_vtable_call, pCppI=%p\n", pCppI
);
400 typelib_InterfaceTypeDescription
* pTypeDescr
= pCppI
->getTypeDescr();
402 if (nFunctionIndex
>= pTypeDescr
->nMapFunctionIndexToMemberIndex
)
406 "illegal " << OUString::unacquired(&pTypeDescr
->aBase
.pTypeName
)
407 << " vtable index " << nFunctionIndex
<< "/"
408 << pTypeDescr
->nMapFunctionIndexToMemberIndex
);
409 throw RuntimeException(
410 ("illegal " + OUString::unacquired(&pTypeDescr
->aBase
.pTypeName
)
411 + " vtable index " + OUString::number(nFunctionIndex
) + "/"
412 + OUString::number(pTypeDescr
->nMapFunctionIndexToMemberIndex
)),
413 (XInterface
*)pThis
);
416 // determine called method
417 sal_Int32 nMemberPos
= pTypeDescr
->pMapFunctionIndexToMemberIndex
[nFunctionIndex
];
418 assert(nMemberPos
< pTypeDescr
->nAllMembers
);
420 TypeDescription
aMemberDescr( pTypeDescr
->ppAllMembers
[nMemberPos
] );
423 OString
cstr( OUStringToOString( aMemberDescr
.get()->pTypeName
, RTL_TEXTENCODING_ASCII_US
) );
424 fprintf(stderr
, "calling %s, nFunctionIndex=%d\n", cstr
.getStr(), nFunctionIndex
);
426 typelib_TypeClass eRet
;
427 switch (aMemberDescr
.get()->eTypeClass
)
429 case typelib_TypeClass_INTERFACE_ATTRIBUTE
:
432 fprintf(stderr
, "cpp_vtable_call interface attribute\n");
434 typelib_TypeDescriptionReference
*pAttrTypeRef
=
435 reinterpret_cast<typelib_InterfaceAttributeTypeDescription
*>( aMemberDescr
.get() )->pAttributeTypeRef
;
437 if (pTypeDescr
->pMapMemberIndexToFunctionIndex
[nMemberPos
] == nFunctionIndex
)
440 eRet
= cpp2uno_call( pCppI
, aMemberDescr
.get(), pAttrTypeRef
,
442 gpreg
, fpreg
, ovrflw
, pRegisterReturn
);
447 typelib_MethodParameter aParam
;
448 aParam
.pTypeRef
= pAttrTypeRef
;
449 aParam
.bIn
= sal_True
;
450 aParam
.bOut
= sal_False
;
452 eRet
= cpp2uno_call( pCppI
, aMemberDescr
.get(),
453 0, // indicates void return
455 gpreg
, fpreg
, ovrflw
, pRegisterReturn
);
459 case typelib_TypeClass_INTERFACE_METHOD
:
462 fprintf(stderr
, "cpp_vtable_call interface method\n");
465 switch (nFunctionIndex
)
469 fprintf(stderr
, "cpp_vtable_call method acquire\n");
471 pCppI
->acquireProxy(); // non virtual call!
472 eRet
= typelib_TypeClass_VOID
;
476 fprintf(stderr
, "cpp_vtable_call method release\n");
478 pCppI
->releaseProxy(); // non virtual call!
479 eRet
= typelib_TypeClass_VOID
;
481 case 0: // queryInterface() opt
484 fprintf(stderr
, "cpp_vtable_call method query interface opt\n");
486 typelib_TypeDescription
* pTD
= 0;
487 TYPELIB_DANGER_GET( &pTD
, reinterpret_cast< Type
* >( gpreg
[2] )->getTypeLibType() );
490 XInterface
* pInterface
= 0;
491 (*pCppI
->getBridge()->getCppEnv()->getRegisteredInterface
)
492 ( pCppI
->getBridge()->getCppEnv(),
493 (void **)&pInterface
,
494 pCppI
->getOid().pData
,
495 reinterpret_cast<typelib_InterfaceTypeDescription
*>( pTD
) );
499 ::uno_any_construct( reinterpret_cast< uno_Any
* >( gpreg
[0] ),
500 &pInterface
, pTD
, cpp_acquire
);
502 pInterface
->release();
503 TYPELIB_DANGER_RELEASE( pTD
);
505 reinterpret_cast<void **>( pRegisterReturn
)[0] = gpreg
[0];
506 eRet
= typelib_TypeClass_ANY
;
509 TYPELIB_DANGER_RELEASE( pTD
);
511 } // else perform queryInterface()
514 fprintf(stderr
, "cpp_vtable_call method query interface\n");
516 typelib_InterfaceMethodTypeDescription
*pMethodTD
=
517 reinterpret_cast<typelib_InterfaceMethodTypeDescription
*>( aMemberDescr
.get() );
519 eRet
= cpp2uno_call( pCppI
, aMemberDescr
.get(),
520 pMethodTD
->pReturnTypeRef
,
523 gpreg
, fpreg
, ovrflw
, pRegisterReturn
);
530 fprintf(stderr
, "cpp_vtable_call no member\n");
532 throw RuntimeException( "no member description found!", (XInterface
*)pThis
);
539 extern "C" void privateSnippetExecutor( ... );
541 int const codeSnippetSize
= 0x44;
543 unsigned char * codeSnippet( unsigned char * code
,
544 sal_Int32 functionIndex
, sal_Int32 vtableOffset
,
545 bool bHasHiddenParam
)
548 fprintf(stderr
,"in codeSnippet functionIndex is %d\n", functionIndex
);
549 fprintf(stderr
,"in codeSnippet vtableOffset is %d\n", vtableOffset
);
553 if ( bHasHiddenParam
)
554 functionIndex
|= 0x80000000;
556 unsigned int * p
= (unsigned int *) code
;
558 assert((((unsigned long)code
) & 0x3) == 0 ); //aligned to 4 otherwise a mistake
560 /* generate this code */
563 0: 3c020000 lui v0,0x0
564 4: 34420000 ori v0,v0,0x0
565 # privateSnippetExecutor
566 8: 3c0c0000 lui t0,0x0
567 c: 358c0000 ori t0,t0,0x0
568 10: 000c6438 dsll t0,t0,0x10
569 14: 358c0000 ori t0,t0,0x0
570 18: 000c6438 dsll t0,t0,0x10
571 1c: 358c0000 ori t0,t0,0x0
573 20: 3c190000 lui t9,0x0
574 24: 37390000 ori t9,t9,0x0
575 28: 0019cc38 dsll t9,t9,0x10
576 2c: 37390000 ori t9,t9,0x0
577 30: 0019cc38 dsll t9,t9,0x10
578 34: 37390000 ori t9,t9,0x0
580 38: 3c030000 lui v1,0x0
582 40: 34630000 ori v1,v1,0x0
585 * p
++ = 0x3c020000 | ((functionIndex
>>16) & 0x0000ffff);
586 * p
++ = 0x34420000 | (functionIndex
& 0x0000ffff);
587 * p
++ = 0x3c0c0000 | ((((unsigned long)privateSnippetExecutor
) >> 48) & 0x0000ffff);
588 * p
++ = 0x358c0000 | ((((unsigned long)privateSnippetExecutor
) >> 32) & 0x0000ffff);
590 * p
++ = 0x358c0000 | ((((unsigned long)privateSnippetExecutor
) >> 16) & 0x0000ffff);
592 * p
++ = 0x358c0000 | (((unsigned long)privateSnippetExecutor
) & 0x0000ffff);
593 * p
++ = 0x3c190000 | ((((unsigned long)cpp_vtable_call
) >> 48) & 0x0000ffff);
594 * p
++ = 0x37390000 | ((((unsigned long)cpp_vtable_call
) >> 32) & 0x0000ffff);
596 * p
++ = 0x37390000 | ((((unsigned long)cpp_vtable_call
) >> 16) & 0x0000ffff);
598 * p
++ = 0x37390000 | (((unsigned long)cpp_vtable_call
) & 0x0000ffff);
599 * p
++ = 0x3c030000 | ((vtableOffset
>>16) & 0x0000ffff);
601 * p
++ = 0x34630000 | (vtableOffset
& 0x0000ffff);
602 return (code
+ codeSnippetSize
);
609 void bridges::cpp_uno::shared::VtableFactory::flushCode(unsigned char const *bptr
, unsigned char const *eptr
)
614 sysmips(FLUSH_CACHE
, 0, 0, 0);
616 cacheflush((long) bptr
, (long) eptr
, 0);
620 struct bridges::cpp_uno::shared::VtableFactory::Slot
{ void const * fn
; };
622 bridges::cpp_uno::shared::VtableFactory::Slot
*
623 bridges::cpp_uno::shared::VtableFactory::mapBlockToVtable(void * block
)
625 return static_cast< Slot
* >(block
) + 2;
629 std::size_t bridges::cpp_uno::shared::VtableFactory::getBlockSize(
632 return (slotCount
+ 2) * sizeof (Slot
) + slotCount
* codeSnippetSize
;
636 // Some dummy type whose RTTI is used in the synthesized proxy vtables to make uses of dynamic_cast
637 // on such proxy objects not crash:
641 bridges::cpp_uno::shared::VtableFactory::Slot
*
642 bridges::cpp_uno::shared::VtableFactory::initializeBlock(
643 void * block
, sal_Int32 slotCount
, sal_Int32
,
644 typelib_InterfaceTypeDescription
*)
646 Slot
* slots
= mapBlockToVtable(block
);
647 slots
[-2].fn
= 0; //null
648 slots
[-1].fn
= &typeid(ProxyRtti
);
649 return slots
+ slotCount
;
652 unsigned char * bridges::cpp_uno::shared::VtableFactory::addLocalFunctions(
653 Slot
** slots
, unsigned char * code
, sal_PtrDiff writetoexecdiff
,
654 typelib_InterfaceTypeDescription
const * type
, sal_Int32 functionOffset
,
655 sal_Int32 functionCount
, sal_Int32 vtableOffset
)
657 (*slots
) -= functionCount
;
661 fprintf(stderr
, "in addLocalFunctions functionOffset is %d\n", functionOffset
);
662 fprintf(stderr
, "in addLocalFunctions vtableOffset is %d\n", vtableOffset
);
663 fprintf(stderr
, "nMembers=%d\n", type
->nMembers
);
667 for (sal_Int32 i
= 0; i
< type
->nMembers
; ++i
) {
668 typelib_TypeDescription
* member
= 0;
669 TYPELIB_DANGER_GET(&member
, type
->ppMembers
[i
]);
671 switch (member
->eTypeClass
) {
672 case typelib_TypeClass_INTERFACE_ATTRIBUTE
:
674 (s
++)->fn
= code
+ writetoexecdiff
;
676 code
, functionOffset
++, vtableOffset
,
677 CPPU_CURRENT_NAMESPACE::return_in_hidden_param(
679 typelib_InterfaceAttributeTypeDescription
* >(
680 member
)->pAttributeTypeRef
));
683 if (!reinterpret_cast<
684 typelib_InterfaceAttributeTypeDescription
* >(
687 (s
++)->fn
= code
+ writetoexecdiff
;
688 code
= codeSnippet(code
, functionOffset
++, vtableOffset
, false);
692 case typelib_TypeClass_INTERFACE_METHOD
:
693 (s
++)->fn
= code
+ writetoexecdiff
;
695 code
, functionOffset
++, vtableOffset
,
696 CPPU_CURRENT_NAMESPACE::return_in_hidden_param(
698 typelib_InterfaceMethodTypeDescription
* >(
699 member
)->pReturnTypeRef
));
706 TYPELIB_DANGER_RELEASE(member
);
711 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */