Line 0
Link Here
|
|
|
1 |
/************************************************************************* |
2 |
* |
3 |
* $RCSfile: cpp2uno.cxx,v $ |
4 |
* |
5 |
* $Revision: 1.6 $ |
6 |
* |
7 |
* last change: $Author: obo $ $Date: 2005/01/25 13:11:46 $ |
8 |
* |
9 |
* The Contents of this file are made available subject to the terms of |
10 |
* either of the following licenses |
11 |
* |
12 |
* - GNU Lesser General Public License Version 2.1 |
13 |
* - Sun Industry Standards Source License Version 1.1 |
14 |
* |
15 |
* Sun Microsystems Inc., October, 2000 |
16 |
* |
17 |
* GNU Lesser General Public License Version 2.1 |
18 |
* ============================================= |
19 |
* Copyright 2000 by Sun Microsystems, Inc. |
20 |
* 901 San Antonio Road, Palo Alto, CA 94303, USA |
21 |
* |
22 |
* This library is free software; you can redistribute it and/or |
23 |
* modify it under the terms of the GNU Lesser General Public |
24 |
* License version 2.1, as published by the Free Software Foundation. |
25 |
* |
26 |
* This library is distributed in the hope that it will be useful, |
27 |
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
28 |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
29 |
* Lesser General Public License for more details. |
30 |
* |
31 |
* You should have received a copy of the GNU Lesser General Public |
32 |
* License along with this library; if not, write to the Free Software |
33 |
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, |
34 |
* MA 02111-1307 USA |
35 |
* |
36 |
* |
37 |
* Sun Industry Standards Source License Version 1.1 |
38 |
* ================================================= |
39 |
* The contents of this file are subject to the Sun Industry Standards |
40 |
* Source License Version 1.1 (the "License"); You may not use this file |
41 |
* except in compliance with the License. You may obtain a copy of the |
42 |
* License at http://www.openoffice.org/license.html. |
43 |
* |
44 |
* Software provided under this License is provided on an "AS IS" basis, |
45 |
* WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, |
46 |
* WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, |
47 |
* MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. |
48 |
* See the License for the specific provisions governing your rights and |
49 |
* obligations concerning the Software. |
50 |
* |
51 |
* The Initial Developer of the Original Code is: Sun Microsystems, Inc. |
52 |
* |
53 |
* Copyright: 2000 by Sun Microsystems, Inc. |
54 |
* |
55 |
* All Rights Reserved. |
56 |
* |
57 |
* Contributor(s): _______________________________________ |
58 |
* |
59 |
* |
60 |
************************************************************************/ |
61 |
#include <com/sun/star/uno/genfunc.hxx> |
62 |
#include <typelib/typedescription.hxx> |
63 |
#include <uno/data.h> |
64 |
#include "bridges/cpp_uno/shared/bridge.hxx" |
65 |
#include "bridges/cpp_uno/shared/cppinterfaceproxy.hxx" |
66 |
#include "bridges/cpp_uno/shared/types.hxx" |
67 |
#include "bridges/cpp_uno/shared/vtablefactory.hxx" |
68 |
#include "share.hxx" |
69 |
#include <alloca.h> |
70 |
|
71 |
using namespace com::sun::star::uno; |
72 |
|
73 |
namespace |
74 |
{ |
75 |
//================================================================================================== |
76 |
static typelib_TypeClass cpp2uno_call( |
77 |
bridges::cpp_uno::shared::CppInterfaceProxy * pThis, |
78 |
const typelib_TypeDescription * pMemberTypeDescr, |
79 |
typelib_TypeDescriptionReference * pReturnTypeRef, // 0 indicates void return |
80 |
sal_Int32 nParams, typelib_MethodParameter * pParams, |
81 |
void ** pCallStack, |
82 |
sal_Int64 * pRegisterReturn /* space for register return */ ) |
83 |
{ |
84 |
// pCallStack: [ret ptr], this, params |
85 |
char * pCppStack = (char *)pCallStack; |
86 |
|
87 |
// return |
88 |
typelib_TypeDescription * pReturnTypeDescr = 0; |
89 |
if (pReturnTypeRef) |
90 |
TYPELIB_DANGER_GET( &pReturnTypeDescr, pReturnTypeRef ); |
91 |
|
92 |
void * pUnoReturn = 0; |
93 |
void * pCppReturn = 0; // complex return ptr: if != 0 && != pUnoReturn, reconversion need |
94 |
|
95 |
if (pReturnTypeDescr) |
96 |
{ |
97 |
if (bridges::cpp_uno::shared::isSimpleType( pReturnTypeDescr )) |
98 |
pUnoReturn = pRegisterReturn; // direct way for simple types |
99 |
else // complex return via ptr (pCppReturn) |
100 |
{ |
101 |
pCppReturn = *(void**)pCppStack; |
102 |
pUnoReturn = (bridges::cpp_uno::shared::relatesToInterfaceType( |
103 |
pReturnTypeDescr ) |
104 |
? alloca( pReturnTypeDescr->nSize ) |
105 |
: pCppReturn); // direct way |
106 |
pCppStack += sizeof( void* ); |
107 |
} |
108 |
} |
109 |
// pop this |
110 |
pCppStack += sizeof( void* ); |
111 |
|
112 |
// stack space |
113 |
OSL_ENSURE( sizeof(void *) == sizeof(sal_Int32), "### unexpected size!" ); |
114 |
// parameters |
115 |
void ** pUnoArgs = (void **)alloca( 4 * sizeof(void *) * nParams ); |
116 |
void ** pCppArgs = pUnoArgs + nParams; |
117 |
// indizes of values this have to be converted (interface conversion cpp<=>uno) |
118 |
sal_Int32 * pTempIndizes = (sal_Int32 *)(pUnoArgs + (2 * nParams)); |
119 |
// type descriptions for reconversions |
120 |
typelib_TypeDescription ** ppTempParamTypeDescr = (typelib_TypeDescription **)(pUnoArgs + (3 * nParams)); |
121 |
|
122 |
sal_Int32 nTempIndizes = 0; |
123 |
|
124 |
for ( sal_Int32 nPos = 0; nPos < nParams; ++nPos ) |
125 |
{ |
126 |
const typelib_MethodParameter & rParam = pParams[nPos]; |
127 |
typelib_TypeDescription * pParamTypeDescr = 0; |
128 |
TYPELIB_DANGER_GET( &pParamTypeDescr, rParam.pTypeRef ); |
129 |
|
130 |
if (!rParam.bOut && bridges::cpp_uno::shared::isSimpleType( pParamTypeDescr )) // value |
131 |
{ |
132 |
pCppArgs[nPos] = pUnoArgs[nPos] = CPPU_CURRENT_NAMESPACE::adjustPointer(pCppStack, pParamTypeDescr); |
133 |
switch (pParamTypeDescr->eTypeClass) |
134 |
{ |
135 |
case typelib_TypeClass_HYPER: |
136 |
case typelib_TypeClass_UNSIGNED_HYPER: |
137 |
case typelib_TypeClass_DOUBLE: |
138 |
{ |
139 |
if ((reinterpret_cast< long >(pCppStack) & 7) != 0) |
140 |
{ |
141 |
OSL_ASSERT( sizeof (double) == sizeof (sal_Int64) ); |
142 |
void * pDest = alloca( sizeof (sal_Int64) ); |
143 |
*reinterpret_cast< sal_Int32 * >(pDest) = |
144 |
*reinterpret_cast< sal_Int32 const * >(pCppStack); |
145 |
*(reinterpret_cast< sal_Int32 * >(pDest) + 1) = |
146 |
*(reinterpret_cast< sal_Int32 const * >(pCppStack) + 1); |
147 |
pCppArgs[nPos] = pUnoArgs[nPos] = pDest; |
148 |
} |
149 |
pCppStack += sizeof (sal_Int32); // extra long |
150 |
break; |
151 |
} |
152 |
} |
153 |
// no longer needed |
154 |
TYPELIB_DANGER_RELEASE( pParamTypeDescr ); |
155 |
} |
156 |
else // ptr to complex value | ref |
157 |
{ |
158 |
pCppArgs[nPos] = *(void **)pCppStack; |
159 |
|
160 |
if (! rParam.bIn) // is pure out |
161 |
{ |
162 |
// uno out is unconstructed mem! |
163 |
pUnoArgs[nPos] = alloca( pParamTypeDescr->nSize ); |
164 |
pTempIndizes[nTempIndizes] = nPos; |
165 |
// will be released at reconversion |
166 |
ppTempParamTypeDescr[nTempIndizes++] = pParamTypeDescr; |
167 |
} |
168 |
// is in/inout |
169 |
else if (bridges::cpp_uno::shared::relatesToInterfaceType( |
170 |
pParamTypeDescr )) |
171 |
{ |
172 |
uno_copyAndConvertData( pUnoArgs[nPos] = alloca( pParamTypeDescr->nSize ), |
173 |
*(void **)pCppStack, pParamTypeDescr, |
174 |
pThis->getBridge()->getCpp2Uno() ); |
175 |
pTempIndizes[nTempIndizes] = nPos; // has to be reconverted |
176 |
// will be released at reconversion |
177 |
ppTempParamTypeDescr[nTempIndizes++] = pParamTypeDescr; |
178 |
} |
179 |
else // direct way |
180 |
{ |
181 |
pUnoArgs[nPos] = *(void **)pCppStack; |
182 |
// no longer needed |
183 |
TYPELIB_DANGER_RELEASE( pParamTypeDescr ); |
184 |
} |
185 |
} |
186 |
pCppStack += sizeof(sal_Int32); // standard parameter length |
187 |
} |
188 |
|
189 |
// ExceptionHolder |
190 |
uno_Any aUnoExc; // Any will be constructed by callee |
191 |
uno_Any * pUnoExc = &aUnoExc; |
192 |
|
193 |
// invoke uno dispatch call |
194 |
(*pThis->getUnoI()->pDispatcher)(pThis->getUnoI(), pMemberTypeDescr, pUnoReturn, pUnoArgs, &pUnoExc ); |
195 |
|
196 |
// in case an exception occured... |
197 |
if (pUnoExc) |
198 |
{ |
199 |
// destruct temporary in/inout params |
200 |
for ( ; nTempIndizes--; ) |
201 |
{ |
202 |
sal_Int32 nIndex = pTempIndizes[nTempIndizes]; |
203 |
|
204 |
if (pParams[nIndex].bIn) // is in/inout => was constructed |
205 |
uno_destructData( pUnoArgs[nIndex], ppTempParamTypeDescr[nTempIndizes], 0 ); |
206 |
TYPELIB_DANGER_RELEASE( ppTempParamTypeDescr[nTempIndizes] ); |
207 |
} |
208 |
if (pReturnTypeDescr) |
209 |
TYPELIB_DANGER_RELEASE( pReturnTypeDescr ); |
210 |
CPPU_CURRENT_NAMESPACE::raiseException(&aUnoExc, pThis->getBridge()->getUno2Cpp() ); |
211 |
// has to destruct the any |
212 |
// is here for dummy |
213 |
return typelib_TypeClass_VOID; |
214 |
} |
215 |
else // else no exception occured... |
216 |
{ |
217 |
// temporary params |
218 |
for ( ; nTempIndizes--; ) |
219 |
{ |
220 |
sal_Int32 nIndex = pTempIndizes[nTempIndizes]; |
221 |
typelib_TypeDescription * pParamTypeDescr = ppTempParamTypeDescr[nTempIndizes]; |
222 |
|
223 |
if (pParams[nIndex].bOut) // inout/out |
224 |
{ |
225 |
// convert and assign |
226 |
uno_destructData( pCppArgs[nIndex], pParamTypeDescr, cpp_release ); |
227 |
uno_copyAndConvertData( pCppArgs[nIndex], pUnoArgs[nIndex], pParamTypeDescr, |
228 |
pThis->getBridge()->getUno2Cpp() ); |
229 |
} |
230 |
// destroy temp uno param |
231 |
uno_destructData( pUnoArgs[nIndex], pParamTypeDescr, 0 ); |
232 |
|
233 |
TYPELIB_DANGER_RELEASE( pParamTypeDescr ); |
234 |
} |
235 |
// return |
236 |
if (pCppReturn) // has complex return |
237 |
{ |
238 |
if (pUnoReturn != pCppReturn) // needs reconversion |
239 |
{ |
240 |
uno_copyAndConvertData( pCppReturn, pUnoReturn, pReturnTypeDescr, |
241 |
pThis->getBridge()->getUno2Cpp() ); |
242 |
// destroy temp uno return |
243 |
uno_destructData( pUnoReturn, pReturnTypeDescr, 0 ); |
244 |
} |
245 |
// complex return ptr is set to eax |
246 |
*(void **)pRegisterReturn = pCppReturn; |
247 |
} |
248 |
if (pReturnTypeDescr) |
249 |
{ |
250 |
typelib_TypeClass eRet = (typelib_TypeClass)pReturnTypeDescr->eTypeClass; |
251 |
TYPELIB_DANGER_RELEASE( pReturnTypeDescr ); |
252 |
return eRet; |
253 |
} |
254 |
else |
255 |
return typelib_TypeClass_VOID; |
256 |
} |
257 |
} |
258 |
|
259 |
|
260 |
//================================================================================================== |
261 |
static typelib_TypeClass cpp_mediate( |
262 |
sal_Int32 nFunctionIndex, |
263 |
sal_Int32 nVtableOffset, |
264 |
void ** pCallStack, |
265 |
sal_Int64 * pRegisterReturn /* space for register return */ ) |
266 |
{ |
267 |
OSL_ENSURE( sizeof(sal_Int32)==sizeof(void *), "### unexpected!" ); |
268 |
|
269 |
// pCallStack: this, params |
270 |
// eventual [ret*] lies at pCallStack -1 |
271 |
// so count down pCallStack by one to keep it simple |
272 |
// pCallStack: this, params |
273 |
// eventual [ret*] lies at pCallStack -1 |
274 |
// so count down pCallStack by one to keep it simple |
275 |
bridges::cpp_uno::shared::CppInterfaceProxy * pCppI |
276 |
= bridges::cpp_uno::shared::CppInterfaceProxy::castInterfaceToProxy( |
277 |
static_cast< char * >(*pCallStack) - nVtableOffset); |
278 |
if ((nFunctionIndex & 0x80000000) != 0) { |
279 |
nFunctionIndex &= 0x7FFFFFFF; |
280 |
--pCallStack; |
281 |
} |
282 |
|
283 |
typelib_InterfaceTypeDescription * pTypeDescr = pCppI->getTypeDescr(); |
284 |
|
285 |
OSL_ENSURE( nFunctionIndex < pTypeDescr->nMapFunctionIndexToMemberIndex, |
286 |
"### illegal vtable index!" ); |
287 |
if (nFunctionIndex >= pTypeDescr->nMapFunctionIndexToMemberIndex) |
288 |
{ |
289 |
throw RuntimeException( rtl::OUString::createFromAscii("illegal vtable index!"), (XInterface *)pCppI ); |
290 |
} |
291 |
|
292 |
// determine called method |
293 |
sal_Int32 nMemberPos = pTypeDescr->pMapFunctionIndexToMemberIndex[nFunctionIndex]; |
294 |
OSL_ENSURE( nMemberPos < pTypeDescr->nAllMembers, "### illegal member index!" ); |
295 |
|
296 |
TypeDescription aMemberDescr( pTypeDescr->ppAllMembers[nMemberPos] ); |
297 |
|
298 |
#if defined BRIDGES_DEBUG |
299 |
OString cstr( OUStringToOString( aMemberDescr.get()->pTypeName, RTL_TEXTENCODING_ASCII_US ) ); |
300 |
fprintf( stderr, "calling %s, nFunctionIndex=%d\n", cstr.getStr(), nFunctionIndex ); |
301 |
#endif |
302 |
|
303 |
typelib_TypeClass eRet; |
304 |
switch (aMemberDescr.get()->eTypeClass) |
305 |
{ |
306 |
case typelib_TypeClass_INTERFACE_ATTRIBUTE: |
307 |
{ |
308 |
if (pTypeDescr->pMapMemberIndexToFunctionIndex[nMemberPos] == nFunctionIndex) |
309 |
{ |
310 |
// is GET method |
311 |
eRet = cpp2uno_call( |
312 |
pCppI, aMemberDescr.get(), |
313 |
((typelib_InterfaceAttributeTypeDescription *)aMemberDescr.get())->pAttributeTypeRef, |
314 |
0, 0, // no params |
315 |
pCallStack, pRegisterReturn ); |
316 |
} |
317 |
else |
318 |
{ |
319 |
// is SET method |
320 |
typelib_MethodParameter aParam; |
321 |
aParam.pTypeRef = |
322 |
((typelib_InterfaceAttributeTypeDescription *)aMemberDescr.get())->pAttributeTypeRef; |
323 |
aParam.bIn = sal_True; |
324 |
aParam.bOut = sal_False; |
325 |
|
326 |
eRet = cpp2uno_call( |
327 |
pCppI, aMemberDescr.get(), |
328 |
0, // indicates void return |
329 |
1, &aParam, |
330 |
pCallStack, pRegisterReturn ); |
331 |
} |
332 |
break; |
333 |
} |
334 |
case typelib_TypeClass_INTERFACE_METHOD: |
335 |
{ |
336 |
// is METHOD |
337 |
switch (nFunctionIndex) |
338 |
{ |
339 |
case 1: // acquire() |
340 |
pCppI->acquireProxy(); // non virtual call! |
341 |
eRet = typelib_TypeClass_VOID; |
342 |
break; |
343 |
case 2: // release() |
344 |
pCppI->releaseProxy(); // non virtual call! |
345 |
eRet = typelib_TypeClass_VOID; |
346 |
break; |
347 |
case 0: // queryInterface() opt |
348 |
{ |
349 |
typelib_TypeDescription * pTD = 0; |
350 |
TYPELIB_DANGER_GET( &pTD, reinterpret_cast< Type * >( pCallStack[2] )->getTypeLibType() ); |
351 |
if (pTD) |
352 |
{ |
353 |
XInterface * pInterface = 0; |
354 |
(*pCppI->getBridge()->getCppEnv()->getRegisteredInterface)( |
355 |
pCppI->getBridge()->getCppEnv(), |
356 |
(void **)&pInterface, pCppI->getOid().pData, (typelib_InterfaceTypeDescription *)pTD ); |
357 |
|
358 |
if (pInterface) |
359 |
{ |
360 |
::uno_any_construct( |
361 |
reinterpret_cast< uno_Any * >( pCallStack[0] ), |
362 |
&pInterface, pTD, cpp_acquire ); |
363 |
pInterface->release(); |
364 |
TYPELIB_DANGER_RELEASE( pTD ); |
365 |
*(void **)pRegisterReturn = pCallStack[0]; |
366 |
eRet = typelib_TypeClass_ANY; |
367 |
break; |
368 |
} |
369 |
TYPELIB_DANGER_RELEASE( pTD ); |
370 |
} |
371 |
} // else perform queryInterface() |
372 |
default: |
373 |
eRet = cpp2uno_call( |
374 |
pCppI, aMemberDescr.get(), |
375 |
((typelib_InterfaceMethodTypeDescription *)aMemberDescr.get())->pReturnTypeRef, |
376 |
((typelib_InterfaceMethodTypeDescription *)aMemberDescr.get())->nParams, |
377 |
((typelib_InterfaceMethodTypeDescription *)aMemberDescr.get())->pParams, |
378 |
pCallStack, pRegisterReturn ); |
379 |
} |
380 |
break; |
381 |
} |
382 |
default: |
383 |
{ |
384 |
throw RuntimeException(rtl::OUString::createFromAscii("no member description found!"), (XInterface *)pCppI ); |
385 |
// is here for dummy |
386 |
eRet = typelib_TypeClass_VOID; |
387 |
} |
388 |
} |
389 |
return eRet; |
390 |
} |
391 |
|
392 |
|
393 |
|
394 |
//================================================================================================== |
395 |
/** |
396 |
* is called on incoming vtable calls |
397 |
* (called by asm snippets) |
398 |
*/ |
399 |
static void cpp_vtable_call() |
400 |
{ |
401 |
volatile sal_Int64 nRegReturn; |
402 |
int nFunctionIndex; |
403 |
void** pCallStack; |
404 |
int vTableOffset; |
405 |
|
406 |
__asm__( "st %%i0, %0\n\t" |
407 |
"st %%i1, %1\n\t" |
408 |
"st %%i2, %2\n\t" |
409 |
: : "m"(nFunctionIndex), "m"(pCallStack), "m"(vTableOffset) ); |
410 |
|
411 |
// fprintf(stderr,"cpp_mediate nFunctionIndex=%x\n",nFunctionIndex); |
412 |
// fflush(stderr); |
413 |
|
414 |
sal_Bool bComplex = nFunctionIndex & 0x80000000 ? sal_True : sal_False; |
415 |
typelib_TypeClass aType = |
416 |
cpp_mediate( nFunctionIndex, vTableOffset, pCallStack+17, (sal_Int64*)&nRegReturn ); |
417 |
|
418 |
switch( aType ) |
419 |
{ |
420 |
case typelib_TypeClass_BOOLEAN: |
421 |
case typelib_TypeClass_BYTE: |
422 |
__asm__( "ld %0, %%l0\n\t" |
423 |
"ldsb [%%l0], %%i0\n" |
424 |
: : "m"(&nRegReturn) ); |
425 |
break; |
426 |
case typelib_TypeClass_CHAR: |
427 |
case typelib_TypeClass_SHORT: |
428 |
case typelib_TypeClass_UNSIGNED_SHORT: |
429 |
__asm__( "ld %0, %%l0\n\t" |
430 |
"ldsh [%%l0], %%i0\n" |
431 |
: : "m"(&nRegReturn) ); |
432 |
break; |
433 |
case typelib_TypeClass_HYPER: |
434 |
case typelib_TypeClass_UNSIGNED_HYPER: |
435 |
|
436 |
__asm__( "ld %0, %%l0\n\t" |
437 |
"ld [%%l0], %%i0\n\t" |
438 |
"ld %1, %%l0\n\t" |
439 |
"ld [%%l0], %%i1\n\t" |
440 |
: : "m"(&nRegReturn), "m"(((long*)&nRegReturn) +1) ); |
441 |
|
442 |
break; |
443 |
case typelib_TypeClass_FLOAT: |
444 |
__asm__( "ld %0, %%l0\n\t" |
445 |
"ld [%%l0], %%f0\n" |
446 |
: : "m"(&nRegReturn) ); |
447 |
break; |
448 |
case typelib_TypeClass_DOUBLE: |
449 |
__asm__( "ld %0, %%l0\n\t" |
450 |
"ldd [%%l0], %%f0\n" |
451 |
: : "m"(&nRegReturn) ); |
452 |
break; |
453 |
case typelib_TypeClass_VOID: |
454 |
break; |
455 |
default: |
456 |
__asm__( "ld %0, %%l0\n\t" |
457 |
"ld [%%l0], %%i0\n" |
458 |
: : "m"(&nRegReturn) ); |
459 |
break; |
460 |
} |
461 |
|
462 |
if( bComplex ) |
463 |
{ |
464 |
__asm__( "add %i7, 4, %i7\n\t" ); |
465 |
// after call to complex return valued funcion there is an unimp instruction |
466 |
} |
467 |
|
468 |
} |
469 |
//__________________________________________________________________________________________________ |
470 |
|
471 |
int const codeSnippetSize = 56; |
472 |
unsigned char * codeSnippet( |
473 |
unsigned char * code, sal_Int32 functionIndex, sal_Int32 vtableOffset, |
474 |
bool simpleRetType) |
475 |
{ |
476 |
sal_uInt32 index = functionIndex; |
477 |
if (!simpleRetType) { |
478 |
index |= 0x80000000; |
479 |
} |
480 |
unsigned int * p = reinterpret_cast< unsigned int * >(code); |
481 |
OSL_ASSERT(sizeof (unsigned int) == 4); |
482 |
// st %o0, [%sp+68]: |
483 |
*p++ = 0xD023A044; |
484 |
// st %o1, [%sp+72]: |
485 |
*p++ = 0xD223A048; |
486 |
// st %o2, [%sp+76]: |
487 |
*p++ = 0xD423A04C; |
488 |
// st %o3, [%sp+80]: |
489 |
*p++ = 0xD623A050; |
490 |
// st %o4, [%sp+84]: |
491 |
*p++ = 0xD823A054; |
492 |
// st %o5, [%sp+88]: |
493 |
*p++ = 0xDA23A058; |
494 |
// sethi %hi(index), %o0: |
495 |
*p++ = 0x11000000 | (index >> 10); |
496 |
// or %o0, %lo(index), %o0: |
497 |
*p++ = 0x90122000 | (index & 0x3FF); |
498 |
// sethi %hi(vtableOffset), %o2: |
499 |
*p++ = 0x15000000 | (vtableOffset >> 10); |
500 |
// or %o2, %lo(vtableOffset), %o2: |
501 |
*p++ = 0x9412A000 | (vtableOffset & 0x3FF); |
502 |
// sethi %hi(cpp_vtable_call), %o3: |
503 |
*p++ = 0x17000000 | (reinterpret_cast< unsigned int >(cpp_vtable_call) >> 10); |
504 |
// or %o3, %lo(cpp_vtable_call), %o3: |
505 |
*p++ = 0x9612E000 | (reinterpret_cast< unsigned int >(cpp_vtable_call) & 0x3FF); |
506 |
// jmpl %o3, %g0: |
507 |
*p++ = 0x81C2C000; |
508 |
// mov %sp, %o1: |
509 |
*p++ = 0x9210000E; |
510 |
OSL_ASSERT( |
511 |
reinterpret_cast< unsigned char * >(p) - code <= codeSnippetSize); |
512 |
return code + codeSnippetSize; |
513 |
} |
514 |
|
515 |
} //end of namespace |
516 |
|
517 |
void ** bridges::cpp_uno::shared::VtableFactory::mapBlockToVtable(char * block) |
518 |
{ |
519 |
return reinterpret_cast< void ** >(block) + 2; |
520 |
} |
521 |
|
522 |
char * bridges::cpp_uno::shared::VtableFactory::createBlock( |
523 |
sal_Int32 slotCount, void *** slots) |
524 |
{ |
525 |
char * block = new char[ |
526 |
(slotCount + 2) * sizeof (void *) + slotCount * codeSnippetSize]; |
527 |
*slots = mapBlockToVtable(block); |
528 |
(*slots)[-2] = 0; //null |
529 |
(*slots)[-1] = 0; //destructor |
530 |
return block; |
531 |
} |
532 |
|
533 |
unsigned char * bridges::cpp_uno::shared::VtableFactory::addLocalFunctions( |
534 |
void ** slots, unsigned char * code, |
535 |
typelib_InterfaceTypeDescription const * type, sal_Int32 functionOffset, |
536 |
sal_Int32 functionCount, sal_Int32 vTableOffset) |
537 |
{ |
538 |
for (sal_Int32 i = 0; i < type->nMembers; ++i) { |
539 |
typelib_TypeDescription * member = 0; |
540 |
TYPELIB_DANGER_GET(&member, type->ppMembers[i]); |
541 |
OSL_ASSERT(member != 0); |
542 |
switch (member->eTypeClass) { |
543 |
case typelib_TypeClass_INTERFACE_ATTRIBUTE: |
544 |
// Getter: |
545 |
*slots++ = code; |
546 |
code = codeSnippet( |
547 |
code, functionOffset++, vTableOffset, |
548 |
bridges::cpp_uno::shared::isSimpleType( |
549 |
reinterpret_cast< |
550 |
typelib_InterfaceAttributeTypeDescription * >( |
551 |
member)->pAttributeTypeRef)); |
552 |
// Setter: |
553 |
if (!reinterpret_cast< |
554 |
typelib_InterfaceAttributeTypeDescription * >( |
555 |
member)->bReadOnly) |
556 |
{ |
557 |
*slots++ = code; |
558 |
code = codeSnippet(code, functionOffset++, vTableOffset, true); |
559 |
} |
560 |
break; |
561 |
|
562 |
case typelib_TypeClass_INTERFACE_METHOD: |
563 |
*slots++ = code; |
564 |
code = codeSnippet( |
565 |
code, functionOffset++, vTableOffset, |
566 |
bridges::cpp_uno::shared::isSimpleType( |
567 |
reinterpret_cast< |
568 |
typelib_InterfaceMethodTypeDescription * >( |
569 |
member)->pReturnTypeRef)); |
570 |
break; |
571 |
|
572 |
default: |
573 |
OSL_ASSERT(false); |
574 |
break; |
575 |
} |
576 |
TYPELIB_DANGER_RELEASE(member); |
577 |
} |
578 |
return code; |
579 |
} |
580 |
|
581 |
void bridges::cpp_uno::shared::VtableFactory::flushCode( |
582 |
unsigned char const *, unsigned char const *) |
583 |
{ |
584 |
//TODO: IZ 25819 flush the instruction cache (there probably is OS support for this) |
585 |
} |