Lines 2-10
Link Here
|
2 |
* |
2 |
* |
3 |
* $RCSfile: cpp2uno.cxx,v $ |
3 |
* $RCSfile: cpp2uno.cxx,v $ |
4 |
* |
4 |
* |
5 |
* $Revision: 1.2 $ |
5 |
* $Revision: 1.2.62.1 $ |
6 |
* |
6 |
* |
7 |
* last change: $Author: hr $ $Date: 2003/04/28 16:28:42 $ |
7 |
* last change: $Author: waratah $ $Date: 2003/12/27 09:50:06 $ |
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 63-108
Link Here
|
63 |
// #define TRACE(x) OSL_TRACE(x) |
63 |
// #define TRACE(x) OSL_TRACE(x) |
64 |
#define TRACE(x) |
64 |
#define TRACE(x) |
65 |
|
65 |
|
66 |
#include <malloc.h> |
|
|
67 |
#include <list> |
66 |
#include <list> |
68 |
#include <map> |
67 |
#include <map> |
69 |
#include <typeinfo> |
68 |
#include <typeinfo> |
70 |
#ifndef _RTL_ALLOC_H_ |
69 |
#include <com/sun/star/uno/genfunc.hxx> |
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_ |
70 |
#ifndef _TYPELIB_TYPEDESCRIPTION_HXX_ |
78 |
#include <typelib/typedescription.hxx> |
71 |
#include <typelib/typedescription.hxx> |
79 |
#endif |
72 |
#endif |
80 |
#ifndef _UNO_DATA_H_ |
73 |
#ifndef _UNO_DATA_H_ |
81 |
#include <uno/data.h> |
74 |
#include <uno/data.h> |
82 |
#endif |
75 |
#endif |
83 |
#ifndef _BRIDGES_CPP_UNO_BRIDGE_HXX_ |
76 |
#include "bridges/cpp_uno/shared/bridge.hxx" |
84 |
#include <bridges/cpp_uno/bridge.hxx> |
77 |
#include "bridges/cpp_uno/shared/cppinterfaceproxy.hxx" |
85 |
#endif |
78 |
#include "bridges/cpp_uno/shared/types.hxx" |
86 |
#ifndef _BRIDGES_CPP_UNO_TYPE_MISC_HXX_ |
79 |
#include "bridges/cpp_uno/shared/vtablefactory.hxx" |
87 |
#include <bridges/cpp_uno/type_misc.hxx> |
|
|
88 |
#endif |
89 |
|
90 |
#include "share.hxx" |
80 |
#include "share.hxx" |
91 |
|
81 |
|
92 |
using namespace com::sun::star::uno; |
82 |
using namespace com::sun::star::uno; |
93 |
using namespace std; |
83 |
using namespace std; |
94 |
using namespace osl; |
|
|
95 |
using namespace rtl; |
84 |
using namespace rtl; |
96 |
|
85 |
|
97 |
namespace CPPU_CURRENT_NAMESPACE |
86 |
namespace |
98 |
{ |
87 |
{ |
99 |
|
88 |
|
100 |
//================================================================================================== |
89 |
//================================================================================================== |
101 |
rtl_StandardModuleCount g_moduleCount = MODULE_COUNT_INIT; |
|
|
102 |
|
103 |
//================================================================================================== |
104 |
static typelib_TypeClass cpp2uno_call( |
90 |
static typelib_TypeClass cpp2uno_call( |
105 |
cppu_cppInterfaceProxy * pThis, |
91 |
bridges::cpp_uno::shared::CppInterfaceProxy * pThis, |
106 |
const typelib_TypeDescription * pMemberTypeDescr, |
92 |
const typelib_TypeDescription * pMemberTypeDescr, |
107 |
typelib_TypeDescriptionReference * pReturnTypeRef, // 0 indicates void return |
93 |
typelib_TypeDescriptionReference * pReturnTypeRef, // 0 indicates void return |
108 |
sal_Int32 nParams, typelib_MethodParameter * pParams, |
94 |
sal_Int32 nParams, typelib_MethodParameter * pParams, |
Lines 122-137
Link Here
|
122 |
|
108 |
|
123 |
if (pReturnTypeDescr) |
109 |
if (pReturnTypeDescr) |
124 |
{ |
110 |
{ |
125 |
if (cppu_isSimpleType( pReturnTypeDescr )) |
111 |
if (bridges::cpp_uno::shared::isSimpleType( pReturnTypeDescr )) |
|
|
112 |
{ |
126 |
pUnoReturn = pRegisterReturn; // direct way for simple types |
113 |
pUnoReturn = pRegisterReturn; // direct way for simple types |
|
|
114 |
} |
127 |
else // complex return via ptr (pCppReturn) |
115 |
else // complex return via ptr (pCppReturn) |
128 |
{ |
116 |
{ |
129 |
pCppReturn = *(void**)pCppStack; |
117 |
pCppReturn = *(void**)pCppStack; |
130 |
|
118 |
pCppStack += sizeof( void* ); |
131 |
pUnoReturn = (cppu_relatesToInterface( pReturnTypeDescr ) |
119 |
pUnoReturn = (bridges::cpp_uno::shared::relatesToInterfaceType( |
|
|
120 |
pReturnTypeDescr ) |
132 |
? alloca( pReturnTypeDescr->nSize ) |
121 |
? alloca( pReturnTypeDescr->nSize ) |
133 |
: pCppReturn); // direct way |
122 |
: pCppReturn); // direct way |
134 |
pCppStack += sizeof( void* ); |
123 |
|
135 |
} |
124 |
} |
136 |
} |
125 |
} |
137 |
// pop this |
126 |
// pop this |
Lines 155-170
Link Here
|
155 |
typelib_TypeDescription * pParamTypeDescr = 0; |
144 |
typelib_TypeDescription * pParamTypeDescr = 0; |
156 |
TYPELIB_DANGER_GET( &pParamTypeDescr, rParam.pTypeRef ); |
145 |
TYPELIB_DANGER_GET( &pParamTypeDescr, rParam.pTypeRef ); |
157 |
|
146 |
|
158 |
if (!rParam.bOut && cppu_isSimpleType( pParamTypeDescr )) // value |
147 |
if (!rParam.bOut |
|
|
148 |
&& bridges::cpp_uno::shared::isSimpleType( pParamTypeDescr )) |
149 |
// value |
159 |
{ |
150 |
{ |
160 |
pCppArgs[nPos] = pUnoArgs[nPos] = |
151 |
pCppArgs[nPos] = pUnoArgs[nPos] = |
161 |
adjustPointer( pCppStack, pParamTypeDescr ); |
152 |
CPPU_CURRENT_NAMESPACE::adjustPointer( pCppStack, pParamTypeDescr ); |
162 |
switch (pParamTypeDescr->eTypeClass) |
153 |
switch (pParamTypeDescr->eTypeClass) |
163 |
{ |
154 |
{ |
164 |
case typelib_TypeClass_HYPER: |
155 |
case typelib_TypeClass_HYPER: |
165 |
case typelib_TypeClass_UNSIGNED_HYPER: |
156 |
case typelib_TypeClass_UNSIGNED_HYPER: |
166 |
case typelib_TypeClass_DOUBLE: |
157 |
case typelib_TypeClass_DOUBLE: |
167 |
pCppStack += sizeof(sal_Int32); // extra long |
158 |
{ |
|
|
159 |
if ((reinterpret_cast< long >(pCppStack) & 7) != 0) |
160 |
{ |
161 |
OSL_ASSERT( sizeof (double) == sizeof (sal_Int64) ); |
162 |
void * pDest = alloca( sizeof (sal_Int64) ); |
163 |
*reinterpret_cast< sal_Int32 * >(pDest) = |
164 |
*reinterpret_cast< sal_Int32 const * >(pCppStack); |
165 |
*(reinterpret_cast< sal_Int32 * >(pDest) + 1) = |
166 |
*(reinterpret_cast< sal_Int32 const * >(pCppStack) + 1); |
167 |
pCppArgs[nPos] = pUnoArgs[nPos] = pDest; |
168 |
} |
169 |
pCppStack += sizeof (sal_Int32); // extra long |
170 |
break; |
171 |
} |
168 |
} |
172 |
} |
169 |
// no longer needed |
173 |
// no longer needed |
170 |
TYPELIB_DANGER_RELEASE( pParamTypeDescr ); |
174 |
TYPELIB_DANGER_RELEASE( pParamTypeDescr ); |
Lines 182-192
Link Here
|
182 |
ppTempParamTypeDescr[nTempIndizes++] = pParamTypeDescr; |
186 |
ppTempParamTypeDescr[nTempIndizes++] = pParamTypeDescr; |
183 |
} |
187 |
} |
184 |
// is in/inout |
188 |
// is in/inout |
185 |
else if (cppu_relatesToInterface( pParamTypeDescr )) |
189 |
else if (bridges::cpp_uno::shared::relatesToInterfaceType( |
|
|
190 |
pParamTypeDescr )) |
186 |
{ |
191 |
{ |
187 |
uno_copyAndConvertData( pUnoArgs[nPos] = alloca( pParamTypeDescr->nSize ), |
192 |
uno_copyAndConvertData( pUnoArgs[nPos] = alloca( pParamTypeDescr->nSize ), |
188 |
*(void **)pCppStack, pParamTypeDescr, |
193 |
*(void **)pCppStack, pParamTypeDescr, |
189 |
&pThis->pBridge->aCpp2Uno ); |
194 |
pThis->getBridge()->getCpp2Uno() ); |
190 |
pTempIndizes[nTempIndizes] = nPos; // has to be reconverted |
195 |
pTempIndizes[nTempIndizes] = nPos; // has to be reconverted |
191 |
// will be released at reconversion |
196 |
// will be released at reconversion |
192 |
ppTempParamTypeDescr[nTempIndizes++] = pParamTypeDescr; |
197 |
ppTempParamTypeDescr[nTempIndizes++] = pParamTypeDescr; |
Lines 206-213
Link Here
|
206 |
uno_Any * pUnoExc = &aUnoExc; |
211 |
uno_Any * pUnoExc = &aUnoExc; |
207 |
|
212 |
|
208 |
// invoke uno dispatch call |
213 |
// invoke uno dispatch call |
209 |
(*pThis->pUnoI->pDispatcher)( pThis->pUnoI, pMemberTypeDescr, pUnoReturn, pUnoArgs, &pUnoExc ); |
214 |
(*pThis->getUnoI()->pDispatcher)( |
210 |
|
215 |
pThis->getUnoI(), pMemberTypeDescr, pUnoReturn, pUnoArgs, &pUnoExc ); |
211 |
// in case an exception occured... |
216 |
// in case an exception occured... |
212 |
if (pUnoExc) |
217 |
if (pUnoExc) |
213 |
{ |
218 |
{ |
Lines 222-230
Link Here
|
222 |
} |
227 |
} |
223 |
if (pReturnTypeDescr) |
228 |
if (pReturnTypeDescr) |
224 |
TYPELIB_DANGER_RELEASE( pReturnTypeDescr ); |
229 |
TYPELIB_DANGER_RELEASE( pReturnTypeDescr ); |
225 |
|
230 |
CPPU_CURRENT_NAMESPACE::raiseException( |
226 |
raiseException( &aUnoExc, &pThis->pBridge->aUno2Cpp ); // has to destruct the any |
231 |
&aUnoExc, pThis->getBridge()->getUno2Cpp() ); |
227 |
// is here for dummy |
232 |
// has to destruct the any |
|
|
233 |
// is here for dummy |
228 |
return typelib_TypeClass_VOID; |
234 |
return typelib_TypeClass_VOID; |
229 |
} |
235 |
} |
230 |
else // else no exception occured... |
236 |
else // else no exception occured... |
Lines 240-246
Link Here
|
240 |
// convert and assign |
246 |
// convert and assign |
241 |
uno_destructData( pCppArgs[nIndex], pParamTypeDescr, cpp_release ); |
247 |
uno_destructData( pCppArgs[nIndex], pParamTypeDescr, cpp_release ); |
242 |
uno_copyAndConvertData( pCppArgs[nIndex], pUnoArgs[nIndex], pParamTypeDescr, |
248 |
uno_copyAndConvertData( pCppArgs[nIndex], pUnoArgs[nIndex], pParamTypeDescr, |
243 |
&pThis->pBridge->aUno2Cpp ); |
249 |
pThis->getBridge()->getUno2Cpp() ); |
244 |
} |
250 |
} |
245 |
// destroy temp uno param |
251 |
// destroy temp uno param |
246 |
uno_destructData( pUnoArgs[nIndex], pParamTypeDescr, 0 ); |
252 |
uno_destructData( pUnoArgs[nIndex], pParamTypeDescr, 0 ); |
Lines 253-259
Link Here
|
253 |
if (pUnoReturn != pCppReturn) // needs reconversion |
259 |
if (pUnoReturn != pCppReturn) // needs reconversion |
254 |
{ |
260 |
{ |
255 |
uno_copyAndConvertData( pCppReturn, pUnoReturn, pReturnTypeDescr, |
261 |
uno_copyAndConvertData( pCppReturn, pUnoReturn, pReturnTypeDescr, |
256 |
&pThis->pBridge->aUno2Cpp ); |
262 |
pThis->getBridge()->getUno2Cpp() ); |
257 |
// destroy temp uno return |
263 |
// destroy temp uno return |
258 |
uno_destructData( pUnoReturn, pReturnTypeDescr, 0 ); |
264 |
uno_destructData( pUnoReturn, pReturnTypeDescr, 0 ); |
259 |
} |
265 |
} |
Lines 274-281
Link Here
|
274 |
|
280 |
|
275 |
//================================================================================================== |
281 |
//================================================================================================== |
276 |
static typelib_TypeClass cpp_mediate( |
282 |
static typelib_TypeClass cpp_mediate( |
277 |
sal_Int32 nVtableCall, |
283 |
sal_Int32 nFunctionIndex, |
278 |
void ** pCallStack, |
284 |
void ** pCallStack, |
|
|
285 |
sal_Int32 nVtableOffset, |
279 |
sal_Int64 * pRegisterReturn /* space for register return */ ) |
286 |
sal_Int64 * pRegisterReturn /* space for register return */ ) |
280 |
{ |
287 |
{ |
281 |
OSL_ENSURE( sizeof(sal_Int32)==sizeof(void *), "### unexpected!" ); |
288 |
OSL_ENSURE( sizeof(sal_Int32)==sizeof(void *), "### unexpected!" ); |
Lines 283-309
Link Here
|
283 |
// pCallStack: this, params |
290 |
// pCallStack: this, params |
284 |
// eventual [ret*] lies at pCallStack -1 |
291 |
// eventual [ret*] lies at pCallStack -1 |
285 |
// so count down pCallStack by one to keep it simple |
292 |
// so count down pCallStack by one to keep it simple |
286 |
// _this_ ptr is patched cppu_XInterfaceProxy object |
293 |
|
287 |
cppu_cppInterfaceProxy * pCppI = NULL; |
294 |
void * pThis; |
288 |
pCppI = (cppu_cppInterfaceProxy *)(XInterface *)*pCallStack; |
295 |
if( nFunctionIndex & 0x80000000 ) |
289 |
if( nVtableCall & 0x80000000 ) |
|
|
290 |
{ |
296 |
{ |
291 |
pCallStack--; |
297 |
nFunctionIndex &= 0x7fffffff; |
292 |
nVtableCall &= 0x7fffffff; |
298 |
pThis = pCallStack[1]; //jw: from solaris/sparc, linux/intel has 2 |
293 |
} |
299 |
} |
294 |
|
300 |
else |
295 |
typelib_InterfaceTypeDescription * pTypeDescr = pCppI->pTypeDescr; |
301 |
{ |
296 |
|
302 |
pThis = pCallStack[0]; //jw: from solaris/sparc, linux/intel has 1 |
297 |
OSL_ENSURE( nVtableCall < pTypeDescr->nMapFunctionIndexToMemberIndex, |
303 |
} |
|
|
304 |
pThis = static_cast< char * >(pThis) - nVtableOffset; |
305 |
bridges::cpp_uno::shared::CppInterfaceProxy * pCppI |
306 |
= bridges::cpp_uno::shared::CppInterfaceProxy::castInterfaceToProxy( |
307 |
pThis); |
308 |
typelib_InterfaceTypeDescription * pTypeDescr = pCppI->getTypeDescr(); |
309 |
OSL_ENSURE( nFunctionIndex < pTypeDescr->nMapFunctionIndexToMemberIndex, |
298 |
"### illegal vtable index!" ); |
310 |
"### illegal vtable index!" ); |
299 |
if (nVtableCall >= pTypeDescr->nMapFunctionIndexToMemberIndex) |
311 |
if (nFunctionIndex >= pTypeDescr->nMapFunctionIndexToMemberIndex) |
300 |
{ |
312 |
{ |
301 |
throw RuntimeException( OUString::createFromAscii("illegal vtable index!"), (XInterface *)pCppI ); |
313 |
throw RuntimeException( OUString::createFromAscii("illegal vtable index!"), (XInterface *)pCppI ); |
302 |
} |
314 |
} |
303 |
|
315 |
|
304 |
// determine called method |
316 |
// determine called method |
305 |
OSL_ENSURE( nVtableCall < pTypeDescr->nMapFunctionIndexToMemberIndex, "### illegal vtable index!" ); |
317 |
sal_Int32 nMemberPos = pTypeDescr->pMapFunctionIndexToMemberIndex[nFunctionIndex]; |
306 |
sal_Int32 nMemberPos = pTypeDescr->pMapFunctionIndexToMemberIndex[nVtableCall]; |
|
|
307 |
OSL_ENSURE( nMemberPos < pTypeDescr->nAllMembers, "### illegal member index!" ); |
318 |
OSL_ENSURE( nMemberPos < pTypeDescr->nAllMembers, "### illegal member index!" ); |
308 |
|
319 |
|
309 |
TypeDescription aMemberDescr( pTypeDescr->ppAllMembers[nMemberPos] ); |
320 |
TypeDescription aMemberDescr( pTypeDescr->ppAllMembers[nMemberPos] ); |
Lines 318-324
Link Here
|
318 |
{ |
329 |
{ |
319 |
case typelib_TypeClass_INTERFACE_ATTRIBUTE: |
330 |
case typelib_TypeClass_INTERFACE_ATTRIBUTE: |
320 |
{ |
331 |
{ |
321 |
if (pTypeDescr->pMapMemberIndexToFunctionIndex[nMemberPos] == nVtableCall) |
332 |
if (pTypeDescr->pMapMemberIndexToFunctionIndex[nMemberPos] == nFunctionIndex) |
322 |
{ |
333 |
{ |
323 |
// is GET method |
334 |
// is GET method |
324 |
eRet = cpp2uno_call( |
335 |
eRet = cpp2uno_call( |
Lines 347-353
Link Here
|
347 |
case typelib_TypeClass_INTERFACE_METHOD: |
358 |
case typelib_TypeClass_INTERFACE_METHOD: |
348 |
{ |
359 |
{ |
349 |
// is METHOD |
360 |
// is METHOD |
350 |
switch (nVtableCall) |
361 |
switch (nFunctionIndex) |
351 |
{ |
362 |
{ |
352 |
case 1: // acquire() |
363 |
case 1: // acquire() |
353 |
pCppI->acquireProxy(); // non virtual call! |
364 |
pCppI->acquireProxy(); // non virtual call! |
Lines 364-372
Link Here
|
364 |
if (pTD) |
375 |
if (pTD) |
365 |
{ |
376 |
{ |
366 |
XInterface * pInterface = 0; |
377 |
XInterface * pInterface = 0; |
367 |
(*pCppI->pBridge->pCppEnv->getRegisteredInterface)( |
378 |
(*pCppI->getBridge()->getCppEnv()->getRegisteredInterface)( |
368 |
pCppI->pBridge->pCppEnv, |
379 |
pCppI->getBridge()->getCppEnv(), |
369 |
(void **)&pInterface, pCppI->oid.pData, (typelib_InterfaceTypeDescription *)pTD ); |
380 |
(void **)&pInterface, pCppI->getOid().pData, |
|
|
381 |
(typelib_InterfaceTypeDescription *)pTD ); |
370 |
|
382 |
|
371 |
if (pInterface) |
383 |
if (pInterface) |
372 |
{ |
384 |
{ |
Lines 394-494
Link Here
|
394 |
} |
406 |
} |
395 |
default: |
407 |
default: |
396 |
{ |
408 |
{ |
397 |
throw RuntimeException( OUString::createFromAscii("no member description found!"), (XInterface *)pCppI ); |
409 |
throw RuntimeException( |
|
|
410 |
rtl::OUString::createFromAscii("no member description found!"), |
411 |
(XInterface *)pThis ); |
398 |
// is here for dummy |
412 |
// is here for dummy |
399 |
eRet = typelib_TypeClass_VOID; |
413 |
eRet = typelib_TypeClass_VOID; |
400 |
} |
414 |
} |
401 |
} |
415 |
} |
402 |
|
|
|
403 |
return eRet; |
404 |
} |
405 |
|
406 |
//================================================================================================== |
407 |
class MediateClassData |
408 |
{ |
409 |
public: |
410 |
struct ClassDataBuffer |
411 |
{ |
412 |
void* m_pVTable; |
413 |
|
414 |
~ClassDataBuffer(); |
415 |
}; |
416 |
private: |
417 |
|
416 |
|
418 |
map< OUString, ClassDataBuffer* > m_aClassData; |
417 |
return eRet; |
419 |
Mutex m_aMutex; |
|
|
420 |
|
421 |
void createVTable( ClassDataBuffer*, typelib_InterfaceTypeDescription* ); |
422 |
public: |
423 |
const ClassDataBuffer* getClassData( typelib_InterfaceTypeDescription* ); |
424 |
|
425 |
MediateClassData() {} |
426 |
~MediateClassData(); |
427 |
}; |
428 |
//__________________________________________________________________________________________________ |
429 |
MediateClassData::ClassDataBuffer::~ClassDataBuffer() |
430 |
{ |
431 |
delete m_pVTable; |
432 |
} |
433 |
|
434 |
//__________________________________________________________________________________________________ |
435 |
MediateClassData::~MediateClassData() |
436 |
{ |
437 |
TRACE( "> calling ~MediateClassData(): freeing mediate vtables... <\n" ); |
438 |
|
439 |
// this MUST be the absolute last one which is called! |
440 |
for ( map< OUString, ClassDataBuffer* >::iterator iPos( m_aClassData.begin() ); iPos != m_aClassData.end(); ++iPos ) |
441 |
{ |
442 |
// todo |
443 |
// delete (*iPos).second; |
444 |
} |
445 |
} |
446 |
|
447 |
//__________________________________________________________________________________________________ |
448 |
|
449 |
const MediateClassData::ClassDataBuffer* MediateClassData::getClassData( typelib_InterfaceTypeDescription* pType ) |
450 |
{ |
451 |
MutexGuard aGuard( m_aMutex ); |
452 |
|
453 |
map< OUString, ClassDataBuffer* >::iterator element = m_aClassData.find( pType->aBase.pTypeName ); |
454 |
if( element != m_aClassData.end() ) |
455 |
return (*element).second; |
456 |
|
457 |
ClassDataBuffer* pBuffer = new ClassDataBuffer(); |
458 |
createVTable( pBuffer, pType ); |
459 |
m_aClassData[ pType->aBase.pTypeName ] = pBuffer; |
460 |
return pBuffer; |
461 |
} |
418 |
} |
462 |
|
419 |
|
463 |
|
|
|
464 |
//================================================================================================== |
420 |
//================================================================================================== |
465 |
/** |
421 |
/** |
466 |
* is called on incoming vtable calls |
422 |
* is called on incoming vtable calls |
467 |
* (called by asm snippets) |
423 |
* (called by asm snippets) |
468 |
*/ |
424 |
*/ |
469 |
static void cpp_vtable_call() |
425 |
static void cpp_vtable_call() |
470 |
{ |
426 |
{ |
471 |
int nTableEntry; |
427 |
sal_Int32 functionIndex; |
472 |
void** pCallStack; |
428 |
void** pCallStack; |
|
|
429 |
sal_Int32 vtableOffset; |
473 |
volatile sal_Int64 nRegReturn; |
430 |
volatile sal_Int64 nRegReturn; |
474 |
|
431 |
|
475 |
// nTableEntry and pCallStack are delivered in registers as usual |
|
|
476 |
// but cpp_vtable_call is declared void. |
477 |
// the reason is that this way the compiler won't clobber the |
478 |
// call stack prepared by the assembler snippet to save its input |
479 |
// registers |
480 |
// also restore %i2 here which was clobbered to jump here |
481 |
__asm__( "st %%i0, %0\n\t" |
432 |
__asm__( "st %%i0, %0\n\t" |
482 |
"st %%i1, %1\n\t" |
433 |
"st %%i1, %1\n\t" |
483 |
"ld [%%fp+68], %%i0\n\t" |
434 |
"st %%i2, %2\n\t" |
484 |
"ld [%%fp+72], %%i1\n\t" |
435 |
: : "m"(functionIndex), "m"(pCallStack), "m"(vtableOffset) ); |
485 |
"ld [%%fp+76], %%i2\n\t" |
|
|
486 |
: : "m"(nTableEntry), "m"(pCallStack) ); |
487 |
|
436 |
|
488 |
sal_Bool bComplex = nTableEntry & 0x80000000 ? sal_True : sal_False; |
437 |
sal_Bool bComplex = functionIndex & 0x80000000 ? sal_True : sal_False; |
489 |
|
438 |
|
490 |
typelib_TypeClass aType = |
439 |
typelib_TypeClass aType = |
491 |
cpp_mediate( nTableEntry, pCallStack+17, &nRegReturn ); |
440 |
cpp_mediate( functionIndex, pCallStack+17, vtableOffset, (sal_Int64*)&nRegReturn ); |
492 |
|
441 |
|
493 |
switch( aType ) |
442 |
switch( aType ) |
494 |
{ |
443 |
{ |
Lines 513-519
Link Here
|
513 |
"ld %1, %%l0\n\t" |
462 |
"ld %1, %%l0\n\t" |
514 |
"ld [%%l0], %%i1\n\t" |
463 |
"ld [%%l0], %%i1\n\t" |
515 |
: : "m"(&nRegReturn), "m"(((long*)&nRegReturn) +1) ); |
464 |
: : "m"(&nRegReturn), "m"(((long*)&nRegReturn) +1) ); |
516 |
|
|
|
517 |
break; |
465 |
break; |
518 |
case typelib_TypeClass_FLOAT: |
466 |
case typelib_TypeClass_FLOAT: |
519 |
__asm__( "ld %0, %%l0\n\t" |
467 |
__asm__( "ld %0, %%l0\n\t" |
Lines 542-678
Link Here
|
542 |
|
490 |
|
543 |
} |
491 |
} |
544 |
//__________________________________________________________________________________________________ |
492 |
//__________________________________________________________________________________________________ |
|
|
493 |
namespace { |
545 |
|
494 |
|
546 |
void MediateClassData::createVTable( ClassDataBuffer* pBuffer, typelib_InterfaceTypeDescription* pType ) |
495 |
int const codeSnippetSize = 56; |
547 |
{ |
|
|
548 |
// get all member functions |
549 |
list< sal_Bool > aComplexReturn; |
550 |
|
551 |
for( int n = 0; n < pType->nAllMembers; n++ ) |
552 |
{ |
553 |
typelib_TypeDescription* pMember = NULL; |
554 |
TYPELIB_DANGER_GET( &pMember, pType->ppAllMembers[n] ); |
555 |
if( pMember->eTypeClass == typelib_TypeClass_INTERFACE_ATTRIBUTE ) |
556 |
{ |
557 |
typelib_TypeDescription * pRetTD = 0; |
558 |
TYPELIB_DANGER_GET( &pRetTD, ((typelib_InterfaceAttributeTypeDescription *)pMember)->pAttributeTypeRef ); |
559 |
// get method |
560 |
aComplexReturn.push_back( !cppu_isSimpleType( pRetTD ) ); |
561 |
// set method |
562 |
if( ! ((typelib_InterfaceAttributeTypeDescription*)pMember)->bReadOnly ) |
563 |
aComplexReturn.push_back( sal_False ); |
564 |
TYPELIB_DANGER_RELEASE( pRetTD ); |
565 |
} |
566 |
else |
567 |
{ |
568 |
typelib_TypeDescription * pRetTD = 0; |
569 |
TYPELIB_DANGER_GET( &pRetTD, ((typelib_InterfaceMethodTypeDescription *)pMember)->pReturnTypeRef ); |
570 |
aComplexReturn.push_back( !cppu_isSimpleType( pRetTD ) ); |
571 |
TYPELIB_DANGER_RELEASE( pRetTD ); |
572 |
} |
573 |
TYPELIB_DANGER_RELEASE( pMember ); |
574 |
} |
575 |
|
576 |
int nSize = aComplexReturn.size(); |
577 |
const int nSnippetSize = 64; |
578 |
char * pSpace = (char *)rtl_allocateMemory( (2*(nSize+2)*sizeof(void *)) + (nSize*nSnippetSize) ); |
579 |
pBuffer->m_pVTable = (void*)pSpace; |
580 |
|
581 |
char * pCode = pSpace + (2*(nSize+2)*sizeof(void *)); |
582 |
void ** pvft = (void **)pSpace; |
583 |
|
584 |
// setup vft and code |
585 |
for ( sal_Int32 nPos = 0; nPos < nSize; ++nPos ) |
586 |
{ |
587 |
unsigned long * codeSnip = (unsigned long *)(pCode + (nPos*nSnippetSize)); |
588 |
pvft[ nPos ] = codeSnip; |
589 |
unsigned long nTablePos = nPos; |
590 |
sal_Bool bComplex = aComplexReturn.front(); |
591 |
if( bComplex ) |
592 |
nTablePos |= 0x80000000; |
593 |
aComplexReturn.pop_front(); |
594 |
|
595 |
/* |
596 |
* generate this code |
597 |
* |
598 |
* st %o0, [%sp+68] save registers |
599 |
* st %o1, [%sp+72] |
600 |
* st %o2, [%sp+76] |
601 |
* st %o3, [%sp+80] |
602 |
* st %o4, [%sp+84] |
603 |
* st %o5, [%sp+88] |
604 |
* |
605 |
* mov %sp, %o1 prepare stack ptr for cpp_vtable_call |
606 |
* sethi %hi( nTablePos ), %o0 prepare table entry |
607 |
* or %lo( nTablePos ), %o0 (on complex return set high bit |
608 |
* |
609 |
* sethi $hi( cpp_vtable_call ), %l0 |
610 |
* or %l0, %lo( cpp_vtable_call ), %l0 |
611 |
* jmp %l0 |
612 |
* nop |
613 |
* |
614 |
* Note: %o0 should be restored by cpp_vtable_call if void returned |
615 |
* %o1 should be restored if not hyper returned |
616 |
* %o2 must be restored |
617 |
* |
618 |
*/ |
619 |
*codeSnip++ = 0xd023a044; |
620 |
*codeSnip++ = 0xd223a048; |
621 |
*codeSnip++ = 0xd423a04c; |
622 |
*codeSnip++ = 0xd623a050; |
623 |
*codeSnip++ = 0xd823a054; |
624 |
*codeSnip++ = 0xda23a058; |
625 |
|
626 |
*codeSnip++ = 0x9210000e; |
627 |
*codeSnip++ = 0x11000000 | ( nTablePos >> 10 ); |
628 |
*codeSnip++ = 0x90122000 | ( nTablePos & 1023 ); |
629 |
*codeSnip++ = 0x15000000 | ( ((unsigned long)cpp_vtable_call) >> 10 ); |
630 |
*codeSnip++ = 0x9412a000 | ( ((unsigned long)cpp_vtable_call) & 1023 ); |
631 |
*codeSnip++ = 0x81c28000; |
632 |
*codeSnip++ = 0x01000000; |
633 |
} |
634 |
} |
635 |
|
636 |
//================================================================================================== |
637 |
void SAL_CALL cppu_cppInterfaceProxy_patchVtable( |
638 |
XInterface * pCppI, typelib_InterfaceTypeDescription * pTypeDescr ) throw () |
639 |
{ |
640 |
static MediateClassData * s_pMediateClassData = 0; |
641 |
if (! s_pMediateClassData) |
642 |
{ |
643 |
MutexGuard aGuard( Mutex::getGlobalMutex() ); |
644 |
if (! s_pMediateClassData) |
645 |
{ |
646 |
#ifdef LEAK_STATIC_DATA |
647 |
s_pMediateClassData = new MediateClassData(); |
648 |
#else |
649 |
static MediateClassData s_aMediateClassData; |
650 |
s_pMediateClassData = &s_aMediateClassData; |
651 |
#endif |
652 |
} |
653 |
} |
654 |
*(const void **)pCppI = s_pMediateClassData->getClassData( pTypeDescr )->m_pVTable; |
655 |
} |
656 |
|
496 |
|
657 |
} |
497 |
unsigned char * codeSnippet( |
|
|
498 |
unsigned char *codeSnip, |
499 |
sal_Int32 functionIndex, |
500 |
sal_Int32 vtableOffset, |
501 |
bool simpleReturnType) |
502 |
{ |
503 |
if( !simpleReturnType ) |
504 |
functionIndex |= 0x80000000; // is this correct?? |
505 |
|
506 |
// st %o0, [%sp+68]: |
507 |
*codeSnip++ = 0xd023a044; |
508 |
// st %o1, [%sp+72]: |
509 |
*codeSnip++ = 0xd223a048; |
510 |
// st %o2, [%sp+76]: |
511 |
*codeSnip++ = 0xd423a04c; |
512 |
// st %o3, [%sp+80]: |
513 |
*codeSnip++ = 0xd623a050; |
514 |
// st %o4, [%sp+84]: |
515 |
*codeSnip++ = 0xd823a054; |
516 |
// st %o5, [%sp+88]: |
517 |
*codeSnip++ = 0xda23a058; |
518 |
// sethi %hi(functionIndex), %o0: |
519 |
*codeSnip++ = 0x11000000 | (static_cast< unsigned long >(functionIndex) >> 10); |
520 |
// or %o0, %lo(functionIndex), %o0: |
521 |
*codeSnip++ = 0x90122000 | (static_cast< unsigned long >(functionIndex) & 0x3FF); |
522 |
// sethi %hi(vtableOffset), %o2: |
523 |
*codeSnip++ = 0x15000000 | (static_cast< unsigned long >(vtableOffset) >> 10); |
524 |
// or %o2, %lo(vtableOffset), %o2: |
525 |
*codeSnip++ = 0x9412a000 | (static_cast< unsigned long >(vtableOffset) & 0x3FF); |
526 |
// sethi %hi(cpp_vtable_call), %o3: |
527 |
*codeSnip++ = 0x17000000 | (((unsigned long) cpp_vtable_call) >> 10); |
528 |
// or %o3, %lo(cpp_vtable_call), %o3: |
529 |
*codeSnip++ = 0x9612e000 | (((unsigned long) cpp_vtable_call) & 0x3FF); |
530 |
// jmp %o3: |
531 |
*codeSnip++ = 0x81c2c000; |
532 |
// mov %sp, %o1: |
533 |
*codeSnip++ = 0x9210000e; |
534 |
} |
535 |
} |
536 |
|
537 |
void ** bridges::cpp_uno::shared::VtableFactory::mapBlockToVtable(char * block) |
538 |
{ |
539 |
return reinterpret_cast< void ** >(block) + 2; |
540 |
} |
541 |
|
542 |
char * bridges::cpp_uno::shared::VtableFactory::createBlock( |
543 |
sal_Int32 slotCount, void *** slots) |
544 |
{ |
545 |
char * block = new char[ |
546 |
(slotCount + 2) * sizeof (void *) + slotCount * codeSnippetSize]; |
547 |
*slots = mapBlockToVtable(block); |
548 |
(*slots)[-2] = 0; |
549 |
(*slots)[-1] = 0; |
550 |
return block; |
551 |
} |
552 |
|
553 |
unsigned char * bridges::cpp_uno::shared::VtableFactory::addLocalFunctions( |
554 |
void ** slots, unsigned char * code, |
555 |
typelib_InterfaceTypeDescription const * type, sal_Int32 functionOffset, |
556 |
sal_Int32 functionCount, sal_Int32 vtableOffset) |
557 |
{ |
558 |
for (sal_Int32 i = 0; i < type->nMembers; ++i) { |
559 |
typelib_TypeDescription * member = 0; |
560 |
TYPELIB_DANGER_GET(&member, type->ppMembers[i]); |
561 |
OSL_ASSERT(member != 0); |
562 |
switch (member->eTypeClass) { |
563 |
case typelib_TypeClass_INTERFACE_ATTRIBUTE: |
564 |
// Getter: |
565 |
*slots++ = code; |
566 |
code = codeSnippet( |
567 |
code, functionOffset++, vtableOffset, |
568 |
bridges::cpp_uno::shared::isSimpleType( |
569 |
reinterpret_cast< |
570 |
typelib_InterfaceAttributeTypeDescription * >( |
571 |
member)->pAttributeTypeRef)); |
572 |
// Setter: |
573 |
if (!reinterpret_cast< |
574 |
typelib_InterfaceAttributeTypeDescription * >( |
575 |
member)->bReadOnly) |
576 |
{ |
577 |
*slots++ = code; |
578 |
code = codeSnippet(code, functionOffset++, vtableOffset, true); |
579 |
} |
580 |
break; |
658 |
|
581 |
|
659 |
//################################################################################################## |
582 |
case typelib_TypeClass_INTERFACE_METHOD: |
660 |
extern "C" SAL_DLLEXPORT sal_Bool SAL_CALL component_canUnload( TimeValue * pTime ) |
583 |
*slots++ = code; |
661 |
SAL_THROW_EXTERN_C() |
584 |
code = codeSnippet( |
662 |
{ |
585 |
code, functionOffset++, vtableOffset, |
663 |
return CPPU_CURRENT_NAMESPACE::g_moduleCount.canUnload( &CPPU_CURRENT_NAMESPACE::g_moduleCount, pTime ); |
586 |
bridges::cpp_uno::shared::isSimpleType( |
664 |
} |
587 |
reinterpret_cast< |
665 |
//################################################################################################## |
588 |
typelib_InterfaceMethodTypeDescription * >( |
666 |
extern "C" SAL_DLLEXPORT void SAL_CALL uno_initEnvironment( uno_Environment * pCppEnv ) |
589 |
member)->pReturnTypeRef)); |
667 |
SAL_THROW_EXTERN_C() |
590 |
break; |
668 |
{ |
591 |
|
669 |
CPPU_CURRENT_NAMESPACE::cppu_cppenv_initEnvironment( pCppEnv ); |
592 |
default: |
670 |
} |
593 |
OSL_ASSERT(false); |
671 |
//################################################################################################## |
594 |
break; |
672 |
extern "C" SAL_DLLEXPORT void SAL_CALL uno_ext_getMapping( |
595 |
} |
673 |
uno_Mapping ** ppMapping, uno_Environment * pFrom, uno_Environment * pTo ) |
596 |
TYPELIB_DANGER_RELEASE(member); |
674 |
SAL_THROW_EXTERN_C() |
597 |
} |
675 |
{ |
598 |
return code; |
676 |
CPPU_CURRENT_NAMESPACE::cppu_ext_getMapping( ppMapping, pFrom, pTo ); |
|
|
677 |
} |
599 |
} |
678 |
|
600 |
|
|
|
601 |
} |