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

« back to all changes in this revision

Viewing changes to debian/patches/02_function-Correctly-convert-from-ffi-return-values-to.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 e3fa476cf681d5e826d5b3494ef45e3daebf3cbf Mon Sep 17 00:00:00 2001
2
 
From: Colin Walters <walters@verbum.org>
3
 
Date: Wed, 21 Dec 2011 16:51:30 -0500
4
 
Subject: [PATCH 1/2] function: Correctly convert from ffi return values to
5
 
 GIArgument on big-endian
6
 
 
7
 
ffi always returns a long value even if a function's return type is
8
 
e.g. guint8.  We can't just directly give ffi_call a GIArgument to
9
 
store its return value because when the size of the return type is
10
 
smaller than long, it will write into the wrong address.
11
 
 
12
 
Instead cast the value at the C level.
13
 
 
14
 
Based on a patch from Ray Strode <rstrode@redhat.com>
15
 
 
16
 
https://bugzilla.gnome.org/show_bug.cgi?id=665152
17
 
---
18
 
 gi/function.c |  129 ++++++++++++++++++++++++++++++++++++++++++++++++++++++---
19
 
 1 files changed, 123 insertions(+), 6 deletions(-)
20
 
 
21
 
diff --git a/gi/function.c b/gi/function.c
22
 
index ef644da..dcba849 100644
23
 
--- a/gi/function.c
24
 
+++ b/gi/function.c
25
 
@@ -147,6 +147,61 @@ gjs_callback_trampoline_unref(GjsCallbackTrampoline *trampoline)
26
 
     }
27
 
 }
28
 
 
29
 
+static void
30
 
+set_return_ffi_arg_from_giargument (GITypeInfo  *ret_type,
31
 
+                                    void        *result,
32
 
+                                    GIArgument  *return_value)
33
 
+{
34
 
+    switch (g_type_info_get_tag(ret_type)) {
35
 
+    case GI_TYPE_TAG_INT8:
36
 
+        *(ffi_sarg *) result = return_value->v_int8;
37
 
+    case GI_TYPE_TAG_UINT8:
38
 
+        *(ffi_arg *) result = return_value->v_uint8;
39
 
+        break;
40
 
+    case GI_TYPE_TAG_INT16:
41
 
+        *(ffi_sarg *) result = return_value->v_int16;
42
 
+        break;
43
 
+    case GI_TYPE_TAG_UINT16:
44
 
+        *(ffi_arg *) result = return_value->v_uint16;
45
 
+        break;
46
 
+    case GI_TYPE_TAG_INT32:
47
 
+        *(ffi_sarg *) result = return_value->v_int32;
48
 
+        break;
49
 
+    case GI_TYPE_TAG_UINT32:
50
 
+    case GI_TYPE_TAG_BOOLEAN:
51
 
+    case GI_TYPE_TAG_UNICHAR:
52
 
+        *(ffi_arg *) result = return_value->v_uint32;
53
 
+               
54
 
+        break;
55
 
+    case GI_TYPE_TAG_INT64:
56
 
+        *(ffi_sarg *) result = return_value->v_int64;
57
 
+        break;
58
 
+    case GI_TYPE_TAG_UINT64:
59
 
+        *(ffi_arg *) result = return_value->v_uint64;
60
 
+        break;
61
 
+    case GI_TYPE_TAG_INTERFACE:
62
 
+        {
63
 
+            GIBaseInfo* interface_info;
64
 
+            GIInfoType interface_type;
65
 
+
66
 
+            interface_info = g_type_info_get_interface(ret_type);
67
 
+            interface_type = g_base_info_get_type(interface_info);
68
 
+
69
 
+            switch (interface_type) {
70
 
+            case GI_INFO_TYPE_ENUM:
71
 
+            case GI_INFO_TYPE_FLAGS:
72
 
+                *(ffi_sarg *) result = return_value->v_long;
73
 
+                break;
74
 
+            default:
75
 
+                *(ffi_arg *) result = (ffi_arg) return_value->v_pointer;
76
 
+                break;
77
 
+            }
78
 
+        }
79
 
+    default:
80
 
+        *(ffi_arg *) result = (ffi_arg) return_value->v_pointer;
81
 
+        break;
82
 
+    }
83
 
+}
84
 
 
85
 
 /* This is our main entry point for ffi_closure callbacks.
86
 
  * ffi_prep_closure is doing pure magic and replaces the original
87
 
@@ -166,6 +221,7 @@ gjs_callback_closure(ffi_cif *cif,
88
 
     int i, n_args, n_jsargs;
89
 
     jsval *jsargs, rval;
90
 
     GITypeInfo ret_type;
91
 
+    GArgument return_value;
92
 
     gboolean success = FALSE;
93
 
 
94
 
     trampoline = data;
95
 
@@ -215,10 +271,13 @@ gjs_callback_closure(ffi_cif *cif,
96
 
                                  GJS_ARGUMENT_RETURN_VALUE,
97
 
                                  FALSE,
98
 
                                  TRUE,
99
 
-                                 result)) {
100
 
+                                 &return_value)) {
101
 
         goto out;
102
 
     }
103
 
 
104
 
+    
105
 
+    set_return_ffi_arg_from_giargument(&ret_type, result, &return_value);
106
 
+
107
 
     success = TRUE;
108
 
 
109
 
 out:
110
 
@@ -306,6 +365,61 @@ get_length_from_arg (GArgument *arg, GITypeTag tag)
111
 
     }
112
 
 }
113
 
 
114
 
+/* Extract the correct bits from an ffi_arg return value into
115
 
+ * GIArgument: https://bugzilla.gnome.org/show_bug.cgi?id=665152
116
 
+ */
117
 
