Lines 2-10
Link Here
|
2 |
* |
2 |
* |
3 |
* $RCSfile: cpp2uno.cxx,v $ |
3 |
* $RCSfile: cpp2uno.cxx,v $ |
4 |
* |
4 |
* |
5 |
* $Revision: 1.2.34.1 $ |
5 |
* $Revision: 1.4 $ |
6 |
* |
6 |
* |
7 |
* last change: $Author: vg $ $Date: 2004/05/03 15:43:35 $ |
7 |
* last change: $Author: svesik $ $Date: 2004/04/21 13:40:45 $ |
8 |
* |
8 |
* |
9 |
* The Contents of this file are made available subject to the terms of |
9 |
* The Contents of this file are made available subject to the terms of |
10 |
* either of the following licenses |
10 |
* either of the following licenses |
Lines 58-108
Link Here
|
58 |
* |
58 |
* |
59 |
* |
59 |
* |
60 |
************************************************************************/ |
60 |
************************************************************************/ |
61 |
|
61 |
#include <com/sun/star/uno/genfunc.hxx> |
62 |
#define LEAK_STATIC_DATA |
|
|
63 |
// #define TRACE(x) OSL_TRACE(x) |
64 |
#define TRACE(x) |
65 |
|
66 |
#include <malloc.h> |
67 |
#include <list> |
68 |
#include <map> |
69 |
#include <typeinfo> |
70 |
#ifndef _RTL_ALLOC_H_ |
71 |
#include <rtl/alloc.h> |
72 |
#endif |
73 |
#ifndef _OSL_MUTEX_HXX_ |
74 |
#include <osl/mutex.hxx> |
75 |
#endif |
76 |
|
77 |
#ifndef _TYPELIB_TYPEDESCRIPTION_HXX_ |
78 |
#include <typelib/typedescription.hxx> |
62 |
#include <typelib/typedescription.hxx> |
79 |
#endif |
|
|
80 |
#ifndef _UNO_DATA_H_ |
81 |
#include <uno/data.h> |
63 |
#include <uno/data.h> |
82 |
#endif |
64 |
#include "bridges/cpp_uno/shared/bridge.hxx" |
83 |
#ifndef _BRIDGES_CPP_UNO_BRIDGE_HXX_ |
65 |
#include "bridges/cpp_uno/shared/cppinterfaceproxy.hxx" |
84 |
#include <bridges/cpp_uno/bridge.hxx> |
66 |
#include "bridges/cpp_uno/shared/types.hxx" |
85 |
#endif |
67 |
#include "bridges/cpp_uno/shared/vtablefactory.hxx" |
86 |
#ifndef _BRIDGES_CPP_UNO_TYPE_MISC_HXX_ |
|
|
87 |
#include <bridges/cpp_uno/type_misc.hxx> |
88 |
#endif |
89 |
|
90 |
#include "share.hxx" |
68 |
#include "share.hxx" |
91 |
|
69 |
|
92 |
using namespace com::sun::star::uno; |
70 |
using namespace com::sun::star::uno; |
93 |
using namespace std; |
|
|
94 |
using namespace osl; |
95 |
using namespace rtl; |
96 |
|
71 |
|
97 |
namespace CPPU_CURRENT_NAMESPACE |
72 |
namespace |
98 |
{ |
73 |
{ |
99 |
|
|
|
100 |
//================================================================================================== |
101 |
rtl_StandardModuleCount g_moduleCount = MODULE_COUNT_INIT; |
102 |
|
103 |
//================================================================================================== |
74 |
//================================================================================================== |
104 |
static typelib_TypeClass cpp2uno_call( |
75 |
static typelib_TypeClass cpp2uno_call( |
105 |
cppu_cppInterfaceProxy * pThis, |
76 |
bridges::cpp_uno::shared::CppInterfaceProxy * pThis, |
106 |
const typelib_TypeDescription * pMemberTypeDescr, |
77 |
const typelib_TypeDescription * pMemberTypeDescr, |
107 |
typelib_TypeDescriptionReference * pReturnTypeRef, // 0 indicates void return |
78 |
typelib_TypeDescriptionReference * pReturnTypeRef, // 0 indicates void return |
108 |
sal_Int32 nParams, typelib_MethodParameter * pParams, |
79 |
sal_Int32 nParams, typelib_MethodParameter * pParams, |
Lines 122-137
Link Here
|
122 |
|
93 |
|
123 |
if (pReturnTypeDescr) |
94 |
if (pReturnTypeDescr) |
124 |
{ |
95 |
{ |
125 |
if (cppu_isSimpleType( pReturnTypeDescr )) |
96 |
if (bridges::cpp_uno::shared::isSimpleType( pReturnTypeDescr )) |
|
|
97 |
{ |
126 |
pUnoReturn = pRegisterReturn; // direct way for simple types |
98 |
pUnoReturn = pRegisterReturn; // direct way for simple types |
|
|
99 |
} |
127 |
else // complex return via ptr (pCppReturn) |
100 |
else // complex return via ptr (pCppReturn) |
128 |
{ |
101 |
{ |
129 |
pCppReturn = *(void**)pCppStack; |
102 |
pCppReturn = *(void**)pCppStack; |
130 |
|
103 |
pCppStack += sizeof( void* ); |
131 |
pUnoReturn = (cppu_relatesToInterface( pReturnTypeDescr ) |
104 |
pUnoReturn = (bridges::cpp_uno::shared::relatesToInterfaceType( |
|
|
105 |
pReturnTypeDescr ) |
132 |
? alloca( pReturnTypeDescr->nSize ) |
106 |
? alloca( pReturnTypeDescr->nSize ) |
133 |
: pCppReturn); // direct way |
107 |
: pCppReturn); // direct way |
134 |
pCppStack += sizeof( void* ); |
108 |
|
135 |
} |
109 |
} |
136 |
} |
110 |
} |
137 |
// pop this |
111 |
// pop this |
Lines 155-164
Link Here
|
155 |
typelib_TypeDescription * pParamTypeDescr = 0; |
129 |
typelib_TypeDescription * pParamTypeDescr = 0; |
156 |
TYPELIB_DANGER_GET( &pParamTypeDescr, rParam.pTypeRef ); |
130 |
TYPELIB_DANGER_GET( &pParamTypeDescr, rParam.pTypeRef ); |
157 |
|
131 |
|
158 |
if (!rParam.bOut && cppu_isSimpleType( pParamTypeDescr )) // value |
132 |
if (!rParam.bOut && bridges::cpp_uno::shared::isSimpleType( pParamTypeDescr )) // value |
159 |
{ |
133 |
{ |
160 |
pCppArgs[nPos] = pUnoArgs[nPos] = |
134 |
pCppArgs[nPos] = pCppStack; |
161 |
adjustPointer( pCppStack, pParamTypeDescr ); |
135 |
pUnoArgs[nPos] = pCppStack; |
162 |
switch (pParamTypeDescr->eTypeClass) |
136 |
switch (pParamTypeDescr->eTypeClass) |
163 |
{ |
137 |
{ |
164 |
case typelib_TypeClass_HYPER: |
138 |
case typelib_TypeClass_HYPER: |
Lines 195-205
Link Here
|
195 |
ppTempParamTypeDescr[nTempIndizes++] = pParamTypeDescr; |
169 |
ppTempParamTypeDescr[nTempIndizes++] = pParamTypeDescr; |
196 |
} |
170 |
} |
197 |
// is in/inout |
171 |
// is in/inout |
198 |
else if (cppu_relatesToInterface( pParamTypeDescr )) |
172 |
else if (bridges::cpp_uno::shared::relatesToInterfaceType( |
|
|
173 |
pParamTypeDescr )) |
199 |
{ |
174 |
{ |
200 |
uno_copyAndConvertData( pUnoArgs[nPos] = alloca( pParamTypeDescr->nSize ), |
175 |
uno_copyAndConvertData( pUnoArgs[nPos] = alloca( pParamTypeDescr->nSize ), |
201 |
*(void **)pCppStack, pParamTypeDescr, |
176 |
*(void **)pCppStack, pParamTypeDescr, |
202 |
&pThis->pBridge->aCpp2Uno ); |
177 |
pThis->getBridge()->getCpp2Uno() ); |
203 |
pTempIndizes[nTempIndizes] = nPos; // has to be reconverted |
178 |
pTempIndizes[nTempIndizes] = nPos; // has to be reconverted |
204 |
// will be released at reconversion |
179 |
// will be released at reconversion |
205 |
ppTempParamTypeDescr[nTempIndizes++] = pParamTypeDescr; |
180 |
ppTempParamTypeDescr[nTempIndizes++] = pParamTypeDescr; |
Lines 219-226
Link Here
|
219 |
uno_Any * pUnoExc = &aUnoExc; |
194 |
uno_Any * pUnoExc = &aUnoExc; |
220 |
|
195 |
|
221 |
// invoke uno dispatch call |
196 |
// invoke uno dispatch call |
222 |
(*pThis->pUnoI->pDispatcher)( pThis->pUnoI, pMemberTypeDescr, pUnoReturn, pUnoArgs, &pUnoExc ); |
197 |
(*pThis->getUnoI()->pDispatcher)(pThis->getUnoI(), pMemberTypeDescr, pUnoReturn, pUnoArgs, &pUnoExc ); |
223 |
|
|
|
224 |
// in case an exception occured... |
198 |
// in case an exception occured... |
225 |
if (pUnoExc) |
199 |
if (pUnoExc) |
226 |
{ |
200 |
{ |
Lines 235-243
Link Here
|
235 |
} |
209 |
} |
236 |
if (pReturnTypeDescr) |
210 |
if (pReturnTypeDescr) |
237 |
TYPELIB_DANGER_RELEASE( pReturnTypeDescr ); |
211 |
TYPELIB_DANGER_RELEASE( pReturnTypeDescr ); |
238 |
|
212 |
CPPU_CURRENT_NAMESPACE::raiseException( |
239 |
raiseException( &aUnoExc, &pThis->pBridge->aUno2Cpp ); // has to destruct the any |
213 |
&aUnoExc, pThis->getBridge()->getUno2Cpp() ); |
240 |
// is here for dummy |
214 |
// has to destruct the any |
|
|
215 |
// is here for dummy |
241 |
return typelib_TypeClass_VOID; |
216 |
return typelib_TypeClass_VOID; |
242 |
} |
217 |
} |
243 |
else // else no exception occured... |
218 |
else // else no exception occured... |
Lines 253-259
Link Here
|
253 |
// convert and assign |
228 |
// convert and assign |
254 |
uno_destructData( pCppArgs[nIndex], pParamTypeDescr, cpp_release ); |
229 |
uno_destructData( pCppArgs[nIndex], pParamTypeDescr, cpp_release ); |
255 |
uno_copyAndConvertData( pCppArgs[nIndex], pUnoArgs[nIndex], pParamTypeDescr, |
230 |
uno_copyAndConvertData( pCppArgs[nIndex], pUnoArgs[nIndex], pParamTypeDescr, |
256 |
&pThis->pBridge->aUno2Cpp ); |
231 |
pThis->getBridge()->getUno2Cpp() ); |
257 |
} |
232 |
} |
258 |
// destroy temp uno param |
233 |
// destroy temp uno param |
259 |
uno_destructData( pUnoArgs[nIndex], pParamTypeDescr, 0 ); |
234 |
uno_destructData( pUnoArgs[nIndex], pParamTypeDescr, 0 ); |
Lines 266-272
Link Here
|
266 |
if (pUnoReturn != pCppReturn) // needs reconversion |
241 |
if (pUnoReturn != pCppReturn) // needs reconversion |
267 |
{ |
242 |
{ |
268 |
uno_copyAndConvertData( pCppReturn, pUnoReturn, pReturnTypeDescr, |
243 |
uno_copyAndConvertData( pCppReturn, pUnoReturn, pReturnTypeDescr, |
269 |
&pThis->pBridge->aUno2Cpp ); |
244 |
pThis->getBridge()->getUno2Cpp() ); |
270 |
// destroy temp uno return |
245 |
// destroy temp uno return |
271 |
uno_destructData( pUnoReturn, pReturnTypeDescr, 0 ); |
246 |
uno_destructData( pUnoReturn, pReturnTypeDescr, 0 ); |
272 |
} |
247 |
} |
Lines 287-337
Link Here
|
287 |
|
262 |
|
288 |
//================================================================================================== |
263 |
//================================================================================================== |
289 |
static typelib_TypeClass cpp_mediate( |
264 |
static typelib_TypeClass cpp_mediate( |
290 |
sal_Int32 nVtableCall, |
265 |
int nFunctionIndex, |
291 |
void ** pCallStack, |
266 |
void ** pCallStack, |
292 |
sal_Int64 * pRegisterReturn /* space for register return */ ) |
267 |
int nVtableOffset, |
|
|
268 |
sal_Int64 * pRegisterReturn /* space for register return */ ) |
293 |
{ |
269 |
{ |
294 |
OSL_ENSURE( sizeof(sal_Int32)==sizeof(void *), "### unexpected!" ); |
270 |
OSL_ENSURE( sizeof(sal_Int32)==sizeof(void *), "### unexpected!" ); |
295 |
|
|
|
296 |
// pCallStack: this, params |
271 |
// pCallStack: this, params |
297 |
// eventual [ret*] lies at pCallStack -1 |
272 |
// eventual [ret*] lies at pCallStack -1 |
298 |
// so count down pCallStack by one to keep it simple |
273 |
// so count down pCallStack by one to keep it simple |
299 |
// _this_ ptr is patched cppu_XInterfaceProxy object |
274 |
void * pThis; |
300 |
cppu_cppInterfaceProxy * pCppI = NULL; |
275 |
if (nFunctionIndex & 0x80000000) |
301 |
pCppI = (cppu_cppInterfaceProxy *)(XInterface *)*pCallStack; |
|
|
302 |
if( nVtableCall & 0x80000000 ) |
303 |
{ |
276 |
{ |
304 |
pCallStack--; |
277 |
nFunctionIndex &= 0x7FFFFFFF; |
305 |
nVtableCall &= 0x7fffffff; |
278 |
pThis=pCallStack[1]; |
306 |
} |
279 |
} |
|
|
280 |
else |
281 |
{ |
282 |
pThis=pCallStack[0]; |
283 |
} |
284 |
pThis = static_cast< char *>(pThis) - nVtableOffset; |
285 |
bridges::cpp_uno::shared::CppInterfaceProxy * pCppI |
286 |
= bridges::cpp_uno::shared::CppInterfaceProxy::castInterfaceToProxy( |
287 |
pThis); |
288 |
typelib_InterfaceTypeDescription * pTypeDescr = pCppI->getTypeDescr(); |
307 |
|
289 |
|
308 |
typelib_InterfaceTypeDescription * pTypeDescr = pCppI->pTypeDescr; |
290 |
OSL_ENSURE( nFunctionIndex < pTypeDescr->nMapFunctionIndexToMemberIndex, |
309 |
|
|
|
310 |
OSL_ENSURE( nVtableCall < pTypeDescr->nMapFunctionIndexToMemberIndex, |
311 |
"### illegal vtable index!" ); |
291 |
"### illegal vtable index!" ); |
312 |
if (nVtableCall >= pTypeDescr->nMapFunctionIndexToMemberIndex) |
292 |
if (nFunctionIndex >= pTypeDescr->nMapFunctionIndexToMemberIndex) |
313 |
{ |
293 |
{ |
314 |
throw RuntimeException( OUString::createFromAscii("illegal vtable index!"), (XInterface *)pCppI ); |
294 |
throw RuntimeException( rtl::OUString::createFromAscii("illegal vtable index!"), (XInterface *)pCppI ); |
315 |
} |
295 |
} |
316 |
|
296 |
|
317 |
// determine called method |
297 |
// determine called method |
318 |
OSL_ENSURE( nVtableCall < pTypeDescr->nMapFunctionIndexToMemberIndex, "### illegal vtable index!" ); |
298 |
sal_Int32 nMemberPos = pTypeDescr->pMapFunctionIndexToMemberIndex[nFunctionIndex]; |
319 |
sal_Int32 nMemberPos = pTypeDescr->pMapFunctionIndexToMemberIndex[nVtableCall]; |
|
|
320 |
OSL_ENSURE( nMemberPos < pTypeDescr->nAllMembers, "### illegal member index!" ); |
299 |
OSL_ENSURE( nMemberPos < pTypeDescr->nAllMembers, "### illegal member index!" ); |
321 |
|
|
|
322 |
TypeDescription aMemberDescr( pTypeDescr->ppAllMembers[nMemberPos] ); |
300 |
TypeDescription aMemberDescr( pTypeDescr->ppAllMembers[nMemberPos] ); |
323 |
|
301 |
//#if defined BRIDGES_DEBUG |
324 |
#if defined BRIDGES_DEBUG |
302 |
// OString cstr( OUStringToOString( aMemberDescr.get()->pTypeName, RTL_TEXTENCODING_ASCII_US ) ); |
325 |
OString cstr( OUStringToOString( aMemberDescr.get()->pTypeName, RTL_TEXTENCODING_ASCII_US ) ); |
303 |
// fprintf( stderr, "calling %s, nVtableCall=%d\n", cstr.getStr(), nVtableCall ); |
326 |
fprintf( stderr, "calling %s, nVtableCall=%d\n", cstr.getStr(), nVtableCall ); |
304 |
//#endif |
327 |
#endif |
|
|
328 |
|
305 |
|
329 |
typelib_TypeClass eRet; |
306 |
typelib_TypeClass eRet; |
330 |
switch (aMemberDescr.get()->eTypeClass) |
307 |
switch (aMemberDescr.get()->eTypeClass) |
331 |
{ |
308 |
{ |
332 |
case typelib_TypeClass_INTERFACE_ATTRIBUTE: |
309 |
case typelib_TypeClass_INTERFACE_ATTRIBUTE: |
333 |
{ |
310 |
{ |
334 |
if (pTypeDescr->pMapMemberIndexToFunctionIndex[nMemberPos] == nVtableCall) |
311 |
if (pTypeDescr->pMapMemberIndexToFunctionIndex[nMemberPos] == nFunctionIndex) |
335 |
{ |
312 |
{ |
336 |
// is GET method |
313 |
// is GET method |
337 |
eRet = cpp2uno_call( |
314 |
eRet = cpp2uno_call( |
Lines 360-366
Link Here
|
360 |
case typelib_TypeClass_INTERFACE_METHOD: |
337 |
case typelib_TypeClass_INTERFACE_METHOD: |
361 |
{ |
338 |
{ |
362 |
// is METHOD |
339 |
// is METHOD |
363 |
switch (nVtableCall) |
340 |
switch (nFunctionIndex) |
364 |
{ |
341 |
{ |
365 |
case 1: // acquire() |
342 |
case 1: // acquire() |
366 |
pCppI->acquireProxy(); // non virtual call! |
343 |
pCppI->acquireProxy(); // non virtual call! |
Lines 377-385
Link Here
|
377 |
if (pTD) |
354 |
if (pTD) |
378 |
{ |
355 |
{ |
379 |
XInterface * pInterface = 0; |
356 |
XInterface * pInterface = 0; |
380 |
(*pCppI->pBridge->pCppEnv->getRegisteredInterface)( |
357 |
(*pCppI->getBridge()->getCppEnv()->getRegisteredInterface)( |
381 |
pCppI->pBridge->pCppEnv, |
358 |
pCppI->getBridge()->getCppEnv(), |
382 |
(void **)&pInterface, pCppI->oid.pData, (typelib_InterfaceTypeDescription *)pTD ); |
359 |
(void **)&pInterface, pCppI->getOid().pData, |
|
|
360 |
(typelib_InterfaceTypeDescription *)pTD ); |
383 |
|
361 |
|
384 |
if (pInterface) |
362 |
if (pInterface) |
385 |
{ |
363 |
{ |
Lines 405-477
Link Here
|
405 |
} |
383 |
} |
406 |
break; |
384 |
break; |
407 |
} |
385 |
} |
408 |
default: |
386 |
// default: |
409 |
{ |
387 |
// { |
410 |
throw RuntimeException( OUString::createFromAscii("no member description found!"), (XInterface *)pCppI ); |
388 |
// throw RuntimeException( |
411 |
// is here for dummy |
389 |
// rtl::OUString::createFromAscii("no member description found!"), |
412 |
eRet = typelib_TypeClass_VOID; |
390 |
// (XInterface *)pThis ); |
413 |
} |
391 |
// // is here for dummy |
|
|
392 |
// eRet = typelib_TypeClass_VOID; |
393 |
// } |
414 |
} |
394 |
} |
415 |
|
|
|
416 |
return eRet; |
395 |
return eRet; |
417 |
} |
396 |
} |
418 |
|
397 |
|
419 |
//================================================================================================== |
|
|
420 |
class MediateClassData |
421 |
{ |
422 |
public: |
423 |
struct ClassDataBuffer |
424 |
{ |
425 |
void* m_pVTable; |
426 |
|
427 |
~ClassDataBuffer(); |
428 |
}; |
429 |
private: |
430 |
|
431 |
map< OUString, ClassDataBuffer* > m_aClassData; |
432 |
Mutex m_aMutex; |
433 |
|
434 |
void createVTable( ClassDataBuffer*, typelib_InterfaceTypeDescription* ); |
435 |
public: |
436 |
const ClassDataBuffer* getClassData( typelib_InterfaceTypeDescription* ); |
437 |
|
438 |
MediateClassData() {} |
439 |
~MediateClassData(); |
440 |
}; |
441 |
//__________________________________________________________________________________________________ |
442 |
MediateClassData::ClassDataBuffer::~ClassDataBuffer() |
443 |
{ |
444 |
delete m_pVTable; |
445 |
} |
446 |
|
447 |
//__________________________________________________________________________________________________ |
448 |
MediateClassData::~MediateClassData() |
449 |
{ |
450 |
TRACE( "> calling ~MediateClassData(): freeing mediate vtables... <\n" ); |
451 |
|
452 |
// this MUST be the absolute last one which is called! |
453 |
for ( map< OUString, ClassDataBuffer* >::iterator iPos( m_aClassData.begin() ); iPos != m_aClassData.end(); ++iPos ) |
454 |
{ |
455 |
// todo |
456 |
// delete (*iPos).second; |
457 |
} |
458 |
} |
459 |
|
460 |
//__________________________________________________________________________________________________ |
461 |
|
462 |
const MediateClassData::ClassDataBuffer* MediateClassData::getClassData( typelib_InterfaceTypeDescription* pType ) |
463 |
{ |
464 |
MutexGuard aGuard( m_aMutex ); |
465 |
|
466 |
map< OUString, ClassDataBuffer* >::iterator element = m_aClassData.find( pType->aBase.pTypeName ); |
467 |
if( element != m_aClassData.end() ) |
468 |
return (*element).second; |
469 |
|
470 |
ClassDataBuffer* pBuffer = new ClassDataBuffer(); |
471 |
createVTable( pBuffer, pType ); |
472 |
m_aClassData[ pType->aBase.pTypeName ] = pBuffer; |
473 |
return pBuffer; |
474 |
} |
475 |
|
398 |
|
476 |
|
399 |
|
477 |
//================================================================================================== |
400 |
//================================================================================================== |
Lines 479-507
Link Here
|
479 |
* is called on incoming vtable calls |
402 |
* is called on incoming vtable calls |
480 |
* (called by asm snippets) |
403 |
* (called by asm snippets) |
481 |
*/ |
404 |
*/ |
482 |
static void cpp_vtable_call() |
405 |
static void cpp_vtable_call() |
483 |
{ |
406 |
{ |
484 |
int nTableEntry; |
407 |
|
485 |
void** pCallStack; |
408 |
int functionIndex; |
|
|
409 |
void** pCallStack; |
410 |
int vtableOffset; |
486 |
volatile sal_Int64 nRegReturn; |
411 |
volatile sal_Int64 nRegReturn; |
487 |
|
|
|
488 |
// nTableEntry and pCallStack are delivered in registers as usual |
412 |
// nTableEntry and pCallStack are delivered in registers as usual |
489 |
// but cpp_vtable_call is declared void. |
413 |
// but cpp_vtable_call is declared void. |
490 |
// the reason is that this way the compiler won't clobber the |
414 |
// the reason is that this way the compiler won't clobber the |
491 |
// call stack prepared by the assembler snippet to save its input |
415 |
// call stack prepared by the assembler snippet to save its input |
492 |
// registers |
416 |
// registers |
493 |
// also restore %i2 here which was clobbered to jump here |
417 |
// also restore %i3 here which was clobbered to jump here |
494 |
__asm__( "st %%i0, %0\n\t" |
|
|
495 |
"st %%i1, %1\n\t" |
496 |
"ld [%%fp+68], %%i0\n\t" |
497 |
"ld [%%fp+72], %%i1\n\t" |
498 |
"ld [%%fp+76], %%i2\n\t" |
499 |
: : "m"(nTableEntry), "m"(pCallStack) ); |
500 |
|
418 |
|
501 |
sal_Bool bComplex = nTableEntry & 0x80000000 ? sal_True : sal_False; |
419 |
__asm__("st %%i0, %0\n\t" |
|
|
420 |
"st %%i1, %1\n\t" |
421 |
"ld [%%fp+68], %%i0\n\t" |
422 |
"ld [%%fp+72], %%i1\n\t" |
423 |
"ld [%%fp+76], %%i2\n\t" |
424 |
"ld [%%fp+80], %%i3\n\t" |
425 |
: : "m"(functionIndex), "m"(pCallStack), "m"(vtableOffset)); |
426 |
|
427 |
|
428 |
sal_Bool bComplex = functionIndex & 0x80000000 ? sal_True : sal_False; |
502 |
|
429 |
|
503 |
typelib_TypeClass aType = |
430 |
typelib_TypeClass aType = |
504 |
cpp_mediate( nTableEntry, pCallStack+17, (sal_Int64*)&nRegReturn ); |
431 |
cpp_mediate( functionIndex, pCallStack, vtableOffset, (sal_Int64*)&nRegReturn ); |
505 |
|
432 |
|
506 |
switch( aType ) |
433 |
switch( aType ) |
507 |
{ |
434 |
{ |
Lines 554-691
Link Here
|
554 |
} |
481 |
} |
555 |
|
482 |
|
556 |
} |
483 |
} |
|
|
484 |
|
557 |
//__________________________________________________________________________________________________ |
485 |
//__________________________________________________________________________________________________ |
558 |
|
486 |
|
559 |
void MediateClassData::createVTable( ClassDataBuffer* pBuffer, typelib_InterfaceTypeDescription* pType ) |
487 |
int const codeSnippetSize = 56; |
560 |
{ |
488 |
unsigned char * codeSnippet( |
561 |
// get all member functions |
489 |
unsigned char * code, sal_Int32 functionIndex, sal_Int32 vtableOffset, |
562 |
list< sal_Bool > aComplexReturn; |
490 |
bool simpleRetType) |
563 |
|
491 |
{ |
564 |
for( int n = 0; n < pType->nAllMembers; n++ ) |
492 |
sal_uInt32 index = functionIndex; |
565 |
{ |
493 |
if (!simpleRetType) { |
566 |
typelib_TypeDescription* pMember = NULL; |
494 |
index |= 0x80000000; |
567 |
TYPELIB_DANGER_GET( &pMember, pType->ppAllMembers[n] ); |
495 |
} |
568 |
if( pMember->eTypeClass == typelib_TypeClass_INTERFACE_ATTRIBUTE ) |
496 |
unsigned int * p = reinterpret_cast< unsigned int * >(code); |
569 |
{ |
497 |
OSL_ASSERT(sizeof (unsigned int) == 4); |
570 |
typelib_TypeDescription * pRetTD = 0; |
498 |
// st %o0, [%sp+68]: |
571 |
TYPELIB_DANGER_GET( &pRetTD, ((typelib_InterfaceAttributeTypeDescription *)pMember)->pAttributeTypeRef ); |
499 |
*p++ = 0xD023A044; |
572 |
// get method |
500 |
// st %o1, [%sp+72]: |
573 |
aComplexReturn.push_back( !cppu_isSimpleType( pRetTD ) ); |
501 |
*p++ = 0xD223A048; |
574 |
// set method |
502 |
// st %o2, [%sp+76]: |
575 |
if( ! ((typelib_InterfaceAttributeTypeDescription*)pMember)->bReadOnly ) |
503 |
*p++ = 0xD423A04C; |
576 |
aComplexReturn.push_back( sal_False ); |
504 |
// st %o3, [%sp+80]: |
577 |
TYPELIB_DANGER_RELEASE( pRetTD ); |
505 |
*p++ = 0xD623A050; |
578 |
} |
506 |
// st %o4, [%sp+84]: |
579 |
else |
507 |
*p++ = 0xD823A054; |
580 |
{ |
508 |
// st %o5, [%sp+88]: |
581 |
typelib_TypeDescription * pRetTD = 0; |
509 |
*p++ = 0xDA23A058; |
582 |
TYPELIB_DANGER_GET( &pRetTD, ((typelib_InterfaceMethodTypeDescription *)pMember)->pReturnTypeRef ); |
510 |
// sethi %hi(index), %o0: |
583 |
aComplexReturn.push_back( !cppu_isSimpleType( pRetTD ) ); |
511 |
*p++ = 0x11000000 | (index >> 10); |
584 |
TYPELIB_DANGER_RELEASE( pRetTD ); |
512 |
// or %o0, %lo(index), %o0: |
585 |
} |
513 |
*p++ = 0x90122000 | (index & 0x3FF); |
586 |
TYPELIB_DANGER_RELEASE( pMember ); |
514 |
// sethi %hi(vtableOffset), %o2: |
587 |
} |
515 |
*p++ = 0x15000000 | (vtableOffset >> 10); |
588 |
|
516 |
// or %o2, %lo(vtableOffset), %o2: |
589 |
int nSize = aComplexReturn.size(); |
517 |
*p++ = 0x9412A000 | (vtableOffset & 0x3FF); |
590 |
const int nSnippetSize = 64; |
518 |
// sethi %hi(cpp_vtable_call), %o3: |
591 |
char * pSpace = (char *)rtl_allocateMemory( (2*(nSize+2)*sizeof(void *)) + (nSize*nSnippetSize) ); |
519 |
*p++ = 0x17000000 | (reinterpret_cast< unsigned int >(cpp_vtable_call) >> 10); |
592 |
pBuffer->m_pVTable = (void*)pSpace; |
520 |
// or %o3, %lo(cpp_vtable_call), %o3: |
593 |
|
521 |
*p++ = 0x9612E000 | (reinterpret_cast< unsigned int >(cpp_vtable_call) & 0x3FF); |
594 |
char * pCode = pSpace + (2*(nSize+2)*sizeof(void *)); |
522 |
// jmpl %o3, %g0: |
595 |
void ** pvft = (void **)pSpace; |
523 |
*p++ = 0x81C2C000; |
596 |
|
524 |
// mov %sp, %o1: |
597 |
// setup vft and code |
525 |
*p++ = 0x9210000E; |
598 |
for ( sal_Int32 nPos = 0; nPos < nSize; ++nPos ) |
526 |
OSL_ASSERT( |
599 |
{ |
527 |
reinterpret_cast< unsigned char * >(p) - code <= codeSnippetSize); |
600 |
unsigned long * codeSnip = (unsigned long *)(pCode + (nPos*nSnippetSize)); |
528 |
return code + codeSnippetSize; |
601 |
pvft[ nPos ] = codeSnip; |
529 |
} |
602 |
unsigned long nTablePos = nPos; |
530 |
|
603 |
sal_Bool bComplex = aComplexReturn.front(); |
531 |
} |
604 |
if( bComplex ) |
532 |
|
605 |
nTablePos |= 0x80000000; |
533 |
void ** bridges::cpp_uno::shared::VtableFactory::mapBlockToVtable(char * block) |
606 |
aComplexReturn.pop_front(); |
534 |
{ |
607 |
|
535 |
return reinterpret_cast< void ** >(block) + 1; |
608 |
/* |
536 |
} |
609 |
* generate this code |
537 |
|
610 |
* |
538 |
char * bridges::cpp_uno::shared::VtableFactory::createBlock( |
611 |
* st %o0, [%sp+68] save registers |
539 |
sal_Int32 slotCount, void *** slots) |
612 |
* st %o1, [%sp+72] |
540 |
{ |
613 |
* st %o2, [%sp+76] |
541 |
char * block = new char[ |
614 |
* st %o3, [%sp+80] |
542 |
(slotCount + 3) * sizeof (void *) + slotCount * codeSnippetSize]; |
615 |
* st %o4, [%sp+84] |
543 |
*slots = mapBlockToVtable(block) + 2; |
616 |
* st %o5, [%sp+88] |
544 |
(*slots)[-3] = 0; //RTTI |
617 |
* |
545 |
(*slots)[-2] = 0; //null |
618 |
* mov %sp, %o1 prepare stack ptr for cpp_vtable_call |
546 |
(*slots)[-1] = 0; //destructor |
619 |
* sethi %hi( nTablePos ), %o0 prepare table entry |
547 |
return block; |
620 |
* or %lo( nTablePos ), %o0 (on complex return set high bit |
548 |
} |
621 |
* |
549 |
|
622 |
* sethi $hi( cpp_vtable_call ), %l0 |
550 |
unsigned char * bridges::cpp_uno::shared::VtableFactory::addLocalFunctions( |
623 |
* or %l0, %lo( cpp_vtable_call ), %l0 |
551 |
void ** slots, unsigned char * code, |
624 |
* jmp %l0 |
552 |
typelib_InterfaceTypeDescription const * type, sal_Int32 functionOffset, |
625 |
* nop |
553 |
sal_Int32 functionCount, sal_Int32 vtableOffset) |
626 |
* |
554 |
{ |
627 |
* Note: %o0 should be restored by cpp_vtable_call if void returned |
555 |
for (sal_Int32 i = 0; i < type->nMembers; ++i) { |
628 |
* %o1 should be restored if not hyper returned |
556 |
typelib_TypeDescription * member = 0; |
629 |
* %o2 must be restored |
557 |
TYPELIB_DANGER_GET(&member, type->ppMembers[i]); |
630 |
* |
558 |
OSL_ASSERT(member != 0); |
631 |
*/ |
559 |
switch (member->eTypeClass) { |
632 |
*codeSnip++ = 0xd023a044; |
560 |
case typelib_TypeClass_INTERFACE_ATTRIBUTE: |
633 |
*codeSnip++ = 0xd223a048; |
561 |
// Getter: |
634 |
*codeSnip++ = 0xd423a04c; |
562 |
*slots++ = code; |
635 |
*codeSnip++ = 0xd623a050; |
563 |
code = codeSnippet( |
636 |
*codeSnip++ = 0xd823a054; |
564 |
code, functionOffset++, vtableOffset, |
637 |
*codeSnip++ = 0xda23a058; |
565 |
bridges::cpp_uno::shared::isSimpleType( |
638 |
|
566 |
reinterpret_cast< |
639 |
*codeSnip++ = 0x9210000e; |
567 |
typelib_InterfaceAttributeTypeDescription * >( |
640 |
*codeSnip++ = 0x11000000 | ( nTablePos >> 10 ); |
568 |
member)->pAttributeTypeRef)); |
641 |
*codeSnip++ = 0x90122000 | ( nTablePos & 1023 ); |
569 |
// Setter: |
642 |
*codeSnip++ = 0x15000000 | ( ((unsigned long)cpp_vtable_call) >> 10 ); |
570 |
if (!reinterpret_cast< |
643 |
*codeSnip++ = 0x9412a000 | ( ((unsigned long)cpp_vtable_call) & 1023 ); |
571 |
typelib_InterfaceAttributeTypeDescription * >( |
644 |
*codeSnip++ = 0x81c28000; |
572 |
member)->bReadOnly) |
645 |
*codeSnip++ = 0x01000000; |
573 |
{ |
646 |
} |
574 |
*slots++ = code; |
647 |
} |
575 |
code = codeSnippet(code, functionOffset++, vtableOffset, true); |
|
|
576 |
} |
577 |
break; |
648 |
|
578 |
|
649 |
//================================================================================================== |
579 |
case typelib_TypeClass_INTERFACE_METHOD: |
650 |
void SAL_CALL cppu_cppInterfaceProxy_patchVtable( |
580 |
*slots++ = code; |
651 |
XInterface * pCppI, typelib_InterfaceTypeDescription * pTypeDescr ) throw () |
581 |
code = codeSnippet( |
652 |
{ |
582 |
code, functionOffset++, vtableOffset, |
653 |
static MediateClassData * s_pMediateClassData = 0; |
583 |
bridges::cpp_uno::shared::isSimpleType( |
654 |
if (! s_pMediateClassData) |
584 |
reinterpret_cast< |
655 |
{ |
585 |
typelib_InterfaceMethodTypeDescription * >( |
656 |
MutexGuard aGuard( Mutex::getGlobalMutex() ); |
586 |
member)->pReturnTypeRef)); |
657 |
if (! s_pMediateClassData) |
587 |
break; |
658 |
{ |
588 |
|
659 |
#ifdef LEAK_STATIC_DATA |
589 |
default: |
660 |
s_pMediateClassData = new MediateClassData(); |
590 |
OSL_ASSERT(false); |
661 |
#else |
591 |
break; |
662 |
static MediateClassData s_aMediateClassData; |
592 |
} |
663 |
s_pMediateClassData = &s_aMediateClassData; |
593 |
TYPELIB_DANGER_RELEASE(member); |
664 |
#endif |
594 |
} |
665 |
} |
595 |
return code; |
|
|
596 |
} |
597 |
|
598 |
void bridges::cpp_uno::shared::VtableFactory::flushCode( |
599 |
unsigned char const *, unsigned char const *) |
600 |
{ |
601 |
//TODO: IZ 25819 flush the instruction cache (there probably is OS support for this) |
666 |
} |
602 |
} |
667 |
*(const void **)pCppI = s_pMediateClassData->getClassData( pTypeDescr )->m_pVTable; |
|
|
668 |
} |
669 |
|
670 |
} |
671 |
|
672 |
//################################################################################################## |
673 |
extern "C" SAL_DLLEXPORT sal_Bool SAL_CALL component_canUnload( TimeValue * pTime ) |
674 |
SAL_THROW_EXTERN_C() |
675 |
{ |
676 |
return CPPU_CURRENT_NAMESPACE::g_moduleCount.canUnload( &CPPU_CURRENT_NAMESPACE::g_moduleCount, pTime ); |
677 |
} |
678 |
//################################################################################################## |
679 |
extern "C" SAL_DLLEXPORT void SAL_CALL uno_initEnvironment( uno_Environment * pCppEnv ) |
680 |
SAL_THROW_EXTERN_C() |
681 |
{ |
682 |
CPPU_CURRENT_NAMESPACE::cppu_cppenv_initEnvironment( pCppEnv ); |
683 |
} |
684 |
//################################################################################################## |
685 |
extern "C" SAL_DLLEXPORT void SAL_CALL uno_ext_getMapping( |
686 |
uno_Mapping ** ppMapping, uno_Environment * pFrom, uno_Environment * pTo ) |
687 |
SAL_THROW_EXTERN_C() |
688 |
{ |
689 |
CPPU_CURRENT_NAMESPACE::cppu_ext_getMapping( ppMapping, pFrom, pTo ); |
690 |
} |
691 |
|