176cf6069SPedro Giffuni /**************************************************************
276cf6069SPedro Giffuni *
376cf6069SPedro Giffuni * Licensed to the Apache Software Foundation (ASF) under one
476cf6069SPedro Giffuni * or more contributor license agreements. See the NOTICE file
576cf6069SPedro Giffuni * distributed with this work for additional information
676cf6069SPedro Giffuni * regarding copyright ownership. The ASF licenses this file
776cf6069SPedro Giffuni * to you under the Apache License, Version 2.0 (the
876cf6069SPedro Giffuni * "License"); you may not use this file except in compliance
976cf6069SPedro Giffuni * with the License. You may obtain a copy of the License at
1076cf6069SPedro Giffuni *
1176cf6069SPedro Giffuni * http://www.apache.org/licenses/LICENSE-2.0
1276cf6069SPedro Giffuni *
1376cf6069SPedro Giffuni * Unless required by applicable law or agreed to in writing,
1476cf6069SPedro Giffuni * software distributed under the License is distributed on an
1576cf6069SPedro Giffuni * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
1676cf6069SPedro Giffuni * KIND, either express or implied. See the License for the
1776cf6069SPedro Giffuni * specific language governing permissions and limitations
1876cf6069SPedro Giffuni * under the License.
1976cf6069SPedro Giffuni *
2076cf6069SPedro Giffuni *************************************************************/
2176cf6069SPedro Giffuni
2276cf6069SPedro Giffuni
2376cf6069SPedro Giffuni
2476cf6069SPedro Giffuni // MARKER(update_precomp.py): autogen include statement, do not remove
2576cf6069SPedro Giffuni #include "precompiled_bridges.hxx"
2676cf6069SPedro Giffuni
27e15a4534Spfg #include <stdlib.h>
2876cf6069SPedro Giffuni
29*a0c169eaSCurtis Hamilton #include <exception>
30*a0c169eaSCurtis Hamilton #include <malloc.h>
31*a0c169eaSCurtis Hamilton #include <typeinfo>
32*a0c169eaSCurtis Hamilton
33*a0c169eaSCurtis Hamilton #include <com/sun/star/uno/Exception.hpp>
34*a0c169eaSCurtis Hamilton #include <com/sun/star/uno/RuntimeException.hpp>
3576cf6069SPedro Giffuni #include <com/sun/star/uno/genfunc.hxx>
3676cf6069SPedro Giffuni #include <uno/data.h>
3776cf6069SPedro Giffuni
3876cf6069SPedro Giffuni #include "bridges/cpp_uno/shared/bridge.hxx"
3976cf6069SPedro Giffuni #include "bridges/cpp_uno/shared/types.hxx"
4076cf6069SPedro Giffuni #include "bridges/cpp_uno/shared/unointerfaceproxy.hxx"
4176cf6069SPedro Giffuni #include "bridges/cpp_uno/shared/vtables.hxx"
4276cf6069SPedro Giffuni
4376cf6069SPedro Giffuni #include "share.hxx"
4476cf6069SPedro Giffuni
4576cf6069SPedro Giffuni #include <stdio.h>
4676cf6069SPedro Giffuni #include <string.h>
4776cf6069SPedro Giffuni
4876cf6069SPedro Giffuni
4976cf6069SPedro Giffuni using namespace ::rtl;
5076cf6069SPedro Giffuni using namespace ::com::sun::star::uno;
51*a0c169eaSCurtis Hamilton #ifdef __GLIBCXX__
52*a0c169eaSCurtis Hamilton using CPPU_CURRENT_NAMESPACE::__cxa_exception;
53*a0c169eaSCurtis Hamilton using CPPU_CURRENT_NAMESPACE::__cxa_get_globals;
54*a0c169eaSCurtis Hamilton #else
55*a0c169eaSCurtis Hamilton using __cxxabiv1::__cxa_exception;
56*a0c169eaSCurtis Hamilton using __cxxabiv1::__cxa_current_primary_exception;
57*a0c169eaSCurtis Hamilton using __cxxabiv1::__cxa_decrement_exception_refcount;
58*a0c169eaSCurtis Hamilton #endif
5976cf6069SPedro Giffuni
60*a0c169eaSCurtis Hamilton namespace ppc64
6176cf6069SPedro Giffuni {
62*a0c169eaSCurtis Hamilton #if defined(_CALL_ELF) && _CALL_ELF == 2
is_complex_struct(const typelib_TypeDescription * type)63*a0c169eaSCurtis Hamilton bool is_complex_struct(const typelib_TypeDescription * type)
64*a0c169eaSCurtis Hamilton {
65*a0c169eaSCurtis Hamilton const typelib_CompoundTypeDescription * p
66*a0c169eaSCurtis Hamilton = reinterpret_cast< const typelib_CompoundTypeDescription * >(type);
67*a0c169eaSCurtis Hamilton for (sal_Int32 i = 0; i < p->nMembers; ++i)
68*a0c169eaSCurtis Hamilton {
69*a0c169eaSCurtis Hamilton if (p->ppTypeRefs[i]->eTypeClass == typelib_TypeClass_STRUCT ||
70*a0c169eaSCurtis Hamilton p->ppTypeRefs[i]->eTypeClass == typelib_TypeClass_EXCEPTION)
71*a0c169eaSCurtis Hamilton {
72*a0c169eaSCurtis Hamilton typelib_TypeDescription * t = 0;
73*a0c169eaSCurtis Hamilton TYPELIB_DANGER_GET(&t, p->ppTypeRefs[i]);
74*a0c169eaSCurtis Hamilton bool b = is_complex_struct(t);
75*a0c169eaSCurtis Hamilton TYPELIB_DANGER_RELEASE(t);
76*a0c169eaSCurtis Hamilton if (b) {
77*a0c169eaSCurtis Hamilton return true;
78*a0c169eaSCurtis Hamilton }
79*a0c169eaSCurtis Hamilton }
80*a0c169eaSCurtis Hamilton else if (!bridges::cpp_uno::shared::isSimpleType(p->ppTypeRefs[i]->eTypeClass))
81*a0c169eaSCurtis Hamilton return true;
82*a0c169eaSCurtis Hamilton }
83*a0c169eaSCurtis Hamilton if (p->pBaseTypeDescription != 0)
84*a0c169eaSCurtis Hamilton return is_complex_struct(&p->pBaseTypeDescription->aBase);
85*a0c169eaSCurtis Hamilton return false;
86*a0c169eaSCurtis Hamilton }
87*a0c169eaSCurtis Hamilton #endif
88*a0c169eaSCurtis Hamilton
return_in_hidden_param(typelib_TypeDescriptionReference * pTypeRef)89*a0c169eaSCurtis Hamilton bool return_in_hidden_param( typelib_TypeDescriptionReference *pTypeRef )
90*a0c169eaSCurtis Hamilton {
91*a0c169eaSCurtis Hamilton if (bridges::cpp_uno::shared::isSimpleType(pTypeRef))
92*a0c169eaSCurtis Hamilton return false;
93*a0c169eaSCurtis Hamilton #if defined(_CALL_ELF) && _CALL_ELF == 2
94*a0c169eaSCurtis Hamilton else if (pTypeRef->eTypeClass == typelib_TypeClass_STRUCT || pTypeRef->eTypeClass == typelib_TypeClass_EXCEPTION)
95*a0c169eaSCurtis Hamilton {
96*a0c169eaSCurtis Hamilton typelib_TypeDescription * pTypeDescr = 0;
97*a0c169eaSCurtis Hamilton TYPELIB_DANGER_GET( &pTypeDescr, pTypeRef );
98*a0c169eaSCurtis Hamilton
99*a0c169eaSCurtis Hamilton //A Composite Type not larger than 16 bytes is returned in up to two GPRs
100*a0c169eaSCurtis Hamilton bool bRet = pTypeDescr->nSize > 16 || is_complex_struct(pTypeDescr);
101*a0c169eaSCurtis Hamilton
102*a0c169eaSCurtis Hamilton TYPELIB_DANGER_RELEASE( pTypeDescr );
103*a0c169eaSCurtis Hamilton return bRet;
104*a0c169eaSCurtis Hamilton }
105*a0c169eaSCurtis Hamilton #endif
106*a0c169eaSCurtis Hamilton return true;
107*a0c169eaSCurtis Hamilton }
108*a0c169eaSCurtis Hamilton }
109*a0c169eaSCurtis Hamilton
MapReturn(long r3,long r4,double dret,typelib_TypeDescriptionReference * pReturnType,void * pRegisterReturn)110*a0c169eaSCurtis Hamilton extern "C" void MapReturn(long r3, long r4, double dret, typelib_TypeDescriptionReference* pReturnType, void *pRegisterReturn)
111*a0c169eaSCurtis Hamilton {
112*a0c169eaSCurtis Hamilton switch (pReturnType->eTypeClass)
11376cf6069SPedro Giffuni {
11476cf6069SPedro Giffuni case typelib_TypeClass_HYPER:
11576cf6069SPedro Giffuni case typelib_TypeClass_UNSIGNED_HYPER:
11676cf6069SPedro Giffuni *reinterpret_cast<sal_uInt64 *>( pRegisterReturn ) = r3;
11776cf6069SPedro Giffuni break;
11876cf6069SPedro Giffuni case typelib_TypeClass_LONG:
11976cf6069SPedro Giffuni case typelib_TypeClass_UNSIGNED_LONG:
12076cf6069SPedro Giffuni case typelib_TypeClass_ENUM:
12176cf6069SPedro Giffuni *reinterpret_cast<sal_uInt32 *>( pRegisterReturn ) = r3;
12276cf6069SPedro Giffuni break;
12376cf6069SPedro Giffuni case typelib_TypeClass_CHAR:
12476cf6069SPedro Giffuni case typelib_TypeClass_SHORT:
12576cf6069SPedro Giffuni case typelib_TypeClass_UNSIGNED_SHORT:
12676cf6069SPedro Giffuni *reinterpret_cast<sal_uInt16 *>( pRegisterReturn ) = (unsigned short)r3;
12776cf6069SPedro Giffuni break;
12876cf6069SPedro Giffuni case typelib_TypeClass_BOOLEAN:
12976cf6069SPedro Giffuni case typelib_TypeClass_BYTE:
13076cf6069SPedro Giffuni *reinterpret_cast<sal_uInt8 *>( pRegisterReturn ) = (unsigned char)r3;
13176cf6069SPedro Giffuni break;
13276cf6069SPedro Giffuni case typelib_TypeClass_FLOAT:
13376cf6069SPedro Giffuni *reinterpret_cast<float *>( pRegisterReturn ) = dret;
13476cf6069SPedro Giffuni break;
13576cf6069SPedro Giffuni case typelib_TypeClass_DOUBLE:
13676cf6069SPedro Giffuni *reinterpret_cast<double *>( pRegisterReturn ) = dret;
13776cf6069SPedro Giffuni break;
138*a0c169eaSCurtis Hamilton #if defined(_CALL_ELF) && _CALL_ELF == 2
139*a0c169eaSCurtis Hamilton case typelib_TypeClass_STRUCT:
140*a0c169eaSCurtis Hamilton case typelib_TypeClass_EXCEPTION:
141*a0c169eaSCurtis Hamilton if (!ppc64::return_in_hidden_param(pReturnType))
142*a0c169eaSCurtis Hamilton {
143*a0c169eaSCurtis Hamilton sal_uInt64 *pRegisters = reinterpret_cast<sal_uInt64*>(pRegisterReturn);
144*a0c169eaSCurtis Hamilton pRegisters[0] = r3;
145*a0c169eaSCurtis Hamilton if (pReturnType->pType->nSize > 8)
146*a0c169eaSCurtis Hamilton pRegisters[1] = r4;
147*a0c169eaSCurtis Hamilton }
148*a0c169eaSCurtis Hamilton #else
149*a0c169eaSCurtis Hamilton (void)r4;
150*a0c169eaSCurtis Hamilton #endif
15176cf6069SPedro Giffuni default:
15276cf6069SPedro Giffuni break;
15376cf6069SPedro Giffuni }
15476cf6069SPedro Giffuni }
15576cf6069SPedro Giffuni
15676cf6069SPedro Giffuni namespace
15776cf6069SPedro Giffuni {
15876cf6069SPedro Giffuni //==================================================================================================
159*a0c169eaSCurtis Hamilton extern "C" void callVirtualMethod(void * pThis, sal_uInt32 nVtableIndex,
16076cf6069SPedro Giffuni void * pRegisterReturn, typelib_TypeDescription * pReturnTypeDescr,
16176cf6069SPedro Giffuni sal_uInt64 *pStack, sal_uInt32 nStack,
16276cf6069SPedro Giffuni sal_uInt64 *pGPR, sal_uInt32 nGPR,
163*a0c169eaSCurtis Hamilton double *pFPR, sal_uInt32 nFPR);
164*a0c169eaSCurtis Hamilton
165*a0c169eaSCurtis Hamilton #if 0
16676cf6069SPedro Giffuni {
16776cf6069SPedro Giffuni // Stack, if used, must be 16-bytes aligned
16876cf6069SPedro Giffuni if ( nStack )
16976cf6069SPedro Giffuni nStack = ( nStack + 1 ) & ~1;
17076cf6069SPedro Giffuni
17176cf6069SPedro Giffuni // Should not happen, but...
17276cf6069SPedro Giffuni if ( nFPR > ppc64::MAX_SSE_REGS )
17376cf6069SPedro Giffuni nFPR = ppc64::MAX_SSE_REGS;
17476cf6069SPedro Giffuni if ( nGPR > ppc64::MAX_GPR_REGS )
17576cf6069SPedro Giffuni nGPR = ppc64::MAX_GPR_REGS;
17676cf6069SPedro Giffuni
17776cf6069SPedro Giffuni #ifdef CMC_DEBUG
17876cf6069SPedro Giffuni // Let's figure out what is really going on here
17976cf6069SPedro Giffuni {
18076cf6069SPedro Giffuni fprintf( stderr, "= callVirtualMethod() =\nGPR's (%d): ", nGPR );
181*a0c169eaSCurtis Hamilton for ( sal_uInt32 i = 0; i < nGPR; ++i )
18276cf6069SPedro Giffuni fprintf( stderr, "0x%lx, ", pGPR[i] );
18376cf6069SPedro Giffuni fprintf( stderr, "\nFPR's (%d): ", nFPR );
184*a0c169eaSCurtis Hamilton for ( sal_uInt32 i = 0; i < nFPR; ++i )
185*a0c169eaSCurtis Hamilton fprintf( stderr, "0x%lx (%lf), ", (sal_Int64)pFPR[i], pFPR[i] );
18676cf6069SPedro Giffuni fprintf( stderr, "\nStack (%d): ", nStack );
187*a0c169eaSCurtis Hamilton for ( sal_uInt32 i = 0; i < nStack; ++i )
18876cf6069SPedro Giffuni fprintf( stderr, "0x%lx, ", pStack[i] );
18976cf6069SPedro Giffuni fprintf( stderr, "\n" );
19076cf6069SPedro Giffuni }
19176cf6069SPedro Giffuni #endif
19276cf6069SPedro Giffuni
19376cf6069SPedro Giffuni // Load parameters to stack, if necessary
19476cf6069SPedro Giffuni sal_uInt64 *stack = (sal_uInt64 *) __builtin_alloca( nStack * 8 );
19576cf6069SPedro Giffuni memcpy( stack, pStack, nStack * 8 );
19676cf6069SPedro Giffuni
19776cf6069SPedro Giffuni // Get pointer to method
19876cf6069SPedro Giffuni sal_uInt64 pMethod = *((sal_uInt64 *)pThis);
19976cf6069SPedro Giffuni pMethod += 8 * nVtableIndex;
20076cf6069SPedro Giffuni pMethod = *((sal_uInt64 *)pMethod);
20176cf6069SPedro Giffuni
202*a0c169eaSCurtis Hamilton #if defined(_CALL_ELF) && _CALL_ELF == 2
203*a0c169eaSCurtis Hamilton typedef void (* FunctionCall )(...);
204*a0c169eaSCurtis Hamilton #else
20576cf6069SPedro Giffuni typedef void (* FunctionCall )( sal_uInt64, sal_uInt64, sal_uInt64, sal_uInt64, sal_uInt64, sal_uInt64, sal_uInt64, sal_uInt64 );
206*a0c169eaSCurtis Hamilton #endif
20776cf6069SPedro Giffuni FunctionCall pFunc = (FunctionCall)pMethod;
20876cf6069SPedro Giffuni
20976cf6069SPedro Giffuni volatile double dret;
21076cf6069SPedro Giffuni
21176cf6069SPedro Giffuni // fill registers
21276cf6069SPedro Giffuni __asm__ __volatile__ (
213*a0c169eaSCurtis Hamilton "lfd 1, 0(%0)\n\t"
214*a0c169eaSCurtis Hamilton "lfd 2, 8(%0)\n\t"
215*a0c169eaSCurtis Hamilton "lfd 3, 16(%0)\n\t"
216*a0c169eaSCurtis Hamilton "lfd 4, 24(%0)\n\t"
217*a0c169eaSCurtis Hamilton "lfd 5, 32(%0)\n\t"
218*a0c169eaSCurtis Hamilton "lfd 6, 40(%0)\n\t"
219*a0c169eaSCurtis Hamilton "lfd 7, 48(%0)\n\t"
220*a0c169eaSCurtis Hamilton "lfd 8, 56(%0)\n\t"
221*a0c169eaSCurtis Hamilton "lfd 9, 64(%0)\n\t"
222*a0c169eaSCurtis Hamilton "lfd 10, 72(%0)\n\t"
223*a0c169eaSCurtis Hamilton "lfd 11, 80(%0)\n\t"
224*a0c169eaSCurtis Hamilton "lfd 12, 88(%0)\n\t"
225*a0c169eaSCurtis Hamilton "lfd 13, 96(%0)\n\t"
226*a0c169eaSCurtis Hamilton : : "r" (pFPR)
227*a0c169eaSCurtis Hamilton : "fr1", "fr2", "fr3", "fr4", "fr5", "fr6", "fr7", "fr8", "fr9",
22876cf6069SPedro Giffuni "fr10", "fr11", "fr12", "fr13"
22976cf6069SPedro Giffuni );
23076cf6069SPedro Giffuni
23176cf6069SPedro Giffuni // tell gcc that r3 to r11 are not available to it for doing the TOC and exception munge on the func call
23276cf6069SPedro Giffuni register sal_uInt64 r3 asm("r3");
23376cf6069SPedro Giffuni register sal_uInt64 r4 asm("r4");
23476cf6069SPedro Giffuni
235*a0c169eaSCurtis Hamilton (*pFunc)(pGPR[0], pGPR[1], pGPR[2], pGPR[3], pGPR[4], pGPR[5], pGPR[6], pGPR[7]);
23676cf6069SPedro Giffuni
23776cf6069SPedro Giffuni // get return value
23876cf6069SPedro Giffuni __asm__ __volatile__ (
23976cf6069SPedro Giffuni "mr %1, 3\n\t"
24076cf6069SPedro Giffuni "mr %2, 4\n\t"
24176cf6069SPedro Giffuni "fmr %0, 1\n\t"
24276cf6069SPedro Giffuni : "=f" (dret), "=r" (r3), "=r" (r4) : );
24376cf6069SPedro Giffuni
244*a0c169eaSCurtis Hamilton MapReturn(r3, r4, dret, reinterpret_cast<typelib_TypeDescriptionReference *>(pReturnTypeDescr), pRegisterReturn);
24576cf6069SPedro Giffuni }
246*a0c169eaSCurtis Hamilton #endif
24776cf6069SPedro Giffuni
24876cf6069SPedro Giffuni // Macros for easier insertion of values to registers or stack
24976cf6069SPedro Giffuni // pSV - pointer to the source
25076cf6069SPedro Giffuni // nr - order of the value [will be increased if stored to register]
25176cf6069SPedro Giffuni // pFPR, pGPR - pointer to the registers
25276cf6069SPedro Giffuni // pDS - pointer to the stack [will be increased if stored here]
25376cf6069SPedro Giffuni
25476cf6069SPedro Giffuni // The value in %xmm register is already prepared to be retrieved as a float,
25576cf6069SPedro Giffuni // thus we treat float and double the same
256*a0c169eaSCurtis Hamilton #define INSERT_FLOAT( pSV, nr, pFPR, nGPR, pDS, bOverFlow ) \
257*a0c169eaSCurtis Hamilton if ( nGPR < ppc64::MAX_GPR_REGS ) \
258*a0c169eaSCurtis Hamilton ++nGPR; \
25976cf6069SPedro Giffuni if ( nr < ppc64::MAX_SSE_REGS ) \
26076cf6069SPedro Giffuni pFPR[nr++] = *reinterpret_cast<float *>( pSV ); \
26176cf6069SPedro Giffuni else \
26276cf6069SPedro Giffuni bOverFlow = true; \
26376cf6069SPedro Giffuni if (bOverFlow) \
26476cf6069SPedro Giffuni *pDS++ = *reinterpret_cast<sal_uInt64 *>( pSV ); // verbatim!
26576cf6069SPedro Giffuni
266*a0c169eaSCurtis Hamilton #define INSERT_DOUBLE( pSV, nr, pFPR, nGPR, pDS, bOverFlow ) \
267*a0c169eaSCurtis Hamilton if ( nGPR < ppc64::MAX_GPR_REGS ) \
268*a0c169eaSCurtis Hamilton ++nGPR; \
26976cf6069SPedro Giffuni if ( nr < ppc64::MAX_SSE_REGS ) \
27076cf6069SPedro Giffuni pFPR[nr++] = *reinterpret_cast<double *>( pSV ); \
27176cf6069SPedro Giffuni else \
27276cf6069SPedro Giffuni bOverFlow = true; \
27376cf6069SPedro Giffuni if (bOverFlow) \
27476cf6069SPedro Giffuni *pDS++ = *reinterpret_cast<sal_uInt64 *>( pSV ); // verbatim!
27576cf6069SPedro Giffuni
276*a0c169eaSCurtis Hamilton #define INSERT_INT64( pSV, nr, pGPR, pDS, bOverFlow ) \
277*a0c169eaSCurtis Hamilton if ( nr < ppc64::MAX_GPR_REGS ) \
278*a0c169eaSCurtis Hamilton pGPR[nr++] = *reinterpret_cast<sal_Int64 *>( pSV ); \
279*a0c169eaSCurtis Hamilton else \
280*a0c169eaSCurtis Hamilton bOverFlow = true; \
281*a0c169eaSCurtis Hamilton if (bOverFlow) \
282*a0c169eaSCurtis Hamilton *pDS++ = *reinterpret_cast<sal_Int64 *>( pSV );
283*a0c169eaSCurtis Hamilton
284*a0c169eaSCurtis Hamilton #define INSERT_UINT64( pSV, nr, pGPR, pDS, bOverFlow ) \
28576cf6069SPedro Giffuni if ( nr < ppc64::MAX_GPR_REGS ) \
28676cf6069SPedro Giffuni pGPR[nr++] = *reinterpret_cast<sal_uInt64 *>( pSV ); \
28776cf6069SPedro Giffuni else \
28876cf6069SPedro Giffuni bOverFlow = true; \
28976cf6069SPedro Giffuni if (bOverFlow) \
29076cf6069SPedro Giffuni *pDS++ = *reinterpret_cast<sal_uInt64 *>( pSV );
29176cf6069SPedro Giffuni
292*a0c169eaSCurtis Hamilton #define INSERT_INT32( pSV, nr, pGPR, pDS, bOverFlow ) \
293*a0c169eaSCurtis Hamilton if ( nr < ppc64::MAX_GPR_REGS ) \
294*a0c169eaSCurtis Hamilton pGPR[nr++] = *reinterpret_cast<sal_Int32 *>( pSV ); \
295*a0c169eaSCurtis Hamilton else \
296*a0c169eaSCurtis Hamilton bOverFlow = true; \
297*a0c169eaSCurtis Hamilton if (bOverFlow) \
298*a0c169eaSCurtis Hamilton *pDS++ = *reinterpret_cast<sal_Int32 *>( pSV );
299*a0c169eaSCurtis Hamilton
300*a0c169eaSCurtis Hamilton #define INSERT_UINT32( pSV, nr, pGPR, pDS, bOverFlow ) \
30176cf6069SPedro Giffuni if ( nr < ppc64::MAX_GPR_REGS ) \
30276cf6069SPedro Giffuni pGPR[nr++] = *reinterpret_cast<sal_uInt32 *>( pSV ); \
30376cf6069SPedro Giffuni else \
30476cf6069SPedro Giffuni bOverFlow = true; \
30576cf6069SPedro Giffuni if (bOverFlow) \
30676cf6069SPedro Giffuni *pDS++ = *reinterpret_cast<sal_uInt32 *>( pSV );
30776cf6069SPedro Giffuni
308*a0c169eaSCurtis Hamilton #define INSERT_INT16( pSV, nr, pGPR, pDS, bOverFlow ) \
309*a0c169eaSCurtis Hamilton if ( nr < ppc64::MAX_GPR_REGS ) \
310*a0c169eaSCurtis Hamilton pGPR[nr++] = *reinterpret_cast<sal_Int16 *>( pSV ); \
311*a0c169eaSCurtis Hamilton else \
312*a0c169eaSCurtis Hamilton bOverFlow = true; \
313*a0c169eaSCurtis Hamilton if (bOverFlow) \
314*a0c169eaSCurtis Hamilton *pDS++ = *reinterpret_cast<sal_Int16 *>( pSV );
315*a0c169eaSCurtis Hamilton
316*a0c169eaSCurtis Hamilton #define INSERT_UINT16( pSV, nr, pGPR, pDS, bOverFlow ) \
31776cf6069SPedro Giffuni if ( nr < ppc64::MAX_GPR_REGS ) \
31876cf6069SPedro Giffuni pGPR[nr++] = *reinterpret_cast<sal_uInt16 *>( pSV ); \
31976cf6069SPedro Giffuni else \
32076cf6069SPedro Giffuni bOverFlow = true; \
32176cf6069SPedro Giffuni if (bOverFlow) \
32276cf6069SPedro Giffuni *pDS++ = *reinterpret_cast<sal_uInt16 *>( pSV );
32376cf6069SPedro Giffuni
324*a0c169eaSCurtis Hamilton #define INSERT_INT8( pSV, nr, pGPR, pDS, bOverFlow ) \
325*a0c169eaSCurtis Hamilton if ( nr < ppc64::MAX_GPR_REGS ) \
326*a0c169eaSCurtis Hamilton pGPR[nr++] = *reinterpret_cast<sal_Int8 *>( pSV ); \
327*a0c169eaSCurtis Hamilton else \
328*a0c169eaSCurtis Hamilton bOverFlow = true; \
329*a0c169eaSCurtis Hamilton if (bOverFlow) \
330*a0c169eaSCurtis Hamilton *pDS++ = *reinterpret_cast<sal_Int8 *>( pSV );
331*a0c169eaSCurtis Hamilton
332*a0c169eaSCurtis Hamilton #define INSERT_UINT8( pSV, nr, pGPR, pDS, bOverFlow ) \
33376cf6069SPedro Giffuni if ( nr < ppc64::MAX_GPR_REGS ) \
33476cf6069SPedro Giffuni pGPR[nr++] = *reinterpret_cast<sal_uInt8 *>( pSV ); \
33576cf6069SPedro Giffuni else \
33676cf6069SPedro Giffuni bOverFlow = true; \
33776cf6069SPedro Giffuni if (bOverFlow) \
33876cf6069SPedro Giffuni *pDS++ = *reinterpret_cast<sal_uInt8 *>( pSV );
33976cf6069SPedro Giffuni
34076cf6069SPedro Giffuni //==================================================================================================
cpp_call(bridges::cpp_uno::shared::UnoInterfaceProxy * pThis,bridges::cpp_uno::shared::VtableSlot aVtableSlot,typelib_TypeDescriptionReference * pReturnTypeRef,sal_Int32 nParams,typelib_MethodParameter * pParams,void * pUnoReturn,void * pUnoArgs[],uno_Any ** ppUnoExc)34176cf6069SPedro Giffuni static void cpp_call(
34276cf6069SPedro Giffuni bridges::cpp_uno::shared::UnoInterfaceProxy * pThis,
34376cf6069SPedro Giffuni bridges::cpp_uno::shared::VtableSlot aVtableSlot,
34476cf6069SPedro Giffuni typelib_TypeDescriptionReference * pReturnTypeRef,
34576cf6069SPedro Giffuni sal_Int32 nParams, typelib_MethodParameter * pParams,
34676cf6069SPedro Giffuni void * pUnoReturn, void * pUnoArgs[], uno_Any ** ppUnoExc )
34776cf6069SPedro Giffuni {
34876cf6069SPedro Giffuni // max space for: [complex ret ptr], values|ptr ...
34976cf6069SPedro Giffuni sal_uInt64 * pStack = (sal_uInt64 *)alloca( (nParams+3) * sizeof(sal_Int64) );
35076cf6069SPedro Giffuni sal_uInt64 * pStackStart = pStack;
35176cf6069SPedro Giffuni
35276cf6069SPedro Giffuni sal_uInt64 pGPR[ppc64::MAX_GPR_REGS];
35376cf6069SPedro Giffuni sal_uInt32 nGPR = 0;
35476cf6069SPedro Giffuni
35576cf6069SPedro Giffuni double pFPR[ppc64::MAX_SSE_REGS];
35676cf6069SPedro Giffuni sal_uInt32 nFPR = 0;
35776cf6069SPedro Giffuni
35876cf6069SPedro Giffuni // return
35976cf6069SPedro Giffuni typelib_TypeDescription * pReturnTypeDescr = 0;
36076cf6069SPedro Giffuni TYPELIB_DANGER_GET( &pReturnTypeDescr, pReturnTypeRef );
36176cf6069SPedro Giffuni OSL_ENSURE( pReturnTypeDescr, "### expected return type description!" );
36276cf6069SPedro Giffuni
36376cf6069SPedro Giffuni void * pCppReturn = 0; // if != 0 && != pUnoReturn, needs reconversion
36476cf6069SPedro Giffuni
36576cf6069SPedro Giffuni bool bOverFlow = false;
36676cf6069SPedro Giffuni
36776cf6069SPedro Giffuni if (pReturnTypeDescr)
36876cf6069SPedro Giffuni {
36976cf6069SPedro Giffuni #ifdef CMC_DEBUG
37076cf6069SPedro Giffuni fprintf(stderr, "return type is %d\n", pReturnTypeDescr->eTypeClass);
37176cf6069SPedro Giffuni #endif
37276cf6069SPedro Giffuni if (bridges::cpp_uno::shared::isSimpleType( pReturnTypeDescr ))
37376cf6069SPedro Giffuni {
37476cf6069SPedro Giffuni pCppReturn = pUnoReturn; // direct way for simple types
37576cf6069SPedro Giffuni #ifdef CMC_DEBUG
37676cf6069SPedro Giffuni fprintf(stderr, "simple return\n");
37776cf6069SPedro Giffuni #endif
37876cf6069SPedro Giffuni }
37976cf6069SPedro Giffuni else
38076cf6069SPedro Giffuni {
38176cf6069SPedro Giffuni // complex return via ptr
38276cf6069SPedro Giffuni pCppReturn = (bridges::cpp_uno::shared::relatesToInterfaceType( pReturnTypeDescr )
38376cf6069SPedro Giffuni ? alloca( pReturnTypeDescr->nSize ) : pUnoReturn);
38476cf6069SPedro Giffuni #ifdef CMC_DEBUG
38576cf6069SPedro Giffuni fprintf(stderr, "pCppReturn/pUnoReturn is %lx/%lx", pCppReturn, pUnoReturn);
38676cf6069SPedro Giffuni #endif
38776cf6069SPedro Giffuni INSERT_INT64( &pCppReturn, nGPR, pGPR, pStack, bOverFlow );
38876cf6069SPedro Giffuni }
38976cf6069SPedro Giffuni }
39076cf6069SPedro Giffuni // push "this" pointer
39176cf6069SPedro Giffuni void * pAdjustedThisPtr = reinterpret_cast< void ** >( pThis->getCppI() ) + aVtableSlot.offset;
39276cf6069SPedro Giffuni #ifdef CMC_DEBUG
39376cf6069SPedro Giffuni fprintf(stderr, "this pointer is %p\n", pAdjustedThisPtr);
39476cf6069SPedro Giffuni #endif
39576cf6069SPedro Giffuni INSERT_INT64( &pAdjustedThisPtr, nGPR, pGPR, pStack, bOverFlow );
39676cf6069SPedro Giffuni
39776cf6069SPedro Giffuni // Args
39876cf6069SPedro Giffuni void ** pCppArgs = (void **)alloca( 3 * sizeof(void *) * nParams );
39976cf6069SPedro Giffuni // indizes of values this have to be converted (interface conversion cpp<=>uno)
40076cf6069SPedro Giffuni sal_Int32 * pTempIndizes = (sal_Int32 *)(pCppArgs + nParams);
40176cf6069SPedro Giffuni // type descriptions for reconversions
40276cf6069SPedro Giffuni typelib_TypeDescription ** ppTempParamTypeDescr = (typelib_TypeDescription **)(pCppArgs + (2 * nParams));
40376cf6069SPedro Giffuni
40476cf6069SPedro Giffuni sal_Int32 nTempIndizes = 0;
40576cf6069SPedro Giffuni
40676cf6069SPedro Giffuni #ifdef CMC_DEBUG
40776cf6069SPedro Giffuni fprintf(stderr, "n params is %d\n", nParams);
40876cf6069SPedro Giffuni #endif
40976cf6069SPedro Giffuni
41076cf6069SPedro Giffuni for ( sal_Int32 nPos = 0; nPos < nParams; ++nPos )
41176cf6069SPedro Giffuni {
41276cf6069SPedro Giffuni const typelib_MethodParameter & rParam = pParams[nPos];
41376cf6069SPedro Giffuni typelib_TypeDescription * pParamTypeDescr = 0;
41476cf6069SPedro Giffuni TYPELIB_DANGER_GET( &pParamTypeDescr, rParam.pTypeRef );
41576cf6069SPedro Giffuni
41676cf6069SPedro Giffuni #ifdef CMC_DEBUG
41776cf6069SPedro Giffuni fprintf(stderr, "param %d is %d %d %d\n", nPos, rParam.bOut, bridges::cpp_uno::shared::isSimpleType( pParamTypeDescr ),
41876cf6069SPedro Giffuni pParamTypeDescr->eTypeClass);
41976cf6069SPedro Giffuni #endif
42076cf6069SPedro Giffuni
42176cf6069SPedro Giffuni if (!rParam.bOut && bridges::cpp_uno::shared::isSimpleType( pParamTypeDescr ))
42276cf6069SPedro Giffuni {
42376cf6069SPedro Giffuni // uno_copyAndConvertData( pCppArgs[nPos] = alloca( 8 ), pUnoArgs[nPos], pParamTypeDescr,
42476cf6069SPedro Giffuni uno_copyAndConvertData( pCppArgs[nPos] = pStack, pUnoArgs[nPos], pParamTypeDescr,
42576cf6069SPedro Giffuni pThis->getBridge()->getUno2Cpp() );
42676cf6069SPedro Giffuni switch (pParamTypeDescr->eTypeClass)
42776cf6069SPedro Giffuni {
42876cf6069SPedro Giffuni case typelib_TypeClass_HYPER:
42976cf6069SPedro Giffuni case typelib_TypeClass_UNSIGNED_HYPER:
43076cf6069SPedro Giffuni #ifdef CMC_DEBUG
43176cf6069SPedro Giffuni fprintf(stderr, "hyper is %lx\n", pCppArgs[nPos]);
43276cf6069SPedro Giffuni #endif
43376cf6069SPedro Giffuni INSERT_INT64( pCppArgs[nPos], nGPR, pGPR, pStack, bOverFlow );
43476cf6069SPedro Giffuni break;
43576cf6069SPedro Giffuni case typelib_TypeClass_LONG:
43676cf6069SPedro Giffuni case typelib_TypeClass_UNSIGNED_LONG:
43776cf6069SPedro Giffuni case typelib_TypeClass_ENUM:
43876cf6069SPedro Giffuni #ifdef CMC_DEBUG
43976cf6069SPedro Giffuni fprintf(stderr, "long is %x\n", pCppArgs[nPos]);
44076cf6069SPedro Giffuni #endif
44176cf6069SPedro Giffuni INSERT_INT32( pCppArgs[nPos], nGPR, pGPR, pStack, bOverFlow );
44276cf6069SPedro Giffuni break;
44376cf6069SPedro Giffuni case typelib_TypeClass_SHORT:
444*a0c169eaSCurtis Hamilton INSERT_INT16( pCppArgs[nPos], nGPR, pGPR, pStack, bOverFlow );
445*a0c169eaSCurtis Hamilton break;
44676cf6069SPedro Giffuni case typelib_TypeClass_CHAR:
44776cf6069SPedro Giffuni case typelib_TypeClass_UNSIGNED_SHORT:
44876cf6069SPedro Giffuni INSERT_INT16( pCppArgs[nPos], nGPR, pGPR, pStack, bOverFlow );
44976cf6069SPedro Giffuni break;
45076cf6069SPedro Giffuni case typelib_TypeClass_BOOLEAN:
451*a0c169eaSCurtis Hamilton INSERT_UINT8( pCppArgs[nPos], nGPR, pGPR, pStack, bOverFlow );
452*a0c169eaSCurtis Hamilton break;
45376cf6069SPedro Giffuni case typelib_TypeClass_BYTE:
45476cf6069SPedro Giffuni INSERT_INT8( pCppArgs[nPos], nGPR, pGPR, pStack, bOverFlow );
45576cf6069SPedro Giffuni break;
45676cf6069SPedro Giffuni case typelib_TypeClass_FLOAT:
457*a0c169eaSCurtis Hamilton INSERT_FLOAT( pCppArgs[nPos], nFPR, pFPR, nGPR, pStack, bOverFlow );
45876cf6069SPedro Giffuni break;
45976cf6069SPedro Giffuni case typelib_TypeClass_DOUBLE:
460*a0c169eaSCurtis Hamilton INSERT_DOUBLE( pCppArgs[nPos], nFPR, pFPR, nGPR, pStack, bOverFlow );
46176cf6069SPedro Giffuni break;
46276cf6069SPedro Giffuni }
46376cf6069SPedro Giffuni
46476cf6069SPedro Giffuni // no longer needed
46576cf6069SPedro Giffuni TYPELIB_DANGER_RELEASE( pParamTypeDescr );
46676cf6069SPedro Giffuni
46776cf6069SPedro Giffuni }
46876cf6069SPedro Giffuni else // ptr to complex value | ref
46976cf6069SPedro Giffuni {
47076cf6069SPedro Giffuni #ifdef CMC_DEBUG
47176cf6069SPedro Giffuni fprintf(stderr, "complex type again %d\n", rParam.bIn);
47276cf6069SPedro Giffuni #endif
47376cf6069SPedro Giffuni if (! rParam.bIn) // is pure out
47476cf6069SPedro Giffuni {
47576cf6069SPedro Giffuni #ifdef CMC_DEBUG
47676cf6069SPedro Giffuni fprintf(stderr, "complex size is %d\n", pParamTypeDescr->nSize );
47776cf6069SPedro Giffuni #endif
47876cf6069SPedro Giffuni // cpp out is constructed mem, uno out is not!
47976cf6069SPedro Giffuni uno_constructData(
48076cf6069SPedro Giffuni pCppArgs[nPos] = alloca( pParamTypeDescr->nSize ),
48176cf6069SPedro Giffuni pParamTypeDescr );
48276cf6069SPedro Giffuni pTempIndizes[nTempIndizes] = nPos; // default constructed for cpp call
48376cf6069SPedro Giffuni // will be released at reconversion
48476cf6069SPedro Giffuni ppTempParamTypeDescr[nTempIndizes++] = pParamTypeDescr;
48576cf6069SPedro Giffuni }
48676cf6069SPedro Giffuni // is in/inout
48776cf6069SPedro Giffuni else if (bridges::cpp_uno::shared::relatesToInterfaceType( pParamTypeDescr ))
48876cf6069SPedro Giffuni {
48976cf6069SPedro Giffuni #ifdef CMC_DEBUG
49076cf6069SPedro Giffuni fprintf(stderr, "this one\n");
49176cf6069SPedro Giffuni #endif
49276cf6069SPedro Giffuni uno_copyAndConvertData(
49376cf6069SPedro Giffuni pCppArgs[nPos] = alloca( pParamTypeDescr->nSize ),
49476cf6069SPedro Giffuni pUnoArgs[nPos], pParamTypeDescr, pThis->getBridge()->getUno2Cpp() );
49576cf6069SPedro Giffuni
49676cf6069SPedro Giffuni pTempIndizes[nTempIndizes] = nPos; // has to be reconverted
49776cf6069SPedro Giffuni // will be released at reconversion
49876cf6069SPedro Giffuni ppTempParamTypeDescr[nTempIndizes++] = pParamTypeDescr;
49976cf6069SPedro Giffuni }
50076cf6069SPedro Giffuni else // direct way
50176cf6069SPedro Giffuni {
50276cf6069SPedro Giffuni #ifdef CMC_DEBUG
50376cf6069SPedro Giffuni fprintf(stderr, "that one, passing %lx through\n", pUnoArgs[nPos]);
50476cf6069SPedro Giffuni #endif
50576cf6069SPedro Giffuni pCppArgs[nPos] = pUnoArgs[nPos];
50676cf6069SPedro Giffuni // no longer needed
50776cf6069SPedro Giffuni TYPELIB_DANGER_RELEASE( pParamTypeDescr );
50876cf6069SPedro Giffuni }
50976cf6069SPedro Giffuni INSERT_INT64( &(pCppArgs[nPos]), nGPR, pGPR, pStack, bOverFlow );
51076cf6069SPedro Giffuni }
51176cf6069SPedro Giffuni }
51276cf6069SPedro Giffuni
51376cf6069SPedro Giffuni try
51476cf6069SPedro Giffuni {
51576cf6069SPedro Giffuni callVirtualMethod(
51676cf6069SPedro Giffuni pAdjustedThisPtr, aVtableSlot.index,
51776cf6069SPedro Giffuni pCppReturn, pReturnTypeDescr,
51876cf6069SPedro Giffuni pStackStart, ( pStack - pStackStart ),
51976cf6069SPedro Giffuni pGPR, nGPR,
52076cf6069SPedro Giffuni pFPR, nFPR );
52176cf6069SPedro Giffuni // NO exception occurred...
52276cf6069SPedro Giffuni *ppUnoExc = 0;
52376cf6069SPedro Giffuni
52476cf6069SPedro Giffuni // reconvert temporary params
52576cf6069SPedro Giffuni for ( ; nTempIndizes--; )
52676cf6069SPedro Giffuni {
52776cf6069SPedro Giffuni sal_Int32 nIndex = pTempIndizes[nTempIndizes];
52876cf6069SPedro Giffuni typelib_TypeDescription * pParamTypeDescr = ppTempParamTypeDescr[nTempIndizes];
52976cf6069SPedro Giffuni
53076cf6069SPedro Giffuni if (pParams[nIndex].bIn)
53176cf6069SPedro Giffuni {
53276cf6069SPedro Giffuni if (pParams[nIndex].bOut) // inout
53376cf6069SPedro Giffuni {
53476cf6069SPedro Giffuni uno_destructData( pUnoArgs[nIndex], pParamTypeDescr, 0 ); // destroy uno value
53576cf6069SPedro Giffuni uno_copyAndConvertData( pUnoArgs[nIndex], pCppArgs[nIndex], pParamTypeDescr,
53676cf6069SPedro Giffuni pThis->getBridge()->getCpp2Uno() );
53776cf6069SPedro Giffuni }
53876cf6069SPedro Giffuni }
53976cf6069SPedro Giffuni else // pure out
54076cf6069SPedro Giffuni {
54176cf6069SPedro Giffuni uno_copyAndConvertData( pUnoArgs[nIndex], pCppArgs[nIndex], pParamTypeDescr,
54276cf6069SPedro Giffuni pThis->getBridge()->getCpp2Uno() );
54376cf6069SPedro Giffuni }
54476cf6069SPedro Giffuni // destroy temp cpp param => cpp: every param was constructed
54576cf6069SPedro Giffuni uno_destructData( pCppArgs[nIndex], pParamTypeDescr, cpp_release );
54676cf6069SPedro Giffuni
54776cf6069SPedro Giffuni TYPELIB_DANGER_RELEASE( pParamTypeDescr );
54876cf6069SPedro Giffuni }
54976cf6069SPedro Giffuni // return value
55076cf6069SPedro Giffuni if (pCppReturn && pUnoReturn != pCppReturn)
55176cf6069SPedro Giffuni {
55276cf6069SPedro Giffuni uno_copyAndConvertData( pUnoReturn, pCppReturn, pReturnTypeDescr,
55376cf6069SPedro Giffuni pThis->getBridge()->getCpp2Uno() );
55476cf6069SPedro Giffuni uno_destructData( pCppReturn, pReturnTypeDescr, cpp_release );
55576cf6069SPedro Giffuni }
55676cf6069SPedro Giffuni }
55776cf6069SPedro Giffuni catch (...)
55876cf6069SPedro Giffuni {
559*a0c169eaSCurtis Hamilton __cxa_exception *header;
560*a0c169eaSCurtis Hamilton #ifdef __GLIBCXX__
561*a0c169eaSCurtis Hamilton header = __cxa_get_globals()->caughtExceptions;
562*a0c169eaSCurtis Hamilton #else
563*a0c169eaSCurtis Hamilton header = reinterpret_cast<__cxa_exception *>( __cxa_current_primary_exception() );
564*a0c169eaSCurtis Hamilton if (header) {
565*a0c169eaSCurtis Hamilton __cxa_decrement_exception_refcount( header );
566*a0c169eaSCurtis Hamilton header--;
567*a0c169eaSCurtis Hamilton }
568*a0c169eaSCurtis Hamilton #endif
56976cf6069SPedro Giffuni // fill uno exception
570*a0c169eaSCurtis Hamilton CPPU_CURRENT_NAMESPACE::fillUnoException( header, *ppUnoExc, pThis->getBridge()->getCpp2Uno() );
57176cf6069SPedro Giffuni
57276cf6069SPedro Giffuni // temporary params
57376cf6069SPedro Giffuni for ( ; nTempIndizes--; )
57476cf6069SPedro Giffuni {
57576cf6069SPedro Giffuni sal_Int32 nIndex = pTempIndizes[nTempIndizes];
57676cf6069SPedro Giffuni // destroy temp cpp param => cpp: every param was constructed
57776cf6069SPedro Giffuni uno_destructData( pCppArgs[nIndex], ppTempParamTypeDescr[nTempIndizes], cpp_release );
57876cf6069SPedro Giffuni TYPELIB_DANGER_RELEASE( ppTempParamTypeDescr[nTempIndizes] );
57976cf6069SPedro Giffuni }
58076cf6069SPedro Giffuni // return type
58176cf6069SPedro Giffuni if (pReturnTypeDescr)
58276cf6069SPedro Giffuni TYPELIB_DANGER_RELEASE( pReturnTypeDescr );
58376cf6069SPedro Giffuni }
58476cf6069SPedro Giffuni }
58576cf6069SPedro Giffuni
58676cf6069SPedro Giffuni }
58776cf6069SPedro Giffuni
58876cf6069SPedro Giffuni namespace bridges { namespace cpp_uno { namespace shared {
58976cf6069SPedro Giffuni
unoInterfaceProxyDispatch(uno_Interface * pUnoI,const typelib_TypeDescription * pMemberDescr,void * pReturn,void * pArgs[],uno_Any ** ppException)59076cf6069SPedro Giffuni void unoInterfaceProxyDispatch(
59176cf6069SPedro Giffuni uno_Interface * pUnoI, const typelib_TypeDescription * pMemberDescr,
59276cf6069SPedro Giffuni void * pReturn, void * pArgs[], uno_Any ** ppException )
59376cf6069SPedro Giffuni {
59476cf6069SPedro Giffuni // is my surrogate
595*a0c169eaSCurtis Hamilton ::bridges::cpp_uno::shared::UnoInterfaceProxy * pThis
596*a0c169eaSCurtis Hamilton = static_cast< ::bridges::cpp_uno::shared::UnoInterfaceProxy *> (pUnoI);
59776cf6069SPedro Giffuni typelib_InterfaceTypeDescription * pTypeDescr = pThis->pTypeDescr;
59876cf6069SPedro Giffuni
59976cf6069SPedro Giffuni switch (pMemberDescr->eTypeClass)
60076cf6069SPedro Giffuni {
60176cf6069SPedro Giffuni case typelib_TypeClass_INTERFACE_ATTRIBUTE:
60276cf6069SPedro Giffuni {
60376cf6069SPedro Giffuni
604*a0c169eaSCurtis Hamilton ::bridges::cpp_uno::shared::VtableSlot aVtableSlot(
605*a0c169eaSCurtis Hamilton ::bridges::cpp_uno::shared::getVtableSlot(
60676cf6069SPedro Giffuni reinterpret_cast<
60776cf6069SPedro Giffuni typelib_InterfaceAttributeTypeDescription const * >(
60876cf6069SPedro Giffuni pMemberDescr)));
60976cf6069SPedro Giffuni
61076cf6069SPedro Giffuni if (pReturn)
61176cf6069SPedro Giffuni {
61276cf6069SPedro Giffuni // dependent dispatch
61376cf6069SPedro Giffuni cpp_call(
61476cf6069SPedro Giffuni pThis, aVtableSlot,
61576cf6069SPedro Giffuni ((typelib_InterfaceAttributeTypeDescription *)pMemberDescr)->pAttributeTypeRef,
61676cf6069SPedro Giffuni 0, 0, // no params
61776cf6069SPedro Giffuni pReturn, pArgs, ppException );
61876cf6069SPedro Giffuni }
61976cf6069SPedro Giffuni else
62076cf6069SPedro Giffuni {
62176cf6069SPedro Giffuni // is SET
62276cf6069SPedro Giffuni typelib_MethodParameter aParam;
62376cf6069SPedro Giffuni aParam.pTypeRef =
62476cf6069SPedro Giffuni ((typelib_InterfaceAttributeTypeDescription *)pMemberDescr)->pAttributeTypeRef;
62576cf6069SPedro Giffuni aParam.bIn = sal_True;
62676cf6069SPedro Giffuni aParam.bOut = sal_False;
62776cf6069SPedro Giffuni
62876cf6069SPedro Giffuni typelib_TypeDescriptionReference * pReturnTypeRef = 0;
62976cf6069SPedro Giffuni OUString aVoidName( RTL_CONSTASCII_USTRINGPARAM("void") );
63076cf6069SPedro Giffuni typelib_typedescriptionreference_new(
63176cf6069SPedro Giffuni &pReturnTypeRef, typelib_TypeClass_VOID, aVoidName.pData );
63276cf6069SPedro Giffuni
63376cf6069SPedro Giffuni // dependent dispatch
63476cf6069SPedro Giffuni aVtableSlot.index += 1; //get then set method
63576cf6069SPedro Giffuni cpp_call(
63676cf6069SPedro Giffuni pThis, aVtableSlot,
63776cf6069SPedro Giffuni pReturnTypeRef,
63876cf6069SPedro Giffuni 1, &aParam,
63976cf6069SPedro Giffuni pReturn, pArgs, ppException );
64076cf6069SPedro Giffuni
64176cf6069SPedro Giffuni typelib_typedescriptionreference_release( pReturnTypeRef );
64276cf6069SPedro Giffuni }
64376cf6069SPedro Giffuni
64476cf6069SPedro Giffuni break;
64576cf6069SPedro Giffuni }
64676cf6069SPedro Giffuni case typelib_TypeClass_INTERFACE_METHOD:
64776cf6069SPedro Giffuni {
64876cf6069SPedro Giffuni
649*a0c169eaSCurtis Hamilton ::bridges::cpp_uno::shared::VtableSlot aVtableSlot(
650*a0c169eaSCurtis Hamilton ::bridges::cpp_uno::shared::getVtableSlot(
65176cf6069SPedro Giffuni reinterpret_cast<
65276cf6069SPedro Giffuni typelib_InterfaceMethodTypeDescription const * >(
65376cf6069SPedro Giffuni pMemberDescr)));
65476cf6069SPedro Giffuni switch (aVtableSlot.index)
65576cf6069SPedro Giffuni {
65676cf6069SPedro Giffuni // standard calls
65776cf6069SPedro Giffuni case 1: // acquire uno interface
65876cf6069SPedro Giffuni (*pUnoI->acquire)( pUnoI );
65976cf6069SPedro Giffuni *ppException = 0;
66076cf6069SPedro Giffuni break;
66176cf6069SPedro Giffuni case 2: // release uno interface
66276cf6069SPedro Giffuni (*pUnoI->release)( pUnoI );
66376cf6069SPedro Giffuni *ppException = 0;
66476cf6069SPedro Giffuni break;
66576cf6069SPedro Giffuni case 0: // queryInterface() opt
66676cf6069SPedro Giffuni {
66776cf6069SPedro Giffuni typelib_TypeDescription * pTD = 0;
66876cf6069SPedro Giffuni TYPELIB_DANGER_GET( &pTD, reinterpret_cast< Type * >( pArgs[0] )->getTypeLibType() );
66976cf6069SPedro Giffuni if (pTD)
67076cf6069SPedro Giffuni {
67176cf6069SPedro Giffuni uno_Interface * pInterface = 0;
67276cf6069SPedro Giffuni (*pThis->pBridge->getUnoEnv()->getRegisteredInterface)(
67376cf6069SPedro Giffuni pThis->pBridge->getUnoEnv(),
67476cf6069SPedro Giffuni (void **)&pInterface, pThis->oid.pData, (typelib_InterfaceTypeDescription *)pTD );
67576cf6069SPedro Giffuni
67676cf6069SPedro Giffuni if (pInterface)
67776cf6069SPedro Giffuni {
67876cf6069SPedro Giffuni ::uno_any_construct(
67976cf6069SPedro Giffuni reinterpret_cast< uno_Any * >( pReturn ),
68076cf6069SPedro Giffuni &pInterface, pTD, 0 );
68176cf6069SPedro Giffuni (*pInterface->release)( pInterface );
68276cf6069SPedro Giffuni TYPELIB_DANGER_RELEASE( pTD );
68376cf6069SPedro Giffuni *ppException = 0;
68476cf6069SPedro Giffuni break;
68576cf6069SPedro Giffuni }
68676cf6069SPedro Giffuni TYPELIB_DANGER_RELEASE( pTD );
68776cf6069SPedro Giffuni }
68876cf6069SPedro Giffuni } // else perform queryInterface()
68976cf6069SPedro Giffuni default:
69076cf6069SPedro Giffuni // dependent dispatch
69176cf6069SPedro Giffuni cpp_call(
69276cf6069SPedro Giffuni pThis, aVtableSlot,
69376cf6069SPedro Giffuni ((typelib_InterfaceMethodTypeDescription *)pMemberDescr)->pReturnTypeRef,
69476cf6069SPedro Giffuni ((typelib_InterfaceMethodTypeDescription *)pMemberDescr)->nParams,
69576cf6069SPedro Giffuni ((typelib_InterfaceMethodTypeDescription *)pMemberDescr)->pParams,
69676cf6069SPedro Giffuni pReturn, pArgs, ppException );
69776cf6069SPedro Giffuni }
69876cf6069SPedro Giffuni break;
69976cf6069SPedro Giffuni }
70076cf6069SPedro Giffuni default:
70176cf6069SPedro Giffuni {
70276cf6069SPedro Giffuni ::com::sun::star::uno::RuntimeException aExc(
70376cf6069SPedro Giffuni OUString( RTL_CONSTASCII_USTRINGPARAM("illegal member type description!") ),
70476cf6069SPedro Giffuni ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >() );
70576cf6069SPedro Giffuni
70676cf6069SPedro Giffuni Type const & rExcType = ::getCppuType( &aExc );
70776cf6069SPedro Giffuni // binary identical null reference
70876cf6069SPedro Giffuni ::uno_type_any_construct( *ppException, &aExc, rExcType.getTypeLibType(), 0 );
70976cf6069SPedro Giffuni }
71076cf6069SPedro Giffuni }
71176cf6069SPedro Giffuni }
71276cf6069SPedro Giffuni
71376cf6069SPedro Giffuni } } }
714