diff options
Diffstat (limited to 'bridges/source/cpp_uno/gcc3_linux_x86-64/cpp2uno.cxx')
-rw-r--r-- | bridges/source/cpp_uno/gcc3_linux_x86-64/cpp2uno.cxx | 81 |
1 files changed, 50 insertions, 31 deletions
diff --git a/bridges/source/cpp_uno/gcc3_linux_x86-64/cpp2uno.cxx b/bridges/source/cpp_uno/gcc3_linux_x86-64/cpp2uno.cxx index 29212988f78d..14673ab7d5e2 100644 --- a/bridges/source/cpp_uno/gcc3_linux_x86-64/cpp2uno.cxx +++ b/bridges/source/cpp_uno/gcc3_linux_x86-64/cpp2uno.cxx @@ -18,10 +18,6 @@ */ -#include <stdio.h> -#include <stdlib.h> - -#include <rtl/alloc.h> #include <sal/log.hxx> #include <com/sun/star/uno/genfunc.hxx> @@ -37,9 +33,12 @@ #include "abi.hxx" #include "call.hxx" -#include "rtti.hxx" #include "share.hxx" +#if !ENABLE_RUNTIME_OPTIMIZATIONS +#include "rtti.hxx" +#endif + using namespace ::com::sun::star::uno; // Perform the UNO call @@ -54,7 +53,9 @@ using namespace ::com::sun::star::uno; // [ret *] is present when we are returning a structure bigger than 16 bytes // Simple types are returned in rax, rdx (int), or xmm0, xmm1 (fp). // Similarly structures <= 16 bytes are in rax, rdx, xmm0, xmm1 as necessary. -static typelib_TypeClass cpp2uno_call( +// +// The return value is the same as for cpp_vtable_call. +static int cpp2uno_call( bridges::cpp_uno::shared::CppInterfaceProxy * pThis, const typelib_TypeDescription * pMemberTypeDescr, typelib_TypeDescriptionReference * pReturnTypeRef, // 0 indicates void return @@ -69,13 +70,16 @@ static typelib_TypeClass cpp2uno_call( typelib_TypeDescription * pReturnTypeDescr = nullptr; if (pReturnTypeRef) TYPELIB_DANGER_GET( &pReturnTypeDescr, pReturnTypeRef ); + x86_64::ReturnKind returnKind + = (pReturnTypeRef == nullptr || pReturnTypeRef->eTypeClass == typelib_TypeClass_VOID) + ? x86_64::ReturnKind::RegistersGeneral : x86_64::getReturnKind(pReturnTypeRef); void * pUnoReturn = nullptr; void * pCppReturn = nullptr; // complex return ptr: if != 0 && != pUnoReturn, reconversion need if ( pReturnTypeDescr ) { - if ( x86_64::return_in_hidden_param( pReturnTypeRef ) ) + if ( returnKind == x86_64::ReturnKind::Memory ) { pCppReturn = *gpreg++; nr_gpr++; @@ -107,11 +111,12 @@ static typelib_TypeClass cpp2uno_call( { const typelib_MethodParameter & rParam = pParams[nPos]; - int nUsedGPR = 0; - int nUsedSSE = 0; - bool bFitsRegisters = x86_64::examine_argument( rParam.pTypeRef, false, nUsedGPR, nUsedSSE ); if ( !rParam.bOut && bridges::cpp_uno::shared::isSimpleType( rParam.pTypeRef ) ) // value { + int nUsedGPR = 0; + int nUsedSSE = 0; + bool bFitsRegisters = x86_64::examine_argument( rParam.pTypeRef, nUsedGPR, nUsedSSE ); + // Simple types must fit exactly one register on x86_64 assert( bFitsRegisters && ( ( nUsedSSE == 1 && nUsedGPR == 0 ) || ( nUsedSSE == 0 && nUsedGPR == 1 ) ) ); (void)bFitsRegisters; @@ -136,7 +141,7 @@ static typelib_TypeClass cpp2uno_call( pCppArgs[nPos] = pUnoArgs[nPos] = ovrflw++; } } - else // struct <= 16 bytes || ptr to complex value || ref + else // ref { typelib_TypeDescription * pParamTypeDescr = nullptr; TYPELIB_DANGER_GET( &pParamTypeDescr, rParam.pTypeRef ); @@ -201,7 +206,7 @@ static typelib_TypeClass cpp2uno_call( CPPU_CURRENT_NAMESPACE::raiseException( &aUnoExc, pThis->getBridge()->getUno2Cpp() ); // has to destruct the any // is here for dummy - return typelib_TypeClass_VOID; + return 0; } else // else no exception occurred... { @@ -238,17 +243,27 @@ static typelib_TypeClass cpp2uno_call( } if ( pReturnTypeDescr ) { - typelib_TypeClass eRet = pReturnTypeDescr->eTypeClass; TYPELIB_DANGER_RELEASE( pReturnTypeDescr ); - return eRet; } - else - return typelib_TypeClass_VOID; + switch (returnKind) { + case x86_64::ReturnKind::RegistersFpInt: + return 0; + case x86_64::ReturnKind::RegistersIntFp: + return 1; + default: + return -1; + } } } - -typelib_TypeClass cpp_vtable_call( +// Returns -1 for the general case where potential return values from privateSnippetExecutor can be +// copied from pRegisterReturn to both %rax and %rdx (in that order) and to %xmm0 and %xmm1 (in that +// order)---each specific return type will only require a subset of that copy operations, but the +// other copies to those non--callee-saved registers will be redundant and harmless. Returns 0 for +// the special case where return values from privateSnippetExecutor must be copied from +// pRegisterReturn to %xmm0 and %rax (in that order). Returns 1 for the special case where return +// privateSnippetExecutor must be copied from pRegisterReturn to %rax and %xmm0 (in that order). +int cpp_vtable_call( sal_Int32 nFunctionIndex, sal_Int32 nVtableOffset, void ** gpreg, void ** fpreg, void ** ovrflw, sal_uInt64 * pRegisterReturn /* space for register return */ ) @@ -293,7 +308,7 @@ typelib_TypeClass cpp_vtable_call( TypeDescription aMemberDescr( pTypeDescr->ppAllMembers[nMemberPos] ); - typelib_TypeClass eRet; + int eRet; switch ( aMemberDescr.get()->eTypeClass ) { case typelib_TypeClass_INTERFACE_ATTRIBUTE: @@ -330,11 +345,11 @@ typelib_TypeClass cpp_vtable_call( { case 1: // acquire() pCppI->acquireProxy(); // non virtual call! - eRet = typelib_TypeClass_VOID; + eRet = 0; break; case 2: // release() pCppI->releaseProxy(); // non virtual call! - eRet = typelib_TypeClass_VOID; + eRet = 0; break; case 0: // queryInterface() opt { @@ -358,7 +373,7 @@ typelib_TypeClass cpp_vtable_call( TYPELIB_DANGER_RELEASE( pTD ); reinterpret_cast<void **>( pRegisterReturn )[0] = gpreg[0]; - eRet = typelib_TypeClass_ANY; + eRet = 0; break; } TYPELIB_DANGER_RELEASE( pTD ); @@ -426,16 +441,10 @@ static unsigned char * codeSnippet( unsigned char * code, // jmpq *%r11 *reinterpret_cast<sal_uInt32 *>( code + 20 ) = 0x00e3ff49; -#if OSL_DEBUG_LEVEL > 1 - fprintf(stderr, - "==> codeSnippet, functionIndex=%d%s, vtableOffset=%d\n", - nFunctionIndex, (bHasHiddenParam ? "|0x80000000":""), nVtableOffset); -#endif - return code + codeSnippetSize; } -struct bridges::cpp_uno::shared::VtableFactory::Slot { void * fn; }; +struct bridges::cpp_uno::shared::VtableFactory::Slot { void const * fn; }; bridges::cpp_uno::shared::VtableFactory::Slot * bridges::cpp_uno::shared::VtableFactory::mapBlockToVtable(void * block) @@ -449,17 +458,27 @@ std::size_t bridges::cpp_uno::shared::VtableFactory::getBlockSize( return (slotCount + 2) * sizeof (Slot) + slotCount * codeSnippetSize; } +#if ENABLE_RUNTIME_OPTIMIZATIONS +namespace { +// Some dummy type whose RTTI is used in the synthesized proxy vtables to make uses of dynamic_cast +// on such proxy objects not crash: +struct ProxyRtti {}; +} +#endif + bridges::cpp_uno::shared::VtableFactory::Slot * bridges::cpp_uno::shared::VtableFactory::initializeBlock( void * block, sal_Int32 slotCount, sal_Int32 vtableNumber, typelib_InterfaceTypeDescription * type) { Slot * slots = mapBlockToVtable(block); - slots[-2].fn = reinterpret_cast<void *>(-(vtableNumber * sizeof (void *))); #if ENABLE_RUNTIME_OPTIMIZATIONS - slots[-1].fn = nullptr; + slots[-2].fn = nullptr; + slots[-1].fn = &typeid(ProxyRtti); + (void)vtableNumber; (void)type; #else + slots[-2].fn = reinterpret_cast<void *>(-(vtableNumber * sizeof (void *))); slots[-1].fn = x86_64::getRtti(type->aBase); #endif return slots + slotCount; |