1*61dff127SAndrew Rist /**************************************************************
2cdf0e10cSrcweir *
3*61dff127SAndrew Rist * Licensed to the Apache Software Foundation (ASF) under one
4*61dff127SAndrew Rist * or more contributor license agreements. See the NOTICE file
5*61dff127SAndrew Rist * distributed with this work for additional information
6*61dff127SAndrew Rist * regarding copyright ownership. The ASF licenses this file
7*61dff127SAndrew Rist * to you under the Apache License, Version 2.0 (the
8*61dff127SAndrew Rist * "License"); you may not use this file except in compliance
9*61dff127SAndrew Rist * with the License. You may obtain a copy of the License at
10*61dff127SAndrew Rist *
11*61dff127SAndrew Rist * http://www.apache.org/licenses/LICENSE-2.0
12*61dff127SAndrew Rist *
13*61dff127SAndrew Rist * Unless required by applicable law or agreed to in writing,
14*61dff127SAndrew Rist * software distributed under the License is distributed on an
15*61dff127SAndrew Rist * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16*61dff127SAndrew Rist * KIND, either express or implied. See the License for the
17*61dff127SAndrew Rist * specific language governing permissions and limitations
18*61dff127SAndrew Rist * under the License.
19*61dff127SAndrew Rist *
20*61dff127SAndrew Rist *************************************************************/
21*61dff127SAndrew Rist
22*61dff127SAndrew 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
311cdf0e10cSrcweir // in case an exception occured...
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 }
331cdf0e10cSrcweir else // else no exception occured...
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
681cdf0e10cSrcweir write down regs. This can avoid the need to make use of arbitary 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 }
799cdf0e10cSrcweir
800