r32467 - in /desktop/unstable/gjs/debian: changelog patches/02_function-Correctly-convert-from-ffi-return-values-to.patch patches/03_function-Fix-ffi-return-value-handling-on-32-bit.patch patches/series

biebl at users.alioth.debian.org biebl at users.alioth.debian.org
Thu Jan 26 17:46:12 UTC 2012


Author: biebl
Date: Thu Jan 26 17:46:11 2012
New Revision: 32467

URL: http://svn.debian.org/wsvn/pkg-gnome/?sc=1&rev=32467
Log:
* Cherry-pick patches from upstream Git to correctly handle ffi return
  values. Fixes test-suite failures on big-endian architectures.
  Closes: #610256
  - Add 02_function-Correctly-convert-from-ffi-return-values-to.patch.
  - Add 03_function-Fix-ffi-return-value-handling-on-32-bit.patch

Added:
    desktop/unstable/gjs/debian/patches/02_function-Correctly-convert-from-ffi-return-values-to.patch
    desktop/unstable/gjs/debian/patches/03_function-Fix-ffi-return-value-handling-on-32-bit.patch
Modified:
    desktop/unstable/gjs/debian/changelog
    desktop/unstable/gjs/debian/patches/series

Modified: desktop/unstable/gjs/debian/changelog
URL: http://svn.debian.org/wsvn/pkg-gnome/desktop/unstable/gjs/debian/changelog?rev=32467&op=diff
==============================================================================
--- desktop/unstable/gjs/debian/changelog [utf-8] (original)
+++ desktop/unstable/gjs/debian/changelog [utf-8] Thu Jan 26 17:46:11 2012
@@ -1,6 +1,11 @@
 gjs (1.30.1-1) UNRELEASED; urgency=low
 
   * New upstream release.
+  * Cherry-pick patches from upstream Git to correctly handle ffi return
+    values. Fixes test-suite failures on big-endian architectures.
+    Closes: #610256
+    - Add 02_function-Correctly-convert-from-ffi-return-values-to.patch.
+    - Add 03_function-Fix-ffi-return-value-handling-on-32-bit.patch
 
  -- Michael Biebl <biebl at debian.org>  Thu, 26 Jan 2012 17:59:02 +0100
 

