From a2c6904911577b51c2486ad7115a4311524d4a96 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ludovic=20Court=C3=A8s?= Date: Sat, 20 Mar 2010 16:45:14 +0100 Subject: [PATCH] Fix argument passing to foreign functions. * libguile/foreign.c (scm_i_foreign_call): When allocating room for DATA, use the sum of all the argument sizes, not `cif->bytes'. --- libguile/foreign.c | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/libguile/foreign.c b/libguile/foreign.c index 52ed10c57..1488b5848 100644 --- a/libguile/foreign.c +++ b/libguile/foreign.c @@ -952,16 +952,28 @@ scm_i_foreign_call (SCM foreign, SCM *argv) void *rvalue; void **args; unsigned i; + size_t arg_size; scm_t_ptrdiff off; cif = SCM_FOREIGN_POINTER (scm_car (foreign), ffi_cif); func = SCM_FOREIGN_POINTER (scm_cdr (foreign), void); - - /* arg pointers */ + + /* Argument pointers. */ args = alloca (sizeof(void*) * cif->nargs); - /* arg values, then return type value */ - data = alloca (ROUND_UP (cif->bytes, cif->rtype->alignment) - + cif->rtype->size); + + /* Compute the amount of memory needed to store all the argument values. + Note: as of libffi 3.0.9 `cif->bytes' is undocumented and is zero, so it + can't be used for that purpose. */ + for (i = 0, arg_size = 0; + i < cif->nargs; + i++, arg_size) + arg_size += ROUND_UP (cif->arg_types[i]->size, + cif->arg_types[i]->alignment); + + /* Space for argument values, followed by return value. */ + data = alloca (arg_size + + ROUND_UP (cif->rtype->size, cif->rtype->alignment)); + /* unpack argv to native values, setting argv pointers */ off = 0; for (i = 0; i < cif->nargs; i++)