diff dyncallback/dyncall_args_x64.c @ 557:b36a738c8975

- dyncallback: fix for calling back win/x64 C++ methods returning non-trivial aggregates (thanks Raphael!) - test/callback_plain_c++: * added test code for C++ method callbacks returning non-trivial aggregates * makefile linker command fix (was linking assuming c and not c++) - test/plain_c++: comments for completeness
author Tassilo Philipp
date Sat, 20 Aug 2022 21:04:15 +0200
parents 4d87bd4890b0
children 93ce63d72d59
line wrap: on
line diff
--- a/dyncallback/dyncall_args_x64.c	Mon Jul 11 23:17:50 2022 +0200
+++ b/dyncallback/dyncall_args_x64.c	Sat Aug 20 21:04:15 2022 +0200
@@ -149,30 +149,28 @@
 }
 
 
-/* A 16 byte struct would be sufficient for System V (because at most two of the four registers can be full). */
-/* But then it's much more complicated to copy the result to the correct registers in assembly. */
-typedef struct {
-  DClonglong r[2]; /* rax, rdx   */
-  DCdouble   x[2]; /* xmm0, xmm1 */
-} DCRetRegs_SysV;
-
 void dcbReturnAggr(DCArgs *args, DCValue *result, DCpointer ret)
 {
   int i;
   DCaggr *ag = *(args->aggrs++);
 
-  if(!ag) {
-    /* non-trivial aggr: all we can do is to provide the ptr to the output space, user has to make copy */
-    result->p = (DCpointer) args->reg_data.i[0];
-    return;
-  }
-
-  if (args->aggr_return_register >= 0) {
+  if(args->aggr_return_register >= 0) {
     DCpointer dest = (DCpointer) args->reg_data.i[args->aggr_return_register];
-    memcpy(dest, ret, ag->size);
+    if(ag)
+      memcpy(dest, ret, ag->size);
+    else {
+      /* non-trivial aggr: all we can do is to provide the ptr to the output space, user has to make copy */
+    }
     result->p = dest;
   } else {
 #if defined(DC_UNIX)
+    /* A 16 byte struct would be sufficient for System V (because at most two of the four registers can be full). */
+    /* But then it's much more complicated to copy the result to the correct registers in assembly. */
+    typedef struct {
+      DClonglong r[2]; /* rax, rdx   */
+      DCdouble   x[2]; /* xmm0, xmm1 */
+    } DCRetRegs_SysV;
+
     /* a max of 2 regs are used in this case, out of rax, rdx, xmm0 and xmm1 */
     /* space for 4 qwords is pointed to by (DCRetRegs_SysV*)result */
     DClonglong *intRegs = ((DCRetRegs_SysV*)result)->r;