diff options
author | Jens-Heiner Rechtien <hr@openoffice.org> | 2004-02-03 11:36:30 +0000 |
---|---|---|
committer | Jens-Heiner Rechtien <hr@openoffice.org> | 2004-02-03 11:36:30 +0000 |
commit | 841c727d6a91d733487395d449da5fed9638512b (patch) | |
tree | ef9a8dc5b43125a224ce59850d4d9bc65e4ae342 /bridges | |
parent | 007ce2a20cec76d1d399c3beea605173a2cd99a5 (diff) |
INTEGRATION: CWS sb10 (1.3.104); FILE MERGED
2004/01/08 15:42:07 sb 1.3.104.5: #114000# Cleaned up.
2004/01/08 13:45:43 sb 1.3.104.4: #114000# Factored out more shared code.
2003/12/19 16:15:52 sb 1.3.104.3: #114000# Factored out even more shared behaviour.
2003/12/10 10:49:20 sb 1.3.104.2: #114000# Removed debug-code debris.
2003/12/10 10:00:11 sb 1.3.104.1: #114000# Adapted to multiple-inheritance interface types.
Diffstat (limited to 'bridges')
-rw-r--r-- | bridges/source/cpp_uno/gcc3_linux_intel/cpp2uno.cxx | 331 |
1 files changed, 137 insertions, 194 deletions
diff --git a/bridges/source/cpp_uno/gcc3_linux_intel/cpp2uno.cxx b/bridges/source/cpp_uno/gcc3_linux_intel/cpp2uno.cxx index d3ef1136cdd1..0c105ac5b6da 100644 --- a/bridges/source/cpp_uno/gcc3_linux_intel/cpp2uno.cxx +++ b/bridges/source/cpp_uno/gcc3_linux_intel/cpp2uno.cxx @@ -2,9 +2,9 @@ * * $RCSfile: cpp2uno.cxx,v $ * - * $Revision: 1.3 $ + * $Revision: 1.4 $ * - * last change: $Author: dbo $ $Date: 2001-10-26 07:22:57 $ + * last change: $Author: hr $ $Date: 2004-02-03 12:36:30 $ * * The Contents of this file are made available subject to the terms of * either of the following licenses @@ -59,34 +59,25 @@ * ************************************************************************/ -#include <malloc.h> -#include <hash_map> - -#include <rtl/alloc.h> -#include <osl/mutex.hxx> - +#include <com/sun/star/uno/genfunc.hxx> #include <uno/data.h> #include <typelib/typedescription.hxx> -#include <bridges/cpp_uno/bridge.hxx> -#include <bridges/cpp_uno/type_misc.hxx> +#include "bridges/cpp_uno/shared/bridge.hxx" +#include "bridges/cpp_uno/shared/cppinterfaceproxy.hxx" +#include "bridges/cpp_uno/shared/types.hxx" +#include "bridges/cpp_uno/shared/vtablefactory.hxx" #include "share.hxx" - -using namespace ::osl; -using namespace ::rtl; using namespace ::com::sun::star::uno; -namespace CPPU_CURRENT_NAMESPACE +namespace { //================================================================================================== -rtl_StandardModuleCount g_moduleCount = MODULE_COUNT_INIT; - -//================================================================================================== static typelib_TypeClass cpp2uno_call( - cppu_cppInterfaceProxy * pThis, + bridges::cpp_uno::shared::CppInterfaceProxy * pThis, const typelib_TypeDescription * pMemberTypeDescr, typelib_TypeDescriptionReference * pReturnTypeRef, // 0 indicates void return sal_Int32 nParams, typelib_MethodParameter * pParams, @@ -106,7 +97,7 @@ static typelib_TypeClass cpp2uno_call( if (pReturnTypeDescr) { - if (cppu_isSimpleType( pReturnTypeDescr )) + if (bridges::cpp_uno::shared::isSimpleType( pReturnTypeDescr )) { pUnoReturn = pRegisterReturn; // direct way for simple types } @@ -115,7 +106,8 @@ static typelib_TypeClass cpp2uno_call( pCppReturn = *(void **)pCppStack; pCppStack += sizeof(void *); - pUnoReturn = (cppu_relatesToInterface( pReturnTypeDescr ) + pUnoReturn = (bridges::cpp_uno::shared::relatesToInterfaceType( + pReturnTypeDescr ) ? alloca( pReturnTypeDescr->nSize ) : pCppReturn); // direct way } @@ -141,7 +133,9 @@ static typelib_TypeClass cpp2uno_call( typelib_TypeDescription * pParamTypeDescr = 0; TYPELIB_DANGER_GET( &pParamTypeDescr, rParam.pTypeRef ); - if (!rParam.bOut && cppu_isSimpleType( pParamTypeDescr )) // value + if (!rParam.bOut + && bridges::cpp_uno::shared::isSimpleType( pParamTypeDescr )) + // value { pCppArgs[nPos] = pCppStack; pUnoArgs[nPos] = pCppStack; @@ -168,11 +162,12 @@ static typelib_TypeClass cpp2uno_call( ppTempParamTypeDescr[nTempIndizes++] = pParamTypeDescr; } // is in/inout - else if (cppu_relatesToInterface( pParamTypeDescr )) + else if (bridges::cpp_uno::shared::relatesToInterfaceType( + pParamTypeDescr )) { uno_copyAndConvertData( pUnoArgs[nPos] = alloca( pParamTypeDescr->nSize ), *(void **)pCppStack, pParamTypeDescr, - &pThis->pBridge->aCpp2Uno ); + pThis->getBridge()->getCpp2Uno() ); pTempIndizes[nTempIndizes] = nPos; // has to be reconverted // will be released at reconversion ppTempParamTypeDescr[nTempIndizes++] = pParamTypeDescr; @@ -192,7 +187,8 @@ static typelib_TypeClass cpp2uno_call( uno_Any * pUnoExc = &aUnoExc; // invoke uno dispatch call - (*pThis->pUnoI->pDispatcher)( pThis->pUnoI, pMemberTypeDescr, pUnoReturn, pUnoArgs, &pUnoExc ); + (*pThis->getUnoI()->pDispatcher)( + pThis->getUnoI(), pMemberTypeDescr, pUnoReturn, pUnoArgs, &pUnoExc ); // in case an exception occured... if (pUnoExc) @@ -209,7 +205,9 @@ static typelib_TypeClass cpp2uno_call( if (pReturnTypeDescr) TYPELIB_DANGER_RELEASE( pReturnTypeDescr ); - raiseException( &aUnoExc, &pThis->pBridge->aUno2Cpp ); // has to destruct the any + CPPU_CURRENT_NAMESPACE::raiseException( + &aUnoExc, pThis->getBridge()->getUno2Cpp() ); + // has to destruct the any // is here for dummy return typelib_TypeClass_VOID; } @@ -226,7 +224,7 @@ static typelib_TypeClass cpp2uno_call( // convert and assign uno_destructData( pCppArgs[nIndex], pParamTypeDescr, cpp_release ); uno_copyAndConvertData( pCppArgs[nIndex], pUnoArgs[nIndex], pParamTypeDescr, - &pThis->pBridge->aUno2Cpp ); + pThis->getBridge()->getUno2Cpp() ); } // destroy temp uno param uno_destructData( pUnoArgs[nIndex], pParamTypeDescr, 0 ); @@ -239,7 +237,7 @@ static typelib_TypeClass cpp2uno_call( if (pUnoReturn != pCppReturn) // needs reconversion { uno_copyAndConvertData( pCppReturn, pUnoReturn, pReturnTypeDescr, - &pThis->pBridge->aUno2Cpp ); + pThis->getBridge()->getUno2Cpp() ); // destroy temp uno return uno_destructData( pUnoReturn, pReturnTypeDescr, 0 ); } @@ -260,38 +258,41 @@ static typelib_TypeClass cpp2uno_call( //================================================================================================== static typelib_TypeClass cpp_mediate( - sal_Int32 nVtableCall, + sal_Int32 nFunctionIndex, + sal_Int32 nVtableOffset, void ** pCallStack, sal_Int64 * pRegisterReturn /* space for register return */ ) { OSL_ENSURE( sizeof(sal_Int32)==sizeof(void *), "### unexpected!" ); // pCallStack: ret adr, [ret *], this, params - // _this_ ptr is patched cppu_XInterfaceProxy object - cppu_cppInterfaceProxy * pCppI = NULL; - if( nVtableCall & 0x80000000 ) + void * pThis; + if( nFunctionIndex & 0x80000000 ) { - nVtableCall &= 0x7fffffff; - pCppI = (cppu_cppInterfaceProxy *)(XInterface *)*(pCallStack +2); + nFunctionIndex &= 0x7fffffff; + pThis = pCallStack[2]; } else { - pCppI = (cppu_cppInterfaceProxy *)(XInterface *)*(pCallStack +1); + pThis = pCallStack[1]; } + pThis = static_cast< char * >(pThis) - nVtableOffset; + bridges::cpp_uno::shared::CppInterfaceProxy * pCppI + = bridges::cpp_uno::shared::CppInterfaceProxy::castInterfaceToProxy( + pThis); - typelib_InterfaceTypeDescription * pTypeDescr = pCppI->pTypeDescr; + typelib_InterfaceTypeDescription * pTypeDescr = pCppI->getTypeDescr(); - OSL_ENSURE( nVtableCall < pTypeDescr->nMapFunctionIndexToMemberIndex, "### illegal vtable index!" ); - if (nVtableCall >= pTypeDescr->nMapFunctionIndexToMemberIndex) + OSL_ENSURE( nFunctionIndex < pTypeDescr->nMapFunctionIndexToMemberIndex, "### illegal vtable index!" ); + if (nFunctionIndex >= pTypeDescr->nMapFunctionIndexToMemberIndex) { throw RuntimeException( - OUString::createFromAscii("illegal vtable index!"), - (XInterface *)pCppI ); + rtl::OUString::createFromAscii("illegal vtable index!"), + (XInterface *)pThis ); } // determine called method - OSL_ENSURE( nVtableCall < pTypeDescr->nMapFunctionIndexToMemberIndex, "### illegal vtable index!" ); - sal_Int32 nMemberPos = pTypeDescr->pMapFunctionIndexToMemberIndex[nVtableCall]; + sal_Int32 nMemberPos = pTypeDescr->pMapFunctionIndexToMemberIndex[nFunctionIndex]; OSL_ENSURE( nMemberPos < pTypeDescr->nAllMembers, "### illegal member index!" ); TypeDescription aMemberDescr( pTypeDescr->ppAllMembers[nMemberPos] ); @@ -301,7 +302,7 @@ static typelib_TypeClass cpp_mediate( { case typelib_TypeClass_INTERFACE_ATTRIBUTE: { - if (pTypeDescr->pMapMemberIndexToFunctionIndex[nMemberPos] == nVtableCall) + if (pTypeDescr->pMapMemberIndexToFunctionIndex[nMemberPos] == nFunctionIndex) { // is GET method eRet = cpp2uno_call( @@ -330,7 +331,7 @@ static typelib_TypeClass cpp_mediate( case typelib_TypeClass_INTERFACE_METHOD: { // is METHOD - switch (nVtableCall) + switch (nFunctionIndex) { case 1: // acquire() pCppI->acquireProxy(); // non virtual call! @@ -347,9 +348,10 @@ static typelib_TypeClass cpp_mediate( if (pTD) { XInterface * pInterface = 0; - (*pCppI->pBridge->pCppEnv->getRegisteredInterface)( - pCppI->pBridge->pCppEnv, - (void **)&pInterface, pCppI->oid.pData, (typelib_InterfaceTypeDescription *)pTD ); + (*pCppI->getBridge()->getCppEnv()->getRegisteredInterface)( + pCppI->getBridge()->getCppEnv(), + (void **)&pInterface, pCppI->getOid().pData, + (typelib_InterfaceTypeDescription *)pTD ); if (pInterface) { @@ -378,8 +380,8 @@ static typelib_TypeClass cpp_mediate( default: { throw RuntimeException( - OUString::createFromAscii("no member description found!"), - (XInterface *)pCppI ); + rtl::OUString::createFromAscii("no member description found!"), + (XInterface *)pThis ); // is here for dummy eRet = typelib_TypeClass_VOID; } @@ -393,12 +395,15 @@ static typelib_TypeClass cpp_mediate( * is called on incoming vtable calls * (called by asm snippets) */ -static void cpp_vtable_call( int nTableEntry, void** pCallStack ) __attribute__((regparm(2))); +static void cpp_vtable_call( + int nFunctionIndex, int nVtableOffset, void** pCallStack ) + __attribute__((regparm(3))); -void cpp_vtable_call( int nTableEntry, void** pCallStack ) +void cpp_vtable_call( int nFunctionIndex, int nVtableOffset, void** pCallStack ) { volatile long nRegReturn[2]; - typelib_TypeClass aType = cpp_mediate( nTableEntry, pCallStack, (sal_Int64*)nRegReturn ); + typelib_TypeClass aType = cpp_mediate( + nFunctionIndex, nVtableOffset, pCallStack, (sal_Int64*)nRegReturn ); switch( aType ) { @@ -434,161 +439,99 @@ void cpp_vtable_call( int nTableEntry, void** pCallStack ) //================================================================================================== -class MediateClassData -{ - typedef ::std::hash_map< OUString, void *, OUStringHash > t_classdata_map; - t_classdata_map m_map; - Mutex m_mutex; - -public: - void const * get_vtable( typelib_InterfaceTypeDescription * pTD ) SAL_THROW( () ); - - inline MediateClassData() SAL_THROW( () ) - {} - ~MediateClassData() SAL_THROW( () ); -}; -//__________________________________________________________________________________________________ -MediateClassData::~MediateClassData() SAL_THROW( () ) -{ - OSL_TRACE( "> calling ~MediateClassData(): freeing mediate vtables." ); +int const codeSnippetSize = 20; - for ( t_classdata_map::const_iterator iPos( m_map.begin() ); iPos != m_map.end(); ++iPos ) - { - ::rtl_freeMemory( iPos->second ); +unsigned char * codeSnippet( + unsigned char * code, sal_Int32 functionIndex, sal_Int32 vtableOffset, + bool simpleRetType) +{ + if (!simpleRetType) { + functionIndex |= 0x80000000; } + unsigned char * p = code; + OSL_ASSERT(sizeof (sal_Int32) == 4); + // mov function_index, %eax: + *p++ = 0xB8; + *reinterpret_cast< sal_Int32 * >(p) = functionIndex; + p += sizeof (sal_Int32); + // mov vtable_offset, %edx: + *p++ = 0xBA; + *reinterpret_cast< sal_Int32 * >(p) = vtableOffset; + p += sizeof (sal_Int32); + // mov %esp, %ecx: + *p++ = 0x89; + *p++ = 0xE1; + // jmp cpp_vtable_call: + *p++ = 0xE9; + *reinterpret_cast< sal_Int32 * >(p) + = ((unsigned char *) cpp_vtable_call) - p - sizeof (sal_Int32); + p += sizeof (sal_Int32); + OSL_ASSERT(p - code <= codeSnippetSize); + return code + codeSnippetSize; +} + } -//-------------------------------------------------------------------------------------------------- -static inline void codeSnippet( char * code, sal_uInt32 vtable_pos, bool simple_ret_type ) SAL_THROW( () ) + +void ** bridges::cpp_uno::shared::VtableFactory::mapBlockToVtable(char * block) { - if (! simple_ret_type) - vtable_pos |= 0x80000000; - OSL_ASSERT( sizeof (long) == 4 ); - // mov $nPos, %eax - *code++ = 0xb8; - *(long *)code = vtable_pos; - code += sizeof (long); - // mov %esp, %edx - *code++ = 0x89; - *code++ = 0xe2; - // jmp cpp_vtable_call - *code++ = 0xe9; - *(long *)code = ((char *)cpp_vtable_call) - code - sizeof (long); + return reinterpret_cast< void ** >(block) + 2; } -//__________________________________________________________________________________________________ -void const * MediateClassData::get_vtable( typelib_InterfaceTypeDescription * pTD ) SAL_THROW( () ) + +char * bridges::cpp_uno::shared::VtableFactory::createBlock( + sal_Int32 slotCount, void *** slots) { - void * buffer; + char * block = new char[ + (slotCount + 2) * sizeof (void *) + slotCount * codeSnippetSize]; + *slots = mapBlockToVtable(block); + (*slots)[-2] = 0; + (*slots)[-1] = 0; + return block; +} - // avoiding locked counts - OUString const & unoName = *(OUString const *)&((typelib_TypeDescription *)pTD)->pTypeName; - { - MutexGuard aGuard( m_mutex ); - t_classdata_map::const_iterator iFind( m_map.find( unoName ) ); - if (iFind == m_map.end()) - { - // create new vtable - sal_Int32 nSlots = pTD->nMapFunctionIndexToMemberIndex; - buffer = ::rtl_allocateMemory( ((2+ nSlots) * sizeof (void *)) + (nSlots *20) ); - - ::std::pair< t_classdata_map::iterator, bool > insertion( - m_map.insert( t_classdata_map::value_type( unoName, buffer ) ) ); - OSL_ENSURE( insertion.second, "### inserting new vtable buffer failed?!" ); - - void ** slots = (void **)buffer; - *slots++ = 0; - *slots++ = 0; // rtti - char * code = (char *)(slots + nSlots); - - sal_uInt32 vtable_pos = 0; - sal_Int32 nAllMembers = pTD->nAllMembers; - typelib_TypeDescriptionReference ** ppAllMembers = pTD->ppAllMembers; - for ( sal_Int32 nPos = 0; nPos < nAllMembers; ++nPos ) - { - typelib_TypeDescription * pTD = 0; - TYPELIB_DANGER_GET( &pTD, ppAllMembers[ nPos ] ); - OSL_ASSERT( pTD ); - if (typelib_TypeClass_INTERFACE_ATTRIBUTE == pTD->eTypeClass) - { - bool simple_ret = cppu_isSimpleType( - ((typelib_InterfaceAttributeTypeDescription *)pTD)->pAttributeTypeRef->eTypeClass ); - // get method - *slots++ = code; - codeSnippet( code, vtable_pos++, simple_ret ); - code += 20; - if (! ((typelib_InterfaceAttributeTypeDescription *)pTD)->bReadOnly) - { - // set method - *slots++ = code; - codeSnippet( code, vtable_pos++, true ); - code += 20; - } - } - else +unsigned char * bridges::cpp_uno::shared::VtableFactory::addLocalFunctions( + void ** slots, unsigned char * code, + typelib_InterfaceTypeDescription const * type, sal_Int32 functionOffset, + sal_Int32 functionCount, sal_Int32 vtableOffset) +{ + for (sal_Int32 i = 0; i < type->nMembers; ++i) { + typelib_TypeDescription * member = 0; + TYPELIB_DANGER_GET(&member, type->ppMembers[i]); + OSL_ASSERT(member != 0); + switch (member->eTypeClass) { + case typelib_TypeClass_INTERFACE_ATTRIBUTE: + // Getter: + *slots++ = code; + code = codeSnippet( + code, functionOffset++, vtableOffset, + bridges::cpp_uno::shared::isSimpleType( + reinterpret_cast< + typelib_InterfaceAttributeTypeDescription * >( + member)->pAttributeTypeRef)); + // Setter: + if (!reinterpret_cast< + typelib_InterfaceAttributeTypeDescription * >( + member)->bReadOnly) { - bool simple_ret = cppu_isSimpleType( - ((typelib_InterfaceMethodTypeDescription *)pTD)->pReturnTypeRef->eTypeClass ); *slots++ = code; - codeSnippet( code, vtable_pos++, simple_ret ); - code += 20; + code = codeSnippet(code, functionOffset++, vtableOffset, true); } - TYPELIB_DANGER_RELEASE( pTD ); - } - OSL_ASSERT( vtable_pos == nSlots ); - } - else - { - buffer = iFind->second; - } - } + break; - return ((void **)buffer +2); -} + case typelib_TypeClass_INTERFACE_METHOD: + *slots++ = code; + code = codeSnippet( + code, functionOffset++, vtableOffset, + bridges::cpp_uno::shared::isSimpleType( + reinterpret_cast< + typelib_InterfaceMethodTypeDescription * >( + member)->pReturnTypeRef)); + break; -//================================================================================================== -void SAL_CALL cppu_cppInterfaceProxy_patchVtable( - XInterface * pCppI, typelib_InterfaceTypeDescription * pTypeDescr ) throw () -{ - static MediateClassData * s_pMediateClassData = 0; - if (! s_pMediateClassData) - { - MutexGuard aGuard( Mutex::getGlobalMutex() ); - if (! s_pMediateClassData) - { -#ifdef LEAK_STATIC_DATA - s_pMediateClassData = new MediateClassData(); -#else - static MediateClassData s_aMediateClassData; - s_pMediateClassData = &s_aMediateClassData; -#endif + default: + OSL_ASSERT(false); + break; } + TYPELIB_DANGER_RELEASE(member); } - *(void const **)pCppI = s_pMediateClassData->get_vtable( pTypeDescr ); -} - -} - -extern "C" -{ -//################################################################################################## -sal_Bool SAL_CALL component_canUnload( TimeValue * pTime ) - SAL_THROW_EXTERN_C() -{ - return CPPU_CURRENT_NAMESPACE::g_moduleCount.canUnload( - &CPPU_CURRENT_NAMESPACE::g_moduleCount, pTime ); -} -//################################################################################################## -void SAL_CALL uno_initEnvironment( uno_Environment * pCppEnv ) - SAL_THROW_EXTERN_C() -{ - CPPU_CURRENT_NAMESPACE::cppu_cppenv_initEnvironment( - pCppEnv ); -} -//################################################################################################## -void SAL_CALL uno_ext_getMapping( - uno_Mapping ** ppMapping, uno_Environment * pFrom, uno_Environment * pTo ) - SAL_THROW_EXTERN_C() -{ - CPPU_CURRENT_NAMESPACE::cppu_ext_getMapping( - ppMapping, pFrom, pTo ); -} + return code; } |