diff 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
line wrap: on
line diff
--- a/dyncallback/dyncall_callback_x64.c	Tue May 31 18:35:06 2022 +0200
+++ b/dyncallback/dyncall_callback_x64.c	Tue May 31 19:29:34 2022 +0200
@@ -48,6 +48,7 @@
 void dcbInitCallback2(DCCallback* pcb, const DCsigchar* signature, DCCallbackHandler* handler, void* userdata, DCaggr *const * aggrs)
 {
   const DCsigchar *ch = signature;
+  int mode = DC_CALL_C_DEFAULT;
   DCint num_aggrs = 0;
 
   pcb->handler              = handler;
@@ -55,6 +56,12 @@
   pcb->aggrs                = NULL;
   pcb->aggr_return_register = -2; /* default, = no aggr as ret value */
 
+  if(*ch == DC_SIGCHAR_CC_PREFIX)
+  {
+    mode = dcGetModeFromCCSigChar(ch[1]);
+    ch += 2;
+  }
+
   while(*ch)
     num_aggrs += (*(ch++) == DC_SIGCHAR_AGGREGATE);
 
@@ -68,7 +75,9 @@
 #if defined(DC_UNIX)
       if (!ag || (ag->sysv_classes[0] == SYSVC_MEMORY)) {
 #else
-      if (!ag || ag->size > 8) {
+      if (mode == DC_CALL_C_DEFAULT_THIS) {
+        pcb->aggr_return_register = 1;
+      } else if (!ag || ag->size > 8 || /*not a power of 2?*/(ag->size & (ag->size - 1))) {
 #endif 
         /* we need to "return" this aggr as a hidden pointer (first arg) */
         pcb->aggr_return_register = 0;