[gjs] Skip user_data arguments in gjs_callback_closure



commit 269e4fd6a386898b2c853cefd3dfbf7910c5cce2
Author: Owen W. Taylor <otaylor fishsoup net>
Date:   Sun May 9 15:34:55 2010 -0400

    Skip user_data arguments in gjs_callback_closure
    
    The user_data argument to a callback now holds the GjsCallbackTrampoline
    instead of a JS provided value, so we must not cast it to a jsval
    and treat it as a function argument.
    
    This fixes segfaults when trying to get a stracktrace inside a callback.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=618195

 gi/function.c                  |   22 +++++++++++-----------
 test/js/testEverythingBasic.js |    7 +++++++
 2 files changed, 18 insertions(+), 11 deletions(-)
---
diff --git a/gi/function.c b/gi/function.c
index 1aac362..1eb0972 100644
--- a/gi/function.c
+++ b/gi/function.c
@@ -147,7 +147,7 @@ gjs_callback_closure(ffi_cif *cif,
                      void *data)
 {
     GjsCallbackTrampoline *trampoline;
-    int i, n_args;
+    int i, n_args, n_jsargs;
     jsval *jsargs, rval;
     GITypeInfo ret_type;
 
@@ -159,28 +159,28 @@ gjs_callback_closure(ffi_cif *cif,
     g_assert(n_args >= 0);
 
     jsargs = (jsval*)g_newa(jsval, n_args);
-    for (i = 0; i < n_args; i++) {
+    for (i = 0, n_jsargs = 0; i < n_args; i++) {
         GIArgInfo arg_info;
         GITypeInfo type_info;
 
         g_callable_info_load_arg(trampoline->info, i, &arg_info);
         g_arg_info_load_type(&arg_info, &type_info);
 
-        if (g_type_info_get_tag(&type_info) == GI_TYPE_TAG_VOID) {
-            jsargs[i] = *((jsval*)args[i]);
-        } else if (!gjs_value_from_g_argument(trampoline->context,
-                                              &jsargs[i],
-                                              &type_info,
-                                              args[i])) {
-            gjs_throw(trampoline->context, "could not convert argument of callback");
+        /* Skip void * arguments */
+        if (g_type_info_get_tag(&type_info) == GI_TYPE_TAG_VOID)
+            continue;
+
+        if (!gjs_value_from_g_argument(trampoline->context,
+                                       &jsargs[n_jsargs++],
+                                       &type_info,
+                                       args[i]))
             goto out;
-        }
     }
 
     if (!JS_CallFunctionValue(trampoline->context,
                               NULL,
                               trampoline->js_function,
-                              n_args,
+                              n_jsargs,
                               jsargs,
                               &rval)) {
         gjs_throw(trampoline->context, "Couldn't call callback");
diff --git a/test/js/testEverythingBasic.js b/test/js/testEverythingBasic.js
index 3501cec..ee837fc 100644
--- a/test/js/testEverythingBasic.js
+++ b/test/js/testEverythingBasic.js
@@ -177,22 +177,29 @@ function testStaticMeth() {
 }
 
 function testClosure() {
+    let arguments_length = -1;
     let someCallback = function() {
+                           arguments_length = arguments.length;
                            return 42;
                        };
 
     let i = Everything.test_closure(someCallback);
 
+    assertEquals('callback arguments length', 0, arguments_length);
     assertEquals('callback return value', 42, i);
 }
 
 function testClosureOneArg() {
+    let arguments_length = -1;
     let someCallback = function(someValue) {
+                           arguments_length = arguments.length;
+                           assertEquals(1, arguments.length);
                            return someValue;
                        };
 
     let i = Everything.test_closure_one_arg(someCallback, 42);
 
+    assertEquals('callback arguments length', 1, arguments_length);
     assertEquals('callback with one arg return value', 42, i);
 }
 



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]