summaryrefslogtreecommitdiff
path: root/bridges/source/cpp_uno/msvc_win32_x86-64
diff options
context:
space:
mode:
Diffstat (limited to 'bridges/source/cpp_uno/msvc_win32_x86-64')
-rw-r--r--bridges/source/cpp_uno/msvc_win32_x86-64/asmbits.asm328
-rw-r--r--bridges/source/cpp_uno/msvc_win32_x86-64/cpp2uno.cxx574
-rw-r--r--bridges/source/cpp_uno/msvc_win32_x86-64/dllinit.cxx61
-rw-r--r--bridges/source/cpp_uno/msvc_win32_x86-64/except.cxx623
-rw-r--r--bridges/source/cpp_uno/msvc_win32_x86-64/makefile.mk82
-rw-r--r--bridges/source/cpp_uno/msvc_win32_x86-64/mscx.hxx62
-rw-r--r--bridges/source/cpp_uno/msvc_win32_x86-64/uno2cpp.cxx453
7 files changed, 2183 insertions, 0 deletions
diff --git a/bridges/source/cpp_uno/msvc_win32_x86-64/asmbits.asm b/bridges/source/cpp_uno/msvc_win32_x86-64/asmbits.asm
new file mode 100644
index 000000000000..09f1177b9a9e
--- /dev/null
+++ b/bridges/source/cpp_uno/msvc_win32_x86-64/asmbits.asm
@@ -0,0 +1,328 @@
+; -*- Mode: text; tab-width: 8; indent-tabs-mode: nil comment-column: 32; comment-start: "; " comment-start-skip: "; *" -*-
+
+;*************************************************************************
+;*
+;* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+;*
+;* Copyright 2000, 2011 Oracle and/or its affiliates.
+;*
+;* OpenOffice.org - a multi-platform office productivity suite
+;*
+;* This file is part of OpenOffice.org.
+;*
+;* OpenOffice.org is free software: you can redistribute it and/or modify
+;* it under the terms of the GNU Lesser General Public License version 3
+;* only, as published by the Free Software Foundation.
+;*
+;* OpenOffice.org is distributed in the hope that it will be useful,
+;* but WITHOUT ANY WARRANTY; without even the implied warranty of
+;* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;* GNU Lesser General Public License version 3 for more details
+;* (a copy is included in the LICENSE file that accompanied this code).
+;*
+;* You should have received a copy of the GNU Lesser General Public License
+;* version 3 along with OpenOffice.org. If not, see
+;* <http://www.openoffice.org/license.html>
+;* for a copy of the LGPLv3 License.
+;*
+;************************************************************************
+
+; Emacs asm-mode is not really ideal for the convention in this
+; file. So I use text-mode with custom comment syntax... not really
+; ideal either. Maybe I should just re-format this to match asm-mode's
+; conventions?
+
+; NOTE: EXTREMELY UNFINISHED, I KNOW. WORK IN PROGRESS.
+
+; I really don't have a good high-level understanding of the big
+; picture and what the actual task of the C++/UNO bridge is yet... I
+; should debug the x86 version and see what is actually going on to
+; get an understanding.
+
+; This is in a separate file for x86-64 as MSVC doesn't have in-line
+; assembly for x64. The code here is still partly just a crude copy of
+; the in-line x86 code from ../msvc_win32_intel that is totally
+; pointless on x64. But parts have been properly changed into x64
+; calling convention and might even work.
+
+; Random web links and other documentation about low-level
+; implementation details for the C++/UNO bridge on x64 Windows kept
+; here:
+
+; Caolan's "Lazy Hackers Guide To Porting" is useful:
+; http://wiki.services.openoffice.org/wiki/Lazy_Hackers_Guide_To_Porting
+
+; As for details about the x64 Windows calling convention, register
+; usage, stack usage, exception handling etc, the official
+; documentation (?) on MSDN is a bit fragmented and split up into a
+; needlessly large number of short pages. But still:
+; http://msdn.microsoft.com/en-us/library/7kcdt6fy%28v=VS.90%29.aspx
+
+; Also see Raymond Chen's blog post:
+; http://blogs.msdn.com/b/oldnewthing/archive/2004/01/14/58579.aspx
+
+; This one is actually more readable: "Improving Automated Analysis of
+; Windows x64 Binaries":
+; http://www.uninformed.org/?v=4&a=1
+
+; The bridge uses dynamic code generation. For exception handling and
+; unwinding to work across that (as I assume we want?), one apparently
+; needs to use either RtlAddFunctionTable() or
+; RtlInstallFunctionTableCallback(). See Windows SDK documentation.
+
+; Random interesting discussion threads:
+; http://social.msdn.microsoft.com/Forums/en/vcgeneral/thread/300bd6d3-9381-4d2d-8129-e48b392c05d8
+
+; Ken Johnson's blog http://www.nynaeve.net/ has much interesting
+; information, for instance:
+; http://www.nynaeve.net/?p=11
+
+; From <typelib/typeclass.h>
+typelib_TypeClass_VOID = 0
+typelib_TypeClass_CHAR = 1
+typelib_TypeClass_BOOLEAN = 2
+typelib_TypeClass_BYTE = 3
+typelib_TypeClass_SHORT = 4
+typelib_TypeClass_UNSIGNED_SHORT = 5
+typelib_TypeClass_LONG = 6
+typelib_TypeClass_UNSIGNED_LONG = 7
+typelib_TypeClass_HYPER = 8
+typelib_TypeClass_UNSIGNED_HYPER = 9
+typelib_TypeClass_FLOAT = 10
+typelib_TypeClass_DOUBLE = 11
+typelib_TypeClass_ENUM = 15
+
+extrn __copyConstruct : proc
+extrn __destruct : proc
+extrn cpp_mediate: proc
+
+.code
+
+; First we have three code snippets that aren't real functions, but
+; "naked" (in x86 calling convention parlance) functions jumped to
+; from code generated in C++.
+
+; I think that for x64 Windows we shouldn't be jumping so wildly from
+; generated code snippets into fixed code snippets here. "Procedures"
+; should be continuous in memory, or the unwinding information will be
+; broken. (For dynamically generated code, that is dynamically
+; registered unwind information, obviously.)
+
+; So instead of generating jumps into here, we should just make the
+; C++ code copy the machine code that these three "naked" functions
+; compile to after the snippet it is generating. Of course, that means
+; the code here needs to be position independent, or (eek) that we
+; would need to come up with some home-brewed minimal relocation
+; mechanism.
+
+; Jumped to from code generated in except.cxx: ObjectFunction::ObjectFunction()
+
+copyConstruct proc
+ ; ObjectFunction this already on stack
+ push [rsp+8] ; source exc object this
+ push rcx ; exc object
+ call __copyConstruct
+ add rsp, 12 ; + ObjectFunction this
+ ret 4
+copyConstruct endp
+
+; Ditto
+
+destruct proc
+ ; ObjectFunction this already on stack
+ push rcx ; exc object
+ call __destruct
+ add rsp, 8 ; + ObjectFunction this
+ ret
+destruct endp
+
+; Jumped to from code generated in cpp2uno.cxx:codeSnippet()
+
+cpp_vtable_call proc
+ sub rsp, 8 ; space for immediate return type
+ push rsp
+ push rdx ; vtable offset
+ push rax ; function index
+ mov rax, rsp
+ add rax, 20
+ push rax ; original stack ptr
+
+ call cpp_mediate
+ add rsp, 16
+
+ cmp rax, typelib_TypeClass_FLOAT
+ je Lfloat
+ cmp rax, typelib_TypeClass_DOUBLE
+ je Ldouble
+ cmp rax, typelib_TypeClass_HYPER
+ je Lhyper
+ cmp eax, typelib_TypeClass_UNSIGNED_HYPER
+ je Lhyper
+ ; rest is eax
+ pop rax
+ add rsp, 4
+ ret
+Lhyper:
+ pop rax
+ pop rdx
+ ret
+Lfloat:
+ fld dword ptr [rsp]
+ add rsp, 8
+ ret
+Ldouble:
+ fld qword ptr [rsp]
+ add rsp, 8
+ ret
+cpp_vtable_call endp
+
+; Called from uno2cpp.cxx
+
+; This one is now hopefully proper x64 Windows code following the
+; appropriate conventions and might actually work.
+
+; void callVirtualMethod( ; location on entry
+; void * pAdjustedThisPtr, ; rcx
+; sal_Int32 nVtableIndex, ; rdx
+; void * pReturn, ; r8
+; typelib_TypeClass eReturnTypeClass, ; r9
+; sal_Int64 * pStack, ; ((4+1)*8)[rsp]
+; sal_Int32 nStack ; ((5+1)*8)[rsp]
+; sal_uInt64 *pGPR, ; ((6+1)*8)[rsp]
+; double *pFPR) ; ((7+1)*8)[rsp]
+
+callVirtualMethod proc frame
+ ; Prologue
+ mov ((3+1)*8)[rsp], r9
+ mov ((2+1)*8)[rsp], r8
+ mov ((0+1)*8)[rsp], rcx
+ push rsi
+ .pushreg rsi
+ push rdi
+ .pushreg rdi
+
+ ; Our stack frame size is 24 qwords (space for 20 parameters
+ ; to pass, plus the two pushed registers rsi and rdi, plus
+ ; return address, rounded up to 16 bytes)
+
+ sub rsp, (20+1)*8
+ .allocstack (20+1)*8
+ .endprolog
+
+ ; Stack parameters first
+
+ ; nStack is number of qwords of stack space (including spilled
+ ; registers). If four or less, 4 is passed in anyway to make
+ ; code here simpler.
+
+ mov rcx, ((24+5)*8)[rsp] ; nStack
+ sub rcx, 4
+ jle Lxmmregs
+
+ mov rsi, ((24+4)*8)[rsp] ; pStack
+ add rsi, 32
+ lea rdi, 32[rsp]
+ rep movsq
+
+Lxmmregs:
+ ; Parameters passed in XMM registers
+
+ ; We don't bother checking which actually needed, if any.
+ mov rax, ((24+7)*8)[rsp] ; pFPR
+ movsd xmm0, qword ptr [rax]
+ movsd xmm1, qword ptr 8[rax]
+ movsd xmm2, qword ptr 16[rax]
+ movsd xmm3, qword ptr 24[rax]
+
+ ; Prepare pointer to function to call
+ mov rcx, ((24+0)*8)[rsp]
+ mov r12, [rcx] ; pAdjustedThisPtr->vtable
+ shl rdx, 3 ; nVtableIndex *= 8
+ add r12, rdx
+
+ ; Fill parameters passed in general purpose registers
+ mov rax, ((24+6)*8)[rsp] ; pGPR
+ mov rcx, (0*8)[rax]
+ mov rdx, (1*8)[rax]
+ mov r8, (2*8)[rax]
+ mov r9, (3*8)[rax]
+
+ call qword ptr [r12]
+
+ ; Test return type
+ mov r9, ((24+3)*8)[rsp]
+ cmp r9, typelib_TypeClass_VOID
+ je Lepilog
+
+ ; int32
+ cmp r9, typelib_TypeClass_LONG
+ je Lint32
+ cmp r9, typelib_TypeClass_UNSIGNED_LONG
+ je Lint32
+ cmp r9, typelib_TypeClass_ENUM
+ je Lint32
+
+ ; int8
+ cmp r9, typelib_TypeClass_BOOLEAN
+ je Lint8
+ cmp r9, typelib_TypeClass_BYTE
+ je Lint8
+
+ ; int16
+ cmp r9, typelib_TypeClass_CHAR
+ je Lint16
+ cmp r9, typelib_TypeClass_SHORT
+ je Lint16
+ cmp r9, typelib_TypeClass_UNSIGNED_SHORT
+ je Lint16
+
+ ; int64
+ cmp r9, typelib_TypeClass_HYPER
+ je Lint64
+ cmp r9, typelib_TypeClass_UNSIGNED_HYPER
+ je Lint64
+
+ ; float
+ cmp r9, typelib_TypeClass_FLOAT
+ je Lfloat
+
+ ; double
+ cmp r9, typelib_TypeClass_DOUBLE
+ je Ldouble
+
+ jmp Lepilog ; no simple type
+
+Lint8:
+ mov byte ptr [r8], al
+ jmp Lepilog
+
+Lint16:
+ mov word ptr [r8], ax
+ jmp Lepilog
+
+Lint32:
+ mov dword ptr [r8], eax
+ jmp Lepilog
+
+Lint64:
+ mov qword ptr [r8], rax
+ jmp Lepilog
+
+Lfloat:
+ movss dword ptr [r8], xmm0
+ jmp Lepilog
+
+Ldouble:
+ movsd qword ptr [r8], xmm0
+
+Lepilog:
+ ; Epilogue
+ add rsp, (20+1)*8
+ pop rdi
+ pop rsi
+ ret
+callVirtualMethod endp
+
+end
+
+; vim:set shiftwidth=4 softtabstop=4 expandtab:
diff --git a/bridges/source/cpp_uno/msvc_win32_x86-64/cpp2uno.cxx b/bridges/source/cpp_uno/msvc_win32_x86-64/cpp2uno.cxx
new file mode 100644
index 000000000000..a2310cbd8d7d
--- /dev/null
+++ b/bridges/source/cpp_uno/msvc_win32_x86-64/cpp2uno.cxx
@@ -0,0 +1,574 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_bridges.hxx"
+
+#include <malloc.h>
+
+#include <com/sun/star/uno/genfunc.hxx>
+#include <uno/data.h>
+#include <typelib/typedescription.hxx>
+
+#include "bridges/cpp_uno/shared/bridge.hxx"
+#include "bridges/cpp_uno/shared/cppinterfaceproxy.hxx"
+#include "bridges/cpp_uno/shared/types.hxx"
+#include "bridges/cpp_uno/shared/vtablefactory.hxx"
+
+#include "mscx.hxx"
+
+using namespace ::com::sun::star::uno;
+
+namespace
+{
+
+//==================================================================================================
+static inline typelib_TypeClass cpp2uno_call(
+ bridges::cpp_uno::shared::CppInterfaceProxy * pThis,
+ const typelib_TypeDescription * pMemberTypeDescr,
+ typelib_TypeDescriptionReference * pReturnTypeRef, // 0 indicates void return
+ sal_Int32 nParams, typelib_MethodParameter * pParams,
+ void ** pCallStack,
+ sal_Int64 * pRegisterReturn /* space for register return */ )
+{
+ // pCallStack: 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 (bridges::cpp_uno::shared::isSimpleType( pReturnTypeDescr ))
+ {
+ pUnoReturn = pRegisterReturn; // 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
+ }
+ }
+
+ // parameters
+ void ** pUnoArgs = (void **)alloca( 4 * sizeof(void *) * nParams );
+ void ** pCppArgs = pUnoArgs + nParams;
+ // indexes of values this have to be converted (interface conversion cpp<=>uno)
+ sal_Int64 * pTempIndexes = (sal_Int64 *)(pUnoArgs + (2 * nParams));
+ // type descriptions for reconversions
+ typelib_TypeDescription ** ppTempParamTypeDescr = (typelib_TypeDescription **)(pUnoArgs + (3 * nParams));
+
+ sal_Int32 nTempIndexes = 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_Int64); // extra qword
+ 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 );
+ pTempIndexes[nTempIndexes] = nPos;
+ // will be released at reconversion
+ ppTempParamTypeDescr[nTempIndexes++] = 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() );
+ pTempIndexes[nTempIndexes] = nPos; // has to be reconverted
+ // will be released at reconversion
+ ppTempParamTypeDescr[nTempIndexes++] = pParamTypeDescr;
+ }
+ else // direct way
+ {
+ pUnoArgs[nPos] = *(void **)pCppStack;
+ // no longer needed
+ TYPELIB_DANGER_RELEASE( pParamTypeDescr );
+ }
+ }
+ pCppStack += sizeof(sal_Int64); // 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 occurred...
+ if (pUnoExc)
+ {
+ // destruct temporary in/inout params
+ while (nTempIndexes--)
+ {
+ sal_Int32 nIndex = pTempIndexes[nTempIndexes];
+
+ if (pParams[nIndex].bIn) // is in/inout => was constructed
+ {
+ ::uno_destructData( pUnoArgs[nIndex], ppTempParamTypeDescr[nTempIndexes], 0 );
+ }
+ TYPELIB_DANGER_RELEASE( ppTempParamTypeDescr[nTempIndexes] );
+ }
+ if (pReturnTypeDescr)
+ {
+ TYPELIB_DANGER_RELEASE( pReturnTypeDescr );
+ }
+
+ CPPU_CURRENT_NAMESPACE::mscx_raiseException(
+ &aUnoExc, pThis->getBridge()->getUno2Cpp() );
+ // has to destruct the any
+ // is here for dummy
+ return typelib_TypeClass_VOID;
+ }
+ else // else no exception occurred...
+ {
+ // temporary params
+ while (nTempIndexes--)
+ {
+ sal_Int32 nIndex = pTempIndexes[nTempIndexes];
+ typelib_TypeDescription * pParamTypeDescr = ppTempParamTypeDescr[nTempIndexes];
+
+ 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
+ *(void **)pRegisterReturn = pCppReturn;
+ }
+ if (pReturnTypeDescr)
+ {
+ typelib_TypeClass eRet = (typelib_TypeClass)pReturnTypeDescr->eTypeClass;
+ TYPELIB_DANGER_RELEASE( pReturnTypeDescr );
+ return eRet;
+ }
+ else
+ return typelib_TypeClass_VOID;
+ }
+}
+
+//==================================================================================================
+typelib_TypeClass __cdecl cpp_mediate(
+ void ** pCallStack, sal_Int32 nFunctionIndex, sal_Int32 nVtableOffset,
+ sal_Int64 * pRegisterReturn /* space for register return */ )
+{
+ // pCallStack: ret adr, this, [ret *], params
+ void * pThis = static_cast< char * >(pCallStack[1]) - 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( RTL_CONSTASCII_USTRINGPARAM("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] );
+
+ typelib_TypeClass eRet;
+ switch (aMemberDescr.get()->eTypeClass)
+ {
+ case typelib_TypeClass_INTERFACE_ATTRIBUTE:
+ {
+ if (pTypeDescr->pMapMemberIndexToFunctionIndex[nMemberPos] == nFunctionIndex)
+ {
+ // is GET method
+ eRet = cpp2uno_call(
+ pCppI, aMemberDescr.get(),
+ ((typelib_InterfaceAttributeTypeDescription *)aMemberDescr.get())->pAttributeTypeRef,
+ 0, 0, // no params
+ pCallStack, pRegisterReturn );
+ }
+ else
+ {
+ // is SET method
+ typelib_MethodParameter aParam;
+ aParam.pTypeRef =
+ ((typelib_InterfaceAttributeTypeDescription *)aMemberDescr.get())->pAttributeTypeRef;
+ aParam.bIn = sal_True;
+ aParam.bOut = sal_False;
+
+ eRet = cpp2uno_call(
+ pCppI, aMemberDescr.get(),
+ 0, // indicates void return
+ 1, &aParam,
+ pCallStack, pRegisterReturn );
+ }
+ break;
+ }
+ case typelib_TypeClass_INTERFACE_METHOD:
+ {
+ // is METHOD
+ switch (nFunctionIndex)
+ {
+ // standard XInterface vtable calls
+ case 1: // acquire()
+ pCppI->acquireProxy(); // non virtual call!
+ eRet = typelib_TypeClass_VOID;
+ break;
+ case 2: // release()
+ pCppI->releaseProxy(); // non virtual call!
+ eRet = typelib_TypeClass_VOID;
+ break;
+ case 0: // queryInterface() opt
+ {
+ typelib_TypeDescription * pTD = 0;
+ TYPELIB_DANGER_GET( &pTD, reinterpret_cast< Type * >( pCallStack[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[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(
+ pCppI, aMemberDescr.get(),
+ ((typelib_InterfaceMethodTypeDescription *)aMemberDescr.get())->pReturnTypeRef,
+ ((typelib_InterfaceMethodTypeDescription *)aMemberDescr.get())->nParams,
+ ((typelib_InterfaceMethodTypeDescription *)aMemberDescr.get())->pParams,
+ pCallStack, pRegisterReturn );
+ }
+ break;
+ }
+ default:
+ {
+ throw RuntimeException(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("no member description found!") ),
+ (XInterface *)pThis );
+ // is here for dummy
+ eRet = typelib_TypeClass_VOID;
+ }
+ }
+
+ return eRet;
+}
+
+extern void *cpp_vtable_call;
+
+//==================================================================================================
+int const codeSnippetSize = 28;
+
+// This function generates the code that acts as a proxy for the UNO function to be called.
+// The generated code does the following:
+// - Save register parametrs.
+
+unsigned char * codeSnippet(
+ unsigned char * code, sal_Int32 functionIndex, sal_Int32 vtableOffset)
+{
+ unsigned char * p = code;
+
+ // mov eax, functionIndex:
+ *p++ = 0xB8;
+ *reinterpret_cast< sal_Int32 * >(p) = functionIndex;
+ p += sizeof (sal_Int32);
+
+ // mov edx, vtableOffset:
+ *p++ = 0xBA;
+ *reinterpret_cast< sal_Int32 * >(p) = vtableOffset;
+ p += sizeof (sal_Int32);
+
+#if 0
+ sub esp, 8 // space for immediate return type
+ push esp
+ push edx // vtable offset
+ push eax // function index
+ mov eax, esp
+ add eax, 20
+ push eax // original stack ptr
+
+ call cpp_mediate
+ add esp, 16
+
+ 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
+
+#endif
+
+#if 0
+ // jmp rel64 cpp_vtable_call:
+ *p++ = 0xE9;
+ *reinterpret_cast< sal_Int64 * >(p)
+ = ((unsigned char *) cpp_vtable_call) - p - sizeof (sal_Int64);
+ p += sizeof (sal_Int64);
+#endif
+ OSL_ASSERT(p - code <= codeSnippetSize);
+ return code + codeSnippetSize;
+}
+
+}
+
+struct bridges::cpp_uno::shared::VtableFactory::Slot { void * fn; };
+
+bridges::cpp_uno::shared::VtableFactory::Slot *
+bridges::cpp_uno::shared::VtableFactory::mapBlockToVtable(void * block)
+{
+ return static_cast< Slot * >(block) + 1;
+}
+
+sal_Size bridges::cpp_uno::shared::VtableFactory::getBlockSize(
+ sal_Int32 slotCount)
+{
+ return (slotCount + 1) * sizeof (Slot) + slotCount * codeSnippetSize;
+}
+
+bridges::cpp_uno::shared::VtableFactory::Slot *
+bridges::cpp_uno::shared::VtableFactory::initializeBlock(
+ void * block, sal_Int32 slotCount)
+{
+ struct Rtti {
+ sal_Int32 n0, n1, n2;
+ type_info * rtti;
+ Rtti():
+ n0(0), n1(0), n2(0),
+ rtti(CPPU_CURRENT_NAMESPACE::mscx_getRTTI(
+ rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
+ "com.sun.star.uno.XInterface"))))
+ {}
+ };
+ static Rtti rtti;
+
+ Slot * slots = mapBlockToVtable(block);
+ slots[-1].fn = &rtti;
+ return slots + slotCount;
+}
+
+#if 0
+
+#else
+
+static void whatthefuck(sal_Int64 i, ...)
+{
+ MessageBoxA (NULL, "Shit!", "whatthefuck in cpp2uno.cxx", MB_OK);
+}
+
+#endif
+
+unsigned char * bridges::cpp_uno::shared::VtableFactory::addLocalFunctions(
+ Slot ** slots, unsigned char * code,
+ typelib_InterfaceTypeDescription const * type, sal_Int32 functionOffset,
+ sal_Int32 functionCount, sal_Int32 vtableOffset)
+{
+ (*slots) -= functionCount;
+ Slot * s = *slots;
+
+ for (int i = 0; i < functionCount; ++i) {
+ typelib_TypeDescription * pTD = 0;
+
+ TYPELIB_DANGER_GET( &pTD, type->ppMembers[ i ] );
+ OSL_ASSERT( pTD );
+
+ CPPU_CURRENT_NAMESPACE::RegParamKind param_kind[4];
+ int nr = 0;
+
+ if ( pTD->eTypeClass == typelib_TypeClass_INTERFACE_ATTRIBUTE )
+ {
+ typelib_InterfaceAttributeTypeDescription *pAttrTD =
+ reinterpret_cast<typelib_InterfaceAttributeTypeDescription *>( pTD );
+
+ // get method
+#if 0
+ (s++)->fn = code;
+ code = codeSnippet(code, functionOffset++, vtableOffset);
+#else
+ (s++)->fn = whatthefuck;
+#endif
+
+ if ( ! pAttrTD->bReadOnly )
+ {
+ // set method
+#if 0
+ (s++)->fn = code;
+ code = codeSnippet(code, functionOffset++, vtableOffset);
+#else
+ (s++)->fn = whatthefuck;
+#endif
+ }
+ }
+ else if ( pTD->eTypeClass == typelib_TypeClass_INTERFACE_METHOD )
+ {
+ typelib_InterfaceMethodTypeDescription *pMethodTD =
+ reinterpret_cast<typelib_InterfaceMethodTypeDescription *>( pTD );
+
+ typelib_TypeDescription *pReturnTD = 0;
+ TYPELIB_DANGER_GET( &pReturnTD, pMethodTD->pReturnTypeRef );
+ OSL_ASSERT( pReturnTD );
+
+ if ( pReturnTD->nSize > 8 ) {
+ // Hidden return value
+ param_kind[nr++] = CPPU_CURRENT_NAMESPACE::REGPARAM_INT;
+ }
+ TYPELIB_DANGER_RELEASE( pReturnTD );
+
+ // 'this'
+ param_kind[nr++] = CPPU_CURRENT_NAMESPACE::REGPARAM_INT;
+
+ for (int j = 0; nr < 4 && j < pMethodTD->nParams; ++j)
+ {
+ typelib_TypeDescription *pParamTD = 0;
+
+ TYPELIB_DANGER_GET( &pParamTD, pMethodTD->pParams[j].pTypeRef );
+ OSL_ASSERT( pParamTD );
+
+ if ( pParamTD->eTypeClass == typelib_TypeClass_FLOAT ||
+ pParamTD->eTypeClass == typelib_TypeClass_DOUBLE )
+ param_kind[nr++] = CPPU_CURRENT_NAMESPACE::REGPARAM_FLT;
+ else
+ param_kind[nr++] = CPPU_CURRENT_NAMESPACE::REGPARAM_INT;
+
+ TYPELIB_DANGER_RELEASE( pParamTD );
+
+#if 0
+ (s++)->fn = code;
+ code = codeSnippet(code, functionOffset++, vtableOffset);
+#else
+ (s++)->fn = whatthefuck;
+#endif
+ }
+ }
+ else
+ OSL_ASSERT( false );
+ }
+ return code;
+}
+
+void bridges::cpp_uno::shared::VtableFactory::flushCode(
+ unsigned char const *, unsigned char const *)
+{}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/bridges/source/cpp_uno/msvc_win32_x86-64/dllinit.cxx b/bridges/source/cpp_uno/msvc_win32_x86-64/dllinit.cxx
new file mode 100644
index 000000000000..cfbc58650f0d
--- /dev/null
+++ b/bridges/source/cpp_uno/msvc_win32_x86-64/dllinit.cxx
@@ -0,0 +1,61 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_bridges.hxx"
+
+
+#pragma warning(push,1) // disable warnings within system headers
+#include <windows.h>
+#pragma warning(pop)
+
+
+void dso_init(void);
+void dso_exit(void);
+
+
+extern "C" BOOL WINAPI DllMain(HMODULE hModule, DWORD dwReason, LPVOID lpvReserved)
+{
+ switch(dwReason) {
+ case DLL_PROCESS_ATTACH:
+ DisableThreadLibraryCalls(hModule);
+
+ dso_init();
+ break;
+
+ case DLL_PROCESS_DETACH:
+ if (!lpvReserved)
+ dso_exit();
+ break;
+ }
+
+ return TRUE;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/bridges/source/cpp_uno/msvc_win32_x86-64/except.cxx b/bridges/source/cpp_uno/msvc_win32_x86-64/except.cxx
new file mode 100644
index 000000000000..bb5c5b1922b8
--- /dev/null
+++ b/bridges/source/cpp_uno/msvc_win32_x86-64/except.cxx
@@ -0,0 +1,623 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_bridges.hxx"
+
+#pragma warning( disable : 4237 )
+#include <hash_map>
+#include <sal/config.h>
+#include <malloc.h>
+#include <new.h>
+#include <typeinfo.h>
+#include <signal.h>
+
+#include "rtl/alloc.h"
+#include "rtl/strbuf.hxx"
+#include "rtl/ustrbuf.hxx"
+
+#include "com/sun/star/uno/Any.hxx"
+
+#include "mscx.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 OUString toUNOname( OUString const & rRTTIname ) throw ()
+{
+ OUStringBuffer aRet( 64 );
+ OUString aStr( rRTTIname.copy( 4, rRTTIname.getLength()-4-2 ) ); // filter .?AUzzz@yyy@xxx@@
+ sal_Int32 nPos = aStr.getLength();
+ while (nPos > 0)
+ {
+ sal_Int32 n = aStr.lastIndexOf( '@', nPos );
+ aRet.append( aStr.copy( n +1, nPos -n -1 ) );
+ if (n >= 0)
+ {
+ aRet.append( (sal_Unicode)'.' );
+ }
+ nPos = n;
+ }
+ return aRet.makeStringAndClear();
+}
+//==================================================================================================
+static inline OUString toRTTIname( OUString const & rUNOname ) throw ()
+{
+ OUStringBuffer aRet( 64 );
+ aRet.appendAscii( RTL_CONSTASCII_STRINGPARAM(".?AV") ); // class ".?AV"; struct ".?AU"
+ sal_Int32 nPos = rUNOname.getLength();
+ while (nPos > 0)
+ {
+ sal_Int32 n = rUNOname.lastIndexOf( '.', nPos );
+ aRet.append( rUNOname.copy( n +1, nPos -n -1 ) );
+ aRet.append( (sal_Unicode)'@' );
+ nPos = n;
+ }
+ aRet.append( (sal_Unicode)'@' );
+ return aRet.makeStringAndClear();
+}
+
+
+//##################################################################################################
+//#### RTTI simulation #############################################################################
+//##################################################################################################
+
+
+typedef hash_map< OUString, void *, OUStringHash, equal_to< OUString > > t_string2PtrMap;
+
+//==================================================================================================
+class RTTInfos
+{
+ Mutex _aMutex;
+ t_string2PtrMap _allRTTI;
+
+ static OUString toRawName( OUString const & rUNOname ) throw ();
+public:
+ type_info * getRTTI( OUString const & rUNOname ) throw ();
+
+ RTTInfos();
+ ~RTTInfos();
+};
+
+//==================================================================================================
+class __type_info
+{
+ friend type_info * RTTInfos::getRTTI( OUString const & ) throw ();
+ friend int mscx_filterCppException(
+ LPEXCEPTION_POINTERS, uno_Any *, uno_Mapping * );
+
+public:
+ virtual ~__type_info() throw ();
+
+ inline __type_info( void * m_data, const char * m_d_name ) throw ()
+ : _m_data( m_data )
+ { ::strcpy( _m_d_name, m_d_name ); } // #100211# - checked
+
+private:
+ void * _m_data;
+ char _m_d_name[1];
+};
+//__________________________________________________________________________________________________
+__type_info::~__type_info() throw ()
+{
+}
+//__________________________________________________________________________________________________
+type_info * RTTInfos::getRTTI( OUString const & rUNOname ) throw ()
+{
+ // a must be
+ OSL_ENSURE( sizeof(__type_info) == sizeof(type_info), "### type info structure size differ!" );
+
+ MutexGuard aGuard( _aMutex );
+ t_string2PtrMap::const_iterator const iFind( _allRTTI.find( rUNOname ) );
+
+ // check if type is already available
+ if (iFind == _allRTTI.end())
+ {
+ // insert new type_info
+ OString aRawName( OUStringToOString( toRTTIname( rUNOname ), RTL_TEXTENCODING_ASCII_US ) );
+ __type_info * pRTTI = new( ::rtl_allocateMemory( sizeof(__type_info) + aRawName.getLength() ) )
+ __type_info( NULL, aRawName.getStr() );
+
+ // put into map
+ pair< t_string2PtrMap::iterator, bool > insertion(
+ _allRTTI.insert( t_string2PtrMap::value_type( rUNOname, pRTTI ) ) );
+ OSL_ENSURE( insertion.second, "### rtti insertion failed?!" );
+
+ return (type_info *)pRTTI;
+ }
+ else
+ {
+ return (type_info *)iFind->second;
+ }
+}
+//__________________________________________________________________________________________________
+RTTInfos::RTTInfos() throw ()
+{
+}
+//__________________________________________________________________________________________________
+RTTInfos::~RTTInfos() throw ()
+{
+#if OSL_DEBUG_LEVEL > 1
+ OSL_TRACE( "> freeing generated RTTI infos... <\n" );
+#endif
+
+ 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
+
+ inline static void * operator new ( size_t nSize );
+ inline static void operator delete ( void * pMem );
+
+ ObjectFunction( typelib_TypeDescription * pTypeDescr, void * fpFunc ) throw ();
+ ~ObjectFunction() throw ();
+};
+
+inline void * ObjectFunction::operator new ( size_t nSize )
+{
+ void * pMem = rtl_allocateMemory( nSize );
+ if (pMem != 0)
+ {
+ DWORD old_protect;
+#if OSL_DEBUG_LEVEL > 0
+ BOOL success =
+#endif
+ VirtualProtect( pMem, nSize, PAGE_EXECUTE_READWRITE, &old_protect );
+ OSL_ENSURE( success, "VirtualProtect() failed!" );
+ }
+ return pMem;
+}
+
+inline void ObjectFunction::operator delete ( void * pMem )
+{
+ rtl_freeMemory( pMem );
+}
+
+//__________________________________________________________________________________________________
+ObjectFunction::ObjectFunction( typelib_TypeDescription * pTypeDescr, void * fpFunc ) throw ()
+ : _pTypeDescr( pTypeDescr )
+{
+ ::typelib_typedescription_acquire( _pTypeDescr );
+
+ unsigned char * pCode = (unsigned char *)somecode;
+ // a must be!
+ OSL_ENSURE( (void *)this == (void *)pCode, "### unexpected!" );
+
+ // push ObjectFunction this
+ *pCode++ = 0x68;
+ *(void **)pCode = this;
+ pCode += sizeof(void *);
+ // jmp rel64 fpFunc
+ *pCode++ = 0xe9;
+ *(sal_Int64 *)pCode = ((unsigned char *)fpFunc) - pCode - sizeof(sal_Int64);
+}
+//__________________________________________________________________________________________________
+ObjectFunction::~ObjectFunction() throw ()
+{
+ ::typelib_typedescription_release( _pTypeDescr );
+}
+
+//==================================================================================================
+void * __cdecl __copyConstruct( void * pExcThis, void * pSource, ObjectFunction * pThis )
+ throw ()
+{
+ ::uno_copyData( pExcThis, pSource, pThis->_pTypeDescr, cpp_acquire );
+ return pExcThis;
+}
+//==================================================================================================
+void * __cdecl __destruct( void * pExcThis, ObjectFunction * pThis )
+ throw ()
+{
+ ::uno_destructData( pExcThis, pThis->_pTypeDescr, cpp_release );
+ return pExcThis;
+}
+
+
+#if 0
+
+// These are machine code snippets in asmbits.asm
+
+extern void *copyConstruct;
+extern void *destruct;
+
+#else
+
+static void whatthefuck_copyctor(sal_Int64 i, ...)
+{
+ MessageBoxA (NULL, "Shit!", "whatthefuck_copyctor in except.cxx", MB_OK);
+}
+
+static void whatthefuck_dtor(sal_Int64 i, ...)
+{
+ MessageBoxA (NULL, "Shit!", "whatthefuck_dtor in except.cxx", MB_OK);
+}
+
+#endif
+
+//==================================================================================================
+struct ExceptionType
+{
+ sal_Int32 _n0;
+ type_info * _pTypeInfo;
+ sal_Int32 _n1, _n2, _n3, _n4;
+ ObjectFunction * _pCopyCtor;
+ sal_Int32 _n5;
+
+ inline ExceptionType( typelib_TypeDescription * pTypeDescr ) throw ()
+ : _n0( 0 )
+ , _n1( 0 )
+ , _n2( -1 )
+ , _n3( 0 )
+ , _n4( pTypeDescr->nSize )
+#if 0
+ , _pCopyCtor( new ObjectFunction( pTypeDescr, copyConstruct ) )
+#else
+ , _pCopyCtor( (ObjectFunction*) whatthefuck_copyctor )
+#endif
+ , _n5( 0 )
+ { _pTypeInfo = mscx_getRTTI( pTypeDescr->pTypeName ); }
+ inline ~ExceptionType() throw ()
+ { delete _pCopyCtor; }
+};
+//==================================================================================================
+struct RaiseInfo
+{
+ sal_Int32 _n0;
+ ObjectFunction * _pDtor;
+ sal_Int32 _n2;
+ void * _types;
+ sal_Int32 _n3, _n4;
+
+ RaiseInfo( typelib_TypeDescription * pTypeDescr ) throw ();
+ ~RaiseInfo() throw ();
+};
+//__________________________________________________________________________________________________
+RaiseInfo::RaiseInfo( typelib_TypeDescription * pTypeDescr ) throw ()
+ : _n0( 0 )
+#if 0
+ , _pDtor( new ObjectFunction( pTypeDescr, destruct ) )
+#else
+ , _pDtor( (ObjectFunction*) whatthefuck_dtor )
+#endif
+ , _n2( 0 )
+ , _n3( 0 )
+ , _n4( 0 )
+{
+ 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_Int64) + (sizeof(ExceptionType *) * nLen) );
+ *(sal_Int64 *)_types = nLen;
+
+ ExceptionType ** ppTypes = (ExceptionType **)((sal_Int64 *)_types + 1);
+
+ sal_Int32 nPos = 0;
+ for ( pCompTypeDescr = (typelib_CompoundTypeDescription*)pTypeDescr;
+ pCompTypeDescr; pCompTypeDescr = pCompTypeDescr->pBaseTypeDescription )
+ {
+ ppTypes[nPos++] = new ExceptionType( (typelib_TypeDescription *)pCompTypeDescr );
+ }
+}
+//__________________________________________________________________________________________________
+RaiseInfo::~RaiseInfo() throw ()
+{
+ ExceptionType ** ppTypes = (ExceptionType **)((sal_Int64 *)_types + 1);
+ for ( sal_Int32 nTypes = *(sal_Int64 *)_types; nTypes--; )
+ {
+ delete ppTypes[nTypes];
+ }
+ ::rtl_freeMemory( _types );
+
+ delete _pDtor;
+}
+
+//==================================================================================================
+class ExceptionInfos
+{
+ Mutex _aMutex;
+ t_string2PtrMap _allRaiseInfos;
+
+public:
+ static void * getRaiseInfo( typelib_TypeDescription * pTypeDescr ) throw ();
+
+ ExceptionInfos() throw ();
+ ~ExceptionInfos() throw ();
+};
+//__________________________________________________________________________________________________
+ExceptionInfos::ExceptionInfos() throw ()
+{
+}
+//__________________________________________________________________________________________________
+ExceptionInfos::~ExceptionInfos() throw ()
+{
+#if OSL_DEBUG_LEVEL > 1
+ OSL_TRACE( "> freeing exception infos... <\n" );
+#endif
+
+ MutexGuard aGuard( _aMutex );
+ for ( t_string2PtrMap::const_iterator iPos( _allRaiseInfos.begin() );
+ iPos != _allRaiseInfos.end(); ++iPos )
+ {
+ delete (RaiseInfo *)iPos->second;
+ }
+}
+//__________________________________________________________________________________________________
+void * ExceptionInfos::getRaiseInfo( typelib_TypeDescription * pTypeDescr ) throw ()
+{
+ 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
+ }
+ }
+
+ OSL_ASSERT( pTypeDescr &&
+ (pTypeDescr->eTypeClass == typelib_TypeClass_STRUCT ||
+ pTypeDescr->eTypeClass == typelib_TypeClass_EXCEPTION) );
+
+ void * pRaiseInfo;
+
+ OUString const & rTypeName = *reinterpret_cast< OUString * >( &pTypeDescr->pTypeName );
+ MutexGuard aGuard( s_pInfos->_aMutex );
+ t_string2PtrMap::const_iterator const iFind(
+ s_pInfos->_allRaiseInfos.find( rTypeName ) );
+ if (iFind == s_pInfos->_allRaiseInfos.end())
+ {
+ pRaiseInfo = new RaiseInfo( pTypeDescr );
+ // put into map
+ pair< t_string2PtrMap::iterator, bool > insertion(
+ s_pInfos->_allRaiseInfos.insert( t_string2PtrMap::value_type( rTypeName, pRaiseInfo ) ) );
+ OSL_ENSURE( insertion.second, "### raise info insertion failed?!" );
+ }
+ else
+ {
+ // reuse existing info
+ pRaiseInfo = iFind->second;
+ }
+
+ return pRaiseInfo;
+}
+
+
+//##################################################################################################
+//#### exported ####################################################################################
+//##################################################################################################
+
+
+//##################################################################################################
+type_info * mscx_getRTTI( OUString const & 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 mscx_raiseException( uno_Any * pUnoExc, uno_Mapping * pUno2Cpp )
+{
+ // no ctor/dtor in here: this leads to dtors called twice upon RaiseException()!
+ // thus this obj file will be compiled without opt, so no inling of
+ // ExceptionInfos::getRaiseInfo()
+
+ // construct cpp exception object
+ typelib_TypeDescription * pTypeDescr = 0;
+ TYPELIB_DANGER_GET( &pTypeDescr, pUnoExc->pType );
+
+ void * pCppExc = alloca( pTypeDescr->nSize );
+ ::uno_copyAndConvertData( pCppExc, pUnoExc->pData, pTypeDescr, pUno2Cpp );
+
+ ULONG_PTR arFilterArgs[3];
+ arFilterArgs[0] = MSVC_magic_number;
+ arFilterArgs[1] = (ULONG_PTR)pCppExc;
+ arFilterArgs[2] = (ULONG_PTR)ExceptionInfos::getRaiseInfo( pTypeDescr );
+
+ // destruct uno exception
+ ::uno_any_destruct( pUnoExc, 0 );
+ TYPELIB_DANGER_RELEASE( pTypeDescr );
+
+ // last point to release anything not affected by stack unwinding
+ RaiseException( MSVC_ExceptionCode, EXCEPTION_NONCONTINUABLE, 3, arFilterArgs );
+}
+
+//##############################################################################
+int mscx_filterCppException(
+ EXCEPTION_POINTERS * pPointers, uno_Any * pUnoExc, uno_Mapping * pCpp2Uno )
+{
+ if (pPointers == 0)
+ return EXCEPTION_CONTINUE_SEARCH;
+ EXCEPTION_RECORD * pRecord = pPointers->ExceptionRecord;
+ // handle only C++ exceptions:
+ if (pRecord == 0 || pRecord->ExceptionCode != MSVC_ExceptionCode)
+ return EXCEPTION_CONTINUE_SEARCH;
+
+ bool rethrow = __CxxDetectRethrow( &pRecord );
+ OSL_ASSERT( pRecord == pPointers->ExceptionRecord );
+
+ if (rethrow && pRecord == pPointers->ExceptionRecord)
+ {
+ // hack to get msvcrt internal _curexception field:
+ pRecord = *reinterpret_cast< EXCEPTION_RECORD ** >(
+ reinterpret_cast< char * >( __pxcptinfoptrs() ) +
+ // as long as we don't demand msvcr source as build prerequisite
+ // (->platform sdk), we have to code those offsets here.
+ //
+ // crt\src\mtdll.h:
+ // offsetof (_tiddata, _curexception) -
+ // offsetof (_tiddata, _tpxcptinfoptrs):
+#if _MSC_VER < 1500
+ error, this compiler version is not supported
+#elif _MSC_VER < 1600
+ 0x48 // msvcr90.dll
+#else
+ error, please find value for this compiler version
+#endif
+ );
+ }
+ // rethrow: handle only C++ exceptions:
+ if (pRecord == 0 || pRecord->ExceptionCode != MSVC_ExceptionCode)
+ return EXCEPTION_CONTINUE_SEARCH;
+
+ if (pRecord->NumberParameters == 3 &&
+// pRecord->ExceptionInformation[ 0 ] == MSVC_magic_number &&
+ pRecord->ExceptionInformation[ 1 ] != 0 &&
+ pRecord->ExceptionInformation[ 2 ] != 0)
+ {
+ void * types = reinterpret_cast< RaiseInfo * >(
+ pRecord->ExceptionInformation[ 2 ] )->_types;
+ if (types != 0 && *reinterpret_cast< DWORD * >( types ) > 0) // count
+ {
+ ExceptionType * pType = *reinterpret_cast< ExceptionType ** >(
+ reinterpret_cast< DWORD * >( types ) + 1 );
+ if (pType != 0 && pType->_pTypeInfo != 0)
+ {
+ OUString aRTTIname(
+ OStringToOUString(
+ reinterpret_cast< __type_info * >(
+ pType->_pTypeInfo )->_m_d_name,
+ RTL_TEXTENCODING_ASCII_US ) );
+ OUString aUNOname( toUNOname( aRTTIname ) );
+
+ typelib_TypeDescription * pExcTypeDescr = 0;
+ typelib_typedescription_getByName(
+ &pExcTypeDescr, aUNOname.pData );
+ if (pExcTypeDescr == 0)
+ {
+ OUStringBuffer buf;
+ buf.appendAscii(
+ RTL_CONSTASCII_STRINGPARAM(
+ "[mscx_uno bridge error] UNO type of "
+ "C++ exception unknown: \"") );
+ buf.append( aUNOname );
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(
+ "\", RTTI-name=\"") );
+ buf.append( aRTTIname );
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("\"!") );
+ RuntimeException exc(
+ buf.makeStringAndClear(), Reference< XInterface >() );
+ uno_type_any_constructAndConvert(
+ pUnoExc, &exc,
+ ::getCppuType( &exc ).getTypeLibType(), pCpp2Uno );
+#if _MSC_VER < 1400 // msvcr80.dll cleans up, different from former msvcrs
+ // if (! rethrow):
+ // though this unknown exception leaks now, no user-defined
+ // exception is ever thrown thru the binary C-UNO dispatcher
+ // call stack.
+#endif
+ }
+ else
+ {
+ // construct uno exception any
+ uno_any_constructAndConvert(
+ pUnoExc, (void *) pRecord->ExceptionInformation[1],
+ pExcTypeDescr, pCpp2Uno );
+#if _MSC_VER < 1400 // msvcr80.dll cleans up, different from former msvcrs
+ if (! rethrow)
+ {
+ uno_destructData(
+ (void *) pRecord->ExceptionInformation[1],
+ pExcTypeDescr, cpp_release );
+ }
+#endif
+ typelib_typedescription_release( pExcTypeDescr );
+ }
+
+ return EXCEPTION_EXECUTE_HANDLER;
+ }
+ }
+ }
+ // though this unknown exception leaks now, no user-defined exception
+ // is ever thrown thru the binary C-UNO dispatcher call stack.
+ RuntimeException exc(
+ OUString( RTL_CONSTASCII_USTRINGPARAM(
+ "[mscx_uno bridge error] unexpected "
+ "C++ exception occurred!") ),
+ Reference< XInterface >() );
+ uno_type_any_constructAndConvert(
+ pUnoExc, &exc, ::getCppuType( &exc ).getTypeLibType(), pCpp2Uno );
+ return EXCEPTION_EXECUTE_HANDLER;
+}
+
+}
+
+#pragma pack(pop)
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/bridges/source/cpp_uno/msvc_win32_x86-64/makefile.mk b/bridges/source/cpp_uno/msvc_win32_x86-64/makefile.mk
new file mode 100644
index 000000000000..604799a18e5a
--- /dev/null
+++ b/bridges/source/cpp_uno/msvc_win32_x86-64/makefile.mk
@@ -0,0 +1,82 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+
+PRJ=..$/..$/..
+
+PRJNAME=bridges
+TARGET=mscx_uno
+LIBTARGET=no
+ENABLE_EXCEPTIONS=TRUE
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : settings.mk
+
+# --- Files --------------------------------------------------------
+.IF "$(COM)$(CPU)" == "MSCX"
+
+.IF "$(debug)" != ""
+CFLAGS += -Ob0
+.ENDIF
+
+.IF "$(cppu_no_leak)" == ""
+.IF "$(bndchk)" == ""
+CFLAGS += -DLEAK_STATIC_DATA
+.ENDIF
+.ENDIF
+
+
+SLOFILES= \
+ $(SLO)$/cpp2uno.obj \
+ $(SLO)$/uno2cpp.obj \
+ $(SLO)$/dllinit.obj \
+ $(SLO)$/except.obj
+
+NOOPTFILES= \
+ $(SLO)$/except.obj
+
+SHL1TARGET= $(TARGET)
+
+SHL1DEF=$(MISC)$/$(SHL1TARGET).def
+SHL1IMPLIB=i$(TARGET)
+SHL1VERSIONMAP=..$/..$/bridge_exports.map
+SHL1RPATH=URELIB
+
+SHL1OBJS = $(SLOFILES)
+SHL1LIBS = $(SLB)$/cpp_uno_shared.lib
+
+SHL1STDLIBS= \
+ $(CPPULIB) \
+ $(SALLIB)
+
+DEF1NAME=$(SHL1TARGET)
+
+.ENDIF
+
+# --- Targets ------------------------------------------------------
+
+.INCLUDE : target.mk
diff --git a/bridges/source/cpp_uno/msvc_win32_x86-64/mscx.hxx b/bridges/source/cpp_uno/msvc_win32_x86-64/mscx.hxx
new file mode 100644
index 000000000000..044bd4bb1316
--- /dev/null
+++ b/bridges/source/cpp_uno/msvc_win32_x86-64/mscx.hxx
@@ -0,0 +1,62 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#pragma warning(push, 1)
+#include <windows.h>
+#pragma warning(pop)
+
+#include "rtl/ustring.hxx"
+
+
+class type_info;
+typedef struct _uno_Any uno_Any;
+typedef struct _uno_Mapping uno_Mapping;
+
+namespace CPPU_CURRENT_NAMESPACE
+{
+
+const DWORD MSVC_ExceptionCode = 0xe06d7363;
+const long MSVC_magic_number = 0x19930520L;
+
+typedef enum { REGPARAM_INT, REGPARAM_FLT } RegParamKind;
+
+
+//==============================================================================
+type_info * mscx_getRTTI( ::rtl::OUString const & rUNOname );
+
+//==============================================================================
+int mscx_filterCppException(
+ EXCEPTION_POINTERS * pPointers, uno_Any * pUnoExc, uno_Mapping * pCpp2Uno );
+
+//==============================================================================
+void mscx_raiseException(
+ uno_Any * pUnoExc, uno_Mapping * pUno2Cpp );
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/bridges/source/cpp_uno/msvc_win32_x86-64/uno2cpp.cxx b/bridges/source/cpp_uno/msvc_win32_x86-64/uno2cpp.cxx
new file mode 100644
index 000000000000..de6f5f212ec4
--- /dev/null
+++ b/bridges/source/cpp_uno/msvc_win32_x86-64/uno2cpp.cxx
@@ -0,0 +1,453 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_bridges.hxx"
+
+#include <malloc.h>
+
+#include <com/sun/star/uno/genfunc.hxx>
+#include <uno/data.h>
+
+#include "bridges/cpp_uno/shared/bridge.hxx"
+#include "bridges/cpp_uno/shared/types.hxx"
+#include "bridges/cpp_uno/shared/unointerfaceproxy.hxx"
+#include "bridges/cpp_uno/shared/vtables.hxx"
+
+#include "mscx.hxx"
+
+#if OSL_DEBUG_LEVEL > 1
+#include <stdio.h>
+#endif
+
+using namespace ::rtl;
+using namespace ::com::sun::star::uno;
+
+namespace
+{
+
+// As "long" is 32 bit also in x64 Windows we don't use "longs" in names
+// to indicate pointer-sized stack slots etc like in the other x64 archs,
+// but "qword" as in ml64.
+
+//==================================================================================================
+// In asmbits.asm
+extern void callVirtualMethod(
+ void * pAdjustedThisPtr, sal_Int32 nVtableIndex,
+ void * pReturn, typelib_TypeClass eReturnTypeClass,
+ sal_Int64 * pStack, sal_Int32 nStack,
+ sal_uInt64 *pGPR,
+ double *pFPR);
+
+#if OSL_DEBUG_LEVEL > 1
+inline void callVirtualMethodwrapper(
+ void * pAdjustedThisPtr, sal_Int32 nVtableIndex,
+ void * pReturn, typelib_TypeDescriptionReference * pReturnTypeRef,
+ sal_Int64 * pStack, sal_Int32 nStack,
+ sal_uInt64 *pGPR, sal_uInt32 nGPR,
+ double *pFPR, sal_uInt32 nFPR)
+{
+ // Let's figure out what is really going on here
+ {
+ fprintf( stderr, "= callVirtualMethod() =\nGPR's (%d): ", nGPR );
+ for ( unsigned int i = 0; i < nGPR; ++i )
+ fprintf( stderr, "0x%lx, ", pGPR[i] );
+ fprintf( stderr, "\nFPR's (%d): ", nFPR );
+ for ( unsigned int i = 0; i < nFPR; ++i )
+ fprintf( stderr, "%f, ", pFPR[i] );
+ fprintf( stderr, "\nStack (%d): ", nStack );
+ for ( unsigned int i = 0; i < nStack; ++i )
+ fprintf( stderr, "0x%lx, ", pStack[i] );
+ fprintf( stderr, "\n" );
+ }
+
+ callVirtualMethod( pAdjustedThisPtr, nVtableIndex,
+ pReturn, pReturnTypeRef->eTypeClass,
+ pStack, nStack,
+ pGPR,
+ pFPR);
+}
+
+#define callVirtualMethod callVirtualMethodwrapper
+
+#endif
+
+//==================================================================================================
+static void cpp_call(
+ bridges::cpp_uno::shared::UnoInterfaceProxy * pThis,
+ bridges::cpp_uno::shared::VtableSlot aVtableSlot,
+ typelib_TypeDescriptionReference * pReturnTypeRef,
+ sal_Int32 nParams, typelib_MethodParameter * pParams,
+ void * pUnoReturn, void * pUnoArgs[], uno_Any ** ppUnoExc ) throw ()
+{
+ const int MAXPARAMS = 20;
+
+ MessageBoxA (NULL, "Whoa!", "cpp_call in uno2cpp.cxx", MB_OK);
+
+ if (nParams > MAXPARAMS)
+ {
+ // We have a hard limit on the number of parameters so that we
+ // don't need any assembler stuff but can call the function
+ // using normal C++.
+
+ // What is the proper way to abort with at least some
+ // information given to the user?
+ abort();
+ }
+
+ // table with optional complex return value ptr, this pointer, and the parameters
+ union {
+ sal_Int64 i;
+ void *p;
+ double d;
+ } aCppParams[MAXPARAMS+2], uRetVal;
+ int nCppParamIndex = 0;
+
+ // Return type
+ typelib_TypeDescription * pReturnTypeDescr = 0;
+ TYPELIB_DANGER_GET( &pReturnTypeDescr, pReturnTypeRef );
+ OSL_ENSURE( pReturnTypeDescr, "### expected return type description!" );
+
+ bool bSimpleReturn = true;
+ if (pReturnTypeDescr)
+ {
+ if (pReturnTypeDescr->nSize > 8)
+ {
+ // complex return via ptr
+ bSimpleReturn = false;
+ aCppParams[nCppParamIndex++].p = alloca( pReturnTypeDescr->nSize );
+ }
+ }
+
+ // "this"
+ sal_Int64 * pCppThis = (sal_Int64 *) (pThis->getCppI()) + aVtableSlot.offset;
+ aCppParams[nCppParamIndex++].p = pCppThis;
+
+ // Indexes of values this have to be converted (interface conversion cpp<=>uno)
+ int pTempCppIndexes[MAXPARAMS];
+ int pTempIndexes[MAXPARAMS];
+ int nTempIndexes = 0;
+
+ // Type descriptions for reconversions
+ typelib_TypeDescription *pTempParamTypeDescr[MAXPARAMS];
+
+ for ( int 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 ))
+ {
+ ::uno_copyAndConvertData(
+ aCppParams[nCppParamIndex++].p, pUnoArgs[nPos], pParamTypeDescr,
+ pThis->getBridge()->getUno2Cpp() );
+
+ // 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(
+ aCppParams[nCppParamIndex].p = alloca( pParamTypeDescr->nSize ),
+ pParamTypeDescr );
+
+ pTempCppIndexes[nTempIndexes] = nCppParamIndex;
+ pTempIndexes[nTempIndexes] = nPos;
+
+ // will be released at reconversion
+ pTempParamTypeDescr[nTempIndexes++] = pParamTypeDescr;
+
+ nCppParamIndex++;
+ }
+ // is in/inout
+ else if (bridges::cpp_uno::shared::relatesToInterfaceType(
+ pParamTypeDescr ))
+ {
+ ::uno_copyAndConvertData(
+ aCppParams[nCppParamIndex].p = alloca( pParamTypeDescr->nSize ),
+ pUnoArgs[nPos], pParamTypeDescr,
+ pThis->getBridge()->getUno2Cpp() );
+
+ pTempCppIndexes[nTempIndexes] = nCppParamIndex;
+ pTempIndexes[nTempIndexes] = nPos;
+
+ // will be released at reconversion
+ pTempParamTypeDescr[nTempIndexes++] = pParamTypeDescr;
+
+ nCppParamIndex++;
+ }
+ else // direct way
+ {
+ aCppParams[nCppParamIndex++].p = pUnoArgs[nPos];
+ // no longer needed
+ TYPELIB_DANGER_RELEASE( pParamTypeDescr );
+ }
+ }
+ }
+
+ __try
+ {
+ // The first real parameter is always a pointer: either the
+ // address of where to store a complex return value or "this".
+
+ // The Windows x64 calling convention is very regular and
+ // elegant (even if perhaps then slightly slower than the
+ // Linux x64 one): The first four parameters, never more, are
+ // passed in registers, as long as they are a qword in size
+ // or less. (If larger, a pointer to a temp copy is passed, so
+ // it's equivalent anyway.) Floating point values are passed
+ // in XMM0..3 registers, others in RCX, RDX, R8, R9.
+
+ // Now, the nice thing for us is that when calling varargs
+ // functions, floating-point parameters among the four first
+ // ones are always passed *both* in an XMM and integer
+ // register. So we don't need to bother here calling the
+ // method different ways depending on what types of parameters
+ // it actually expects. We just pretend parameters 3..4 are
+ // doubles, and they will be passed both in XMM and integer
+ // registers, and the callee will find them where it
+ // expects. (The callee is not actually varargs, of course.)
+
+ sal_Int64 (*pMethod)(sal_Int64, ...) =
+ (sal_Int64 (*)(sal_Int64, ...))
+ (((sal_Int64 *)pCppThis) + aVtableSlot.index);
+
+ // Pass parameters 2..4 as double so that it gets put in both XMM and integer
+ // registers per the
+ uRetVal.i =
+ pMethod (aCppParams[0].i, aCppParams[1].d, aCppParams[2].d, aCppParams[3].d,
+ aCppParams[4].i, aCppParams[5].i, aCppParams[6].i, aCppParams[7].i,
+ aCppParams[8].i, aCppParams[9].i, aCppParams[10].i, aCppParams[11].i,
+ aCppParams[12].i, aCppParams[13].i, aCppParams[14].i, aCppParams[15].i,
+ aCppParams[16].i, aCppParams[17].i, aCppParams[18].i, aCppParams[19].i );
+ }
+ __except (CPPU_CURRENT_NAMESPACE::mscx_filterCppException(
+ GetExceptionInformation(),
+ *ppUnoExc, pThis->getBridge()->getCpp2Uno() ))
+ {
+ // *ppUnoExc was constructed by filter function
+ // temporary params
+ while (nTempIndexes--)
+ {
+ int nCppIndex = pTempCppIndexes[nTempIndexes];
+ // destroy temp cpp param => cpp: every param was constructed
+ ::uno_destructData(
+ aCppParams[nCppIndex].p, pTempParamTypeDescr[nTempIndexes],
+ cpp_release );
+ TYPELIB_DANGER_RELEASE( pTempParamTypeDescr[nTempIndexes] );
+ }
+ // return type
+ if (pReturnTypeDescr)
+ {
+ TYPELIB_DANGER_RELEASE( pReturnTypeDescr );
+ }
+ // end here
+ return;
+ }
+
+ // NO exception occurred
+ *ppUnoExc = 0;
+
+ // Reconvert temporary params
+ while (nTempIndexes--)
+ {
+ int nCppIndex = pTempCppIndexes[nTempIndexes];
+ int nIndex = pTempIndexes[nTempIndexes];
+ typelib_TypeDescription * pParamTypeDescr =
+ pTempParamTypeDescr[nTempIndexes];
+
+ if (pParams[nIndex].bIn)
+ {
+ if (pParams[nIndex].bOut) // inout
+ {
+ ::uno_destructData(
+ pUnoArgs[nIndex], pParamTypeDescr, 0 ); // destroy uno value
+ ::uno_copyAndConvertData(
+ pUnoArgs[nIndex], aCppParams[nCppIndex].p, pParamTypeDescr,
+ pThis->getBridge()->getCpp2Uno() );
+ }
+ }
+ else // pure out
+ {
+ ::uno_copyAndConvertData(
+ pUnoArgs[nIndex], aCppParams[nCppIndex].p, pParamTypeDescr,
+ pThis->getBridge()->getCpp2Uno() );
+ }
+ // destroy temp cpp param => cpp: every param was constructed
+ ::uno_destructData(
+ aCppParams[nCppIndex].p, pParamTypeDescr, cpp_release );
+
+ TYPELIB_DANGER_RELEASE( pParamTypeDescr );
+ }
+ // return value
+ if (!bSimpleReturn)
+ {
+ ::uno_copyAndConvertData(
+ pUnoReturn, uRetVal.p, pReturnTypeDescr,
+ pThis->getBridge()->getCpp2Uno() );
+ ::uno_destructData(
+ aCppParams[0].p, pReturnTypeDescr, cpp_release );
+ }
+ // return type
+ if (pReturnTypeDescr)
+ {
+ TYPELIB_DANGER_RELEASE( pReturnTypeDescr );
+ }
+}
+
+}
+
+namespace bridges { namespace cpp_uno { namespace shared {
+
+void unoInterfaceProxyDispatch(
+ uno_Interface * pUnoI, const typelib_TypeDescription * pMemberDescr,
+ void * pReturn, void * pArgs[], uno_Any ** ppException )
+{
+ // is my surrogate
+ bridges::cpp_uno::shared::UnoInterfaceProxy * pThis
+ = static_cast< bridges::cpp_uno::shared::UnoInterfaceProxy * >(pUnoI);
+
+ switch (pMemberDescr->eTypeClass)
+ {
+ case typelib_TypeClass_INTERFACE_ATTRIBUTE:
+ {
+ VtableSlot aVtableSlot(
+ getVtableSlot(
+ reinterpret_cast<
+ typelib_InterfaceAttributeTypeDescription const * >(
+ pMemberDescr)));
+ if (pReturn)
+ {
+ // dependent dispatch
+ cpp_call(
+ pThis, aVtableSlot,
+ ((typelib_InterfaceAttributeTypeDescription *)pMemberDescr)->pAttributeTypeRef,
+ 0, 0, // no params
+ pReturn, pArgs, ppException );
+ }
+ else
+ {
+ // is SET
+ typelib_MethodParameter aParam;
+ aParam.pTypeRef =
+ ((typelib_InterfaceAttributeTypeDescription *)pMemberDescr)->pAttributeTypeRef;
+ aParam.bIn = sal_True;
+ aParam.bOut = sal_False;
+
+ typelib_TypeDescriptionReference * pReturnTypeRef = 0;
+ OUString aVoidName( RTL_CONSTASCII_USTRINGPARAM("void") );
+ typelib_typedescriptionreference_new(
+ &pReturnTypeRef, typelib_TypeClass_VOID, aVoidName.pData );
+
+ // dependent dispatch
+ aVtableSlot.index += 1; // get, then set method
+ cpp_call(
+ pThis, aVtableSlot,
+ pReturnTypeRef,
+ 1, &aParam,
+ pReturn, pArgs, ppException );
+
+ typelib_typedescriptionreference_release( pReturnTypeRef );
+ }
+
+ break;
+ }
+ case typelib_TypeClass_INTERFACE_METHOD:
+ {
+ VtableSlot aVtableSlot(
+ getVtableSlot(
+ reinterpret_cast<
+ typelib_InterfaceMethodTypeDescription const * >(
+ pMemberDescr)));
+ switch (aVtableSlot.index)
+ {
+ // standard calls
+ case 1: // acquire uno interface
+ (*pUnoI->acquire)( pUnoI );
+ *ppException = 0;
+ break;
+ case 2: // release uno interface
+ (*pUnoI->release)( pUnoI );
+ *ppException = 0;
+ break;
+ case 0: // queryInterface() opt
+ {
+ typelib_TypeDescription * pTD = 0;
+ TYPELIB_DANGER_GET( &pTD, reinterpret_cast< Type * >( pArgs[0] )->getTypeLibType() );
+ if (pTD)
+ {
+ uno_Interface * pInterface = 0;
+ (*pThis->pBridge->getUnoEnv()->getRegisteredInterface)(
+ pThis->pBridge->getUnoEnv(),
+ (void **)&pInterface, pThis->oid.pData, (typelib_InterfaceTypeDescription *)pTD );
+
+ if (pInterface)
+ {
+ ::uno_any_construct(
+ reinterpret_cast< uno_Any * >( pReturn ),
+ &pInterface, pTD, 0 );
+ (*pInterface->release)( pInterface );
+ TYPELIB_DANGER_RELEASE( pTD );
+ *ppException = 0;
+ break;
+ }
+ TYPELIB_DANGER_RELEASE( pTD );
+ }
+ } // else perform queryInterface()
+ default:
+ // dependent dispatch
+ cpp_call(
+ pThis, aVtableSlot,
+ ((typelib_InterfaceMethodTypeDescription *)pMemberDescr)->pReturnTypeRef,
+ ((typelib_InterfaceMethodTypeDescription *)pMemberDescr)->nParams,
+ ((typelib_InterfaceMethodTypeDescription *)pMemberDescr)->pParams,
+ pReturn, pArgs, ppException );
+ }
+ break;
+ }
+ default:
+ {
+ ::com::sun::star::uno::RuntimeException aExc(
+ OUString( RTL_CONSTASCII_USTRINGPARAM("illegal member type description!") ),
+ ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >() );
+
+ Type const & rExcType = ::getCppuType( &aExc );
+ // binary identical null reference
+ ::uno_type_any_construct( *ppException, &aExc, rExcType.getTypeLibType(), 0 );
+ }
+ }
+}
+
+} } }
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */