summaryrefslogtreecommitdiffstats
path: root/bridges/source/cpp_uno/msvc_win32_x86-64/call.asm
blob: 406e78d397a12314ac1c0455642e479f2c78fdc3 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
; -*- 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
;; Novell, Inc. All Rights Reserved.
;;
;; Major Contributor(s):
;;       Tor Lillqvist <tml@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 function jumped to from the trampoline generated by
;; codeSnippet() in cpp2uno.cxx. Here we call cpp_vtable_call() which
;; then calls the actual UNO function.

;; The code snippet generated is called from "normal" C++ code which
;; has no idea that it is calling dynamically generated code.

;; The generated short code snippet is not covered by any function
;; table and unwind info, but that doesn't matter, as the instructions
;; in it are not really going to cause any exception. Once it jumps
;; here it is covered by a function table, and the calls further down
;; through cpp_vtable_call() can be unwound cleanly.

;; This is in a separate file for x86-64 as MSVC doesn't have in-line
;; assembly for x64.

;; 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

;; This one has a mass of information about different architectures
;; and compilers, and contains some details about the x64 Windows
;; calling convention in particular that Microsoft doesn't mention
;; above:
;; http://www.agner.org/optimize/calling_conventions.pdf

;; 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

typelib_TypeClass_FLOAT equ 10
typelib_TypeClass_DOUBLE equ 11

extern cpp_vtable_call: proc

.code

privateSnippetExecutor proc frame

    ;; 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
    .allocstack (40)
    .endprolog

    ;; Call cpp_vtable_call() with 2 parameters:

    ;; 1 (rcx): nOffsetAndIndex (already put there in code generated by codeSnippet)
    ;; 2 (rdx): 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.

    lea rdx, 32[rsp]

    call cpp_vtable_call

    ;; 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
privateSnippetExecutor endp

end

; vim:set shiftwidth=4 softtabstop=4 expandtab: