summaryrefslogtreecommitdiff
path: root/bridges/source/cpp_uno/msvc_win32_x86-64
diff options
context:
space:
mode:
authorTor Lillqvist <tlillqvist@novell.com>2011-01-20 02:36:55 +0200
committerTor Lillqvist <tlillqvist@novell.com>2011-01-20 02:39:23 +0200
commit266c2d6b349be355560ba6dbf782cebbc4de8609 (patch)
treeca8950d9dd2c33dbfa78a23036ba14d766848db1 /bridges/source/cpp_uno/msvc_win32_x86-64
parent7a042510db17b37d9afab7be992bf61d2bc14fbe (diff)
More hacking on the wntmscx bridge, still far from ready
See asmbits.asm for some general comments and pointers to useful information.
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.cxx82
-rw-r--r--bridges/source/cpp_uno/msvc_win32_x86-64/except.cxx79
-rw-r--r--bridges/source/cpp_uno/msvc_win32_x86-64/makefile.mk4
-rw-r--r--bridges/source/cpp_uno/msvc_win32_x86-64/uno2cpp.cxx167
5 files changed, 433 insertions, 227 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..29e75ff38845
--- /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 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
index b84da9e866ed..d3a445bed2c1 100644
--- a/bridges/source/cpp_uno/msvc_win32_x86-64/cpp2uno.cxx
+++ b/bridges/source/cpp_uno/msvc_win32_x86-64/cpp2uno.cxx
@@ -87,13 +87,11 @@ static inline typelib_TypeClass cpp2uno_call(
}
}
- // stack space
- OSL_ENSURE( sizeof(void *) == sizeof(sal_Int32), "### unexpected size!" );
// parameters
void ** pUnoArgs = (void **)alloca( 4 * sizeof(void *) * nParams );
void ** pCppArgs = pUnoArgs + nParams;
// indizes of values this have to be converted (interface conversion cpp<=>uno)
- sal_Int32 * pTempIndizes = (sal_Int32 *)(pUnoArgs + (2 * nParams));
+ sal_Int64 * pTempIndizes = (sal_Int64 *)(pUnoArgs + (2 * nParams));
// type descriptions for reconversions
typelib_TypeDescription ** ppTempParamTypeDescr = (typelib_TypeDescription **)(pUnoArgs + (3 * nParams));
@@ -116,7 +114,7 @@ static inline typelib_TypeClass cpp2uno_call(
case typelib_TypeClass_HYPER:
case typelib_TypeClass_UNSIGNED_HYPER:
case typelib_TypeClass_DOUBLE:
- pCppStack += sizeof(sal_Int32); // extra long
+ pCppStack += sizeof(sal_Int64); // extra qword
break;
default:
break;
@@ -155,7 +153,7 @@ static inline typelib_TypeClass cpp2uno_call(
TYPELIB_DANGER_RELEASE( pParamTypeDescr );
}
}
- pCppStack += sizeof(sal_Int32); // standard parameter length
+ pCppStack += sizeof(sal_Int64); // standard parameter length
}
// ExceptionHolder
@@ -240,12 +238,10 @@ static inline typelib_TypeClass cpp2uno_call(
}
//==================================================================================================
-static typelib_TypeClass __cdecl cpp_mediate(
+typelib_TypeClass __cdecl cpp_mediate(
void ** pCallStack, sal_Int32 nFunctionIndex, sal_Int32 nVtableOffset,
sal_Int64 * pRegisterReturn /* space for register return */ )
{
- OSL_ENSURE( sizeof(sal_Int32)==sizeof(void *), "### unexpected!" );
-
// pCallStack: ret adr, this, [ret *], params
void * pThis = static_cast< char * >(pCallStack[1]) - nVtableOffset;
bridges::cpp_uno::shared::CppInterfaceProxy * pCppI
@@ -361,74 +357,28 @@ static typelib_TypeClass __cdecl cpp_mediate(
return eRet;
}
-//==================================================================================================
-/**
- * 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 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
- }
-}
+extern void *cpp_vtable_call;
//==================================================================================================
-int const codeSnippetSize = 16;
+int const codeSnippetSize = 28;
unsigned char * codeSnippet(
unsigned char * code, sal_Int32 functionIndex, sal_Int32 vtableOffset)
{
unsigned char * p = code;
- OSL_ASSERT(sizeof (sal_Int32) == 4);
- // mov eax, functionIndex:
+ // mov rax, functionIndex:
*p++ = 0xB8;
- *reinterpret_cast< sal_Int32 * >(p) = functionIndex;
- p += sizeof (sal_Int32);
- // mov edx, vtableOffset:
+ *reinterpret_cast< sal_Int64 * >(p) = functionIndex;
+ p += sizeof (sal_Int64);
+ // mov rdx, vtableOffset:
*p++ = 0xBA;
- *reinterpret_cast< sal_Int32 * >(p) = vtableOffset;
- p += sizeof (sal_Int32);
- // jmp rel32 cpp_vtable_call:
+ *reinterpret_cast< sal_Int64 * >(p) = vtableOffset;
+ p += sizeof (sal_Int64);
+ // jmp rel64 cpp_vtable_call:
*p++ = 0xE9;
- *reinterpret_cast< sal_Int32 * >(p)
- = ((unsigned char *) cpp_vtable_call) - p - sizeof (sal_Int32);
- p += sizeof (sal_Int32);
+ *reinterpret_cast< sal_Int64 * >(p)
+ = ((unsigned char *) cpp_vtable_call) - p - sizeof (sal_Int64);
+ p += sizeof (sal_Int64);
OSL_ASSERT(p - code <= codeSnippetSize);
return code + codeSnippetSize;
}
diff --git a/bridges/source/cpp_uno/msvc_win32_x86-64/except.cxx b/bridges/source/cpp_uno/msvc_win32_x86-64/except.cxx
index 8894c5b1cbad..c7fea183d91f 100644
--- a/bridges/source/cpp_uno/msvc_win32_x86-64/except.cxx
+++ b/bridges/source/cpp_uno/msvc_win32_x86-64/except.cxx
@@ -238,9 +238,9 @@ ObjectFunction::ObjectFunction( typelib_TypeDescription * pTypeDescr, void * fpF
*pCode++ = 0x68;
*(void **)pCode = this;
pCode += sizeof(void *);
- // jmp rel32 fpFunc
+ // jmp rel64 fpFunc
*pCode++ = 0xe9;
- *(sal_Int32 *)pCode = ((unsigned char *)fpFunc) - pCode - sizeof(sal_Int32);
+ *(sal_Int64 *)pCode = ((unsigned char *)fpFunc) - pCode - sizeof(sal_Int64);
}
//__________________________________________________________________________________________________
ObjectFunction::~ObjectFunction() throw ()
@@ -249,47 +249,25 @@ ObjectFunction::~ObjectFunction() throw ()
}
//==================================================================================================
-static void * __cdecl __copyConstruct( void * pExcThis, void * pSource, ObjectFunction * pThis )
+void * __cdecl __copyConstruct( void * pExcThis, void * pSource, ObjectFunction * pThis )
throw ()
{
::uno_copyData( pExcThis, pSource, pThis->_pTypeDescr, cpp_acquire );
return pExcThis;
}
//==================================================================================================
-static void * __cdecl __destruct( void * pExcThis, ObjectFunction * pThis )
+void * __cdecl __destruct( void * pExcThis, ObjectFunction * pThis )
throw ()
{
::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) void copyConstruct() throw ()
-{
- __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) void destruct() throw ()
-{
- __asm
- {
- // ObjectFunction this already on stack
- push ecx // exc object
- call __destruct
- add esp, 8 // + ObjectFunction this
- ret
- }
-}
+// These are machine code snippets in asmbits.asm
+
+extern void *copyConstruct;
+extern void *destruct;
//==================================================================================================
struct ExceptionType
@@ -332,9 +310,6 @@ RaiseInfo::RaiseInfo( typelib_TypeDescription * pTypeDescr ) throw ()
, _n3( 0 )
, _n4( 0 )
{
- // a must be
- OSL_ENSURE( sizeof(sal_Int32) == sizeof(ExceptionType *), "### pointer size differs from sal_Int32!" );
-
typelib_CompoundTypeDescription * pCompTypeDescr;
// info count
@@ -346,10 +321,10 @@ RaiseInfo::RaiseInfo( typelib_TypeDescription * pTypeDescr ) throw ()
}
// 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;
+ _types = ::rtl_allocateMemory( sizeof(sal_Int64) + (sizeof(ExceptionType *) * nLen) );
+ *(sal_Int64 *)_types = nLen;
- ExceptionType ** ppTypes = (ExceptionType **)((sal_Int32 *)_types + 1);
+ ExceptionType ** ppTypes = (ExceptionType **)((sal_Int64 *)_types + 1);
sal_Int32 nPos = 0;
for ( pCompTypeDescr = (typelib_CompoundTypeDescription*)pTypeDescr;
@@ -361,8 +336,8 @@ RaiseInfo::RaiseInfo( typelib_TypeDescription * pTypeDescr ) throw ()
//__________________________________________________________________________________________________
RaiseInfo::~RaiseInfo() throw ()
{
- ExceptionType ** ppTypes = (ExceptionType **)((sal_Int32 *)_types + 1);
- for ( sal_Int32 nTypes = *(sal_Int32 *)_types; nTypes--; )
+ ExceptionType ** ppTypes = (ExceptionType **)((sal_Int64 *)_types + 1);
+ for ( sal_Int32 nTypes = *(sal_Int64 *)_types; nTypes--; )
{
delete ppTypes[nTypes];
}
@@ -486,14 +461,10 @@ void mscx_raiseException( uno_Any * pUnoExc, uno_Mapping * pUno2Cpp )
void * pCppExc = alloca( pTypeDescr->nSize );
::uno_copyAndConvertData( pCppExc, pUnoExc->pData, pTypeDescr, pUno2Cpp );
- // a must be
- OSL_ENSURE(
- sizeof(sal_Int32) == sizeof(void *),
- "### pointer size differs from sal_Int32!" );
- DWORD arFilterArgs[3];
+ ULONG_PTR arFilterArgs[3];
arFilterArgs[0] = MSVC_magic_number;
- arFilterArgs[1] = (DWORD)pCppExc;
- arFilterArgs[2] = (DWORD)ExceptionInfos::getRaiseInfo( pTypeDescr );
+ arFilterArgs[1] = (ULONG_PTR)pCppExc;
+ arFilterArgs[2] = (ULONG_PTR)ExceptionInfos::getRaiseInfo( pTypeDescr );
// destruct uno exception
::uno_any_destruct( pUnoExc, 0 );
@@ -514,13 +485,9 @@ int mscx_filterCppException(
if (pRecord == 0 || pRecord->ExceptionCode != MSVC_ExceptionCode)
return EXCEPTION_CONTINUE_SEARCH;
-#if _MSC_VER < 1300 // MSVC -6
- bool rethrow = (pRecord->NumberParameters < 3 ||
- pRecord->ExceptionInformation[ 2 ] == 0);
-#else
bool rethrow = __CxxDetectRethrow( &pRecord );
OSL_ASSERT( pRecord == pPointers->ExceptionRecord );
-#endif
+
if (rethrow && pRecord == pPointers->ExceptionRecord)
{
// hack to get msvcrt internal _curexception field:
@@ -532,14 +499,12 @@ int mscx_filterCppException(
// crt\src\mtdll.h:
// offsetof (_tiddata, _curexception) -
// offsetof (_tiddata, _tpxcptinfoptrs):
-#if _MSC_VER < 1300
- 0x18 // msvcrt,dll
-#elif _MSC_VER < 1310
- 0x20 // msvcr70.dll
-#elif _MSC_VER < 1400
- 0x24 // msvcr71.dll
+#if _MSC_VER < 1500
+ error, this compiler version is not supported
+#elif _MSC_VER < 1600
+ 0x48 // msvcr90.dll
#else
- 0x28 // msvcr80.dll
+ error, please find value for this compiler version
#endif
);
}
diff --git a/bridges/source/cpp_uno/msvc_win32_x86-64/makefile.mk b/bridges/source/cpp_uno/msvc_win32_x86-64/makefile.mk
index d8e760cb598c..44ea288e8cb5 100644
--- a/bridges/source/cpp_uno/msvc_win32_x86-64/makefile.mk
+++ b/bridges/source/cpp_uno/msvc_win32_x86-64/makefile.mk
@@ -54,7 +54,8 @@ SLOFILES= \
$(SLO)$/cpp2uno.obj \
$(SLO)$/uno2cpp.obj \
$(SLO)$/dllinit.obj \
- $(SLO)$/except.obj
+ $(SLO)$/except.obj \
+ $(SLO)$/asmbits.obj
NOOPTFILES= \
$(SLO)$/except.obj
@@ -80,4 +81,3 @@ DEF1NAME=$(SHL1TARGET)
# --- Targets ------------------------------------------------------
.INCLUDE : target.mk
-
diff --git a/bridges/source/cpp_uno/msvc_win32_x86-64/uno2cpp.cxx b/bridges/source/cpp_uno/msvc_win32_x86-64/uno2cpp.cxx
index f112b1a15f16..74b55397e6e8 100644
--- a/bridges/source/cpp_uno/msvc_win32_x86-64/uno2cpp.cxx
+++ b/bridges/source/cpp_uno/msvc_win32_x86-64/uno2cpp.cxx
@@ -47,106 +47,52 @@ 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.
+
//==================================================================================================
-inline static void callVirtualMethod(
+// In asmbits.asm
+extern void callVirtualMethod(
void * pAdjustedThisPtr, 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
+ void * pReturn, typelib_TypeClass eReturnTypeClass,
+ sal_Int64 * pStack, sal_Int32 nStack,
+ sal_uInt64 *pGPR,
+ double *pFPR);
- OSL_ENSURE( pStackLongs && pAdjustedThisPtr, "### null ptr!" );
- OSL_ENSURE( (sizeof(void *) == 4) &&
- (sizeof(sal_Int32) == 4), "### unexpected size of int!" );
-
-__asm
+#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
{
- 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, pAdjustedThisPtr
- 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
+ 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,
@@ -156,16 +102,33 @@ static void cpp_call(
void * pUnoReturn, void * pUnoArgs[], uno_Any ** ppUnoExc ) throw ()
{
// max space for: [complex ret ptr], values|ptr ...
- char * pCppStack = (char *)alloca( sizeof(sal_Int32) + (nParams * sizeof(sal_Int64)) );
+ // (but will be used less - some of the values will be in pGPR and pFPR)
+ sal_uInt64 *pStack = (sal_uInt64 *) alloca( (nParams + 3) * sizeof(sal_uInt64) );
+ sal_uInt64 *pStackStart = pStack;
+
+ // Parameters to be passed in registers stored here
+ sal_uInt64 pGPR[4];
+ sal_uInt32 nGPR = 0;
+ double pFPR[4];
+ sal_uInt32 nFPR = 0;
+
+ if (nParams > 20)
+ {
+
+ }
+
+
+ char * pCppStack = (char *)alloca( sizeof(sal_Int64) + (nParams * sizeof(sal_Int64)) );
char * pCppStackStart = pCppStack;
- // return
+ // Return
typelib_TypeDescription * pReturnTypeDescr = 0;
TYPELIB_DANGER_GET( &pReturnTypeDescr, pReturnTypeRef );
OSL_ENSURE( pReturnTypeDescr, "### expected return type description!" );
void * pCppReturn = 0; // if != 0 && != pUnoReturn, needs reconversion
+ bool bSimpleReturn = true;
if (pReturnTypeDescr)
{
if (bridges::cpp_uno::shared::isSimpleType( pReturnTypeDescr ))
@@ -186,15 +149,15 @@ static void cpp_call(
// stack space
- OSL_ENSURE( sizeof(void *) == sizeof(sal_Int32), "### unexpected size!" );
+ OSL_ENSURE( sizeof(void *) == sizeof(sal_Int64), "### unexpected size!" );
// args
- void ** pCppArgs = (void **)alloca( 3 * sizeof(void *) * nParams );
+ 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;
+ sal_Int32 nTempIndizes = 0;
for ( sal_Int32 nPos = 0; nPos < nParams; ++nPos )
{
@@ -214,7 +177,7 @@ static void cpp_call(
case typelib_TypeClass_HYPER:
case typelib_TypeClass_UNSIGNED_HYPER:
case typelib_TypeClass_DOUBLE:
- pCppStack += sizeof(sal_Int32); // extra long
+ pCppStack += sizeof(sal_Int64); // extra qword
break;
default:
break;
@@ -254,7 +217,7 @@ static void cpp_call(
TYPELIB_DANGER_RELEASE( pParamTypeDescr );
}
}
- pCppStack += sizeof(sal_Int32); // standard parameter length
+ pCppStack += sizeof(sal_Int64); // standard parameter length
}
__try
@@ -264,8 +227,8 @@ static void cpp_call(
reinterpret_cast< void ** >(pThis->getCppI()) + aVtableSlot.offset,
aVtableSlot.index,
pCppReturn, pReturnTypeDescr->eTypeClass,
- (sal_Int32 *)pCppStackStart,
- (pCppStack - pCppStackStart) / sizeof(sal_Int32) );
+ (sal_Int64 *)pCppStackStart,
+ (pCppStack - pCppStackStart) / sizeof(sal_Int64) );
}
__except (CPPU_CURRENT_NAMESPACE::mscx_filterCppException(
GetExceptionInformation(),