[Libreoffice-commits] .: bridges/source

Tor Lillqvist tml at kemper.freedesktop.org
Thu Jan 27 13:42:56 PST 2011


 bridges/source/cpp_uno/msvc_win32_x86-64/asmbits.asm     |  328 ---------
 bridges/source/cpp_uno/msvc_win32_x86-64/codeSnippet.asm |  186 +++++
 bridges/source/cpp_uno/msvc_win32_x86-64/cpp2uno.cxx     |  542 +++++++--------
 bridges/source/cpp_uno/msvc_win32_x86-64/makefile.mk     |   11 
 bridges/source/cpp_uno/shared/vtablefactory.cxx          |    5 
 5 files changed, 468 insertions(+), 604 deletions(-)

New commits:
commit c56eed9e44b97a86cad82ea801beaa4d97f57c2f
Author: Tor Lillqvist <tlillqvist at novell.com>
Date:   Thu Jan 27 15:44:09 2011 +0200

    More work on the x64 Windows C++-UNO bridge

diff --git a/bridges/source/cpp_uno/msvc_win32_x86-64/asmbits.asm b/bridges/source/cpp_uno/msvc_win32_x86-64/asmbits.asm
deleted file mode 100644
index 09f1177..0000000
--- a/bridges/source/cpp_uno/msvc_win32_x86-64/asmbits.asm
+++ /dev/null
@@ -1,328 +0,0 @@
-; -*- 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/codeSnippet.asm b/bridges/source/cpp_uno/msvc_win32_x86-64/codeSnippet.asm
new file mode 100644
index 0000000..30322d3
--- /dev/null
+++ b/bridges/source/cpp_uno/msvc_win32_x86-64/codeSnippet.asm
@@ -0,0 +1,186 @@
+; -*- Mode: text; tab-width: 8; indent-tabs-mode: nil comment-column: 44; comment-start: ";; " comment-start-skip: ";; *" -*-
+
+;; Version: MPL 1.1 / GPLv3+ / LGPLv3+
+;;
+;; The contents of this file are subject to the Mozilla Public License Version
+;; 1.1 (the "License"); you may not use this file except in compliance with
+;; the License or as specified alternatively below. You may obtain a copy of
+;; the License at http://www.mozilla.org/MPL/
+;;
+;; Software distributed under the License is distributed on an "AS IS" basis,
+;; WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+;; for the specific language governing rights and limitations under the
+;; License.
+;;
+;; The Initial Developer of the Original Code is
+;;       Novell, Inc.
+;; Portions created by the Initial Developer are Copyright (C) 2011 the
+;; Initial Developer. All Rights Reserved.
+;;
+;; Major Contributor(s):
+;; Tor Lillqvist <tml at iki.fi>
+;; Portions created by Tor Lillqvist are Copyright (C) 2011 Tor Lillqvist. All Rights Reserved.
+;;
+;; For minor contributions see the git repository.
+;;
+;; Alternatively, the contents of this file may be used under the terms of
+;; either the GNU General Public License Version 3 or later (the "GPLv3+"), or
+;; the GNU Lesser General Public License Version 3 or later (the "LGPLv3+"),
+;; in which case the provisions of the GPLv3+ or the LGPLv3+ are applicable
+;; instead of those above.
+
+;; This is the template source code for the trampoline generated by
+;; codeSnippet() in cpp2uno.cxx. codeSnippet() copies the code from
+;; this function, modifying it as necessary in a few places. The
+;; generated trampoline calls cpp_vtable_call() which then calls the
+;; actual UNO function.
+
+;; We keep this as a separate .asm file here so that it is easy to
+;; modify, and we don't need to laborously enter machine code into
+;; codeSnippet().
+
+;; 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
+
+;; For exception handling and unwinding to work across the generated
+;; functions (as I assume we want?), we would need call
+;; RtlAddFunctionTable() (and RtlDeleteFunctionTable()). 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
+
+;; The code snippet generated is called from "normal" C++ code which
+;; has no idea that it is calling dynamically generated code.
+
+typelib_TypeClass_FLOAT equ 10
+typelib_TypeClass_DOUBLE equ 11
+
+extern cpp_vtable_call: proc
+
+.code
+
+;; Single instruction templates. For each register paramter, which can
+;; be either in an integer or floating-point register, either of two
+;; instruction sequences are used, either:
+;;     mov qword ptr offset[rsp], reg
+;;     nop
+;; or:
+;;     movsd qwort ptr offset[rsp], xmmreg
+;;
+;; The nop in the integer case is so that both are of equal length
+
+fp_spill_templates:
+public fp_spill_templates
+    movsd qword ptr 32[rsp], xmm3
+    movsd qword ptr 24[rsp], xmm2
+    movsd qword ptr 16[rsp], xmm1
+    movsd qword ptr 8[rsp], xmm0
+fp_spill_templates_end:
+public fp_spill_templates_end
+
+;; The actual template function code here
+
+trampoline_template proc
+
+    ;; Spill our register parameters. In the x64 Windows calling
+    ;; convention the caller always has stack space allocated
+    ;; where the callee can spill register parameters.
+
+    ;; The default is integer moves, that are replaced in the
+    ;; generated code snippet with floating-point moves for
+    ;; floating-point parameters.
+
+    mov qword ptr 32[rsp], r9
+    nop
+    mov qword ptr 24[rsp], r8
+    nop
+    mov qword ptr 16[rsp], rdx
+    nop
+    mov qword ptr 8[rsp], rcx
+    nop
+trampoline_template_spill_end::
+public trampoline_template_spill_end
+
+    ;; Make stack frame. Re-align RSP at 16 bytes. We need just one
+    ;; qword of stack for our own purposes: Where cpp_vtable_call()
+    ;; will store the return value of the UNO callee. But we of course
+    ;; must also allocate space for the functions we call (i.e., just
+    ;; cpp_vtable_call()) to spill their register parameters.
+
+    sub rsp, 40
+
+    ;; Call cpp_vtable_call() with 3 parameters:
+
+    ;; 1 (rcx): nFunctionIndex
+    ;; 2 (rdx): nVtableOffset
+    ;; 3 (r8): pointer to where to store return value, followed by our
+    ;; return address (uninteresting to cpp_vtable_call()), followed
+    ;; by our spilled register parameters, as stored above, followed
+    ;; by the rest of our parameters, if any.
+
+    mov rcx, 12345467890abcdeh              ;; nFunctionIndex, actual value generated from
+                                            ;;  parameter to codeSnippet()
+trampoline_template_function_index::
+public trampoline_template_function_index
+
+    mov rdx, 12345467890abcdeh               ;; nVtableOffset, ditto
+trampoline_template_vtable_offset::
+public trampoline_template_vtable_offset
+
+    lea r8, 32[rsp]                         ;; Where cpp_vtable_call() will store the return value
+
+    call cpp_vtable_call                    ;; Actual address generated by codeSnippet()
+
+    ;; cpp_vtable_call() returns the typelib_TypeClass type of the
+    ;; return value of the called UNO function
+
+    cmp rax, typelib_TypeClass_FLOAT
+    je Lfloat
+
+    cmp rax, typelib_TypeClass_DOUBLE
+    je Lfloat
+
+    mov rax, qword ptr 32[rsp]
+    jmp Lepilogue
+
+Lfloat:
+    movsd xmm0, qword ptr 32[rsp]
+
+Lepilogue:
+    add rsp, 40
+    ret
+trampoline_template_end::
+public trampoline_template_end
+
+trampoline_template 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 7c8831a..d73e729 100644
--- a/bridges/source/cpp_uno/msvc_win32_x86-64/cpp2uno.cxx
+++ b/bridges/source/cpp_uno/msvc_win32_x86-64/cpp2uno.cxx
@@ -42,191 +42,180 @@
 
 #include "mscx.hxx"
 
