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