diff options
Diffstat (limited to 'bridges/source/cpp_uno/cc50_solaris_sparc')
-rw-r--r-- | bridges/source/cpp_uno/cc50_solaris_sparc/call.s | 199 | ||||
-rw-r--r-- | bridges/source/cpp_uno/cc50_solaris_sparc/cc50_solaris_sparc.hxx | 87 | ||||
-rw-r--r-- | bridges/source/cpp_uno/cc50_solaris_sparc/cpp2uno.cxx | 530 | ||||
-rw-r--r-- | bridges/source/cpp_uno/cc50_solaris_sparc/except.cxx | 445 | ||||
-rw-r--r-- | bridges/source/cpp_uno/cc50_solaris_sparc/flushcode.hxx | 48 | ||||
-rw-r--r-- | bridges/source/cpp_uno/cc50_solaris_sparc/hash.cxx | 264 | ||||
-rw-r--r-- | bridges/source/cpp_uno/cc50_solaris_sparc/makefile.mk | 80 | ||||
-rw-r--r-- | bridges/source/cpp_uno/cc50_solaris_sparc/uno2cpp.cxx | 396 |
8 files changed, 2049 insertions, 0 deletions
diff --git a/bridges/source/cpp_uno/cc50_solaris_sparc/call.s b/bridges/source/cpp_uno/cc50_solaris_sparc/call.s new file mode 100644 index 000000000000..be4027fda070 --- /dev/null +++ b/bridges/source/cpp_uno/cc50_solaris_sparc/call.s @@ -0,0 +1,199 @@ +.global privateSnippetExecutor +.type privateSnippetExecutor,2 +privateSnippetExecutor: + ! save %sp, -96, %sp already done in code snippet + st %i0, [%fp+68] + st %i1, [%fp+72] + st %i2, [%fp+76] + st %i3, [%fp+80] + st %i4, [%fp+84] + st %i5, [%fp+88] + ! %o0: functionIndex, stored by code snippet + ! %o1: vtableOffset, stored by code snippet + call cpp_vtable_call + add %fp, 68, %o2 +.privateSnippetExecutorExceptionPosition: + subcc %o0, 11, %g0 + be .double + subcc %o0, 10, %g0 + be .float + ld [%fp+72], %i0 + ld [%fp+76], %i1 + ret + restore +.double: + ldd [%fp+72], %f0 + ret + restore +.float: + ld [%fp+72], %f0 + ret + restore +.size privateSnippetExecutor,(.-privateSnippetExecutor) +.align 8 + + +.global callVirtualMethod +.type callVirtualMethod,2 +callVirtualMethod: + ! allocate FIRST stack to have own local registers + sethi %hi(-96), %g1 + or %g1, %lo(-96), %g1 + subcc %g1, %o5, %g1 + subcc %g1, %o5, %g1 + subcc %g1, %o5, %g1 + subcc %g1, %o5, %g1 + save %sp, %g1, %sp + ! copy stack longs if necessary + subcc %i5, 6, %l5 + ble .copyRegisters + nop + + ! prepare source location + add %i4, 24, %l4 + + ! prepare real stack + add %sp, 92, %l3 + +.copyLong: + ld [%l4+0], %l0 + st %l0, [%l3] + add %l4, 4, %l4 + add %l3, 4, %l3 + deccc %l5 + bne .copyLong + nop +.copyRegisters: + mov %i5, %l5 + mov %i4, %l4 + + ld [%l4], %o0 + add %l4, 4, %l4 + deccc %l5 + ble .doCall + + ld [%l4], %o1 + add %l4, 4, %l4 + deccc %l5 + ble .doCall + + ld [%l4], %o2 + add %l4, 4, %l4 + deccc %l5 + ble .doCall + + ld [%l4], %o3 + add %l4, 4, %l4 + deccc %l5 + ble .doCall + + ld [%l4], %o4 + add %l4, 4, %l4 + deccc %l5 + ble .doCall + + ld [%l4], %o5 + add %l4, 4, %l4 + + ! prepare complex return pointer + st %i2, [%sp+64] +.doCall: + ! get virtual table entry + mov %i1, %l1 + add %l1, 2, %l1 + sll %l1, 2, %l1 + ld [%i0], %l3 + add %l3, %l1, %l1 + ld [%l1], %l0 + jmpl %l0,%o7 + nop +.callVirtualMethodExceptionPosition: + ! handle returns + + !byte types + subcc %i3, 2, %l3 ! typelib_TypeClass_BOOLEAN + be .handleByte + subcc %i3, 3, %l3 ! typelib_TypeClass_BYTE + be .handleByte + + ! half word types + subcc %i3, 4, %l3 ! typelib_TypeClass_SHORT + be .handleShort + subcc %i3, 5, %l3 ! typelib_TypeClass_UNSIGNED_SHORT + be .handleShort + subcc %i3, 1, %l3 ! typelib_TypeClass_CHAR (sal_Unicode==sal_uInt16) + be .handleShort + + ! word types + subcc %i3, 6, %l3 ! typelib_TypeClass_LONG + be .handleWord + subcc %i3, 7, %l3 ! typelib_TypeClass_UNSIGNED_LONG + be .handleWord + subcc %i3, 15, %l3 ! typelib_TypeClass_ENUM + be .handleWord + + ! double word types + subcc %i3, 8, %l3 ! typelib_TypeClass_HYPER + be .handleDoubleWord + subcc %i3, 9, %l3 ! typelib_TypeClass_UNSIGNED_HYPER + be .handleDoubleWord + + ! float + subcc %i3, 10, %l3 ! typelib_TypeClass_FLOAT + be .handleFloat + + ! double + subcc %i3, 11, %l3 ! typelib_TypeClass_DOUBLE + be .handleDouble + + ! default: return void + nop ! empty prefetch + ba .doRestore + nop +.handleByte: + stb %o0, [%i2] + ba .doRestore + nop +.handleShort: + sth %o0, [%i2] + ba .doRestore + nop +.handleWord: + st %o0, [%i2] + ba .doRestore + nop +.handleDoubleWord: + st %o0, [%i2] + st %o1, [%i2+4] + ba .doRestore + nop +.handleFloat: + st %f0, [%i2] + ba .doRestore + nop +.handleDouble: + std %f0, [%fp-8] + ldd [%fp-8], %o0 + st %o0, [%i2] + st %o1, [%i2+4] + ba .doRestore + nop +.doRestore: + ret + restore ! stack frame for own locals +.size callVirtualMethod,(.-callVirtualMethod) +.align 8 + +.rethrow_handler: + call __1cG__CrunMex_rethrow_q6F_v_ + nop + +.section ".exception_ranges",#alloc +.word %r_disp32(.privateSnippetExecutorExceptionPosition) +.word 0 +.word .rethrow_handler-.privateSnippetExecutorExceptionPosition +.word 0,0 +.word %r_disp32(.callVirtualMethodExceptionPosition) +.word 0 +.word .rethrow_handler-.callVirtualMethodExceptionPosition +.word 0,0 diff --git a/bridges/source/cpp_uno/cc50_solaris_sparc/cc50_solaris_sparc.hxx b/bridges/source/cpp_uno/cc50_solaris_sparc/cc50_solaris_sparc.hxx new file mode 100644 index 000000000000..d327d0307c51 --- /dev/null +++ b/bridges/source/cpp_uno/cc50_solaris_sparc/cc50_solaris_sparc.hxx @@ -0,0 +1,87 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#include <cstddef> +#include <rtl/string.hxx> +#include <typeinfo> + +typedef struct _uno_Any uno_Any; +typedef struct _uno_Mapping uno_Mapping; + +// private C50 structures and functions +namespace __Crun +{ + struct static_type_info + { + std::ptrdiff_t m_pClassName; + int m_nSkip1; // must be 0 + void* m_pMagic; // points to some magic data + int m_nMagic[ 4 ]; + int m_nSkip2[2]; // must be 0 + }; + void* ex_alloc(unsigned); + void ex_throw( void*, const static_type_info*, void(*)(void*)); + void* ex_get(); + void ex_rethrow_q() throw(); +} + +namespace __Cimpl +{ + const char* ex_name(); +} + +extern "C" void _ex_register( void*, int ); + +namespace CPPU_CURRENT_NAMESPACE +{ + +inline char* adjustPointer( char* pIn, typelib_TypeDescription* pType ) +{ + switch( pType->nSize ) + { + case 1: return pIn + 3; + case 2: return pIn + 2; + case 3: return pIn + 1; + // Huh ? perhaps a char[3] ? Though that would be a pointer + // well, we have it anyway for symmetry + } + return pIn; +} + +//################################################################################################## +//#### exceptions ################################################################################## +//################################################################################################## + +void cc50_solaris_sparc_raiseException( + uno_Any * pUnoExc, uno_Mapping * pUno2Cpp ); + +void cc50_solaris_sparc_fillUnoException( + void*, const char*, + uno_Any*, uno_Mapping * pCpp2Uno ); + +} + diff --git a/bridges/source/cpp_uno/cc50_solaris_sparc/cpp2uno.cxx b/bridges/source/cpp_uno/cc50_solaris_sparc/cpp2uno.cxx new file mode 100644 index 000000000000..df16b62bdf27 --- /dev/null +++ b/bridges/source/cpp_uno/cc50_solaris_sparc/cpp2uno.cxx @@ -0,0 +1,530 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_bridges.hxx" + +#include <sal/alloca.h> + +#include <com/sun/star/uno/genfunc.hxx> +#include <uno/data.h> +#include <typelib/typedescription.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 "cc50_solaris_sparc.hxx" +#include "flushcode.hxx" + +using namespace com::sun::star::uno; + +namespace +{ + +//================================================================================================== +static typelib_TypeClass cpp2uno_call( + bridges::cpp_uno::shared::CppInterfaceProxy * pThis, + const typelib_TypeDescription * pMemberTypeDescr, + typelib_TypeDescriptionReference * pReturnTypeRef, // 0 indicates void return + sal_Int32 nParams, typelib_MethodParameter * pParams, + void ** pCallStack, + sal_Int64 * pRegisterReturn /* space for register return */ ) +{ + // pCallStack: [return ptr], this, params + char * pCppStack = (char *)pCallStack; + + // return + typelib_TypeDescription * pReturnTypeDescr = 0; + if (pReturnTypeRef) + TYPELIB_DANGER_GET( &pReturnTypeDescr, pReturnTypeRef ); + + void * pUnoReturn = 0; + void * pCppReturn = 0; // complex return ptr: if != 0 && != pUnoReturn, reconversion need + + if (pReturnTypeDescr) + { + if (bridges::cpp_uno::shared::isSimpleType( pReturnTypeDescr )) + { + pUnoReturn = pRegisterReturn; // direct way for simple types + } + else // complex return via ptr (pCppReturn) + { + pCppReturn = *pCallStack; + pCppStack += sizeof( void* ); + pUnoReturn = (bridges::cpp_uno::shared::relatesToInterfaceType( + pReturnTypeDescr ) + ? alloca( pReturnTypeDescr->nSize ) + : pCppReturn); // direct way + } + } + // pop this + pCppStack += sizeof( void* ); + + // stack space + OSL_ENSURE( sizeof(void *) == sizeof(sal_Int32), "### unexpected size!" ); + // parameters + void ** pUnoArgs = (void **)alloca( 4 * sizeof(void *) * nParams ); + void ** pCppArgs = pUnoArgs + nParams; + // indizes of values this have to be converted (interface conversion cpp<=>uno) + sal_Int32 * pTempIndizes = (sal_Int32 *)(pUnoArgs + (2 * nParams)); + // type descriptions for reconversions + typelib_TypeDescription ** ppTempParamTypeDescr = (typelib_TypeDescription **)(pUnoArgs + (3 * nParams)); + + sal_Int32 nTempIndizes = 0; + + for ( sal_Int32 nPos = 0; nPos < nParams; ++nPos ) + { + 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 )) + // value + { + pCppArgs[ nPos ] = pUnoArgs[ nPos ] = + CPPU_CURRENT_NAMESPACE::adjustPointer( + pCppStack, pParamTypeDescr ); + switch (pParamTypeDescr->eTypeClass) + { + case typelib_TypeClass_HYPER: + case typelib_TypeClass_UNSIGNED_HYPER: + case typelib_TypeClass_DOUBLE: + pCppStack += sizeof(sal_Int32); // extra long + } + // no longer needed + TYPELIB_DANGER_RELEASE( pParamTypeDescr ); + } + else // ptr to complex value | ref + { + pCppArgs[nPos] = *(void **)pCppStack; + + if (! rParam.bIn) // is pure out + { + // uno out is unconstructed mem! + pUnoArgs[nPos] = alloca( pParamTypeDescr->nSize ); + pTempIndizes[nTempIndizes] = nPos; + // will be released at reconversion + ppTempParamTypeDescr[nTempIndizes++] = pParamTypeDescr; + } + // is in/inout + else if (bridges::cpp_uno::shared::relatesToInterfaceType( + pParamTypeDescr )) + { + uno_copyAndConvertData( pUnoArgs[nPos] = alloca( pParamTypeDescr->nSize ), + *(void **)pCppStack, pParamTypeDescr, + pThis->getBridge()->getCpp2Uno() ); + pTempIndizes[nTempIndizes] = nPos; // has to be reconverted + // will be released at reconversion + ppTempParamTypeDescr[nTempIndizes++] = pParamTypeDescr; + } + else // direct way + { + pUnoArgs[nPos] = *(void **)pCppStack; + // no longer needed + TYPELIB_DANGER_RELEASE( pParamTypeDescr ); + } + } + pCppStack += sizeof(sal_Int32); // standard parameter length + } + + // ExceptionHolder + uno_Any aUnoExc; // Any will be constructed by callee + uno_Any * pUnoExc = &aUnoExc; + + // invoke uno dispatch call + (*pThis->getUnoI()->pDispatcher)( + pThis->getUnoI(), pMemberTypeDescr, pUnoReturn, pUnoArgs, &pUnoExc ); + + // in case no exception occured... + if (pUnoExc) + { + // destruct temporary in/inout params + for ( ; nTempIndizes--; ) + { + sal_Int32 nIndex = pTempIndizes[nTempIndizes]; + + if (pParams[nIndex].bIn) // is in/inout => was constructed + uno_destructData( pUnoArgs[nIndex], ppTempParamTypeDescr[nTempIndizes], 0 ); + TYPELIB_DANGER_RELEASE( ppTempParamTypeDescr[nTempIndizes] ); + } + if (pReturnTypeDescr) + TYPELIB_DANGER_RELEASE( pReturnTypeDescr ); + + CPPU_CURRENT_NAMESPACE::cc50_solaris_sparc_raiseException( + &aUnoExc, pThis->getBridge()->getUno2Cpp() ); + // has to destruct the any + // is here for dummy + return typelib_TypeClass_VOID; + } + else // else no exception occured... + { + // temporary params + for ( ; nTempIndizes--; ) + { + sal_Int32 nIndex = pTempIndizes[nTempIndizes]; + typelib_TypeDescription * pParamTypeDescr = ppTempParamTypeDescr[nTempIndizes]; + + if (pParams[nIndex].bOut) // inout/out + { + // convert and assign + uno_destructData( + pCppArgs[nIndex], pParamTypeDescr, + reinterpret_cast< uno_ReleaseFunc >(cpp_release) ); + uno_copyAndConvertData( pCppArgs[nIndex], pUnoArgs[nIndex], pParamTypeDescr, + pThis->getBridge()->getUno2Cpp() ); + } + // destroy temp uno param + uno_destructData( pUnoArgs[nIndex], pParamTypeDescr, 0 ); + + TYPELIB_DANGER_RELEASE( pParamTypeDescr ); + } + // return + if (pCppReturn) // has complex return + { + if (pUnoReturn != pCppReturn) // needs reconversion + { + uno_copyAndConvertData( pCppReturn, pUnoReturn, pReturnTypeDescr, + pThis->getBridge()->getUno2Cpp() ); + // destroy temp uno return + uno_destructData( pUnoReturn, pReturnTypeDescr, 0 ); + } + // complex return ptr is set to eax + *(void **)pRegisterReturn = pCppReturn; + } + if (pReturnTypeDescr) + { + typelib_TypeClass eRet = (typelib_TypeClass)pReturnTypeDescr->eTypeClass; + TYPELIB_DANGER_RELEASE( pReturnTypeDescr ); + return eRet; + } + else + return typelib_TypeClass_VOID; + } +} + + +//================================================================================================== +static typelib_TypeClass cpp_mediate( + sal_Int32 nFunctionIndex, + sal_Int32 nVtableOffset, + void ** pCallStack, + sal_Int64 * pRegisterReturn /* space for register return */ ) +{ + OSL_ENSURE( sizeof(sal_Int32)==sizeof(void *), "### unexpected!" ); + + // pCallStack: this, params + void * pThis; + if( nFunctionIndex & 0x80000000 ) + { + nFunctionIndex &= 0x7fffffff; + pThis = pCallStack[1]; + } + else + { + pThis = pCallStack[0]; + } + pThis = static_cast< char * >(pThis) - nVtableOffset; + bridges::cpp_uno::shared::CppInterfaceProxy * pCppI + = bridges::cpp_uno::shared::CppInterfaceProxy::castInterfaceToProxy( + pThis); + + typelib_InterfaceTypeDescription * pTypeDescr = pCppI->getTypeDescr(); + + OSL_ENSURE( nFunctionIndex < pTypeDescr->nMapFunctionIndexToMemberIndex, + "### illegal vtable index!" ); +// if (nFunctionIndex >= pTypeDescr->nMapFunctionIndexToMemberIndex) +// { +// RuntimeException aExc; +// aExc.Message = OUString::createFromAscii("illegal vtable index!"); +// aExc.Context = (XInterface *)pThis; +// throw aExc; +// } + + // determine called method + sal_Int32 nMemberPos = pTypeDescr->pMapFunctionIndexToMemberIndex[nFunctionIndex]; + OSL_ENSURE( nMemberPos < pTypeDescr->nAllMembers, "### illegal member index!" ); + + TypeDescription aMemberDescr( pTypeDescr->ppAllMembers[nMemberPos] ); + + typelib_TypeClass eRet; + switch (aMemberDescr.get()->eTypeClass) + { + case typelib_TypeClass_INTERFACE_ATTRIBUTE: + { + if (pTypeDescr->pMapMemberIndexToFunctionIndex[nMemberPos] == nFunctionIndex) + { + // is GET method + eRet = cpp2uno_call( + pCppI, aMemberDescr.get(), + ((typelib_InterfaceAttributeTypeDescription *)aMemberDescr.get())->pAttributeTypeRef, + 0, 0, // no params + pCallStack, pRegisterReturn ); + } + else + { + // is SET method + typelib_MethodParameter aParam; + aParam.pTypeRef = + ((typelib_InterfaceAttributeTypeDescription *)aMemberDescr.get())->pAttributeTypeRef; + aParam.bIn = sal_True; + aParam.bOut = sal_False; + + eRet = cpp2uno_call( + pCppI, aMemberDescr.get(), + 0, // indicates void return + 1, &aParam, + pCallStack, pRegisterReturn ); + } + break; + } + case typelib_TypeClass_INTERFACE_METHOD: + { + // is METHOD + switch (nFunctionIndex) + { + // standard XInterface vtable calls + case 1: // acquire() + pCppI->acquireProxy(); // non virtual call! + eRet = typelib_TypeClass_VOID; + break; + case 2: // release() + pCppI->releaseProxy(); // non virtual call! + eRet = typelib_TypeClass_VOID; + break; + case 0: // queryInterface() opt + { + typelib_TypeDescription * pTD = 0; + TYPELIB_DANGER_GET( &pTD, reinterpret_cast< Type * >( pCallStack[2] )->getTypeLibType() ); + if (pTD) + { + XInterface * pInterface = 0; + (*pCppI->getBridge()->getCppEnv()->getRegisteredInterface)( + pCppI->getBridge()->getCppEnv(), + (void **)&pInterface, pCppI->getOid().pData, + (typelib_InterfaceTypeDescription *)pTD ); + + if (pInterface) + { + ::uno_any_construct( + reinterpret_cast< uno_Any * >( pCallStack[0] ), + &pInterface, pTD, + reinterpret_cast< uno_AcquireFunc >(cpp_acquire) ); + pInterface->release(); + TYPELIB_DANGER_RELEASE( pTD ); + *(void **)pRegisterReturn = pCallStack[0]; + eRet = typelib_TypeClass_ANY; + break; + } + TYPELIB_DANGER_RELEASE( pTD ); + } + } // else perform queryInterface() + default: + eRet = cpp2uno_call( + pCppI, aMemberDescr.get(), + ((typelib_InterfaceMethodTypeDescription *)aMemberDescr.get())->pReturnTypeRef, + ((typelib_InterfaceMethodTypeDescription *)aMemberDescr.get())->nParams, + ((typelib_InterfaceMethodTypeDescription *)aMemberDescr.get())->pParams, + pCallStack, pRegisterReturn ); + } + break; + } +// default: +// { +// RuntimeException aExc; +// aExc.Message = OUString::createFromAscii("no member description found!"); +// aExc.Context = (XInterface *)pThis; +// throw aExc; +// // is here for dummy +// eRet = typelib_TypeClass_VOID; +// } + } + + return eRet; +} + +} + +//================================================================================================== +extern "C" int cpp_vtable_call( + int nFunctionIndex, int nVtableOffset, void** pCallStack ) +{ + sal_Int64 nRegReturn; + typelib_TypeClass aType = cpp_mediate( + nFunctionIndex, nVtableOffset, pCallStack, &nRegReturn ); + OSL_ASSERT( sizeof(void *) == sizeof(sal_Int32) ); + switch( aType ) + { + // move return value into register space + // (will be loaded by machine code snippet) + // Use pCallStack[1/2] instead of pCallStack[0/1], because the former is + // properly dword aligned: + case typelib_TypeClass_BOOLEAN: + case typelib_TypeClass_BYTE: + pCallStack[1] = (void*)*(char*)&nRegReturn; + break; + case typelib_TypeClass_CHAR: + case typelib_TypeClass_SHORT: + case typelib_TypeClass_UNSIGNED_SHORT: + pCallStack[1] = (void*)*(short*)&nRegReturn; + break; + case typelib_TypeClass_DOUBLE: + case typelib_TypeClass_HYPER: + case typelib_TypeClass_UNSIGNED_HYPER: + // move long to %i1 + pCallStack[2] = ((void **)&nRegReturn)[ 1 ]; + case typelib_TypeClass_FLOAT: + default: + // move long to %i0 + pCallStack[1] = ((void **)&nRegReturn)[ 0 ]; + break; + } + return aType; +} + +//================================================================================================== +namespace { + +extern "C" void privateSnippetExecutor(); + +int const codeSnippetSize = 7 * 4; + +unsigned char * codeSnippet( + unsigned char * code, sal_Int32 functionIndex, sal_Int32 vtableOffset, + bool simpleRetType) +{ + sal_uInt32 index = functionIndex; + if (!simpleRetType) { + index |= 0x80000000; + } + unsigned int * p = reinterpret_cast< unsigned int * >(code); + OSL_ASSERT(sizeof (unsigned int) == 4); + // save %sp, -96, %sp ! 92 byte minimal stack frame, + 4 byte dword align: + *p++ = 0x9DE3BFA0; + // sethi %hi(privateSnippetExecutor), %l0: + *p++ = 0x21000000 + | (reinterpret_cast< unsigned int >(privateSnippetExecutor) >> 10); + // sethi %hi(index), %o0: + *p++ = 0x11000000 | (index >> 10); + // or %o0, %lo(index), %o0: + *p++ = 0x90122000 | (index & 0x3FF); + // sethi %hi(vtableOffset), %o1: + *p++ = 0x13000000 | (vtableOffset >> 10); + // jmpl %l0, %lo(privateSnippetExecutor), %g0: + *p++ = 0x81C42000 + | (reinterpret_cast< unsigned int >(privateSnippetExecutor) & 0x3FF); + // or %o1, %lo(vtableOffset), %o1: + *p++ = 0x92126000 | (vtableOffset & 0x3FF); + OSL_ASSERT( + reinterpret_cast< unsigned char * >(p) - code <= codeSnippetSize); + return code + codeSnippetSize; +} + +} + +struct bridges::cpp_uno::shared::VtableFactory::Slot { void * fn; }; + +bridges::cpp_uno::shared::VtableFactory::Slot * +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) +{ + return (slotCount + 3) * sizeof (Slot) + slotCount * codeSnippetSize; +} + +bridges::cpp_uno::shared::VtableFactory::Slot * +bridges::cpp_uno::shared::VtableFactory::initializeBlock( + void * block, sal_Int32 slotCount) +{ + Slot * slots = mapBlockToVtable(block) + 2; + slots[-3].fn = 0; // RTTI + slots[-2].fn = 0; // null + slots[-1].fn = 0; // destructor + return slots + slotCount; +} + +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) +{ + (*slots) -= functionCount; + Slot * s = *slots; + 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: + (s++)->fn = 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) + { + (s++)->fn = code; + code = codeSnippet(code, functionOffset++, vtableOffset, true); + } + break; + + case typelib_TypeClass_INTERFACE_METHOD: + (s++)->fn = code; + code = codeSnippet( + code, functionOffset++, vtableOffset, + bridges::cpp_uno::shared::isSimpleType( + reinterpret_cast< + typelib_InterfaceMethodTypeDescription * >( + member)->pReturnTypeRef)); + break; + + default: + OSL_ASSERT(false); + break; + } + TYPELIB_DANGER_RELEASE(member); + } + return code; +} + +void bridges::cpp_uno::shared::VtableFactory::flushCode( + unsigned char const * begin, unsigned char const * end) +{ + bridges::cpp_uno::cc50_solaris_sparc::flushCode(begin, end); +} diff --git a/bridges/source/cpp_uno/cc50_solaris_sparc/except.cxx b/bridges/source/cpp_uno/cc50_solaris_sparc/except.cxx new file mode 100644 index 000000000000..2ee6bb3614b6 --- /dev/null +++ b/bridges/source/cpp_uno/cc50_solaris_sparc/except.cxx @@ -0,0 +1,445 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_bridges.hxx" + +#include <cstddef> +#include <dlfcn.h> +#include <new.h> +#include <typeinfo> +#include <list> +#include <map> +#include <rtl/alloc.h> +#include <osl/diagnose.h> +#include <typelib/typedescription.hxx> +#include <com/sun/star/uno/Any.hxx> +#include "com/sun/star/uno/RuntimeException.hpp" + +#include "cc50_solaris_sparc.hxx" +#include "flushcode.hxx" +#include <rtl/strbuf.hxx> + +#include "bridges/cpp_uno/shared/arraypointer.hxx" + +#include <hash.cxx> + +// need a += operator for OString and sal_Char +namespace rtl +{ + inline OString& operator+=( OString& rString, sal_Char cAdd ) + { + sal_Char add[2]; + add[0] = cAdd; + add[1] = 0; + return rString += add; + } +} + +using namespace std; +using namespace osl; +using namespace rtl; +using namespace com::sun::star::uno; + +namespace CPPU_CURRENT_NAMESPACE +{ + +//================================================================================================== +static OString toUNOname( const OString & rRTTIname ) +{ + OString aRet; + + const sal_Char* pRTTI = rRTTIname.getStr(); + const sal_Char* pOrg = pRTTI; + const sal_Char* pLast = pRTTI; + + while( 1 ) + { + if( *pRTTI == ':' || ! *pRTTI ) + { + if( aRet.getLength() ) + aRet += "."; + aRet += rRTTIname.copy( pLast - pOrg, pRTTI - pLast ); + while( *pRTTI == ':' ) + pRTTI++; + pLast = pRTTI; + if( ! *pRTTI ) + break; + } + else + pRTTI++; + } + + return aRet; +} +//================================================================================================== +static OString toRTTIname( const OString & rUNOname ) +{ + OStringBuffer aRet( rUNOname.getLength()*2 ); + + sal_Int32 nIndex = 0; + do + { + if( nIndex > 0 ) + aRet.append( "::" ); + aRet.append( rUNOname.getToken( 0, '.', nIndex ) ); + } while( nIndex != -1 ); + + return aRet.makeStringAndClear(); +} +//================================================================================================== + +static OString toRTTImangledname( const OString & rRTTIname ) +{ + if( ! rRTTIname.getLength() ) + return OString(); + + OStringBuffer aRet( rRTTIname.getLength()*2 ); + + aRet.append( "__1n" ); + sal_Int32 nIndex = 0; + do + { + OString aToken( rRTTIname.getToken( 0, ':', nIndex ) ); + int nBytes = aToken.getLength(); + if( nBytes ) + { + if( nBytes > 25 ) + { + aRet.append( (sal_Char)( nBytes/26 + 'a' ) ); + aRet.append( (sal_Char)( nBytes%26 + 'A' ) ); + } + else + aRet.append( (sal_Char)( nBytes + 'A' ) ); + for (sal_Int32 i = 0; i < aToken.getLength(); ++i) { + char c = aToken[i]; + if (c == 'Q') { + aRet.append("QdD"); + } else { + aRet.append(c); + } + } + } + } while( nIndex != -1 ); + + aRet.append( '_' ); + + return aRet.makeStringAndClear(); +} + + +//################################################################################################## +//#### RTTI simulation ############################################################################# +//################################################################################################## + +class RTTIHolder +{ + std::map< OString, void* > aAllRTTI; +public: + ~RTTIHolder(); + + void* getRTTI( const OString& rTypename ); + void* getRTTI_UnoName( const OString& rUnoTypename ) + { return getRTTI( toRTTIname( rUnoTypename ) ); } + + void* insertRTTI( const OString& rTypename ); + void* insertRTTI_UnoName( const OString& rTypename ) + { return insertRTTI( toRTTIname( rTypename ) ); } + void* generateRTTI( typelib_CompoundTypeDescription* pCompTypeDescr ); +}; + +RTTIHolder::~RTTIHolder() +{ + for ( std::map< OString, void* >::const_iterator iPos( aAllRTTI.begin() ); + iPos != aAllRTTI.end(); ++iPos ) + { + delete[] static_cast< char * >(iPos->second); + } +} + +#if OSL_DEBUG_LEVEL > 1 +#include <stdio.h> +#endif + +void* RTTIHolder::getRTTI( const OString& rTypename ) +{ + std::map< OString, void* >::iterator element; + + element = aAllRTTI.find( rTypename ); + if( element != aAllRTTI.end() ) + return (*element).second; + + // create rtti structure + element = aAllRTTI.find( rTypename ); + if( element != aAllRTTI.end() ) + return (*element).second; + + return NULL; +} + +void* RTTIHolder::insertRTTI( const OString& rTypename ) +{ + OString aMangledName( toRTTImangledname( rTypename ) ); + NIST_Hash aHash( aMangledName.getStr(), aMangledName.getLength() ); + + std::size_t const RTTI_SIZE = 19; // 14??? + void** pRTTI = reinterpret_cast< void ** >( + new char[RTTI_SIZE * sizeof (void *) + strlen(rTypename.getStr()) + 1]); + pRTTI[ 0 ] = reinterpret_cast< void * >(RTTI_SIZE * sizeof (void *)); + pRTTI[ 1 ] = NULL; + pRTTI[ 2 ] = (void*)(7*sizeof(void*)); + pRTTI[ 3 ] = (void*)aHash.getHash()[0]; + pRTTI[ 4 ] = (void*)aHash.getHash()[1]; + pRTTI[ 5 ] = (void*)aHash.getHash()[2]; + pRTTI[ 6 ] = (void*)aHash.getHash()[3]; + pRTTI[ 7 ] = NULL; + pRTTI[ 8 ] = NULL; + + pRTTI[ 9 ] = pRTTI[ 3 ]; + pRTTI[ 10 ] = pRTTI[ 4 ]; + pRTTI[ 11 ] = pRTTI[ 5 ]; + pRTTI[ 12 ] = pRTTI[ 6 ]; + pRTTI[ 13 ] = (void*)0x80000000; + strcpy(reinterpret_cast< char * >(pRTTI + RTTI_SIZE), rTypename.getStr()); + + aAllRTTI[ rTypename ] = (void*)pRTTI; +#if OSL_DEBUG_LEVEL > 1 + fprintf( stderr, + "generating base RTTI for type %s:\n" + " mangled: %s\n" + " hash: %.8x %.8x %.8x %.8x\n", + rTypename.getStr(), + aMangledName.getStr(), + pRTTI[ 3 ], pRTTI[ 4 ], pRTTI[ 5 ], pRTTI[ 6 ] + ); +#endif + return pRTTI; +} + +//-------------------------------------------------------------------------------------------------- + +void* RTTIHolder::generateRTTI( typelib_CompoundTypeDescription * pCompTypeDescr ) +{ + OString aUNOCompTypeName( OUStringToOString( pCompTypeDescr->aBase.pTypeName, RTL_TEXTENCODING_ASCII_US ) ); + OString aRTTICompTypeName( toRTTIname( aUNOCompTypeName ) ); + + void* pHaveRTTI = getRTTI( aRTTICompTypeName ); + if( pHaveRTTI ) + return pHaveRTTI; + + if( ! pCompTypeDescr->pBaseTypeDescription ) + // this is a base type + return insertRTTI( aRTTICompTypeName ); + + // get base class RTTI + void* pSuperRTTI = generateRTTI( pCompTypeDescr->pBaseTypeDescription ); + OSL_ENSURE( pSuperRTTI, "could not generate RTTI for supertype !" ); + + // find out the size to allocate for RTTI + void** pInherit = (void**)((sal_uInt32)pSuperRTTI + ((sal_uInt32*)pSuperRTTI)[2] + 8); + int nInherit; + for( nInherit = 1; pInherit[ nInherit*5-1 ] != (void*)0x80000000; nInherit++ ) + ; + + OString aMangledName( toRTTImangledname( aRTTICompTypeName ) ); + NIST_Hash aHash( aMangledName.getStr(), aMangledName.getLength() ); + + std::size_t const rttiSize = 14 + nInherit * 5; + void** pRTTI = reinterpret_cast< void ** >( + new char[ + rttiSize * sizeof (void *) + + strlen(aRTTICompTypeName.getStr()) + 1]); + pRTTI[ 0 ] = reinterpret_cast< void * >(rttiSize * sizeof (void *)); + pRTTI[ 1 ] = NULL; + pRTTI[ 2 ] = (void*)(7*sizeof(void*)); + pRTTI[ 3 ] = (void*)aHash.getHash()[0]; + pRTTI[ 4 ] = (void*)aHash.getHash()[1]; + pRTTI[ 5 ] = (void*)aHash.getHash()[2]; + pRTTI[ 6 ] = (void*)aHash.getHash()[3]; + pRTTI[ 7 ] = NULL; + pRTTI[ 8 ] = NULL; + + memcpy( pRTTI+9, pInherit, 4*nInherit*5 ); + pRTTI[ 8 +nInherit*5 ] = NULL; + pRTTI[ 9 +nInherit*5 ] = pRTTI[ 3 ]; + pRTTI[ 10+nInherit*5 ] = pRTTI[ 4 ]; + pRTTI[ 11+nInherit*5 ] = pRTTI[ 5 ]; + pRTTI[ 12+nInherit*5 ] = pRTTI[ 6 ]; + pRTTI[ 13+nInherit*5 ] = (void*)0x80000000; + strcpy( + reinterpret_cast< char * >(pRTTI + rttiSize), + aRTTICompTypeName.getStr()); + + aAllRTTI[ aRTTICompTypeName ] = (void*)pRTTI; + +#if OSL_DEBUG_LEVEL > 1 + fprintf( stderr, + "generating struct RTTI for type %s:\n" + " mangled: %s\n" + " hash: %.8x %.8x %.8X %.8x\n", + aRTTICompTypeName.getStr(), + aMangledName.getStr(), + pRTTI[ 3 ], pRTTI[ 4 ], pRTTI[ 5 ], pRTTI[ 6 ] + ); +#endif + + return pRTTI; +} + +//-------------------------------------------------------------------------------------------------- + +static void deleteException( + void* pExc, unsigned int* thunk, typelib_TypeDescription* pType ) +{ + uno_destructData( + pExc, pType, reinterpret_cast< uno_ReleaseFunc >(cpp_release) ); + typelib_typedescription_release( pType ); + delete[] thunk; +} + +//__________________________________________________________________________________________________ + +//################################################################################################## +//#### exported #################################################################################### +//################################################################################################## + +void cc50_solaris_sparc_raiseException( uno_Any * pUnoExc, uno_Mapping * pUno2Cpp ) +{ +#if OSL_DEBUG_LEVEL > 1 + OString cstr( + OUStringToOString( + *reinterpret_cast< OUString const * >( &pUnoExc->pType->pTypeName ), + RTL_TEXTENCODING_ASCII_US ) ); + fprintf( stderr, "> uno exception occured: %s\n", cstr.getStr() ); +#endif + bridges::cpp_uno::shared::ArrayPointer< unsigned int > thunkPtr( + new unsigned int[6]); + + typelib_TypeDescription * pTypeDescr = 0; + // will be released by deleteException + typelib_typedescriptionreference_getDescription( &pTypeDescr, pUnoExc->pType ); + + void* pRTTI; + { + static ::osl::Mutex aMutex; + ::osl::Guard< ::osl::Mutex > guard( aMutex ); + + static RTTIHolder * s_pRTTI = 0; + if (! s_pRTTI) + { +#ifdef LEAK_STATIC_DATA + s_pRTTI = new RTTIHolder(); +#else + static RTTIHolder s_aRTTI; + s_pRTTI = &s_aRTTI; +#endif + } + + pRTTI = s_pRTTI->generateRTTI( (typelib_CompoundTypeDescription *)pTypeDescr ); + } + + // a must be + OSL_ENSURE( sizeof(sal_Int32) == sizeof(void *), "### pointer size differs from sal_Int32!" ); + + void * pCppExc = __Crun::ex_alloc( pTypeDescr->nSize ); + uno_copyAndConvertData( pCppExc, pUnoExc->pData, pTypeDescr, pUno2Cpp ); + + // destruct uno exception + uno_any_destruct( pUnoExc, 0 ); + + unsigned int * thunk = thunkPtr.release(); + // sethi %hi(thunk), %o1: + thunk[0] = 0x13000000 | (reinterpret_cast< unsigned int >(thunk) >> 10); + // or %o1, %lo(thunk), %o1: + thunk[1] = 0x92126000 | (reinterpret_cast< unsigned int >(thunk) & 0x3FF); + // sethi %hi(pTypeDescr), %o2: + thunk[2] = 0x15000000 + | (reinterpret_cast< unsigned int >(pTypeDescr) >> 10); + // sethi %hi(deleteException), %o3 + thunk[3] = 0x17000000 + | (reinterpret_cast< unsigned int >(deleteException) >> 10); + // jmpl %o3, %lo(deleteException), %g0 + thunk[4] = 0x81C2E000 + | (reinterpret_cast< unsigned int >(deleteException) & 0x3FF); + // or %o2, %lo(pTypeDescr), %o2: + thunk[5] = 0x9412A000 + | (reinterpret_cast< unsigned int >(pTypeDescr) & 0x3FF); + bridges::cpp_uno::cc50_solaris_sparc::flushCode(thunk, thunk + 6); + +#pragma disable_warn + void (* f)(void *) = reinterpret_cast< void (*)(void *) >(thunk); +#pragma enable_warn + __Crun::ex_throw(pCppExc, (const __Crun::static_type_info*)pRTTI, f); +} + +void cc50_solaris_sparc_fillUnoException( + void* pCppExc, + const char* pInfo, + uno_Any* pUnoExc, + uno_Mapping * pCpp2Uno ) +{ + OSL_ASSERT( pInfo != 0 ); + OString uno_name( toUNOname( pInfo ) ); + OUString aName( OStringToOUString( + uno_name, RTL_TEXTENCODING_ASCII_US ) ); + typelib_TypeDescription * pExcTypeDescr = 0; + typelib_typedescription_getByName( &pExcTypeDescr, aName.pData ); + + if (pExcTypeDescr == 0) // the thing that should not be + { + RuntimeException aRE( + OUString( RTL_CONSTASCII_USTRINGPARAM( + "exception type not found: ") ) + aName, + Reference< XInterface >() ); + Type const & rType = ::getCppuType( &aRE ); + 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() ); +#endif + return; + } + +#if OSL_DEBUG_LEVEL > 1 + fprintf( stderr, "> c++ exception occured: %s\n", + ::rtl::OUStringToOString( + pExcTypeDescr->pTypeName, + RTL_TEXTENCODING_ASCII_US ).getStr() ); +#endif + // construct uno exception any + uno_any_constructAndConvert( + pUnoExc, pCppExc, pExcTypeDescr, pCpp2Uno ); + typelib_typedescription_release( pExcTypeDescr ); +} + +} + + + + diff --git a/bridges/source/cpp_uno/cc50_solaris_sparc/flushcode.hxx b/bridges/source/cpp_uno/cc50_solaris_sparc/flushcode.hxx new file mode 100644 index 000000000000..af0c551f10df --- /dev/null +++ b/bridges/source/cpp_uno/cc50_solaris_sparc/flushcode.hxx @@ -0,0 +1,48 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef INCLUDED_BRIDGES_SOURCE_CPP_UNO_CC50_SOLARIS_SPARC_FLUSHCODE_HXX +#define INCLUDED_BRIDGES_SOURCE_CPP_UNO_CC50_SOLARIS_SPARC_FLUSHCODE_HXX + +#include "sal/config.h" + +extern "C" void sync_instruction_memory(caddr_t addr, int len); // from libc + +namespace bridges { namespace cpp_uno { namespace cc50_solaris_sparc { + +/** + * Flush a region of memory into which code has been written dynamically. + */ +inline void flushCode(void const * begin, void const * end) { + sync_instruction_memory( + static_cast< caddr_t >(const_cast< void * >(begin)), + static_cast< char const * >(end) - static_cast< char const * >(begin)); +} + +} } } + +#endif diff --git a/bridges/source/cpp_uno/cc50_solaris_sparc/hash.cxx b/bridges/source/cpp_uno/cc50_solaris_sparc/hash.cxx new file mode 100644 index 000000000000..0d1c49a23c11 --- /dev/null +++ b/bridges/source/cpp_uno/cc50_solaris_sparc/hash.cxx @@ -0,0 +1,264 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_bridges.hxx" + + +#ifndef TEST +#ifndef _SAL_TYPES_H_ +#include <sal/types.h> +#endif +#else +typedef unsigned int sal_uInt32; +#endif + +#include <string.h> + +/* + * build a hash for a character buffer using the NIST algorithm + */ + +class NIST_Hash +{ + + // helper functions + sal_uInt32 f1( sal_uInt32 x, sal_uInt32 y, sal_uInt32 z ) + { + return z ^ ( x & ( y ^ z ) ); + } + + sal_uInt32 f2( sal_uInt32 x, sal_uInt32 y, sal_uInt32 z ) + { + return x ^ y ^ z; + } + + sal_uInt32 f3( sal_uInt32 x, sal_uInt32 y, sal_uInt32 z ) + { + return ( x & y ) + ( z & ( x ^ y ) ); + } + + sal_uInt32 rotl( sal_uInt32 nValue, sal_uInt32 nBits ) + { + return ( nValue << nBits ) | ( nValue >> (32-nBits) ); + } + + sal_uInt32 expand_nostore( sal_uInt32 index ) + { + return data[index&15] ^ data[(index-14)&15] ^ data[(index-8)&15] ^ data[(index-3)&15]; + } + + sal_uInt32 expand_store( sal_uInt32 index ) + { + return data[index&15] ^= data[(index-14)&15] ^ data[(index-8)&15] ^ data[(index-3)&15]; + } + + void subRound( sal_uInt32 a, sal_uInt32& b, sal_uInt32 c, sal_uInt32 d, sal_uInt32& e, sal_uInt32 constant, sal_uInt32 datum, sal_uInt32 nFunction ) + { + e += rotl(a,5); + switch( nFunction ) + { + case 1: e += f1( b, c, d );break; + case 2: + case 4: e += f2( b, c, d );break; + case 3: e += f3( b, c, d );break; + } + e += constant + datum; + b = rotl( b, 30 ); + } + + void transform(); + void final(); + + // data members + sal_uInt32 data[16]; + sal_uInt32 hashdata[5]; +public: + NIST_Hash( const char* pString, sal_uInt32 nLen ); + + sal_uInt32 *getHash() { return hashdata; } +}; + +void NIST_Hash::transform() +{ + // constants + const sal_uInt32 K2 = 0x5A827999; + const sal_uInt32 K3 = 0x6ED9EBA1; + const sal_uInt32 K5 = 0x8F1BBCDC; + const sal_uInt32 K10 = 0xCA62C1D6; + + sal_uInt32 a, b, c, d, e; + a = hashdata[0]; + b = hashdata[1]; + c = hashdata[2]; + d = hashdata[3]; + e = hashdata[4]; + + subRound( a, b, c, d, e, K2, data[ 0], 1 ); + subRound( e, a, b, c, d, K2, data[ 1], 1 ); + subRound( d, e, a, b, c, K2, data[ 2], 1 ); + subRound( c, d, e, a, b, K2, data[ 3], 1 ); + subRound( b, c, d, e, a, K2, data[ 4], 1 ); + subRound( a, b, c, d, e, K2, data[ 5], 1 ); + subRound( e, a, b, c, d, K2, data[ 6], 1 ); + subRound( d, e, a, b, c, K2, data[ 7], 1 ); + subRound( c, d, e, a, b, K2, data[ 8], 1 ); + subRound( b, c, d, e, a, K2, data[ 9], 1 ); + subRound( a, b, c, d, e, K2, data[10], 1 ); + subRound( e, a, b, c, d, K2, data[11], 1 ); + subRound( d, e, a, b, c, K2, data[12], 1 ); + subRound( c, d, e, a, b, K2, data[13], 1 ); + subRound( b, c, d, e, a, K2, data[14], 1 ); + subRound( a, b, c, d, e, K2, data[15], 1 ); + subRound( e, a, b, c, d, K2, expand_store( 16 ), 1 ); + subRound( d, e, a, b, c, K2, expand_store( 17 ), 1 ); + subRound( c, d, e, a, b, K2, expand_store( 18 ), 1 ); + subRound( b, c, d, e, a, K2, expand_store( 19 ), 1 ); + + subRound( a, b, c, d, e, K3, expand_store( 20 ), 2 ); + subRound( e, a, b, c, d, K3, expand_store( 21 ), 2 ); + subRound( d, e, a, b, c, K3, expand_store( 22 ), 2 ); + subRound( c, d, e, a, b, K3, expand_store( 23 ), 2 ); + subRound( b, c, d, e, a, K3, expand_store( 24 ), 2 ); + subRound( a, b, c, d, e, K3, expand_store( 25 ), 2 ); + subRound( e, a, b, c, d, K3, expand_store( 26 ), 2 ); + subRound( d, e, a, b, c, K3, expand_store( 27 ), 2 ); + subRound( c, d, e, a, b, K3, expand_store( 28 ), 2 ); + subRound( b, c, d, e, a, K3, expand_store( 29 ), 2 ); + subRound( a, b, c, d, e, K3, expand_store( 30 ), 2 ); + subRound( e, a, b, c, d, K3, expand_store( 31 ), 2 ); + subRound( d, e, a, b, c, K3, expand_store( 32 ), 2 ); + subRound( c, d, e, a, b, K3, expand_store( 33 ), 2 ); + subRound( b, c, d, e, a, K3, expand_store( 34 ), 2 ); + subRound( a, b, c, d, e, K3, expand_store( 35 ), 2 ); + subRound( e, a, b, c, d, K3, expand_store( 36 ), 2 ); + subRound( d, e, a, b, c, K3, expand_store( 37 ), 2 ); + subRound( c, d, e, a, b, K3, expand_store( 38 ), 2 ); + subRound( b, c, d, e, a, K3, expand_store( 39 ), 2 ); + + subRound( a, b, c, d, e, K5, expand_store( 40 ), 3 ); + subRound( e, a, b, c, d, K5, expand_store( 41 ), 3 ); + subRound( d, e, a, b, c, K5, expand_store( 42 ), 3 ); + subRound( c, d, e, a, b, K5, expand_store( 43 ), 3 ); + subRound( b, c, d, e, a, K5, expand_store( 44 ), 3 ); + subRound( a, b, c, d, e, K5, expand_store( 45 ), 3 ); + subRound( e, a, b, c, d, K5, expand_store( 46 ), 3 ); + subRound( d, e, a, b, c, K5, expand_store( 47 ), 3 ); + subRound( c, d, e, a, b, K5, expand_store( 48 ), 3 ); + subRound( b, c, d, e, a, K5, expand_store( 49 ), 3 ); + subRound( a, b, c, d, e, K5, expand_store( 50 ), 3 ); + subRound( e, a, b, c, d, K5, expand_store( 51 ), 3 ); + subRound( d, e, a, b, c, K5, expand_store( 52 ), 3 ); + subRound( c, d, e, a, b, K5, expand_store( 53 ), 3 ); + subRound( b, c, d, e, a, K5, expand_store( 54 ), 3 ); + subRound( a, b, c, d, e, K5, expand_store( 55 ), 3 ); + subRound( e, a, b, c, d, K5, expand_store( 56 ), 3 ); + subRound( d, e, a, b, c, K5, expand_store( 57 ), 3 ); + subRound( c, d, e, a, b, K5, expand_store( 58 ), 3 ); + subRound( b, c, d, e, a, K5, expand_store( 59 ), 3 ); + + subRound( a, b, c, d, e, K10, expand_store( 60 ), 4 ); + subRound( e, a, b, c, d, K10, expand_store( 61 ), 4 ); + subRound( d, e, a, b, c, K10, expand_store( 62 ), 4 ); + subRound( c, d, e, a, b, K10, expand_store( 63 ), 4 ); + subRound( b, c, d, e, a, K10, expand_store( 64 ), 4 ); + subRound( a, b, c, d, e, K10, expand_store( 65 ), 4 ); + subRound( e, a, b, c, d, K10, expand_store( 66 ), 4 ); + subRound( d, e, a, b, c, K10, expand_store( 67 ), 4 ); + subRound( c, d, e, a, b, K10, expand_store( 68 ), 4 ); + subRound( b, c, d, e, a, K10, expand_store( 69 ), 4 ); + subRound( a, b, c, d, e, K10, expand_store( 70 ), 4 ); + subRound( e, a, b, c, d, K10, expand_store( 71 ), 4 ); + subRound( d, e, a, b, c, K10, expand_store( 72 ), 4 ); + subRound( c, d, e, a, b, K10, expand_store( 73 ), 4 ); + subRound( b, c, d, e, a, K10, expand_store( 74 ), 4 ); + subRound( a, b, c, d, e, K10, expand_store( 75 ), 4 ); + subRound( e, a, b, c, d, K10, expand_store( 76 ), 4 ); + subRound( d, e, a, b, c, K10, expand_nostore( 77 ), 4 ); + subRound( c, d, e, a, b, K10, expand_nostore( 78 ), 4 ); + subRound( b, c, d, e, a, K10, expand_nostore( 79 ), 4 ); + + hashdata[0] += a; + hashdata[1] += b; + hashdata[2] += c; + hashdata[3] += d; + hashdata[4] += e; +} + +#define BLOCKSIZE sizeof( data ) + +NIST_Hash::NIST_Hash( const char* pString, sal_uInt32 nLen ) +{ + hashdata[0] = 0x67452301; + hashdata[1] = 0xefcdab89; + hashdata[2] = 0x98badcfe; + hashdata[3] = 0x10325476; + hashdata[4] = 0xc3d2e1f0; + + sal_uInt32 nBytes = nLen; + + while( nLen >= sizeof( data ) ) + { + memcpy( data, pString, sizeof( data ) ); + pString += sizeof( data ); + nLen -= sizeof( data ); + transform(); + } + memcpy( data, pString, nLen ); + ((char*)data)[nLen++] = 0x80; + if( nLen > sizeof( data ) - 8 ) + { + memset( ((char*)data)+nLen, 0, sizeof( data ) - nLen ); + transform(); + memset( data, 0, sizeof( data ) - 8 ); + } + else + memset( ((char*)data)+nLen, 0, sizeof( data ) - 8 - nLen ); + data[14] = 0; + data[15] = nBytes << 3; + transform(); +} + +#ifdef TEST +#include <stdio.h> +int main( int argc, const char** argv ) +{ + const char* pHash = argc < 2 ? argv[0] : argv[1]; + + NIST_Hash aHash( pHash, strlen( pHash ) ); + sal_uInt32* pBits = aHash.getHash(); + + printf( "text : %s\n" + "bits : 0x%.8x 0x%.8x 0x%.8x 0x%.8x 0x%.8x\n", + pHash, + pBits[0], pBits[1], pBits[2],pBits[3],pBits[4] + ); + return 0; +} + +#endif diff --git a/bridges/source/cpp_uno/cc50_solaris_sparc/makefile.mk b/bridges/source/cpp_uno/cc50_solaris_sparc/makefile.mk new file mode 100644 index 000000000000..2af2f29a02a3 --- /dev/null +++ b/bridges/source/cpp_uno/cc50_solaris_sparc/makefile.mk @@ -0,0 +1,80 @@ +#************************************************************************* +# +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# Copyright 2000, 2010 Oracle and/or its affiliates. +# +# OpenOffice.org - a multi-platform office productivity suite +# +# This file is part of OpenOffice.org. +# +# OpenOffice.org is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License version 3 +# only, as published by the Free Software Foundation. +# +# OpenOffice.org is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License version 3 for more details +# (a copy is included in the LICENSE file that accompanied this code). +# +# You should have received a copy of the GNU Lesser General Public License +# version 3 along with OpenOffice.org. If not, see +# <http://www.openoffice.org/license.html> +# for a copy of the LGPLv3 License. +# +#************************************************************************* + +PRJ=..$/..$/.. + +PRJNAME=bridges +TARGET=sunpro5_uno +LIBTARGET=no +ENABLE_EXCEPTIONS=TRUE + +# --- Settings ----------------------------------------------------- + +.INCLUDE : settings.mk + +# --- Files -------------------------------------------------------- + +# disable check for PIC code as it would complain about +# hand coded assembler +CHECKFORPIC= + +.IF "$(COM)" == "C52" && "$(CPU)"=="S" + +#CFLAGS += -O5 -xO5 + +.IF "$(cppu_no_leak)" == "" +CFLAGS += -DLEAK_STATIC_DATA +.ENDIF + +SLOFILES= \ + $(SLO)$/cpp2uno.obj \ + $(SLO)$/uno2cpp.obj \ + $(SLO)$/except.obj \ + $(SLO)$/call.obj + +SHL1TARGET= $(TARGET) + +SHL1DEF= $(MISC)$/$(SHL1TARGET).def +SHL1IMPLIB= i$(TARGET) +SHL1VERSIONMAP=..$/..$/bridge_exports.map +SHL1RPATH= URELIB + +SHL1OBJS = $(SLOFILES) +SHL1LIBS = $(SLB)$/cpp_uno_shared.lib + +SHL1STDLIBS= \ + $(CPPULIB) \ + $(SALLIB) + +.ENDIF + +.INCLUDE : target.mk + + +$(SLO)$/%.obj: %.s + CC -KPIC -c -o $(SLO)$/$(@:b).o $< && touch $@ + diff --git a/bridges/source/cpp_uno/cc50_solaris_sparc/uno2cpp.cxx b/bridges/source/cpp_uno/cc50_solaris_sparc/uno2cpp.cxx new file mode 100644 index 000000000000..896695540f90 --- /dev/null +++ b/bridges/source/cpp_uno/cc50_solaris_sparc/uno2cpp.cxx @@ -0,0 +1,396 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_bridges.hxx" + +#include <sal/alloca.h> + +#include <com/sun/star/uno/genfunc.hxx> +#include "com/sun/star/uno/RuntimeException.hpp" +#include <uno/data.h> + +#include "bridges/cpp_uno/shared/bridge.hxx" +#include "bridges/cpp_uno/shared/types.hxx" +#include "bridges/cpp_uno/shared/unointerfaceproxy.hxx" +#include "bridges/cpp_uno/shared/vtables.hxx" + +#include "cc50_solaris_sparc.hxx" + +using namespace rtl; +using namespace com::sun::star::uno; + +namespace +{ + +extern "C" void callVirtualMethod( + void * pAdjustedThisPtr, + sal_Int32 nVtableIndex, + void * pRegisterReturn, + typelib_TypeClass eReturnType, + sal_Int32 * pStackLongs, + sal_Int32 nStackLongs + ); + +//================================================================================================== +static void 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 ) +{ + // pCppI is cc50_solaris_sparc this pointer + OSL_ENSURE( pThis, "### no interface given!" ); + + // max space for: [complex ret ptr], values|ptr ... + char * pCppStack = (char *)alloca( ((nParams+3) * sizeof(sal_Int64)) ); + char * pCppStackStart = pCppStack; + + // return + typelib_TypeDescription * pReturnTypeDescr = 0; + TYPELIB_DANGER_GET( &pReturnTypeDescr, pReturnTypeRef ); + OSL_ENSURE( pReturnTypeDescr, "### expected return type description!" ); + + void * pCppReturn = 0; // if != 0 && != pUnoReturn, needs reconversion + + if (pReturnTypeDescr) + { + if (bridges::cpp_uno::shared::isSimpleType( pReturnTypeDescr )) + { + pCppReturn = pUnoReturn; // direct way for simple types + } + else + { + // complex return via ptr + pCppReturn = *(void **)pCppStack + = (bridges::cpp_uno::shared::relatesToInterfaceType( + pReturnTypeDescr ) + ? alloca( pReturnTypeDescr->nSize ) + : pUnoReturn); // direct way + pCppStack += sizeof(void *); + } + } + // push this + void * pAdjustedThisPtr = reinterpret_cast< void ** >(pThis->getCppI()) + + aVtableSlot.offset; + *(void**)pCppStack = pAdjustedThisPtr; + pCppStack += sizeof( void* ); + + // args + void ** pCppArgs = (void **)alloca( 3 * sizeof(void *) * nParams ); + // indizes of values this have to be converted (interface conversion cpp<=>uno) + sal_Int32 * pTempIndizes = (sal_Int32 *)(pCppArgs + nParams); + // type descriptions for reconversions + typelib_TypeDescription ** ppTempParamTypeDescr = (typelib_TypeDescription **)(pCppArgs + (2 * nParams)); + + sal_Int32 nTempIndizes = 0; + + for ( sal_Int32 nPos = 0; nPos < nParams; ++nPos ) + { + 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 )) + { + pCppArgs[ nPos ] = CPPU_CURRENT_NAMESPACE::adjustPointer( + pCppStack, pParamTypeDescr ); + uno_copyAndConvertData( pCppArgs[nPos], pUnoArgs[nPos], pParamTypeDescr, + pThis->getBridge()->getUno2Cpp() ); + + switch (pParamTypeDescr->eTypeClass) + { + case typelib_TypeClass_HYPER: + case typelib_TypeClass_UNSIGNED_HYPER: + case typelib_TypeClass_DOUBLE: + pCppStack += sizeof(sal_Int32); // extra long + } + // no longer needed + TYPELIB_DANGER_RELEASE( pParamTypeDescr ); + } + else // ptr to complex value | ref + { + if (! rParam.bIn) // is pure out + { + // cpp out is constructed mem, uno out is not! + uno_constructData( + *(void **)pCppStack = pCppArgs[nPos] = alloca( pParamTypeDescr->nSize ), + pParamTypeDescr ); + pTempIndizes[nTempIndizes] = nPos; // default constructed for cpp call + // will be released at reconversion + ppTempParamTypeDescr[nTempIndizes++] = pParamTypeDescr; + } + // is in/inout + else if (bridges::cpp_uno::shared::relatesToInterfaceType( + pParamTypeDescr )) + { + uno_copyAndConvertData( + *(void **)pCppStack = pCppArgs[nPos] = alloca( pParamTypeDescr->nSize ), + pUnoArgs[nPos], pParamTypeDescr, + pThis->getBridge()->getUno2Cpp() ); + + pTempIndizes[nTempIndizes] = nPos; // has to be reconverted + // will be released at reconversion + ppTempParamTypeDescr[nTempIndizes++] = pParamTypeDescr; + } + else // direct way + { + *(void **)pCppStack = pCppArgs[nPos] = pUnoArgs[nPos]; + // no longer needed + TYPELIB_DANGER_RELEASE( pParamTypeDescr ); + } + } + pCppStack += sizeof(sal_Int32); // standard parameter length + } + +// seems that EH registration for callVirtualMethod is not really +// necessary + +// static unsigned long* pFrameInfo = NULL; + +// if( ! pFrameInfo ) +// { +// pFrameInfo = new unsigned long[ 7 ]; +// pFrameInfo[ 0 ] = 0x40000000 | (((unsigned long)__Crun::ex_rethrow_q) >> 2); +// pFrameInfo[ 1 ] = 0x01000000; +// pFrameInfo[ 2 ] = (unsigned long)callVirtualMethodExceptionHandler; +// pFrameInfo[ 3 ] = 0; +// pFrameInfo[ 4 ] = (unsigned long)pFrameInfo - (unsigned long)callVirtualMethodExceptionHandler; +// pFrameInfo[ 5 ] = 0; +// pFrameInfo[ 6 ] = 0; +// _ex_register( pFrameInfo+2, 1 ); +// } + + try + { + int nStackLongs = (pCppStack - pCppStackStart)/sizeof(sal_Int32); + if( nStackLongs & 1 ) + // stack has to be 8 byte aligned + nStackLongs++; + + callVirtualMethod( + pAdjustedThisPtr, + aVtableSlot.index, + pCppReturn, + pReturnTypeDescr->eTypeClass, + (sal_Int32 *)pCppStackStart, + nStackLongs + ); + + // NO exception occured... + *ppUnoExc = 0; + + // reconvert temporary params + for ( ; nTempIndizes--; ) + { + sal_Int32 nIndex = pTempIndizes[nTempIndizes]; + typelib_TypeDescription * pParamTypeDescr = ppTempParamTypeDescr[nTempIndizes]; + + if (pParams[nIndex].bIn) + { + if (pParams[nIndex].bOut) // inout + { + uno_destructData( pUnoArgs[nIndex], pParamTypeDescr, 0 ); // destroy uno value + uno_copyAndConvertData( pUnoArgs[nIndex], pCppArgs[nIndex], pParamTypeDescr, + pThis->getBridge()->getCpp2Uno() ); + } + } + else // pure out + { + uno_copyAndConvertData( pUnoArgs[nIndex], pCppArgs[nIndex], pParamTypeDescr, + pThis->getBridge()->getCpp2Uno() ); + } + // destroy temp cpp param => cpp: every param was constructed + uno_destructData( + pCppArgs[nIndex], pParamTypeDescr, + reinterpret_cast< uno_ReleaseFunc >(cpp_release) ); + + TYPELIB_DANGER_RELEASE( pParamTypeDescr ); + } + // return value + if (pCppReturn && pUnoReturn != pCppReturn) + { + uno_copyAndConvertData( pUnoReturn, pCppReturn, pReturnTypeDescr, + pThis->getBridge()->getCpp2Uno() ); + uno_destructData( + pCppReturn, pReturnTypeDescr, + reinterpret_cast< uno_ReleaseFunc >(cpp_release) ); + } + } + catch( ... ) + { + void* pExc = __Crun::ex_get(); + const char* pName = __Cimpl::ex_name(); + + // get exception + CPPU_CURRENT_NAMESPACE::cc50_solaris_sparc_fillUnoException( + pExc, pName, *ppUnoExc, pThis->getBridge()->getCpp2Uno()); + + // temporary params + for ( ; nTempIndizes--; ) + { + sal_Int32 nIndex = pTempIndizes[nTempIndizes]; + // destroy temp cpp param => cpp: every param was constructed + uno_destructData( + pCppArgs[nIndex], + ppTempParamTypeDescr[nTempIndizes], + reinterpret_cast< uno_ReleaseFunc >(cpp_release) ); + TYPELIB_DANGER_RELEASE( ppTempParamTypeDescr[nTempIndizes] ); + } + // return type + if (pReturnTypeDescr) + TYPELIB_DANGER_RELEASE( pReturnTypeDescr ); + } +} + +} + +namespace bridges { namespace cpp_uno { namespace shared { + +void unoInterfaceProxyDispatch( + uno_Interface * pUnoI, const typelib_TypeDescription * pMemberDescr, + void * pReturn, void * pArgs[], uno_Any ** ppException ) +{ + // is my surrogate + bridges::cpp_uno::shared::UnoInterfaceProxy * pThis + = static_cast< bridges::cpp_uno::shared::UnoInterfaceProxy * >(pUnoI); + typelib_InterfaceTypeDescription * pTypeDescr = pThis->pTypeDescr; + + switch (pMemberDescr->eTypeClass) + { + case typelib_TypeClass_INTERFACE_ATTRIBUTE: + { + VtableSlot aVtableSlot( + getVtableSlot( + reinterpret_cast< + typelib_InterfaceAttributeTypeDescription const * >( + pMemberDescr))); + if (pReturn) + { + // dependent dispatch + cpp_call( + pThis, aVtableSlot, + ((typelib_InterfaceAttributeTypeDescription *)pMemberDescr)->pAttributeTypeRef, + 0, 0, // no params + pReturn, pArgs, ppException ); + } + else + { + // is SET + typelib_MethodParameter aParam; + aParam.pTypeRef = + ((typelib_InterfaceAttributeTypeDescription *)pMemberDescr)->pAttributeTypeRef; + aParam.bIn = sal_True; + aParam.bOut = sal_False; + + typelib_TypeDescriptionReference * pReturnTypeRef = 0; + 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, + pReturnTypeRef, + 1, &aParam, + pReturn, pArgs, ppException ); + + typelib_typedescriptionreference_release( pReturnTypeRef ); + } + + break; + } + case typelib_TypeClass_INTERFACE_METHOD: + { + VtableSlot aVtableSlot( + getVtableSlot( + reinterpret_cast< + typelib_InterfaceMethodTypeDescription const * >( + pMemberDescr))); + switch (aVtableSlot.index) + { + // standard calls + case 1: // acquire uno interface + (*pUnoI->acquire)( pUnoI ); + *ppException = 0; + break; + case 2: // release uno interface + (*pUnoI->release)( pUnoI ); + *ppException = 0; + break; + case 0: // queryInterface() opt + { + typelib_TypeDescription * pTD = 0; + TYPELIB_DANGER_GET( &pTD, reinterpret_cast< Type * >( pArgs[0] )->getTypeLibType() ); + if (pTD) + { + uno_Interface * pInterface = 0; + (*pThis->pBridge->getUnoEnv()->getRegisteredInterface)( + pThis->pBridge->getUnoEnv(), + (void **)&pInterface, pThis->oid.pData, (typelib_InterfaceTypeDescription *)pTD ); + + 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() + default: + // dependent dispatch + cpp_call( + pThis, aVtableSlot, + ((typelib_InterfaceMethodTypeDescription *)pMemberDescr)->pReturnTypeRef, + ((typelib_InterfaceMethodTypeDescription *)pMemberDescr)->nParams, + ((typelib_InterfaceMethodTypeDescription *)pMemberDescr)->pParams, + pReturn, pArgs, ppException ); + } + 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 >() ); + + Type const & rExcType = ::getCppuType( &aExc ); + // binary identical null reference + ::uno_type_any_construct( *ppException, &aExc, rExcType.getTypeLibType(), 0 ); + } + } +} + +} } } |