diff options
author | Vladimir Glazounov <vg@openoffice.org> | 2007-03-26 12:15:12 +0000 |
---|---|---|
committer | Vladimir Glazounov <vg@openoffice.org> | 2007-03-26 12:15:12 +0000 |
commit | 616b3164b7ac41ae68bef072ff2a7b09ad257c27 (patch) | |
tree | 94d0953192e7123cc62cbe967cbdca4653c483da | |
parent | 7dd6fa339c1daaae4471928ffc100937ec90bff8 (diff) |
INTEGRATION: CWS mingwport03 (1.1.6); FILE ADDED
2006/09/07 09:21:08 vg 1.1.6.1: #i53572# MinGW port
-rw-r--r-- | bridges/source/cpp_uno/mingw_intel/call.s | 267 | ||||
-rw-r--r-- | bridges/source/cpp_uno/mingw_intel/cpp2uno.cxx | 488 | ||||
-rw-r--r-- | bridges/source/cpp_uno/mingw_intel/except.cxx | 318 | ||||
-rw-r--r-- | bridges/source/cpp_uno/mingw_intel/share.hxx | 98 |
4 files changed, 1171 insertions, 0 deletions
diff --git a/bridges/source/cpp_uno/mingw_intel/call.s b/bridges/source/cpp_uno/mingw_intel/call.s new file mode 100644 index 000000000000..4aeedf70608b --- /dev/null +++ b/bridges/source/cpp_uno/mingw_intel/call.s @@ -0,0 +1,267 @@ + .text + +.globl _privateSnippetExecutorGeneral + .type _privateSnippetExecutorGeneral,@function +_privateSnippetExecutorGeneral: +.LFBg: + movl %esp,%ecx + pushl %ebp # proper stack frame needed for exception handling +.LCFIg0: + movl %esp,%ebp +.LCFIg1: + subl $0x4,%esp # 32bit returnValue + pushl %esp # 32bit &returnValue + pushl %ecx # 32bit pCallStack + pushl %edx # 32bit nVtableOffset + pushl %eax # 32bit nFunctionIndex + call _cpp_vtable_call + movl 16(%esp),%eax # 32bit returnValue + leave + ret +.LFEg: + .size _privateSnippetExecutorGeneral,.-_privateSnippetExecutorGeneral + +.globl _privateSnippetExecutorVoid + .type _privateSnippetExecutorVoid,@function +_privateSnippetExecutorVoid: +.LFBv: + movl %esp,%ecx + pushl %ebp # proper stack frame needed for exception handling +.LCFIv0: + movl %esp,%ebp +.LCFIv1: + pushl $0 # 32bit null pointer (returnValue not used) + pushl %ecx # 32bit pCallStack + pushl %edx # 32bit nVtableOffset + pushl %eax # 32bit nFunctionIndex + call _cpp_vtable_call + leave + ret +.LFEv: + .size _privateSnippetExecutorVoid,.-_privateSnippetExecutorVoid + +.globl _privateSnippetExecutorHyper + .type _privateSnippetExecutorHyper,@function +_privateSnippetExecutorHyper: +.LFBh: + movl %esp,%ecx + pushl %ebp # proper stack frame needed for exception handling +.LCFIh0: + movl %esp,%ebp +.LCFIh1: + subl $0x8,%esp # 64bit returnValue + pushl %esp # 32bit &returnValue + pushl %ecx # 32bit pCallStack + pushl %edx # 32bit nVtableOffset + pushl %eax # 32bit nFunctionIndex + call _cpp_vtable_call + movl 16(%esp),%eax # 64bit returnValue, lower half + movl 20(%esp),%edx # 64bit returnValue, upper half + leave + ret +.LFEh: + .size _privateSnippetExecutorHyper,.-_privateSnippetExecutorHyper + +.globl _privateSnippetExecutorFloat + .type _privateSnippetExecutorFloat,@function +_privateSnippetExecutorFloat: +.LFBf: + movl %esp,%ecx + pushl %ebp # proper stack frame needed for exception handling +.LCFIf0: + movl %esp,%ebp +.LCFIf1: + subl $0x4,%esp # 32bit returnValue + pushl %esp # 32bit &returnValue + pushl %ecx # 32bit pCallStack + pushl %edx # 32bit nVtableOffset + pushl %eax # 32bit nFunctionIndex + call _cpp_vtable_call + flds 16(%esp) # 32bit returnValue + leave + ret +.LFEf: + .size _privateSnippetExecutorFloat,.-_privateSnippetExecutorFloat + +.globl _privateSnippetExecutorDouble + .type _privateSnippetExecutorDouble,@function +_privateSnippetExecutorDouble: +.LFBd: + movl %esp,%ecx + pushl %ebp # proper stack frame needed for exception handling +.LCFId0: + movl %esp,%ebp +.LCFId1: + subl $0x8,%esp # 64bit returnValue + pushl %esp # 32bit &returnValue + pushl %ecx # 32bit pCallStack + pushl %edx # 32bit nVtableOffset + pushl %eax # 32bit nFunctionIndex + call _cpp_vtable_call + fldl 16(%esp) # 64bit returnValue + leave + ret +.LFEd: + .size _privateSnippetExecutorDouble,.-_privateSnippetExecutorDouble + +.globl _privateSnippetExecutorClass + .type _privateSnippetExecutorClass,@function +_privateSnippetExecutorClass: +.LFBc: + movl %esp,%ecx + pushl %ebp # proper stack frame needed for exception handling +.LCFIc0: + movl %esp,%ebp +.LCFIc1: + subl $0x4,%esp # 32bit returnValue + pushl %esp # 32bit &returnValue + pushl %ecx # 32bit pCallStack + pushl %edx # 32bit nVtableOffset + pushl %eax # 32bit nFunctionIndex + call _cpp_vtable_call + movl 16(%esp),%eax # 32bit returnValue + leave + ret $4 +.LFEc: + .size _privateSnippetExecutorClass,.-_privateSnippetExecutorClass + + .section .eh_frame,"a",@progbits +.Lframe1: + .long .LECIE1-.LSCIE1 # length +.LSCIE1: + .long 0 # CIE_ID + .byte 1 # version + .string "zR" # augmentation + .uleb128 1 # code_alignment_factor + .sleb128 -4 # data_alignment_factor + .byte 8 # return_address_register + .uleb128 1 # augmentation size 1: + .byte 0x1B # FDE Encoding (pcrel sdata4) + # initial_instructions: + .byte 0x0C # DW_CFA_def_cfa %esp, 4 + .uleb128 4 + .uleb128 4 + .byte 0x88 # DW_CFA_offset ret, 1 + .uleb128 1 + .align 4 +.LECIE1: +.LSFDEg: + .long .LEFDEg-.LASFDEg # length +.LASFDEg: + .long .LASFDEg-.Lframe1 # CIE_pointer + .long .LFBg-. # initial_location + .long .LFEg-.LFBg # address_range + .uleb128 0 # augmentation size 0 + # instructions: + .byte 0x04 # DW_CFA_advance_loc4 + .long .LCFIg0-.LFBg + .byte 0x0E # DW_CFA_def_cfa_offset 8 + .uleb128 8 + .byte 0x85 # DW_CFA_offset %ebp, 2 + .uleb128 2 + .byte 0x04 # DW_CFA_advance_loc4 + .long .LCFIg1-.LCFIg0 + .byte 0x0D # DW_CFA_def_cfa_register %ebp + .uleb128 5 + .align 4 +.LEFDEg: +.LSFDEv: + .long .LEFDEv-.LASFDEv # length +.LASFDEv: + .long .LASFDEv-.Lframe1 # CIE_pointer + .long .LFBv-. # initial_location + .long .LFEv-.LFBv # address_range + .uleb128 0 # augmentation size 0 + # instructions: + .byte 0x04 # DW_CFA_advance_loc4 + .long .LCFIv0-.LFBv + .byte 0x0E # DW_CFA_def_cfa_offset 8 + .uleb128 8 + .byte 0x85 # DW_CFA_offset %ebp, 2 + .uleb128 2 + .byte 0x04 # DW_CFA_advance_loc4 + .long .LCFIv1-.LCFIv0 + .byte 0x0D # DW_CFA_def_cfa_register %ebp + .uleb128 5 + .align 4 +.LEFDEv: +.LSFDEh: + .long .LEFDEh-.LASFDEh # length +.LASFDEh: + .long .LASFDEh-.Lframe1 # CIE_pointer + .long .LFBh-. # initial_location + .long .LFEh-.LFBh # address_range + .uleb128 0 # augmentation size 0 + # instructions: + .byte 0x04 # DW_CFA_advance_loc4 + .long .LCFIh0-.LFBh + .byte 0x0E # DW_CFA_def_cfa_offset 8 + .uleb128 8 + .byte 0x85 # DW_CFA_offset %ebp, 2 + .uleb128 2 + .byte 0x04 # DW_CFA_advance_loc4 + .long .LCFIh1-.LCFIh0 + .byte 0x0D # DW_CFA_def_cfa_register %ebp + .uleb128 5 + .align 4 +.LEFDEh: +.LSFDEf: + .long .LEFDEf-.LASFDEf # length +.LASFDEf: + .long .LASFDEf-.Lframe1 # CIE_pointer + .long .LFBf-. # initial_location + .long .LFEf-.LFBf # address_range + .uleb128 0 # augmentation size 0 + # instructions: + .byte 0x04 # DW_CFA_advance_loc4 + .long .LCFIf0-.LFBf + .byte 0x0E # DW_CFA_def_cfa_offset 8 + .uleb128 8 + .byte 0x85 # DW_CFA_offset %ebp, 2 + .uleb128 2 + .byte 0x04 # DW_CFA_advance_loc4 + .long .LCFIf1-.LCFIf0 + .byte 0x0D # DW_CFA_def_cfa_register %ebp + .uleb128 5 + .align 4 +.LEFDEf: +.LSFDEd: + .long .LEFDEd-.LASFDEd # length +.LASFDEd: + .long .LASFDEd-.Lframe1 # CIE_pointer + .long .LFBd-. # initial_location + .long .LFEd-.LFBd # address_range + .uleb128 0 # augmentation size 0 + # instructions: + .byte 0x04 # DW_CFA_advance_loc4 + .long .LCFId0-.LFBd + .byte 0x0E # DW_CFA_def_cfa_offset 8 + .uleb128 8 + .byte 0x85 # DW_CFA_offset %ebp, 2 + .uleb128 2 + .byte 0x04 # DW_CFA_advance_loc4 + .long .LCFId1-.LCFId0 + .byte 0x0D # DW_CFA_def_cfa_register %ebp + .uleb128 5 + .align 4 +.LEFDEd: +.LSFDEc: + .long .LEFDEc-.LASFDEc # length +.LASFDEc: + .long .LASFDEc-.Lframe1 # CIE_pointer + .long .LFBc-. # initial_location + .long .LFEc-.LFBc # address_range + .uleb128 0 # augmentation size 0 + # instructions: + .byte 0x04 # DW_CFA_advance_loc4 + .long .LCFIc0-.LFBc + .byte 0x0E # DW_CFA_def_cfa_offset 8 + .uleb128 8 + .byte 0x85 # DW_CFA_offset %ebp, 2 + .uleb128 2 + .byte 0x04 # DW_CFA_advance_loc4 + .long .LCFIc1-.LCFIc0 + .byte 0x0D # DW_CFA_def_cfa_register %ebp + .uleb128 5 + .align 4 +.LEFDEc: diff --git a/bridges/source/cpp_uno/mingw_intel/cpp2uno.cxx b/bridges/source/cpp_uno/mingw_intel/cpp2uno.cxx new file mode 100644 index 000000000000..7072db3b41b0 --- /dev/null +++ b/bridges/source/cpp_uno/mingw_intel/cpp2uno.cxx @@ -0,0 +1,488 @@ +/************************************************************************* + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: cpp2uno.cxx,v $ + * + * $Revision: 1.2 $ + * + * last change: $Author: vg $ $Date: 2007-03-26 13:14:31 $ + * + * The Contents of this file are made available subject to + * the terms of GNU Lesser General Public License Version 2.1. + * + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2005 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library 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 for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + ************************************************************************/ + +#include <com/sun/star/uno/genfunc.hxx> +#include "com/sun/star/uno/RuntimeException.hpp" +#include <uno/data.h> +#include <typelib/typedescription.hxx> +#include <sal/alloca.h> + +#include "bridges/cpp_uno/shared/bridge.hxx" +#include "bridges/cpp_uno/shared/cppinterfaceproxy.hxx" +#include "bridges/cpp_uno/shared/types.hxx" +#include "bridges/cpp_uno/shared/vtablefactory.hxx" + +#include "share.hxx" + +using namespace ::com::sun::star::uno; + +namespace +{ + +//================================================================================================== +void 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, + void * pReturnValue ) +{ + // pCallStack: ret, [return ptr], this, params + char * pCppStack = (char *)(pCallStack +1); + + // 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 = pReturnValue; // direct way for simple types + } + else // complex return via ptr (pCppReturn) + { + pCppReturn = *(void **)pCppStack; + 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] = pCppStack; + pUnoArgs[nPos] = pCppStack; + switch (pParamTypeDescr->eTypeClass) + { + case typelib_TypeClass_HYPER: + case typelib_TypeClass_UNSIGNED_HYPER: + case typelib_TypeClass_DOUBLE: + pCppStack += sizeof(sal_Int32); // extra long + break; + default: + break; + } + // 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 an 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::raiseException( + &aUnoExc, pThis->getBridge()->getUno2Cpp() ); + // has to destruct the any + } + 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, 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 + *static_cast< void ** >(pReturnValue) = pCppReturn; + } + if (pReturnTypeDescr) + { + TYPELIB_DANGER_RELEASE( pReturnTypeDescr ); + } + } +} + + +//================================================================================================== +extern "C" void cpp_vtable_call( + int nFunctionIndex, int nVtableOffset, void** pCallStack, + void * pReturnValue ) +{ + OSL_ENSURE( sizeof(sal_Int32)==sizeof(void *), "### unexpected!" ); + + // pCallStack: ret adr, [ret *], this, params + void * pThis; + if( nFunctionIndex & 0x80000000 ) + { + nFunctionIndex &= 0x7fffffff; + pThis = pCallStack[2]; + } + else + { + pThis = pCallStack[1]; + } + pThis = static_cast< char * >(pThis) - nVtableOffset; + bridges::cpp_uno::shared::CppInterfaceProxy * pCppI + = bridges::cpp_uno::shared::CppInterfaceProxy::castInterfaceToProxy( + pThis); + + typelib_InterfaceTypeDescription * pTypeDescr = pCppI->getTypeDescr(); + + OSL_ENSURE( nFunctionIndex < pTypeDescr->nMapFunctionIndexToMemberIndex, "### illegal vtable index!" ); + if (nFunctionIndex >= pTypeDescr->nMapFunctionIndexToMemberIndex) + { + throw RuntimeException( + rtl::OUString::createFromAscii("illegal vtable index!"), + (XInterface *)pThis ); + } + + // determine called method + sal_Int32 nMemberPos = pTypeDescr->pMapFunctionIndexToMemberIndex[nFunctionIndex]; + OSL_ENSURE( nMemberPos < pTypeDescr->nAllMembers, "### illegal member index!" ); + + TypeDescription aMemberDescr( pTypeDescr->ppAllMembers[nMemberPos] ); + + switch (aMemberDescr.get()->eTypeClass) + { + case typelib_TypeClass_INTERFACE_ATTRIBUTE: + { + if (pTypeDescr->pMapMemberIndexToFunctionIndex[nMemberPos] == nFunctionIndex) + { + // is GET method + cpp2uno_call( + pCppI, aMemberDescr.get(), + ((typelib_InterfaceAttributeTypeDescription *)aMemberDescr.get())->pAttributeTypeRef, + 0, 0, // no params + pCallStack, pReturnValue ); + } + else + { + // is SET method + typelib_MethodParameter aParam; + aParam.pTypeRef = + ((typelib_InterfaceAttributeTypeDescription *)aMemberDescr.get())->pAttributeTypeRef; + aParam.bIn = sal_True; + aParam.bOut = sal_False; + + cpp2uno_call( + pCppI, aMemberDescr.get(), + 0, // indicates void return + 1, &aParam, + pCallStack, pReturnValue ); + } + break; + } + case typelib_TypeClass_INTERFACE_METHOD: + { + // is METHOD + switch (nFunctionIndex) + { + case 1: // acquire() + pCppI->acquireProxy(); // non virtual call! + break; + case 2: // release() + pCppI->releaseProxy(); // non virtual call! + break; + case 0: // queryInterface() opt + { + typelib_TypeDescription * pTD = 0; + TYPELIB_DANGER_GET( &pTD, reinterpret_cast< Type * >( pCallStack[3] )->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[1] ), + &pInterface, pTD, cpp_acquire ); + pInterface->release(); + TYPELIB_DANGER_RELEASE( pTD ); + *static_cast< void ** >(pReturnValue) = pCallStack[1]; + break; + } + TYPELIB_DANGER_RELEASE( pTD ); + } + } // else perform queryInterface() + default: + cpp2uno_call( + pCppI, aMemberDescr.get(), + ((typelib_InterfaceMethodTypeDescription *)aMemberDescr.get())->pReturnTypeRef, + ((typelib_InterfaceMethodTypeDescription *)aMemberDescr.get())->nParams, + ((typelib_InterfaceMethodTypeDescription *)aMemberDescr.get())->pParams, + pCallStack, pReturnValue ); + } + break; + } + default: + { + throw RuntimeException( + rtl::OUString::createFromAscii("no member description found!"), + (XInterface *)pThis ); + } + } +} + +//================================================================================================== +extern "C" void privateSnippetExecutorGeneral(); +extern "C" void privateSnippetExecutorVoid(); +extern "C" void privateSnippetExecutorHyper(); +extern "C" void privateSnippetExecutorFloat(); +extern "C" void privateSnippetExecutorDouble(); +extern "C" void privateSnippetExecutorClass(); +extern "C" typedef void (*PrivateSnippetExecutor)(); + +int const codeSnippetSize = 16; + +unsigned char * codeSnippet( + unsigned char * code, sal_Int32 functionIndex, sal_Int32 vtableOffset, + typelib_TypeClass returnTypeClass) +{ + if (!bridges::cpp_uno::shared::isSimpleType(returnTypeClass)) { + functionIndex |= 0x80000000; + } + PrivateSnippetExecutor exec; + switch (returnTypeClass) { + case typelib_TypeClass_VOID: + exec = privateSnippetExecutorVoid; + break; + case typelib_TypeClass_HYPER: + case typelib_TypeClass_UNSIGNED_HYPER: + exec = privateSnippetExecutorHyper; + break; + case typelib_TypeClass_FLOAT: + exec = privateSnippetExecutorFloat; + break; + case typelib_TypeClass_DOUBLE: + exec = privateSnippetExecutorDouble; + break; + case typelib_TypeClass_STRING: + case typelib_TypeClass_TYPE: + case typelib_TypeClass_ANY: + case typelib_TypeClass_SEQUENCE: + case typelib_TypeClass_STRUCT: + case typelib_TypeClass_INTERFACE: + exec = privateSnippetExecutorClass; + break; + default: + exec = privateSnippetExecutorGeneral; + break; + } + unsigned char * p = code; + OSL_ASSERT(sizeof (sal_Int32) == 4); + // mov function_index, %eax: + *p++ = 0xB8; + *reinterpret_cast< sal_Int32 * >(p) = functionIndex; + p += sizeof (sal_Int32); + // mov vtable_offset, %edx: + *p++ = 0xBA; + *reinterpret_cast< sal_Int32 * >(p) = vtableOffset; + p += sizeof (sal_Int32); + // jmp privateSnippetExecutor: + *p++ = 0xE9; + *reinterpret_cast< sal_Int32 * >(p) + = ((unsigned char *) exec) - p - sizeof (sal_Int32); + p += sizeof (sal_Int32); + OSL_ASSERT(p - code <= codeSnippetSize); + return code + codeSnippetSize; +} + +} + +void ** bridges::cpp_uno::shared::VtableFactory::mapBlockToVtable(void * block) +{ + return static_cast< void ** >(block) + 2; +} + +sal_Size bridges::cpp_uno::shared::VtableFactory::getBlockSize( + sal_Int32 slotCount) +{ + return (slotCount + 2) * sizeof (void *) + slotCount * codeSnippetSize; +} + +void ** bridges::cpp_uno::shared::VtableFactory::initializeBlock(void * block) { + void ** slots = mapBlockToVtable(block); + slots[-2] = 0; + slots[-1] = 0; + return slots; +} + +unsigned char * bridges::cpp_uno::shared::VtableFactory::addLocalFunctions( + void ** slots, unsigned char * code, + typelib_InterfaceTypeDescription const * type, sal_Int32 functionOffset, + sal_Int32 /*functionCount*/, sal_Int32 vtableOffset) +{ + for (sal_Int32 i = 0; i < type->nMembers; ++i) { + typelib_TypeDescription * member = 0; + TYPELIB_DANGER_GET(&member, type->ppMembers[i]); + OSL_ASSERT(member != 0); + switch (member->eTypeClass) { + case typelib_TypeClass_INTERFACE_ATTRIBUTE: + // Getter: + *slots++ = code; + code = codeSnippet( + code, functionOffset++, vtableOffset, + reinterpret_cast< typelib_InterfaceAttributeTypeDescription * >( + member)->pAttributeTypeRef->eTypeClass); + // Setter: + if (!reinterpret_cast< + typelib_InterfaceAttributeTypeDescription * >( + member)->bReadOnly) + { + *slots++ = code; + code = codeSnippet( + code, functionOffset++, vtableOffset, + typelib_TypeClass_VOID); + } + break; + + case typelib_TypeClass_INTERFACE_METHOD: + *slots++ = code; + code = codeSnippet( + code, functionOffset++, vtableOffset, + reinterpret_cast< typelib_InterfaceMethodTypeDescription * >( + member)->pReturnTypeRef->eTypeClass); + break; + + default: + OSL_ASSERT(false); + break; + } + TYPELIB_DANGER_RELEASE(member); + } + return code; +} + +void bridges::cpp_uno::shared::VtableFactory::flushCode( + unsigned char const *, unsigned char const *) +{} diff --git a/bridges/source/cpp_uno/mingw_intel/except.cxx b/bridges/source/cpp_uno/mingw_intel/except.cxx new file mode 100644 index 000000000000..52faf5bd7563 --- /dev/null +++ b/bridges/source/cpp_uno/mingw_intel/except.cxx @@ -0,0 +1,318 @@ +/************************************************************************* + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: except.cxx,v $ + * + * $Revision: 1.2 $ + * + * last change: $Author: vg $ $Date: 2007-03-26 13:14:54 $ + * + * The Contents of this file are made available subject to + * the terms of GNU Lesser General Public License Version 2.1. + * + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2005 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library 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 for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + ************************************************************************/ + +#include <stdio.h> +#include <cxxabi.h> +#include <hash_map> + +#include <rtl/strbuf.hxx> +#include <rtl/ustrbuf.hxx> +#include <osl/diagnose.h> +#include <osl/mutex.hxx> + +#include <com/sun/star/uno/genfunc.hxx> +#include "com/sun/star/uno/RuntimeException.hpp" +#include <typelib/typedescription.hxx> +#include <uno/any2.h> + +#include "share.hxx" + + +using namespace ::std; +using namespace ::osl; +using namespace ::rtl; +using namespace ::com::sun::star::uno; +using namespace ::__cxxabiv1; + + +namespace CPPU_CURRENT_NAMESPACE +{ + +void dummy_can_throw_anything( char const * ) +{ +} + +//================================================================================================== +static OUString toUNOname( char const * p ) SAL_THROW( () ) +{ +#if OSL_DEBUG_LEVEL > 1 + char const * start = p; +#endif + + // example: N3com3sun4star4lang24IllegalArgumentExceptionE + + OUStringBuffer buf( 64 ); + OSL_ASSERT( 'N' == *p ); + ++p; // skip N + + while ('E' != *p) + { + // read chars count + long n = (*p++ - '0'); + while ('0' <= *p && '9' >= *p) + { + n *= 10; + n += (*p++ - '0'); + } + buf.appendAscii( p, n ); + p += n; + if ('E' != *p) + buf.append( (sal_Unicode)'.' ); + } + +#if OSL_DEBUG_LEVEL > 1 + OUString ret( buf.makeStringAndClear() ); + OString c_ret( OUStringToOString( ret, RTL_TEXTENCODING_ASCII_US ) ); + fprintf( stderr, "> toUNOname(): %s => %s\n", start, c_ret.getStr() ); + return ret; +#else + return buf.makeStringAndClear(); +#endif +} + +//================================================================================================== +class RTTI +{ + typedef hash_map< OUString, type_info *, OUStringHash > t_rtti_map; + + Mutex m_mutex; + t_rtti_map m_rttis; + t_rtti_map m_generatedRttis; + +public: + RTTI() SAL_THROW( () ); + ~RTTI() SAL_THROW( () ); + + type_info * getRTTI( typelib_CompoundTypeDescription * ) SAL_THROW( () ); +}; +//__________________________________________________________________________________________________ +RTTI::RTTI() SAL_THROW( () ) +{ +} +//__________________________________________________________________________________________________ +RTTI::~RTTI() SAL_THROW( () ) +{ +} + +//__________________________________________________________________________________________________ +type_info * RTTI::getRTTI( typelib_CompoundTypeDescription *pTypeDescr ) SAL_THROW( () ) +{ + type_info * rtti; + + OUString const & unoName = *(OUString const *)&pTypeDescr->aBase.pTypeName; + + MutexGuard guard( m_mutex ); + t_rtti_map::const_iterator iRttiFind( m_rttis.find( unoName ) ); + if (iRttiFind == m_rttis.end()) + { + // RTTI symbol + OStringBuffer buf( 64 ); + buf.append( RTL_CONSTASCII_STRINGPARAM("__ZTIN") ); + sal_Int32 index = 0; + do + { + OUString token( unoName.getToken( 0, '.', index ) ); + buf.append( token.getLength() ); + OString c_token( OUStringToOString( token, RTL_TEXTENCODING_ASCII_US ) ); + buf.append( c_token ); + } + while (index >= 0); + buf.append( 'E' ); + + OString symName( buf.makeStringAndClear() ); + // try to lookup the symbol in the generated rtti map + t_rtti_map::const_iterator iFind( m_generatedRttis.find( unoName ) ); + if (iFind == m_generatedRttis.end()) + { + // we must generate it ! + // symbol and rtti-name is nearly identical, + // the symbol is prefixed with __ZTI + char const * rttiName = symName.getStr() +5; +#if OSL_DEBUG_LEVEL > 1 + fprintf( stderr,"generated rtti for %s\n", rttiName ); +#endif + if (pTypeDescr->pBaseTypeDescription) + { + // ensure availability of base + type_info * base_rtti = getRTTI( + (typelib_CompoundTypeDescription *)pTypeDescr->pBaseTypeDescription ); + rtti = new __si_class_type_info( + strdup( rttiName ), (__class_type_info *)base_rtti ); + } + else + { + // this class has no base class + rtti = new __class_type_info( strdup( rttiName ) ); + } + + pair< t_rtti_map::iterator, bool > insertion( + m_generatedRttis.insert( t_rtti_map::value_type( unoName, rtti ) ) ); + OSL_ENSURE( insertion.second, "### inserting new generated rtti failed?!" ); + } + else // taking already generated rtti + { + rtti = iFind->second; + } + } + else + { + rtti = iRttiFind->second; + } + + return rtti; +} + +//-------------------------------------------------------------------------------------------------- +static void deleteException( void * pExc ) +{ + __cxa_exception const * header = ((__cxa_exception const *)pExc - 1); + typelib_TypeDescription * pTD = 0; + OUString unoName( toUNOname( header->exceptionType->name() ) ); + ::typelib_typedescription_getByName( &pTD, unoName.pData ); + OSL_ENSURE( pTD, "### unknown exception type! leaving out destruction => leaking!!!" ); + if (pTD) + { + ::uno_destructData( pExc, pTD, cpp_release ); + ::typelib_typedescription_release( pTD ); + } +} + +//================================================================================================== +void 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 + void * pCppExc; + type_info * rtti; + + { + // construct cpp exception object + typelib_TypeDescription * pTypeDescr = 0; + TYPELIB_DANGER_GET( &pTypeDescr, pUnoExc->pType ); + OSL_ASSERT( pTypeDescr ); + if (! pTypeDescr) + { + throw RuntimeException( + OUString( RTL_CONSTASCII_USTRINGPARAM("cannot get typedescription for type ") ) + + *reinterpret_cast< OUString const * >( &pUnoExc->pType->pTypeName ), + Reference< XInterface >() ); + } + + pCppExc = __cxa_allocate_exception( pTypeDescr->nSize ); + ::uno_copyAndConvertData( pCppExc, pUnoExc->pData, pTypeDescr, pUno2Cpp ); + + // destruct uno exception + ::uno_any_destruct( pUnoExc, 0 ); + // avoiding locked counts + static RTTI * s_rtti = 0; + if (! s_rtti) + { + MutexGuard guard( Mutex::getGlobalMutex() ); + if (! s_rtti) + { +#ifdef LEAK_STATIC_DATA + s_rtti = new RTTI(); +#else + static RTTI rtti_data; + s_rtti = &rtti_data; +#endif + } + } + rtti = (type_info *)s_rtti->getRTTI( (typelib_CompoundTypeDescription *) pTypeDescr ); + TYPELIB_DANGER_RELEASE( pTypeDescr ); + OSL_ENSURE( rtti, "### no rtti for throwing exception!" ); + if (! rtti) + { + throw RuntimeException( + OUString( RTL_CONSTASCII_USTRINGPARAM("no rtti for type ") ) + + *reinterpret_cast< OUString const * >( &pUnoExc->pType->pTypeName ), + Reference< XInterface >() ); + } + } + + __cxa_throw( pCppExc, rtti, deleteException ); +} + +//================================================================================================== +void fillUnoException( __cxa_exception * header, uno_Any * pUnoExc, uno_Mapping * pCpp2Uno ) +{ + if (! header) + { + RuntimeException aRE( + OUString( RTL_CONSTASCII_USTRINGPARAM("no exception header!") ), + 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; + } + + typelib_TypeDescription * pExcTypeDescr = 0; + OUString unoName( toUNOname( header->exceptionType->name() ) ); +#if OSL_DEBUG_LEVEL > 1 + OString cstr_unoName( OUStringToOString( unoName, RTL_TEXTENCODING_ASCII_US ) ); + fprintf( stderr, "> c++ exception occured: %s\n", cstr_unoName.getStr() ); +#endif + typelib_typedescription_getByName( &pExcTypeDescr, unoName.pData ); + if (0 == pExcTypeDescr) + { + RuntimeException aRE( + OUString( RTL_CONSTASCII_USTRINGPARAM("exception type not found: ") ) + unoName, + 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 + } + else + { + // construct uno exception any + uno_any_constructAndConvert( pUnoExc, header->adjustedPtr, pExcTypeDescr, pCpp2Uno ); + typelib_typedescription_release( pExcTypeDescr ); + } +} + +} + diff --git a/bridges/source/cpp_uno/mingw_intel/share.hxx b/bridges/source/cpp_uno/mingw_intel/share.hxx new file mode 100644 index 000000000000..92f757795088 --- /dev/null +++ b/bridges/source/cpp_uno/mingw_intel/share.hxx @@ -0,0 +1,98 @@ +/************************************************************************* + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: share.hxx,v $ + * + * $Revision: 1.2 $ + * + * last change: $Author: vg $ $Date: 2007-03-26 13:15:12 $ + * + * The Contents of this file are made available subject to + * the terms of GNU Lesser General Public License Version 2.1. + * + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2005 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library 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 for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + ************************************************************************/ + +#include "uno/mapping.h" + +#include <typeinfo> +#include <exception> +#include <cstddef> + +namespace CPPU_CURRENT_NAMESPACE +{ + +void dummy_can_throw_anything( char const * ); + +// ----- following decl from libstdc++-v3/libsupc++/unwind-cxx.h and unwind.h + +struct _Unwind_Exception +{ + unsigned exception_class __attribute__((__mode__(__DI__))); + void * exception_cleanup; + unsigned private_1 __attribute__((__mode__(__word__))); + unsigned private_2 __attribute__((__mode__(__word__))); +} __attribute__((__aligned__)); + +struct __cxa_exception +{ + ::std::type_info *exceptionType; + void (*exceptionDestructor)(void *); + + ::std::unexpected_handler unexpectedHandler; + ::std::terminate_handler terminateHandler; + + __cxa_exception *nextException; + + int handlerCount; + + int handlerSwitchValue; + const unsigned char *actionRecord; + const unsigned char *languageSpecificData; + void *catchTemp; + void *adjustedPtr; + + _Unwind_Exception unwindHeader; +}; + +extern "C" void *__cxa_allocate_exception( + std::size_t thrown_size ) throw(); +extern "C" void __cxa_throw ( + void *thrown_exception, std::type_info *tinfo, void (*dest) (void *) ) __attribute__((noreturn)); + +struct __cxa_eh_globals +{ + __cxa_exception *caughtExceptions; + unsigned int uncaughtExceptions; +}; +extern "C" __cxa_eh_globals *__cxa_get_globals () throw(); + +// ----- + +//================================================================================================== +void raiseException( + uno_Any * pUnoExc, uno_Mapping * pUno2Cpp ); +//================================================================================================== +void fillUnoException( + __cxa_exception * header, uno_Any *, uno_Mapping * pCpp2Uno ); +} |