comparison dyncallback/dyncall_callback_x64.c @ 546:ba70fb631bea

x64: * support for non-standard aggr-by-value packing (#pragma pack, etc.) * callbacks: handling callconv prefixes in signature
author Tassilo Philipp
date Tue, 31 May 2022 19:29:34 +0200
parents 71c884e610f0
children
comparison
equal deleted inserted replaced
545:ca28e9e3c644 546:ba70fb631bea
46 46
47 47
48 void dcbInitCallback2(DCCallback* pcb, const DCsigchar* signature, DCCallbackHandler* handler, void* userdata, DCaggr *const * aggrs) 48 void dcbInitCallback2(DCCallback* pcb, const DCsigchar* signature, DCCallbackHandler* handler, void* userdata, DCaggr *const * aggrs)
49 { 49 {
50 const DCsigchar *ch = signature; 50 const DCsigchar *ch = signature;
51 int mode = DC_CALL_C_DEFAULT;
51 DCint num_aggrs = 0; 52 DCint num_aggrs = 0;
52 53
53 pcb->handler = handler; 54 pcb->handler = handler;
54 pcb->userdata = userdata; 55 pcb->userdata = userdata;
55 pcb->aggrs = NULL; 56 pcb->aggrs = NULL;
56 pcb->aggr_return_register = -2; /* default, = no aggr as ret value */ 57 pcb->aggr_return_register = -2; /* default, = no aggr as ret value */
58
59 if(*ch == DC_SIGCHAR_CC_PREFIX)
60 {
61 mode = dcGetModeFromCCSigChar(ch[1]);
62 ch += 2;
63 }
57 64
58 while(*ch) 65 while(*ch)
59 num_aggrs += (*(ch++) == DC_SIGCHAR_AGGREGATE); 66 num_aggrs += (*(ch++) == DC_SIGCHAR_AGGREGATE);
60 67
61 if(num_aggrs) 68 if(num_aggrs)
66 const DCaggr *ag = pcb->aggrs[num_aggrs - 1]; 73 const DCaggr *ag = pcb->aggrs[num_aggrs - 1];
67 74
68 #if defined(DC_UNIX) 75 #if defined(DC_UNIX)
69 if (!ag || (ag->sysv_classes[0] == SYSVC_MEMORY)) { 76 if (!ag || (ag->sysv_classes[0] == SYSVC_MEMORY)) {
70 #else 77 #else
71 if (!ag || ag->size > 8) { 78 if (mode == DC_CALL_C_DEFAULT_THIS) {
79 pcb->aggr_return_register = 1;
80 } else if (!ag || ag->size > 8 || /*not a power of 2?*/(ag->size & (ag->size - 1))) {
72 #endif 81 #endif
73 /* we need to "return" this aggr as a hidden pointer (first arg) */ 82 /* we need to "return" this aggr as a hidden pointer (first arg) */
74 pcb->aggr_return_register = 0; 83 pcb->aggr_return_register = 0;
75 } else { 84 } else {
76 pcb->aggr_return_register = -1; /* small aggr, returned in register */ 85 pcb->aggr_return_register = -1; /* small aggr, returned in register */