diff options
Diffstat (limited to 'bridges/source/cpp_uno/gcc3_linux_intel')
5 files changed, 150 insertions, 29 deletions
diff --git a/bridges/source/cpp_uno/gcc3_linux_intel/cpp2uno.cxx b/bridges/source/cpp_uno/gcc3_linux_intel/cpp2uno.cxx index 8e3c391ca..0850d5c53 100644 --- a/bridges/source/cpp_uno/gcc3_linux_intel/cpp2uno.cxx +++ b/bridges/source/cpp_uno/gcc3_linux_intel/cpp2uno.cxx @@ -1,3 +1,4 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /************************************************************************* * * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. @@ -67,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 } @@ -163,7 +164,7 @@ void cpp2uno_call( (*pThis->getUnoI()->pDispatcher)( pThis->getUnoI(), pMemberTypeDescr, pUnoReturn, pUnoArgs, &pUnoExc ); - // in case an exception occured... + // in case an exception occurred... if (pUnoExc) { // destruct temporary in/inout params @@ -182,7 +183,7 @@ void cpp2uno_call( &aUnoExc, pThis->getBridge()->getUno2Cpp() ); // has to destruct the any } - else // else no exception occured... + else // else no exception occurred... { // temporary params for ( ; nTempIndizes--; ) @@ -252,7 +253,7 @@ extern "C" void cpp_vtable_call( if (nFunctionIndex >= pTypeDescr->nMapFunctionIndexToMemberIndex) { throw RuntimeException( - rtl::OUString::createFromAscii("illegal vtable index!"), + rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "illegal vtable index!" )), (XInterface *)pThis ); } @@ -341,7 +342,7 @@ extern "C" void cpp_vtable_call( default: { throw RuntimeException( - rtl::OUString::createFromAscii("no member description found!"), + rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "no member description found!" )), (XInterface *)pThis ); } } @@ -358,15 +359,40 @@ extern "C" typedef void (*PrivateSnippetExecutor)(); int const codeSnippetSize = 16; +#if defined (FREEBSD) || defined(NETBSD) || defined(OPENBSD) || defined(MACOSX) || \ + defined(DRAGONFLY) +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; @@ -380,13 +406,25 @@ 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) || \ + defined(DRAGONFLY) + 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; @@ -454,7 +492,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 * >( @@ -463,7 +501,7 @@ unsigned char * bridges::cpp_uno::shared::VtableFactory::addLocalFunctions( (s++)->fn = code + writetoexecdiff; code = codeSnippet( code, writetoexecdiff, functionOffset++, vtableOffset, - typelib_TypeClass_VOID); + NULL); } break; @@ -472,7 +510,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: @@ -487,3 +525,5 @@ unsigned char * bridges::cpp_uno::shared::VtableFactory::addLocalFunctions( void bridges::cpp_uno::shared::VtableFactory::flushCode( unsigned char const *, unsigned char const *) {} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/bridges/source/cpp_uno/gcc3_linux_intel/except.cxx b/bridges/source/cpp_uno/gcc3_linux_intel/except.cxx index 04e70c5e9..51206fbe6 100644 --- a/bridges/source/cpp_uno/gcc3_linux_intel/except.cxx +++ b/bridges/source/cpp_uno/gcc3_linux_intel/except.cxx @@ -1,3 +1,4 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /************************************************************************* * * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. @@ -31,8 +32,9 @@ #include <stdio.h> #include <string.h> #include <dlfcn.h> +#include <boost/unordered_map.hpp> + #include <cxxabi.h> -#include <hash_map> #include <rtl/strbuf.hxx> #include <rtl/ustrbuf.hxx> @@ -46,7 +48,6 @@ #include "share.hxx" - using namespace ::std; using namespace ::osl; using namespace ::rtl; @@ -102,7 +103,7 @@ static OUString toUNOname( char const * p ) SAL_THROW( () ) //================================================================================================== class RTTI { - typedef hash_map< OUString, type_info *, OUStringHash > t_rtti_map; + typedef boost::unordered_map< OUString, type_info *, OUStringHash > t_rtti_map; Mutex m_mutex; t_rtti_map m_rttis; @@ -118,7 +119,11 @@ public: }; //__________________________________________________________________________________________________ RTTI::RTTI() SAL_THROW( () ) +#if defined(FREEBSD) && __FreeBSD_version < 702104 + : m_hApp( dlopen( 0, RTLD_NOW | RTLD_GLOBAL ) ) +#else : m_hApp( dlopen( 0, RTLD_LAZY ) ) +#endif { } //__________________________________________________________________________________________________ @@ -153,7 +158,11 @@ type_info * RTTI::getRTTI( typelib_CompoundTypeDescription *pTypeDescr ) SAL_THR buf.append( 'E' ); OString symName( buf.makeStringAndClear() ); +#if defined(FREEBSD) && __FreeBSD_version < 702104 /* #i22253# */ + rtti = (type_info *)dlsym( RTLD_DEFAULT, symName.getStr() ); +#else rtti = (type_info *)dlsym( m_hApp, symName.getStr() ); +#endif if (rtti) { @@ -229,7 +238,7 @@ void raiseException( uno_Any * pUnoExc, uno_Mapping * pUno2Cpp ) OUStringToOString( *reinterpret_cast< OUString const * >( &pUnoExc->pType->pTypeName ), RTL_TEXTENCODING_ASCII_US ) ); - fprintf( stderr, "> uno exception occured: %s\n", cstr.getStr() ); + fprintf( stderr, "> uno exception occurred: %s\n", cstr.getStr() ); #endif void * pCppExc; type_info * rtti; @@ -294,7 +303,7 @@ void fillUnoException( __cxa_exception * header, uno_Any * pUnoExc, uno_Mapping uno_type_any_constructAndConvert( pUnoExc, &aRE, rType.getTypeLibType(), pCpp2Uno ); #if OSL_DEBUG_LEVEL > 0 OString cstr( OUStringToOString( aRE.Message, RTL_TEXTENCODING_ASCII_US ) ); - OSL_ENSURE( 0, cstr.getStr() ); + OSL_FAIL( cstr.getStr() ); #endif return; } @@ -303,7 +312,7 @@ void fillUnoException( __cxa_exception * header, uno_Any * pUnoExc, uno_Mapping OUString unoName( toUNOname( header->exceptionType->name() ) ); #if OSL_DEBUG_LEVEL > 1 OString cstr_unoName( OUStringToOString( unoName, RTL_TEXTENCODING_ASCII_US ) ); - fprintf( stderr, "> c++ exception occured: %s\n", cstr_unoName.getStr() ); + fprintf( stderr, "> c++ exception occurred: %s\n", cstr_unoName.getStr() ); #endif typelib_typedescription_getByName( &pExcTypeDescr, unoName.pData ); if (0 == pExcTypeDescr) @@ -315,7 +324,7 @@ void fillUnoException( __cxa_exception * header, uno_Any * pUnoExc, uno_Mapping uno_type_any_constructAndConvert( pUnoExc, &aRE, rType.getTypeLibType(), pCpp2Uno ); #if OSL_DEBUG_LEVEL > 0 OString cstr( OUStringToOString( aRE.Message, RTL_TEXTENCODING_ASCII_US ) ); - OSL_ENSURE( 0, cstr.getStr() ); + OSL_FAIL( cstr.getStr() ); #endif } else @@ -328,3 +337,4 @@ void fillUnoException( __cxa_exception * header, uno_Any * pUnoExc, uno_Mapping } +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/bridges/source/cpp_uno/gcc3_linux_intel/makefile.mk b/bridges/source/cpp_uno/gcc3_linux_intel/makefile.mk index d5eb2dd6e..beedf9daf 100644 --- a/bridges/source/cpp_uno/gcc3_linux_intel/makefile.mk +++ b/bridges/source/cpp_uno/gcc3_linux_intel/makefile.mk @@ -38,7 +38,11 @@ ENABLE_EXCEPTIONS=TRUE # --- Files -------------------------------------------------------- -.IF "$(COM)$(OS)$(CPU)$(COMNAME)" == "GCCLINUXIgcc3" +.IF "$(COM)$(OS)$(CPU)$(COMNAME)" == "GCCLINUXIgcc3" || \ + "$(COM)$(OS)$(CPU)$(COMNAME)" == "GCCOPENBSDIgcc3" || \ + "$(COM)$(OS)$(CPU)$(COMNAME)" == "GCCFREEBSDIgcc3" || \ + "$(COM)$(OS)$(CPU)$(COMNAME)" == "GCCNETBSDIgcc3" || \ + "$(COM)$(OS)$(CPU)$(COMNAME)" == "GCCDRAGONFLYIgcc3" .IF "$(cppu_no_leak)" == "" CFLAGS += -DLEAK_STATIC_DATA @@ -46,7 +50,7 @@ CFLAGS += -DLEAK_STATIC_DATA # In case someone enabled the non-standard -fomit-frame-pointer which does not # work with the .cxx sources in this directory: -CFLAGSCXX += -fno-omit-frame-pointer +CFLAGSCXX += -fno-omit-frame-pointer -fno-strict-aliasing CFLAGSNOOPT=-O0 diff --git a/bridges/source/cpp_uno/gcc3_linux_intel/share.hxx b/bridges/source/cpp_uno/gcc3_linux_intel/share.hxx index f825e295c..f7dc2f956 100644 --- a/bridges/source/cpp_uno/gcc3_linux_intel/share.hxx +++ b/bridges/source/cpp_uno/gcc3_linux_intel/share.hxx @@ -1,3 +1,4 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /************************************************************************* * * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. @@ -87,4 +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: */ diff --git a/bridges/source/cpp_uno/gcc3_linux_intel/uno2cpp.cxx b/bridges/source/cpp_uno/gcc3_linux_intel/uno2cpp.cxx index 27a7c902b..dca8e69f5 100644 --- a/bridges/source/cpp_uno/gcc3_linux_intel/uno2cpp.cxx +++ b/bridges/source/cpp_uno/gcc3_linux_intel/uno2cpp.cxx @@ -1,3 +1,4 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /************************************************************************* * * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. @@ -28,7 +29,11 @@ // MARKER(update_precomp.py): autogen include statement, do not remove #include "precompiled_bridges.hxx" +#if defined (FREEBSD) || defined(NETBSD) || defined(OPENBSD) || defined(DRAGONFLY) +#include <stdlib.h> +#else #include <malloc.h> +#endif #include <com/sun/star/uno/genfunc.hxx> #include "com/sun/star/uno/RuntimeException.hpp" @@ -58,7 +63,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)); @@ -66,7 +71,7 @@ void callVirtualMethod( void * pAdjustedThisPtr, sal_Int32 nVtableIndex, void * pRegisterReturn, - typelib_TypeClass eReturnType, + typelib_TypeDescription * pReturnTypeDescr, bool bSimpleReturn, sal_Int32 * pStackLongs, sal_Int32 nStackLongs ) { @@ -119,8 +124,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; @@ -145,7 +152,21 @@ void callVirtualMethod( asm ( "fstpl %0\n\t" : : "m"(*(char *)pRegisterReturn) ); break; default: + { +#if defined (FREEBSD) || defined(NETBSD) || defined(OPENBSD) || defined(MACOSX) || \ + defined(DRAGONFLY) + 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; + } } } @@ -168,10 +189,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 } @@ -268,9 +291,9 @@ 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... + // NO exception occurred... *ppUnoExc = 0; // reconvert temporary params @@ -327,6 +350,39 @@ 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) || defined(DRAGONFLY) + // 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( @@ -449,3 +505,5 @@ void unoInterfaceProxyDispatch( } } } } + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |