INTEGRATION: CWS sb29 (1.6.46); FILE MERGED
2005/02/01 15:36:20 sb 1.6.46.1: #i41817# When calling from binary UNO to C++, correctly remove from the stack the pointer to a class object return value.
This commit is contained in:
@@ -2,9 +2,9 @@
|
|||||||
*
|
*
|
||||||
* $RCSfile: cpp2uno.cxx,v $
|
* $RCSfile: cpp2uno.cxx,v $
|
||||||
*
|
*
|
||||||
* $Revision: 1.6 $
|
* $Revision: 1.7 $
|
||||||
*
|
*
|
||||||
* last change: $Author: obo $ $Date: 2004-06-04 02:59:45 $
|
* last change: $Author: vg $ $Date: 2005-02-21 12:13:28 $
|
||||||
*
|
*
|
||||||
* The Contents of this file are made available subject to the terms of
|
* The Contents of this file are made available subject to the terms of
|
||||||
* either of the following licenses
|
* either of the following licenses
|
||||||
@@ -77,7 +77,7 @@ namespace
|
|||||||
{
|
{
|
||||||
|
|
||||||
//==================================================================================================
|
//==================================================================================================
|
||||||
static typelib_TypeClass cpp2uno_call(
|
void cpp2uno_call(
|
||||||
bridges::cpp_uno::shared::CppInterfaceProxy * pThis,
|
bridges::cpp_uno::shared::CppInterfaceProxy * pThis,
|
||||||
const typelib_TypeDescription * pMemberTypeDescr,
|
const typelib_TypeDescription * pMemberTypeDescr,
|
||||||
typelib_TypeDescriptionReference * pReturnTypeRef, // 0 indicates void return
|
typelib_TypeDescriptionReference * pReturnTypeRef, // 0 indicates void return
|
||||||
@@ -209,8 +209,6 @@ static typelib_TypeClass cpp2uno_call(
|
|||||||
CPPU_CURRENT_NAMESPACE::raiseException(
|
CPPU_CURRENT_NAMESPACE::raiseException(
|
||||||
&aUnoExc, pThis->getBridge()->getUno2Cpp() );
|
&aUnoExc, pThis->getBridge()->getUno2Cpp() );
|
||||||
// has to destruct the any
|
// has to destruct the any
|
||||||
// is here for dummy
|
|
||||||
return typelib_TypeClass_VOID;
|
|
||||||
}
|
}
|
||||||
else // else no exception occured...
|
else // else no exception occured...
|
||||||
{
|
{
|
||||||
@@ -247,22 +245,16 @@ static typelib_TypeClass cpp2uno_call(
|
|||||||
}
|
}
|
||||||
if (pReturnTypeDescr)
|
if (pReturnTypeDescr)
|
||||||
{
|
{
|
||||||
typelib_TypeClass eRet = (typelib_TypeClass)pReturnTypeDescr->eTypeClass;
|
|
||||||
TYPELIB_DANGER_RELEASE( pReturnTypeDescr );
|
TYPELIB_DANGER_RELEASE( pReturnTypeDescr );
|
||||||
return eRet;
|
|
||||||
}
|
}
|
||||||
else
|
|
||||||
return typelib_TypeClass_VOID;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//==================================================================================================
|
//==================================================================================================
|
||||||
static typelib_TypeClass cpp_mediate(
|
extern "C" void cpp_vtable_call(
|
||||||
sal_Int32 nFunctionIndex,
|
int nFunctionIndex, int nVtableOffset, void** pCallStack,
|
||||||
sal_Int32 nVtableOffset,
|
sal_Int64 nRegReturn )
|
||||||
void ** pCallStack,
|
|
||||||
sal_Int64 * pRegisterReturn /* space for register return */ )
|
|
||||||
{
|
{
|
||||||
OSL_ENSURE( sizeof(sal_Int32)==sizeof(void *), "### unexpected!" );
|
OSL_ENSURE( sizeof(sal_Int32)==sizeof(void *), "### unexpected!" );
|
||||||
|
|
||||||
@@ -298,7 +290,6 @@ static typelib_TypeClass cpp_mediate(
|
|||||||
|
|
||||||
TypeDescription aMemberDescr( pTypeDescr->ppAllMembers[nMemberPos] );
|
TypeDescription aMemberDescr( pTypeDescr->ppAllMembers[nMemberPos] );
|
||||||
|
|
||||||
typelib_TypeClass eRet;
|
|
||||||
switch (aMemberDescr.get()->eTypeClass)
|
switch (aMemberDescr.get()->eTypeClass)
|
||||||
{
|
{
|
||||||
case typelib_TypeClass_INTERFACE_ATTRIBUTE:
|
case typelib_TypeClass_INTERFACE_ATTRIBUTE:
|
||||||
@@ -306,11 +297,11 @@ static typelib_TypeClass cpp_mediate(
|
|||||||
if (pTypeDescr->pMapMemberIndexToFunctionIndex[nMemberPos] == nFunctionIndex)
|
if (pTypeDescr->pMapMemberIndexToFunctionIndex[nMemberPos] == nFunctionIndex)
|
||||||
{
|
{
|
||||||
// is GET method
|
// is GET method
|
||||||
eRet = cpp2uno_call(
|
cpp2uno_call(
|
||||||
pCppI, aMemberDescr.get(),
|
pCppI, aMemberDescr.get(),
|
||||||
((typelib_InterfaceAttributeTypeDescription *)aMemberDescr.get())->pAttributeTypeRef,
|
((typelib_InterfaceAttributeTypeDescription *)aMemberDescr.get())->pAttributeTypeRef,
|
||||||
0, 0, // no params
|
0, 0, // no params
|
||||||
pCallStack, pRegisterReturn );
|
pCallStack, &nRegReturn );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -321,11 +312,11 @@ static typelib_TypeClass cpp_mediate(
|
|||||||
aParam.bIn = sal_True;
|
aParam.bIn = sal_True;
|
||||||
aParam.bOut = sal_False;
|
aParam.bOut = sal_False;
|
||||||
|
|
||||||
eRet = cpp2uno_call(
|
cpp2uno_call(
|
||||||
pCppI, aMemberDescr.get(),
|
pCppI, aMemberDescr.get(),
|
||||||
0, // indicates void return
|
0, // indicates void return
|
||||||
1, &aParam,
|
1, &aParam,
|
||||||
pCallStack, pRegisterReturn );
|
pCallStack, &nRegReturn );
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -336,11 +327,9 @@ static typelib_TypeClass cpp_mediate(
|
|||||||
{
|
{
|
||||||
case 1: // acquire()
|
case 1: // acquire()
|
||||||
pCppI->acquireProxy(); // non virtual call!
|
pCppI->acquireProxy(); // non virtual call!
|
||||||
eRet = typelib_TypeClass_VOID;
|
|
||||||
break;
|
break;
|
||||||
case 2: // release()
|
case 2: // release()
|
||||||
pCppI->releaseProxy(); // non virtual call!
|
pCppI->releaseProxy(); // non virtual call!
|
||||||
eRet = typelib_TypeClass_VOID;
|
|
||||||
break;
|
break;
|
||||||
case 0: // queryInterface() opt
|
case 0: // queryInterface() opt
|
||||||
{
|
{
|
||||||
@@ -361,20 +350,19 @@ static typelib_TypeClass cpp_mediate(
|
|||||||
&pInterface, pTD, cpp_acquire );
|
&pInterface, pTD, cpp_acquire );
|
||||||
pInterface->release();
|
pInterface->release();
|
||||||
TYPELIB_DANGER_RELEASE( pTD );
|
TYPELIB_DANGER_RELEASE( pTD );
|
||||||
*(void **)pRegisterReturn = pCallStack[1];
|
*(void **)&nRegReturn = pCallStack[1];
|
||||||
eRet = typelib_TypeClass_ANY;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
TYPELIB_DANGER_RELEASE( pTD );
|
TYPELIB_DANGER_RELEASE( pTD );
|
||||||
}
|
}
|
||||||
} // else perform queryInterface()
|
} // else perform queryInterface()
|
||||||
default:
|
default:
|
||||||
eRet = cpp2uno_call(
|
cpp2uno_call(
|
||||||
pCppI, aMemberDescr.get(),
|
pCppI, aMemberDescr.get(),
|
||||||
((typelib_InterfaceMethodTypeDescription *)aMemberDescr.get())->pReturnTypeRef,
|
((typelib_InterfaceMethodTypeDescription *)aMemberDescr.get())->pReturnTypeRef,
|
||||||
((typelib_InterfaceMethodTypeDescription *)aMemberDescr.get())->nParams,
|
((typelib_InterfaceMethodTypeDescription *)aMemberDescr.get())->nParams,
|
||||||
((typelib_InterfaceMethodTypeDescription *)aMemberDescr.get())->pParams,
|
((typelib_InterfaceMethodTypeDescription *)aMemberDescr.get())->pParams,
|
||||||
pCallStack, pRegisterReturn );
|
pCallStack, &nRegReturn );
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -383,72 +371,55 @@ static typelib_TypeClass cpp_mediate(
|
|||||||
throw RuntimeException(
|
throw RuntimeException(
|
||||||
rtl::OUString::createFromAscii("no member description found!"),
|
rtl::OUString::createFromAscii("no member description found!"),
|
||||||
(XInterface *)pThis );
|
(XInterface *)pThis );
|
||||||
// is here for dummy
|
|
||||||
eRet = typelib_TypeClass_VOID;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return eRet;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//==================================================================================================
|
//==================================================================================================
|
||||||
/**
|
extern "C" void privateSnippetExecutorGeneral();
|
||||||
* is called on incoming vtable calls
|
extern "C" void privateSnippetExecutorVoid();
|
||||||
* (called by asm snippets)
|
extern "C" void privateSnippetExecutorHyper();
|
||||||
*/
|
extern "C" void privateSnippetExecutorFloat();
|
||||||
static void cpp_vtable_call(
|
extern "C" void privateSnippetExecutorDouble();
|
||||||
int nFunctionIndex, int nVtableOffset, void** pCallStack )
|
extern "C" void privateSnippetExecutorClass();
|
||||||
__attribute__((regparm(3)));
|
extern "C" typedef void (*PrivateSnippetExecutor)();
|
||||||
|
|
||||||
void cpp_vtable_call( int nFunctionIndex, int nVtableOffset, void** pCallStack )
|
int const codeSnippetSize = 16;
|
||||||
{
|
|
||||||
volatile long nRegReturn[2];
|
|
||||||
typelib_TypeClass aType = cpp_mediate(
|
|
||||||
nFunctionIndex, nVtableOffset, pCallStack, (sal_Int64*)nRegReturn );
|
|
||||||
|
|
||||||
switch( aType )
|
|
||||||
{
|
|
||||||
case typelib_TypeClass_HYPER:
|
|
||||||
case typelib_TypeClass_UNSIGNED_HYPER:
|
|
||||||
__asm__( "movl %1, %%edx\n\t"
|
|
||||||
"movl %0, %%eax\n"
|
|
||||||
: : "m"(nRegReturn[0]), "m"(nRegReturn[1]) );
|
|
||||||
break;
|
|
||||||
case typelib_TypeClass_FLOAT:
|
|
||||||
__asm__( "flds %0\n\t"
|
|
||||||
"fstp %%st(0)\n\t"
|
|
||||||
"flds %0\n"
|
|
||||||
: : "m"(*(float *)nRegReturn) );
|
|
||||||
break;
|
|
||||||
case typelib_TypeClass_DOUBLE:
|
|
||||||
__asm__( "fldl %0\n\t"
|
|
||||||
"fstp %%st(0)\n\t"
|
|
||||||
"fldl %0\n"
|
|
||||||
: : "m"(*(double *)nRegReturn) );
|
|
||||||
break;
|
|
||||||
// case typelib_TypeClass_UNSIGNED_SHORT:
|
|
||||||
// case typelib_TypeClass_SHORT:
|
|
||||||
// __asm__( "movswl %0, %%eax\n"
|
|
||||||
// : : "m"(nRegReturn) );
|
|
||||||
// break;
|
|
||||||
default:
|
|
||||||
__asm__( "movl %0, %%eax\n"
|
|
||||||
: : "m"(nRegReturn[0]) );
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//==================================================================================================
|
|
||||||
int const codeSnippetSize = 20;
|
|
||||||
|
|
||||||
unsigned char * codeSnippet(
|
unsigned char * codeSnippet(
|
||||||
unsigned char * code, sal_Int32 functionIndex, sal_Int32 vtableOffset,
|
unsigned char * code, sal_Int32 functionIndex, sal_Int32 vtableOffset,
|
||||||
bool simpleRetType)
|
typelib_TypeClass returnTypeClass)
|
||||||
{
|
{
|
||||||
if (!simpleRetType) {
|
if (!bridges::cpp_uno::shared::isSimpleType(returnTypeClass)) {
|
||||||
functionIndex |= 0x80000000;
|
functionIndex |= 0x80000000;
|
||||||
}
|
}
|
||||||
|
PrivateSnippetExecutor exec;
|
||||||
|
switch (returnTypeClass) {
|
||||||
|
case typelib_TypeClass_VOID:
|
||||||
|
exec = privateSnippetExecutorVoid;
|
||||||
|
break;
|
||||||
|
case typelib_TypeClass_HYPER:
|
||||||
|
case typelib_TypeClass_UNSIGNED_HYPER:
|
||||||
|
exec = privateSnippetExecutorHyper;
|
||||||
|
break;
|
||||||
|
case typelib_TypeClass_FLOAT:
|
||||||
|
exec = privateSnippetExecutorFloat;
|
||||||
|
break;
|
||||||
|
case typelib_TypeClass_DOUBLE:
|
||||||
|
exec = privateSnippetExecutorDouble;
|
||||||
|
break;
|
||||||
|
case typelib_TypeClass_STRING:
|
||||||
|
case typelib_TypeClass_TYPE:
|
||||||
|
case typelib_TypeClass_ANY:
|
||||||
|
case typelib_TypeClass_SEQUENCE:
|
||||||
|
case typelib_TypeClass_STRUCT:
|
||||||
|
case typelib_TypeClass_INTERFACE:
|
||||||
|
exec = privateSnippetExecutorClass;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
exec = privateSnippetExecutorGeneral;
|
||||||
|
break;
|
||||||
|
}
|
||||||
unsigned char * p = code;
|
unsigned char * p = code;
|
||||||
OSL_ASSERT(sizeof (sal_Int32) == 4);
|
OSL_ASSERT(sizeof (sal_Int32) == 4);
|
||||||
// mov function_index, %eax:
|
// mov function_index, %eax:
|
||||||
@@ -459,13 +430,10 @@ unsigned char * codeSnippet(
|
|||||||
*p++ = 0xBA;
|
*p++ = 0xBA;
|
||||||
*reinterpret_cast< sal_Int32 * >(p) = vtableOffset;
|
*reinterpret_cast< sal_Int32 * >(p) = vtableOffset;
|
||||||
p += sizeof (sal_Int32);
|
p += sizeof (sal_Int32);
|
||||||
// mov %esp, %ecx:
|
// jmp privateSnippetExecutor:
|
||||||
*p++ = 0x89;
|
|
||||||
*p++ = 0xE1;
|
|
||||||
// jmp cpp_vtable_call:
|
|
||||||
*p++ = 0xE9;
|
*p++ = 0xE9;
|
||||||
*reinterpret_cast< sal_Int32 * >(p)
|
*reinterpret_cast< sal_Int32 * >(p)
|
||||||
= ((unsigned char *) cpp_vtable_call) - p - sizeof (sal_Int32);
|
= ((unsigned char *) exec) - p - sizeof (sal_Int32);
|
||||||
p += sizeof (sal_Int32);
|
p += sizeof (sal_Int32);
|
||||||
OSL_ASSERT(p - code <= codeSnippetSize);
|
OSL_ASSERT(p - code <= codeSnippetSize);
|
||||||
return code + codeSnippetSize;
|
return code + codeSnippetSize;
|
||||||
@@ -504,17 +472,17 @@ unsigned char * bridges::cpp_uno::shared::VtableFactory::addLocalFunctions(
|
|||||||
*slots++ = code;
|
*slots++ = code;
|
||||||
code = codeSnippet(
|
code = codeSnippet(
|
||||||
code, functionOffset++, vtableOffset,
|
code, functionOffset++, vtableOffset,
|
||||||
bridges::cpp_uno::shared::isSimpleType(
|
reinterpret_cast< typelib_InterfaceAttributeTypeDescription * >(
|
||||||
reinterpret_cast<
|
member)->pAttributeTypeRef->eTypeClass);
|
||||||
typelib_InterfaceAttributeTypeDescription * >(
|
|
||||||
member)->pAttributeTypeRef));
|
|
||||||
// Setter:
|
// Setter:
|
||||||
if (!reinterpret_cast<
|
if (!reinterpret_cast<
|
||||||
typelib_InterfaceAttributeTypeDescription * >(
|
typelib_InterfaceAttributeTypeDescription * >(
|
||||||
member)->bReadOnly)
|
member)->bReadOnly)
|
||||||
{
|
{
|
||||||
*slots++ = code;
|
*slots++ = code;
|
||||||
code = codeSnippet(code, functionOffset++, vtableOffset, true);
|
code = codeSnippet(
|
||||||
|
code, functionOffset++, vtableOffset,
|
||||||
|
typelib_TypeClass_VOID);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -522,10 +490,8 @@ unsigned char * bridges::cpp_uno::shared::VtableFactory::addLocalFunctions(
|
|||||||
*slots++ = code;
|
*slots++ = code;
|
||||||
code = codeSnippet(
|
code = codeSnippet(
|
||||||
code, functionOffset++, vtableOffset,
|
code, functionOffset++, vtableOffset,
|
||||||
bridges::cpp_uno::shared::isSimpleType(
|
reinterpret_cast< typelib_InterfaceMethodTypeDescription * >(
|
||||||
reinterpret_cast<
|
member)->pReturnTypeRef->eTypeClass);
|
||||||
typelib_InterfaceMethodTypeDescription * >(
|
|
||||||
member)->pReturnTypeRef));
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
Reference in New Issue
Block a user