~ubuntu-branches/ubuntu/raring/gjs/raring

« back to all changes in this revision

Viewing changes to debian/patches/03_function-Fix-ffi-return-value-handling-on-32-bit.patch

  • Committer: Package Import Robot
  • Author(s): Jeremy Bicha
  • Date: 2012-03-13 19:15:08 UTC
  • mfrom: (1.6.7)
  • Revision ID: package-import@ubuntu.com-20120313191508-k44let6s97mb45uv
Tags: 1.31.20-0ubuntu1
* New upstream release.
* Add gir package
* debian/control.in: Require minimum glib 2.31
* Drop all patches since they've been applied upstream

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
From 889b4fc62f1b384f6956315c209ce7d8b97ea5e2 Mon Sep 17 00:00:00 2001
2
 
From: Colin Walters <walters@verbum.org>
3
 
Date: Wed, 4 Jan 2012 14:05:04 -0500
4
 
Subject: [PATCH 2/2] function: Fix ffi return value handling on 32 bit
5
 
 
6
 
We had two major problems in marshaling.  One is that our conversion
7
 
routine took an unsigned ffi_arg value, which we put signed values
8
 
into. Also, our fallback case was copying from ffi_arg (which is
9
 
always 64 bit on architectures we support) into the pointer member of
10
 
the GIArgument union, but on 32 bit architecture pointers are just 32
11
 
bit.
12
 
 
13
 
Fix both of these by creating a new union, and then passing in a
14
 
pointer to the correct member of it for the given return value type
15
 
we're supplying to ffi.  We then need to again convert from this union
16
 
type into a GIArgument.
17
 
 
18
 
Debugged with lots of help from Ray Strode <rstrode@redhat.com>
19
 
 
20
 
https://bugzilla.gnome.org/show_bug.cgi?id=665152
21
 
---
22
 
 gi/function.c |   68 +++++++++++++++++++++++++++++++++++++++++++-------------
23
 
 1 files changed, 52 insertions(+), 16 deletions(-)
24
 
 
25
 
diff --git a/gi/function.c b/gi/function.c
26
 
index dcba849..3755c20 100644
27
 
--- a/gi/function.c
28
 
+++ b/gi/function.c
29
 
@@ -155,6 +155,7 @@ set_return_ffi_arg_from_giargument (GITypeInfo  *ret_type,
30
 
     switch (g_type_info_get_tag(ret_type)) {
31
 
     case GI_TYPE_TAG_INT8:
32
 
         *(ffi_sarg *) result = return_value->v_int8;
33
 
+        break;
34
 
     case GI_TYPE_TAG_UINT8:
35
 
         *(ffi_arg *) result = return_value->v_uint8;
36
 
         break;
37
 
@@ -198,7 +199,7 @@ set_return_ffi_arg_from_giargument (GITypeInfo  *ret_type,
38
 
             }
39
 
         }
40
 
     default:
41
 
-        *(ffi_arg *) result = (ffi_arg) return_value->v_pointer;
42
 
+        *(ffi_arg *) result = (ffi_arg) return_value->v_uint64;
43
 
         break;
44
 
     }
45
 
 }
46
 
@@ -367,33 +368,57 @@ get_length_from_arg (GArgument *arg, GITypeTag tag)
47
 
 
48
 
 /* Extract the correct bits from an ffi_arg return value into
49
 
  * GIArgument: https://bugzilla.gnome.org/show_bug.cgi?id=665152
50
 
+ *
51
 
+ * Also see the ffi_call man page - the storage requirements for return
52
 
+ * values are "special".
53
 
  */
54
 
+union GjsFFIReturnValue {
55
 
+    ffi_arg  rv_ffi_arg;
56
 
+    ffi_sarg rv_ffi_sarg;
57
 
+    guint64  rv_u64;
58
 
+    gint64   rv_s64;
59
 
+    float    rv_float;
60
 
+    double   rv_double;
61
 
+};
62
 
 static void
63
 
-set_gargument_from_ffi_return_value (GITypeInfo  *return_info,
64
 
-                                     GIArgument  *return_value,
65
 
-                                     ffi_arg      value)
66
 
+set_gargument_from_ffi_return_value (GITypeInfo                  *return_info,
67
 
+                                     GIArgument                  *return_value,
68
 
+                                     union GjsFFIReturnValue     *value)
69
 
 {
70
 
     switch (g_type_info_get_tag (return_info)) {
71
 
     case GI_TYPE_TAG_INT8:
72
 
-        return_value->v_int8 = (gint8) value;
73
 
+        return_value->v_int8 = (gint8) value->rv_ffi_sarg;
74
 
+        break;
75
 
     case GI_TYPE_TAG_UINT8:
76
 
-        return_value->v_uint8 = (guint8) value;
77
 
+        return_value->v_uint8 = (guint8) value->rv_ffi_arg;
78
 
         break;
79
 
     case GI_TYPE_TAG_INT16:
80
 
-        return_value->v_int16 = (gint16) value;
81
 
+        return_value->v_int16 = (gint16) value->rv_ffi_sarg;
82
 
         break;
83
 
     case GI_TYPE_TAG_UINT16:
84
 
-        return_value->v_uint16 = (guint16) value; 
85
 
+        return_value->v_uint16 = (guint16) value->rv_ffi_arg;
86
 
         break;
87
 
     case GI_TYPE_TAG_INT32:
88
 
-        return_value->v_int32 = (gint32) value;
89
 
+        return_value->v_int32 = (gint32) value->rv_ffi_sarg;
90
 
         break;
91
 
     case GI_TYPE_TAG_UINT32:
92
 
     case GI_TYPE_TAG_BOOLEAN:
93
 
     case GI_TYPE_TAG_UNICHAR:
94
 
-        return_value->v_uint32 = (guint32) value;
95
 
+        return_value->v_uint32 = (guint32) value->rv_ffi_arg;
96
 
                         
97
 
         break;
98
 
+    case GI_TYPE_TAG_INT64:
99
 
+        return_value->v_int64 = (gint64) value->rv_s64;
100
 
+        break;
101
 
+    case GI_TYPE_TAG_UINT64:
102
 
+        return_value->v_uint64 = (guint64) value->rv_u64;
103
 
+        break;
104
 
+    case GI_TYPE_TAG_FLOAT:
105
 
+        return_value->v_float = value->rv_float;
106
 
+        break;
107
 
+    case GI_TYPE_TAG_DOUBLE:
108
 
+        return_value->v_double = value->rv_double;
109
 
+        break;
110
 
     case GI_TYPE_TAG_INTERFACE:
111
 
         {
112
 
             GIBaseInfo* interface_info;
113
 
@@ -405,16 +430,16 @@ set_gargument_from_ffi_return_value (GITypeInfo  *return_info,
114
 
             switch(interface_type) {
115
 
             case GI_INFO_TYPE_ENUM:
116
 
             case GI_INFO_TYPE_FLAGS:
117
 
-                return_value->v_int32 = (gint32) value;
118
 
+                return_value->v_int32 = (gint32) value->rv_ffi_sarg;
119
 
                 break;
120
 
             default:
121
 
-                return_value->v_pointer = (gpointer) value;
122
 
+                return_value->v_pointer = (gpointer) value->rv_ffi_arg;
123
 
                 break;
124
 
             }
125
 
         }
126
 
         break;
127
 
     default:
128
 
-        return_value->v_pointer = (gpointer) value;
129
 
+        return_value->v_pointer = (gpointer) value->rv_ffi_arg;
130
 
         break;
131
 
     }
132
 
 }
133
 
@@ -443,7 +468,8 @@ gjs_invoke_c_function(JSContext      *context,
134
 
     GArgument *out_arg_cvalues;
135
 
     GArgument *inout_original_arg_cvalues;
136
 
     gpointer *ffi_arg_pointers;
137
 
-    ffi_arg return_value;
138
 
+    union GjsFFIReturnValue return_value;
139
 
+    gpointer return_value_p; /* Will point inside the union return_value */
140
 
     GArgument return_gargument;
141
 
 
142
 
     guint8 processed_c_args = 0;
143
 
@@ -760,7 +786,17 @@ gjs_invoke_c_function(JSContext      *context,
144
 
 
145
 
     g_assert_cmpuint(c_arg_pos, ==, c_argc);
146
 
     g_assert_cmpuint(gi_arg_pos, ==, gi_argc);
147
 
-    ffi_call(&(function->invoker.cif), function->invoker.native_address, &return_value, ffi_arg_pointers);
148
 
+
149
 
+    /* See comment for GjsFFIReturnValue above */
150
 
+    if (return_tag == GI_TYPE_TAG_FLOAT)
151
 
+        return_value_p = &return_value.rv_float;
152
 
+    else if (return_tag == GI_TYPE_TAG_DOUBLE)
153
 
+        return_value_p = &return_value.rv_double;
154
 
+    else if (return_tag == GI_TYPE_TAG_INT64 || return_tag == GI_TYPE_TAG_UINT64)
155
 
+        return_value_p = &return_value.rv_u64;
156
 
+    else
157
 
+        return_value_p = &return_value.rv_ffi_arg;
158
 
+    ffi_call(&(function->invoker.cif), function->invoker.native_address, return_value_p, ffi_arg_pointers);
159
 
 
160
 
     gjs_runtime_pop_context(JS_GetRuntime(context));
161
 
 
162
 
@@ -788,7 +824,7 @@ gjs_invoke_c_function(JSContext      *context,
163
 
 
164
 
             g_assert_cmpuint(next_rval, <, function->js_out_argc);
165
 
 
166
 
-            set_gargument_from_ffi_return_value(&return_info, &return_gargument, return_value);
167
 
+            set_gargument_from_ffi_return_value(&return_info, &return_gargument, &return_value);
168
 
 
169
 
             array_length_pos = g_type_info_get_array_length(&return_info);
170
 
             if (array_length_pos >= 0) {
171
 
1.7.8.3
172