summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAnthony Green <green@moxielogic.com>2022-05-28 13:53:26 -0400
committerAnthony Green <green@moxielogic.com>2022-05-28 13:53:26 -0400
commit72c3192773fe483f6517e343ecc3ea468ce73a4f (patch)
tree11cd621baced502b2c95ba77598f3be4a2d65580 /src
parente409225b41b60c490a094bb068e639a2364202fd (diff)
downloadlibffi-72c3192773fe483f6517e343ecc3ea468ce73a4f.tar.gz
Pass copies of large structs on the stack
Diffstat (limited to 'src')
-rw-r--r--src/moxie/ffi.c18
1 files changed, 17 insertions, 1 deletions
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: