1*af84ad07SPedro Giffuni /**************************************************************
2*af84ad07SPedro Giffuni  *
3*af84ad07SPedro Giffuni  * Licensed to the Apache Software Foundation (ASF) under one
4*af84ad07SPedro Giffuni  * or more contributor license agreements.  See the NOTICE file
5*af84ad07SPedro Giffuni  * distributed with this work for additional information
6*af84ad07SPedro Giffuni  * regarding copyright ownership.  The ASF licenses this file
7*af84ad07SPedro Giffuni  * to you under the Apache License, Version 2.0 (the
8*af84ad07SPedro Giffuni  * "License"); you may not use this file except in compliance
9*af84ad07SPedro Giffuni  * with the License.  You may obtain a copy of the License at
10*af84ad07SPedro Giffuni  *
11*af84ad07SPedro Giffuni  *   http://www.apache.org/licenses/LICENSE-2.0
12*af84ad07SPedro Giffuni  *
13*af84ad07SPedro Giffuni  * Unless required by applicable law or agreed to in writing,
14*af84ad07SPedro Giffuni  * software distributed under the License is distributed on an
15*af84ad07SPedro Giffuni  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16*af84ad07SPedro Giffuni  * KIND, either express or implied.  See the License for the
17*af84ad07SPedro Giffuni  * specific language governing permissions and limitations
18*af84ad07SPedro Giffuni  * under the License.
19*af84ad07SPedro Giffuni  *
20*af84ad07SPedro Giffuni  *************************************************************/
21*af84ad07SPedro Giffuni 
22*af84ad07SPedro Giffuni 
23*af84ad07SPedro Giffuni 
24*af84ad07SPedro Giffuni // MARKER(update_precomp.py): autogen include statement, do not remove
25*af84ad07SPedro Giffuni #include "precompiled_bridges.hxx"
26*af84ad07SPedro Giffuni 
27*af84ad07SPedro Giffuni #include <com/sun/star/uno/genfunc.hxx>
28*af84ad07SPedro Giffuni #include <uno/data.h>
29*af84ad07SPedro Giffuni #include <typelib/typedescription.hxx>
30*af84ad07SPedro Giffuni 
31*af84ad07SPedro Giffuni #include "bridges/cpp_uno/shared/bridge.hxx"
32*af84ad07SPedro Giffuni #include "bridges/cpp_uno/shared/cppinterfaceproxy.hxx"
33*af84ad07SPedro Giffuni #include "bridges/cpp_uno/shared/types.hxx"
34*af84ad07SPedro Giffuni #include "bridges/cpp_uno/shared/vtablefactory.hxx"
35*af84ad07SPedro Giffuni 
36*af84ad07SPedro Giffuni #include "share.hxx"
37*af84ad07SPedro Giffuni #include <stdio.h>
38*af84ad07SPedro Giffuni #include <string.h>
39*af84ad07SPedro Giffuni 
40*af84ad07SPedro Giffuni 
41*af84ad07SPedro Giffuni using namespace ::com::sun::star::uno;
42*af84ad07SPedro Giffuni 
43*af84ad07SPedro Giffuni namespace
44*af84ad07SPedro Giffuni {
45*af84ad07SPedro Giffuni 
46*af84ad07SPedro Giffuni //==================================================================================================
cpp2uno_call(bridges::cpp_uno::shared::CppInterfaceProxy * pThis,const typelib_TypeDescription * pMemberTypeDescr,typelib_TypeDescriptionReference * pReturnTypeRef,sal_Int32 nParams,typelib_MethodParameter * pParams,void ** gpreg,void ** fpreg,void ** ovrflw,sal_Int64 * pRegisterReturn)47*af84ad07SPedro Giffuni static typelib_TypeClass cpp2uno_call(
48*af84ad07SPedro Giffuni 	bridges::cpp_uno::shared::CppInterfaceProxy * pThis,
49*af84ad07SPedro Giffuni 	const typelib_TypeDescription * pMemberTypeDescr,
50*af84ad07SPedro Giffuni 	typelib_TypeDescriptionReference * pReturnTypeRef, // 0 indicates void return
51*af84ad07SPedro Giffuni 	sal_Int32 nParams, typelib_MethodParameter * pParams,
52*af84ad07SPedro Giffuni         void ** gpreg, void ** fpreg, void ** ovrflw,
53*af84ad07SPedro Giffuni 	sal_Int64 * pRegisterReturn /* space for register return */ )
54*af84ad07SPedro Giffuni {
55*af84ad07SPedro Giffuni #ifdef CMC_DEBUG
56*af84ad07SPedro Giffuni     fprintf(stderr, "as far as cpp2uno_call\n");
57*af84ad07SPedro Giffuni #endif
58*af84ad07SPedro Giffuni 
59*af84ad07SPedro Giffuni     int ng = 0; //number of gpr registers used
60*af84ad07SPedro Giffuni     int nf = 0; //number of fpr regsiters used
61*af84ad07SPedro Giffuni 
62*af84ad07SPedro Giffuni     // gpreg:  [ret *], this, [gpr params]
63*af84ad07SPedro Giffuni     // fpreg:  [fpr params]
64*af84ad07SPedro Giffuni     // ovrflw: [gpr or fpr params (properly aligned)]
65*af84ad07SPedro Giffuni 
66*af84ad07SPedro Giffuni 	// return
67*af84ad07SPedro Giffuni 	typelib_TypeDescription * pReturnTypeDescr = 0;
68*af84ad07SPedro Giffuni 	if (pReturnTypeRef)
69*af84ad07SPedro Giffuni 		TYPELIB_DANGER_GET( &pReturnTypeDescr, pReturnTypeRef );
70*af84ad07SPedro Giffuni 
71*af84ad07SPedro Giffuni 	void * pUnoReturn = 0;
72*af84ad07SPedro Giffuni 	void * pCppReturn = 0; // complex return ptr: if != 0 && != pUnoReturn, reconversion need
73*af84ad07SPedro Giffuni 
74*af84ad07SPedro Giffuni 	if (pReturnTypeDescr)
75*af84ad07SPedro Giffuni 	{
76*af84ad07SPedro Giffuni 		if (bridges::cpp_uno::shared::isSimpleType( pReturnTypeDescr ))
77*af84ad07SPedro Giffuni 		{
78*af84ad07SPedro Giffuni 			pUnoReturn = pRegisterReturn; // direct way for simple types
79*af84ad07SPedro Giffuni 		}
80*af84ad07SPedro Giffuni 		else // complex return via ptr (pCppReturn)
81*af84ad07SPedro Giffuni 		{
82*af84ad07SPedro Giffuni 			pCppReturn = *(void **)gpreg;
83*af84ad07SPedro Giffuni             gpreg++;
84*af84ad07SPedro Giffuni             ng++;
85*af84ad07SPedro Giffuni 
86*af84ad07SPedro Giffuni 			pUnoReturn = (bridges::cpp_uno::shared::relatesToInterfaceType( pReturnTypeDescr )
87*af84ad07SPedro Giffuni 						  ? alloca( pReturnTypeDescr->nSize )
88*af84ad07SPedro Giffuni 						  : pCppReturn); // direct way
89*af84ad07SPedro Giffuni 		}
90*af84ad07SPedro Giffuni 	}
91*af84ad07SPedro Giffuni 	// pop this
92*af84ad07SPedro Giffuni     gpreg++;
93*af84ad07SPedro Giffuni     ng++;
94*af84ad07SPedro Giffuni 
95*af84ad07SPedro Giffuni 	// stack space
96*af84ad07SPedro Giffuni 	OSL_ENSURE( sizeof(void *) == sizeof(sal_Int64), "### unexpected size!" );
97*af84ad07SPedro Giffuni 	// parameters
98*af84ad07SPedro Giffuni 	void ** pUnoArgs = (void **)alloca( 4 * sizeof(void *) * nParams );
99*af84ad07SPedro Giffuni 	void ** pCppArgs = pUnoArgs + nParams;
100*af84ad07SPedro Giffuni 	// indizes of values this have to be converted (interface conversion cpp<=>uno)
101*af84ad07SPedro Giffuni 	sal_Int32 * pTempIndizes = (sal_Int32 *)(pUnoArgs + (2 * nParams));
102*af84ad07SPedro Giffuni 	// type descriptions for reconversions
103*af84ad07SPedro Giffuni 	typelib_TypeDescription ** ppTempParamTypeDescr = (typelib_TypeDescription **)(pUnoArgs + (3 * nParams));
104*af84ad07SPedro Giffuni 
105*af84ad07SPedro Giffuni 	sal_Int32 nTempIndizes = 0;
106*af84ad07SPedro Giffuni 	bool bOverFlowUsed = false;
107*af84ad07SPedro Giffuni 	for ( sal_Int32 nPos = 0; nPos < nParams; ++nPos )
108*af84ad07SPedro Giffuni 	{
109*af84ad07SPedro Giffuni 		const typelib_MethodParameter & rParam = pParams[nPos];
110*af84ad07SPedro Giffuni 		typelib_TypeDescription * pParamTypeDescr = 0;
111*af84ad07SPedro Giffuni 		TYPELIB_DANGER_GET( &pParamTypeDescr, rParam.pTypeRef );
112*af84ad07SPedro Giffuni 
113*af84ad07SPedro Giffuni #ifdef CMC_DEBUG
114*af84ad07SPedro Giffuni 		fprintf(stderr, "arg %d of %d\n", nPos, nParams);
115*af84ad07SPedro Giffuni #endif
116*af84ad07SPedro Giffuni 
117*af84ad07SPedro Giffuni 		if (!rParam.bOut && bridges::cpp_uno::shared::isSimpleType( pParamTypeDescr ))
118*af84ad07SPedro Giffuni 		{
119*af84ad07SPedro Giffuni #ifdef CMC_DEBUG
120*af84ad07SPedro Giffuni 			fprintf(stderr, "simple\n");
121*af84ad07SPedro Giffuni #endif
122*af84ad07SPedro Giffuni 
123*af84ad07SPedro Giffuni 			switch (pParamTypeDescr->eTypeClass)
124*af84ad07SPedro Giffuni 			{
125*af84ad07SPedro Giffuni 				case typelib_TypeClass_FLOAT:
126*af84ad07SPedro Giffuni 				case typelib_TypeClass_DOUBLE:
127*af84ad07SPedro Giffuni 					if (nf < ppc64::MAX_SSE_REGS)
128*af84ad07SPedro Giffuni 					{
129*af84ad07SPedro Giffuni 						if (pParamTypeDescr->eTypeClass == typelib_TypeClass_FLOAT)
130*af84ad07SPedro Giffuni 						{
131*af84ad07SPedro Giffuni                         	float tmp = (float) (*((double *)fpreg));
132*af84ad07SPedro Giffuni                         	(*((float *) fpreg)) = tmp;
133*af84ad07SPedro Giffuni 						}
134*af84ad07SPedro Giffuni 						pCppArgs[nPos] = pUnoArgs[nPos] = fpreg++;
135*af84ad07SPedro Giffuni 						nf++;
136*af84ad07SPedro Giffuni 					}
137*af84ad07SPedro Giffuni 					else
138*af84ad07SPedro Giffuni                     {
139*af84ad07SPedro Giffuni 						pCppArgs[nPos] = pUnoArgs[nPos] = ovrflw;
140*af84ad07SPedro Giffuni                         bOverFlowUsed = true;
141*af84ad07SPedro Giffuni                     }
142*af84ad07SPedro Giffuni                     if (bOverFlowUsed) ovrflw++;
143*af84ad07SPedro Giffuni 					break;
144*af84ad07SPedro Giffuni                 case typelib_TypeClass_BYTE:
145*af84ad07SPedro Giffuni                 case typelib_TypeClass_BOOLEAN:
146*af84ad07SPedro Giffuni                     if (ng < ppc64::MAX_GPR_REGS)
147*af84ad07SPedro Giffuni 					{
148*af84ad07SPedro Giffuni                         pCppArgs[nPos] = pUnoArgs[nPos] = (((char *)gpreg) + (sizeof(void*)-1));
149*af84ad07SPedro Giffuni                         ng++;
150*af84ad07SPedro Giffuni                         gpreg++;
151*af84ad07SPedro Giffuni                     }
152*af84ad07SPedro Giffuni                     else
153*af84ad07SPedro Giffuni 					{
154*af84ad07SPedro Giffuni                         pCppArgs[nPos] = pUnoArgs[nPos] = (((char *)ovrflw) + (sizeof(void*)-1));
155*af84ad07SPedro Giffuni                         bOverFlowUsed = true;
156*af84ad07SPedro Giffuni                     }
157*af84ad07SPedro Giffuni                     if (bOverFlowUsed) ovrflw++;
158*af84ad07SPedro Giffuni                     break;
159*af84ad07SPedro Giffuni                 case typelib_TypeClass_CHAR:
160*af84ad07SPedro Giffuni                 case typelib_TypeClass_SHORT:
161*af84ad07SPedro Giffuni                 case typelib_TypeClass_UNSIGNED_SHORT:
162*af84ad07SPedro Giffuni                     if (ng < ppc64::MAX_GPR_REGS)
163*af84ad07SPedro Giffuni 					{
164*af84ad07SPedro Giffuni                         pCppArgs[nPos] = pUnoArgs[nPos] = (((char *)gpreg) + (sizeof(void*)-2));
165*af84ad07SPedro Giffuni                         ng++;
166*af84ad07SPedro Giffuni                         gpreg++;
167*af84ad07SPedro Giffuni                     }
168*af84ad07SPedro Giffuni                     else
169*af84ad07SPedro Giffuni 					{
170*af84ad07SPedro Giffuni                         pCppArgs[nPos] = pUnoArgs[nPos] = (((char *)ovrflw) + (sizeof(void*)-2));
171*af84ad07SPedro Giffuni                         bOverFlowUsed = true;
172*af84ad07SPedro Giffuni                     }
173*af84ad07SPedro Giffuni                     if (bOverFlowUsed) ovrflw++;
174*af84ad07SPedro Giffuni                     break;
175*af84ad07SPedro Giffuni 		case typelib_TypeClass_ENUM:
176*af84ad07SPedro Giffuni                 case typelib_TypeClass_LONG:
177*af84ad07SPedro Giffuni                 case typelib_TypeClass_UNSIGNED_LONG:
178*af84ad07SPedro Giffuni                     if (ng < ppc64::MAX_GPR_REGS)
179*af84ad07SPedro Giffuni 					{
180*af84ad07SPedro Giffuni                         pCppArgs[nPos] = pUnoArgs[nPos] = (((char *)gpreg) + (sizeof(void*)-4));
181*af84ad07SPedro Giffuni                         ng++;
182*af84ad07SPedro Giffuni                         gpreg++;
183*af84ad07SPedro Giffuni                     }
184*af84ad07SPedro Giffuni                     else
185*af84ad07SPedro Giffuni 					{
186*af84ad07SPedro Giffuni                         pCppArgs[nPos] = pUnoArgs[nPos] = (((char *)ovrflw) + (sizeof(void*)-4));
187*af84ad07SPedro Giffuni                         bOverFlowUsed = true;
188*af84ad07SPedro Giffuni                     }
189*af84ad07SPedro Giffuni                     if (bOverFlowUsed) ovrflw++;
190*af84ad07SPedro Giffuni                     break;
191*af84ad07SPedro Giffuni 				default:
192*af84ad07SPedro Giffuni 					if (ng < ppc64::MAX_GPR_REGS)
193*af84ad07SPedro Giffuni 					{
194*af84ad07SPedro Giffuni 						pCppArgs[nPos] = pUnoArgs[nPos] = gpreg++;
195*af84ad07SPedro Giffuni 						ng++;
196*af84ad07SPedro Giffuni 					}
197*af84ad07SPedro Giffuni 					else
198*af84ad07SPedro Giffuni                     {
199*af84ad07SPedro Giffuni 						pCppArgs[nPos] = pUnoArgs[nPos] = ovrflw;
200*af84ad07SPedro Giffuni                         bOverFlowUsed = true;
201*af84ad07SPedro Giffuni                     }
202*af84ad07SPedro Giffuni                     if (bOverFlowUsed) ovrflw++;
203*af84ad07SPedro Giffuni 					break;
204*af84ad07SPedro Giffuni 		        }
205*af84ad07SPedro Giffuni 
206*af84ad07SPedro Giffuni 		        // no longer needed
207*af84ad07SPedro Giffuni 				TYPELIB_DANGER_RELEASE( pParamTypeDescr );
208*af84ad07SPedro Giffuni 		}
209*af84ad07SPedro Giffuni 		else // ptr to complex value | ref
210*af84ad07SPedro Giffuni 		{
211*af84ad07SPedro Giffuni #ifdef CMC_DEBUG
212*af84ad07SPedro Giffuni 			fprintf(stderr, "complex, ng is %d\n", ng);
213*af84ad07SPedro Giffuni #endif
214*af84ad07SPedro Giffuni             void *pCppStack; //temporary stack pointer
215*af84ad07SPedro Giffuni 
216*af84ad07SPedro Giffuni 			if (ng < ppc64::MAX_GPR_REGS)
217*af84ad07SPedro Giffuni 			{
218*af84ad07SPedro Giffuni 		        pCppArgs[nPos] = pCppStack = *gpreg++;
219*af84ad07SPedro Giffuni 			    ng++;
220*af84ad07SPedro Giffuni 			}
221*af84ad07SPedro Giffuni 			else
222*af84ad07SPedro Giffuni             {
223*af84ad07SPedro Giffuni 			    pCppArgs[nPos] = pCppStack = *ovrflw;
224*af84ad07SPedro Giffuni                 bOverFlowUsed = true;
225*af84ad07SPedro Giffuni             }
226*af84ad07SPedro Giffuni             if (bOverFlowUsed) ovrflw++;
227*af84ad07SPedro Giffuni 
228*af84ad07SPedro Giffuni 			if (! rParam.bIn) // is pure out
229*af84ad07SPedro Giffuni 			{
230*af84ad07SPedro Giffuni 				// uno out is unconstructed mem!
231*af84ad07SPedro Giffuni 				pUnoArgs[nPos] = alloca( pParamTypeDescr->nSize );
232*af84ad07SPedro Giffuni 				pTempIndizes[nTempIndizes] = nPos;
233*af84ad07SPedro Giffuni 				// will be released at reconversion
234*af84ad07SPedro Giffuni 				ppTempParamTypeDescr[nTempIndizes++] = pParamTypeDescr;
235*af84ad07SPedro Giffuni 			}
236*af84ad07SPedro Giffuni 			// is in/inout
237*af84ad07SPedro Giffuni 			else if (bridges::cpp_uno::shared::relatesToInterfaceType( pParamTypeDescr ))
238*af84ad07SPedro Giffuni 			{
239*af84ad07SPedro Giffuni 				uno_copyAndConvertData( pUnoArgs[nPos] = alloca( pParamTypeDescr->nSize ),
240*af84ad07SPedro Giffuni 										pCppStack, pParamTypeDescr,
241*af84ad07SPedro Giffuni 										pThis->getBridge()->getCpp2Uno() );
242*af84ad07SPedro Giffuni 				pTempIndizes[nTempIndizes] = nPos; // has to be reconverted
243*af84ad07SPedro Giffuni 				// will be released at reconversion
244*af84ad07SPedro Giffuni 				ppTempParamTypeDescr[nTempIndizes++] = pParamTypeDescr;
245*af84ad07SPedro Giffuni 			}
246*af84ad07SPedro Giffuni 			else // direct way
247*af84ad07SPedro Giffuni 			{
248*af84ad07SPedro Giffuni 				pUnoArgs[nPos] = pCppStack;
249*af84ad07SPedro Giffuni 				// no longer needed
250*af84ad07SPedro Giffuni 				TYPELIB_DANGER_RELEASE( pParamTypeDescr );
251*af84ad07SPedro Giffuni 			}
252*af84ad07SPedro Giffuni 		}
253*af84ad07SPedro Giffuni 	}
254*af84ad07SPedro Giffuni 
255*af84ad07SPedro Giffuni #ifdef CMC_DEBUG
256*af84ad07SPedro Giffuni 	fprintf(stderr, "end of params\n");
257*af84ad07SPedro Giffuni #endif
258*af84ad07SPedro Giffuni 
259*af84ad07SPedro Giffuni 	// ExceptionHolder
260*af84ad07SPedro Giffuni 	uno_Any aUnoExc; // Any will be constructed by callee
261*af84ad07SPedro Giffuni 	uno_Any * pUnoExc = &aUnoExc;
262*af84ad07SPedro Giffuni 
263*af84ad07SPedro Giffuni 	// invoke uno dispatch call
264*af84ad07SPedro Giffuni 	(*pThis->getUnoI()->pDispatcher)( pThis->getUnoI(), pMemberTypeDescr, pUnoReturn, pUnoArgs, &pUnoExc );
265*af84ad07SPedro Giffuni 
266*af84ad07SPedro Giffuni 	// in case an exception occurred...
267*af84ad07SPedro Giffuni 	if (pUnoExc)
268*af84ad07SPedro Giffuni 	{
269*af84ad07SPedro Giffuni 		// destruct temporary in/inout params
270*af84ad07SPedro Giffuni 		for ( ; nTempIndizes--; )
271*af84ad07SPedro Giffuni 		{
272*af84ad07SPedro Giffuni 			sal_Int32 nIndex = pTempIndizes[nTempIndizes];
273*af84ad07SPedro Giffuni 
274*af84ad07SPedro Giffuni 			if (pParams[nIndex].bIn) // is in/inout => was constructed
275*af84ad07SPedro Giffuni 				uno_destructData( pUnoArgs[nIndex], ppTempParamTypeDescr[nTempIndizes], 0 );
276*af84ad07SPedro Giffuni 			TYPELIB_DANGER_RELEASE( ppTempParamTypeDescr[nTempIndizes] );
277*af84ad07SPedro Giffuni 		}
278*af84ad07SPedro Giffuni 		if (pReturnTypeDescr)
279*af84ad07SPedro Giffuni 			TYPELIB_DANGER_RELEASE( pReturnTypeDescr );
280*af84ad07SPedro Giffuni 
281*af84ad07SPedro Giffuni 		CPPU_CURRENT_NAMESPACE::raiseException( &aUnoExc, pThis->getBridge()->getUno2Cpp() );
282*af84ad07SPedro Giffuni                 // has to destruct the any
283*af84ad07SPedro Giffuni 		// is here for dummy
284*af84ad07SPedro Giffuni 		return typelib_TypeClass_VOID;
285*af84ad07SPedro Giffuni 	}
286*af84ad07SPedro Giffuni 	else // else no exception occurred...
287*af84ad07SPedro Giffuni 	{
288*af84ad07SPedro Giffuni 		// temporary params
289*af84ad07SPedro Giffuni 		for ( ; nTempIndizes--; )
290*af84ad07SPedro Giffuni 		{
291*af84ad07SPedro Giffuni 			sal_Int32 nIndex = pTempIndizes[nTempIndizes];
292*af84ad07SPedro Giffuni 			typelib_TypeDescription * pParamTypeDescr = ppTempParamTypeDescr[nTempIndizes];
293*af84ad07SPedro Giffuni 
294*af84ad07SPedro Giffuni 			if (pParams[nIndex].bOut) // inout/out
295*af84ad07SPedro Giffuni 			{
296*af84ad07SPedro Giffuni 				// convert and assign
297*af84ad07SPedro Giffuni 				uno_destructData( pCppArgs[nIndex], pParamTypeDescr, cpp_release );
298*af84ad07SPedro Giffuni 				uno_copyAndConvertData( pCppArgs[nIndex], pUnoArgs[nIndex], pParamTypeDescr,
299*af84ad07SPedro Giffuni 										pThis->getBridge()->getUno2Cpp() );
300*af84ad07SPedro Giffuni 			}
301*af84ad07SPedro Giffuni 			// destroy temp uno param
302*af84ad07SPedro Giffuni 			uno_destructData( pUnoArgs[nIndex], pParamTypeDescr, 0 );
303*af84ad07SPedro Giffuni 
304*af84ad07SPedro Giffuni 			TYPELIB_DANGER_RELEASE( pParamTypeDescr );
305*af84ad07SPedro Giffuni 		}
306*af84ad07SPedro Giffuni 		// return
307*af84ad07SPedro Giffuni 		if (pCppReturn) // has complex return
308*af84ad07SPedro Giffuni 		{
309*af84ad07SPedro Giffuni 			if (pUnoReturn != pCppReturn) // needs reconversion
310*af84ad07SPedro Giffuni 			{
311*af84ad07SPedro Giffuni 				uno_copyAndConvertData( pCppReturn, pUnoReturn, pReturnTypeDescr,
312*af84ad07SPedro Giffuni 										pThis->getBridge()->getUno2Cpp() );
313*af84ad07SPedro Giffuni 				// destroy temp uno return
314*af84ad07SPedro Giffuni 				uno_destructData( pUnoReturn, pReturnTypeDescr, 0 );
315*af84ad07SPedro Giffuni 			}
316*af84ad07SPedro Giffuni 			// complex return ptr is set to return reg
317*af84ad07SPedro Giffuni 			*(void **)pRegisterReturn = pCppReturn;
318*af84ad07SPedro Giffuni 		}
319*af84ad07SPedro Giffuni 		if (pReturnTypeDescr)
320*af84ad07SPedro Giffuni 		{
321*af84ad07SPedro Giffuni 			typelib_TypeClass eRet = (typelib_TypeClass)pReturnTypeDescr->eTypeClass;
322*af84ad07SPedro Giffuni 			TYPELIB_DANGER_RELEASE( pReturnTypeDescr );
323*af84ad07SPedro Giffuni 			return eRet;
324*af84ad07SPedro Giffuni 		}
325*af84ad07SPedro Giffuni 		else
326*af84ad07SPedro Giffuni 			return typelib_TypeClass_VOID;
327*af84ad07SPedro Giffuni 	}
328*af84ad07SPedro Giffuni }
329*af84ad07SPedro Giffuni 
330*af84ad07SPedro Giffuni 
331*af84ad07SPedro Giffuni //==================================================================================================
cpp_mediate(sal_uInt64 nOffsetAndIndex,void ** gpreg,void ** fpreg,long sp,sal_Int64 * pRegisterReturn)332*af84ad07SPedro Giffuni static typelib_TypeClass cpp_mediate(
333*af84ad07SPedro Giffuni 	sal_uInt64 nOffsetAndIndex,
334*af84ad07SPedro Giffuni         void ** gpreg, void ** fpreg, long sp,
335*af84ad07SPedro Giffuni 	sal_Int64 * pRegisterReturn /* space for register return */ )
336*af84ad07SPedro Giffuni {
337*af84ad07SPedro Giffuni     OSL_ENSURE( sizeof(sal_Int64)==sizeof(void *), "### unexpected!" );
338*af84ad07SPedro Giffuni 
339*af84ad07SPedro Giffuni     sal_Int32 nVtableOffset = (nOffsetAndIndex >> 32);
340*af84ad07SPedro Giffuni     sal_Int32 nFunctionIndex = (nOffsetAndIndex & 0xFFFFFFFF);
341*af84ad07SPedro Giffuni 
342*af84ad07SPedro Giffuni     long sf = *(long*)sp;
343*af84ad07SPedro Giffuni     void ** ovrflw = (void**)(sf + 112);
344*af84ad07SPedro Giffuni 
345*af84ad07SPedro Giffuni     // gpreg:  [ret *], this, [other gpr params]
346*af84ad07SPedro Giffuni     // fpreg:  [fpr params]
347*af84ad07SPedro Giffuni     // ovrflw: [gpr or fpr params (properly aligned)]
348*af84ad07SPedro Giffuni 
349*af84ad07SPedro Giffuni     void * pThis;
350*af84ad07SPedro Giffuni     if (nFunctionIndex & 0x80000000 )
351*af84ad07SPedro Giffuni     {
352*af84ad07SPedro Giffuni 	nFunctionIndex &= 0x7fffffff;
353*af84ad07SPedro Giffuni 	pThis = gpreg[1];
354*af84ad07SPedro Giffuni #ifdef CMC_DEBUG
355*af84ad07SPedro Giffuni 	fprintf(stderr, "pThis is gpreg[1]\n");
356*af84ad07SPedro Giffuni #endif
357*af84ad07SPedro Giffuni     }
358*af84ad07SPedro Giffuni     else
359*af84ad07SPedro Giffuni     {
360*af84ad07SPedro Giffuni 	pThis = gpreg[0];
361*af84ad07SPedro Giffuni #ifdef CMC_DEBUG
362*af84ad07SPedro Giffuni 	fprintf(stderr, "pThis is gpreg[0]\n");
363*af84ad07SPedro Giffuni #endif
364*af84ad07SPedro Giffuni     }
365*af84ad07SPedro Giffuni 
366*af84ad07SPedro Giffuni #ifdef CMC_DEBUG
367*af84ad07SPedro Giffuni     fprintf(stderr, "pThis is %lx\n", pThis);
368*af84ad07SPedro Giffuni #endif
369*af84ad07SPedro Giffuni 
370*af84ad07SPedro Giffuni     pThis = static_cast< char * >(pThis) - nVtableOffset;
371*af84ad07SPedro Giffuni 
372*af84ad07SPedro Giffuni #ifdef CMC_DEBUG
373*af84ad07SPedro Giffuni     fprintf(stderr, "pThis is now %lx\n", pThis);
374*af84ad07SPedro Giffuni #endif
375*af84ad07SPedro Giffuni 
376*af84ad07SPedro Giffuni     bridges::cpp_uno::shared::CppInterfaceProxy * pCppI
377*af84ad07SPedro Giffuni 	    = bridges::cpp_uno::shared::CppInterfaceProxy::castInterfaceToProxy(
378*af84ad07SPedro Giffuni 			pThis);
379*af84ad07SPedro Giffuni 
380*af84ad07SPedro Giffuni     typelib_InterfaceTypeDescription * pTypeDescr = pCppI->getTypeDescr();
381*af84ad07SPedro Giffuni 
382*af84ad07SPedro Giffuni #ifdef CMC_DEBUG
383*af84ad07SPedro Giffuni     fprintf(stderr, "indexes are %d %d\n", nFunctionIndex, pTypeDescr->nMapFunctionIndexToMemberIndex);
384*af84ad07SPedro Giffuni #endif
385*af84ad07SPedro Giffuni 
386*af84ad07SPedro Giffuni 	OSL_ENSURE( nFunctionIndex < pTypeDescr->nMapFunctionIndexToMemberIndex, "### illegal vtable index!" );
387*af84ad07SPedro Giffuni 	if (nFunctionIndex >= pTypeDescr->nMapFunctionIndexToMemberIndex)
388*af84ad07SPedro Giffuni 	{
389*af84ad07SPedro Giffuni 		throw RuntimeException(
390*af84ad07SPedro Giffuni             rtl::OUString::createFromAscii("illegal vtable index!"),
391*af84ad07SPedro Giffuni             (XInterface *)pThis );
392*af84ad07SPedro Giffuni 	}
393*af84ad07SPedro Giffuni 
394*af84ad07SPedro Giffuni 	// determine called method
395*af84ad07SPedro Giffuni 	sal_Int32 nMemberPos = pTypeDescr->pMapFunctionIndexToMemberIndex[nFunctionIndex];
396*af84ad07SPedro Giffuni 	OSL_ENSURE( nMemberPos < pTypeDescr->nAllMembers, "### illegal member index!" );
397*af84ad07SPedro Giffuni 
398*af84ad07SPedro Giffuni #ifdef CMC_DEBUG
399*af84ad07SPedro Giffuni 	fprintf(stderr, "members are %d %d\n", nMemberPos, pTypeDescr->nAllMembers);
400*af84ad07SPedro Giffuni #endif
401*af84ad07SPedro Giffuni 
402*af84ad07SPedro Giffuni 	TypeDescription aMemberDescr( pTypeDescr->ppAllMembers[nMemberPos] );
403*af84ad07SPedro Giffuni 
404*af84ad07SPedro Giffuni 	typelib_TypeClass eRet;
405*af84ad07SPedro Giffuni 	switch (aMemberDescr.get()->eTypeClass)
406*af84ad07SPedro Giffuni 	{
407*af84ad07SPedro Giffuni 	case typelib_TypeClass_INTERFACE_ATTRIBUTE:
408*af84ad07SPedro Giffuni 	{
409*af84ad07SPedro Giffuni 		if (pTypeDescr->pMapMemberIndexToFunctionIndex[nMemberPos] == nFunctionIndex)
410*af84ad07SPedro Giffuni 		{
411*af84ad07SPedro Giffuni 			// is GET method
412*af84ad07SPedro Giffuni 			eRet = cpp2uno_call(
413*af84ad07SPedro Giffuni 				pCppI, aMemberDescr.get(),
414*af84ad07SPedro Giffuni 				((typelib_InterfaceAttributeTypeDescription *)aMemberDescr.get())->pAttributeTypeRef,
415*af84ad07SPedro Giffuni 				0, 0, // no params
416*af84ad07SPedro Giffuni 				gpreg, fpreg, ovrflw, pRegisterReturn );
417*af84ad07SPedro Giffuni 		}
418*af84ad07SPedro Giffuni 		else
419*af84ad07SPedro Giffuni 		{
420*af84ad07SPedro Giffuni 			// is SET method
421*af84ad07SPedro Giffuni 			typelib_MethodParameter aParam;
422*af84ad07SPedro Giffuni 			aParam.pTypeRef =
423*af84ad07SPedro Giffuni 				((typelib_InterfaceAttributeTypeDescription *)aMemberDescr.get())->pAttributeTypeRef;
424*af84ad07SPedro Giffuni 			aParam.bIn		= sal_True;
425*af84ad07SPedro Giffuni 			aParam.bOut		= sal_False;
426*af84ad07SPedro Giffuni 
427*af84ad07SPedro Giffuni 			eRet = cpp2uno_call(
428*af84ad07SPedro Giffuni 				pCppI, aMemberDescr.get(),
429*af84ad07SPedro Giffuni 				0, // indicates void return
430*af84ad07SPedro Giffuni 				1, &aParam,
431*af84ad07SPedro Giffuni 				gpreg, fpreg, ovrflw, pRegisterReturn );
432*af84ad07SPedro Giffuni 		}
433*af84ad07SPedro Giffuni 		break;
434*af84ad07SPedro Giffuni 	}
435*af84ad07SPedro Giffuni 	case typelib_TypeClass_INTERFACE_METHOD:
436*af84ad07SPedro Giffuni 	{
437*af84ad07SPedro Giffuni 		// is METHOD
438*af84ad07SPedro Giffuni 		switch (nFunctionIndex)
439*af84ad07SPedro Giffuni 		{
440*af84ad07SPedro Giffuni 		case 1: // acquire()
441*af84ad07SPedro Giffuni 			pCppI->acquireProxy(); // non virtual call!
442*af84ad07SPedro Giffuni 			eRet = typelib_TypeClass_VOID;
443*af84ad07SPedro Giffuni 			break;
444*af84ad07SPedro Giffuni 		case 2: // release()
445*af84ad07SPedro Giffuni 			pCppI->releaseProxy(); // non virtual call!
446*af84ad07SPedro Giffuni 			eRet = typelib_TypeClass_VOID;
447*af84ad07SPedro Giffuni 			break;
448*af84ad07SPedro Giffuni 		case 0: // queryInterface() opt
449*af84ad07SPedro Giffuni 		{
450*af84ad07SPedro Giffuni 			typelib_TypeDescription * pTD = 0;
451*af84ad07SPedro Giffuni 			TYPELIB_DANGER_GET( &pTD, reinterpret_cast< Type * >( gpreg[2] )->getTypeLibType() );
452*af84ad07SPedro Giffuni 			if (pTD)
453*af84ad07SPedro Giffuni 			{
454*af84ad07SPedro Giffuni                 XInterface * pInterface = 0;
455*af84ad07SPedro Giffuni                 (*pCppI->getBridge()->getCppEnv()->getRegisteredInterface)(
456*af84ad07SPedro Giffuni                     pCppI->getBridge()->getCppEnv(),
457*af84ad07SPedro Giffuni                     (void **)&pInterface, pCppI->getOid().pData,
458*af84ad07SPedro Giffuni                     (typelib_InterfaceTypeDescription *)pTD );
459*af84ad07SPedro Giffuni 
460*af84ad07SPedro Giffuni                 if (pInterface)
461*af84ad07SPedro Giffuni                 {
462*af84ad07SPedro Giffuni                     ::uno_any_construct(
463*af84ad07SPedro Giffuni                         reinterpret_cast< uno_Any * >( gpreg[0] ),
464*af84ad07SPedro Giffuni                         &pInterface, pTD, cpp_acquire );
465*af84ad07SPedro Giffuni                     pInterface->release();
466*af84ad07SPedro Giffuni                     TYPELIB_DANGER_RELEASE( pTD );
467*af84ad07SPedro Giffuni                     *(void **)pRegisterReturn = gpreg[0];
468*af84ad07SPedro Giffuni                     eRet = typelib_TypeClass_ANY;
469*af84ad07SPedro Giffuni                     break;
470*af84ad07SPedro Giffuni                 }
471*af84ad07SPedro Giffuni                 TYPELIB_DANGER_RELEASE( pTD );
472*af84ad07SPedro Giffuni 			}
473*af84ad07SPedro Giffuni 		} // else perform queryInterface()
474*af84ad07SPedro Giffuni 		default:
475*af84ad07SPedro Giffuni 			eRet = cpp2uno_call(
476*af84ad07SPedro Giffuni 				pCppI, aMemberDescr.get(),
477*af84ad07SPedro Giffuni 				((typelib_InterfaceMethodTypeDescription *)aMemberDescr.get())->pReturnTypeRef,
478*af84ad07SPedro Giffuni 				((typelib_InterfaceMethodTypeDescription *)aMemberDescr.get())->nParams,
479*af84ad07SPedro Giffuni 				((typelib_InterfaceMethodTypeDescription *)aMemberDescr.get())->pParams,
480*af84ad07SPedro Giffuni 				gpreg, fpreg, ovrflw, pRegisterReturn );
481*af84ad07SPedro Giffuni 		}
482*af84ad07SPedro Giffuni 		break;
483*af84ad07SPedro Giffuni 	}
484*af84ad07SPedro Giffuni 	default:
485*af84ad07SPedro Giffuni 	{
486*af84ad07SPedro Giffuni #ifdef CMC_DEBUG
487*af84ad07SPedro Giffuni 	    fprintf(stderr, "screwed\n");
488*af84ad07SPedro Giffuni #endif
489*af84ad07SPedro Giffuni 
490*af84ad07SPedro Giffuni 		throw RuntimeException(
491*af84ad07SPedro Giffuni             rtl::OUString::createFromAscii("no member description found!"),
492*af84ad07SPedro Giffuni             (XInterface *)pThis );
493*af84ad07SPedro Giffuni 		// is here for dummy
494*af84ad07SPedro Giffuni 		eRet = typelib_TypeClass_VOID;
495*af84ad07SPedro Giffuni 	}
496*af84ad07SPedro Giffuni 	}
497*af84ad07SPedro Giffuni 
498*af84ad07SPedro Giffuni #ifdef CMC_DEBUG
499*af84ad07SPedro Giffuni         fprintf(stderr, "end of cpp_mediate\n");
500*af84ad07SPedro Giffuni #endif
501*af84ad07SPedro Giffuni 	return eRet;
502*af84ad07SPedro Giffuni }
503*af84ad07SPedro Giffuni 
privateSnippetExecutor(...)504*af84ad07SPedro Giffuni extern "C" void privateSnippetExecutor( ... )
505*af84ad07SPedro Giffuni {
506*af84ad07SPedro Giffuni     volatile long nOffsetAndIndex;
507*af84ad07SPedro Giffuni 
508*af84ad07SPedro Giffuni     //mr %r3, %r11            # move into arg1 the 64bit value passed from OOo
509*af84ad07SPedro Giffuni     __asm__ __volatile__ (
510*af84ad07SPedro Giffuni                 "mr     %0,    11\n\t"
511*af84ad07SPedro Giffuni                 : "=r" (nOffsetAndIndex) : );
512*af84ad07SPedro Giffuni 
513*af84ad07SPedro Giffuni     sal_uInt64 gpreg[ppc64::MAX_GPR_REGS];
514*af84ad07SPedro Giffuni     double fpreg[ppc64::MAX_SSE_REGS];
515*af84ad07SPedro Giffuni 
516*af84ad07SPedro Giffuni     __asm__ __volatile__ (
517*af84ad07SPedro Giffuni         "std 3,   0(%0)\t\n"
518*af84ad07SPedro Giffuni         "std 4,   8(%0)\t\n"
519*af84ad07SPedro Giffuni         "std 5,  16(%0)\t\n"
520*af84ad07SPedro Giffuni         "std 6,  24(%0)\t\n"
521*af84ad07SPedro Giffuni         "std 7,  32(%0)\t\n"
522*af84ad07SPedro Giffuni         "std 8,  40(%0)\t\n"
523*af84ad07SPedro Giffuni         "std 9,  48(%0)\t\n"
524*af84ad07SPedro Giffuni         "std 10, 56(%0)\t\n"
525*af84ad07SPedro Giffuni         "stfd 1,   0(%1)\t\n"
526*af84ad07SPedro Giffuni         "stfd 2,   8(%1)\t\n"
527*af84ad07SPedro Giffuni         "stfd 3,  16(%1)\t\n"
528*af84ad07SPedro Giffuni         "stfd 4,  24(%1)\t\n"
529*af84ad07SPedro Giffuni         "stfd 5,  32(%1)\t\n"
530*af84ad07SPedro Giffuni         "stfd 6,  40(%1)\t\n"
531*af84ad07SPedro Giffuni         "stfd 7,  48(%1)\t\n"
532*af84ad07SPedro Giffuni         "stfd 8,  56(%1)\t\n"
533*af84ad07SPedro Giffuni         "stfd 9,  64(%1)\t\n"
534*af84ad07SPedro Giffuni         "stfd 10, 72(%1)\t\n"
535*af84ad07SPedro Giffuni         "stfd 11, 80(%1)\t\n"
536*af84ad07SPedro Giffuni         "stfd 12, 88(%1)\t\n"
537*af84ad07SPedro Giffuni         "stfd 13, 96(%1)\t\n"
538*af84ad07SPedro Giffuni 	: : "r" (gpreg), "r" (fpreg)
539*af84ad07SPedro Giffuni         : "r0", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10",
540*af84ad07SPedro Giffuni           "fr1", "fr2", "fr3", "fr4", "fr5", "fr6", "fr7", "fr8", "fr9",
541*af84ad07SPedro Giffuni           "fr10", "fr11", "fr12", "fr13"
542*af84ad07SPedro Giffuni     );
543*af84ad07SPedro Giffuni 
544*af84ad07SPedro Giffuni     volatile long sp;
545*af84ad07SPedro Giffuni 
546*af84ad07SPedro Giffuni     //stack pointer
547*af84ad07SPedro Giffuni     __asm__ __volatile__ (
548*af84ad07SPedro Giffuni                 "mr     %0,    1\n\t"
549*af84ad07SPedro Giffuni                 : "=r" (sp) : );
550*af84ad07SPedro Giffuni 
551*af84ad07SPedro Giffuni     volatile long nRegReturn[1];
552*af84ad07SPedro Giffuni 
553*af84ad07SPedro Giffuni     typelib_TypeClass aType =
554*af84ad07SPedro Giffuni         cpp_mediate( nOffsetAndIndex, (void**)gpreg, (void**)fpreg, sp, (sal_Int64*)nRegReturn);
555*af84ad07SPedro Giffuni 
556*af84ad07SPedro Giffuni     switch( aType )
557*af84ad07SPedro Giffuni     {
558*af84ad07SPedro Giffuni         case typelib_TypeClass_VOID:
559*af84ad07SPedro Giffuni 	    break;
560*af84ad07SPedro Giffuni         case typelib_TypeClass_BOOLEAN:
561*af84ad07SPedro Giffuni         case typelib_TypeClass_BYTE:
562*af84ad07SPedro Giffuni             __asm__( "lbz 3,%0\n\t"
563*af84ad07SPedro Giffuni                 : : "m" (nRegReturn[0]) );
564*af84ad07SPedro Giffuni             break;
565*af84ad07SPedro Giffuni         case typelib_TypeClass_CHAR:
566*af84ad07SPedro Giffuni         case typelib_TypeClass_UNSIGNED_SHORT:
567*af84ad07SPedro Giffuni             __asm__( "lhz 3,%0\n\t"
568*af84ad07SPedro Giffuni                 : : "m" (nRegReturn[0]) );
569*af84ad07SPedro Giffuni             break;
570*af84ad07SPedro Giffuni         case typelib_TypeClass_SHORT:
571*af84ad07SPedro Giffuni             __asm__( "lha 3,%0\n\t"
572*af84ad07SPedro Giffuni                 : : "m" (nRegReturn[0]) );
573*af84ad07SPedro Giffuni             break;
574*af84ad07SPedro Giffuni         case typelib_TypeClass_ENUM:
575*af84ad07SPedro Giffuni         case typelib_TypeClass_UNSIGNED_LONG:
576*af84ad07SPedro Giffuni             __asm__( "lwz 3,%0\n\t"
577*af84ad07SPedro Giffuni                 : : "m"(nRegReturn[0]) );
578*af84ad07SPedro Giffuni             break;
579*af84ad07SPedro Giffuni         case typelib_TypeClass_LONG:
580*af84ad07SPedro Giffuni             __asm__( "lwa 3,%0\n\t"
581*af84ad07SPedro Giffuni                 : : "m"(nRegReturn[0]) );
582*af84ad07SPedro Giffuni             break;
583*af84ad07SPedro Giffuni         case typelib_TypeClass_FLOAT:
584*af84ad07SPedro Giffuni             __asm__( "lfs 1,%0\n\t"
585*af84ad07SPedro Giffuni                 : : "m" (*((float*)nRegReturn)) );
586*af84ad07SPedro Giffuni             break;
587*af84ad07SPedro Giffuni         case typelib_TypeClass_DOUBLE:
588*af84ad07SPedro Giffuni             __asm__( "lfd 1,%0\n\t"
589*af84ad07SPedro Giffuni                 : : "m" (*((double*)nRegReturn)) );
590*af84ad07SPedro Giffuni             break;
591*af84ad07SPedro Giffuni         default:
592*af84ad07SPedro Giffuni             __asm__( "ld 3,%0\n\t"
593*af84ad07SPedro Giffuni                 : : "m" (nRegReturn[0]) );
594*af84ad07SPedro Giffuni             break;
595*af84ad07SPedro Giffuni     }
596*af84ad07SPedro Giffuni }
597*af84ad07SPedro Giffuni 
598*af84ad07SPedro Giffuni const int codeSnippetSize = 24;
599*af84ad07SPedro Giffuni 
codeSnippet(unsigned char * code,sal_Int32 nFunctionIndex,sal_Int32 nVtableOffset,bool simpleRetType)600*af84ad07SPedro Giffuni unsigned char *  codeSnippet( unsigned char * code, sal_Int32 nFunctionIndex, sal_Int32 nVtableOffset,
601*af84ad07SPedro Giffuni                               bool simpleRetType)
602*af84ad07SPedro Giffuni {
603*af84ad07SPedro Giffuni #ifdef CMC_DEBUG
604*af84ad07SPedro Giffuni     fprintf(stderr,"in codeSnippet functionIndex is %x\n", nFunctionIndex);
605*af84ad07SPedro Giffuni     fprintf(stderr,"in codeSnippet vtableOffset is %x\n", nVtableOffset);
606*af84ad07SPedro Giffuni #endif
607*af84ad07SPedro Giffuni 
608*af84ad07SPedro Giffuni     sal_uInt64 nOffsetAndIndex = ( ( (sal_uInt64) nVtableOffset ) << 32 ) | ( (sal_uInt64) nFunctionIndex );
609*af84ad07SPedro Giffuni 
610*af84ad07SPedro Giffuni     if ( !simpleRetType )
611*af84ad07SPedro Giffuni         nOffsetAndIndex |= 0x80000000;
612*af84ad07SPedro Giffuni 
613*af84ad07SPedro Giffuni     void ** raw = (void **)&code[0];
614*af84ad07SPedro Giffuni     memcpy(raw, (char*) privateSnippetExecutor, 16);
615*af84ad07SPedro Giffuni     raw[2] = (void*) nOffsetAndIndex;
616*af84ad07SPedro Giffuni #ifdef CMC_DEBUG
617*af84ad07SPedro Giffuni     fprintf(stderr, "in: offset/index is %x %x %d, %lx\n",
618*af84ad07SPedro Giffuni 	nFunctionIndex, nVtableOffset, !simpleRetType, raw[2]);
619*af84ad07SPedro Giffuni #endif
620*af84ad07SPedro Giffuni     return (code + codeSnippetSize);
621*af84ad07SPedro Giffuni }
622*af84ad07SPedro Giffuni 
623*af84ad07SPedro Giffuni }
624*af84ad07SPedro Giffuni 
flushCode(unsigned char const * bptr,unsigned char const * eptr)625*af84ad07SPedro Giffuni void bridges::cpp_uno::shared::VtableFactory::flushCode(unsigned char const * bptr, unsigned char const * eptr)
626*af84ad07SPedro Giffuni {
627*af84ad07SPedro Giffuni     int const lineSize = 32;
628*af84ad07SPedro Giffuni     for (unsigned char const * p = bptr; p < eptr + lineSize; p += lineSize) {
629*af84ad07SPedro Giffuni         __asm__ volatile ("dcbst 0, %0" : : "r"(p) : "memory");
630*af84ad07SPedro Giffuni     }
631*af84ad07SPedro Giffuni     __asm__ volatile ("sync" : : : "memory");
632*af84ad07SPedro Giffuni     for (unsigned char const * p = bptr; p < eptr + lineSize; p += lineSize) {
633*af84ad07SPedro Giffuni         __asm__ volatile ("icbi 0, %0" : : "r"(p) : "memory");
634*af84ad07SPedro Giffuni     }
635*af84ad07SPedro Giffuni     __asm__ volatile ("isync" : : : "memory");
636*af84ad07SPedro Giffuni }
637*af84ad07SPedro Giffuni 
638*af84ad07SPedro Giffuni struct bridges::cpp_uno::shared::VtableFactory::Slot { void * fn; };
639*af84ad07SPedro Giffuni 
640*af84ad07SPedro Giffuni bridges::cpp_uno::shared::VtableFactory::Slot *
mapBlockToVtable(void * block)641*af84ad07SPedro Giffuni bridges::cpp_uno::shared::VtableFactory::mapBlockToVtable(void * block)
642*af84ad07SPedro Giffuni {
643*af84ad07SPedro Giffuni     return static_cast< Slot * >(block) + 2;
644*af84ad07SPedro Giffuni }
645*af84ad07SPedro Giffuni 
getBlockSize(sal_Int32 slotCount)646*af84ad07SPedro Giffuni sal_Size bridges::cpp_uno::shared::VtableFactory::getBlockSize(
647*af84ad07SPedro Giffuni     sal_Int32 slotCount)
648*af84ad07SPedro Giffuni {
649*af84ad07SPedro Giffuni     return (slotCount + 2) * sizeof (Slot) + slotCount * codeSnippetSize;
650*af84ad07SPedro Giffuni }
651*af84ad07SPedro Giffuni 
652*af84ad07SPedro Giffuni bridges::cpp_uno::shared::VtableFactory::Slot *
initializeBlock(void * block,sal_Int32 slotCount)653*af84ad07SPedro Giffuni bridges::cpp_uno::shared::VtableFactory::initializeBlock(
654*af84ad07SPedro Giffuni     void * block, sal_Int32 slotCount)
655*af84ad07SPedro Giffuni {
656*af84ad07SPedro Giffuni     Slot * slots = mapBlockToVtable(block);
657*af84ad07SPedro Giffuni     slots[-2].fn = 0;
658*af84ad07SPedro Giffuni     slots[-1].fn = 0;
659*af84ad07SPedro Giffuni     return slots + slotCount;
660*af84ad07SPedro Giffuni }
661*af84ad07SPedro Giffuni 
addLocalFunctions(Slot ** slots,unsigned char * code,sal_PtrDiff writetoexecdiff,typelib_InterfaceTypeDescription const * type,sal_Int32 functionOffset,sal_Int32 functionCount,sal_Int32 vtableOffset)662*af84ad07SPedro Giffuni unsigned char * bridges::cpp_uno::shared::VtableFactory::addLocalFunctions(
663*af84ad07SPedro Giffuni     Slot ** slots, unsigned char * code, sal_PtrDiff writetoexecdiff,
664*af84ad07SPedro Giffuni     typelib_InterfaceTypeDescription const * type, sal_Int32 functionOffset,
665*af84ad07SPedro Giffuni     sal_Int32 functionCount, sal_Int32 vtableOffset)
666*af84ad07SPedro Giffuni {
667*af84ad07SPedro Giffuni      (*slots) -= functionCount;
668*af84ad07SPedro Giffuni      Slot * s = *slots;
669*af84ad07SPedro Giffuni #ifdef CMC_DEBUG
670*af84ad07SPedro Giffuni     fprintf(stderr, "in addLocalFunctions functionOffset is %x\n",functionOffset);
671*af84ad07SPedro Giffuni     fprintf(stderr, "in addLocalFunctions vtableOffset is %x\n",vtableOffset);
672*af84ad07SPedro Giffuni #endif
673*af84ad07SPedro Giffuni 
674*af84ad07SPedro Giffuni     for (sal_Int32 i = 0; i < type->nMembers; ++i) {
675*af84ad07SPedro Giffuni         typelib_TypeDescription * member = 0;
676*af84ad07SPedro Giffuni         TYPELIB_DANGER_GET(&member, type->ppMembers[i]);
677*af84ad07SPedro Giffuni         OSL_ASSERT(member != 0);
678*af84ad07SPedro Giffuni         switch (member->eTypeClass) {
679*af84ad07SPedro Giffuni         case typelib_TypeClass_INTERFACE_ATTRIBUTE:
680*af84ad07SPedro Giffuni             // Getter:
681*af84ad07SPedro Giffuni             (s++)->fn = code + writetoexecdiff;
682*af84ad07SPedro Giffuni             code = codeSnippet(
683*af84ad07SPedro Giffuni                 code, functionOffset++, vtableOffset,
684*af84ad07SPedro Giffuni                 bridges::cpp_uno::shared::isSimpleType(
685*af84ad07SPedro Giffuni                     reinterpret_cast<
686*af84ad07SPedro Giffuni                     typelib_InterfaceAttributeTypeDescription * >(
687*af84ad07SPedro Giffuni                         member)->pAttributeTypeRef));
688*af84ad07SPedro Giffuni 
689*af84ad07SPedro Giffuni             // Setter:
690*af84ad07SPedro Giffuni             if (!reinterpret_cast<
691*af84ad07SPedro Giffuni                 typelib_InterfaceAttributeTypeDescription * >(
692*af84ad07SPedro Giffuni                     member)->bReadOnly)
693*af84ad07SPedro Giffuni             {
694*af84ad07SPedro Giffuni                 (s++)->fn = code + writetoexecdiff;
695*af84ad07SPedro Giffuni                 code = codeSnippet(code, functionOffset++, vtableOffset, true);
696*af84ad07SPedro Giffuni             }
697*af84ad07SPedro Giffuni             break;
698*af84ad07SPedro Giffuni 
699*af84ad07SPedro Giffuni         case typelib_TypeClass_INTERFACE_METHOD:
700*af84ad07SPedro Giffuni             (s++)->fn = code + writetoexecdiff;
701*af84ad07SPedro Giffuni             code = codeSnippet(
702*af84ad07SPedro Giffuni                 code, functionOffset++, vtableOffset,
703*af84ad07SPedro Giffuni                 bridges::cpp_uno::shared::isSimpleType(
704*af84ad07SPedro Giffuni                     reinterpret_cast<
705*af84ad07SPedro Giffuni                     typelib_InterfaceMethodTypeDescription * >(
706*af84ad07SPedro Giffuni                         member)->pReturnTypeRef));
707*af84ad07SPedro Giffuni             break;
708*af84ad07SPedro Giffuni 
709*af84ad07SPedro Giffuni         default:
710*af84ad07SPedro Giffuni             OSL_ASSERT(false);
711*af84ad07SPedro Giffuni             break;
712*af84ad07SPedro Giffuni         }
713*af84ad07SPedro Giffuni         TYPELIB_DANGER_RELEASE(member);
714*af84ad07SPedro Giffuni     }
715*af84ad07SPedro Giffuni     return code;
716*af84ad07SPedro Giffuni }
717*af84ad07SPedro Giffuni 
718*af84ad07SPedro Giffuni /* vi:set tabstop=4 shiftwidth=4 expandtab: */
719