Mercurial > pub > dyncall > dyncall
comparison dyncallback/dyncall_callback_x64.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 | f5577f6bf97a |
children | ba70fb631bea |
comparison
equal
deleted
inserted
replaced
532:d4bf63ab9164 | 533:71c884e610f0 |
---|---|
4 Library: dyncallback | 4 Library: dyncallback |
5 File: dyncallback/dyncall_callback_x64.c | 5 File: dyncallback/dyncall_callback_x64.c |
6 Description: Callback - Implementation for x64 | 6 Description: Callback - Implementation for x64 |
7 License: | 7 License: |
8 | 8 |
9 Copyright (c) 2007-2018 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. |
24 */ | 24 */ |
25 | 25 |
26 | 26 |
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_aggregate.h" | |
29 #include "dyncall_thunk.h" | 30 #include "dyncall_thunk.h" |
31 | |
30 | 32 |
31 /* Callback symbol. */ | 33 /* Callback symbol. */ |
32 extern void dcCallback_x64_sysv(); | 34 extern void dcCallback_x64_sysv(); |
33 extern void dcCallback_x64_win64(); | 35 extern void dcCallback_x64_win64(); |
34 | 36 |
35 struct DCCallback | 37 struct DCCallback |
36 { | 38 { |
37 DCThunk thunk; // offset 0, size 24 | 39 DCThunk thunk; /* offset 0, size 24 */ |
38 DCCallbackHandler* handler; // offset 24 | 40 DCCallbackHandler* handler; /* offset 24 */ |
39 void* userdata; // offset 32 | 41 void* userdata; /* offset 32 */ |
42 DCint aggr_return_register; /* offset 40 */ | |
43 DCint pad; /* offset 44 */ | |
44 DCaggr *const * aggrs; /* offset 48 */ | |
40 }; | 45 }; |
41 | 46 |
42 | 47 |
43 void dcbInitCallback(DCCallback* pcb, const char* signature, DCCallbackHandler* handler, void* userdata) | 48 void dcbInitCallback2(DCCallback* pcb, const DCsigchar* signature, DCCallbackHandler* handler, void* userdata, DCaggr *const * aggrs) |
44 { | 49 { |
45 pcb->handler = handler; | 50 const DCsigchar *ch = signature; |
46 pcb->userdata = userdata; | 51 DCint num_aggrs = 0; |
52 | |
53 pcb->handler = handler; | |
54 pcb->userdata = userdata; | |
55 pcb->aggrs = NULL; | |
56 pcb->aggr_return_register = -2; /* default, = no aggr as ret value */ | |
57 | |
58 while(*ch) | |
59 num_aggrs += (*(ch++) == DC_SIGCHAR_AGGREGATE); | |
60 | |
61 if(num_aggrs) | |
62 { | |
63 pcb->aggrs = aggrs; | |
64 | |
65 if (ch != signature && *(ch - 1) == DC_SIGCHAR_AGGREGATE) { | |
66 const DCaggr *ag = pcb->aggrs[num_aggrs - 1]; | |
67 | |
68 #if defined(DC_UNIX) | |
69 if (!ag || (ag->sysv_classes[0] == SYSVC_MEMORY)) { | |
70 #else | |
71 if (!ag || ag->size > 8) { | |
72 #endif | |
73 /* we need to "return" this aggr as a hidden pointer (first arg) */ | |
74 pcb->aggr_return_register = 0; | |
75 } else { | |
76 pcb->aggr_return_register = -1; /* small aggr, returned in register */ | |
77 } | |
78 } | |
79 } | |
47 } | 80 } |
48 | 81 |
49 | 82 |
50 DCCallback* dcbNewCallback(const char* signature, DCCallbackHandler* handler, void* userdata) | 83 DCCallback* dcbNewCallback2(const DCsigchar* signature, DCCallbackHandler* handler, void* userdata, DCaggr *const * aggrs) |
51 { | 84 { |
52 int err; | 85 int err; |
53 DCCallback* pcb; | 86 DCCallback* pcb; |
54 err = dcAllocWX(sizeof(DCCallback), (void**) &pcb); | 87 err = dcAllocWX(sizeof(DCCallback), (void**) &pcb); |
55 if(err) | 88 if(err) |
56 return NULL; | 89 return NULL; |
57 | 90 |
91 dcbInitCallback2(pcb, signature, handler, userdata, aggrs); | |
92 | |
58 #if defined (DC__OS_Win64) | 93 #if defined (DC__OS_Win64) |
59 dcbInitThunk(&pcb->thunk, dcCallback_x64_win64); | 94 dcbInitThunk(&pcb->thunk, dcCallback_x64_win64); |
60 #else | 95 #else |
61 dcbInitThunk(&pcb->thunk, dcCallback_x64_sysv); | 96 dcbInitThunk(&pcb->thunk, dcCallback_x64_sysv); |
62 #endif | 97 #endif |
63 dcbInitCallback(pcb, signature, handler, userdata); | |
64 | 98 |
65 err = dcInitExecWX(pcb, sizeof(DCCallback)); | 99 err = dcInitExecWX(pcb, sizeof(DCCallback)); |
66 if(err) { | 100 if(err) { |
67 dcFreeWX(pcb, sizeof(DCCallback)); | 101 dcFreeWX(pcb, sizeof(DCCallback)); |
68 return NULL; | 102 return NULL; |
69 } | 103 } |
70 | 104 |
71 return pcb; | 105 return pcb; |
72 } | 106 } |
73 | 107 |
74 | |
75 void dcbFreeCallback(DCCallback* pcb) | |
76 { | |
77 dcFreeWX(pcb, sizeof(DCCallback)); | |
78 } | |
79 | |
80 void* dcbGetUserData(DCCallback* pcb) | |
81 { | |
82 return pcb->userdata; | |
83 } |