diff options
author | Tor Lillqvist <tlillqvist@novell.com> | 2011-01-31 01:08:29 +0200 |
---|---|---|
committer | Tor Lillqvist <tlillqvist@novell.com> | 2011-01-31 01:23:16 +0200 |
commit | 40797af7e23999b68e152ec42d35fccba686f343 (patch) | |
tree | 41abcfce6e97cebb46143966aaf5a356c1733b7d /bridges/source | |
parent | 6734127f11b49e65571f8e1d6b346db9e94ea64d (diff) |
Now the C++-UNO bridge on x64 Windows works a bit better
I had implemented a couple of basic things quite wrong, partly because
of easily misunderstood Microsoft documentation. A couple of things I
just had forgot to do properly.
Attempt to make the source code more consistent in spacing and
variable naming. Clean away meaningless vertical space wasting
non-verbal comments.
The bridgetest over in testtools now runs through quite a lot of its
paces successfully. But exception handling and RTTI, the stuff in
except.cxx, is still not really done at all. And even if I comment out
those checks in bridgetest so that no exceptios are thrown, I then get
a crash later.
Diffstat (limited to 'bridges/source')
-rw-r--r-- | bridges/source/cpp_uno/msvc_win32_x86-64/call.asm | 9 | ||||
-rw-r--r-- | bridges/source/cpp_uno/msvc_win32_x86-64/cpp2uno.cxx | 199 | ||||
-rw-r--r-- | bridges/source/cpp_uno/msvc_win32_x86-64/except.cxx | 98 | ||||
-rw-r--r-- | bridges/source/cpp_uno/msvc_win32_x86-64/uno2cpp.cxx | 355 |
4 files changed, 312 insertions, 349 deletions
diff --git a/bridges/source/cpp_uno/msvc_win32_x86-64/call.asm b/bridges/source/cpp_uno/msvc_win32_x86-64/call.asm index ae514fd06..406e78d39 100644 --- a/bridges/source/cpp_uno/msvc_win32_x86-64/call.asm +++ b/bridges/source/cpp_uno/msvc_win32_x86-64/call.asm @@ -64,10 +64,11 @@ ;; This one is actually more readable: "Improving Automated Analysis ;; of Windows x64 Binaries": http://www.uninformed.org/?v=4&a=1 -;; For exception handling and unwinding to work across the generated -;; functions (as I assume we want?), we would need call -;; RtlAddFunctionTable() (and RtlDeleteFunctionTable()). See Windows -;; SDK documentation. +;; This one has a mass of information about different architectures +;; and compilers, and contains some details about the x64 Windows +;; calling convention in particular that Microsoft doesn't mention +;; above: +;; http://www.agner.org/optimize/calling_conventions.pdf ;; Random interesting discussion threads: ;; http://social.msdn.microsoft.com/Forums/en/vcgeneral/thread/300bd6d3-9381-4d2d-8129-e48b392c05d8 diff --git a/bridges/source/cpp_uno/msvc_win32_x86-64/cpp2uno.cxx b/bridges/source/cpp_uno/msvc_win32_x86-64/cpp2uno.cxx index 6a6ffd540..75798059b 100644 --- a/bridges/source/cpp_uno/msvc_win32_x86-64/cpp2uno.cxx +++ b/bridges/source/cpp_uno/msvc_win32_x86-64/cpp2uno.cxx @@ -42,16 +42,14 @@ #include "mscx.hxx" -// #define DEBUG_WITH_JUST_MESSAGEBOXES - using namespace ::com::sun::star::uno; -//================================================================================================== static inline typelib_TypeClass cpp2uno_call( bridges::cpp_uno::shared::CppInterfaceProxy * pThis, - const typelib_TypeDescription * pMemberTypeDescr, + const typelib_TypeDescription * pMemberTD, typelib_TypeDescriptionReference * pReturnTypeRef, // NULL indicates void return - sal_Int32 nParams, typelib_MethodParameter * pParams, + sal_Int32 nParams, + typelib_MethodParameter * pParams, void ** pStack ) { // Return type @@ -59,14 +57,20 @@ static inline typelib_TypeClass cpp2uno_call( if ( pReturnTypeRef ) TYPELIB_DANGER_GET( &pReturnTD, pReturnTypeRef ); - int nFirstRealParam = 2; + int nFirstRealParam = 3; // Index into pStack, past return + // value, return address and 'this' + // pointer. void * pUnoReturn = NULL; void * pCppReturn = NULL; // Complex return ptr: if != NULL && != pUnoReturn, reconversion need if ( pReturnTD ) { - if ( pReturnTD->nSize > 8 ) + if ( bridges::cpp_uno::shared::isSimpleType( pReturnTD ) ) + { + pUnoReturn = pStack; + } + else { pCppReturn = pStack[nFirstRealParam++]; @@ -74,15 +78,8 @@ static inline typelib_TypeClass cpp2uno_call( ? alloca( pReturnTD->nSize ) : pCppReturn ); // direct way } - else - { - pUnoReturn = pStack; - } } - // "this" - nFirstRealParam++; - void ** pCppIncomingParams = pStack + nFirstRealParam; // Unlike this method for other archs, prefer clarity to @@ -94,7 +91,7 @@ static inline typelib_TypeClass cpp2uno_call( // Parameters received from C++ void ** pCppArgs = (void **)alloca( sizeof(void *) * nParams ); - // Indexes of values this have to be converted (interface conversion cpp<=>uno) + // Indexes of values this have to be converted (interface conversion C++<=>UNO) int * pTempIndexes = (int *)alloca( sizeof(int) * nParams ); @@ -111,7 +108,8 @@ static inline typelib_TypeClass cpp2uno_call( typelib_TypeDescription * pParamTD = NULL; TYPELIB_DANGER_GET( &pParamTD, rParam.pTypeRef ); - if ( !rParam.bOut && pParamTD->nSize <= 8 ) + if ( !rParam.bOut && + bridges::cpp_uno::shared::isSimpleType( pParamTD ) ) { pCppArgs[nPos] = pUnoArgs[nPos] = pCppIncomingParams++; @@ -132,8 +130,7 @@ static inline typelib_TypeClass cpp2uno_call( ppTempParamTD[nTempIndexes++] = pParamTD; } // - else if ( bridges::cpp_uno::shared::relatesToInterfaceType( - pParamTD ) ) + else if ( bridges::cpp_uno::shared::relatesToInterfaceType( pParamTD ) ) { ::uno_copyAndConvertData( pUnoArgs[nPos] = alloca( pParamTD->nSize ), @@ -158,7 +155,7 @@ static inline typelib_TypeClass cpp2uno_call( // invoke UNO dispatch call (*pThis->getUnoI()->pDispatcher)( - pThis->getUnoI(), pMemberTypeDescr, pUnoReturn, pUnoArgs, &pUnoExc ); + pThis->getUnoI(), pMemberTD, pUnoReturn, pUnoArgs, &pUnoExc ); // in case an exception occurred... if ( pUnoExc ) @@ -200,7 +197,7 @@ static inline typelib_TypeClass cpp2uno_call( pCppArgs[nIndex], pUnoArgs[nIndex], pParamTD, pThis->getBridge()->getUno2Cpp() ); } - // Destroy temp uno param + // Destroy temp UNO param ::uno_destructData( pUnoArgs[nIndex], pParamTD, 0 ); TYPELIB_DANGER_RELEASE( pParamTD ); @@ -213,7 +210,7 @@ static inline typelib_TypeClass cpp2uno_call( ::uno_copyAndConvertData( pCppReturn, pUnoReturn, pReturnTD, pThis->getBridge()->getUno2Cpp() ); - // Destroy temp uno return + // Destroy temp UNO return ::uno_destructData( pUnoReturn, pReturnTD, 0 ); } // Complex return ptr is set to eax @@ -230,7 +227,6 @@ static inline typelib_TypeClass cpp2uno_call( } } -//================================================================================================== extern "C" typelib_TypeClass cpp_vtable_call( sal_Int64 nOffsetAndIndex, void ** pStack ) @@ -238,43 +234,33 @@ extern "C" typelib_TypeClass cpp_vtable_call( sal_Int32 nFunctionIndex = (nOffsetAndIndex & 0xFFFFFFFF); sal_Int32 nVtableOffset = ((nOffsetAndIndex >> 32) & 0xFFFFFFFF); - // pStack points to space for return value, after which - // follows our return address (uninteresting) then the spilled - // integer or floating-point register parameters from the call to - // the trampoline, followed by stack parameters. Note that if the - // callee returns a large value, the first parameter is actually a - // pointer to where it should store its return value. The first - // "real" parameter is the "this" pointer. + // pStack points to space for return value allocated by + // privateSnippetExecutor() in call.asm, after which follows our + // return address (uninteresting), then the integer or + // floating-point register parameters (spilled by + // privateSnippetExecutor()) from the call to the trampoline, + // followed by stacked parameters. The first parameter is the + // 'this' pointer. If the callee returns a large value, the + // parameter after that is actually a pointer to where the callee + // should store its return value. - void * pThis; - if ( nFunctionIndex & 0x80000000 ) - { - nFunctionIndex &= 0x7fffffff; - pThis = pStack[3]; - } - else - { - pThis = pStack[2]; - } - pThis = static_cast<char *>( pThis ) - nVtableOffset; + void * pThis = static_cast<char *>( pStack[2] ) - nVtableOffset; bridges::cpp_uno::shared::CppInterfaceProxy * pCppI = bridges::cpp_uno::shared::CppInterfaceProxy::castInterfaceToProxy( pThis ); - typelib_InterfaceTypeDescription * pTypeDescr = pCppI->getTypeDescr(); + typelib_InterfaceTypeDescription * pTD = pCppI->getTypeDescr(); - OSL_ENSURE( nFunctionIndex < pTypeDescr->nMapFunctionIndexToMemberIndex, "### illegal vtable index!\n" ); - if ( nFunctionIndex >= pTypeDescr->nMapFunctionIndexToMemberIndex ) - { - throw RuntimeException( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("illegal vtable index!")), + OSL_ENSURE( nFunctionIndex < pTD->nMapFunctionIndexToMemberIndex, "### illegal vtable index!\n" ); + if ( nFunctionIndex >= pTD->nMapFunctionIndexToMemberIndex ) + throw RuntimeException( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Illegal vtable index!")), reinterpret_cast<XInterface *>( pCppI ) ); - } - // determine called method - sal_Int32 nMemberPos = pTypeDescr->pMapFunctionIndexToMemberIndex[nFunctionIndex]; - OSL_ENSURE( nMemberPos < pTypeDescr->nAllMembers, "### illegal member index!\n" ); + // Determine called method + int nMemberPos = pTD->pMapFunctionIndexToMemberIndex[nFunctionIndex]; + OSL_ENSURE( nMemberPos < pTD->nAllMembers, "### illegal member index!\n" ); - TypeDescription aMemberDescr( pTypeDescr->ppAllMembers[nMemberPos] ); + TypeDescription aMemberDescr( pTD->ppAllMembers[nMemberPos] ); typelib_TypeClass eRet; switch ( aMemberDescr.get()->eTypeClass ) @@ -284,11 +270,11 @@ extern "C" typelib_TypeClass cpp_vtable_call( typelib_TypeDescriptionReference *pAttrTypeRef = reinterpret_cast<typelib_InterfaceAttributeTypeDescription *>( aMemberDescr.get() )->pAttributeTypeRef; - if ( pTypeDescr->pMapMemberIndexToFunctionIndex[nMemberPos] == nFunctionIndex ) + if ( pTD->pMapMemberIndexToFunctionIndex[nMemberPos] == nFunctionIndex ) { // is GET method eRet = cpp2uno_call( pCppI, aMemberDescr.get(), pAttrTypeRef, - 0, NULL, // no params + 0, NULL, // No params pStack ); } else @@ -300,7 +286,7 @@ extern "C" typelib_TypeClass cpp_vtable_call( aParam.bOut = sal_False; eRet = cpp2uno_call( pCppI, aMemberDescr.get(), - 0, // indicates void return + NULL, // Indicates void return 1, &aParam, pStack ); } @@ -312,7 +298,7 @@ extern "C" typelib_TypeClass cpp_vtable_call( switch ( nFunctionIndex ) { case 1: // acquire() - pCppI->acquireProxy(); // non virtual call! + pCppI->acquireProxy(); // Non virtual call! eRet = typelib_TypeClass_VOID; break; case 2: // release() @@ -322,9 +308,12 @@ extern "C" typelib_TypeClass cpp_vtable_call( case 0: // queryInterface() opt { typelib_TypeDescription * pTD = NULL; - // the incoming C++ parameters are: The hidden return value pointer, - // the this pointer, and then the actual queryInterface() only parameter. - // Thus pStack[4], the third parameter. + + // the incoming C++ parameters are: The this + // pointer, the hidden return value pointer, and + // then the actual queryInterface() only + // parameter. Thus pStack[4].. + TYPELIB_DANGER_GET( &pTD, reinterpret_cast<Type *>( pStack[4] )->getTypeLibType() ); if ( pTD ) @@ -353,7 +342,7 @@ extern "C" typelib_TypeClass cpp_vtable_call( } // Fall through! default: { - typelib_InterfaceMethodTypeDescription *pMethodTD = + typelib_InterfaceMethodTypeDescription * pMethodTD = reinterpret_cast<typelib_InterfaceMethodTypeDescription *>( aMemberDescr.get() ); eRet = cpp2uno_call( pCppI, aMemberDescr.get(), @@ -367,7 +356,7 @@ extern "C" typelib_TypeClass cpp_vtable_call( } default: { - throw RuntimeException( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("no member description found!")), + throw RuntimeException( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("No member description found!")), reinterpret_cast<XInterface *>( pCppI ) ); // is here for dummy eRet = typelib_TypeClass_VOID; @@ -377,8 +366,6 @@ extern "C" typelib_TypeClass cpp_vtable_call( return eRet; } -//================================================================================================== - int const codeSnippetSize = 48; extern "C" char privateSnippetExecutor; @@ -393,15 +380,11 @@ unsigned char * codeSnippet( unsigned char * code, char param_kind[4], sal_Int32 nFunctionIndex, - sal_Int32 nVtableOffset, - bool bHasHiddenParam ) + sal_Int32 nVtableOffset ) { sal_uInt64 nOffsetAndIndex = ( ( (sal_uInt64) nVtableOffset ) << 32 ) | ( (sal_uInt64) nFunctionIndex ); unsigned char *p = code; - if ( bHasHiddenParam ) - nOffsetAndIndex |= 0x80000000; - // Spill parameters if ( param_kind[0] == CPPU_CURRENT_NAMESPACE::REGPARAM_INT ) { @@ -463,20 +446,22 @@ unsigned char * codeSnippet( struct bridges::cpp_uno::shared::VtableFactory::Slot { void * fn; }; bridges::cpp_uno::shared::VtableFactory::Slot * -bridges::cpp_uno::shared::VtableFactory::mapBlockToVtable(void * block) +bridges::cpp_uno::shared::VtableFactory::mapBlockToVtable( + void * block ) { return static_cast< Slot * >(block) + 1; } sal_Size bridges::cpp_uno::shared::VtableFactory::getBlockSize( - sal_Int32 slotCount) + sal_Int32 slotCount ) { return (slotCount + 1) * sizeof (Slot) + slotCount * codeSnippetSize; } bridges::cpp_uno::shared::VtableFactory::Slot * bridges::cpp_uno::shared::VtableFactory::initializeBlock( - void * block, sal_Int32 slotCount) + void * block, + sal_Int32 slotCount ) { struct Rtti { sal_Int32 n0, n1, n2; @@ -495,19 +480,13 @@ bridges::cpp_uno::shared::VtableFactory::initializeBlock( return slots + slotCount; } -#ifdef DEBUG_WITH_JUST_MESSAGEBOXES - -static void whatthefuck(sal_Int64 i, ...) -{ - MessageBoxA (NULL, "Shit!", "whatthefuck in cpp2uno.cxx", MB_OK); -} - -#endif - unsigned char * bridges::cpp_uno::shared::VtableFactory::addLocalFunctions( - Slot ** slots, unsigned char * code, - typelib_InterfaceTypeDescription const * type, sal_Int32 functionOffset, - sal_Int32 functionCount, sal_Int32 vtableOffset) + Slot ** slots, + unsigned char * code, + typelib_InterfaceTypeDescription const * type, + sal_Int32 nFunctionOffset, + sal_Int32 functionCount, + sal_Int32 nVtableOffset ) { (*slots) -= functionCount; Slot * s = *slots; @@ -524,53 +503,53 @@ unsigned char * bridges::cpp_uno::shared::VtableFactory::addLocalFunctions( for (int i = 0; i < 4; ++i) param_kind[i] = CPPU_CURRENT_NAMESPACE::REGPARAM_INT; + // 'this' + ++nr; + if ( pTD->eTypeClass == typelib_TypeClass_INTERFACE_ATTRIBUTE ) { - typelib_InterfaceAttributeTypeDescription *pAttrTD = + typelib_InterfaceAttributeTypeDescription * pIfaceAttrTD = reinterpret_cast<typelib_InterfaceAttributeTypeDescription *>( pTD ); // Getter -#ifndef DEBUG_WITH_JUST_MESSAGEBOXES (s++)->fn = code; - code = codeSnippet( code, param_kind, functionOffset++, vtableOffset, - pTD->nSize > 8); -#else - (s++)->fn = whatthefuck; -#endif - - if ( ! pAttrTD->bReadOnly ) + code = codeSnippet( code, param_kind, nFunctionOffset++, nVtableOffset ); + if ( ! pIfaceAttrTD->bReadOnly ) { + typelib_TypeDescription * pAttrTD = NULL; + TYPELIB_DANGER_GET( &pAttrTD, pIfaceAttrTD->pAttributeTypeRef ); + OSL_ASSERT( pAttrTD ); + // Setter -#ifndef DEBUG_WITH_JUST_MESSAGEBOXES + if ( pAttrTD->eTypeClass == typelib_TypeClass_FLOAT || + pAttrTD->eTypeClass == typelib_TypeClass_DOUBLE ) + param_kind[nr++] = CPPU_CURRENT_NAMESPACE::REGPARAM_FLT; + + TYPELIB_DANGER_RELEASE( pAttrTD ); + (s++)->fn = code; - code = codeSnippet( code, param_kind, functionOffset++, vtableOffset, false ); -#else - (s++)->fn = whatthefuck; -#endif + code = codeSnippet( code, param_kind, nFunctionOffset++, nVtableOffset ); } } else if ( pTD->eTypeClass == typelib_TypeClass_INTERFACE_METHOD ) { - typelib_InterfaceMethodTypeDescription *pMethodTD = + typelib_InterfaceMethodTypeDescription * pMethodTD = reinterpret_cast<typelib_InterfaceMethodTypeDescription *>( pTD ); - typelib_TypeDescription *pReturnTD = NULL; + typelib_TypeDescription * pReturnTD = NULL; TYPELIB_DANGER_GET( &pReturnTD, pMethodTD->pReturnTypeRef ); OSL_ASSERT( pReturnTD ); - if ( pReturnTD->nSize > 8 ) + if ( !bridges::cpp_uno::shared::isSimpleType( pReturnTD ) ) { - // Hidden return value + // Return value ++nr; } - // 'this' - ++nr; - for (int param = 0; nr < 4 && param < pMethodTD->nParams; ++param, ++nr) { - typelib_TypeDescription *pParamTD = NULL; + typelib_TypeDescription * pParamTD = NULL; TYPELIB_DANGER_GET( &pParamTD, pMethodTD->pParams[param].pTypeRef ); OSL_ASSERT( pParamTD ); @@ -581,14 +560,8 @@ unsigned char * bridges::cpp_uno::shared::VtableFactory::addLocalFunctions( TYPELIB_DANGER_RELEASE( pParamTD ); } - -#ifndef DEBUG_WITH_JUST_MESSAGEBOXES (s++)->fn = code; - code = codeSnippet( code, param_kind, functionOffset++, vtableOffset, - pReturnTD->nSize > 8); -#else - (s++)->fn = whatthefuck; -#endif + code = codeSnippet( code, param_kind, nFunctionOffset++, nVtableOffset ); TYPELIB_DANGER_RELEASE( pReturnTD ); } @@ -601,7 +574,9 @@ unsigned char * bridges::cpp_uno::shared::VtableFactory::addLocalFunctions( } void bridges::cpp_uno::shared::VtableFactory::flushCode( - unsigned char const *, unsigned char const *) -{} + unsigned char const *, + unsigned char const * ) +{ +} /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/bridges/source/cpp_uno/msvc_win32_x86-64/except.cxx b/bridges/source/cpp_uno/msvc_win32_x86-64/except.cxx index 573af2cbb..7cb9f735a 100644 --- a/bridges/source/cpp_uno/msvc_win32_x86-64/except.cxx +++ b/bridges/source/cpp_uno/msvc_win32_x86-64/except.cxx @@ -45,7 +45,6 @@ #include "mscx.hxx" - #pragma pack(push, 8) using namespace ::com::sun::star::uno; @@ -56,8 +55,9 @@ using namespace ::rtl; namespace CPPU_CURRENT_NAMESPACE { -//================================================================================================== -static inline OUString toUNOname( OUString const & rRTTIname ) throw () +static inline OUString toUNOname( + OUString const & rRTTIname ) + throw () { OUStringBuffer aRet( 64 ); OUString aStr( rRTTIname.copy( 4, rRTTIname.getLength()-4-2 ) ); // filter .?AUzzz@yyy@xxx@@ @@ -74,8 +74,10 @@ static inline OUString toUNOname( OUString const & rRTTIname ) throw () } return aRet.makeStringAndClear(); } -//================================================================================================== -static inline OUString toRTTIname( OUString const & rUNOname ) throw () + +static inline OUString toRTTIname( + OUString const & rUNOname ) + throw () { OUStringBuffer aRet( 64 ); aRet.appendAscii( RTL_CONSTASCII_STRINGPARAM(".?AV") ); // class ".?AV"; struct ".?AU" @@ -91,15 +93,10 @@ static inline OUString toRTTIname( OUString const & rUNOname ) throw () return aRet.makeStringAndClear(); } - -//################################################################################################## -//#### RTTI simulation ############################################################################# -//################################################################################################## - +//RTTI simulation typedef hash_map< OUString, void *, OUStringHash, equal_to< OUString > > t_string2PtrMap; -//================================================================================================== class RTTInfos { Mutex _aMutex; @@ -113,7 +110,6 @@ public: ~RTTInfos(); }; -//================================================================================================== class __type_info { friend type_info * RTTInfos::getRTTI( OUString const & ) throw (); @@ -131,11 +127,11 @@ private: void * _m_data; char _m_d_name[1]; }; -//__________________________________________________________________________________________________ + __type_info::~__type_info() throw () { } -//__________________________________________________________________________________________________ + type_info * RTTInfos::getRTTI( OUString const & rUNOname ) throw () { // a must be @@ -164,11 +160,11 @@ type_info * RTTInfos::getRTTI( OUString const & rUNOname ) throw () return (type_info *)iFind->second; } } -//__________________________________________________________________________________________________ + RTTInfos::RTTInfos() throw () { } -//__________________________________________________________________________________________________ + RTTInfos::~RTTInfos() throw () { #if OSL_DEBUG_LEVEL > 1 @@ -185,13 +181,6 @@ RTTInfos::~RTTInfos() throw () } } - -//################################################################################################## -//#### Exception raising ########################################################################### -//################################################################################################## - - -//================================================================================================== struct ObjectFunction { char somecode[12]; @@ -204,7 +193,8 @@ struct ObjectFunction ~ObjectFunction() throw (); }; -inline void * ObjectFunction::operator new ( size_t nSize ) +inline void * ObjectFunction::operator new( + size_t nSize ) { void * pMem = rtl_allocateMemory( nSize ); if (pMem != 0) @@ -219,13 +209,15 @@ inline void * ObjectFunction::operator new ( size_t nSize ) return pMem; } -inline void ObjectFunction::operator delete ( void * pMem ) +inline void ObjectFunction::operator delete( + void * pMem ) { rtl_freeMemory( pMem ); } -//__________________________________________________________________________________________________ -ObjectFunction::ObjectFunction( typelib_TypeDescription * pTypeDescr, void * fpFunc ) throw () +ObjectFunction::ObjectFunction( + typelib_TypeDescription * pTypeDescr, + void * fpFunc ) throw () : _pTypeDescr( pTypeDescr ) { ::typelib_typedescription_acquire( _pTypeDescr ); @@ -242,28 +234,32 @@ ObjectFunction::ObjectFunction( typelib_TypeDescription * pTypeDescr, void * fpF *pCode++ = 0xe9; *(sal_Int64 *)pCode = ((unsigned char *)fpFunc) - pCode - sizeof(sal_Int64); } -//__________________________________________________________________________________________________ + ObjectFunction::~ObjectFunction() throw () { ::typelib_typedescription_release( _pTypeDescr ); } -//================================================================================================== -void * __cdecl __copyConstruct( void * pExcThis, void * pSource, ObjectFunction * pThis ) + +void * __cdecl __copyConstruct( + void * pExcThis, + void * pSource, + ObjectFunction * pThis ) throw () { ::uno_copyData( pExcThis, pSource, pThis->_pTypeDescr, cpp_acquire ); return pExcThis; } -//================================================================================================== -void * __cdecl __destruct( void * pExcThis, ObjectFunction * pThis ) + +void * __cdecl __destruct( + void * pExcThis, + ObjectFunction * pThis ) throw () { ::uno_destructData( pExcThis, pThis->_pTypeDescr, cpp_release ); return pExcThis; } - #if 0 // These are machine code snippets in asmbits.asm @@ -285,7 +281,6 @@ static void whatthefuck_dtor(sal_Int64 i, ...) #endif -//================================================================================================== struct ExceptionType { sal_Int32 _n0; @@ -310,7 +305,7 @@ struct ExceptionType inline ~ExceptionType() throw () { delete _pCopyCtor; } }; -//================================================================================================== + struct RaiseInfo { sal_Int32 _n0; @@ -322,7 +317,7 @@ struct RaiseInfo RaiseInfo( typelib_TypeDescription * pTypeDescr ) throw (); ~RaiseInfo() throw (); }; -//__________________________________________________________________________________________________ + RaiseInfo::RaiseInfo( typelib_TypeDescription * pTypeDescr ) throw () : _n0( 0 ) #if 0 @@ -357,7 +352,7 @@ RaiseInfo::RaiseInfo( typelib_TypeDescription * pTypeDescr ) throw () ppTypes[nPos++] = new ExceptionType( (typelib_TypeDescription *)pCompTypeDescr ); } } -//__________________________________________________________________________________________________ + RaiseInfo::~RaiseInfo() throw () { ExceptionType ** ppTypes = (ExceptionType **)((sal_Int64 *)_types + 1); @@ -370,7 +365,6 @@ RaiseInfo::~RaiseInfo() throw () delete _pDtor; } -//================================================================================================== class ExceptionInfos { Mutex _aMutex; @@ -382,11 +376,11 @@ public: ExceptionInfos() throw (); ~ExceptionInfos() throw (); }; -//__________________________________________________________________________________________________ + ExceptionInfos::ExceptionInfos() throw () { } -//__________________________________________________________________________________________________ + ExceptionInfos::~ExceptionInfos() throw () { #if OSL_DEBUG_LEVEL > 1 @@ -400,8 +394,8 @@ ExceptionInfos::~ExceptionInfos() throw () delete (RaiseInfo *)iPos->second; } } -//__________________________________________________________________________________________________ -void * ExceptionInfos::getRaiseInfo( typelib_TypeDescription * pTypeDescr ) throw () +void * ExceptionInfos::getRaiseInfo( + typelib_TypeDescription * pTypeDescr ) throw () { static ExceptionInfos * s_pInfos = 0; if (! s_pInfos) @@ -445,14 +439,8 @@ void * ExceptionInfos::getRaiseInfo( typelib_TypeDescription * pTypeDescr ) thro return pRaiseInfo; } - -//################################################################################################## -//#### exported #################################################################################### -//################################################################################################## - - -//################################################################################################## -type_info * mscx_getRTTI( OUString const & rUNOname ) +type_info * mscx_getRTTI( + OUString const & rUNOname ) { static RTTInfos * s_pRTTIs = 0; if (! s_pRTTIs) @@ -471,8 +459,9 @@ type_info * mscx_getRTTI( OUString const & rUNOname ) return s_pRTTIs->getRTTI( rUNOname ); } -//################################################################################################## -void mscx_raiseException( uno_Any * pUnoExc, uno_Mapping * pUno2Cpp ) +void mscx_raiseException( + uno_Any * pUnoExc, + uno_Mapping * pUno2Cpp ) { // no ctor/dtor in here: this leads to dtors called twice upon RaiseException()! // thus this obj file will be compiled without opt, so no inling of @@ -498,9 +487,10 @@ void mscx_raiseException( uno_Any * pUnoExc, uno_Mapping * pUno2Cpp ) RaiseException( MSVC_ExceptionCode, EXCEPTION_NONCONTINUABLE, 3, arFilterArgs ); } -//############################################################################## int mscx_filterCppException( - EXCEPTION_POINTERS * pPointers, uno_Any * pUnoExc, uno_Mapping * pCpp2Uno ) + EXCEPTION_POINTERS * pPointers, + uno_Any * pUnoExc, + uno_Mapping * pCpp2Uno ) { if (pPointers == 0) return EXCEPTION_CONTINUE_SEARCH; diff --git a/bridges/source/cpp_uno/msvc_win32_x86-64/uno2cpp.cxx b/bridges/source/cpp_uno/msvc_win32_x86-64/uno2cpp.cxx index 92be09d3d..c82e3bbd1 100644 --- a/bridges/source/cpp_uno/msvc_win32_x86-64/uno2cpp.cxx +++ b/bridges/source/cpp_uno/msvc_win32_x86-64/uno2cpp.cxx @@ -51,76 +51,28 @@ using namespace ::com::sun::star::uno; namespace { -// As "long" is 32 bit also in x64 Windows we don't use "longs" in names -// to indicate pointer-sized stack slots etc like in the other x64 archs, -// but "qword" as in ml64. - -//================================================================================================== -// In asmbits.asm -extern void callVirtualMethod( - void * pAdjustedThisPtr, sal_Int32 nVtableIndex, - void * pReturn, typelib_TypeClass eReturnTypeClass, - sal_Int64 * pStack, sal_Int32 nStack, - sal_uInt64 *pGPR, - double *pFPR); - -#if OSL_DEBUG_LEVEL > 1 -inline void callVirtualMethodwrapper( - void * pAdjustedThisPtr, sal_Int32 nVtableIndex, - void * pReturn, typelib_TypeDescriptionReference * pReturnTypeRef, - sal_Int64 * pStack, sal_Int32 nStack, - sal_uInt64 *pGPR, sal_uInt32 nGPR, - double *pFPR, sal_uInt32 nFPR) -{ - // Let's figure out what is really going on here - { - fprintf( stderr, "= callVirtualMethod() =\nGPR's (%d): ", nGPR ); - for ( unsigned int i = 0; i < nGPR; ++i ) - fprintf( stderr, "0x%lx, ", pGPR[i] ); - fprintf( stderr, "\nFPR's (%d): ", nFPR ); - for ( unsigned int i = 0; i < nFPR; ++i ) - fprintf( stderr, "%f, ", pFPR[i] ); - fprintf( stderr, "\nStack (%d): ", nStack ); - for ( unsigned int i = 0; i < nStack; ++i ) - fprintf( stderr, "0x%lx, ", pStack[i] ); - fprintf( stderr, "\n" ); - } - - callVirtualMethod( pAdjustedThisPtr, nVtableIndex, - pReturn, pReturnTypeRef->eTypeClass, - pStack, nStack, - pGPR, - pFPR); -} - -#define callVirtualMethod callVirtualMethodwrapper - -#endif - -//================================================================================================== -static void cpp_call( +static bool cpp_call( bridges::cpp_uno::shared::UnoInterfaceProxy * pThis, bridges::cpp_uno::shared::VtableSlot aVtableSlot, typelib_TypeDescriptionReference * pReturnTypeRef, - sal_Int32 nParams, typelib_MethodParameter * pParams, - void * pUnoReturn, void * pUnoArgs[], uno_Any ** ppUnoExc ) throw () + sal_Int32 nParams, + typelib_MethodParameter * pParams, + void * pUnoReturn, + void * pUnoArgs[], + uno_Any ** ppUnoExc ) throw () { const int MAXPARAMS = 20; - MessageBoxA (NULL, "Whoa!", "cpp_call in uno2cpp.cxx", MB_OK); - - if (nParams > MAXPARAMS) + if ( nParams > MAXPARAMS ) { // We have a hard limit on the number of parameters so that we - // don't need any assembler stuff but can call the function - // using normal C++. + // don't need any assembler code here but can call the + // function using normal C++. - // What is the proper way to abort with at least some - // information given to the user? - abort(); + return false; } - // table with optional complex return value ptr, this pointer, and the parameters + // Table with this pointer, optional complex return value ptr, and the parameters union { sal_Int64 i; void *p; @@ -129,26 +81,28 @@ static void cpp_call( int nCppParamIndex = 0; // Return type - typelib_TypeDescription * pReturnTypeDescr = 0; - TYPELIB_DANGER_GET( &pReturnTypeDescr, pReturnTypeRef ); - OSL_ENSURE( pReturnTypeDescr, "### expected return type description!" ); + typelib_TypeDescription * pReturnTD = NULL; + TYPELIB_DANGER_GET( &pReturnTD, pReturnTypeRef ); + OSL_ENSURE( pReturnTD, "### expected return type description!" ); + + // 'this' + void * pAdjustedThisPtr = (void **)( pThis->getCppI() ) + aVtableSlot.offset; + aCppParams[nCppParamIndex++].p = pAdjustedThisPtr; bool bSimpleReturn = true; - if (pReturnTypeDescr) + if ( pReturnTD ) { - if (pReturnTypeDescr->nSize > 8) + if ( !bridges::cpp_uno::shared::isSimpleType( pReturnTD ) ) { - // complex return via ptr + // Complex return via ptr bSimpleReturn = false; - aCppParams[nCppParamIndex++].p = alloca( pReturnTypeDescr->nSize ); + aCppParams[nCppParamIndex++].p = + bridges::cpp_uno::shared::relatesToInterfaceType( pReturnTD )? + alloca( pReturnTD->nSize ) : pUnoReturn; } } - // "this" - sal_Int64 * pCppThis = (sal_Int64 *) (pThis->getCppI()) + aVtableSlot.offset; - aCppParams[nCppParamIndex++].p = pCppThis; - - // Indexes of values this have to be converted (interface conversion cpp<=>uno) + // Indexes of values this have to be converted (interface conversion C++<=>UNO) int pTempCppIndexes[MAXPARAMS]; int pTempIndexes[MAXPARAMS]; int nTempIndexes = 0; @@ -156,69 +110,66 @@ static void cpp_call( // Type descriptions for reconversions typelib_TypeDescription *pTempParamTypeDescr[MAXPARAMS]; - for ( int nPos = 0; nPos < nParams; ++nPos ) + for ( int nPos = 0; nPos < nParams; ++nPos, ++nCppParamIndex ) { const typelib_MethodParameter & rParam = pParams[nPos]; - typelib_TypeDescription * pParamTypeDescr = 0; - TYPELIB_DANGER_GET( &pParamTypeDescr, rParam.pTypeRef ); - if (!rParam.bOut - && bridges::cpp_uno::shared::isSimpleType( pParamTypeDescr )) + typelib_TypeDescription * pParamTD = NULL; + TYPELIB_DANGER_GET( &pParamTD, rParam.pTypeRef ); + + if ( !rParam.bOut && + bridges::cpp_uno::shared::isSimpleType( pParamTD ) ) { ::uno_copyAndConvertData( - aCppParams[nCppParamIndex++].p, pUnoArgs[nPos], pParamTypeDescr, + &aCppParams[nCppParamIndex], pUnoArgs[nPos], pParamTD, pThis->getBridge()->getUno2Cpp() ); - // no longer needed - TYPELIB_DANGER_RELEASE( pParamTypeDescr ); + // No longer needed + TYPELIB_DANGER_RELEASE( pParamTD ); } - else // ptr to complex value | ref + else // Ptr to complex value | ref { - if (! rParam.bIn) // is pure out + if ( !rParam.bIn ) // Is pure out { - // cpp out is constructed mem, uno out is not! + // C++ out is constructed mem, UNO out is not! ::uno_constructData( - aCppParams[nCppParamIndex].p = alloca( pParamTypeDescr->nSize ), - pParamTypeDescr ); + aCppParams[nCppParamIndex].p = alloca( pParamTD->nSize ), + pParamTD ); pTempCppIndexes[nTempIndexes] = nCppParamIndex; pTempIndexes[nTempIndexes] = nPos; - // will be released at reconversion - pTempParamTypeDescr[nTempIndexes++] = pParamTypeDescr; + // Will be released at reconversion + pTempParamTypeDescr[nTempIndexes++] = pParamTD; - nCppParamIndex++; } - // is in/inout - else if (bridges::cpp_uno::shared::relatesToInterfaceType( - pParamTypeDescr )) + // Is in/inout + else if ( bridges::cpp_uno::shared::relatesToInterfaceType( pParamTD ) ) { ::uno_copyAndConvertData( - aCppParams[nCppParamIndex].p = alloca( pParamTypeDescr->nSize ), - pUnoArgs[nPos], pParamTypeDescr, + aCppParams[nCppParamIndex].p = alloca( pParamTD->nSize ), + pUnoArgs[nPos], pParamTD, pThis->getBridge()->getUno2Cpp() ); pTempCppIndexes[nTempIndexes] = nCppParamIndex; pTempIndexes[nTempIndexes] = nPos; - // will be released at reconversion - pTempParamTypeDescr[nTempIndexes++] = pParamTypeDescr; - - nCppParamIndex++; + // Will be released at reconversion + pTempParamTypeDescr[nTempIndexes++] = pParamTD; } else // direct way { - aCppParams[nCppParamIndex++].p = pUnoArgs[nPos]; - // no longer needed - TYPELIB_DANGER_RELEASE( pParamTypeDescr ); + aCppParams[nCppParamIndex].p = pUnoArgs[nPos]; + + // No longer needed + TYPELIB_DANGER_RELEASE( pParamTD ); } } } __try { - // The first real parameter is always a pointer: either the - // address of where to store a complex return value or "this". + // The first real parameter is always 'this'. // The Windows x64 calling convention is very regular and // elegant (even if perhaps then slightly slower than the @@ -238,91 +189,111 @@ static void cpp_call( // registers, and the callee will find them where it // expects. (The callee is not actually varargs, of course.) - sal_Int64 (*pMethod)(sal_Int64, ...) = + sal_Int64 (*pIMethod)(sal_Int64, ...) = (sal_Int64 (*)(sal_Int64, ...)) - (((sal_Int64 *)pCppThis) + aVtableSlot.index); - - // Pass parameters 2..4 as double so that it gets put in both XMM and integer - // registers per the - uRetVal.i = - pMethod (aCppParams[0].i, aCppParams[1].d, aCppParams[2].d, aCppParams[3].d, - aCppParams[4].i, aCppParams[5].i, aCppParams[6].i, aCppParams[7].i, - aCppParams[8].i, aCppParams[9].i, aCppParams[10].i, aCppParams[11].i, - aCppParams[12].i, aCppParams[13].i, aCppParams[14].i, aCppParams[15].i, - aCppParams[16].i, aCppParams[17].i, aCppParams[18].i, aCppParams[19].i ); + (*((sal_uInt64 **)pAdjustedThisPtr))[aVtableSlot.index]; + + double (*pFMethod)(sal_Int64, ...) = + (double (*)(sal_Int64, ...)) + (*((sal_uInt64 **)pAdjustedThisPtr))[aVtableSlot.index]; + + // Pass parameters 2..4 as if it was a floating-point value so + // that it gets put in both XMM and integer registers per the + // calling convention. It doesn't matter if it actually is a + // fp or not. + + if ( pReturnTD && + (pReturnTD->eTypeClass == typelib_TypeClass_FLOAT || + pReturnTD->eTypeClass == typelib_TypeClass_DOUBLE) ) + uRetVal.d = + pFMethod (aCppParams[0].i, aCppParams[1].d, aCppParams[2].d, aCppParams[3].d, + aCppParams[4].i, aCppParams[5].i, aCppParams[6].i, aCppParams[7].i, + aCppParams[8].i, aCppParams[9].i, aCppParams[10].i, aCppParams[11].i, + aCppParams[12].i, aCppParams[13].i, aCppParams[14].i, aCppParams[15].i, + aCppParams[16].i, aCppParams[17].i, aCppParams[18].i, aCppParams[19].i ); + else + uRetVal.i = + pIMethod (aCppParams[0].i, aCppParams[1].d, aCppParams[2].d, aCppParams[3].d, + aCppParams[4].i, aCppParams[5].i, aCppParams[6].i, aCppParams[7].i, + aCppParams[8].i, aCppParams[9].i, aCppParams[10].i, aCppParams[11].i, + aCppParams[12].i, aCppParams[13].i, aCppParams[14].i, aCppParams[15].i, + aCppParams[16].i, aCppParams[17].i, aCppParams[18].i, aCppParams[19].i ); } __except (CPPU_CURRENT_NAMESPACE::mscx_filterCppException( GetExceptionInformation(), *ppUnoExc, pThis->getBridge()->getCpp2Uno() )) { - // *ppUnoExc was constructed by filter function - // temporary params - while (nTempIndexes--) + // *ppUnoExc was constructed by filter function. + // Temporary params + while ( nTempIndexes-- ) { int nCppIndex = pTempCppIndexes[nTempIndexes]; - // destroy temp cpp param => cpp: every param was constructed + // Destroy temp C++ param => C++: every param was constructed ::uno_destructData( aCppParams[nCppIndex].p, pTempParamTypeDescr[nTempIndexes], cpp_release ); TYPELIB_DANGER_RELEASE( pTempParamTypeDescr[nTempIndexes] ); } - // return type - if (pReturnTypeDescr) - { - TYPELIB_DANGER_RELEASE( pReturnTypeDescr ); - } - // end here - return; + // Return type + if ( pReturnTD ) + TYPELIB_DANGER_RELEASE( pReturnTD ); + + // End here + return true; } - // NO exception occurred - *ppUnoExc = 0; + // No exception occurred + *ppUnoExc = NULL; // Reconvert temporary params - while (nTempIndexes--) + while ( nTempIndexes-- ) { int nCppIndex = pTempCppIndexes[nTempIndexes]; int nIndex = pTempIndexes[nTempIndexes]; - typelib_TypeDescription * pParamTypeDescr = + typelib_TypeDescription * pParamTD = pTempParamTypeDescr[nTempIndexes]; - if (pParams[nIndex].bIn) + if ( pParams[nIndex].bIn ) { - if (pParams[nIndex].bOut) // inout + if ( pParams[nIndex].bOut ) // Inout { ::uno_destructData( - pUnoArgs[nIndex], pParamTypeDescr, 0 ); // destroy uno value + pUnoArgs[nIndex], pParamTD, 0 ); // Destroy UNO value ::uno_copyAndConvertData( - pUnoArgs[nIndex], aCppParams[nCppIndex].p, pParamTypeDescr, + pUnoArgs[nIndex], aCppParams[nCppIndex].p, pParamTD, pThis->getBridge()->getCpp2Uno() ); } } - else // pure out + else // Pure out { ::uno_copyAndConvertData( - pUnoArgs[nIndex], aCppParams[nCppIndex].p, pParamTypeDescr, + pUnoArgs[nIndex], aCppParams[nCppIndex].p, pParamTD, pThis->getBridge()->getCpp2Uno() ); } - // destroy temp cpp param => cpp: every param was constructed + + // Destroy temp C++ param => C++: every param was constructed ::uno_destructData( - aCppParams[nCppIndex].p, pParamTypeDescr, cpp_release ); + aCppParams[nCppIndex].p, pParamTD, cpp_release ); - TYPELIB_DANGER_RELEASE( pParamTypeDescr ); + TYPELIB_DANGER_RELEASE( pParamTD ); } - // return value - if (!bSimpleReturn) + + // Return value + if ( !bSimpleReturn ) { ::uno_copyAndConvertData( - pUnoReturn, uRetVal.p, pReturnTypeDescr, + pUnoReturn, uRetVal.p, pReturnTD, pThis->getBridge()->getCpp2Uno() ); ::uno_destructData( - aCppParams[0].p, pReturnTypeDescr, cpp_release ); - } - // return type - if (pReturnTypeDescr) - { - TYPELIB_DANGER_RELEASE( pReturnTypeDescr ); + aCppParams[1].p, pReturnTD, cpp_release ); } + else if ( pUnoReturn ) + *(sal_Int64*)pUnoReturn = uRetVal.i; + + if ( pReturnTD ) + TYPELIB_DANGER_RELEASE( pReturnTD ); + + return true; } } @@ -330,46 +301,56 @@ static void cpp_call( namespace bridges { namespace cpp_uno { namespace shared { void unoInterfaceProxyDispatch( - uno_Interface * pUnoI, const typelib_TypeDescription * pMemberDescr, - void * pReturn, void * pArgs[], uno_Any ** ppException ) + uno_Interface * pUnoI, + const typelib_TypeDescription * pMemberTD, + void * pReturn, + void * pArgs[], + uno_Any ** ppException ) { // is my surrogate bridges::cpp_uno::shared::UnoInterfaceProxy * pThis = static_cast< bridges::cpp_uno::shared::UnoInterfaceProxy * >(pUnoI); +#if OSL_DEBUG_LEVEL > 0 + typelib_InterfaceTypeDescription * pTypeDescr = pThis->pTypeDescr; +#endif - switch (pMemberDescr->eTypeClass) + switch (pMemberTD->eTypeClass) { case typelib_TypeClass_INTERFACE_ATTRIBUTE: { +#if OSL_DEBUG_LEVEL > 0 + // determine vtable call index + sal_Int32 nMemberPos = ((typelib_InterfaceMemberTypeDescription *)pMemberTD)->nPosition; + OSL_ENSURE( nMemberPos < pTypeDescr->nAllMembers, "### member pos out of range!" ); +#endif VtableSlot aVtableSlot( getVtableSlot( reinterpret_cast< typelib_InterfaceAttributeTypeDescription const * >( - pMemberDescr))); - if (pReturn) + pMemberTD))); + if ( pReturn ) { - // dependent dispatch + // Is GET cpp_call( pThis, aVtableSlot, - ((typelib_InterfaceAttributeTypeDescription *)pMemberDescr)->pAttributeTypeRef, - 0, 0, // no params + ((typelib_InterfaceAttributeTypeDescription *)pMemberTD)->pAttributeTypeRef, + 0, NULL, // no params pReturn, pArgs, ppException ); } else { - // is SET + // Is SET typelib_MethodParameter aParam; aParam.pTypeRef = - ((typelib_InterfaceAttributeTypeDescription *)pMemberDescr)->pAttributeTypeRef; + ((typelib_InterfaceAttributeTypeDescription *)pMemberTD)->pAttributeTypeRef; aParam.bIn = sal_True; aParam.bOut = sal_False; - typelib_TypeDescriptionReference * pReturnTypeRef = 0; + typelib_TypeDescriptionReference * pReturnTypeRef = NULL; OUString aVoidName( RTL_CONSTASCII_USTRINGPARAM("void") ); typelib_typedescriptionreference_new( &pReturnTypeRef, typelib_TypeClass_VOID, aVoidName.pData ); - // dependent dispatch aVtableSlot.index += 1; // get, then set method cpp_call( pThis, aVtableSlot, @@ -384,65 +365,81 @@ void unoInterfaceProxyDispatch( } case typelib_TypeClass_INTERFACE_METHOD: { +#if OSL_DEBUG_LEVEL > 0 + // determine vtable call index + sal_Int32 nMemberPos = ((typelib_InterfaceMemberTypeDescription *)pMemberTD)->nPosition; + OSL_ENSURE( nMemberPos < pTypeDescr->nAllMembers, "### member pos out of range!" ); +#endif VtableSlot aVtableSlot( getVtableSlot( reinterpret_cast< typelib_InterfaceMethodTypeDescription const * >( - pMemberDescr))); + pMemberTD))); + switch (aVtableSlot.index) { - // standard calls - case 1: // acquire uno interface + // Standard calls + case 1: // Acquire UNO interface (*pUnoI->acquire)( pUnoI ); *ppException = 0; break; - case 2: // release uno interface + case 2: // Release UNO interface (*pUnoI->release)( pUnoI ); *ppException = 0; break; case 0: // queryInterface() opt { - typelib_TypeDescription * pTD = 0; + typelib_TypeDescription * pTD = NULL; TYPELIB_DANGER_GET( &pTD, reinterpret_cast< Type * >( pArgs[0] )->getTypeLibType() ); - if (pTD) + + if ( pTD ) { - uno_Interface * pInterface = 0; - (*pThis->pBridge->getUnoEnv()->getRegisteredInterface)( - pThis->pBridge->getUnoEnv(), + uno_Interface * pInterface = NULL; + (*pThis->getBridge()->getUnoEnv()->getRegisteredInterface)( + pThis->getBridge()->getUnoEnv(), (void **)&pInterface, pThis->oid.pData, (typelib_InterfaceTypeDescription *)pTD ); - if (pInterface) + if ( pInterface ) { ::uno_any_construct( reinterpret_cast< uno_Any * >( pReturn ), &pInterface, pTD, 0 ); (*pInterface->release)( pInterface ); + TYPELIB_DANGER_RELEASE( pTD ); + *ppException = 0; break; } TYPELIB_DANGER_RELEASE( pTD ); } - } // else perform queryInterface() + } // Else perform queryInterface() default: - // dependent dispatch - cpp_call( - pThis, aVtableSlot, - ((typelib_InterfaceMethodTypeDescription *)pMemberDescr)->pReturnTypeRef, - ((typelib_InterfaceMethodTypeDescription *)pMemberDescr)->nParams, - ((typelib_InterfaceMethodTypeDescription *)pMemberDescr)->pParams, - pReturn, pArgs, ppException ); + if ( ! cpp_call( + pThis, aVtableSlot, + ((typelib_InterfaceMethodTypeDescription *)pMemberTD)->pReturnTypeRef, + ((typelib_InterfaceMethodTypeDescription *)pMemberTD)->nParams, + ((typelib_InterfaceMethodTypeDescription *)pMemberTD)->pParams, + pReturn, pArgs, ppException ) ) + { + RuntimeException aExc( + OUString( RTL_CONSTASCII_USTRINGPARAM("Too many parameters!") ), + Reference< XInterface >() ); + + Type const & rExcType = ::getCppuType( &aExc ); + ::uno_type_any_construct( *ppException, &aExc, rExcType.getTypeLibType(), 0 ); + } } break; } default: { - ::com::sun::star::uno::RuntimeException aExc( - OUString( RTL_CONSTASCII_USTRINGPARAM("illegal member type description!") ), - ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >() ); + RuntimeException aExc( + OUString( RTL_CONSTASCII_USTRINGPARAM("Illegal member type description!") ), + Reference< XInterface >() ); Type const & rExcType = ::getCppuType( &aExc ); - // binary identical null reference + // Binary identical null reference (whatever that comment means...) ::uno_type_any_construct( *ppException, &aExc, rExcType.getTypeLibType(), 0 ); } } |