Commit 72c3192773fe483f6517e343ecc3ea468ce73a4f

Anthony Green 2022-05-28T13:53:26

Pass copies of large structs on the stack

diff --git a/src/moxie/ffi.c b/src/moxie/ffi.c
index 1a65660..9d71673 100644
--- a/src/moxie/ffi.c
+++ b/src/moxie/ffi.c
@@ -1,5 +1,5 @@
 /* -----------------------------------------------------------------------
-   ffi.c - Copyright (C) 2012, 2013, 2018, 2021  Anthony Green
+   ffi.c - Copyright (C) 2012, 2013, 2018, 2021, 2022  Anthony Green
 
    Moxie Foreign Function Interface
 
@@ -128,6 +128,8 @@ void ffi_call(ffi_cif *cif,
 	      void **avalue)
 {
   extended_cif ecif;
+  ffi_type **arg_types = cif->arg_types;
+  int i, nargs = cif->nargs;
 
   ecif.cif = cif;
   ecif.avalue = avalue;
@@ -143,6 +145,20 @@ void ffi_call(ffi_cif *cif,
   else
     ecif.rvalue = rvalue;
 
+  /* If we have any large structure arguments, make a copy so we are passing
+     by value.  */
+  for (i = 0; i < nargs; i++)
+    {
+      ffi_type *at = arg_types[i];
+      int size = at->size;
+      if (at->type == FFI_TYPE_STRUCT && size > 16)
+        {
+          char *argcopy = alloca (size);
+          memcpy (argcopy, avalue[i], size);
+          avalue[i] = argcopy;
+        }
+    }
+
   switch (cif->abi)
     {
     case FFI_EABI: