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