xref: /trunk/main/bridges/source/cpp_uno/gcc3_linux_mips/cpp2uno.cxx (revision cf6516809c57e1bb0a940545cca99cdad54d4ce2)
161dff127SAndrew Rist /**************************************************************
2cdf0e10cSrcweir  *
361dff127SAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
461dff127SAndrew Rist  * or more contributor license agreements.  See the NOTICE file
561dff127SAndrew Rist  * distributed with this work for additional information
661dff127SAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
761dff127SAndrew Rist  * to you under the Apache License, Version 2.0 (the
861dff127SAndrew Rist  * "License"); you may not use this file except in compliance
961dff127SAndrew Rist  * with the License.  You may obtain a copy of the License at
10cdf0e10cSrcweir  *
1161dff127SAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
12cdf0e10cSrcweir  *
1361dff127SAndrew Rist  * Unless required by applicable law or agreed to in writing,
1461dff127SAndrew Rist  * software distributed under the License is distributed on an
1561dff127SAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
1661dff127SAndrew Rist  * KIND, either express or implied.  See the License for the
1761dff127SAndrew Rist  * specific language governing permissions and limitations
1861dff127SAndrew Rist  * under the License.
19cdf0e10cSrcweir  *
2061dff127SAndrew Rist  *************************************************************/
2161dff127SAndrew Rist 
2261dff127SAndrew Rist 
23cdf0e10cSrcweir #include <com/sun/star/uno/genfunc.hxx>
24cdf0e10cSrcweir #include <typelib/typedescription.hxx>
25cdf0e10cSrcweir #include <uno/data.h>
26cdf0e10cSrcweir #include <osl/endian.h>
27cdf0e10cSrcweir #include "bridges/cpp_uno/shared/bridge.hxx"
28cdf0e10cSrcweir #include "bridges/cpp_uno/shared/cppinterfaceproxy.hxx"
29cdf0e10cSrcweir #include "bridges/cpp_uno/shared/types.hxx"
30cdf0e10cSrcweir #include "bridges/cpp_uno/shared/vtablefactory.hxx"
31cdf0e10cSrcweir #include "share.hxx"
32cdf0e10cSrcweir 
33cdf0e10cSrcweir #include <stdio.h>
34cdf0e10cSrcweir #include <string.h>
35cdf0e10cSrcweir 
36cdf0e10cSrcweir using namespace com::sun::star::uno;
37cdf0e10cSrcweir 
38cdf0e10cSrcweir //#define BRDEBUG
39cdf0e10cSrcweir 
40cdf0e10cSrcweir #ifdef BRDEBUG
41cdf0e10cSrcweir #include <rtl/strbuf.hxx>
42cdf0e10cSrcweir #include <rtl/ustrbuf.hxx>
43cdf0e10cSrcweir #include <osl/diagnose.h>
44cdf0e10cSrcweir #include <osl/mutex.hxx>
45cdf0e10cSrcweir using namespace ::std;
46cdf0e10cSrcweir using namespace ::osl;
47cdf0e10cSrcweir using namespace ::rtl;
48cdf0e10cSrcweir #endif
49cdf0e10cSrcweir #include <sys/sysmips.h>
50cdf0e10cSrcweir 
51cdf0e10cSrcweir #ifdef OSL_BIGENDIAN
52cdf0e10cSrcweir #define IS_BIG_ENDIAN 1
53cdf0e10cSrcweir #else
54cdf0e10cSrcweir #define IS_BIG_ENDIAN 0
55cdf0e10cSrcweir #endif
56cdf0e10cSrcweir 
57cdf0e10cSrcweir using namespace ::com::sun::star::uno;
58cdf0e10cSrcweir 
59cdf0e10cSrcweir namespace
60cdf0e10cSrcweir {
61cdf0e10cSrcweir 
62cdf0e10cSrcweir   //==================================================================================================
cpp2uno_call(bridges::cpp_uno::shared::CppInterfaceProxy * pThis,const typelib_TypeDescription * pMemberTypeDescr,typelib_TypeDescriptionReference * pReturnTypeRef,sal_Int32 nParams,typelib_MethodParameter * pParams,void ** gpreg,void **,void ** ovrflw,sal_Int64 * pRegisterReturn)63cdf0e10cSrcweir   static typelib_TypeClass cpp2uno_call(
64cdf0e10cSrcweir       bridges::cpp_uno::shared::CppInterfaceProxy * pThis,
65cdf0e10cSrcweir       const typelib_TypeDescription * pMemberTypeDescr,
66cdf0e10cSrcweir       typelib_TypeDescriptionReference * pReturnTypeRef, // 0 indicates void return
67cdf0e10cSrcweir       sal_Int32 nParams, typelib_MethodParameter * pParams,
68cdf0e10cSrcweir       void ** gpreg, void ** /*fpreg*/, void ** ovrflw,
69cdf0e10cSrcweir       sal_Int64 * pRegisterReturn /* space for register return */ )
70cdf0e10cSrcweir   {
71cdf0e10cSrcweir     /*  Most MIPS ABIs view the arguments as a struct, of which the
72cdf0e10cSrcweir         first N words go in registers and the rest go on the stack.  If I < N, the
73cdf0e10cSrcweir         Ith word might go in Ith integer argument register or the Ith
74cdf0e10cSrcweir         floating-point one.  For these ABIs, we only need to remember the number
75cdf0e10cSrcweir         of words passed so far.  We are interested only in o32 ABI,so it is the
76cdf0e10cSrcweir         case.
77cdf0e10cSrcweir         */
78cdf0e10cSrcweir     int nw = 0; // number of words used by arguments
79cdf0e10cSrcweir 
80cdf0e10cSrcweir #ifdef BRDEBUG
81cdf0e10cSrcweir     fprintf(stderr,"cpp2uno_call1\n");
82cdf0e10cSrcweir #endif
83cdf0e10cSrcweir 
84cdf0e10cSrcweir     /* C++ has [ret *] or this as the first arguments, so no arguments will
85cdf0e10cSrcweir      * be passed in floating-point registers?
86cdf0e10cSrcweir      */
87cdf0e10cSrcweir     //int int_seen = 0; // have we seen integer arguments?
88cdf0e10cSrcweir 
89cdf0e10cSrcweir     void ** pCppStack; //temporary stack pointer
90cdf0e10cSrcweir 
91cdf0e10cSrcweir     // gpreg:  [ret *], this, [gpr params]
92cdf0e10cSrcweir     // fpreg:  [fpr params]
93cdf0e10cSrcweir     // ovrflw: [gpr or fpr params (properly aligned)]
94cdf0e10cSrcweir 
95cdf0e10cSrcweir     // return
96cdf0e10cSrcweir     typelib_TypeDescription * pReturnTypeDescr = 0;
97cdf0e10cSrcweir     if (pReturnTypeRef)
98cdf0e10cSrcweir       TYPELIB_DANGER_GET( &pReturnTypeDescr, pReturnTypeRef );
99cdf0e10cSrcweir 
100cdf0e10cSrcweir     void * pUnoReturn = 0;
101cdf0e10cSrcweir     void * pCppReturn = 0; // complex return ptr: if != 0 && != pUnoReturn, reconversion need
102cdf0e10cSrcweir 
103cdf0e10cSrcweir     if (pReturnTypeDescr)
104cdf0e10cSrcweir     {
105cdf0e10cSrcweir       if (bridges::cpp_uno::shared::isSimpleType( pReturnTypeDescr ))
106cdf0e10cSrcweir       {
107cdf0e10cSrcweir         pUnoReturn = pRegisterReturn; // direct way for simple types
108cdf0e10cSrcweir #ifdef BRDEBUG
109cdf0e10cSrcweir     fprintf(stderr,"cpp2uno_call:simplereturn\n");
110cdf0e10cSrcweir #endif
111cdf0e10cSrcweir       }
112cdf0e10cSrcweir       else // complex return via ptr (pCppReturn)
113cdf0e10cSrcweir       {
114cdf0e10cSrcweir         pCppReturn = *(void **)gpreg;
115cdf0e10cSrcweir         gpreg++;
116cdf0e10cSrcweir         nw++;
117cdf0e10cSrcweir 
118cdf0e10cSrcweir         pUnoReturn = (bridges::cpp_uno::shared::relatesToInterfaceType( pReturnTypeDescr )
119cdf0e10cSrcweir             ? alloca( pReturnTypeDescr->nSize )
120cdf0e10cSrcweir             : pCppReturn); // direct way
121cdf0e10cSrcweir #ifdef BRDEBUG
122cdf0e10cSrcweir     fprintf(stderr,"cpp2uno_call:complexreturn\n");
123cdf0e10cSrcweir #endif
124cdf0e10cSrcweir       }
125cdf0e10cSrcweir     }
126cdf0e10cSrcweir 
127cdf0e10cSrcweir     // pop this
128cdf0e10cSrcweir     gpreg++;
129cdf0e10cSrcweir     nw++;
130cdf0e10cSrcweir 
131cdf0e10cSrcweir     // stack space
132cdf0e10cSrcweir     OSL_ENSURE( sizeof(void *) == sizeof(sal_Int32), "### unexpected size!" );
133cdf0e10cSrcweir     // parameters
134cdf0e10cSrcweir     void ** pUnoArgs = (void **)alloca( 4 * sizeof(void *) * nParams );
135cdf0e10cSrcweir     void ** pCppArgs = pUnoArgs + nParams;
136cdf0e10cSrcweir     // indizes of values this have to be converted (interface conversion cpp<=>uno)
137cdf0e10cSrcweir     sal_Int32 * pTempIndizes = (sal_Int32 *)(pUnoArgs + (2 * nParams));
138cdf0e10cSrcweir     // type descriptions for reconversions
139cdf0e10cSrcweir     typelib_TypeDescription ** ppTempParamTypeDescr = (typelib_TypeDescription **)(pUnoArgs + (3 * nParams));
140cdf0e10cSrcweir 
141cdf0e10cSrcweir     sal_Int32 nTempIndizes   = 0;
142cdf0e10cSrcweir 
143cdf0e10cSrcweir #ifdef BRDEBUG
144cdf0e10cSrcweir     fprintf(stderr,"cpp2uno_call:nParams=%d\n",nParams);
145cdf0e10cSrcweir #endif
146cdf0e10cSrcweir 
147cdf0e10cSrcweir     for ( sal_Int32 nPos = 0; nPos < nParams; ++nPos )
148cdf0e10cSrcweir     {
149cdf0e10cSrcweir       const typelib_MethodParameter & rParam = pParams[nPos];
150cdf0e10cSrcweir       typelib_TypeDescription * pParamTypeDescr = 0;
151cdf0e10cSrcweir       TYPELIB_DANGER_GET( &pParamTypeDescr, rParam.pTypeRef );
152cdf0e10cSrcweir 
153cdf0e10cSrcweir       if (!rParam.bOut && bridges::cpp_uno::shared::isSimpleType( pParamTypeDescr ))
154cdf0e10cSrcweir         // value
155cdf0e10cSrcweir       {
156cdf0e10cSrcweir 
157cdf0e10cSrcweir         switch (pParamTypeDescr->eTypeClass)
158cdf0e10cSrcweir         {
159cdf0e10cSrcweir           case typelib_TypeClass_DOUBLE:
160cdf0e10cSrcweir           case typelib_TypeClass_HYPER:
161cdf0e10cSrcweir           case typelib_TypeClass_UNSIGNED_HYPER:
162cdf0e10cSrcweir #ifdef BRDEBUG
163cdf0e10cSrcweir     fprintf(stderr,"cpp2uno_call:hyper=%d,%p\n",pParamTypeDescr->eTypeClass,gpreg[0]);
164cdf0e10cSrcweir #endif
165cdf0e10cSrcweir             if (nw < 3) {
166cdf0e10cSrcweir               if (nw & 1) {
167cdf0e10cSrcweir                 nw++;
168cdf0e10cSrcweir                 gpreg++;
169cdf0e10cSrcweir               }
170cdf0e10cSrcweir #ifdef BRDEBUG
171cdf0e10cSrcweir     fprintf(stderr,"cpp2uno_call:gpreg=%p,%p\n",gpreg[0],gpreg[1]);
172cdf0e10cSrcweir #endif
173cdf0e10cSrcweir               pCppArgs[nPos] = gpreg;
174cdf0e10cSrcweir               pUnoArgs[nPos] = gpreg;
175cdf0e10cSrcweir               nw += 2;
176cdf0e10cSrcweir               gpreg += 2;
177cdf0e10cSrcweir             } else {
178cdf0e10cSrcweir               if (((long)ovrflw) & 4) ovrflw++;
179cdf0e10cSrcweir #ifdef BRDEBUG
180cdf0e10cSrcweir     fprintf(stderr,"cpp2uno_call:overflw=%p,%p\n",ovrflw[0],ovrflw[1]);
181cdf0e10cSrcweir #endif
182cdf0e10cSrcweir               pCppArgs[nPos] = ovrflw;
183cdf0e10cSrcweir               pUnoArgs[nPos] = ovrflw;
184cdf0e10cSrcweir               ovrflw += 2;
185cdf0e10cSrcweir             }
186cdf0e10cSrcweir             break;
187cdf0e10cSrcweir 
188cdf0e10cSrcweir           case typelib_TypeClass_BYTE:
189cdf0e10cSrcweir           case typelib_TypeClass_BOOLEAN:
190cdf0e10cSrcweir #ifdef BRDEBUG
191cdf0e10cSrcweir     fprintf(stderr,"cpp2uno_call:byte=%p,%p\n",gpreg[0],ovrflw[0]);
192cdf0e10cSrcweir #endif
193cdf0e10cSrcweir             if (nw < 4) {
194cdf0e10cSrcweir               pCppArgs[nPos] = ((char *)gpreg + 3*IS_BIG_ENDIAN);
195cdf0e10cSrcweir               pUnoArgs[nPos] = ((char *)gpreg + 3*IS_BIG_ENDIAN);
196cdf0e10cSrcweir               nw++;
197cdf0e10cSrcweir               gpreg++;
198cdf0e10cSrcweir             } else {
199cdf0e10cSrcweir               pCppArgs[nPos] = ((char *)ovrflw + 3*IS_BIG_ENDIAN);
200cdf0e10cSrcweir               pUnoArgs[nPos] = ((char *)ovrflw + 3*IS_BIG_ENDIAN);
201cdf0e10cSrcweir               ovrflw++;
202cdf0e10cSrcweir             }
203cdf0e10cSrcweir             break;
204cdf0e10cSrcweir 
205cdf0e10cSrcweir 
206cdf0e10cSrcweir           case typelib_TypeClass_CHAR:
207cdf0e10cSrcweir           case typelib_TypeClass_SHORT:
208cdf0e10cSrcweir           case typelib_TypeClass_UNSIGNED_SHORT:
209cdf0e10cSrcweir #ifdef BRDEBUG
210cdf0e10cSrcweir     fprintf(stderr,"cpp2uno_call:char=%p,%p\n",gpreg[0],ovrflw[0]);
211cdf0e10cSrcweir #endif
212cdf0e10cSrcweir             if (nw < 4) {
213cdf0e10cSrcweir               pCppArgs[nPos] = ((char *)gpreg + 2*IS_BIG_ENDIAN);
214cdf0e10cSrcweir               pUnoArgs[nPos] = ((char *)gpreg + 2*IS_BIG_ENDIAN);
215cdf0e10cSrcweir               nw++;
216cdf0e10cSrcweir               gpreg++;
217cdf0e10cSrcweir             } else {
218cdf0e10cSrcweir               pCppArgs[nPos] = ((char *)ovrflw + 2*IS_BIG_ENDIAN);
219cdf0e10cSrcweir               pUnoArgs[nPos] = ((char *)ovrflw + 2*IS_BIG_ENDIAN);
220cdf0e10cSrcweir               ovrflw++;
221cdf0e10cSrcweir             }
222cdf0e10cSrcweir             break;
223cdf0e10cSrcweir 
224cdf0e10cSrcweir 
225cdf0e10cSrcweir           default:
226cdf0e10cSrcweir #ifdef BRDEBUG
227cdf0e10cSrcweir     fprintf(stderr,"cpp2uno_call:def=%p,%p\n",gpreg[0],ovrflw[0]);
228cdf0e10cSrcweir #endif
229cdf0e10cSrcweir             if (nw < 4) {
230cdf0e10cSrcweir               pCppArgs[nPos] = gpreg;
231cdf0e10cSrcweir               pUnoArgs[nPos] = gpreg;
232cdf0e10cSrcweir               nw++;
233cdf0e10cSrcweir               gpreg++;
234cdf0e10cSrcweir             } else {
235cdf0e10cSrcweir               pCppArgs[nPos] = ovrflw;
236cdf0e10cSrcweir               pUnoArgs[nPos] = ovrflw;
237cdf0e10cSrcweir               ovrflw++;
238cdf0e10cSrcweir             }
239cdf0e10cSrcweir             break;
240cdf0e10cSrcweir 
241cdf0e10cSrcweir         }
242cdf0e10cSrcweir         // no longer needed
243cdf0e10cSrcweir         TYPELIB_DANGER_RELEASE( pParamTypeDescr );
244cdf0e10cSrcweir       }
245cdf0e10cSrcweir       else // ptr to complex value | ref
246cdf0e10cSrcweir       {
247cdf0e10cSrcweir 
248cdf0e10cSrcweir #ifdef BRDEBUG
249cdf0e10cSrcweir     fprintf(stderr,"cpp2uno_call:ptr|ref\n");
250cdf0e10cSrcweir #endif
251cdf0e10cSrcweir         if (nw < 4) {
252cdf0e10cSrcweir           pCppArgs[nPos] = *(void **)gpreg;
253cdf0e10cSrcweir           pCppStack = gpreg;
254cdf0e10cSrcweir           nw++;
255cdf0e10cSrcweir           gpreg++;
256cdf0e10cSrcweir         } else {
257cdf0e10cSrcweir           pCppArgs[nPos] = *(void **)ovrflw;
258cdf0e10cSrcweir           pCppStack = ovrflw;
259cdf0e10cSrcweir           ovrflw++;
260cdf0e10cSrcweir         }
261cdf0e10cSrcweir #ifdef BRDEBUG
262cdf0e10cSrcweir     fprintf(stderr,"cpp2uno_call:pCppStack=%p\n",pCppStack);
263cdf0e10cSrcweir #endif
264cdf0e10cSrcweir 
265cdf0e10cSrcweir         if (! rParam.bIn) // is pure out
266cdf0e10cSrcweir         {
267cdf0e10cSrcweir           // uno out is unconstructed mem!
268cdf0e10cSrcweir           pUnoArgs[nPos] = alloca( pParamTypeDescr->nSize );
269cdf0e10cSrcweir           pTempIndizes[nTempIndizes] = nPos;
270cdf0e10cSrcweir           // will be released at reconversion
271cdf0e10cSrcweir           ppTempParamTypeDescr[nTempIndizes++] = pParamTypeDescr;
272cdf0e10cSrcweir         }
273cdf0e10cSrcweir         // is in/inout
274cdf0e10cSrcweir         else if (bridges::cpp_uno::shared::relatesToInterfaceType( pParamTypeDescr ))
275cdf0e10cSrcweir         {
276cdf0e10cSrcweir           uno_copyAndConvertData( pUnoArgs[nPos] = alloca( pParamTypeDescr->nSize ),
277cdf0e10cSrcweir               *(void **)pCppStack, pParamTypeDescr,
278cdf0e10cSrcweir               pThis->getBridge()->getCpp2Uno() );
279cdf0e10cSrcweir           pTempIndizes[nTempIndizes] = nPos; // has to be reconverted
280cdf0e10cSrcweir           // will be released at reconversion
281cdf0e10cSrcweir           ppTempParamTypeDescr[nTempIndizes++] = pParamTypeDescr;
282cdf0e10cSrcweir #ifdef BRDEBUG
283cdf0e10cSrcweir     fprintf(stderr,"cpp2uno_call:related to interface,%p,%d,pUnoargs[%d]=%p\n",*(void**)pCppStack,pParamTypeDescr->nSize,nPos,pUnoArgs[nPos]);
284cdf0e10cSrcweir #endif
285cdf0e10cSrcweir         }
286cdf0e10cSrcweir         else // direct way
287cdf0e10cSrcweir         {
288cdf0e10cSrcweir           pUnoArgs[nPos] = *(void **)pCppStack;
289cdf0e10cSrcweir #ifdef BRDEBUG
290cdf0e10cSrcweir     fprintf(stderr,"cpp2uno_call:direct,pUnoArgs[%d]=%p\n",nPos,pUnoArgs[nPos]);
291cdf0e10cSrcweir #endif
292cdf0e10cSrcweir           // no longer needed
293cdf0e10cSrcweir           TYPELIB_DANGER_RELEASE( pParamTypeDescr );
294cdf0e10cSrcweir         }
295cdf0e10cSrcweir       }
296cdf0e10cSrcweir     }
297cdf0e10cSrcweir #ifdef BRDEBUG
298cdf0e10cSrcweir     fprintf(stderr,"cpp2uno_call2,%p,unoargs=%p\n",pThis->getUnoI()->pDispatcher,pUnoArgs);
299cdf0e10cSrcweir #endif
300cdf0e10cSrcweir 
301cdf0e10cSrcweir     // ExceptionHolder
302cdf0e10cSrcweir     uno_Any aUnoExc; // Any will be constructed by callee
303cdf0e10cSrcweir     uno_Any * pUnoExc = &aUnoExc;
304cdf0e10cSrcweir 
305cdf0e10cSrcweir     // invoke uno dispatch call
306cdf0e10cSrcweir     (*pThis->getUnoI()->pDispatcher)( pThis->getUnoI(), pMemberTypeDescr, pUnoReturn, pUnoArgs, &pUnoExc );
307cdf0e10cSrcweir #ifdef BRDEBUG
308cdf0e10cSrcweir     fprintf(stderr,"cpp2uno_call2,after dispatch\n");
309cdf0e10cSrcweir #endif
310cdf0e10cSrcweir 
311*07a3d7f1SPedro Giffuni     // in case an exception occurred...
312cdf0e10cSrcweir     if (pUnoExc)
313cdf0e10cSrcweir     {
314cdf0e10cSrcweir       // destruct temporary in/inout params
315cdf0e10cSrcweir       for ( ; nTempIndizes--; )
316cdf0e10cSrcweir       {
317cdf0e10cSrcweir         sal_Int32 nIndex = pTempIndizes[nTempIndizes];
318cdf0e10cSrcweir 
319cdf0e10cSrcweir         if (pParams[nIndex].bIn) // is in/inout => was constructed
320cdf0e10cSrcweir           uno_destructData( pUnoArgs[nIndex], ppTempParamTypeDescr[nTempIndizes], 0 );
321cdf0e10cSrcweir         TYPELIB_DANGER_RELEASE( ppTempParamTypeDescr[nTempIndizes] );
322cdf0e10cSrcweir       }
323cdf0e10cSrcweir       if (pReturnTypeDescr)
324cdf0e10cSrcweir         TYPELIB_DANGER_RELEASE( pReturnTypeDescr );
325cdf0e10cSrcweir 
326cdf0e10cSrcweir       CPPU_CURRENT_NAMESPACE::raiseException( &aUnoExc, pThis->getBridge()->getUno2Cpp() );
327cdf0e10cSrcweir       // has to destruct the any
328cdf0e10cSrcweir       // is here for dummy
329cdf0e10cSrcweir       return typelib_TypeClass_VOID;
330cdf0e10cSrcweir     }
331*07a3d7f1SPedro Giffuni     else // else no exception occurred...
332cdf0e10cSrcweir     {
333cdf0e10cSrcweir       // temporary params
334cdf0e10cSrcweir       for ( ; nTempIndizes--; )
335cdf0e10cSrcweir       {
336cdf0e10cSrcweir         sal_Int32 nIndex = pTempIndizes[nTempIndizes];
337cdf0e10cSrcweir         typelib_TypeDescription * pParamTypeDescr = ppTempParamTypeDescr[nTempIndizes];
338cdf0e10cSrcweir 
339cdf0e10cSrcweir         if (pParams[nIndex].bOut) // inout/out
340cdf0e10cSrcweir         {
341cdf0e10cSrcweir           // convert and assign
342cdf0e10cSrcweir           uno_destructData( pCppArgs[nIndex], pParamTypeDescr, cpp_release );
343cdf0e10cSrcweir           uno_copyAndConvertData( pCppArgs[nIndex], pUnoArgs[nIndex], pParamTypeDescr,
344cdf0e10cSrcweir               pThis->getBridge()->getUno2Cpp() );
345cdf0e10cSrcweir         }
346cdf0e10cSrcweir         // destroy temp uno param
347cdf0e10cSrcweir         uno_destructData( pUnoArgs[nIndex], pParamTypeDescr, 0 );
348cdf0e10cSrcweir 
349cdf0e10cSrcweir         TYPELIB_DANGER_RELEASE( pParamTypeDescr );
350cdf0e10cSrcweir       }
351cdf0e10cSrcweir       // return
352cdf0e10cSrcweir       if (pCppReturn) // has complex return
353cdf0e10cSrcweir       {
354cdf0e10cSrcweir         if (pUnoReturn != pCppReturn) // needs reconversion
355cdf0e10cSrcweir         {
356cdf0e10cSrcweir           uno_copyAndConvertData( pCppReturn, pUnoReturn, pReturnTypeDescr,
357cdf0e10cSrcweir               pThis->getBridge()->getUno2Cpp() );
358cdf0e10cSrcweir           // destroy temp uno return
359cdf0e10cSrcweir           uno_destructData( pUnoReturn, pReturnTypeDescr, 0 );
360cdf0e10cSrcweir         }
361cdf0e10cSrcweir         // complex return ptr is set to return reg
362cdf0e10cSrcweir         *(void **)pRegisterReturn = pCppReturn;
363cdf0e10cSrcweir       }
364cdf0e10cSrcweir       if (pReturnTypeDescr)
365cdf0e10cSrcweir       {
366cdf0e10cSrcweir         typelib_TypeClass eRet = (typelib_TypeClass)pReturnTypeDescr->eTypeClass;
367cdf0e10cSrcweir         TYPELIB_DANGER_RELEASE( pReturnTypeDescr );
368cdf0e10cSrcweir         return eRet;
369cdf0e10cSrcweir       }
370cdf0e10cSrcweir       else
371cdf0e10cSrcweir         return typelib_TypeClass_VOID;
372cdf0e10cSrcweir     }
373cdf0e10cSrcweir   }
374cdf0e10cSrcweir 
375cdf0e10cSrcweir 
376cdf0e10cSrcweir   //==================================================================================================
cpp_mediate(sal_Int32 nFunctionIndex,sal_Int32 nVtableOffset,void ** gpreg,void ** fpreg,void ** ovrflw,sal_Int64 * pRegisterReturn)377cdf0e10cSrcweir   static typelib_TypeClass cpp_mediate(
378cdf0e10cSrcweir       sal_Int32 nFunctionIndex,
379cdf0e10cSrcweir       sal_Int32 nVtableOffset,
380cdf0e10cSrcweir       void ** gpreg, void ** fpreg, void ** ovrflw,
381cdf0e10cSrcweir       sal_Int64 * pRegisterReturn /* space for register return */ )
382cdf0e10cSrcweir   {
383cdf0e10cSrcweir     OSL_ENSURE( sizeof(sal_Int32)==sizeof(void *), "### unexpected!" );
384cdf0e10cSrcweir 
385cdf0e10cSrcweir #ifdef BRDEBUG
386cdf0e10cSrcweir     fprintf(stderr,"cpp_mediate1 gp=%p,fp=%p,ov=%p\n",gpreg,fpreg,ovrflw);
387cdf0e10cSrcweir     fprintf(stderr,"gp=%x,%x,%x,%x\n",gpreg[0],gpreg[1],gpreg[2],gpreg[3]);
388cdf0e10cSrcweir #endif
389cdf0e10cSrcweir 
390cdf0e10cSrcweir     // gpreg:  [ret *], this, [other gpr params]
391cdf0e10cSrcweir     // fpreg:  [fpr params]
392cdf0e10cSrcweir     // ovrflw: [gpr or fpr params (properly aligned)]
393cdf0e10cSrcweir 
394cdf0e10cSrcweir     void * pThis;
395cdf0e10cSrcweir     if (nFunctionIndex & 0x80000000 )
396cdf0e10cSrcweir     {
397cdf0e10cSrcweir       nFunctionIndex &= 0x7fffffff;
398cdf0e10cSrcweir       pThis = gpreg[1];
399cdf0e10cSrcweir     }
400cdf0e10cSrcweir     else
401cdf0e10cSrcweir     {
402cdf0e10cSrcweir       pThis = gpreg[0];
403cdf0e10cSrcweir     }
404cdf0e10cSrcweir #ifdef BRDEBUG
405cdf0e10cSrcweir     fprintf(stderr,"cpp_mediate12,pThis=%p, nFunctionIndex=%d,nVtableOffset=%d\n",pThis,nFunctionIndex,nVtableOffset);
406cdf0e10cSrcweir #endif
407cdf0e10cSrcweir 
408cdf0e10cSrcweir     pThis = static_cast< char * >(pThis) - nVtableOffset;
409cdf0e10cSrcweir     bridges::cpp_uno::shared::CppInterfaceProxy * pCppI
410cdf0e10cSrcweir       = bridges::cpp_uno::shared::CppInterfaceProxy::castInterfaceToProxy(
411cdf0e10cSrcweir           pThis);
412cdf0e10cSrcweir #ifdef BRDEBUG
413cdf0e10cSrcweir     fprintf(stderr,"cpp_mediate13,pCppI=%p\n",pCppI);
414cdf0e10cSrcweir #endif
415cdf0e10cSrcweir 
416cdf0e10cSrcweir     typelib_InterfaceTypeDescription * pTypeDescr = pCppI->getTypeDescr();
417cdf0e10cSrcweir 
418cdf0e10cSrcweir #ifdef BRDEBUG
419cdf0e10cSrcweir     fprintf(stderr,"cpp_mediate2\n");
420cdf0e10cSrcweir #endif
421cdf0e10cSrcweir     OSL_ENSURE( nFunctionIndex < pTypeDescr->nMapFunctionIndexToMemberIndex, "### illegal vtable index!" );
422cdf0e10cSrcweir     if (nFunctionIndex >= pTypeDescr->nMapFunctionIndexToMemberIndex)
423cdf0e10cSrcweir     {
424cdf0e10cSrcweir       throw RuntimeException(
425cdf0e10cSrcweir           rtl::OUString::createFromAscii("illegal vtable index!"),
426cdf0e10cSrcweir           (XInterface *)pThis );
427cdf0e10cSrcweir     }
428cdf0e10cSrcweir 
429cdf0e10cSrcweir     // determine called method
430cdf0e10cSrcweir     sal_Int32 nMemberPos = pTypeDescr->pMapFunctionIndexToMemberIndex[nFunctionIndex];
431cdf0e10cSrcweir     OSL_ENSURE( nMemberPos < pTypeDescr->nAllMembers, "### illegal member index!" );
432cdf0e10cSrcweir 
433cdf0e10cSrcweir     TypeDescription aMemberDescr( pTypeDescr->ppAllMembers[nMemberPos] );
434cdf0e10cSrcweir 
435cdf0e10cSrcweir #ifdef BRDEBUG
436cdf0e10cSrcweir     fprintf(stderr,"cpp_mediate3\n");
437cdf0e10cSrcweir     OString cstr( OUStringToOString( aMemberDescr.get()->pTypeName, RTL_TEXTENCODING_ASCII_US ) );
438cdf0e10cSrcweir     fprintf( stderr, "calling %s, nFunctionIndex=%d\n", cstr.getStr(), nFunctionIndex );
439cdf0e10cSrcweir #endif
440cdf0e10cSrcweir     typelib_TypeClass eRet;
441cdf0e10cSrcweir     switch (aMemberDescr.get()->eTypeClass)
442cdf0e10cSrcweir     {
443cdf0e10cSrcweir       case typelib_TypeClass_INTERFACE_ATTRIBUTE:
444cdf0e10cSrcweir         {
445cdf0e10cSrcweir #ifdef BRDEBUG
446cdf0e10cSrcweir     fprintf(stderr,"cpp_mediate4\n");
447cdf0e10cSrcweir #endif
448cdf0e10cSrcweir           if (pTypeDescr->pMapMemberIndexToFunctionIndex[nMemberPos] == nFunctionIndex)
449cdf0e10cSrcweir           {
450cdf0e10cSrcweir             // is GET method
451cdf0e10cSrcweir             eRet = cpp2uno_call(
452cdf0e10cSrcweir                 pCppI, aMemberDescr.get(),
453cdf0e10cSrcweir                 ((typelib_InterfaceAttributeTypeDescription *)aMemberDescr.get())->pAttributeTypeRef,
454cdf0e10cSrcweir                 0, 0, // no params
455cdf0e10cSrcweir                 gpreg, fpreg, ovrflw, pRegisterReturn );
456cdf0e10cSrcweir           }
457cdf0e10cSrcweir           else
458cdf0e10cSrcweir           {
459cdf0e10cSrcweir             // is SET method
460cdf0e10cSrcweir             typelib_MethodParameter aParam;
461cdf0e10cSrcweir             aParam.pTypeRef =
462cdf0e10cSrcweir               ((typelib_InterfaceAttributeTypeDescription *)aMemberDescr.get())->pAttributeTypeRef;
463cdf0e10cSrcweir             aParam.bIn      = sal_True;
464cdf0e10cSrcweir             aParam.bOut     = sal_False;
465cdf0e10cSrcweir 
466cdf0e10cSrcweir             eRet = cpp2uno_call(
467cdf0e10cSrcweir                 pCppI, aMemberDescr.get(),
468cdf0e10cSrcweir                 0, // indicates void return
469cdf0e10cSrcweir                 1, &aParam,
470cdf0e10cSrcweir                 gpreg, fpreg, ovrflw, pRegisterReturn );
471cdf0e10cSrcweir           }
472cdf0e10cSrcweir           break;
473cdf0e10cSrcweir         }
474cdf0e10cSrcweir       case typelib_TypeClass_INTERFACE_METHOD:
475cdf0e10cSrcweir         {
476cdf0e10cSrcweir #ifdef BRDEBUG
477cdf0e10cSrcweir     fprintf(stderr,"cpp_mediate5\n");
478cdf0e10cSrcweir #endif
479cdf0e10cSrcweir           // is METHOD
480cdf0e10cSrcweir           switch (nFunctionIndex)
481cdf0e10cSrcweir           {
482cdf0e10cSrcweir             case 1: // acquire()
483cdf0e10cSrcweir               pCppI->acquireProxy(); // non virtual call!
484cdf0e10cSrcweir               eRet = typelib_TypeClass_VOID;
485cdf0e10cSrcweir               break;
486cdf0e10cSrcweir             case 2: // release()
487cdf0e10cSrcweir #ifdef BRDEBUG
488cdf0e10cSrcweir     fprintf(stderr,"cpp_mediate51\n");
489cdf0e10cSrcweir #endif
490cdf0e10cSrcweir               pCppI->releaseProxy(); // non virtual call!
491cdf0e10cSrcweir               eRet = typelib_TypeClass_VOID;
492cdf0e10cSrcweir #ifdef BRDEBUG
493cdf0e10cSrcweir     fprintf(stderr,"cpp_mediate52\n");
494cdf0e10cSrcweir #endif
495cdf0e10cSrcweir               break;
496cdf0e10cSrcweir             case 0: // queryInterface() opt
497cdf0e10cSrcweir               {
498cdf0e10cSrcweir                 typelib_TypeDescription * pTD = 0;
499cdf0e10cSrcweir                 TYPELIB_DANGER_GET( &pTD, reinterpret_cast< Type * >( gpreg[2] )->getTypeLibType() );
500cdf0e10cSrcweir                 if (pTD)
501cdf0e10cSrcweir                 {
502cdf0e10cSrcweir                   XInterface * pInterface = 0;
503cdf0e10cSrcweir                   (*pCppI->getBridge()->getCppEnv()->getRegisteredInterface)(
504cdf0e10cSrcweir                                                                              pCppI->getBridge()->getCppEnv(),
505cdf0e10cSrcweir                                                                              (void **)&pInterface, pCppI->getOid().pData,
506cdf0e10cSrcweir                                                                              (typelib_InterfaceTypeDescription *)pTD );
507cdf0e10cSrcweir 
508cdf0e10cSrcweir                   if (pInterface)
509cdf0e10cSrcweir                   {
510cdf0e10cSrcweir                     ::uno_any_construct(
511cdf0e10cSrcweir                         reinterpret_cast< uno_Any * >( gpreg[0] ),
512cdf0e10cSrcweir                         &pInterface, pTD, cpp_acquire );
513cdf0e10cSrcweir                     pInterface->release();
514cdf0e10cSrcweir                     TYPELIB_DANGER_RELEASE( pTD );
515cdf0e10cSrcweir                     *(void **)pRegisterReturn = gpreg[0];
516cdf0e10cSrcweir                     eRet = typelib_TypeClass_ANY;
517cdf0e10cSrcweir                     break;
518cdf0e10cSrcweir                   }
519cdf0e10cSrcweir                   TYPELIB_DANGER_RELEASE( pTD );
520cdf0e10cSrcweir                 }
521cdf0e10cSrcweir               } // else perform queryInterface()
522cdf0e10cSrcweir             default:
523cdf0e10cSrcweir               eRet = cpp2uno_call(
524cdf0e10cSrcweir                   pCppI, aMemberDescr.get(),
525cdf0e10cSrcweir                   ((typelib_InterfaceMethodTypeDescription *)aMemberDescr.get())->pReturnTypeRef,
526cdf0e10cSrcweir                   ((typelib_InterfaceMethodTypeDescription *)aMemberDescr.get())->nParams,
527cdf0e10cSrcweir                   ((typelib_InterfaceMethodTypeDescription *)aMemberDescr.get())->pParams,
528cdf0e10cSrcweir                   gpreg, fpreg, ovrflw, pRegisterReturn );
529cdf0e10cSrcweir           }
530cdf0e10cSrcweir           break;
531cdf0e10cSrcweir         }
532cdf0e10cSrcweir       default:
533cdf0e10cSrcweir         {
534cdf0e10cSrcweir #ifdef BRDEBUG
535cdf0e10cSrcweir     fprintf(stderr,"cpp_mediate6\n");
536cdf0e10cSrcweir #endif
537cdf0e10cSrcweir           throw RuntimeException(
538cdf0e10cSrcweir               rtl::OUString::createFromAscii("no member description found!"),
539cdf0e10cSrcweir               (XInterface *)pThis );
540cdf0e10cSrcweir           // is here for dummy
541cdf0e10cSrcweir           eRet = typelib_TypeClass_VOID;
542cdf0e10cSrcweir         }
543cdf0e10cSrcweir     }
544cdf0e10cSrcweir 
545cdf0e10cSrcweir     return eRet;
546cdf0e10cSrcweir   }
547cdf0e10cSrcweir 
548cdf0e10cSrcweir   //==================================================================================================
549cdf0e10cSrcweir   /**
550cdf0e10cSrcweir    * is called on incoming vtable calls
551cdf0e10cSrcweir    * (called by asm snippets)
552cdf0e10cSrcweir    */
553cdf0e10cSrcweir //  static void cpp_vtable_call( int nFunctionIndex, int nVtableOffset, void** gpregptr, void** fpregptr, void** ovrflw)
554cdf0e10cSrcweir //  static void cpp_vtable_call( int nFunctionIndex, int nVtableOffset, void** gpregptr, void** ovrflw)
cpp_vtable_call(void)555cdf0e10cSrcweir   static void cpp_vtable_call(void)
556cdf0e10cSrcweir   {
557cdf0e10cSrcweir     int nFunctionIndex;
558cdf0e10cSrcweir     int vTableOffset;
559cdf0e10cSrcweir     void** pCallStack;
560cdf0e10cSrcweir     void** ovrflw;
561cdf0e10cSrcweir 
562cdf0e10cSrcweir     sal_Int32     gpreg[4];
563cdf0e10cSrcweir     double        fpreg[2];
564cdf0e10cSrcweir 
565cdf0e10cSrcweir     //memcpy( fpreg, fpregptr, 16);
566cdf0e10cSrcweir 
567cdf0e10cSrcweir     volatile long nRegReturn[2];
568cdf0e10cSrcweir 
569cdf0e10cSrcweir     __asm__( "sw $4, %0\n\t"
570cdf0e10cSrcweir          "sw $5, %1\n\t"
571cdf0e10cSrcweir          "sw $6, %2\n\t"
572cdf0e10cSrcweir          "sw $7, %3\n\t"
573cdf0e10cSrcweir             ::"m"(nFunctionIndex), "m"(vTableOffset), "m"(pCallStack), "m"(ovrflw) );
574cdf0e10cSrcweir 
575cdf0e10cSrcweir     memcpy( gpreg, pCallStack, 16);
576cdf0e10cSrcweir 
577cdf0e10cSrcweir #ifdef BRDEBUG
578cdf0e10cSrcweir     fprintf(stderr,"in cpp_vtable_call nFunctionIndex is %d\n",nFunctionIndex);
579cdf0e10cSrcweir     fprintf(stderr,"in cpp_vtable_call nVtableOffset is %d\n",vTableOffset);
580cdf0e10cSrcweir     fprintf(stderr,"gp=%x,%x,%x,%x\n",gpreg[0],gpreg[1],gpreg[2],gpreg[3]);
581cdf0e10cSrcweir #endif
582cdf0e10cSrcweir 
583cdf0e10cSrcweir     //sal_Bool bComplex = nFunctionIndex & 0x80000000 ? sal_True : sal_False;
584cdf0e10cSrcweir 
585cdf0e10cSrcweir     typelib_TypeClass aType =
586cdf0e10cSrcweir       cpp_mediate( nFunctionIndex, vTableOffset, (void**)gpreg, (void**)fpreg, ovrflw, (sal_Int64*)nRegReturn );
587cdf0e10cSrcweir 
588cdf0e10cSrcweir     switch( aType )
589cdf0e10cSrcweir     {
590cdf0e10cSrcweir 
591cdf0e10cSrcweir       // move return value into register space
592cdf0e10cSrcweir       // (will be loaded by machine code snippet)
593cdf0e10cSrcweir 
594cdf0e10cSrcweir       case typelib_TypeClass_BOOLEAN:
595cdf0e10cSrcweir       case typelib_TypeClass_BYTE:
596cdf0e10cSrcweir         __asm__( "lbu $2,%0\n\t" : :
597cdf0e10cSrcweir             "m"(nRegReturn[0]) );
598cdf0e10cSrcweir         break;
599cdf0e10cSrcweir 
600cdf0e10cSrcweir       case typelib_TypeClass_CHAR:
601cdf0e10cSrcweir       case typelib_TypeClass_UNSIGNED_SHORT:
602cdf0e10cSrcweir         __asm__( "lhu $2,%0\n\t" : :
603cdf0e10cSrcweir             "m"(nRegReturn[0]) );
604cdf0e10cSrcweir         break;
605cdf0e10cSrcweir 
606cdf0e10cSrcweir       case typelib_TypeClass_SHORT:
607cdf0e10cSrcweir         __asm__( "lh $2,%0\n\t" : :
608cdf0e10cSrcweir             "m"(nRegReturn[0]) );
609cdf0e10cSrcweir         break;
610cdf0e10cSrcweir 
611cdf0e10cSrcweir 
612cdf0e10cSrcweir       case typelib_TypeClass_FLOAT:
613cdf0e10cSrcweir         __asm__( "lwc1 $f0,%0\n\t" : :
614cdf0e10cSrcweir             "m" (*((float*)nRegReturn)) );
615cdf0e10cSrcweir         break;
616cdf0e10cSrcweir 
617cdf0e10cSrcweir       case typelib_TypeClass_DOUBLE:
618cdf0e10cSrcweir         { register double dret asm("$f0");
619cdf0e10cSrcweir         dret = (*((double*)nRegReturn)); }
620cdf0e10cSrcweir         break;
621cdf0e10cSrcweir 
622cdf0e10cSrcweir       case typelib_TypeClass_HYPER:
623cdf0e10cSrcweir       case typelib_TypeClass_UNSIGNED_HYPER:
624cdf0e10cSrcweir         __asm__( "lw $3,%0\n\t" : :
625cdf0e10cSrcweir             "m"(nRegReturn[1]) );  // fall through
626cdf0e10cSrcweir 
627cdf0e10cSrcweir       default:
628cdf0e10cSrcweir         __asm__( "lw $2,%0\n\t" : :
629cdf0e10cSrcweir             "m"(nRegReturn[0]) );
630cdf0e10cSrcweir         break;
631cdf0e10cSrcweir     }
632cdf0e10cSrcweir   }
633cdf0e10cSrcweir 
634cdf0e10cSrcweir 
635cdf0e10cSrcweir   int const codeSnippetSize = 56;
636cdf0e10cSrcweir 
codeSnippet(unsigned char * code,sal_Int32 functionIndex,sal_Int32 vtableOffset,bool simpleRetType)637cdf0e10cSrcweir   unsigned char *  codeSnippet( unsigned char * code, sal_Int32 functionIndex, sal_Int32 vtableOffset,
638cdf0e10cSrcweir       bool simpleRetType)
639cdf0e10cSrcweir   {
640cdf0e10cSrcweir 
641cdf0e10cSrcweir #ifdef BRDEBUG
642cdf0e10cSrcweir      fprintf(stderr,"in codeSnippet functionIndex is %d\n", functionIndex);
643cdf0e10cSrcweir      fprintf(stderr,"in codeSnippet vtableOffset is %d\n", vtableOffset);
644cdf0e10cSrcweir      fflush(stderr);
645cdf0e10cSrcweir #endif
646cdf0e10cSrcweir 
647cdf0e10cSrcweir     if (! simpleRetType )
648cdf0e10cSrcweir       functionIndex |= 0x80000000;
649cdf0e10cSrcweir 
650cdf0e10cSrcweir     unsigned long * p = (unsigned long *) code;
651cdf0e10cSrcweir 
652cdf0e10cSrcweir     // OSL_ASSERT( sizeof (long) == 4 );
653cdf0e10cSrcweir     OSL_ASSERT((((unsigned long)code) & 0x3) == 0 );  //aligned to 4 otherwise a mistake
654cdf0e10cSrcweir 
655cdf0e10cSrcweir     /* generate this code */
656cdf0e10cSrcweir     /*
657cdf0e10cSrcweir        #save regs into argument space required by mips abi
658cdf0e10cSrcweir             c:   afa40000        sw      a0,0(sp)
659cdf0e10cSrcweir        10:   afa50004        sw      a1,4(sp)
660cdf0e10cSrcweir        14:   afa60008        sw      a2,8(sp)
661cdf0e10cSrcweir        18:   afa7000c        sw      a3,12(sp)
662cdf0e10cSrcweir        #a0=index
663cdf0e10cSrcweir        1c:   3c040000        lui     a0,0x0
664cdf0e10cSrcweir        20:   34840000        ori     a0,a0,0x0
665cdf0e10cSrcweir        #a1=offset
666cdf0e10cSrcweir        24:   3c050000        lui     a1,0x0
667cdf0e10cSrcweir        28:   34a50000        ori     a1,a1,0x0
668cdf0e10cSrcweir        #a2=gpregptr
669cdf0e10cSrcweir        2c:   27a60000        addiu   a2,sp,0
670cdf0e10cSrcweir        #a3=ovrflw
671cdf0e10cSrcweir        30:   27a70010        addiu   a3,sp,16
672cdf0e10cSrcweir        #load cpp_vtable_call addr
673cdf0e10cSrcweir        34:   3c190000        lui     t9,0x0
674cdf0e10cSrcweir        38:   37390000        ori     t9,t9,0
675cdf0e10cSrcweir        #jmp to the function,note: we don't use jalr, that will destroy $ra
676cdf0e10cSrcweir        #but be sure to use t9! gp calculation depends on it
677cdf0e10cSrcweir        3c:   03200008        jr      t9
678cdf0e10cSrcweir        40:   00000000        nop
679cdf0e10cSrcweir 
680cdf0e10cSrcweir        be careful, we use the argument space reserved by the caller to
681*07a3d7f1SPedro Giffuni        write down regs. This can avoid the need to make use of arbitrary far away
682cdf0e10cSrcweir        stack space or to allocate a function frame for this code snippet itself.
683cdf0e10cSrcweir        Since only functions with variable arguments will overwrite the space,
684cdf0e10cSrcweir        cpp_vtable_call should be safe.
685cdf0e10cSrcweir        ??? gcc seems change this behavior! cpp_vtable_call overwrite the space!
686cdf0e10cSrcweir      */
687cdf0e10cSrcweir 
688cdf0e10cSrcweir     * p++ = 0xafa40000;
689cdf0e10cSrcweir     * p++ = 0xafa50004;
690cdf0e10cSrcweir     * p++ = 0xafa60008;
691cdf0e10cSrcweir     * p++ = 0xafa7000c;
692cdf0e10cSrcweir     * p++ = 0x3c040000 | ((functionIndex>>16) & 0x0000ffff);
693cdf0e10cSrcweir     * p++ = 0x34840000 | (functionIndex & 0x0000ffff);
694cdf0e10cSrcweir     * p++ = 0x3c050000 | ((vtableOffset>>16) & 0x0000ffff);
695cdf0e10cSrcweir     * p++ = 0x34a50000 | (vtableOffset & 0x0000ffff);
696cdf0e10cSrcweir     * p++ = 0x27a60000;
697cdf0e10cSrcweir     * p++ = 0x27a70010;
698cdf0e10cSrcweir     * p++ = 0x3c190000 | ((((unsigned long)cpp_vtable_call) >> 16) & 0x0000ffff);
699cdf0e10cSrcweir     * p++ = 0x37390000 | (((unsigned long)cpp_vtable_call) & 0x0000FFFF);
700cdf0e10cSrcweir     * p++ = 0x03200008;
701cdf0e10cSrcweir     * p++ = 0x00000000;
702cdf0e10cSrcweir     return (code + codeSnippetSize);
703cdf0e10cSrcweir 
704cdf0e10cSrcweir   }
705cdf0e10cSrcweir 
706cdf0e10cSrcweir 
707cdf0e10cSrcweir }
708cdf0e10cSrcweir 
709cdf0e10cSrcweir 
710cdf0e10cSrcweir #define MIN_LINE_SIZE 32
711cdf0e10cSrcweir 
flushCode(unsigned char const *,unsigned char const *)712cdf0e10cSrcweir void bridges::cpp_uno::shared::VtableFactory::flushCode(unsigned char const * /*bptr*/, unsigned char const * /*eptr*/)
713cdf0e10cSrcweir {
714cdf0e10cSrcweir   sysmips(FLUSH_CACHE,0,0,0);
715cdf0e10cSrcweir }
716cdf0e10cSrcweir 
717cdf0e10cSrcweir struct bridges::cpp_uno::shared::VtableFactory::Slot { void * fn; };
718cdf0e10cSrcweir 
719cdf0e10cSrcweir bridges::cpp_uno::shared::VtableFactory::Slot *
mapBlockToVtable(void * block)720cdf0e10cSrcweir bridges::cpp_uno::shared::VtableFactory::mapBlockToVtable(void * block)
721cdf0e10cSrcweir {
722cdf0e10cSrcweir     return static_cast< Slot * >(block) + 2;
723cdf0e10cSrcweir }
724cdf0e10cSrcweir 
725cdf0e10cSrcweir 
getBlockSize(sal_Int32 slotCount)726cdf0e10cSrcweir sal_Size bridges::cpp_uno::shared::VtableFactory::getBlockSize(
727cdf0e10cSrcweir     sal_Int32 slotCount)
728cdf0e10cSrcweir {
729cdf0e10cSrcweir     return (slotCount + 2) * sizeof (Slot) + slotCount * codeSnippetSize;
730cdf0e10cSrcweir }
731cdf0e10cSrcweir 
732cdf0e10cSrcweir bridges::cpp_uno::shared::VtableFactory::Slot *
initializeBlock(void * block,sal_Int32 slotCount)733cdf0e10cSrcweir bridges::cpp_uno::shared::VtableFactory::initializeBlock(
734cdf0e10cSrcweir     void * block, sal_Int32 slotCount)
735cdf0e10cSrcweir {
736cdf0e10cSrcweir     Slot * slots = mapBlockToVtable(block);
737cdf0e10cSrcweir     slots[-2].fn = 0; //null
738cdf0e10cSrcweir     slots[-1].fn = 0; //destructor
739cdf0e10cSrcweir     return slots + slotCount;
740cdf0e10cSrcweir }
741cdf0e10cSrcweir 
addLocalFunctions(Slot ** slots,unsigned char * code,sal_PtrDiff writetoexecdiff,typelib_InterfaceTypeDescription const * type,sal_Int32 functionOffset,sal_Int32 functionCount,sal_Int32 vtableOffset)742cdf0e10cSrcweir unsigned char * bridges::cpp_uno::shared::VtableFactory::addLocalFunctions(
743cdf0e10cSrcweir     Slot ** slots, unsigned char * code, sal_PtrDiff writetoexecdiff,
744cdf0e10cSrcweir     typelib_InterfaceTypeDescription const * type, sal_Int32 functionOffset,
745cdf0e10cSrcweir     sal_Int32 functionCount, sal_Int32 vtableOffset)
746cdf0e10cSrcweir {
747cdf0e10cSrcweir    (*slots) -= functionCount;
748cdf0e10cSrcweir     Slot * s = *slots;
749cdf0e10cSrcweir #ifdef BRDEBUG
750cdf0e10cSrcweir    fprintf(stderr, "in addLocalFunctions functionOffset is %d\n",functionOffset);
751cdf0e10cSrcweir    fprintf(stderr, "in addLocalFunctions vtableOffset is %d\n",vtableOffset);
752cdf0e10cSrcweir    fprintf(stderr, "nMembers=%d\n",type->nMembers);
753cdf0e10cSrcweir    fflush(stderr);
754cdf0e10cSrcweir #endif
755cdf0e10cSrcweir 
756cdf0e10cSrcweir   for (sal_Int32 i = 0; i < type->nMembers; ++i) {
757cdf0e10cSrcweir     typelib_TypeDescription * member = 0;
758cdf0e10cSrcweir     TYPELIB_DANGER_GET(&member, type->ppMembers[i]);
759cdf0e10cSrcweir     OSL_ASSERT(member != 0);
760cdf0e10cSrcweir     switch (member->eTypeClass) {
761cdf0e10cSrcweir       case typelib_TypeClass_INTERFACE_ATTRIBUTE:
762cdf0e10cSrcweir         // Getter:
763cdf0e10cSrcweir         (s++)->fn = code + writetoexecdiff;
764cdf0e10cSrcweir         code = codeSnippet(
765cdf0e10cSrcweir             code, functionOffset++, vtableOffset,
766cdf0e10cSrcweir             bridges::cpp_uno::shared::isSimpleType(
767cdf0e10cSrcweir               reinterpret_cast<
768cdf0e10cSrcweir               typelib_InterfaceAttributeTypeDescription * >(
769cdf0e10cSrcweir                 member)->pAttributeTypeRef));
770cdf0e10cSrcweir 
771cdf0e10cSrcweir         // Setter:
772cdf0e10cSrcweir         if (!reinterpret_cast<
773cdf0e10cSrcweir             typelib_InterfaceAttributeTypeDescription * >(
774cdf0e10cSrcweir               member)->bReadOnly)
775cdf0e10cSrcweir         {
776cdf0e10cSrcweir           (s++)->fn = code + writetoexecdiff;
777cdf0e10cSrcweir           code = codeSnippet(code, functionOffset++, vtableOffset, true);
778cdf0e10cSrcweir         }
779cdf0e10cSrcweir         break;
780cdf0e10cSrcweir 
781cdf0e10cSrcweir       case typelib_TypeClass_INTERFACE_METHOD:
782cdf0e10cSrcweir         (s++)->fn = code + writetoexecdiff;
783cdf0e10cSrcweir         code = codeSnippet(
784cdf0e10cSrcweir             code, functionOffset++, vtableOffset,
785cdf0e10cSrcweir             bridges::cpp_uno::shared::isSimpleType(
786cdf0e10cSrcweir               reinterpret_cast<
787cdf0e10cSrcweir               typelib_InterfaceMethodTypeDescription * >(
788cdf0e10cSrcweir                 member)->pReturnTypeRef));
789cdf0e10cSrcweir         break;
790cdf0e10cSrcweir 
791cdf0e10cSrcweir       default:
792cdf0e10cSrcweir         OSL_ASSERT(false);
793cdf0e10cSrcweir         break;
794cdf0e10cSrcweir     }
795cdf0e10cSrcweir     TYPELIB_DANGER_RELEASE(member);
796cdf0e10cSrcweir   }
797cdf0e10cSrcweir   return code;
798cdf0e10cSrcweir }
799