-using namespace ::com::sun::star::uno;
+// #define DEBUG_WITH_JUST_MESSAGEBOXES
 
-namespace
-{
+using namespace ::com::sun::star::uno;
 
 //==================================================================================================
 static inline typelib_TypeClass cpp2uno_call(
     bridges::cpp_uno::shared::CppInterfaceProxy * pThis,
     const typelib_TypeDescription * pMemberTypeDescr,
-    typelib_TypeDescriptionReference * pReturnTypeRef, // 0 indicates void return
+    typelib_TypeDescriptionReference * pReturnTypeRef, // NULL indicates void return
     sal_Int32 nParams, typelib_MethodParameter * pParams,
-    void ** pCallStack,
-    sal_Int64 * pRegisterReturn /* space for register return */ )
+    void ** pStack )
 {
-    // pCallStack: ret, this, [complex return ptr], params
-    char * pCppStack = (char *)(pCallStack +2);
-
-    // return
-    typelib_TypeDescription * pReturnTypeDescr = 0;
-    if (pReturnTypeRef)
-    {
+    // Return type
+    typelib_TypeDescription * pReturnTypeDescr = NULL;
+    if ( pReturnTypeRef )
         TYPELIB_DANGER_GET( &pReturnTypeDescr, pReturnTypeRef );
-    }
 
-    void * pUnoReturn = 0;
-    void * pCppReturn = 0; // complex return ptr: if != 0 && != pUnoReturn, reconversion need
+    int nFirstRealParam = 2;
 
-    if (pReturnTypeDescr)
+    void * pUnoReturn = NULL;
+    void * pCppReturn = NULL;   // Complex return ptr: if != NULL && != pUnoReturn, reconversion need
+
+    if ( pReturnTypeDescr )
     {
-        if (bridges::cpp_uno::shared::isSimpleType( pReturnTypeDescr ))
+        if ( !bridges::cpp_uno::shared::isSimpleType( pReturnTypeDescr ) )
         {
-            pUnoReturn = pRegisterReturn; // direct way for simple types
+            pCppReturn = pStack[nFirstRealParam++];
+
+            pUnoReturn = ( bridges::cpp_uno::shared::relatesToInterfaceType( pReturnTypeDescr )
+                           ? alloca( pReturnTypeDescr->nSize )
+                           : pCppReturn ); // direct way
         }
-        else // complex return via ptr (pCppReturn)
+        else // complex return, store it directly where the C++ called wants it
         {
-            pCppReturn = *(void **)pCppStack;
-            pCppStack += sizeof(void *);
-
-            pUnoReturn = (bridges::cpp_uno::shared::relatesToInterfaceType(
-                              pReturnTypeDescr )
-                          ? alloca( pReturnTypeDescr->nSize )
-                          : pCppReturn); // direct way
+            pUnoReturn = pStack;
         }
     }
 
-    // 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));
+    void ** pCppIncomingParams = pStack + nFirstRealParam;
+
+    // Unlike this method for other archs, prefer clarity to
+    // micro-optimization, and allocate these array separately
+
+    // Parameters passed to the UNO function
+    void ** pUnoArgs = (void **)alloca( sizeof(void *) * nParams );
 
-    sal_Int32 nTempIndexes = 0;
+    // Parameters received from C++
+    void ** pCppArgs = (void **)alloca( sizeof(void *) * nParams );
 
-    for ( sal_Int32 nPos = 0; nPos < nParams; ++nPos )
+    // Indexes of values this have to be converted (interface conversion cpp<=>uno)
+    int * pTempIndexes =
+        (int *)alloca( sizeof(int) * nParams );
+
+    // Type descriptions for reconversions
+    typelib_TypeDescription ** ppTempParamTypeDescr =
+        (typelib_TypeDescription **)alloca( sizeof(void *) * nParams );
+
+    int nTempIndexes = 0;
+
+    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 ))
-            // value
+        if ( !rParam.bOut
+             && bridges::cpp_uno::shared::isSimpleType( rParam.pTypeRef ) )
         {
-            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 );
+            pCppArgs[nPos] = pUnoArgs[nPos] = pCppIncomingParams++;
         }
         else // ptr to complex value | ref
         {
-            pCppArgs[nPos] = *(void **)pCppStack;
+            typelib_TypeDescription * pParamTypeDescr = 0;
+            TYPELIB_DANGER_GET( &pParamTypeDescr, rParam.pTypeRef );
 
-            if (! rParam.bIn) // is pure out
+            void * pCppStack;
+
+            pCppArgs[nPos] = pCppStack = *pCppIncomingParams++;
+
+            if ( !rParam.bIn ) // Pure out
             {
-                // uno out is unconstructed mem!
+                // UNO out is unconstructed mem
                 pUnoArgs[nPos] = alloca( pParamTypeDescr->nSize );
                 pTempIndexes[nTempIndexes] = nPos;
-                // will be released at reconversion
+                // pParamTypeDescr will be released at reconversion
                 ppTempParamTypeDescr[nTempIndexes++] = pParamTypeDescr;
             }
-            // is in/inout
-            else if (bridges::cpp_uno::shared::relatesToInterfaceType(
-                         pParamTypeDescr ))
+            //
+            else if ( bridges::cpp_uno::shared::relatesToInterfaceType(
+                         pParamTypeDescr ) )
             {
                 ::uno_copyAndConvertData(
                     pUnoArgs[nPos] = alloca( pParamTypeDescr->nSize ),
-                    *(void **)pCppStack, pParamTypeDescr,
+                    pCppStack, pParamTypeDescr,
                     pThis->getBridge()->getCpp2Uno() );
-                pTempIndexes[nTempIndexes] = nPos; // has to be reconverted
-                // will be released at reconversion
+                pTempIndexes[nTempIndexes] = nPos; // Has to be reconverted
+                // pParamTypeDescr will be released at reconversion
                 ppTempParamTypeDescr[nTempIndexes++] = pParamTypeDescr;
             }
             else // direct way
             {
-                pUnoArgs[nPos] = *(void **)pCppStack;
-                // no longer needed
+                pUnoArgs[nPos] = 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
+    // invoke UNO dispatch call
     (*pThis->getUnoI()->pDispatcher)(
         pThis->getUnoI(), pMemberTypeDescr, pUnoReturn, pUnoArgs, &pUnoExc );
 
     // in case an exception occurred...
-    if (pUnoExc)
+    if ( pUnoExc )
     {
-        // destruct temporary in/inout params
-        while (nTempIndexes--)
+        // Destruct temporary in/inout params
+        while ( nTempIndexes-- )
         {
-            sal_Int32 nIndex = pTempIndexes[nTempIndexes];
+            int nIndex = pTempIndexes[nTempIndexes];
 
-            if (pParams[nIndex].bIn) // is in/inout => was constructed
+            if ( pParams[nIndex].bIn ) // Is in/inout => was constructed
             {
                 ::uno_destructData( pUnoArgs[nIndex], ppTempParamTypeDescr[nTempIndexes], 0 );
             }
             TYPELIB_DANGER_RELEASE( ppTempParamTypeDescr[nTempIndexes] );
         }
-        if (pReturnTypeDescr)
-        {
+        if ( pReturnTypeDescr )
             TYPELIB_DANGER_RELEASE( pReturnTypeDescr );
-        }
 
         CPPU_CURRENT_NAMESPACE::mscx_raiseException(
-            &aUnoExc, pThis->getBridge()->getUno2Cpp() );
-            // has to destruct the any
-        // is here for dummy
+            &aUnoExc, pThis->getBridge()->getUno2Cpp() ); // Has to destruct the any
+
+        // Is here for dummy
         return typelib_TypeClass_VOID;
     }
-    else // else no exception occurred...
+    else // Else, no exception occurred...
     {
-        // temporary params
+        // Temporary params
         while (nTempIndexes--)
         {
-            sal_Int32 nIndex = pTempIndexes[nTempIndexes];
+            int nIndex = pTempIndexes[nTempIndexes];
             typelib_TypeDescription * pParamTypeDescr = ppTempParamTypeDescr[nTempIndexes];
 
-            if (pParams[nIndex].bOut) // inout/out
+            if ( pParams[nIndex].bOut ) // inout/out
             {
-                // convert and assign
+                // Convert and assign
                 ::uno_destructData(
                     pCppArgs[nIndex], pParamTypeDescr, cpp_release );
                 ::uno_copyAndConvertData(
                     pCppArgs[nIndex], pUnoArgs[nIndex], pParamTypeDescr,
                     pThis->getBridge()->getUno2Cpp() );
             }
-            // destroy temp uno param
+            // Destroy temp uno param
             ::uno_destructData( pUnoArgs[nIndex], pParamTypeDescr, 0 );
 
             TYPELIB_DANGER_RELEASE( pParamTypeDescr );
         }
-        // return
-        if (pCppReturn) // has complex return
+        // Return
+        if ( pCppReturn ) // Has complex return
         {
-            if (pUnoReturn != pCppReturn) // needs reconversion
+            if ( pUnoReturn != pCppReturn ) // Needs reconversion
             {
                 ::uno_copyAndConvertData(
                     pCppReturn, pUnoReturn, pReturnTypeDescr,
                     pThis->getBridge()->getUno2Cpp() );
-                // destroy temp uno return
-                ::uno_destructData(
-                    pUnoReturn, pReturnTypeDescr, 0 );
+                // Destroy temp uno return
+                ::uno_destructData( pUnoReturn, pReturnTypeDescr, 0 );
             }
-            // complex return ptr is set to eax
-            *(void **)pRegisterReturn = pCppReturn;
+            // Complex return ptr is set to eax
+            pStack[0] = pCppReturn;
         }
-        if (pReturnTypeDescr)
+        if ( pReturnTypeDescr )
         {
             typelib_TypeClass eRet = (typelib_TypeClass)pReturnTypeDescr->eTypeClass;
             TYPELIB_DANGER_RELEASE( pReturnTypeDescr );
@@ -238,199 +227,204 @@ static inline typelib_TypeClass cpp2uno_call(
 }
 
 //==================================================================================================
-typelib_TypeClass __cdecl cpp_mediate(
-    void ** pCallStack, sal_Int32 nFunctionIndex, sal_Int32 nVtableOffset,
-    sal_Int64 * pRegisterReturn /* space for register return */ )
+extern "C" typelib_TypeClass cpp_vtable_call(
+    sal_Int32 nFunctionIndex,
+    sal_Int32 nVtableOffset,
+    void ** pStack )
 {
-    // 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);
+    // pStack points to space for return value, after which
+    // follows our return address (uninteresting) then the spilled
+    // integer or floating-point register parameters from the call to
+    // the trampoline, followed by stack parameters. Note that if the
+    // callee returns a large value, the first parameter is actually a
+    // pointer to where it should store its return value. The first
+    // "real" parameter is the "this" pointer.
+
+    void * pThis;
+    if ( nFunctionIndex & 0x80000000 )
+    {
+        nFunctionIndex &= 0x7fffffff;
+        pThis = pStack[3];
+    }
+    else
+    {
+        pThis = pStack[2];
+    }
+    pThis = static_cast<char *>( pThis ) - nVtableOffset;
+
+    bridges::cpp_uno::shared::CppInterfaceProxy * pCppI =
+        bridges::cpp_uno::shared::CppInterfaceProxy::castInterfaceToProxy( pThis );
 
     typelib_InterfaceTypeDescription * pTypeDescr = pCppI->getTypeDescr();
-    OSL_ENSURE( nFunctionIndex < pTypeDescr->nMapFunctionIndexToMemberIndex,
-                 "### illegal vtable index!" );
-    if (nFunctionIndex >= pTypeDescr->nMapFunctionIndexToMemberIndex)
+
+    OSL_ENSURE( nFunctionIndex < pTypeDescr->nMapFunctionIndexToMemberIndex, "### illegal vtable index!\n" );
+    if ( nFunctionIndex >= pTypeDescr->nMapFunctionIndexToMemberIndex )
     {
-        throw RuntimeException( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("illegal vtable index!") ),
-                                (XInterface *)pThis );
+        throw RuntimeException( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("illegal vtable index!")),
+                                reinterpret_cast<XInterface *>( pCppI ) );
     }
 
     // determine called method
     sal_Int32 nMemberPos = pTypeDescr->pMapFunctionIndexToMemberIndex[nFunctionIndex];
-    OSL_ENSURE( nMemberPos < pTypeDescr->nAllMembers, "### illegal member index!" );
+    OSL_ENSURE( nMemberPos < pTypeDescr->nAllMembers, "### illegal member index!\n" );
 
     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:
+    switch ( aMemberDescr.get()->eTypeClass )
     {
-        // is METHOD
-        switch (nFunctionIndex)
+        case typelib_TypeClass_INTERFACE_ATTRIBUTE:
         {
-            // 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;
+            typelib_TypeDescriptionReference *pAttrTypeRef =
+                reinterpret_cast<typelib_InterfaceAttributeTypeDescription *>( aMemberDescr.get() )->pAttributeTypeRef;
+
+            if ( pTypeDescr->pMapMemberIndexToFunctionIndex[nMemberPos] == nFunctionIndex )
+            {
+                // is GET method
+                eRet = cpp2uno_call( pCppI, aMemberDescr.get(), pAttrTypeRef,
+                        0, NULL, // no params
+                        pStack );
+            }
+            else
+            {
+                // is SET method
+                typelib_MethodParameter aParam;
+                aParam.pTypeRef = pAttrTypeRef;
+                aParam.bIn		= sal_True;
+                aParam.bOut		= sal_False;
+
+                eRet = cpp2uno_call( pCppI, aMemberDescr.get(),
+                        0, // indicates void return
+                        1, &aParam,
+                        pStack );
+            }
             break;
-        case 0: // queryInterface() opt
+        }
+        case typelib_TypeClass_INTERFACE_METHOD:
         {
-            typelib_TypeDescription * pTD = 0;
-            TYPELIB_DANGER_GET( &pTD, reinterpret_cast< Type * >( pCallStack[3] )->getTypeLibType() );
-            if (pTD)
+            // is METHOD
+            switch ( nFunctionIndex )
             {
-                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;
+                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 = NULL;
+                    // the incoming C++ parameters are: The hidden return value pointer,
+                    // the this pointer, and then the actual queryInterface() only parameter.
+                    // Thus pStack[4], the third parameter.
+                    TYPELIB_DANGER_GET( &pTD, reinterpret_cast<Type *>( pStack[4] )->getTypeLibType() );
+
+                    if ( pTD )
+                    {
+                        XInterface * pInterface = NULL;
+                        (*pCppI->getBridge()->getCppEnv()->getRegisteredInterface)
+                            ( pCppI->getBridge()->getCppEnv(),
+                              (void **)&pInterface,
+                              pCppI->getOid().pData,
+                              reinterpret_cast<typelib_InterfaceTypeDescription *>( pTD ) );
+
+                        if ( pInterface )
+                        {
+                            // pStack[0] = hidden return value pointer
+                            ::uno_any_construct( reinterpret_cast<uno_Any *>( pStack[0] ),
+                                                 &pInterface, pTD, cpp_acquire );
+
+                            pInterface->release();
+                            TYPELIB_DANGER_RELEASE( pTD );
+
+                            eRet = typelib_TypeClass_ANY;
+                            break;
+                        }
+                        TYPELIB_DANGER_RELEASE( pTD );
+                    }
+                } // Fall through!
+                default:
+                {
+                    typelib_InterfaceMethodTypeDescription *pMethodTD =
+                        reinterpret_cast<typelib_InterfaceMethodTypeDescription *>( aMemberDescr.get() );
+
+                    eRet = cpp2uno_call( pCppI, aMemberDescr.get(),
+                                         pMethodTD->pReturnTypeRef,
+                                         pMethodTD->nParams,
+                                         pMethodTD->pParams,
+                                         pStack );
                 }
-                TYPELIB_DANGER_RELEASE( pTD );
             }
-        } // else perform queryInterface()
+            break;
+        }
         default:
-            eRet = cpp2uno_call(
-                pCppI, aMemberDescr.get(),
-                ((typelib_InterfaceMethodTypeDescription *)aMemberDescr.get())->pReturnTypeRef,
-                ((typelib_InterfaceMethodTypeDescription *)aMemberDescr.get())->nParams,
-                ((typelib_InterfaceMethodTypeDescription *)aMemberDescr.get())->pParams,
-                pCallStack, pRegisterReturn );
+        {
+            throw RuntimeException( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("no member description found!")),
+                                    reinterpret_cast<XInterface *>( pCppI ) );
+            // is here for dummy
+            eRet = typelib_TypeClass_VOID;
         }