Added: desktop/unstable/gjs/debian/patches/02_function-Correctly-convert-from-ffi-return-values-to.patch
URL: http://svn.debian.org/wsvn/pkg-gnome/desktop/unstable/gjs/debian/patches/02_function-Correctly-convert-from-ffi-return-values-to.patch?rev=32467&op=file
==============================================================================
--- desktop/unstable/gjs/debian/patches/02_function-Correctly-convert-from-ffi-return-values-to.patch (added)
+++ desktop/unstable/gjs/debian/patches/02_function-Correctly-convert-from-ffi-return-values-to.patch [utf-8] Thu Jan 26 17:46:11 2012
@@ -1,0 +1,223 @@
+From e3fa476cf681d5e826d5b3494ef45e3daebf3cbf Mon Sep 17 00:00:00 2001
+From: Colin Walters <walters at verbum.org>
+Date: Wed, 21 Dec 2011 16:51:30 -0500
+Subject: [PATCH 1/2] function: Correctly convert from ffi return values to
+ GIArgument on big-endian
+
+ffi always returns a long value even if a function's return type is
+e.g. guint8.  We can't just directly give ffi_call a GIArgument to
+store its return value because when the size of the return type is
+smaller than long, it will write into the wrong address.
+
+Instead cast the value at the C level.
+
+Based on a patch from Ray Strode <rstrode at redhat.com>
+
+https://bugzilla.gnome.org/show_bug.cgi?id=665152
+---
+ gi/function.c |  129 ++++++++++++++++++++++++++++++++++++++++++++++++++++++---
+ 1 files changed, 123 insertions(+), 6 deletions(-)
+
+diff --git a/gi/function.c b/gi/function.c
+index ef644da..dcba849 100644
+--- a/gi/function.c
++++ b/gi/function.c
+@@ -147,6 +147,61 @@ gjs_callback_trampoline_unref(GjsCallbackTrampoline *trampoline)
+     }
+ }
+ 
++static void
++set_return_ffi_arg_from_giargument (GITypeInfo  *ret_type,
++                                    void        *result,
++                                    GIArgument  *return_value)
++{
++    switch (g_type_info_get_tag(ret_type)) {
++    case GI_TYPE_TAG_INT8:
++        *(ffi_sarg *) result = return_value->v_int8;
++    case GI_TYPE_TAG_UINT8:
++        *(ffi_arg *) result = return_value->v_uint8;
++        break;
++    case GI_TYPE_TAG_INT16:
++        *(ffi_sarg *) result = return_value->v_int16;
++        break;
++    case GI_TYPE_TAG_UINT16:
++        *(ffi_arg *) result = return_value->v_uint16;
++        break;
++    case GI_TYPE_TAG_INT32:
++        *(ffi_sarg *) result = return_value->v_int32;
++        break;
++    case GI_TYPE_TAG_UINT32:
++    case GI_TYPE_TAG_BOOLEAN:
++    case GI_TYPE_TAG_UNICHAR:
++        *(ffi_arg *) result = return_value->v_uint32;
++		
++        break;
++    case GI_TYPE_TAG_INT64:
++        *(ffi_sarg *) result = return_value->v_int64;
++        break;
++    case GI_TYPE_TAG_UINT64:
++        *(ffi_arg *) result = return_value->v_uint64;
++        break;
++    case GI_TYPE_TAG_INTERFACE:
++        {
++            GIBaseInfo* interface_info;
++            GIInfoType interface_type;
++
++            interface_info = g_type_info_get_interface(ret_type);
++            interface_type = g_base_info_get_type(interface_info);
++
++            switch (interface_type) {
++            case GI_INFO_TYPE_ENUM:
++            case GI_INFO_TYPE_FLAGS:
++                *(ffi_sarg *) result = return_value->v_long;
++                break;
++            default:
++                *(ffi_arg *) result = (ffi_arg) return_value->v_pointer;
++                break;
++            }
++        }
++    default:
++        *(ffi_arg *) result = (ffi_arg) return_value->v_pointer;
++        break;
++    }
++}
+ 
+ /* This is our main entry point for ffi_closure callbacks.
+  * ffi_prep_closure is doing pure magic and replaces the original
+@@ -166,6 +221,7 @@ gjs_callback_closure(ffi_cif *cif,
+     int i, n_args, n_jsargs;
+     jsval *jsargs, rval;
+     GITypeInfo ret_type;
++    GArgument return_value;
+     gboolean success = FALSE;
+ 
+     trampoline = data;
+@@ -215,10 +271,13 @@ gjs_callback_closure(ffi_cif *cif,
+                                  GJS_ARGUMENT_RETURN_VALUE,
+                                  FALSE,
+                                  TRUE,
+-                                 result)) {
++                                 &return_value)) {
+         goto out;
+     }
+ 
++    
++    set_return_ffi_arg_from_giargument(&ret_type, result, &return_value);
++
+     success = TRUE;
+ 
+ out:
+@@ -306,6 +365,61 @@ get_length_from_arg (GArgument *arg, GITypeTag tag)
+     }
+ }
+ 
++/* Extract the correct bits from an ffi_arg return value into
++ * GIArgument: https://bugzilla.gnome.org/show_bug.cgi?id=665152
++ */
++static void
++set_gargument_from_ffi_return_value (GITypeInfo  *return_info,
++                                     GIArgument  *return_value,
++                                     ffi_arg      value)
++{
++    switch (g_type_info_get_tag (return_info)) {
++    case GI_TYPE_TAG_INT8:
++        return_value->v_int8 = (gint8) value;
++    case GI_TYPE_TAG_UINT8:
++        return_value->v_uint8 = (guint8) value;
++        break;
++    case GI_TYPE_TAG_INT16:
++        return_value->v_int16 = (gint16) value;
++        break;
++    case GI_TYPE_TAG_UINT16:
++        return_value->v_uint16 = (guint16) value; 
++        break;
++    case GI_TYPE_TAG_INT32:
++        return_value->v_int32 = (gint32) value;
++        break;
++    case GI_TYPE_TAG_UINT32:
++    case GI_TYPE_TAG_BOOLEAN:
++    case GI_TYPE_TAG_UNICHAR:
++        return_value->v_uint32 = (guint32) value;
++                        
++        break;
++    case GI_TYPE_TAG_INTERFACE:
++        {
++            GIBaseInfo* interface_info;
++            GIInfoType interface_type;
++
++            interface_info = g_type_info_get_interface(return_info);
++            interface_type = g_base_info_get_type(interface_info);
++
++            switch(interface_type) {
++            case GI_INFO_TYPE_ENUM:
++            case GI_INFO_TYPE_FLAGS:
++                return_value->v_int32 = (gint32) value;
++                break;
++            default:
++                return_value->v_pointer = (gpointer) value;
++                break;
++            }
++        }
++        break;
++    default:
++        return_value->v_pointer = (gpointer) value;
++        break;
++    }
++}
++
++
+ static JSBool
+ gjs_invoke_c_function(JSContext      *context,
+                       Function       *function,
+@@ -329,7 +443,8 @@ gjs_invoke_c_function(JSContext      *context,
+     GArgument *out_arg_cvalues;
+     GArgument *inout_original_arg_cvalues;
+     gpointer *ffi_arg_pointers;
+-    GArgument return_value;
++    ffi_arg return_value;
++    GArgument return_gargument;
+ 
+     guint8 processed_c_args = 0;
+     guint8 gi_argc, gi_arg_pos;
+@@ -673,6 +788,8 @@ gjs_invoke_c_function(JSContext      *context,
+ 
+             g_assert_cmpuint(next_rval, <, function->js_out_argc);
+ 
++            set_gargument_from_ffi_return_value(&return_info, &return_gargument, return_value);
++
+             array_length_pos = g_type_info_get_array_length(&return_info);
+             if (array_length_pos >= 0) {
+                 GIArgInfo array_length_arg;
+@@ -689,7 +806,7 @@ gjs_invoke_c_function(JSContext      *context,
+                     arg_failed = !gjs_value_from_explicit_array(context,
+                                                                 &return_values[next_rval],
+                                                                 &return_info,
+-                                                                &return_value,
++                                                                &return_gargument,
+                                                                 JSVAL_TO_INT(length));
+                 }
+                 if (!arg_failed &&
+@@ -697,17 +814,17 @@ gjs_invoke_c_function(JSContext      *context,
+                                                       transfer,
+                                                       &return_info,
+                                                       JSVAL_TO_INT(length),
+-                                                      &return_value))
++                                                      &return_gargument))
+                     failed = TRUE;
+             } else {
+                 arg_failed = !gjs_value_from_g_argument(context, &return_values[next_rval],
+-                                                        &return_info, &return_value);
++                                                        &return_info, &return_gargument);
+                 /* Free GArgument, the jsval should have ref'd or copied it */
+                 if (!arg_failed &&
+                     !gjs_g_argument_release(context,
+                                             transfer,
+                                             &return_info,
+-                                            &return_value))
++                                            &return_gargument))
+                     failed = TRUE;
+             }
+             if (arg_failed)
+-- 
+1.7.8.3
+