+static void
118
 
+set_gargument_from_ffi_return_value (GITypeInfo  *return_info,
119
 
+                                     GIArgument  *return_value,
120
 
+                                     ffi_arg      value)
121
 
+{
122
 
+    switch (g_type_info_get_tag (return_info)) {
123
 
+    case GI_TYPE_TAG_INT8:
124
 
+        return_value->v_int8 = (gint8) value;
125
 
+    case GI_TYPE_TAG_UINT8:
126
 
+        return_value->v_uint8 = (guint8) value;
127
 
+        break;
128
 
+    case GI_TYPE_TAG_INT16:
129
 
+        return_value->v_int16 = (gint16) value;
130
 
+        break;
131
 
+    case GI_TYPE_TAG_UINT16:
132
 
+        return_value->v_uint16 = (guint16) value; 
133
 
+        break;
134
 
+    case GI_TYPE_TAG_INT32:
135
 
+        return_value->v_int32 = (gint32) value;
136
 
+        break;
137
 
+    case GI_TYPE_TAG_UINT32:
138
 
+    case GI_TYPE_TAG_BOOLEAN:
139
 
+    case GI_TYPE_TAG_UNICHAR:
140
 
+        return_value->v_uint32 = (guint32) value;
141
 
+                        
142
 
+        break;
143
 
+    case GI_TYPE_TAG_INTERFACE:
144
 
+        {
145
 
+            GIBaseInfo* interface_info;
146
 
+            GIInfoType interface_type;
147
 
+
148
 
+            interface_info = g_type_info_get_interface(return_info);
149
 
+            interface_type = g_base_info_get_type(interface_info);
150
 
+
151
 
+            switch(interface_type) {
152
 
+            case GI_INFO_TYPE_ENUM:
153
 
+            case GI_INFO_TYPE_FLAGS:
154
 
+                return_value->v_int32 = (gint32) value;
155
 
+                break;
156
 
+            default:
157
 
+                return_value->v_pointer = (gpointer) value;
158
 
+                break;
159
 
+            }
160
 
+        }
161
 
+        break;
162
 
+    default:
163
 
+        return_value->v_pointer = (gpointer) value;
164
 
+        break;
165
 
+    }
166
 
+}
167
 
+
168
 
+
169
 
 static JSBool
170
 
 gjs_invoke_c_function(JSContext      *context,
171
 
                       Function       *function,
172
 
@@ -329,7 +443,8 @@ gjs_invoke_c_function(JSContext      *context,
173
 
     GArgument *out_arg_cvalues;
174
 
     GArgument *inout_original_arg_cvalues;
175
 
     gpointer *ffi_arg_pointers;
176
 
-    GArgument return_value;
177
 
+    ffi_arg return_value;
178
 
+    GArgument return_gargument;
179
 
 
180
 
     guint8 processed_c_args = 0;
181
 
     guint8 gi_argc, gi_arg_pos;
182
 
@@ -673,6 +788,8 @@ gjs_invoke_c_function(JSContext      *context,
183
 
 
184
 
             g_assert_cmpuint(next_rval, <, function->js_out_argc);
185
 
 
186
 
+            set_gargument_from_ffi_return_value(&return_info, &return_gargument, return_value);
187
 
+
188
 
             array_length_pos = g_type_info_get_array_length(&return_info);
189
 
             if (array_length_pos >= 0) {
190
 
                 GIArgInfo array_length_arg;
191
 
@@ -689,7 +806,7 @@ gjs_invoke_c_function(JSContext      *context,
192
 
                     arg_failed = !gjs_value_from_explicit_array(context,
193
 
                                                                 &return_values[next_rval],
194
 
                                                                 &return_info,
195
 
-                                                                &return_value,
196
 
+                                                                &return_gargument,
197
 
                                                                 JSVAL_TO_INT(length));
198
 
                 }
199
 
                 if (!arg_failed &&
200
 
@@ -697,17 +814,17 @@ gjs_invoke_c_function(JSContext      *context,
201
 
                                                       transfer,
202
 
                                                       &return_info,
203
 
                                                       JSVAL_TO_INT(length),
204
 
-                                                      &return_value))
205
 
+                                                      &return_gargument))
206
 
                     failed = TRUE;
207
 
             } else {
208
 
                 arg_failed = !gjs_value_from_g_argument(context, &return_values[next_rval],
209
 
-                                                        &return_info, &return_value);
210
 
+                                                        &return_info, &return_gargument);
211
 
                 /* Free GArgument, the jsval should have ref'd or copied it */
212
 
                 if (!arg_failed &&
213
 
                     !gjs_g_argument_release(context,
214
 
                                             transfer,
215
 
                                             &return_info,
216
 
-                                            &return_value))
217
 
+                                            &return_gargument))
218
 
                     failed = TRUE;
219
 
             }
220
 
             if (arg_failed)
221
 
1.7.8.3
222