-        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;
+extern "C" {
+
+// These are actually addresses in the code compiled from codeSnippet.asm
+extern char
+    fp_spill_templates,
+    fp_spill_templates_end,
+    trampoline_template,
+    trampoline_template_spill_end,
+    trampoline_template_function_index,
+    trampoline_template_vtable_offset,
+    trampoline_template_end;
+}
+
+int const codeSnippetSize = (int) (&trampoline_template_end - &trampoline_template);
 
 // 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 * code,
+    char param_kind[4],
+    sal_Int32 functionIndex,
+    sal_Int32 vtableOffset,
+    bool bHasHiddenParam )
 {
-    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
+    OSL_ASSERT( (&fp_spill_templates_end - &fp_spill_templates) ==
+                (&trampoline_template_spill_end - &trampoline_template) );
 
-#endif
+    OSL_ASSERT( ((&fp_spill_templates_end - &fp_spill_templates) / 4) * 4 ==
+                (&fp_spill_templates_end - &fp_spill_templates) );
 
-#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;
-}
+    if ( bHasHiddenParam )
+        functionIndex |= 0x80000000;
 
+    int const one_spill_instruction_size = (int) ((&fp_spill_templates_end - &fp_spill_templates)) / 4;
+
+    memcpy( code, &trampoline_template, codeSnippetSize );
+
+    for (int i = 0; i < 4; ++i)
+        if ( param_kind[i] == CPPU_CURRENT_NAMESPACE::REGPARAM_FLT )
+            memcpy (code + i*one_spill_instruction_size,
+                    &fp_spill_templates + i*one_spill_instruction_size,
+                    one_spill_instruction_size);
+
+    ((sal_uInt64*) trampoline_template_function_index)[-1] = functionIndex;
+    ((sal_uInt64*) trampoline_template_vtable_offset)[-1] = vtableOffset;
+
+    // TODO: Add unwind data for the dynamically generated function by
+    // calling RtlAddFunctionTable(). We also need to remove the
+    // unwind data with RtlDeleteFunctionTable() in freeExec() then.
+
+    return code + codeSnippetSize;
 }
 
 struct bridges::cpp_uno::shared::VtableFactory::Slot { void * fn; };
