Subject: bug#10203: closed (Re: bug#10203: [PATCH] FFI: Properly unpack small integer return values in closure call)

From: [email-masked] (GNU bug Tracking System)
Date: Mon, 19 Dec 2011 00:16:02 +0000

Your bug report

#10203: [PATCH] FFI: Properly unpack small integer return values in closure call

which was filed against the guile package, has been closed.

The explanation is attached below, along with your original report.
If you require more details, please reply to [email-masked].

-- 
10203: http://debbugs.gnu.org/cgi/bugreport.cgi?bug=10203
GNU Bug Tracking System
Contact [email-masked] with problems

Subject: Re: bug#10203: [PATCH] FFI: Properly unpack small integer return values in closure call
From: [email-masked] (Ludovic Courtès)
To: Andreas Schwab <[email-masked]>
Cc: [email-masked]
Date: Mon, 19 Dec 2011 01:13:31 +0100
List-Id: <debbugs-submit.debbugs.gnu.org>

Hi Andreas,

Andreas Schwab <[email-masked]> skribis:

> * libguile/foreign.c (unpack): Add parameter return_value_p.
> Properly store integer return values smaller than int.
> (scm_i_foreign_call): Update call to unpack.
> (invoke_closure): Likewise.

Applied, thank you!

Did you actually observe a problem on m68k or something?

Ludo’.

Subject: [PATCH] FFI: Properly unpack small integer return values in closure call
From: Andreas Schwab <[email-masked]>
To: [email-masked]
Date: Sat, 03 Dec 2011 12:17:46 +0100
List-Id: <debbugs-submit.debbugs.gnu.org>

* libguile/foreign.c (unpack): Add parameter return_value_p.
Properly store integer return values smaller than int.
(scm_i_foreign_call): Update call to unpack.
(invoke_closure): Likewise.
---
 libguile/foreign.c |   40 +++++++++++++++++++++++++++++++---------
 1 files changed, 31 insertions(+), 9 deletions(-)

diff --git a/libguile/foreign.c b/libguile/foreign.c
index bb88cf5..8351ae1 100644
--- a/libguile/foreign.c
+++ b/libguile/foreign.c
@@ -910,7 +910,7 @@ cif_to_procedure (SCM cif, SCM func_ptr)
 
 /* Set *LOC to the foreign representation of X with TYPE.  */
 static void
-unpack (const ffi_type *type, void *loc, SCM x)
+unpack (const ffi_type *type, void *loc, SCM x, int return_value_p)
 #define FUNC_NAME "scm_i_foreign_call"
 {
   switch (type->type)
@@ -921,23 +921,45 @@ unpack (const ffi_type *type, void *loc, SCM x)
     case FFI_TYPE_DOUBLE:
       *(double *) loc = scm_to_double (x);
       break;
+
+    /* For integer return values smaller than `int', libffi expects the
+       result in an `ffi_arg'-long buffer.  */
+
     case FFI_TYPE_UINT8:
-      *(scm_t_uint8 *) loc = scm_to_uint8 (x);
+      if (return_value_p)
+	*(ffi_arg *) loc = scm_to_uint8 (x);
+      else
+	*(scm_t_uint8 *) loc = scm_to_uint8 (x);
       break;
     case FFI_TYPE_SINT8:
-      *(scm_t_int8 *) loc = scm_to_int8 (x);
+      if (return_value_p)
+	*(ffi_arg *) loc = scm_to_int8 (x);
+      else
+	*(scm_t_int8 *) loc = scm_to_int8 (x);
       break;
     case FFI_TYPE_UINT16:
-      *(scm_t_uint16 *) loc = scm_to_uint16 (x);
+      if (return_value_p)
+	*(ffi_arg *) loc = scm_to_uint16 (x);
+      else
+	*(scm_t_uint16 *) loc = scm_to_uint16 (x);
       break;
     case FFI_TYPE_SINT16:
-      *(scm_t_int16 *) loc = scm_to_int16 (x);
+      if (return_value_p)
+	*(ffi_arg *) loc = scm_to_int16 (x);
+      else
+	*(scm_t_int16 *) loc = scm_to_int16 (x);
       break;
     case FFI_TYPE_UINT32:
-      *(scm_t_uint32 *) loc = scm_to_uint32 (x);
+      if (return_value_p)
+	*(ffi_arg *) loc = scm_to_uint32 (x);
+      else
+	*(scm_t_uint32 *) loc = scm_to_uint32 (x);
       break;
     case FFI_TYPE_SINT32:
-      *(scm_t_int32 *) loc = scm_to_int32 (x);
+      if (return_value_p)
+	*(ffi_arg *) loc = scm_to_int32 (x);
+      else
+	*(scm_t_int32 *) loc = scm_to_int32 (x);
       break;
     case FFI_TYPE_UINT64:
       *(scm_t_uint64 *) loc = scm_to_uint64 (x);
@@ -1073,7 +1095,7 @@ scm_i_foreign_call (SCM foreign, const SCM *argv)
       args[i] = (void *) ROUND_UP ((scm_t_uintptr) data + off,
 				   cif->arg_types[i]->alignment);
       assert ((scm_t_uintptr) args[i] % cif->arg_types[i]->alignment == 0);
-      unpack (cif->arg_types[i], args[i], argv[i]);
+      unpack (cif->arg_types[i], args[i], argv[i], 0);
     }
 
   /* Prepare space for the return value.  On some platforms, such as
@@ -1112,7 +1134,7 @@ invoke_closure (ffi_cif *cif, void *ret, void **args, void *data)
 
   result = scm_call_n (proc, argv, cif->nargs);
 
-  unpack (cif->rtype, ret, result);
+  unpack (cif->rtype, ret, result, 1);
 }
 
 SCM_DEFINE (scm_procedure_to_pointer, "procedure->pointer", 3, 0, 0,
-- 
1.7.7.4

-- 
Andreas Schwab, [email-masked]
GPG Key fingerprint = 58CA 54C7 6D53 942B 1756  01D3 44D5 214B 8276 4ED5
"And now for something completely different."