summaryrefslogtreecommitdiff
path: root/bridges/source/cpp_uno/msvc_win32_intel
diff options
context:
space:
mode:
authorJens-Heiner Rechtien <hr@openoffice.org>2000-09-18 14:29:57 +0000
committerJens-Heiner Rechtien <hr@openoffice.org>2000-09-18 14:29:57 +0000
commitb525a3115f54576017a576ff842dede5e2e3545d (patch)
treec534b95a9e572b63896467624293a5ca1887d3a3 /bridges/source/cpp_uno/msvc_win32_intel
parent9399c662f36c385b0c705eb34e636a9aec450282 (diff)
initial import
Diffstat (limited to 'bridges/source/cpp_uno/msvc_win32_intel')
-rw-r--r--bridges/source/cpp_uno/msvc_win32_intel/cpp2uno.cxx563
-rw-r--r--bridges/source/cpp_uno/msvc_win32_intel/except.cxx538
-rw-r--r--bridges/source/cpp_uno/msvc_win32_intel/makefile.mk119
-rw-r--r--bridges/source/cpp_uno/msvc_win32_intel/msci.hxx90
-rw-r--r--bridges/source/cpp_uno/msvc_win32_intel/uno2cpp.cxx494
5 files changed, 1804 insertions, 0 deletions
diff --git a/bridges/source/cpp_uno/msvc_win32_intel/cpp2uno.cxx b/bridges/source/cpp_uno/msvc_win32_intel/cpp2uno.cxx
new file mode 100644
index 000000000000..8b7ddf39098b
--- /dev/null
+++ b/bridges/source/cpp_uno/msvc_win32_intel/cpp2uno.cxx
@@ -0,0 +1,563 @@
+/*************************************************************************
+ *
+ * $RCSfile: cpp2uno.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 15:28:49 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 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
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#define LEAK_STATIC_DATA
+// #define TRACE(x) OSL_TRACE(x)
+#define TRACE(x)
+
+#pragma warning( disable : 4237 )
+#include <stl/list>
+#include <malloc.h>
+#ifndef _RTL_ALLOC_H_
+#include <rtl/alloc.h>
+#endif
+#ifndef _RTL_STRING_HXX_
+#include <rtl/string.hxx>
+#endif
+
+#ifndef _TYPELIB_TYPEDESCRIPTION_HXX_
+#include <typelib/typedescription.hxx>
+#endif
+#ifndef _UNO_DATA_H_
+#include <uno/data.h>
+#endif
+#ifndef _BRIDGES_CPP_UNO_BRIDGE_HXX_
+#include <bridges/cpp_uno/bridge.hxx>
+#endif
+#ifndef _BRIDGES_CPP_UNO_TYPE_MISC_HXX_
+#include <bridges/cpp_uno/type_misc.hxx>
+#endif
+
+#include "msci.hxx"
+
+using namespace std;
+using namespace rtl;
+using namespace osl;
+using namespace com::sun::star::uno;
+
+
+namespace CPPU_CURRENT_NAMESPACE
+{
+
+//==================================================================================================
+static inline typelib_TypeClass cpp2uno_call(
+ cppu_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: ret, this, [complex return ptr], params
+ char * pCppStack = (char *)(pCallStack +2);
+
+ // 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 (cppu_isSimpleType( pReturnTypeDescr ))
+ {
+ pUnoReturn = pRegisterReturn; // direct way for simple types
+ }
+ else // complex return via ptr (pCppReturn)
+ {
+ pCppReturn = *(void **)pCppStack;
+ pCppStack += sizeof(void *);
+
+ pUnoReturn = (cppu_relatesToInterface( pReturnTypeDescr )
+ ? alloca( pReturnTypeDescr->nSize )
+ : pCppReturn); // direct way
+ }
+ }
+
+ // stack space
+ OSL_ENSHURE( 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 && cppu_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
+ }
+ // 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 (cppu_relatesToInterface( pParamTypeDescr ))
+ {
+ uno_copyAndConvertData( pUnoArgs[nPos] = alloca( pParamTypeDescr->nSize ),
+ *(void **)pCppStack, pParamTypeDescr,
+ &pThis->pBridge->aCpp2Uno );
+ 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->pUnoI->pDispatcher)( pThis->pUnoI, pMemberTypeDescr, pUnoReturn, pUnoArgs, &pUnoExc );
+
+ // in case an exception occured...
+ if (pUnoExc)
+ {
+ // destruct temporary in/inout params
+ while (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 );
+
+ msci_raiseException( &aUnoExc, &pThis->pBridge->aUno2Cpp ); // has to destruct the any
+ // is here for dummy
+ return typelib_TypeClass_VOID;
+ }
+ else // else no exception occured...
+ {
+ // temporary params
+ while (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->pBridge->aUno2Cpp );
+ }
+ // 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->pBridge->aUno2Cpp );
+ // 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 __cdecl cpp_mediate(
+ void ** pCallStack, sal_Int32 nVtableCall,
+ sal_Int64 * pRegisterReturn /* space for register return */ )
+{
+ OSL_ENSHURE( sizeof(sal_Int32)==sizeof(void *), "### unexpected!" );
+
+ // pCallStack: ret adr, this, [ret *], params
+ // _this_ ptr is patched cppu_XInterfaceProxy object
+ cppu_cppInterfaceProxy * pThis = static_cast< cppu_cppInterfaceProxy * >(
+ reinterpret_cast< XInterface * >( pCallStack[1] ) );
+
+ typelib_InterfaceTypeDescription * pTypeDescr = pThis->pTypeDescr;
+ OSL_ENSHURE( nVtableCall < pTypeDescr->nMapFunctionIndexToMemberIndex,
+ "### illegal vtable index!" );
+ if (nVtableCall >= pTypeDescr->nMapFunctionIndexToMemberIndex)
+ {
+ throw RuntimeException( OUString( RTL_CONSTASCII_USTRINGPARAM("illegal vtable index!") ),
+ (XInterface *)pThis );
+ }
+
+ // determine called method
+ sal_Int32 nMemberPos = pTypeDescr->pMapFunctionIndexToMemberIndex[nVtableCall];
+ OSL_ENSHURE( 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] == nVtableCall)
+ {
+ // is GET method
+ eRet = cpp2uno_call(
+ pThis, 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(
+ pThis, aMemberDescr.get(),
+ 0, // indicates void return
+ 1, &aParam,
+ pCallStack, pRegisterReturn );
+ }
+ break;
+ }
+ case typelib_TypeClass_INTERFACE_METHOD:
+ {
+ // is METHOD
+ switch (nVtableCall)
+ {
+ // standard XInterface vtable calls
+ case 1: // acquire()
+ pThis->acquireProxy(); // non virtual call!
+ eRet = typelib_TypeClass_VOID;
+ break;
+ case 2: // release()
+ pThis->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[3] )->getTypeLibType() );
+ OSL_ASSERT( pTD );
+
+ XInterface * pInterface = 0;
+ (*pThis->pBridge->pCppEnv->getRegisteredInterface)(
+ pThis->pBridge->pCppEnv,
+ (void **)&pInterface, pThis->oid.pData, (typelib_InterfaceTypeDescription *)pTD );
+
+ if (pInterface)
+ {
+ uno_any_construct( reinterpret_cast< uno_Any * >( pCallStack[2] ),
+ &pInterface, pTD, cpp_acquire );
+ pInterface->release();
+ TYPELIB_DANGER_RELEASE( pTD );
+ *(void **)pRegisterReturn = pCallStack[2];
+ eRet = typelib_TypeClass_ANY;
+ break;
+ }
+ TYPELIB_DANGER_RELEASE( pTD );
+ } // else perform queryInterface()
+ default:
+ eRet = cpp2uno_call(
+ pThis, aMemberDescr.get(),
+ ((typelib_InterfaceMethodTypeDescription *)aMemberDescr.get())->pReturnTypeRef,
+ ((typelib_InterfaceMethodTypeDescription *)aMemberDescr.get())->nParams,
+ ((typelib_InterfaceMethodTypeDescription *)aMemberDescr.get())->pParams,
+ pCallStack, pRegisterReturn );
+ }
+ break;
+ }
+ default:
+ {
+ throw RuntimeException(
+ OUString( RTL_CONSTASCII_USTRINGPARAM("no member description found!") ),
+ (XInterface *)pThis );
+ // is here for dummy
+ eRet = typelib_TypeClass_VOID;
+ }
+ }
+
+ return eRet;
+}
+
+//==================================================================================================
+class MediateVtables
+{
+ //----------------------------------------------------------------------------------------------
+ struct DefaultRTTIEntry
+ {
+ sal_Int32 _n0, _n1, _n2;
+ type_info * _pRTTI;
+
+ DefaultRTTIEntry()
+ : _n0( 0 )
+ , _n1( 0 )
+ , _n2( 0 )
+ { _pRTTI = msci_getRTTI( "com.sun.star.uno.XInterface" ); }
+ };
+
+ typedef list<void * > t_pSpacesList;
+
+ Mutex _aMutex;
+ t_pSpacesList _aSpaces;
+
+ sal_Int32 _nCurrent;
+ const void * _pCurrent;
+
+public:
+ const void * getMediateVtable( sal_Int32 nSize );
+
+ MediateVtables( sal_Int32 nSize = 256 )
+ : _nCurrent( 0 )
+ , _pCurrent( 0 )
+ { getMediateVtable( nSize ); }
+ ~MediateVtables();
+};
+//__________________________________________________________________________________________________
+MediateVtables::~MediateVtables()
+{
+ TRACE( "> calling ~MediateVtables(): freeing mediate vtables... <\n" );
+
+ MutexGuard aGuard( _aMutex );
+
+ // this MUST be the absolute last one which is called!
+ for ( t_pSpacesList::iterator iPos( _aSpaces.begin() ); iPos != _aSpaces.end(); ++iPos )
+ {
+ rtl_freeMemory( *iPos );
+ }
+}
+
+//==================================================================================================
+/**
+ * is called on incoming vtable calls
+ * (called by asm snippets)
+ */
+static __declspec(naked) void __cdecl cpp_vtable_call(void)
+{
+__asm
+ {
+ sub esp, 8 // space for immediate return type
+ push esp
+ push eax // vtable index
+ mov eax, esp
+ add eax, 16
+ push eax // original stack ptr
+
+ call cpp_mediate
+ add esp, 12
+
+ cmp eax, typelib_TypeClass_FLOAT
+ je Lfloat
+ cmp eax, typelib_TypeClass_DOUBLE
+ je Ldouble
+ cmp eax, typelib_TypeClass_HYPER
+ je Lhyper
+ cmp eax, typelib_TypeClass_UNSIGNED_HYPER
+ je Lhyper
+ // rest is eax
+ pop eax
+ add esp, 4
+ ret
+Lhyper:
+ pop eax
+ pop edx
+ ret
+Lfloat:
+ fld dword ptr [esp]
+ add esp, 8
+ ret
+Ldouble:
+ fld qword ptr [esp]
+ add esp, 8
+ ret
+ }
+}
+
+//__________________________________________________________________________________________________
+const void * MediateVtables::getMediateVtable( sal_Int32 nSize )
+{
+ if (_nCurrent < nSize)
+ {
+ TRACE( "> need larger vtable! <\n" );
+
+ // dont ever guard each time, so ask twice when guarded
+ MutexGuard aGuard( _aMutex );
+ if (_nCurrent < nSize)
+ {
+ nSize = (nSize +1) & 0xfffffffe;
+ char * pSpace = (char *)rtl_allocateMemory( ((1+nSize)*sizeof(void *)) + (nSize*12) );
+ _aSpaces.push_back( pSpace );
+
+ // on index -1 write default rtti entry
+ static DefaultRTTIEntry s_defaultInterfaceRTTI;
+ *(void **)pSpace = &s_defaultInterfaceRTTI;
+
+ void ** pvft = (void **)(pSpace + sizeof(void *));
+ char * pCode = pSpace + ((1+nSize)*sizeof(void *));
+
+ // setup vft and code
+ for ( sal_Int32 nPos = 0; nPos < nSize; ++nPos )
+ {
+ unsigned char * codeSnip = (unsigned char *)pCode + (nPos *12);
+ pvft[nPos] = codeSnip;
+
+ /**
+ * vtable calls detonate on these code snippets
+ */
+ // mov eax, nPos
+ *codeSnip++ = 0xb8;
+ *(sal_Int32 *)codeSnip = nPos;
+ codeSnip += sizeof(sal_Int32);
+ // jmp rel32 cpp_vtable_call
+ *codeSnip++ = 0xe9;
+ *(sal_Int32 *)codeSnip = ((unsigned char *)cpp_vtable_call) - codeSnip - sizeof(sal_Int32);
+ }
+ _pCurrent = pSpace + sizeof(void *);
+ _nCurrent = nSize;
+ }
+ }
+ return _pCurrent;
+}
+
+//==================================================================================================
+void SAL_CALL cppu_cppInterfaceProxy_patchVtable(
+ XInterface * pCppI, typelib_InterfaceTypeDescription * pTypeDescr )
+{
+ static MediateVtables * s_pMediateVtables = 0;
+ if (! s_pMediateVtables)
+ {
+ MutexGuard aGuard( Mutex::getGlobalMutex() );
+ if (! s_pMediateVtables)
+ {
+#ifdef LEAK_STATIC_DATA
+ s_pMediateVtables = new MediateVtables();
+#else
+ static MediateVtables s_aMediateVtables;
+ s_pMediateVtables = &s_aMediateVtables;
+#endif
+ }
+ }
+ *(const void **)pCppI = s_pMediateVtables->getMediateVtable(
+ pTypeDescr->nMapFunctionIndexToMemberIndex );
+}
+
+}
+
+//##################################################################################################
+extern "C" SAL_DLLEXPORT void SAL_CALL uno_initEnvironment( uno_Environment * pCppEnv )
+{
+ CPPU_CURRENT_NAMESPACE::cppu_cppenv_initEnvironment( pCppEnv );
+}
+//##################################################################################################
+extern "C" SAL_DLLEXPORT void SAL_CALL uno_ext_getMapping(
+ uno_Mapping ** ppMapping, uno_Environment * pFrom, uno_Environment * pTo )
+{
+ CPPU_CURRENT_NAMESPACE::cppu_ext_getMapping( ppMapping, pFrom, pTo );
+}
+
diff --git a/bridges/source/cpp_uno/msvc_win32_intel/except.cxx b/bridges/source/cpp_uno/msvc_win32_intel/except.cxx
new file mode 100644
index 000000000000..9bab2d6bd5d5
--- /dev/null
+++ b/bridges/source/cpp_uno/msvc_win32_intel/except.cxx
@@ -0,0 +1,538 @@
+/*************************************************************************
+ *
+ * $RCSfile: except.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 15:28:49 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 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
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#define LEAK_STATIC_DATA
+#define TRACE(x) OSL_TRACE(x)
+// #define TRACE(x)
+
+#pragma warning( disable : 4237 )
+#include <stl/hash_map>
+#include <sal/config.h>
+#include <malloc.h>
+#include <new.h>
+#include <typeinfo.h>
+#ifndef _RTL_ALLOC_H_
+#include <rtl/alloc.h>
+#endif
+
+#ifndef _RTL_STRBUF_HXX_
+#include <rtl/strbuf.hxx>
+#endif
+
+#ifndef _BRIDGES_CPP_UNO_BRIDGE_HXX_
+#include <bridges/cpp_uno/bridge.hxx>
+#endif
+#ifndef _COM_SUN_STAR_UNO_ANY_HXX_
+#include <com/sun/star/uno/Any.hxx>
+#endif
+
+#include "msci.hxx"
+
+#pragma pack(push, 8)
+
+using namespace com::sun::star::uno;
+using namespace std;
+using namespace osl;
+using namespace rtl;
+
+namespace CPPU_CURRENT_NAMESPACE
+{
+
+//==================================================================================================
+static inline OString toUNOname( const OString & rRTTIname )
+{
+ OStringBuffer aRet( 64 );
+ OString aStr( rRTTIname.copy( 4, rRTTIname.getLength()-4-2 ) ); // filter .?AUzzz@yyy@xxx@@
+ for ( sal_Int32 nToken = aStr.getTokenCount( '@' ); nToken--; )
+ {
+ aRet.append( aStr.getToken( nToken, '@' ) );
+ if (nToken)
+ aRet.append( '.' );
+ }
+ return aRet.makeStringAndClear();
+}
+//==================================================================================================
+static inline OString toRTTIname( const OString & rUNOname )
+{
+ OStringBuffer aRet( 64 );
+ aRet.append( RTL_CONSTASCII_STRINGPARAM(".?AV") ); // class ".?AV"; struct ".?AU"
+ for ( sal_Int32 nToken = rUNOname.getTokenCount( '.' ); nToken--; )
+ {
+ aRet.append( rUNOname.getToken( nToken, '.' ) );
+ aRet.append( '@' );
+ }
+ aRet.append( '@' );
+ return aRet.makeStringAndClear();
+}
+
+
+//##################################################################################################
+//#### RTTI simulation #############################################################################
+//##################################################################################################
+
+
+//==================================================================================================
+struct FctOStringHash : public unary_function< const OString &, size_t >
+{
+ size_t operator()( const OString & rStr ) const
+ { return rStr.hashCode(); }
+};
+typedef hash_map< OString, void *, FctOStringHash, equal_to< OString > > t_string2PtrMap;
+
+//==================================================================================================
+class RTTInfos
+{
+ Mutex _aMutex;
+ t_string2PtrMap _allRTTI;
+
+ static OString toRawName( const OString & rUNOname );
+public:
+ type_info * getRTTI( const OString & rUNOname );
+
+ RTTInfos();
+ ~RTTInfos();
+};
+
+//==================================================================================================
+class __type_info
+{
+ friend type_info * RTTInfos::getRTTI( const OString & );
+ friend sal_Int32 msci_filterCppException( LPEXCEPTION_POINTERS, uno_Any *, uno_Mapping * );
+
+public:
+ virtual ~__type_info();
+
+ __type_info( void * m_data, const char * m_d_name )
+ : _m_data( m_data )
+ { ::strcpy( _m_d_name, m_d_name ); }
+
+private:
+ void * _m_data;
+ char _m_d_name[1];
+};
+//__________________________________________________________________________________________________
+__type_info::~__type_info()
+{
+}
+//__________________________________________________________________________________________________
+type_info * RTTInfos::getRTTI( const OString & rUNOname )
+{
+ // a must be
+ OSL_ENSHURE( sizeof(__type_info) == sizeof(type_info), "### type info structure size differ!" );
+
+ MutexGuard aGuard( _aMutex );
+ const t_string2PtrMap::const_iterator iFind( _allRTTI.find( rUNOname ) );
+
+ // check if type is already available
+ if (iFind == _allRTTI.end())
+ {
+ // insert new type_info
+ OString aRawName( toRTTIname( rUNOname ) );
+ __type_info * pRTTI = new(rtl_allocateMemory( sizeof(__type_info) + aRawName.getLength() ))
+ __type_info( NULL, aRawName.getStr() );
+ // put into map
+ _allRTTI[rUNOname] = pRTTI;
+
+ return (type_info *)pRTTI;
+ }
+ else
+ {
+ return (type_info *)(*iFind).second;
+ }
+}
+//__________________________________________________________________________________________________
+RTTInfos::RTTInfos()
+{
+}
+//__________________________________________________________________________________________________
+RTTInfos::~RTTInfos()
+{
+ TRACE( "> freeing generated RTTI infos... <\n" );
+
+ MutexGuard aGuard( _aMutex );
+ for ( t_string2PtrMap::const_iterator iPos( _allRTTI.begin() );
+ iPos != _allRTTI.end(); ++iPos )
+ {
+ __type_info * pType = (__type_info *)(*iPos).second;
+ pType->~__type_info(); // obsolete, but good style...
+ rtl_freeMemory( pType );
+ }
+}
+
+
+//##################################################################################################
+//#### Exception raising ###########################################################################
+//##################################################################################################
+
+
+//==================================================================================================
+struct ObjectFunction
+{
+ char somecode[12];
+ typelib_TypeDescription * _pTypeDescr; // type of object
+
+ ObjectFunction( typelib_TypeDescription * pTypeDescr, void * fpFunc );
+ ~ObjectFunction();
+};
+//__________________________________________________________________________________________________
+ObjectFunction::ObjectFunction( typelib_TypeDescription * pTypeDescr, void * fpFunc )
+ : _pTypeDescr( pTypeDescr )
+{
+ typelib_typedescription_acquire( _pTypeDescr );
+
+ unsigned char * pCode = (unsigned char *)somecode;
+ // a must be!
+ OSL_ENSHURE( (void *)this == (void *)pCode, "### unexpected!" );
+
+ // push ObjectFunction this
+ *pCode++ = 0x68;
+ *(void **)pCode = this;
+ pCode += sizeof(void *);
+ // jmp rel32 fpFunc
+ *pCode++ = 0xe9;
+ *(sal_Int32 *)pCode = ((unsigned char *)fpFunc) - pCode - sizeof(sal_Int32);
+}
+//__________________________________________________________________________________________________
+ObjectFunction::~ObjectFunction()
+{
+ typelib_typedescription_release( _pTypeDescr );
+}
+
+//==================================================================================================
+static void * __cdecl __copyConstruct( void * pExcThis, void * pSource, ObjectFunction * pThis )
+{
+ uno_copyData( pExcThis, pSource, pThis->_pTypeDescr, cpp_acquire );
+ return pExcThis;
+}
+//==================================================================================================
+static void * __cdecl __destruct( void * pExcThis, ObjectFunction * pThis )
+{
+ uno_destructData( pExcThis, pThis->_pTypeDescr, cpp_release );
+ return pExcThis;
+}
+
+// these are non virtual object methods; there is no this ptr on stack => ecx supplies _this_ ptr
+
+//==================================================================================================
+static __declspec(naked) copyConstruct()
+{
+ __asm
+ {
+ // ObjectFunction this already on stack
+ push [esp+8] // source exc object this
+ push ecx // exc object
+ call __copyConstruct
+ add esp, 12 // + ObjectFunction this
+ ret 4
+ }
+}
+//==================================================================================================
+static __declspec(naked) destruct()
+{
+ __asm
+ {
+ // ObjectFunction this already on stack
+ push ecx // exc object
+ call __destruct
+ add esp, 8 // + ObjectFunction this
+ ret
+ }
+}
+
+//==================================================================================================
+struct ExceptionType
+{
+ sal_Int32 _n0;
+ type_info * _pTypeInfo;
+ sal_Int32 _n1, _n2, _n3, _n4;
+ ObjectFunction * _pCopyCtor;
+ sal_Int32 _n5;
+
+ ExceptionType( typelib_TypeDescription * pTypeDescr )
+ : _n0( 0 )
+ , _n1( 0 )
+ , _n2( -1 )
+ , _n3( 0 )
+ , _n4( pTypeDescr->nSize )
+ , _pCopyCtor( new ObjectFunction( pTypeDescr, copyConstruct ) )
+ , _n5( 0 )
+ { _pTypeInfo = msci_getRTTI( OUStringToOString( pTypeDescr->pTypeName, RTL_TEXTENCODING_ASCII_US ) ); }
+ ~ExceptionType()
+ { delete _pCopyCtor; }
+};
+//==================================================================================================
+struct RaiseInfo
+{
+ sal_Int32 _n0;
+ ObjectFunction * _pDtor;
+ sal_Int32 _n2;
+ void * _types;
+ sal_Int32 _n3, _n4;
+
+ RaiseInfo( typelib_TypeDescription * pTypeDescr );
+ ~RaiseInfo();
+};
+//__________________________________________________________________________________________________
+RaiseInfo::RaiseInfo( typelib_TypeDescription * pTypeDescr )
+ : _n0( 0 )
+ , _pDtor( new ObjectFunction( pTypeDescr, destruct ) )
+ , _n2( 0 )
+ , _n3( 0 )
+ , _n4( 0 )
+{
+ // a must be
+ OSL_ENSHURE( sizeof(sal_Int32) == sizeof(ExceptionType *), "### pointer size differs from sal_Int32!" );
+
+ typelib_CompoundTypeDescription * pCompTypeDescr;
+
+ // info count
+ sal_Int32 nLen = 0;
+ for ( pCompTypeDescr = (typelib_CompoundTypeDescription*)pTypeDescr;
+ pCompTypeDescr; pCompTypeDescr = pCompTypeDescr->pBaseTypeDescription )
+ {
+ ++nLen;
+ }
+
+ // info count accompanied by type info ptrs: type, base type, base base type, ...
+ _types = rtl_allocateMemory( sizeof(sal_Int32) + (sizeof(ExceptionType *) * nLen) );
+ *(sal_Int32 *)_types = nLen;
+
+ ExceptionType ** ppTypes = (ExceptionType **)((sal_Int32 *)_types + 1);
+
+ sal_Int32 nPos = 0;
+ for ( pCompTypeDescr = (typelib_CompoundTypeDescription*)pTypeDescr;
+ pCompTypeDescr; pCompTypeDescr = pCompTypeDescr->pBaseTypeDescription )
+ {
+ ppTypes[nPos++] = new ExceptionType( (typelib_TypeDescription *)pCompTypeDescr );
+ }
+}
+//__________________________________________________________________________________________________
+RaiseInfo::~RaiseInfo()
+{
+ ExceptionType ** ppTypes = (ExceptionType **)((sal_Int32 *)_types + 1);
+ for ( sal_Int32 nTypes = *(sal_Int32 *)_types; nTypes--; )
+ delete ppTypes[nTypes];
+ rtl_freeMemory( _types );
+
+ delete _pDtor;
+}
+
+//==================================================================================================
+class ExceptionInfos
+{
+ Mutex _aMutex;
+ t_string2PtrMap _allRaiseInfos;
+public:
+ void raiseException( uno_Any * pUnoExc, uno_Mapping * pUno2Cpp );
+
+ ExceptionInfos();
+ ~ExceptionInfos();
+};
+//__________________________________________________________________________________________________
+ExceptionInfos::ExceptionInfos()
+{
+}
+//__________________________________________________________________________________________________
+ExceptionInfos::~ExceptionInfos()
+{
+ TRACE( "> freeing exception infos... <\n" );
+
+ MutexGuard aGuard( _aMutex );
+ for ( t_string2PtrMap::const_iterator iPos( _allRaiseInfos.begin() );
+ iPos != _allRaiseInfos.end(); ++iPos )
+ {
+ delete (RaiseInfo *)(*iPos).second;
+ }
+}
+//__________________________________________________________________________________________________
+void ExceptionInfos::raiseException( uno_Any * pUnoExc, uno_Mapping * pUno2Cpp )
+{
+ // construct cpp exception object
+ typelib_TypeDescription * pTypeDescr = 0;
+ TYPELIB_DANGER_GET( &pTypeDescr, pUnoExc->pType );
+
+ OSL_ENSHURE( pTypeDescr && (pTypeDescr->eTypeClass == typelib_TypeClass_STRUCT ||
+ pTypeDescr->eTypeClass == typelib_TypeClass_EXCEPTION),
+ "### can only throw types of class exception/ structs" );
+
+ void * pCppExc = alloca( pTypeDescr->nSize );
+ uno_copyAndConvertData( pCppExc, pUnoExc->pData, pTypeDescr, pUno2Cpp );
+
+ // concatenate all types of exception for key
+ OUStringBuffer aKeyBuf;
+ typelib_CompoundTypeDescription * pCompTypeDescr;
+ for ( pCompTypeDescr = (typelib_CompoundTypeDescription *)pTypeDescr;
+ pCompTypeDescr; pCompTypeDescr = pCompTypeDescr->pBaseTypeDescription )
+ {
+ aKeyBuf.append( ((typelib_TypeDescription *)pCompTypeDescr)->pTypeName );
+ }
+ OString aKey( OUStringToOString( aKeyBuf.makeStringAndClear(), RTL_TEXTENCODING_ASCII_US ) );
+
+ MutexGuard aGuard( _aMutex );
+ const t_string2PtrMap::const_iterator iFind( _allRaiseInfos.find( aKey ) );
+
+ // a must be
+ OSL_ENSHURE( sizeof(sal_Int32) == sizeof(void *), "### pointer size differs from sal_Int32!" );
+ DWORD arFilterArgs[3];
+ arFilterArgs[0] = 0x19930520L;
+ arFilterArgs[1] = (DWORD)pCppExc;
+ arFilterArgs[2] = (DWORD)(iFind != _allRaiseInfos.end()
+ ? (*iFind).second // reuse existing info
+ : _allRaiseInfos[aKey] = new RaiseInfo( pTypeDescr )); // put into map
+
+ // this is the last chance to release anything not affected by stack unwinding:
+ // destruct uno exception
+ uno_any_destruct( pUnoExc, 0 );
+
+ TYPELIB_DANGER_RELEASE( pTypeDescr );
+
+ RaiseException( MSVC_ExceptionCode, EXCEPTION_NONCONTINUABLE, 3, arFilterArgs );
+}
+
+
+//##################################################################################################
+//#### exported ####################################################################################
+//##################################################################################################
+
+
+//##################################################################################################
+type_info * msci_getRTTI( const OString & rUNOname )
+{
+ static RTTInfos * s_pRTTIs = 0;
+ if (! s_pRTTIs)
+ {
+ MutexGuard aGuard( Mutex::getGlobalMutex() );
+ if (! s_pRTTIs)
+ {
+#ifdef LEAK_STATIC_DATA
+ s_pRTTIs = new RTTInfos();
+#else
+ static RTTInfos s_aRTTIs;
+ s_pRTTIs = &s_aRTTIs;
+#endif
+ }
+ }
+ return s_pRTTIs->getRTTI( rUNOname );
+}
+
+//##################################################################################################
+void msci_raiseException( uno_Any * pUnoExc, uno_Mapping * pUno2Cpp )
+{
+ static ExceptionInfos * s_pInfos = 0;
+ if (! s_pInfos)
+ {
+ MutexGuard aGuard( Mutex::getGlobalMutex() );
+ if (! s_pInfos)
+ {
+#ifdef LEAK_STATIC_DATA
+ s_pInfos = new ExceptionInfos();
+#else
+ static ExceptionInfos s_allExceptionInfos;
+ s_pInfos = &s_allExceptionInfos;
+#endif
+ }
+ }
+ s_pInfos->raiseException( pUnoExc, pUno2Cpp );
+}
+
+//##################################################################################################
+sal_Int32 msci_filterCppException(
+ LPEXCEPTION_POINTERS pPointers, uno_Any * pUnoExc, uno_Mapping * pCpp2Uno )
+{
+ PEXCEPTION_RECORD pRecord = pPointers->ExceptionRecord;
+ if (pRecord->ExceptionCode == MSVC_ExceptionCode &&
+ pRecord->ExceptionFlags == EXCEPTION_NONCONTINUABLE &&
+ pRecord->NumberParameters == 3 &&
+// pRecord->ExceptionInformation[0] == 0x19930520 &&
+ pRecord->ExceptionInformation[1] &&
+ pRecord->ExceptionInformation[2])
+ {
+ void * types = ((RaiseInfo *)pRecord->ExceptionInformation[2])->_types;
+ if (types && *(sal_Int32 *)types) // count
+ {
+ ExceptionType * pType = *(ExceptionType **)((sal_Int32 *)types +1);
+ if (pType && pType->_pTypeInfo)
+ {
+ OUString aUNOname( OStringToOUString( toUNOname(
+ ((__type_info *)pType->_pTypeInfo)->_m_d_name ), RTL_TEXTENCODING_ASCII_US ) );
+ typelib_TypeDescription * pExcTypeDescr = 0;
+ typelib_typedescription_getByName( &pExcTypeDescr, aUNOname.pData );
+
+ if (pExcTypeDescr)
+ {
+ // construct uno exception any
+ uno_any_constructAndConvert( pUnoExc, (void *)pRecord->ExceptionInformation[1],
+ pExcTypeDescr, pCpp2Uno );
+ uno_destructData( (void *)pRecord->ExceptionInformation[1],
+ pExcTypeDescr, cpp_release );
+ typelib_typedescription_release( pExcTypeDescr );
+ return EXCEPTION_EXECUTE_HANDLER;
+ }
+ }
+ }
+ }
+ return EXCEPTION_CONTINUE_SEARCH;
+}
+
+}
+
+#pragma pack(pop)
+
diff --git a/bridges/source/cpp_uno/msvc_win32_intel/makefile.mk b/bridges/source/cpp_uno/msvc_win32_intel/makefile.mk
new file mode 100644
index 000000000000..31435863d82a
--- /dev/null
+++ b/bridges/source/cpp_uno/msvc_win32_intel/makefile.mk
@@ -0,0 +1,119 @@
+#*************************************************************************
+#
+# $RCSfile: makefile.mk,v $
+#
+# $Revision: 1.1.1.1 $
+#
+# last change: $Author: hr $ $Date: 2000-09-18 15:28:49 $
+#
+# The Contents of this file are made available subject to the terms of
+# either of the following licenses
+#
+# - GNU Lesser General Public License Version 2.1
+# - Sun Industry Standards Source License Version 1.1
+#
+# Sun Microsystems Inc., October, 2000
+#
+# GNU Lesser General Public License Version 2.1
+# =============================================
+# Copyright 2000 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
+#
+#
+# Sun Industry Standards Source License Version 1.1
+# =================================================
+# The contents of this file are subject to the Sun Industry Standards
+# Source License Version 1.1 (the "License"); You may not use this file
+# except in compliance with the License. You may obtain a copy of the
+# License at http://www.openoffice.org/license.html.
+#
+# Software provided under this License is provided on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+# WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+# MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+# See the License for the specific provisions governing your rights and
+# obligations concerning the Software.
+#
+# The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+#
+# Copyright: 2000 by Sun Microsystems, Inc.
+#
+# All Rights Reserved.
+#
+# Contributor(s): _______________________________________
+#
+#
+#
+#*************************************************************************
+
+PRJ=..$/..$/..
+
+PRJNAME=msci_uno
+TARGET=msci_uno
+LIBTARGET=no
+ENABLE_EXCEPTIONS=TRUE
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : svpre.mk
+.INCLUDE : settings.mk
+.INCLUDE : sv.mk
+
+# --- Files --------------------------------------------------------
+.IF "$(COM)" == "MSC"
+
+.IF "$(debug)" == ""
+CFLAGS += /O2gityb2 /Gs
+.ELSE
+CFLAGS += /Ob0
+.ENDIF
+
+SLOFILES= \
+ $(SLO)$/cpp2uno.obj \
+ $(SLO)$/uno2cpp.obj \
+ $(SLO)$/except.obj
+
+SHL1TARGET= $(TARGET)
+
+SHL1DEF= $(MISC)$/$(SHL1TARGET).def
+SHL1IMPLIB= i$(TARGET)
+
+SHL1OBJS= \
+ $(SLO)$/cpp2uno.obj \
+ $(SLO)$/uno2cpp.obj \
+ $(SLO)$/except.obj
+
+SHL1STDLIBS= \
+ $(CPPULIB) \
+ $(SALLIB)
+
+# --- Targets ------------------------------------------------------
+
+.INCLUDE : target.mk
+
+$(MISC)$/$(SHL1TARGET).def: makefile.mk
+ @echo ------------------------------
+ @echo Making: $@
+ @echo LIBRARY $(SHL1TARGET) >$@
+ @echo DESCRIPTION 'MS Visual C++ bridge to UNO' >>$@
+ @echo DATA READ WRITE NONSHARED >>$@
+ @echo EXPORTS >>$@
+ @echo uno_initEnvironment @3 >>$@
+ @echo uno_ext_getMapping @4 >>$@
+
+.ENDIF
+
diff --git a/bridges/source/cpp_uno/msvc_win32_intel/msci.hxx b/bridges/source/cpp_uno/msvc_win32_intel/msci.hxx
new file mode 100644
index 000000000000..c934158a9ac2
--- /dev/null
+++ b/bridges/source/cpp_uno/msvc_win32_intel/msci.hxx
@@ -0,0 +1,90 @@
+/*************************************************************************
+ *
+ * $RCSfile: msci.hxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 15:28:49 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 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
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#include <windows.h>
+
+#ifndef _RTL_STRING_HXX_
+#include <rtl/string.hxx>
+#endif
+
+#define MSVC_ExceptionCode 0xe06d7363
+
+class type_info;
+typedef struct _uno_Any uno_Any;
+typedef struct _uno_Mapping uno_Mapping;
+
+namespace CPPU_CURRENT_NAMESPACE
+{
+
+//==================================================================================================
+type_info * msci_getRTTI(
+ const ::rtl::OString & rUNOname );
+
+//==================================================================================================
+sal_Int32 msci_filterCppException(
+ LPEXCEPTION_POINTERS pPointers, uno_Any * pUnoExc, uno_Mapping * pCpp2Uno );
+
+//==================================================================================================
+void msci_raiseException(
+ uno_Any * pUnoExc, uno_Mapping * pUno2Cpp );
+
+}
+
diff --git a/bridges/source/cpp_uno/msvc_win32_intel/uno2cpp.cxx b/bridges/source/cpp_uno/msvc_win32_intel/uno2cpp.cxx
new file mode 100644
index 000000000000..c0fa7227d3d5
--- /dev/null
+++ b/bridges/source/cpp_uno/msvc_win32_intel/uno2cpp.cxx
@@ -0,0 +1,494 @@
+/*************************************************************************
+ *
+ * $RCSfile: uno2cpp.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 15:28:49 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 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
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#pragma warning( disable : 4237 )
+#include <malloc.h>
+#ifndef _RTL_ALLOC_H_
+#include <rtl/alloc.h>
+#endif
+#ifndef _RTL_STRING_HXX_
+#include <rtl/string.hxx>
+#endif
+
+#ifndef _UNO_DATA_H_
+#include <uno/data.h>
+#endif
+#ifndef _BRIDGES_CPP_UNO_BRIDGE_HXX_
+#include <bridges/cpp_uno/bridge.hxx>
+#endif
+#ifndef _BRIDGES_CPP_UNO_TYPE_MISC_HXX_
+#include <bridges/cpp_uno/type_misc.hxx>
+#endif
+
+#include "msci.hxx"
+
+using namespace rtl;
+using namespace com::sun::star::uno;
+
+namespace CPPU_CURRENT_NAMESPACE
+{
+
+//==================================================================================================
+inline static void callVirtualMethod( void * pThis, sal_Int32 nVtableIndex,
+ void * pRegisterReturn, typelib_TypeClass eReturnTypeClass,
+ sal_Int32 * pStackLongs, sal_Int32 nStackLongs )
+{
+ // parameter list is mixed list of * and values
+ // reference parameters are pointers
+
+ OSL_ENSHURE( pStackLongs && pThis, "### null ptr!" );
+ OSL_ENSHURE( (sizeof(void *) == 4) &&
+ (sizeof(sal_Int32) == 4), "### unexpected size of int!" );
+
+__asm
+ {
+ mov eax, nStackLongs
+ test eax, eax
+ je Lcall
+ // copy values
+ mov ecx, eax
+ shl eax, 2 // sizeof(sal_Int32) == 4
+ add eax, pStackLongs // params stack space
+Lcopy: sub eax, 4
+ push dword ptr [eax]
+ dec ecx
+ jne Lcopy
+Lcall:
+ // call
+ mov ecx, pThis
+ push ecx // this ptr
+ mov edx, [ecx] // pvft
+ mov eax, nVtableIndex
+ shl eax, 2 // sizeof(void *) == 4
+ add edx, eax
+ call [edx] // interface method call must be __cdecl!!!
+
+ // register return
+ mov ecx, eReturnTypeClass
+ cmp ecx, typelib_TypeClass_VOID
+ je Lcleanup
+ mov ebx, pRegisterReturn
+// int32
+ cmp ecx, typelib_TypeClass_LONG
+ je Lint32
+ cmp ecx, typelib_TypeClass_UNSIGNED_LONG
+ je Lint32
+ cmp ecx, typelib_TypeClass_ENUM
+ je Lint32
+// int8
+ cmp ecx, typelib_TypeClass_BOOLEAN
+ je Lint8
+ cmp ecx, typelib_TypeClass_BYTE
+ je Lint8
+// int16
+ cmp ecx, typelib_TypeClass_CHAR
+ je Lint16
+ cmp ecx, typelib_TypeClass_SHORT
+ je Lint16
+ cmp ecx, typelib_TypeClass_UNSIGNED_SHORT
+ je Lint16
+// float
+ cmp ecx, typelib_TypeClass_FLOAT
+ je Lfloat
+// double
+ cmp ecx, typelib_TypeClass_DOUBLE
+ je Ldouble
+// int64
+ cmp ecx, typelib_TypeClass_HYPER
+ je Lint64
+ cmp ecx, typelib_TypeClass_UNSIGNED_HYPER
+ je Lint64
+ jmp Lcleanup // no simple type
+Lint8:
+ mov byte ptr [ebx], al
+ jmp Lcleanup
+Lint16:
+ mov word ptr [ebx], ax
+ jmp Lcleanup
+Lfloat:
+ fstp dword ptr [ebx]
+ jmp Lcleanup
+Ldouble:
+ fstp qword ptr [ebx]
+ jmp Lcleanup
+Lint64:
+ mov dword ptr [ebx], eax
+ mov dword ptr [ebx+4], edx
+ jmp Lcleanup
+Lint32:
+ mov dword ptr [ebx], eax
+ jmp Lcleanup
+Lcleanup:
+ // cleanup stack (obsolete though because of function)
+ mov eax, nStackLongs
+ shl eax, 2 // sizeof(sal_Int32) == 4
+ add eax, 4 // this ptr
+ add esp, eax
+ }
+}
+
+//==================================================================================================
+inline static void cpp_call(
+ cppu_unoInterfaceProxy * pThis,
+ sal_Int32 nVtableCall,
+ typelib_TypeDescriptionReference * pReturnTypeRef,
+ sal_Int32 nParams, typelib_MethodParameter * pParams,
+ sal_Int32 nExceptions, typelib_TypeDescriptionReference ** ppExceptionRefs,
+ void * pUnoReturn, void * pUnoArgs[], uno_Any ** ppUnoExc )
+{
+ // max space for: [complex ret ptr], values|ptr ...
+ char * pCppStack = (char *)alloca( sizeof(sal_Int32) + (nParams * sizeof(sal_Int64)) );
+ char * pCppStackStart = pCppStack;
+
+ // return
+ typelib_TypeDescription * pReturnTypeDescr = 0;
+ TYPELIB_DANGER_GET( &pReturnTypeDescr, pReturnTypeRef );
+ OSL_ENSHURE( pReturnTypeDescr, "### expected return type description!" );
+
+ void * pCppReturn = 0; // if != 0 && != pUnoReturn, needs reconversion
+
+ if (pReturnTypeDescr)
+ {
+ if (cppu_isSimpleType( pReturnTypeDescr ))
+ {
+ pCppReturn = pUnoReturn; // direct way for simple types
+ }
+ else
+ {
+ // complex return via ptr
+ pCppReturn = *(void **)pCppStack = (cppu_relatesToInterface( pReturnTypeDescr )
+ ? alloca( pReturnTypeDescr->nSize )
+ : pUnoReturn); // direct way
+ pCppStack += sizeof(void *);
+ }
+ }
+
+ // stack space
+
+ OSL_ENSHURE( sizeof(void *) == sizeof(sal_Int32), "### unexpected size!" );
+ // 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 && cppu_isSimpleType( pParamTypeDescr ))
+ {
+ uno_copyAndConvertData( pCppArgs[nPos] = pCppStack, pUnoArgs[nPos], pParamTypeDescr,
+ &pThis->pBridge->aUno2Cpp );
+
+ 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 (cppu_relatesToInterface( pParamTypeDescr ))
+ {
+ uno_copyAndConvertData(
+ *(void **)pCppStack = pCppArgs[nPos] = alloca( pParamTypeDescr->nSize ),
+ pUnoArgs[nPos], pParamTypeDescr,
+ &pThis->pBridge->aUno2Cpp );
+
+ 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
+ }
+
+ // only try-finally/ try-except statements possible...
+ __try
+ {
+ __try
+ {
+ // pCppI is msci this pointer
+ callVirtualMethod(
+ pThis->pCppI, nVtableCall,
+ pCppReturn, pReturnTypeDescr->eTypeClass,
+ (sal_Int32 *)pCppStackStart, (pCppStack - pCppStackStart) / sizeof(sal_Int32) );
+
+ // NO exception occured...
+ *ppUnoExc = 0;
+
+ // reconvert temporary params
+ while (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->pBridge->aCpp2Uno );
+ }
+ }
+ else // pure out
+ {
+ uno_copyAndConvertData( pUnoArgs[nIndex], pCppArgs[nIndex], pParamTypeDescr,
+ &pThis->pBridge->aCpp2Uno );
+ }
+ // destroy temp cpp param => cpp: every param was constructed
+ uno_destructData( pCppArgs[nIndex], pParamTypeDescr, cpp_release );
+
+ TYPELIB_DANGER_RELEASE( pParamTypeDescr );
+ }
+ // return value
+ if (pCppReturn && pUnoReturn != pCppReturn)
+ {
+ uno_copyAndConvertData( pUnoReturn, pCppReturn, pReturnTypeDescr,
+ &pThis->pBridge->aCpp2Uno );
+ uno_destructData( pCppReturn, pReturnTypeDescr, cpp_release );
+ }
+ }
+ __except (msci_filterCppException( GetExceptionInformation(),
+ *ppUnoExc, &pThis->pBridge->aCpp2Uno ))
+ {
+ // *ppUnoExc is untouched and any was constructed by filter function
+ // __finally block will be called
+ return;
+ }
+ }
+ __finally
+ {
+ // cleanup of params was already done in reconversion loop iff no exception occured;
+ // this is quicker than getting all param descriptions twice!
+ // so cleanup only iff an exception occured:
+ if (*ppUnoExc)
+ {
+ // temporary params
+ while (nTempIndizes--)
+ {
+ sal_Int32 nIndex = pTempIndizes[nTempIndizes];
+ // destroy temp cpp param => cpp: every param was constructed
+ uno_destructData( pCppArgs[nIndex], ppTempParamTypeDescr[nTempIndizes], cpp_release );
+ TYPELIB_DANGER_RELEASE( ppTempParamTypeDescr[nTempIndizes] );
+ }
+ }
+ // return type
+ if (pReturnTypeDescr)
+ TYPELIB_DANGER_RELEASE( pReturnTypeDescr );
+ }
+}
+
+//==================================================================================================
+void SAL_CALL cppu_unoInterfaceProxy_dispatch(
+ uno_Interface * pUnoI, const typelib_TypeDescription * pMemberDescr,
+ void * pReturn, void * pArgs[], uno_Any ** ppException )
+{
+ // is my surrogate
+ cppu_unoInterfaceProxy * pThis = static_cast< cppu_unoInterfaceProxy * >( pUnoI );
+ typelib_InterfaceTypeDescription * pTypeDescr = pThis->pTypeDescr;
+
+ switch (pMemberDescr->eTypeClass)
+ {
+ case typelib_TypeClass_INTERFACE_ATTRIBUTE:
+ {
+ // determine vtable call index
+ sal_Int32 nMemberPos = ((typelib_InterfaceMemberTypeDescription *)pMemberDescr)->nPosition;
+ OSL_ENSHURE( nMemberPos < pTypeDescr->nAllMembers, "### member pos out of range!" );
+
+ sal_Int32 nVtableCall = pTypeDescr->pMapMemberIndexToFunctionIndex[nMemberPos];
+ OSL_ENSHURE( nVtableCall < pTypeDescr->nMapFunctionIndexToMemberIndex, "### illegal vtable index!" );
+
+ typelib_TypeDescriptionReference * pRuntimeExcRef = 0;
+
+ if (pReturn)
+ {
+ // dependent dispatch
+ cpp_call( pThis, nVtableCall,
+ ((typelib_InterfaceAttributeTypeDescription *)pMemberDescr)->pAttributeTypeRef,
+ 0, 0, // no params
+ 1, &pRuntimeExcRef, // RuntimeException
+ 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
+ cpp_call( pThis, nVtableCall +1, // get, then set method
+ pReturnTypeRef,
+ 1, &aParam,
+ 1, &pRuntimeExcRef,
+ pReturn, pArgs, ppException );
+
+ typelib_typedescriptionreference_release( pReturnTypeRef );
+ }
+
+ break;
+ }
+ case typelib_TypeClass_INTERFACE_METHOD:
+ {
+ // determine vtable call index
+ sal_Int32 nMemberPos = ((typelib_InterfaceMemberTypeDescription *)pMemberDescr)->nPosition;
+ OSL_ENSHURE( nMemberPos < pTypeDescr->nAllMembers, "### member pos out of range!" );
+
+ sal_Int32 nVtableCall = pTypeDescr->pMapMemberIndexToFunctionIndex[nMemberPos];
+ OSL_ENSHURE( nVtableCall < pTypeDescr->nMapFunctionIndexToMemberIndex, "### illegal vtable index!" );
+
+ switch (nVtableCall)
+ {
+ // 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() );
+ OSL_ASSERT( pTD );
+
+ uno_Interface * pInterface = 0;
+ (*pThis->pBridge->pUnoEnv->getRegisteredInterface)(
+ pThis->pBridge->pUnoEnv,
+ (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, nVtableCall,
+ ((typelib_InterfaceMethodTypeDescription *)pMemberDescr)->pReturnTypeRef,
+ ((typelib_InterfaceMethodTypeDescription *)pMemberDescr)->nParams,
+ ((typelib_InterfaceMethodTypeDescription *)pMemberDescr)->pParams,
+ ((typelib_InterfaceMethodTypeDescription *)pMemberDescr)->nExceptions,
+ ((typelib_InterfaceMethodTypeDescription *)pMemberDescr)->ppExceptions,
+ pReturn, pArgs, ppException );
+ }
+ break;
+ }
+ default:
+ {
+ ::com::sun::star::uno::RuntimeException aExc(
+ OUString( RTL_CONSTASCII_USTRINGPARAM("illegal member type description!") ),
+ pThis->pCppI );
+
+ typelib_TypeDescription * pTD = 0;
+ const Type & rExcType = ::getCppuType( (const ::com::sun::star::uno::RuntimeException *)0 );
+ TYPELIB_DANGER_GET( &pTD, rExcType.getTypeLibType() );
+ uno_any_construct( *ppException, &aExc, pTD, 0 );
+ TYPELIB_DANGER_RELEASE( pTD );
+ }
+ }
+}
+
+}
+