@@ -468,9 +462,7 @@ bridges::cpp_uno::shared::VtableFactory::initializeBlock(
     return slots + slotCount;
 }
 
-#if 0
-
-#else
+#ifdef DEBUG_WITH_JUST_MESSAGEBOXES
 
 static void whatthefuck(sal_Int64 i, ...)
 {
@@ -493,28 +485,33 @@ unsigned char * bridges::cpp_uno::shared::VtableFactory::addLocalFunctions(
         TYPELIB_DANGER_GET( &pTD, type->ppMembers[ i ] );
         OSL_ASSERT( pTD );
 
-        CPPU_CURRENT_NAMESPACE::RegParamKind param_kind[4];
+        char param_kind[4];
         int nr = 0;
 
+        for (int i = 0; i < 4; ++i)
+            param_kind[i] = CPPU_CURRENT_NAMESPACE::REGPARAM_INT;
+
         if ( pTD->eTypeClass == typelib_TypeClass_INTERFACE_ATTRIBUTE )
         {
             typelib_InterfaceAttributeTypeDescription *pAttrTD =
                 reinterpret_cast<typelib_InterfaceAttributeTypeDescription *>( pTD );
 
-            // get method
-#if 0
+            // Getter
+
+#ifndef DEBUG_WITH_JUST_MESSAGEBOXES
             (s++)->fn = code;
-            code = codeSnippet(code, functionOffset++, vtableOffset);
+            code = codeSnippet( code, param_kind, functionOffset++, vtableOffset,
+                                pTD->nSize > 8);
 #else
             (s++)->fn = whatthefuck;
 #endif
 
             if ( ! pAttrTD->bReadOnly )
             {
-                // set method
-#if 0
+                // Setter
+#ifndef DEBUG_WITH_JUST_MESSAGEBOXES
                 (s++)->fn = code;
-                code = codeSnippet(code, functionOffset++, vtableOffset);
+                code = codeSnippet( code, param_kind, functionOffset++, vtableOffset, false );
 #else
                 (s++)->fn = whatthefuck;
 #endif
@@ -529,14 +526,14 @@ unsigned char * bridges::cpp_uno::shared::VtableFactory::addLocalFunctions(
             TYPELIB_DANGER_GET( &pReturnTD, pMethodTD->pReturnTypeRef );
             OSL_ASSERT( pReturnTD );
 
-            if ( pReturnTD->nSize > 8 ) {
+            if ( pReturnTD->nSize > 8 )
+            {
                 // Hidden return value
-                param_kind[nr++] = CPPU_CURRENT_NAMESPACE::REGPARAM_INT;
+                nr++;
             }
-            TYPELIB_DANGER_RELEASE( pReturnTD );
 
             // 'this'
-            param_kind[nr++] = CPPU_CURRENT_NAMESPACE::REGPARAM_INT;
+            nr++;
 
             for (int j = 0; nr < 4 && j < pMethodTD->nParams; ++j)
             {
@@ -548,21 +545,24 @@ unsigned char * bridges::cpp_uno::shared::VtableFactory::addLocalFunctions(
                 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);
+#ifndef DEBUG_WITH_JUST_MESSAGEBOXES
+            (s++)->fn = code;
+            code = codeSnippet( code, param_kind, functionOffset++, vtableOffset,
+                                pReturnTD->nSize > 8);
 #else
-                (s++)->fn = whatthefuck;
+            (s++)->fn = whatthefuck;
 #endif
-            }
+
+            TYPELIB_DANGER_RELEASE( pReturnTD );
         }
         else
             OSL_ASSERT( false );
+
+        TYPELIB_DANGER_RELEASE( pTD );
     }
     return code;
 }
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 604799a..e813fad 100644
--- a/bridges/source/cpp_uno/msvc_win32_x86-64/makefile.mk
+++ b/bridges/source/cpp_uno/msvc_win32_x86-64/makefile.mk
@@ -51,10 +51,11 @@ CFLAGS += -DLEAK_STATIC_DATA
 
 
 SLOFILES= \
-    $(SLO)$/cpp2uno.obj		\
-    $(SLO)$/uno2cpp.obj		\
-    $(SLO)$/dllinit.obj		\
-    $(SLO)$/except.obj
+    $(SLO)$/cpp2uno.obj \
+    $(SLO)$/uno2cpp.obj \
+    $(SLO)$/dllinit.obj \
+    $(SLO)$/except.obj  \
+    $(SLO)$/codeSnippet.obj
 
 NOOPTFILES= \
     $(SLO)$/except.obj
@@ -70,7 +71,7 @@ SHL1OBJS = $(SLOFILES)
 SHL1LIBS = $(SLB)$/cpp_uno_shared.lib
 
 SHL1STDLIBS= \
-    $(CPPULIB)			\
+    $(CPPULIB) \
     $(SALLIB)
 
 DEF1NAME=$(SHL1TARGET)
diff --git a/bridges/source/cpp_uno/shared/vtablefactory.cxx b/bridges/source/cpp_uno/shared/vtablefactory.cxx
index 777d0da..cfc4aa3 100644
--- a/bridges/source/cpp_uno/shared/vtablefactory.cxx
+++ b/bridges/source/cpp_uno/shared/vtablefactory.cxx
@@ -132,6 +132,11 @@ extern "C" void SAL_CALL freeExec(
     munmap(static_cast< char * >(address), size);
 #elif defined SAL_W32
     (void) size; // unused
+
+    // TODO: For wntmscx (x64 Windows), we need to remove the function
+    // table for the dynamically generated function that was added in
+    // codeSnippet() in cpp2uno.cxx.
+
     VirtualFree(address, 0, MEM_RELEASE);
 #elif defined(SAL_OS2)
     (void) DosFreeMem( address);


More information about the Libreoffice-commits mailing list