annotate dyncallback/dyncall_callback_x86.c @ 358:30aae7371373

- extended signature with calling convention mode switches for fastcall (gnu), default, cdecl, stdcall, arm (arm), arm (thumb), syscall - made formatted call (dcV?{Call,Arg}F) interface use those calling convention mode signature specifications to begin with - extended callf testcode with one standard and one vararg call to test those cc mode switches
author Tassilo Philipp
date Mon, 13 Apr 2020 15:12:01 +0200
parents f5577f6bf97a
children 3bdd326dc269
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
1 /*
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
2
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
3 Package: dyncall
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
4 Library: dyncallback
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
5 File: dyncallback/dyncall_callback_x86.c
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
6 Description: Callback - Implementation for x86
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
7 License:
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
8
281
f5577f6bf97a - file header cleanups for release
Tassilo Philipp
parents: 202
diff changeset
9 Copyright (c) 2007-2018 Daniel Adler <dadler@uni-goettingen.de>,
0
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
10 Tassilo Philipp <tphilipp@potion-studios.com>
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
11
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
12 Permission to use, copy, modify, and distribute this software for any
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
13 purpose with or without fee is hereby granted, provided that the above
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
14 copyright notice and this permission notice appear in all copies.
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
15
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
16 THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
17 WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
18 MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
19 ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
20 WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
21 ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
22 OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
23
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
24 */
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
25
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
26
152
d48a8b8d2ef9 - integrated all headers containing DCCallback definition into the translation units used (arm64 already avoided this pointless header, so following that style)
cslag
parents: 0
diff changeset
27 #include "dyncall_callback.h"
d48a8b8d2ef9 - integrated all headers containing DCCallback definition into the translation units used (arm64 already avoided this pointless header, so following that style)
cslag
parents: 0
diff changeset
28 #include "dyncall_alloc_wx.h"
d48a8b8d2ef9 - integrated all headers containing DCCallback definition into the translation units used (arm64 already avoided this pointless header, so following that style)
cslag
parents: 0
diff changeset
29 #include "dyncall_thunk.h"
0
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
30 #include "dyncall_args_x86.h"
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
31
152
d48a8b8d2ef9 - integrated all headers containing DCCallback definition into the translation units used (arm64 already avoided this pointless header, so following that style)
cslag
parents: 0
diff changeset
32 /* Callback symbol. */
d48a8b8d2ef9 - integrated all headers containing DCCallback definition into the translation units used (arm64 already avoided this pointless header, so following that style)
cslag
parents: 0
diff changeset
33 extern void dcCallbackThunkEntry();
0
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
34
152
d48a8b8d2ef9 - integrated all headers containing DCCallback definition into the translation units used (arm64 already avoided this pointless header, so following that style)
cslag
parents: 0
diff changeset
35 struct DCCallback
d48a8b8d2ef9 - integrated all headers containing DCCallback definition into the translation units used (arm64 already avoided this pointless header, so following that style)
cslag
parents: 0
diff changeset
36 {
d48a8b8d2ef9 - integrated all headers containing DCCallback definition into the translation units used (arm64 already avoided this pointless header, so following that style)
cslag
parents: 0
diff changeset
37 DCThunk thunk; /* offset 0, size 16 */
d48a8b8d2ef9 - integrated all headers containing DCCallback definition into the translation units used (arm64 already avoided this pointless header, so following that style)
cslag
parents: 0
diff changeset
38 DCCallbackHandler* handler; /* offset 16 */
d48a8b8d2ef9 - integrated all headers containing DCCallback definition into the translation units used (arm64 already avoided this pointless header, so following that style)
cslag
parents: 0
diff changeset
39 DCArgsVT* args_vt; /* offset 20 */
d48a8b8d2ef9 - integrated all headers containing DCCallback definition into the translation units used (arm64 already avoided this pointless header, so following that style)
cslag
parents: 0
diff changeset
40 size_t stack_cleanup; /* offset 24 */
d48a8b8d2ef9 - integrated all headers containing DCCallback definition into the translation units used (arm64 already avoided this pointless header, so following that style)
cslag
parents: 0
diff changeset
41 void* userdata; /* offset 28 */
d48a8b8d2ef9 - integrated all headers containing DCCallback definition into the translation units used (arm64 already avoided this pointless header, so following that style)
cslag
parents: 0
diff changeset
42 };
0
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
43
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
44
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
45 /* compute stacksize for callee cleanup calling conventions:
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
46 *
152
d48a8b8d2ef9 - integrated all headers containing DCCallback definition into the translation units used (arm64 already avoided this pointless header, so following that style)
cslag
parents: 0
diff changeset
47 * cdecl,stdcall,thiscall_ms,fastcall_ms,fastcall_gnu
0
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
48 */
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
49
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
50 static int dcbCleanupSize_x86_cdecl(const char* signature)
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
51 {
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
52 return 0;
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
53 }
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
54
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
55 static int dcbCleanupSize_x86_std(const char* signature)
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
56 {
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
57 const char* ptr = signature;
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
58 int size = 0;
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
59 char ch;
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
60 while( (ch = *ptr++) != DC_SIGCHAR_ENDARG ) {
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
61 switch(ch) {
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
62 case DC_SIGCHAR_BOOL:
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
63 case DC_SIGCHAR_CHAR:
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
64 case DC_SIGCHAR_SHORT:
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
65 case DC_SIGCHAR_INT:
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
66 case DC_SIGCHAR_LONG:
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
67 case DC_SIGCHAR_POINTER:
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
68 case DC_SIGCHAR_UCHAR:
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
69 case DC_SIGCHAR_USHORT:
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
70 case DC_SIGCHAR_UINT:
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
71 case DC_SIGCHAR_ULONG:
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
72 case DC_SIGCHAR_STRING:
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
73 case DC_SIGCHAR_FLOAT:
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
74 size += 4;
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
75 break;
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
76 case DC_SIGCHAR_DOUBLE:
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
77 case DC_SIGCHAR_LONGLONG:
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
78 case DC_SIGCHAR_ULONGLONG:
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
79 size += 8;
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
80 break;
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
81 }
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
82 }
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
83 return size;
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
84 }
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
85
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
86 static int dcbCleanupSize_x86_this_ms(const char* signature)
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
87 {
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
88 const char* ptr = signature;
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
89 int size = 0;
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
90 char ch;
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
91 while( (ch = *ptr++) != DC_SIGCHAR_ENDARG )
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
92 {
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
93 switch(ch)
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
94 {
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
95 case DC_SIGCHAR_BOOL:
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
96 case DC_SIGCHAR_CHAR:
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
97 case DC_SIGCHAR_SHORT:
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
98 case DC_SIGCHAR_INT:
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
99 case DC_SIGCHAR_LONG:
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
100 case DC_SIGCHAR_POINTER:
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
101 case DC_SIGCHAR_UCHAR:
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
102 case DC_SIGCHAR_USHORT:
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
103 case DC_SIGCHAR_UINT:
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
104 case DC_SIGCHAR_ULONG:
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
105 case DC_SIGCHAR_STRING:
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
106 case DC_SIGCHAR_FLOAT:
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
107 size += 4;
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
108 break;
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
109 case DC_SIGCHAR_DOUBLE:
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
110 case DC_SIGCHAR_LONGLONG:
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
111 case DC_SIGCHAR_ULONGLONG:
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
112 size += 8;
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
113 break;
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
114 }
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
115 }
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
116 return size;
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
117 }
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
118
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
119 static int dcbCleanupSize_x86_fast_ms(const char* signature)
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
120 {
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
121 const char* ptr = signature;
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
122 int size = 0;
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
123 int regs = 0;
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
124 char ch;
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
125 while( (ch = *ptr++) != DC_SIGCHAR_ENDARG )
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
126 {
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
127 switch(ch)
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
128 {
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
129 case DC_SIGCHAR_BOOL:
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
130 case DC_SIGCHAR_CHAR:
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
131 case DC_SIGCHAR_SHORT:
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
132 case DC_SIGCHAR_INT:
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
133 case DC_SIGCHAR_LONG:
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
134 case DC_SIGCHAR_POINTER:
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
135 case DC_SIGCHAR_UCHAR:
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
136 case DC_SIGCHAR_USHORT:
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
137 case DC_SIGCHAR_UINT:
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
138 case DC_SIGCHAR_ULONG:
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
139 case DC_SIGCHAR_STRING:
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
140 if (regs < 2) regs++;
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
141 else size += 4;
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
142 break;
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
143 case DC_SIGCHAR_FLOAT:
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
144 size += 4;
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
145 break;
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
146 case DC_SIGCHAR_DOUBLE:
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
147 size += 8;
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
148 break;
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
149 case DC_SIGCHAR_LONGLONG:
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
150 case DC_SIGCHAR_ULONGLONG:
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
151 size += 8;
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
152 break;
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
153 }
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
154 }
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
155 return size;
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
156 }
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
157
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
158 static int dcbCleanupSize_x86_fast_gnu(const char* signature)
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
159 {
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
160 const char* ptr = signature;
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
161 char ch;
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
162 int size = 0;
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
163 int regs = 0;
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
164 while( (ch = *ptr++) != DC_SIGCHAR_ENDARG ) {
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
165 switch(ch) {
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
166 case DC_SIGCHAR_FLOAT:
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
167 size += 4;
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
168 break;
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
169 case DC_SIGCHAR_DOUBLE:
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
170 size += 8;
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
171 break;
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
172 case DC_SIGCHAR_LONGLONG:
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
173 case DC_SIGCHAR_ULONGLONG:
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
174 regs = 2;
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
175 size += 8;
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
176 break;
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
177 default:
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
178 if (regs < 2) regs++;
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
179 else size += 4;
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
180 break;
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
181 }
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
182 }
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
183 return size;
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
184 }
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
185
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
186 void dcbInitCallback(DCCallback* pcb, const char* signature, DCCallbackHandler* handler, void* userdata)
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
187 {
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
188 const char* ptr;
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
189 char ch;
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
190 int mode;
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
191 pcb->handler = handler;
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
192 pcb->userdata = userdata;
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
193
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
194 ptr = signature;
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
195 ch = *ptr;
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
196
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
197 /* x86 hints: */
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
198
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
199 mode = DC_CALL_C_X86_CDECL;
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
200
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
201 if(ch == DC_SIGCHAR_CC_PREFIX)
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
202 {
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
203 ptr++;
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
204 ch = *ptr++;
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
205 switch(ch) {
358
30aae7371373 - extended signature with calling convention mode switches for fastcall (gnu), default, cdecl, stdcall, arm (arm), arm (thumb), syscall
Tassilo Philipp
parents: 281
diff changeset
206 case DC_SIGCHAR_CC_DEFAULT: mode = DC_CALL_C_DEFAULT; break;
30aae7371373 - extended signature with calling convention mode switches for fastcall (gnu), default, cdecl, stdcall, arm (arm), arm (thumb), syscall
Tassilo Philipp
parents: 281
diff changeset
207 /*@@@ add ellipsis?*/
30aae7371373 - extended signature with calling convention mode switches for fastcall (gnu), default, cdecl, stdcall, arm (arm), arm (thumb), syscall
Tassilo Philipp
parents: 281
diff changeset
208 case DC_SIGCHAR_CC_CDECL: mode = DC_CALL_C_X86_CDECL; break;
0
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
209 case DC_SIGCHAR_CC_STDCALL: mode = DC_CALL_C_X86_WIN32_STD; break;
358
30aae7371373 - extended signature with calling convention mode switches for fastcall (gnu), default, cdecl, stdcall, arm (arm), arm (thumb), syscall
Tassilo Philipp
parents: 281
diff changeset
210 case DC_SIGCHAR_CC_FASTCALL_MS: mode = DC_CALL_C_X86_WIN32_FAST_MS; break;
30aae7371373 - extended signature with calling convention mode switches for fastcall (gnu), default, cdecl, stdcall, arm (arm), arm (thumb), syscall
Tassilo Philipp
parents: 281
diff changeset
211 case DC_SIGCHAR_CC_FASTCALL_GNU: mode = DC_CALL_C_X86_WIN32_FAST_GNU; break;
0
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
212 case DC_SIGCHAR_CC_THISCALL_MS: mode = DC_CALL_C_X86_WIN32_THIS_MS; break;
358
30aae7371373 - extended signature with calling convention mode switches for fastcall (gnu), default, cdecl, stdcall, arm (arm), arm (thumb), syscall
Tassilo Philipp
parents: 281
diff changeset
213 case DC_SIGCHAR_CC_THISCALL_GNU: mode = DC_CALL_C_X86_WIN32_THIS_GNU; break;
30aae7371373 - extended signature with calling convention mode switches for fastcall (gnu), default, cdecl, stdcall, arm (arm), arm (thumb), syscall
Tassilo Philipp
parents: 281
diff changeset
214 case DC_SIGCHAR_CC_SYSCALL: mode = DC_CALL_SYS_DEFAULT; break;
0
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
215 }
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
216 }
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
217
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
218 /* x86 configuration: */
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
219
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
220 switch(mode) {
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
221 case DC_CALL_C_X86_CDECL:
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
222 pcb->args_vt = &dcArgsVT_default;
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
223 pcb->stack_cleanup = dcbCleanupSize_x86_cdecl(ptr);
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
224 break;
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
225 case DC_CALL_C_X86_WIN32_STD:
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
226 pcb->args_vt = &dcArgsVT_default;
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
227 pcb->stack_cleanup = dcbCleanupSize_x86_std(ptr);
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
228 break;
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
229 case DC_CALL_C_X86_WIN32_THIS_MS:
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
230 pcb->args_vt = &dcArgsVT_this_ms;
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
231 pcb->stack_cleanup = dcbCleanupSize_x86_this_ms(ptr);
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
232 break;
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
233 case DC_CALL_C_X86_WIN32_FAST_MS:
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
234 pcb->args_vt = &dcArgsVT_fast_ms;
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
235 pcb->stack_cleanup = dcbCleanupSize_x86_fast_ms(ptr);
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
236 break;
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
237 case DC_CALL_C_X86_WIN32_FAST_GNU:
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
238 pcb->args_vt = &dcArgsVT_fast_gnu;
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
239 pcb->stack_cleanup = dcbCleanupSize_x86_fast_gnu(ptr);
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
240 break;
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
241 }
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
242
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
243 #if defined(DC_PLAN9)
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
244 /* HACK for Plan9 - 'reuse' pcb->stack_cleanup as a flag
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
245 to indicate if return value is 64bit. The field is not
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
246 used anyways as the caller is responsible to clean up
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
247 the stack in Plan9. If set to '1' the callback kernel
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
248 takes into account an extra stack-parameter (pointer
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
249 to 64bit return value).
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
250 I thought of introducing a new field, but for one single
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
251 x86 calling convention out of many, it seemed overkill
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
252 to change the struct for everybody else. Maybe renaming
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
253 would be a good idea, though. ~ Tassilo
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
254 */
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
255 while(*ptr) {
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
256 if(*ptr++ == DC_SIGCHAR_ENDARG) {
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
257 pcb->stack_cleanup = (*ptr == DC_SIGCHAR_LONGLONG) || (*ptr == DC_SIGCHAR_ULONGLONG);
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
258 break;
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
259 }
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
260 }
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
261 #endif
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
262 }
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
263
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
264 /*
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
265 * callback constructor
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
266 */
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
267
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
268 DCCallback* dcbNewCallback(const char* signature, DCCallbackHandler* handler, void* userdata)
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
269 {
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
270 int err;
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
271 DCCallback* pcb;
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
272 err = dcAllocWX(sizeof(DCCallback), (void**) &pcb);
202
030fbb70aa1b - changed allocwx code:
Tassilo Philipp
parents: 152
diff changeset
273 if(err)
030fbb70aa1b - changed allocwx code:
Tassilo Philipp
parents: 152
diff changeset
274 return NULL;
0
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
275
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
276 dcbInitThunk(&pcb->thunk, dcCallbackThunkEntry);
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
277 dcbInitCallback(pcb, signature, handler, userdata);
202
030fbb70aa1b - changed allocwx code:
Tassilo Philipp
parents: 152
diff changeset
278
030fbb70aa1b - changed allocwx code:
Tassilo Philipp
parents: 152
diff changeset
279 err = dcInitExecWX(pcb, sizeof(DCCallback));
030fbb70aa1b - changed allocwx code:
Tassilo Philipp
parents: 152
diff changeset
280 if(err) {
030fbb70aa1b - changed allocwx code:
Tassilo Philipp
parents: 152
diff changeset
281 dcFreeWX(pcb, sizeof(DCCallback));
030fbb70aa1b - changed allocwx code:
Tassilo Philipp
parents: 152
diff changeset
282 return NULL;
030fbb70aa1b - changed allocwx code:
Tassilo Philipp
parents: 152
diff changeset
283 }
030fbb70aa1b - changed allocwx code:
Tassilo Philipp
parents: 152
diff changeset
284
0
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
285 return pcb;
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
286 }
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
287
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
288 /*
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
289 * free
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
290 */
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
291
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
292 void dcbFreeCallback(DCCallback* pcb)
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
293 {
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
294 dcFreeWX(pcb, sizeof(DCCallback));
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
295 }
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
296
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
297 void* dcbGetUserData(DCCallback* pcb)
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
298 {
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
299 return pcb->userdata;
3e629dc19168 initial from svn dyncall-1745
Daniel Adler
parents:
diff changeset
300 }