xref: /trunk/main/bridges/source/cpp_uno/gcc3_freebsd_powerpc64/uno2cpp.cxx (revision cf6516809c57e1bb0a940545cca99cdad54d4ce2)
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