[gjs/wip/ptomato/mozjs31: 7/22] js: Use HandleValueArray as function param



commit 69bef5f347670d0057073f32806a1d60b246213b
Author: Philip Chimento <philip endlessm com>
Date:   Wed Oct 26 16:33:57 2016 -0700

    js: Use HandleValueArray as function param
    
    JS::HandleValueArray is a useful way to pass arrays of arguments around,
    has handy constructors such that you can pass in JS::CallArgs directly,
    and is now required for JS_New() and the JS_CallFunction family.
    Therefore we change some functions to take it instead of argc, argv:
    
    - gjs_call_function_value()
    - gjs_closure_invoke()
    - gjs_construct_dynamic_class()
    
    This requires some changes in the closure callback marshal as previously
    we were passing in an array that was longer with some empty elements at
    the end, and relying on argc not to fall off the end. Now that there is
    no argc parameter, we have to rearrange things a bit in that function.

 gi/boxed.cpp                |   18 ++++++++------
 gi/closure.cpp              |    9 +++----
 gi/closure.h                |    7 ++---
 gi/object.cpp               |    3 +-
 gi/value.cpp                |   55 ++++++++++++++++++------------------------
 gjs/jsapi-dynamic-class.cpp |    9 +++----
 gjs/jsapi-util.cpp          |   14 ++++------
 gjs/jsapi-util.h            |   18 ++++++--------
 8 files changed, 60 insertions(+), 73 deletions(-)
---
diff --git a/gi/boxed.cpp b/gi/boxed.cpp
index 2b95d0a..8b65204 100644
--- a/gi/boxed.cpp
+++ b/gi/boxed.cpp
@@ -339,7 +339,7 @@ boxed_invoke_constructor(JSContext             *context,
         return false;
 
     return gjs_call_function_value(context, JS::NullPtr(), js_constructor_func,
-                                   args.length(), args.array(), args.rval());
+                                   args, args.rval());
 }
 
 static bool
@@ -683,12 +683,12 @@ out:
 }
 
 static bool
