Lines 58-77
Link Here
|
58 |
* |
58 |
* |
59 |
* |
59 |
* |
60 |
************************************************************************/ |
60 |
************************************************************************/ |
61 |
#define LEAK_STATIC_DATA |
|
|
62 |
#define TRACE(x) OSL_TRACE(x) |
63 |
#define TRACE(x) |
64 |
|
65 |
#include <list> |
66 |
#include <map> |
67 |
#include <typeinfo> |
68 |
#include <com/sun/star/uno/genfunc.hxx> |
61 |
#include <com/sun/star/uno/genfunc.hxx> |
69 |
#ifndef _TYPELIB_TYPEDESCRIPTION_HXX_ |
|
|
70 |
#include <typelib/typedescription.hxx> |
62 |
#include <typelib/typedescription.hxx> |
71 |
#endif |
|
|
72 |
#ifndef _UNO_DATA_H_ |
73 |
#include <uno/data.h> |
63 |
#include <uno/data.h> |
74 |
#endif |
|
|
75 |
#include "bridges/cpp_uno/shared/bridge.hxx" |
64 |
#include "bridges/cpp_uno/shared/bridge.hxx" |
76 |
#include "bridges/cpp_uno/shared/cppinterfaceproxy.hxx" |
65 |
#include "bridges/cpp_uno/shared/cppinterfaceproxy.hxx" |
77 |
#include "bridges/cpp_uno/shared/types.hxx" |
66 |
#include "bridges/cpp_uno/shared/types.hxx" |
Lines 79-90
Link Here
|
79 |
#include "share.hxx" |
68 |
#include "share.hxx" |
80 |
|
69 |
|
81 |
using namespace com::sun::star::uno; |
70 |
using namespace com::sun::star::uno; |
82 |
using namespace std; |
|
|
83 |
using namespace rtl; |
84 |
|
71 |
|
85 |
namespace |
72 |
namespace |
86 |
{ |
73 |
{ |
87 |
|
|
|
88 |
//================================================================================================== |
74 |
//================================================================================================== |
89 |
static typelib_TypeClass cpp2uno_call( |
75 |
static typelib_TypeClass cpp2uno_call( |
90 |
bridges::cpp_uno::shared::CppInterfaceProxy * pThis, |
76 |
bridges::cpp_uno::shared::CppInterfaceProxy * pThis, |
Lines 145-152
Link Here
|
145 |
|
131 |
|
146 |
if (!rParam.bOut && bridges::cpp_uno::shared::isSimpleType( pParamTypeDescr )) // value |
132 |
if (!rParam.bOut && bridges::cpp_uno::shared::isSimpleType( pParamTypeDescr )) // value |
147 |
{ |
133 |
{ |
148 |
pCppArgs[nPos] = pUnoArgs[nPos] = |
134 |
pCppArgs[nPos] = pCppStack; |
149 |
CPPU_CURRENT_NAMESPACE::adjustPointer( pCppStack, pParamTypeDescr ); |
135 |
pUnoArgs[nPos] = pCppStack; |
150 |
switch (pParamTypeDescr->eTypeClass) |
136 |
switch (pParamTypeDescr->eTypeClass) |
151 |
{ |
137 |
{ |
152 |
case typelib_TypeClass_HYPER: |
138 |
case typelib_TypeClass_HYPER: |
Lines 276-313
Link Here
|
276 |
|
262 |
|
277 |
//================================================================================================== |
263 |
//================================================================================================== |
278 |
static typelib_TypeClass cpp_mediate( |
264 |
static typelib_TypeClass cpp_mediate( |
279 |
sal_Int32 nFunctionIndex, |
265 |
int nFunctionIndex, |
280 |
sal_Int32 nVtableOffset, |
266 |
void ** pCallStack, |
281 |
void ** pCallStack, |
267 |
int nVtableOffset, |
282 |
sal_Int64 * pRegisterReturn /* space for register return */ ) |
268 |
sal_Int64 * pRegisterReturn /* space for register return */ ) |
283 |
{ |
269 |
{ |
284 |
OSL_ENSURE( sizeof(sal_Int32)==sizeof(void *), "### unexpected!" ); |
270 |
OSL_ENSURE( sizeof(sal_Int32)==sizeof(void *), "### unexpected!" ); |
285 |
|
|
|
286 |
// pCallStack: this, params |
271 |
// pCallStack: this, params |
287 |
// eventual [ret*] lies at pCallStack -1 |
272 |
// eventual [ret*] lies at pCallStack -1 |
288 |
// so count down pCallStack by one to keep it simple |
273 |
// so count down pCallStack by one to keep it simple |
289 |
bridges::cpp_uno::shared::CppInterfaceProxy * pCppI |
274 |
void * pThis; |
290 |
= bridges::cpp_uno::shared::CppInterfaceProxy::castInterfaceToProxy( |
275 |
if (nFunctionIndex & 0x80000000) |
291 |
static_cast< char * >(*pCallStack) - nVtableOffset); |
276 |
{ |
292 |
if ((nFunctionIndex & 0x80000000) != 0) { |
|
|
293 |
nFunctionIndex &= 0x7FFFFFFF; |
277 |
nFunctionIndex &= 0x7FFFFFFF; |
294 |
--pCallStack; |
278 |
pThis=pCallStack[1]; |
295 |
} |
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); |
296 |
typelib_InterfaceTypeDescription * pTypeDescr = pCppI->getTypeDescr(); |
288 |
typelib_InterfaceTypeDescription * pTypeDescr = pCppI->getTypeDescr(); |
297 |
|
289 |
|
298 |
OSL_ENSURE( nFunctionIndex < pTypeDescr->nMapFunctionIndexToMemberIndex, |
290 |
OSL_ENSURE( nFunctionIndex < pTypeDescr->nMapFunctionIndexToMemberIndex, |
299 |
"### illegal vtable index!" ); |
291 |
"### illegal vtable index!" ); |
300 |
if (nFunctionIndex >= pTypeDescr->nMapFunctionIndexToMemberIndex) |
292 |
if (nFunctionIndex >= pTypeDescr->nMapFunctionIndexToMemberIndex) |
301 |
{ |
293 |
{ |
302 |
throw RuntimeException( OUString::createFromAscii("illegal vtable index!"), (XInterface *)pCppI ); |
294 |
throw RuntimeException( rtl::OUString::createFromAscii("illegal vtable index!"), (XInterface *)pCppI ); |
303 |
} |
295 |
} |
304 |
|
296 |
|
305 |
// determine called method |
297 |
// determine called method |
306 |
sal_Int32 nMemberPos = pTypeDescr->pMapFunctionIndexToMemberIndex[nFunctionIndex]; |
298 |
sal_Int32 nMemberPos = pTypeDescr->pMapFunctionIndexToMemberIndex[nFunctionIndex]; |
307 |
OSL_ENSURE( nMemberPos < pTypeDescr->nAllMembers, "### illegal member index!" ); |
299 |
OSL_ENSURE( nMemberPos < pTypeDescr->nAllMembers, "### illegal member index!" ); |
308 |
|
|
|
309 |
TypeDescription aMemberDescr( pTypeDescr->ppAllMembers[nMemberPos] ); |
300 |
TypeDescription aMemberDescr( pTypeDescr->ppAllMembers[nMemberPos] ); |
310 |
|
|
|
311 |
//#if defined BRIDGES_DEBUG |
301 |
//#if defined BRIDGES_DEBUG |
312 |
// OString cstr( OUStringToOString( aMemberDescr.get()->pTypeName, RTL_TEXTENCODING_ASCII_US ) ); |
302 |
// OString cstr( OUStringToOString( aMemberDescr.get()->pTypeName, RTL_TEXTENCODING_ASCII_US ) ); |
313 |
// fprintf( stderr, "calling %s, nVtableCall=%d\n", cstr.getStr(), nVtableCall ); |
303 |
// fprintf( stderr, "calling %s, nVtableCall=%d\n", cstr.getStr(), nVtableCall ); |
Lines 402-464
Link Here
|
402 |
// eRet = typelib_TypeClass_VOID; |
392 |
// eRet = typelib_TypeClass_VOID; |
403 |
// } |
393 |
// } |
404 |
} |
394 |
} |
405 |
|
|
|
406 |
return eRet; |
395 |
return eRet; |
407 |
} |
396 |
} |
408 |
|
397 |
|
409 |
} |
398 |
|
410 |
|
399 |
|
411 |
//================================================================================================== |
400 |
//================================================================================================== |
412 |
/** |
401 |
/** |
413 |
* is called on incoming vtable calls |
402 |
* is called on incoming vtable calls |
414 |
* (called by asm snippets) |
403 |
* (called by asm snippets) |
415 |
*/ |
404 |
*/ |
416 |
int cpp_vtable_call( |
405 |
static void cpp_vtable_call() |
417 |
sal_Int32 nFunctionIndex, sal_Int32 nVtableOffset, void** pCallStack) |
|
|
418 |
{ |
406 |
{ |
|
|
407 |
|
408 |
int functionIndex; |
409 |
void** pCallStack; |
410 |
int vtableOffset; |
419 |
volatile sal_Int64 nRegReturn; |
411 |
volatile sal_Int64 nRegReturn; |
|
|
412 |
// nTableEntry and pCallStack are delivered in registers as usual |
413 |
// but cpp_vtable_call is declared void. |
414 |
// the reason is that this way the compiler won't clobber the |
415 |
// call stack prepared by the assembler snippet to save its input |
416 |
// registers |
417 |
// also restore %i3 here which was clobbered to jump here |
418 |
|
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; |
429 |
|
420 |
typelib_TypeClass aType = |
430 |
typelib_TypeClass aType = |
421 |
cpp_mediate( nFunctionIndex, nVtableOffset, pCallStack, (sal_Int64*)&nRegReturn ); |
431 |
cpp_mediate( functionIndex, pCallStack, vtableOffset, (sal_Int64*)&nRegReturn ); |
422 |
OSL_ASSERT( sizeof(void *) == sizeof(sal_Int32) ); |
432 |
|
423 |
switch( aType ) |
433 |
switch( aType ) |
424 |
{ |
434 |
{ |
425 |
// move return value into register space |
|
|
426 |
// (will be loaded by machine code snippet) |
427 |
// Use pCallStack[1/2] instead of pCallStack[0/1], because the former is |
428 |
// properly dword aligned: |
429 |
case typelib_TypeClass_BOOLEAN: |
435 |
case typelib_TypeClass_BOOLEAN: |
430 |
case typelib_TypeClass_BYTE: |
436 |
case typelib_TypeClass_BYTE: |
431 |
pCallStack[1] = (void*)*(char*)&nRegReturn; |
437 |
__asm__( "ld %0, %%l0\n\t" |
|
|
438 |
"ldsb [%%l0], %%i0\n" |
439 |
: : "m"(&nRegReturn) ); |
432 |
break; |
440 |
break; |
433 |
case typelib_TypeClass_CHAR: |
441 |
case typelib_TypeClass_CHAR: |
434 |
case typelib_TypeClass_SHORT: |
442 |
case typelib_TypeClass_SHORT: |
435 |
case typelib_TypeClass_UNSIGNED_SHORT: |
443 |
case typelib_TypeClass_UNSIGNED_SHORT: |
436 |
pCallStack[1] = (void*)*(short*)&nRegReturn; |
444 |
__asm__( "ld %0, %%l0\n\t" |
|
|
445 |
"ldsh [%%l0], %%i0\n" |
446 |
: : "m"(&nRegReturn) ); |
437 |
break; |
447 |
break; |
438 |
case typelib_TypeClass_DOUBLE: |
|
|
439 |
case typelib_TypeClass_HYPER: |
448 |
case typelib_TypeClass_HYPER: |
440 |
case typelib_TypeClass_UNSIGNED_HYPER: |
449 |
case typelib_TypeClass_UNSIGNED_HYPER: |
441 |
// move long to %i1 |
450 |
|
442 |
pCallStack[2] = ((void **)&nRegReturn)[ 1 ]; |
451 |
__asm__( "ld %0, %%l0\n\t" |
|
|
452 |
"ld [%%l0], %%i0\n\t" |
453 |
"ld %1, %%l0\n\t" |
454 |
"ld [%%l0], %%i1\n\t" |
455 |
: : "m"(&nRegReturn), "m"(((long*)&nRegReturn) +1) ); |
456 |
|
443 |
break; |
457 |
break; |
444 |
case typelib_TypeClass_FLOAT: |
458 |
case typelib_TypeClass_FLOAT: |
|
|
459 |
__asm__( "ld %0, %%l0\n\t" |
460 |
"ld [%%l0], %%f0\n" |
461 |
: : "m"(&nRegReturn) ); |
462 |
break; |
463 |
case typelib_TypeClass_DOUBLE: |
464 |
__asm__( "ld %0, %%l0\n\t" |
465 |
"ldd [%%l0], %%f0\n" |
466 |
: : "m"(&nRegReturn) ); |
467 |
break; |
468 |
case typelib_TypeClass_VOID: |
469 |
break; |
445 |
default: |
470 |
default: |
446 |
// move long to %i0 |
471 |
__asm__( "ld %0, %%l0\n\t" |
447 |
pCallStack[1] = ((void **)&nRegReturn)[ 0 ]; |
472 |
"ld [%%l0], %%i0\n" |
|
|
473 |
: : "m"(&nRegReturn) ); |
448 |
break; |
474 |
break; |
449 |
} |
475 |
} |
450 |
return aType; |
476 |
|
|
|
477 |
if( bComplex ) |
478 |
{ |
479 |
__asm__( "add %i7, 4, %i7\n\t" ); |
480 |
// after call to complex return valued funcion there is an unimp instruction |
481 |
} |
482 |
|
451 |
} |
483 |
} |
|
|
484 |
|
452 |
//__________________________________________________________________________________________________ |
485 |
//__________________________________________________________________________________________________ |
453 |
namespace { |
|
|
454 |
|
486 |
|
455 |
int const codeSnippetSize = 56; |
487 |
int const codeSnippetSize = 56; |
456 |
|
|
|
457 |
unsigned char * codeSnippet( |
488 |
unsigned char * codeSnippet( |
458 |
unsigned char * code, sal_Int32 functionIndex, sal_Int32 vtableOffset, |
489 |
unsigned char * code, sal_Int32 functionIndex, sal_Int32 vtableOffset, |
459 |
bool simpleRetType) |
490 |
bool simpleRetType) |
460 |
{ |
491 |
{ |
461 |
|
|
|
462 |
sal_uInt32 index = functionIndex; |
492 |
sal_uInt32 index = functionIndex; |
463 |
if (!simpleRetType) { |
493 |
if (!simpleRetType) { |
464 |
index |= 0x80000000; |
494 |
index |= 0x80000000; |