comparison dyncallback/dyncall_callback_x86.c @ 533:71c884e610f0

- integration of patches from Raphael Luba, Thekla, Inc.: * integration of aggregate-by-value (struct, union) support patch for x64 (win and sysv) * windows/x64 asm additions to specify how stack unwinds (help for debuggers, exception handling, etc.) * see Changelog for details - new calling convention modes for thiscalls (platform agnostic, was specific before) * new signature character for platform agnostic thiscalls ('*' / DC_SIGCHAR_CC_THISCALL) - dcCallF(), dcVCallF(), dcArgF() and dcVArgF(): * added support for aggregates-by-value (wasn't part of patch) * change that those functions don't implicitly call dcReset() anymore, which was unflexible (breaking change) - added macros to feature test implementation for aggregate-by-value and syscall support - changed libdyncall_s.lib and libdyncallback_s.lib order in callback test makefiles, as some toolchains are picky about order - doc: * man page updates to describe aggregate interface * manual overview changes to highlight platforms with aggregate-by-value support - test/plain: replaced tests w/ old/stale sctruct interface with new aggregate one
author Tassilo Philipp
date Thu, 21 Apr 2022 13:35:47 +0200
parents ddfb9577a00e
children
comparison
equal deleted inserted replaced
532:d4bf63ab9164 533:71c884e610f0
4 Library: dyncallback 4 Library: dyncallback
5 File: dyncallback/dyncall_callback_x86.c 5 File: dyncallback/dyncall_callback_x86.c
6 Description: Callback - Implementation for x86 6 Description: Callback - Implementation for x86
7 License: 7 License:
8 8
9 Copyright (c) 2007-2020 Daniel Adler <dadler@uni-goettingen.de>, 9 Copyright (c) 2007-2022 Daniel Adler <dadler@uni-goettingen.de>,
10 Tassilo Philipp <tphilipp@potion-studios.com> 10 Tassilo Philipp <tphilipp@potion-studios.com>
11 11
12 Permission to use, copy, modify, and distribute this software for any 12 Permission to use, copy, modify, and distribute this software for any
13 purpose with or without fee is hereby granted, provided that the above 13 purpose with or without fee is hereby granted, provided that the above
14 copyright notice and this permission notice appear in all copies. 14 copyright notice and this permission notice appear in all copies.
27 #include "dyncall_callback.h" 27 #include "dyncall_callback.h"
28 #include "dyncall_alloc_wx.h" 28 #include "dyncall_alloc_wx.h"
29 #include "dyncall_thunk.h" 29 #include "dyncall_thunk.h"
30 #include "dyncall_args_x86.h" 30 #include "dyncall_args_x86.h"
31 31
32
32 /* Callback symbol. */ 33 /* Callback symbol. */
33 extern void dcCallbackThunkEntry(); 34 extern void dcCallbackThunkEntry();
34 35
35 struct DCCallback 36 struct DCCallback
36 { 37 {
45 /* compute stacksize for callee cleanup calling conventions: 46 /* compute stacksize for callee cleanup calling conventions:
46 * 47 *
47 * cdecl,stdcall,thiscall_ms,fastcall_ms,fastcall_gnu 48 * cdecl,stdcall,thiscall_ms,fastcall_ms,fastcall_gnu
48 */ 49 */
49 50
50 static int dcbCleanupSize_x86_cdecl(const char* signature) 51 static int dcbCleanupSize_x86_cdecl(const DCsigchar* signature)
51 { 52 {
52 return 0; 53 return 0;
53 } 54 }
54 55
55 static int dcbCleanupSize_x86_std(const char* signature) 56 static int dcbCleanupSize_x86_std(const DCsigchar* signature)
56 { 57 {
57 const char* ptr = signature; 58 const DCsigchar* ptr = signature;
58 int size = 0; 59 int size = 0;
59 char ch; 60 DCsigchar ch;
60 while( (ch = *ptr++) != DC_SIGCHAR_ENDARG ) { 61 while( (ch = *ptr++) != DC_SIGCHAR_ENDARG ) {
61 switch(ch) { 62 switch(ch) {
62 case DC_SIGCHAR_BOOL: 63 case DC_SIGCHAR_BOOL:
63 case DC_SIGCHAR_CHAR: 64 case DC_SIGCHAR_CHAR:
64 case DC_SIGCHAR_SHORT: 65 case DC_SIGCHAR_SHORT:
81 } 82 }
82 } 83 }
83 return size; 84 return size;
84 } 85 }
85 86
86 static int dcbCleanupSize_x86_this_ms(const char* signature) 87 static int dcbCleanupSize_x86_this_ms(const DCsigchar* signature)
87 { 88 {
88 const char* ptr = signature; 89 const DCsigchar* ptr = signature;
89 int size = 0; 90 int size = 0;
90 char ch; 91 DCsigchar ch;
91 while( (ch = *ptr++) != DC_SIGCHAR_ENDARG ) 92 while( (ch = *ptr++) != DC_SIGCHAR_ENDARG )
92 { 93 {
93 switch(ch) 94 switch(ch)
94 { 95 {
95 case DC_SIGCHAR_BOOL: 96 case DC_SIGCHAR_BOOL:
114 } 115 }
115 } 116 }
116 return size; 117 return size;
117 } 118 }
118 119
119 static int dcbCleanupSize_x86_fast_ms(const char* signature) 120 static int dcbCleanupSize_x86_fast_ms(const DCsigchar* signature)
120 { 121 {
121 const char* ptr = signature; 122 const DCsigchar* ptr = signature;
122 int size = 0; 123 int size = 0;
123 int regs = 0; 124 int regs = 0;
124 char ch; 125 DCsigchar ch;
125 while( (ch = *ptr++) != DC_SIGCHAR_ENDARG ) 126 while( (ch = *ptr++) != DC_SIGCHAR_ENDARG )
126 { 127 {
127 switch(ch) 128 switch(ch)
128 { 129 {
129 case DC_SIGCHAR_BOOL: 130 case DC_SIGCHAR_BOOL:
153 } 154 }
154 } 155 }
155 return size; 156 return size;
156 } 157 }
157 158
158 static int dcbCleanupSize_x86_fast_gnu(const char* signature) 159 static int dcbCleanupSize_x86_fast_gnu(const DCsigchar* signature)
159 { 160 {
160 const char* ptr = signature; 161 const DCsigchar* ptr = signature;
161 char ch; 162 DCsigchar ch;
162 int size = 0; 163 int size = 0;
163 int regs = 0; 164 int regs = 0;
164 while( (ch = *ptr++) != DC_SIGCHAR_ENDARG ) { 165 while( (ch = *ptr++) != DC_SIGCHAR_ENDARG ) {
165 switch(ch) { 166 switch(ch) {
166 case DC_SIGCHAR_FLOAT: 167 case DC_SIGCHAR_FLOAT:
181 } 182 }
182 } 183 }
183 return size; 184 return size;
184 } 185 }
185 186
186 void dcbInitCallback(DCCallback* pcb, const char* signature, DCCallbackHandler* handler, void* userdata) 187
187 { 188 void dcbInitCallback2(DCCallback* pcb, const DCsigchar* signature, DCCallbackHandler* handler, void* userdata, DCaggr *const * aggrs)
188 const char* ptr; 189 {
190 const DCsigchar* ptr;
189 int mode; 191 int mode;
190 pcb->handler = handler; 192 pcb->handler = handler;
191 pcb->userdata = userdata; 193 pcb->userdata = userdata;
192 194
193 ptr = signature; 195 ptr = signature;
219 break; 221 break;
220 case DC_CALL_C_X86_WIN32_FAST_GNU: 222 case DC_CALL_C_X86_WIN32_FAST_GNU:
221 pcb->args_vt = &dcArgsVT_fast_gnu; 223 pcb->args_vt = &dcArgsVT_fast_gnu;
222 pcb->stack_cleanup = dcbCleanupSize_x86_fast_gnu(ptr); 224 pcb->stack_cleanup = dcbCleanupSize_x86_fast_gnu(ptr);
223 break; 225 break;
226 #if defined(DC_WINDOWS) && defined(DC__C_MSVC)
227 case DC_CALL_C_DEFAULT_THIS:
228 #endif
224 case DC_CALL_C_X86_WIN32_THIS_MS: 229 case DC_CALL_C_X86_WIN32_THIS_MS:
225 pcb->args_vt = &dcArgsVT_this_ms; 230 pcb->args_vt = &dcArgsVT_this_ms;
226 pcb->stack_cleanup = dcbCleanupSize_x86_this_ms(ptr); 231 pcb->stack_cleanup = dcbCleanupSize_x86_this_ms(ptr);
227 break; 232 break;
228 } 233 }
246 } 251 }
247 } 252 }
248 #endif 253 #endif
249 } 254 }
250 255
251 /* 256
252 * callback constructor 257 DCCallback* dcbNewCallback2(const DCsigchar* signature, DCCallbackHandler* handler, void* userdata, DCaggr *const * aggrs)
253 */ 258 {
254 DCCallback* dcbNewCallback(const char* signature, DCCallbackHandler* handler, void* userdata)
255 {
256 int err;
257 DCCallback* pcb; 259 DCCallback* pcb;
258 err = dcAllocWX(sizeof(DCCallback), (void**) &pcb); 260 int err = dcAllocWX(sizeof(DCCallback), (void**) &pcb);
259 if(err) 261 if(err)
260 return NULL; 262 return NULL;
261 263
264 dcbInitCallback2(pcb, signature, handler, userdata, aggrs);
262 dcbInitThunk(&pcb->thunk, dcCallbackThunkEntry); 265 dcbInitThunk(&pcb->thunk, dcCallbackThunkEntry);
263 dcbInitCallback(pcb, signature, handler, userdata);
264 266
265 err = dcInitExecWX(pcb, sizeof(DCCallback)); 267 err = dcInitExecWX(pcb, sizeof(DCCallback));
266 if(err) { 268 if(err) {
267 dcFreeWX(pcb, sizeof(DCCallback)); 269 dcFreeWX(pcb, sizeof(DCCallback));
268 return NULL; 270 return NULL;
269 } 271 }
270 272
271 return pcb; 273 return pcb;
272 } 274 }
273 275
274 /*
275 * free
276 */
277
278 void dcbFreeCallback(DCCallback* pcb)
279 {
280 dcFreeWX(pcb, sizeof(DCCallback));
281 }
282
283 void* dcbGetUserData(DCCallback* pcb)
284 {
285 return pcb->userdata;
286 }