Added: desktop/unstable/gjs/debian/patches/03_function-Fix-ffi-return-value-handling-on-32-bit.patch
URL: http://svn.debian.org/wsvn/pkg-gnome/desktop/unstable/gjs/debian/patches/03_function-Fix-ffi-return-value-handling-on-32-bit.patch?rev=32467&op=file
==============================================================================
--- desktop/unstable/gjs/debian/patches/03_function-Fix-ffi-return-value-handling-on-32-bit.patch (added)
+++ desktop/unstable/gjs/debian/patches/03_function-Fix-ffi-return-value-handling-on-32-bit.patch [utf-8] Thu Jan 26 17:46:11 2012
@@ -1,0 +1,173 @@
+From 889b4fc62f1b384f6956315c209ce7d8b97ea5e2 Mon Sep 17 00:00:00 2001
+From: Colin Walters <walters at verbum.org>
+Date: Wed, 4 Jan 2012 14:05:04 -0500
+Subject: [PATCH 2/2] function: Fix ffi return value handling on 32 bit
+
+We had two major problems in marshaling.  One is that our conversion
+routine took an unsigned ffi_arg value, which we put signed values
+into. Also, our fallback case was copying from ffi_arg (which is
+always 64 bit on architectures we support) into the pointer member of
+the GIArgument union, but on 32 bit architecture pointers are just 32
+bit.
+
+Fix both of these by creating a new union, and then passing in a
+pointer to the correct member of it for the given return value type
+we're supplying to ffi.  We then need to again convert from this union
+type into a GIArgument.
+
+Debugged with lots of help from Ray Strode <rstrode at redhat.com>
+
+https://bugzilla.gnome.org/show_bug.cgi?id=665152
+---
+ gi/function.c |   68 +++++++++++++++++++++++++++++++++++++++++++-------------
+ 1 files changed, 52 insertions(+), 16 deletions(-)
+
+diff --git a/gi/function.c b/gi/function.c
+index dcba849..3755c20 100644
+--- a/gi/function.c
++++ b/gi/function.c
+@@ -155,6 +155,7 @@ set_return_ffi_arg_from_giargument (GITypeInfo  *ret_type,
+     switch (g_type_info_get_tag(ret_type)) {
+     case GI_TYPE_TAG_INT8:
+         *(ffi_sarg *) result = return_value->v_int8;
++        break;
+     case GI_TYPE_TAG_UINT8:
+         *(ffi_arg *) result = return_value->v_uint8;
+         break;
+@@ -198,7 +199,7 @@ set_return_ffi_arg_from_giargument (GITypeInfo  *ret_type,
+             }
+         }
+     default:
+-        *(ffi_arg *) result = (ffi_arg) return_value->v_pointer;
++        *(ffi_arg *) result = (ffi_arg) return_value->v_uint64;
+         break;
+     }
+ }
+@@ -367,33 +368,57 @@ get_length_from_arg (GArgument *arg, GITypeTag tag)
+ 
+ /* Extract the correct bits from an ffi_arg return value into
+  * GIArgument: https://bugzilla.gnome.org/show_bug.cgi?id=665152
++ *
++ * Also see the ffi_call man page - the storage requirements for return
++ * values are "special".
+  */
++union GjsFFIReturnValue {
++    ffi_arg  rv_ffi_arg;
++    ffi_sarg rv_ffi_sarg;
++    guint64  rv_u64;
++    gint64   rv_s64;
++    float    rv_float;
++    double   rv_double;
++};
+ static void
+-set_gargument_from_ffi_return_value (GITypeInfo  *return_info,
+-                                     GIArgument  *return_value,
+-                                     ffi_arg      value)
++set_gargument_from_ffi_return_value (GITypeInfo                  *return_info,
++                                     GIArgument                  *return_value,
++                                     union GjsFFIReturnValue     *value)
+ {
+     switch (g_type_info_get_tag (return_info)) {
+     case GI_TYPE_TAG_INT8:
+-        return_value->v_int8 = (gint8) value;
++        return_value->v_int8 = (gint8) value->rv_ffi_sarg;
++        break;
+     case GI_TYPE_TAG_UINT8:
+-        return_value->v_uint8 = (guint8) value;
++        return_value->v_uint8 = (guint8) value->rv_ffi_arg;
+         break;
+     case GI_TYPE_TAG_INT16:
+-        return_value->v_int16 = (gint16) value;
++        return_value->v_int16 = (gint16) value->rv_ffi_sarg;
+         break;
+     case GI_TYPE_TAG_UINT16:
+-        return_value->v_uint16 = (guint16) value; 
++        return_value->v_uint16 = (guint16) value->rv_ffi_arg;
+         break;
+     case GI_TYPE_TAG_INT32:
+-        return_value->v_int32 = (gint32) value;
++        return_value->v_int32 = (gint32) value->rv_ffi_sarg;
+         break;
+     case GI_TYPE_TAG_UINT32:
+     case GI_TYPE_TAG_BOOLEAN:
+     case GI_TYPE_TAG_UNICHAR:
+-        return_value->v_uint32 = (guint32) value;
++        return_value->v_uint32 = (guint32) value->rv_ffi_arg;
+                         
+         break;
++    case GI_TYPE_TAG_INT64:
++        return_value->v_int64 = (gint64) value->rv_s64;
++        break;
++    case GI_TYPE_TAG_UINT64:
++        return_value->v_uint64 = (guint64) value->rv_u64;
++        break;
++    case GI_TYPE_TAG_FLOAT:
++        return_value->v_float = value->rv_float;
++        break;
++    case GI_TYPE_TAG_DOUBLE:
++        return_value->v_double = value->rv_double;
++        break;
+     case GI_TYPE_TAG_INTERFACE:
+         {
+             GIBaseInfo* interface_info;
+@@ -405,16 +430,16 @@ set_gargument_from_ffi_return_value (GITypeInfo  *return_info,
+             switch(interface_type) {
+             case GI_INFO_TYPE_ENUM:
+             case GI_INFO_TYPE_FLAGS:
+-                return_value->v_int32 = (gint32) value;
++                return_value->v_int32 = (gint32) value->rv_ffi_sarg;
+                 break;
+             default:
+-                return_value->v_pointer = (gpointer) value;
++                return_value->v_pointer = (gpointer) value->rv_ffi_arg;
+                 break;
+             }
+         }
+         break;
+     default:
+-        return_value->v_pointer = (gpointer) value;
++        return_value->v_pointer = (gpointer) value->rv_ffi_arg;
+         break;
+     }
+ }
+@@ -443,7 +468,8 @@ gjs_invoke_c_function(JSContext      *context,
+     GArgument *out_arg_cvalues;
+     GArgument *inout_original_arg_cvalues;
+     gpointer *ffi_arg_pointers;
+-    ffi_arg return_value;
++    union GjsFFIReturnValue return_value;
++    gpointer return_value_p; /* Will point inside the union return_value */
+     GArgument return_gargument;
+ 
+     guint8 processed_c_args = 0;
+@@ -760,7 +786,17 @@ gjs_invoke_c_function(JSContext      *context,
+ 
+     g_assert_cmpuint(c_arg_pos, ==, c_argc);
+     g_assert_cmpuint(gi_arg_pos, ==, gi_argc);
+-    ffi_call(&(function->invoker.cif), function->invoker.native_address, &return_value, ffi_arg_pointers);
++
++    /* See comment for GjsFFIReturnValue above */
++    if (return_tag == GI_TYPE_TAG_FLOAT)
++        return_value_p = &return_value.rv_float;
++    else if (return_tag == GI_TYPE_TAG_DOUBLE)
++        return_value_p = &return_value.rv_double;
++    else if (return_tag == GI_TYPE_TAG_INT64 || return_tag == GI_TYPE_TAG_UINT64)
++        return_value_p = &return_value.rv_u64;
++    else
++        return_value_p = &return_value.rv_ffi_arg;
++    ffi_call(&(function->invoker.cif), function->invoker.native_address, return_value_p, ffi_arg_pointers);
+ 
+     gjs_runtime_pop_context(JS_GetRuntime(context));
+ 
+@@ -788,7 +824,7 @@ gjs_invoke_c_function(JSContext      *context,
+ 
+             g_assert_cmpuint(next_rval, <, function->js_out_argc);
+ 
+-            set_gargument_from_ffi_return_value(&return_info, &return_gargument, return_value);
++            set_gargument_from_ffi_return_value(&return_info, &return_gargument, &return_value);
+ 
+             array_length_pos = g_type_info_get_array_length(&return_info);
+             if (array_length_pos >= 0) {
+-- 
+1.7.8.3
+

Modified: desktop/unstable/gjs/debian/patches/series
URL: http://svn.debian.org/wsvn/pkg-gnome/desktop/unstable/gjs/debian/patches/series?rev=32467&op=diff
==============================================================================
--- desktop/unstable/gjs/debian/patches/series [utf-8] (original)
+++ desktop/unstable/gjs/debian/patches/series [utf-8] Thu Jan 26 17:46:11 2012
@@ -1,1 +1,3 @@
 01_remove_rpath_flags.patch
+02_function-Correctly-convert-from-ffi-return-values-to.patch
+03_function-Fix-ffi-return-value-handling-on-32-bit.patch




More information about the pkg-gnome-commits mailing list