-set_nested_interface_object (JSContext   *context,
-                             Boxed       *parent_priv,
-                             GIFieldInfo *field_info,
-                             GITypeInfo  *type_info,
-                             GIBaseInfo  *interface_info,
-                             JS::Value    value)
+set_nested_interface_object (JSContext      *context,
+                             Boxed          *parent_priv,
+                             GIFieldInfo    *field_info,
+                             GITypeInfo     *type_info,
+                             GIBaseInfo     *interface_info,
+                             JS::HandleValue value)
 {
     int offset;
     Boxed *proto_priv;
@@ -711,8 +711,10 @@ set_nested_interface_object (JSContext   *context,
      * to construct a new temporary object.
      */
     if (!boxed_get_copy_source(context, proto_priv, value, &source_priv)) {
+        JS::AutoValueArray<1> args(context);
+        args[0].set(value);
         JS::RootedObject tmp_object(context,
-                                    gjs_construct_object_dynamic(context, proto, 1, &value));
+            gjs_construct_object_dynamic(context, proto, args));
         if (!tmp_object)
             return false;
 
diff --git a/gi/closure.cpp b/gi/closure.cpp
index 8e8e7b5..4b1b07a 100644
--- a/gi/closure.cpp
+++ b/gi/closure.cpp
@@ -246,10 +246,9 @@ closure_set_invalid(gpointer  data,
 }
 
 void
-gjs_closure_invoke(GClosure              *closure,
-                   int                    argc,
-                   JS::Value             *argv,
-                   JS::MutableHandleValue retval)
+gjs_closure_invoke(GClosure                   *closure,
+                   const JS::HandleValueArray& args,
+                   JS::MutableHandleValue      retval)
 {
     Closure *c;
     JSContext *context;
@@ -278,7 +277,7 @@ gjs_closure_invoke(GClosure              *closure,
     if (!gjs_call_function_value(context,
                                  /* "this" object; null is some kind of default presumably */
                                  JS::NullPtr(),
-                                 v_closure, argc, argv, retval)) {
+                                 v_closure, args, retval)) {
         /* Exception thrown... */
         gjs_debug_closure("Closure invocation failed (exception should "
                           "have been thrown) closure %p callable %p",
diff --git a/gi/closure.h b/gi/closure.h
index 39cd54c..ddb25ba 100644
--- a/gi/closure.h
+++ b/gi/closure.h
@@ -36,10 +36,9 @@ GClosure*  gjs_closure_new           (JSContext    *context,
                                       const char   *description,
                                       bool          root_function);
 
-void gjs_closure_invoke(GClosure              *closure,
-                        int                    argc,
-                        JS::Value             *argv,
-                        JS::MutableHandleValue retval);
+void gjs_closure_invoke(GClosure                   *closure,
+                        const JS::HandleValueArray& args,
+                        JS::MutableHandleValue      retval);
 
 JSContext* gjs_closure_get_context   (GClosure     *closure);
 bool       gjs_closure_is_valid      (GClosure     *closure);
diff --git a/gi/object.cpp b/gi/object.cpp
index 879caf1..f5d0f82 100644
--- a/gi/object.cpp
+++ b/gi/object.cpp
@@ -1332,8 +1332,7 @@ GJS_NATIVE_CONSTRUCTOR_DECLARE(object_instance)
         return false;
 
     argv.rval().setUndefined();
-    ret = gjs_call_function_value(context, object, initer,
-                                  argc, argv.array(), argv.rval());
+    ret = gjs_call_function_value(context, object, initer, argv, argv.rval());
 
     if (argv.rval().isUndefined())
         argv.rval().setObject(*object);
diff --git a/gi/value.cpp b/gi/value.cpp
index 635a5e6..d32a6ff 100644
--- a/gi/value.cpp
+++ b/gi/value.cpp
@@ -120,14 +120,12 @@ closure_marshal(GClosure        *closure,
     JSContext *context;
     JSRuntime *runtime;
     JSObject *obj;
-    int argc;
-    int i;
+    unsigned i;
     GSignalQuery signal_query = { 0, };
     GISignalInfo *signal_info;
     bool *skip;
     int *array_len_indices_for;
     GITypeInfo **type_info_for;
-    int argv_index;
 
     gjs_debug_marshal(GJS_DEBUG_GCLOSURE,
                       "Marshal closure %p",
@@ -165,14 +163,9 @@ closure_marshal(GClosure        *closure,
     }
 
     obj = gjs_closure_get_callable(closure);
-    JS_BeginRequest(context);
+    JSAutoRequest ar(context);
     JSAutoCompartment ac(context, obj);
 
-    argc = n_param_values;
-    JS::RootedValue rval(context);
-    JS::AutoValueVector argv(context);
-    argv.resize(argc);
-
     if (marshal_data) {
         /* we are used for a signal handler */
         guint signal_id;
@@ -184,31 +177,31 @@ closure_marshal(GClosure        *closure,
         if (!signal_query.signal_id) {
             gjs_debug(GJS_DEBUG_GCLOSURE,
                       "Signal handler being called on invalid signal");
-            goto cleanup;
+            return;
         }
 
         if (signal_query.n_params + 1 != n_param_values) {
             gjs_debug(GJS_DEBUG_GCLOSURE,
                       "Signal handler being called with wrong number of parameters");
-            goto cleanup;
+            return;
         }
     }
 
     /* Check if any parameters, such as array lengths, need to be eliminated
      * before we invoke the closure.
      */
-    skip = g_newa(bool, argc);
-    memset(skip, 0, sizeof (bool) * argc);
-    array_len_indices_for = g_newa(int, argc);
-    for(i = 0; i < argc; i++)
+    skip = g_newa(bool, n_param_values);
+    memset(skip, 0, sizeof (bool) * n_param_values);
+    array_len_indices_for = g_newa(int, n_param_values);
+    for(i = 0; i < n_param_values; i++)
         array_len_indices_for[i] = -1;
-    type_info_for = g_newa(GITypeInfo *, argc);
-    memset(type_info_for, 0, sizeof (gpointer) * argc);
+    type_info_for = g_newa(GITypeInfo *, n_param_values);
+    memset(type_info_for, 0, sizeof (gpointer) * n_param_values);
 
     signal_info = get_signal_info_if_available(&signal_query);
     if (signal_info) {
         /* Start at argument 1, skip the instance parameter */
-        for (i = 1; i < argc; ++i) {
+        for (i = 1; i < n_param_values; ++i) {
             GIArgInfo *arg_info;
             int array_len_pos;
 
@@ -227,8 +220,10 @@ closure_marshal(GClosure        *closure,
         g_base_info_unref((GIBaseInfo *)signal_info);
     }
 
-    argv_index = 0;
-    for (i = 0; i < argc; ++i) {
+    JS::AutoValueVector argv(context);
+    argv.reserve(n_param_values);  /* May end up being less */
+    JS::RootedValue argv_to_append(context);
+    for (i = 0; i < n_param_values; ++i) {
         const GValue *gval = &param_values[i];
         bool no_copy;
         int array_len_index;
@@ -247,14 +242,14 @@ closure_marshal(GClosure        *closure,
         if (array_len_index != -1) {
             const GValue *array_len_gval = &param_values[array_len_index];
             res = gjs_value_from_array_and_length_values(context,
-                                                         argv.handleAt(argv_index),
+                                                         &argv_to_append,
                                                          type_info_for[i],
                                                          gval, array_len_gval,
                                                          no_copy, &signal_query,
                                                          array_len_index);
         } else {
             res = gjs_value_from_g_value_internal(context,
-                                                  argv.handleAt(argv_index),
+                                                  &argv_to_append,
                                                   gval, no_copy, &signal_query,
                                                   i);
         }
@@ -264,34 +259,32 @@ closure_marshal(GClosure        *closure,
                       "Unable to convert arg %d in order to invoke closure",
                       i);
             gjs_log_exception(context);
-            goto cleanup;
+            return;
         }
 
-        argv_index++;
+        argv.append(argv_to_append);
     }
 
-    for (i = 1; i < argc; i++)
+    for (i = 1; i < n_param_values; i++)
         if (type_info_for[i])
             g_base_info_unref((GIBaseInfo *)type_info_for[i]);
 
-    gjs_closure_invoke(closure, argv_index, &argv[0], &rval);
+    JS::RootedValue rval(context);
+    gjs_closure_invoke(closure, argv, &rval);
 
     if (return_value != NULL) {
         if (rval.isUndefined()) {
             /* something went wrong invoking, error should be set already */
-            goto cleanup;
+            return;
         }
 
         if (!gjs_value_to_g_value(context, rval, return_value)) {
             gjs_debug(GJS_DEBUG_GCLOSURE,
                       "Unable to convert return value when invoking closure");
             gjs_log_exception(context);
-            goto cleanup;
+            return;
         }
     }
-
- cleanup:
-    JS_EndRequest(context);
 }
 
 GClosure*
diff --git a/gjs/jsapi-dynamic-class.cpp b/gjs/jsapi-dynamic-class.cpp
index 4ac1071..559cfec 100644
--- a/gjs/jsapi-dynamic-class.cpp
+++ b/gjs/jsapi-dynamic-class.cpp
@@ -162,10 +162,9 @@ gjs_typecheck_instance(JSContext       *context,
 }
 
 JSObject*
-gjs_construct_object_dynamic(JSContext       *context,
-                             JS::HandleObject proto,
-                             unsigned         argc,
-                             JS::Value       *argv)
+gjs_construct_object_dynamic(JSContext           *context,
+                             JS::HandleObject     proto,
+                             JS::HandleValueArray args)
 {
     JSAutoRequest ar(context);
 
@@ -177,5 +176,5 @@ gjs_construct_object_dynamic(JSContext       *context,
                                            constructor_name, &constructor))
         return NULL;
 
-    return JS_New(context, constructor, argc, argv);
+    return JS_New(context, constructor, args);
 }
diff --git a/gjs/jsapi-util.cpp b/gjs/jsapi-util.cpp
index 81f97b9..6baa1ac 100644
--- a/gjs/jsapi-util.cpp
+++ b/gjs/jsapi-util.cpp
@@ -633,19 +633,17 @@ gjs_log_exception(JSContext  *context)
 }
 
 bool
-gjs_call_function_value(JSContext             *context,
-                        JS::HandleObject       obj,
-                        JS::HandleValue        fval,
-                        unsigned               argc,
-                        JS::Value             *argv,
-                        JS::MutableHandleValue rval)
+gjs_call_function_value(JSContext                  *context,
+                        JS::HandleObject            obj,
+                        JS::HandleValue             fval,
+                        const JS::HandleValueArray& args,
+                        JS::MutableHandleValue      rval)
 {
     bool result;
 
     JS_BeginRequest(context);
 
-    result = JS_CallFunctionValue(context, obj, fval,
-                                  argc, argv, rval.address());
+    result = JS_CallFunctionValue(context, obj, fval, args, rval);
 
     if (result)
         gjs_schedule_gc_if_needed(context);
diff --git a/gjs/jsapi-util.h b/gjs/jsapi-util.h
index 95be91d..ae4c96c 100644
--- a/gjs/jsapi-util.h
+++ b/gjs/jsapi-util.h
@@ -344,10 +344,9 @@ bool gjs_typecheck_instance(JSContext       *context,
                             JSClass         *static_clasp,
                             bool             throw_error);
 
-JSObject *gjs_construct_object_dynamic(JSContext       *context,
-                                       JS::HandleObject proto,
-                                       unsigned         argc,
-                                       JS::Value       *argv);
+JSObject *gjs_construct_object_dynamic(JSContext           *context,
+                                       JS::HandleObject     proto,
+                                       JS::HandleValueArray args);
 
 JSObject*   gjs_build_string_array           (JSContext       *context,
                                               gssize           array_length,
@@ -381,12 +380,11 @@ bool gjs_log_exception_full(JSContext       *context,
 char *gjs_value_debug_string(JSContext      *context,
                              JS::HandleValue value);
 
-bool gjs_call_function_value(JSContext             *context,
-                             JS::HandleObject       obj,
-                             JS::HandleValue        fval,
-                             unsigned               argc,
-                             JS::Value             *argv,
-                             JS::MutableHandleValue rval);
+bool gjs_call_function_value(JSContext                  *context,
+                             JS::HandleObject            obj,
+                             JS::HandleValue             fval,
+                             const JS::HandleValueArray& args,
+                             JS::MutableHandleValue      rval);
 
 void        gjs_error_reporter               (JSContext       *context,
                                               const char      *message,


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