xref: /AOO41X/main/bridges/source/cpp_uno/cc50_solaris_sparc/uno2cpp.cxx (revision 61dff127b6698e0bae836c8aedd6ec62111483d1)
1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_bridges.hxx"
26 
27 #include <sal/alloca.h>
28 
29 #include <com/sun/star/uno/genfunc.hxx>
30 #include "com/sun/star/uno/RuntimeException.hpp"
31 #include <uno/data.h>
32 
33 #include "bridges/cpp_uno/shared/bridge.hxx"
34 #include "bridges/cpp_uno/shared/types.hxx"
35 #include "bridges/cpp_uno/shared/unointerfaceproxy.hxx"
36 #include "bridges/cpp_uno/shared/vtables.hxx"
37 
38 #include "cc50_solaris_sparc.hxx"
39 
40 using namespace rtl;
41 using namespace com::sun::star::uno;
42 
43 namespace
44 {
45 
46 extern "C" void callVirtualMethod(
47         void * pAdjustedThisPtr,
48         sal_Int32 nVtableIndex,
49         void * pRegisterReturn,
50         typelib_TypeClass eReturnType,
51         sal_Int32 * pStackLongs,
52         sal_Int32 nStackLongs
53     );
54 
55 //==================================================================================================
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)56 static void cpp_call(
57     bridges::cpp_uno::shared::UnoInterfaceProxy * pThis,
58     bridges::cpp_uno::shared::VtableSlot aVtableSlot,
59     typelib_TypeDescriptionReference * pReturnTypeRef,
60     sal_Int32 nParams, typelib_MethodParameter * pParams,
61     void * pUnoReturn, void * pUnoArgs[], uno_Any ** ppUnoExc )
62 {
63     // pCppI is cc50_solaris_sparc this pointer
64     OSL_ENSURE( pThis, "### no interface given!" );
65 
66     // max space for: [complex ret ptr], values|ptr ...
67     char * pCppStack        = (char *)alloca( ((nParams+3) * sizeof(sal_Int64)) );
68     char * pCppStackStart   = pCppStack;
69 
70     // return
71     typelib_TypeDescription * pReturnTypeDescr = 0;
72     TYPELIB_DANGER_GET( &pReturnTypeDescr, pReturnTypeRef );
73     OSL_ENSURE( pReturnTypeDescr, "### expected return type description!" );
74 
75     void * pCppReturn = 0; // if != 0 && != pUnoReturn, needs reconversion
76 
77     if (pReturnTypeDescr)
78     {
79         if (bridges::cpp_uno::shared::isSimpleType( pReturnTypeDescr ))
80         {
81             pCppReturn = pUnoReturn; // direct way for simple types
82         }
83         else
84         {
85             // complex return via ptr
86             pCppReturn = *(void **)pCppStack
87                 = (bridges::cpp_uno::shared::relatesToInterfaceType(
88                        pReturnTypeDescr )
89                    ? alloca( pReturnTypeDescr->nSize )
90                    : pUnoReturn); // direct way
91             pCppStack += sizeof(void *);
92         }
93     }
94     // push this
95     void * pAdjustedThisPtr = reinterpret_cast< void ** >(pThis->getCppI())
96         + aVtableSlot.offset;
97     *(void**)pCppStack = pAdjustedThisPtr;
98     pCppStack += sizeof( void* );
99 
100     // args
101     void ** pCppArgs  = (void **)alloca( 3 * sizeof(void *) * nParams );
102     // indizes of values this have to be converted (interface conversion cpp<=>uno)
103     sal_Int32 * pTempIndizes = (sal_Int32 *)(pCppArgs + nParams);
104     // type descriptions for reconversions
105     typelib_TypeDescription ** ppTempParamTypeDescr = (typelib_TypeDescription **)(pCppArgs + (2 * nParams));
106 
107     sal_Int32 nTempIndizes   = 0;
108 
109     for ( sal_Int32 nPos = 0; nPos < nParams; ++nPos )
110     {
111         const typelib_MethodParameter & rParam = pParams[nPos];
112         typelib_TypeDescription * pParamTypeDescr = 0;
113         TYPELIB_DANGER_GET( &pParamTypeDescr, rParam.pTypeRef );
114 
115         if (!rParam.bOut
116             && bridges::cpp_uno::shared::isSimpleType( pParamTypeDescr ))
117         {
118             pCppArgs[ nPos ] = CPPU_CURRENT_NAMESPACE::adjustPointer(
119                 pCppStack, pParamTypeDescr );
120             uno_copyAndConvertData( pCppArgs[nPos], pUnoArgs[nPos], pParamTypeDescr,
121                                     pThis->getBridge()->getUno2Cpp() );
122 
123             switch (pParamTypeDescr->eTypeClass)
124             {
125             case typelib_TypeClass_HYPER:
126             case typelib_TypeClass_UNSIGNED_HYPER:
127             case typelib_TypeClass_DOUBLE:
128                 pCppStack += sizeof(sal_Int32); // extra long
129             }
130             // no longer needed
131             TYPELIB_DANGER_RELEASE( pParamTypeDescr );
132         }
133         else // ptr to complex value | ref
134         {
135             if (! rParam.bIn) // is pure out
136             {
137                 // cpp out is constructed mem, uno out is not!
138                 uno_constructData(
139                     *(void **)pCppStack = pCppArgs[nPos] = alloca( pParamTypeDescr->nSize ),
140                     pParamTypeDescr );
141                 pTempIndizes[nTempIndizes] = nPos; // default constructed for cpp call
142                 // will be released at reconversion
143                 ppTempParamTypeDescr[nTempIndizes++] = pParamTypeDescr;
144             }
145             // is in/inout
146             else if (bridges::cpp_uno::shared::relatesToInterfaceType(
147                          pParamTypeDescr ))
148             {
149                 uno_copyAndConvertData(
150                     *(void **)pCppStack = pCppArgs[nPos] = alloca( pParamTypeDescr->nSize ),
151                     pUnoArgs[nPos], pParamTypeDescr,
152                     pThis->getBridge()->getUno2Cpp() );
153 
154                 pTempIndizes[nTempIndizes] = nPos; // has to be reconverted
155                 // will be released at reconversion
156                 ppTempParamTypeDescr[nTempIndizes++] = pParamTypeDescr;
157             }
158             else // direct way
159             {
160                 *(void **)pCppStack = pCppArgs[nPos] = pUnoArgs[nPos];
161                 // no longer needed
162                 TYPELIB_DANGER_RELEASE( pParamTypeDescr );
163             }
164         }
165         pCppStack += sizeof(sal_Int32); // standard parameter length
166     }
167 
168 // seems that EH registration for callVirtualMethod is not really
169 // necessary
170 
171 //  static unsigned long* pFrameInfo = NULL;
172 
173 //  if( ! pFrameInfo )
174 //  {
175 //      pFrameInfo = new unsigned long[ 7 ];
176 //      pFrameInfo[ 0 ] = 0x40000000 | (((unsigned long)__Crun::ex_rethrow_q) >> 2);
177 //      pFrameInfo[ 1 ] = 0x01000000;
178 //      pFrameInfo[ 2 ] = (unsigned long)callVirtualMethodExceptionHandler;
179 //      pFrameInfo[ 3 ] = 0;
180 //          pFrameInfo[ 4 ] = (unsigned long)pFrameInfo - (unsigned long)callVirtualMethodExceptionHandler;
181 //      pFrameInfo[ 5 ] = 0;
182 //      pFrameInfo[ 6 ] = 0;
183 //      _ex_register( pFrameInfo+2, 1 );
184 //  }
185 
186     try
187     {
188         int nStackLongs = (pCppStack - pCppStackStart)/sizeof(sal_Int32);
189         if( nStackLongs & 1 )
190             // stack has to be 8 byte aligned
191             nStackLongs++;
192 
193         callVirtualMethod(
194             pAdjustedThisPtr,
195             aVtableSlot.index,
196             pCppReturn,
197             pReturnTypeDescr->eTypeClass,
198             (sal_Int32 *)pCppStackStart,
199             nStackLongs
200             );
201 
202         // NO exception occured...
203         *ppUnoExc = 0;
204 
205         // reconvert temporary params
206         for ( ; nTempIndizes--; )
207         {
208             sal_Int32 nIndex = pTempIndizes[nTempIndizes];
209             typelib_TypeDescription * pParamTypeDescr = ppTempParamTypeDescr[nTempIndizes];
210 
211             if (pParams[nIndex].bIn)
212             {
213                 if (pParams[nIndex].bOut) // inout
214                 {
215                     uno_destructData( pUnoArgs[nIndex], pParamTypeDescr, 0 ); // destroy uno value
216                     uno_copyAndConvertData( pUnoArgs[nIndex], pCppArgs[nIndex], pParamTypeDescr,
217                                             pThis->getBridge()->getCpp2Uno() );
218                 }
219             }
220             else // pure out
221             {
222                 uno_copyAndConvertData( pUnoArgs[nIndex], pCppArgs[nIndex], pParamTypeDescr,
223                                         pThis->getBridge()->getCpp2Uno() );
224             }
225             // destroy temp cpp param => cpp: every param was constructed
226             uno_destructData(
227                 pCppArgs[nIndex], pParamTypeDescr,
228                 reinterpret_cast< uno_ReleaseFunc >(cpp_release) );
229 
230             TYPELIB_DANGER_RELEASE( pParamTypeDescr );
231         }
232         // return value
233         if (pCppReturn && pUnoReturn != pCppReturn)
234         {
235             uno_copyAndConvertData( pUnoReturn, pCppReturn, pReturnTypeDescr,
236                                     pThis->getBridge()->getCpp2Uno() );
237             uno_destructData(
238                 pCppReturn, pReturnTypeDescr,
239                 reinterpret_cast< uno_ReleaseFunc >(cpp_release) );
240         }
241     }
242     catch( ... )
243     {
244         void* pExc = __Crun::ex_get();
245         const char* pName = __Cimpl::ex_name();
246 
247         // get exception
248         CPPU_CURRENT_NAMESPACE::cc50_solaris_sparc_fillUnoException(
249             pExc, pName, *ppUnoExc, pThis->getBridge()->getCpp2Uno());
250 
251         // temporary params
252         for ( ; nTempIndizes--; )
253         {
254             sal_Int32 nIndex = pTempIndizes[nTempIndizes];
255             // destroy temp cpp param => cpp: every param was constructed
256             uno_destructData(
257                 pCppArgs[nIndex],
258                 ppTempParamTypeDescr[nTempIndizes],
259                 reinterpret_cast< uno_ReleaseFunc >(cpp_release) );
260             TYPELIB_DANGER_RELEASE( ppTempParamTypeDescr[nTempIndizes] );
261         }
262         // return type
263         if (pReturnTypeDescr)
264             TYPELIB_DANGER_RELEASE( pReturnTypeDescr );
265     }
266 }
267 
268 }
269 
270 namespace bridges { namespace cpp_uno { namespace shared {
271 
unoInterfaceProxyDispatch(uno_Interface * pUnoI,const typelib_TypeDescription * pMemberDescr,void * pReturn,void * pArgs[],uno_Any ** ppException)272 void unoInterfaceProxyDispatch(
273     uno_Interface * pUnoI, const typelib_TypeDescription * pMemberDescr,
274     void * pReturn, void * pArgs[], uno_Any ** ppException )
275 {
276     // is my surrogate
277     bridges::cpp_uno::shared::UnoInterfaceProxy * pThis
278         = static_cast< bridges::cpp_uno::shared::UnoInterfaceProxy * >(pUnoI);
279     typelib_InterfaceTypeDescription * pTypeDescr = pThis->pTypeDescr;
280 
281     switch (pMemberDescr->eTypeClass)
282     {
283     case typelib_TypeClass_INTERFACE_ATTRIBUTE:
284     {
285         VtableSlot aVtableSlot(
286             getVtableSlot(
287                 reinterpret_cast<
288                     typelib_InterfaceAttributeTypeDescription const * >(
289                         pMemberDescr)));
290         if (pReturn)
291         {
292             // dependent dispatch
293             cpp_call(
294                 pThis, aVtableSlot,
295                 ((typelib_InterfaceAttributeTypeDescription *)pMemberDescr)->pAttributeTypeRef,
296                 0, 0, // no params
297                 pReturn, pArgs, ppException );
298         }
299         else
300         {
301             // is SET
302             typelib_MethodParameter aParam;
303             aParam.pTypeRef =
304                 ((typelib_InterfaceAttributeTypeDescription *)pMemberDescr)->pAttributeTypeRef;
305             aParam.bIn      = sal_True;
306             aParam.bOut     = sal_False;
307 
308             typelib_TypeDescriptionReference * pReturnTypeRef = 0;
309             OUString aVoidName( RTL_CONSTASCII_USTRINGPARAM("void") );
310             typelib_typedescriptionreference_new(
311                 &pReturnTypeRef, typelib_TypeClass_VOID, aVoidName.pData );
312 
313             // dependent dispatch
314             aVtableSlot.index += 1; // get, then set method
315             cpp_call(
316                 pThis, aVtableSlot,
317                 pReturnTypeRef,
318                 1, &aParam,
319                 pReturn, pArgs, ppException );
320 
321             typelib_typedescriptionreference_release( pReturnTypeRef );
322         }
323 
324         break;
325     }
326     case typelib_TypeClass_INTERFACE_METHOD:
327     {
328         VtableSlot aVtableSlot(
329             getVtableSlot(
330                 reinterpret_cast<
331                     typelib_InterfaceMethodTypeDescription const * >(
332                         pMemberDescr)));
333         switch (aVtableSlot.index)
334         {
335             // standard calls
336         case 1: // acquire uno interface
337             (*pUnoI->acquire)( pUnoI );
338             *ppException = 0;
339             break;
340         case 2: // release uno interface
341             (*pUnoI->release)( pUnoI );
342             *ppException = 0;
343             break;
344         case 0: // queryInterface() opt
345         {
346             typelib_TypeDescription * pTD = 0;
347             TYPELIB_DANGER_GET( &pTD, reinterpret_cast< Type * >( pArgs[0] )->getTypeLibType() );
348             if (pTD)
349             {
350                 uno_Interface * pInterface = 0;
351                 (*pThis->pBridge->getUnoEnv()->getRegisteredInterface)(
352                     pThis->pBridge->getUnoEnv(),
353                     (void **)&pInterface, pThis->oid.pData, (typelib_InterfaceTypeDescription *)pTD );
354 
355                 if (pInterface)
356                 {
357                     ::uno_any_construct(
358                         reinterpret_cast< uno_Any * >( pReturn ),
359                         &pInterface, pTD, 0 );
360                     (*pInterface->release)( pInterface );
361                     TYPELIB_DANGER_RELEASE( pTD );
362                     *ppException = 0;
363                     break;
364                 }
365                 TYPELIB_DANGER_RELEASE( pTD );
366             }
367         } // else perform queryInterface()
368         default:
369             // dependent dispatch
370             cpp_call(
371                 pThis, aVtableSlot,
372                 ((typelib_InterfaceMethodTypeDescription *)pMemberDescr)->pReturnTypeRef,
373                 ((typelib_InterfaceMethodTypeDescription *)pMemberDescr)->nParams,
374                 ((typelib_InterfaceMethodTypeDescription *)pMemberDescr)->pParams,
375                 pReturn, pArgs, ppException );
376         }
377         break;
378     }
379     default:
380     {
381         ::com::sun::star::uno::RuntimeException aExc(
382             OUString( RTL_CONSTASCII_USTRINGPARAM("illegal member type description!") ),
383             ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >() );
384 
385         Type const & rExcType = ::getCppuType( &aExc );
386         // binary identical null reference
387         ::uno_type_any_construct( *ppException, &aExc, rExcType.getTypeLibType(), 0 );
388     }
389     }
390 }
391 
392 } } }
393