fix bsd bridges
(cherry picked from commit a5ac1c19ca78b6549d2dc7381ddd31ae839288ec)
This commit is contained in:
parent
96411be554
commit
992d8305dd
3 changed files with 105 additions and 15 deletions
|
@ -68,7 +68,7 @@ void cpp2uno_call(
|
|||
|
||||
if (pReturnTypeDescr)
|
||||
{
|
||||
if (bridges::cpp_uno::shared::isSimpleType( pReturnTypeDescr ))
|
||||
if (x86::isSimpleReturnType( pReturnTypeDescr ))
|
||||
{
|
||||
pUnoReturn = pReturnValue; // direct way for simple types
|
||||
}
|
||||
|
@ -359,15 +359,39 @@ extern "C" typedef void (*PrivateSnippetExecutor)();
|
|||
|
||||
int const codeSnippetSize = 16;
|
||||
|
||||
#if defined (FREEBSD) || defined(NETBSD) || defined(OPENBSD) || defined(MACOSX)
|
||||
namespace
|
||||
{
|
||||
PrivateSnippetExecutor returnsInRegister(typelib_TypeDescriptionReference * pReturnTypeRef)
|
||||
{
|
||||
//These archs apparently are returning small structs in registers, while Linux
|
||||
//doesn't
|
||||
PrivateSnippetExecutor exec=NULL;
|
||||
|
||||
typelib_TypeDescription * pReturnTypeDescr = 0;
|
||||
TYPELIB_DANGER_GET( &pReturnTypeDescr, pReturnTypeRef );
|
||||
const bool bSimpleReturnStruct = x86::isSimpleReturnType(pReturnTypeDescr);
|
||||
const sal_Int32 nRetSize = pReturnTypeDescr->nSize;
|
||||
TYPELIB_DANGER_RELEASE( pReturnTypeDescr );
|
||||
if (bSimpleReturnStruct)
|
||||
{
|
||||
exec = privateSnippetExecutorGeneral; // fills eax
|
||||
if (nRetSize > 4)
|
||||
exec = privateSnippetExecutorHyper; // fills eax/edx
|
||||
}
|
||||
return exec;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
unsigned char * codeSnippet(
|
||||
unsigned char * code, sal_PtrDiff writetoexecdiff, sal_Int32 functionIndex, sal_Int32 vtableOffset,
|
||||
typelib_TypeClass returnTypeClass)
|
||||
typelib_TypeDescriptionReference * pReturnTypeRef)
|
||||
{
|
||||
if (!bridges::cpp_uno::shared::isSimpleType(returnTypeClass)) {
|
||||
functionIndex |= 0x80000000;
|
||||
}
|
||||
PrivateSnippetExecutor exec;
|
||||
switch (returnTypeClass) {
|
||||
typelib_TypeClass eReturnClass = pReturnTypeRef ? pReturnTypeRef->eTypeClass : typelib_TypeClass_VOID;
|
||||
switch (eReturnClass)
|
||||
{
|
||||
case typelib_TypeClass_VOID:
|
||||
exec = privateSnippetExecutorVoid;
|
||||
break;
|
||||
|
@ -381,13 +405,24 @@ unsigned char * codeSnippet(
|
|||
case typelib_TypeClass_DOUBLE:
|
||||
exec = privateSnippetExecutorDouble;
|
||||
break;
|
||||
case typelib_TypeClass_STRUCT:
|
||||
case typelib_TypeClass_EXCEPTION:
|
||||
#if defined (FREEBSD) || defined(NETBSD) || defined(OPENBSD) || defined(MACOSX)
|
||||
exec = returnsInRegister(pReturnTypeRef);
|
||||
if (!exec)
|
||||
{
|
||||
exec = privateSnippetExecutorClass;
|
||||
functionIndex |= 0x80000000;
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
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;
|
||||
functionIndex |= 0x80000000;
|
||||
break;
|
||||
default:
|
||||
exec = privateSnippetExecutorGeneral;
|
||||
|
@ -455,7 +490,7 @@ unsigned char * bridges::cpp_uno::shared::VtableFactory::addLocalFunctions(
|
|||
code = codeSnippet(
|
||||
code, writetoexecdiff, functionOffset++, vtableOffset,
|
||||
reinterpret_cast< typelib_InterfaceAttributeTypeDescription * >(
|
||||
member)->pAttributeTypeRef->eTypeClass);
|
||||
member)->pAttributeTypeRef);
|
||||
// Setter:
|
||||
if (!reinterpret_cast<
|
||||
typelib_InterfaceAttributeTypeDescription * >(
|
||||
|
@ -464,7 +499,7 @@ unsigned char * bridges::cpp_uno::shared::VtableFactory::addLocalFunctions(
|
|||
(s++)->fn = code + writetoexecdiff;
|
||||
code = codeSnippet(
|
||||
code, writetoexecdiff, functionOffset++, vtableOffset,
|
||||
typelib_TypeClass_VOID);
|
||||
NULL);
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -473,7 +508,7 @@ unsigned char * bridges::cpp_uno::shared::VtableFactory::addLocalFunctions(
|
|||
code = codeSnippet(
|
||||
code, writetoexecdiff, functionOffset++, vtableOffset,
|
||||
reinterpret_cast< typelib_InterfaceMethodTypeDescription * >(
|
||||
member)->pReturnTypeRef->eTypeClass);
|
||||
member)->pReturnTypeRef);
|
||||
break;
|
||||
|
||||
default:
|
||||
|
|
|
@ -88,6 +88,12 @@ void raiseException(
|
|||
//==================================================================================================
|
||||
void fillUnoException(
|
||||
__cxa_exception * header, uno_Any *, uno_Mapping * pCpp2Uno );
|
||||
|
||||
}
|
||||
|
||||
namespace x86
|
||||
{
|
||||
bool isSimpleReturnType(typelib_TypeDescription * pTD, bool recursive = false);
|
||||
}
|
||||
|
||||
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|
||||
|
|
|
@ -59,7 +59,7 @@ void callVirtualMethod(
|
|||
void * pAdjustedThisPtr,
|
||||
sal_Int32 nVtableIndex,
|
||||
void * pRegisterReturn,
|
||||
typelib_TypeClass eReturnType,
|
||||
typelib_TypeDescription * pReturnTypeDescr, bool bSimpleReturn,
|
||||
sal_Int32 * pStackLongs,
|
||||
sal_Int32 nStackLongs ) __attribute__((noinline));
|
||||
|
||||
|
@ -67,7 +67,7 @@ void callVirtualMethod(
|
|||
void * pAdjustedThisPtr,
|
||||
sal_Int32 nVtableIndex,
|
||||
void * pRegisterReturn,
|
||||
typelib_TypeClass eReturnType,
|
||||
typelib_TypeDescription * pReturnTypeDescr, bool bSimpleReturn,
|
||||
sal_Int32 * pStackLongs,
|
||||
sal_Int32 nStackLongs )
|
||||
{
|
||||
|
@ -120,8 +120,10 @@ void callVirtualMethod(
|
|||
: "m"(nStackLongs), "m"(pStackLongs), "m"(pAdjustedThisPtr),
|
||||
"m"(nVtableIndex), "m"(eax), "m"(edx), "m"(stackptr)
|
||||
: "eax", "edx" );
|
||||
switch( eReturnType )
|
||||
switch( pReturnTypeDescr->eTypeClass )
|
||||
{
|
||||
case typelib_TypeClass_VOID:
|
||||
break;
|
||||
case typelib_TypeClass_HYPER:
|
||||
case typelib_TypeClass_UNSIGNED_HYPER:
|
||||
((long*)pRegisterReturn)[1] = edx;
|
||||
|
@ -146,9 +148,22 @@ void callVirtualMethod(
|
|||
asm ( "fstpl %0\n\t" : : "m"(*(char *)pRegisterReturn) );
|
||||
break;
|
||||
default:
|
||||
{
|
||||
#if defined (FREEBSD) || defined(NETBSD) || defined(OPENBSD) || defined(MACOSX)
|
||||
sal_Int32 const nRetSize = pReturnTypeDescr->nSize;
|
||||
if (bSimpleReturn && nRetSize <= 8 && nRetSize > 0)
|
||||
{
|
||||
if (nRetSize > 4)
|
||||
static_cast<long *>(pRegisterReturn)[1] = edx;
|
||||
static_cast<long *>(pRegisterReturn)[0] = eax;
|
||||
}
|
||||
#else
|
||||
(void)bSimpleReturn;
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//==================================================================================================
|
||||
static void cpp_call(
|
||||
|
@ -169,10 +184,12 @@ static void cpp_call(
|
|||
OSL_ENSURE( pReturnTypeDescr, "### expected return type description!" );
|
||||
|
||||
void * pCppReturn = 0; // if != 0 && != pUnoReturn, needs reconversion
|
||||
bool bSimpleReturn = true;
|
||||
|
||||
if (pReturnTypeDescr)
|
||||
{
|
||||
if (bridges::cpp_uno::shared::isSimpleType( pReturnTypeDescr ))
|
||||
bSimpleReturn = x86::isSimpleReturnType(pReturnTypeDescr);
|
||||
if (bSimpleReturn)
|
||||
{
|
||||
pCppReturn = pUnoReturn; // direct way for simple types
|
||||
}
|
||||
|
@ -269,7 +286,7 @@ static void cpp_call(
|
|||
OSL_ENSURE( !( (pCppStack - pCppStackStart ) & 3), "UNALIGNED STACK !!! (Please DO panic)" );
|
||||
callVirtualMethod(
|
||||
pAdjustedThisPtr, aVtableSlot.index,
|
||||
pCppReturn, pReturnTypeDescr->eTypeClass,
|
||||
pCppReturn, pReturnTypeDescr, bSimpleReturn,
|
||||
(sal_Int32 *)pCppStackStart, (pCppStack - pCppStackStart) / sizeof(sal_Int32) );
|
||||
// NO exception occured...
|
||||
*ppUnoExc = 0;
|
||||
|
@ -328,6 +345,38 @@ static void cpp_call(
|
|||
|
||||
}
|
||||
|
||||
namespace x86
|
||||
{
|
||||
bool isSimpleReturnType(typelib_TypeDescription * pTD, bool recursive)
|
||||
{
|
||||
if (bridges::cpp_uno::shared::isSimpleType( pTD ))
|
||||
return true;
|
||||
#if defined (FREEBSD) || defined(NETBSD) || defined(OPENBSD) || defined(MACOSX)
|
||||
// Only structs of exactly 1, 2, 4, or 8 bytes are returned through
|
||||
// registers, see <http://developer.apple.com/documentation/DeveloperTools/
|
||||
// Conceptual/LowLevelABI/Articles/IA32.html>:
|
||||
if (pTD->eTypeClass == typelib_TypeClass_STRUCT &&
|
||||
(recursive || pTD->nSize <= 2 || pTD->nSize == 4 || pTD->nSize == 8))
|
||||
{
|
||||
typelib_CompoundTypeDescription *const pCompTD =
|
||||
(typelib_CompoundTypeDescription *) pTD;
|
||||
for ( sal_Int32 pos = pCompTD->nMembers; pos--; ) {
|
||||
typelib_TypeDescription * pMemberTD = 0;
|
||||
TYPELIB_DANGER_GET( &pMemberTD, pCompTD->ppTypeRefs[pos] );
|
||||
bool const b = isSimpleReturnType(pMemberTD, true);
|
||||
TYPELIB_DANGER_RELEASE( pMemberTD );
|
||||
if (! b)
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
#else
|
||||
(void)recursive;
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
namespace bridges { namespace cpp_uno { namespace shared {
|
||||
|
||||
void unoInterfaceProxyDispatch(
|
||||
|
|
Loading…
Reference in a new issue