[gjs] js: Root throw_invalid_argument() in arg.cpp



commit 6864b3ffcafc09eb16124d83ab66417468b0d5dc
Author: Philip Chimento <philip endlessm com>
Date:   Thu Oct 27 16:55:48 2016 -0700

    js: Root throw_invalid_argument() in arg.cpp
    
    Starting in throw_invalid_argument() and working backwards, we cause
    another cascade of GC rooting changes.
    
    This, by necessity, adds a couple of unnecessary roots in
    gjs_invoke_c_function() which is quite unfortunate. (Eventually the vp
    array comes from a JS::CallArgs somewhere, which is rooted, so we should
    not have to re-root any of its values.) In mozjs31, we will be able to
    remove these again, because it introduces JS::HandleValueArray for
    passing around references to arrays of rooted values.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=742249

 gi/arg.cpp      |   42 +++++++++++++++++++++---------------------
 gi/arg.h        |   20 ++++++++++----------
 gi/boxed.cpp    |   16 ++++++++--------
 gi/function.cpp |   31 +++++++++++++++++++------------
 4 files changed, 58 insertions(+), 51 deletions(-)
---
diff --git a/gi/arg.cpp b/gi/arg.cpp
index 7f9ed7b..93467d9 100644
--- a/gi/arg.cpp
+++ b/gi/arg.cpp
@@ -263,7 +263,6 @@ gjs_array_to_g_list(JSContext   *context,
     guint32 i;
     GList *list;
     GSList *slist;
-    JS::Value elem;
 
     list = NULL;
     slist = NULL;
@@ -282,11 +281,12 @@ gjs_array_to_g_list(JSContext   *context,
         transfer = GI_TRANSFER_NOTHING;
     }
 
+    JS::RootedValue elem(context);
     for (i = 0; i < length; ++i) {
         GArgument elem_arg = { 0 };
 
         elem = JS::UndefinedValue();
-        if (!JS_GetElement(context, array_value.toObjectOrNull(), i, &elem)) {
+        if (!JS_GetElement(context, array_value.toObjectOrNull(), i, elem.address())) {
             gjs_throw(context,
                       "Missing array element %u",
                       i);
@@ -368,13 +368,13 @@ gjs_object_to_g_hash(JSContext   *context,
     /* Don't use key/value destructor functions here, because we can't
      * construct correct ones in general if the value type is complex.
      * Rely on the type-aware g_argument_release functions. */
-   result = g_hash_table_new(g_str_hash, g_str_equal);
+    result = g_hash_table_new(g_str_hash, g_str_equal);
 
-   while (!JSID_IS_VOID(prop_id)) {
-        JS::Value key_js, val_js;
+    JS::RootedValue key_js(context), val_js(context);
+    while (!JSID_IS_VOID(prop_id)) {
         GArgument key_arg = { 0 }, val_arg = { 0 };
 
-        if (!JS_IdToValue(context, prop_id, &key_js))
+        if (!JS_IdToValue(context, prop_id, key_js.address()))
             goto free_hash_and_fail;
 
         /* Type check key type. */
@@ -385,7 +385,7 @@ gjs_object_to_g_hash(JSContext   *context,
                                      &key_arg))
             goto free_hash_and_fail;
 
-        if (!JS_GetPropertyById(context, props, prop_id, &val_js))
+        if (!JS_GetPropertyById(context, props, prop_id, val_js.address()))
             goto free_hash_and_fail;
 
         /* Type check and convert value to a c type */
@@ -715,20 +715,20 @@ gjs_array_to_ptrarray(JSContext   *context,
                       void       **arr_p)
 {
     unsigned int i;
+    JS::RootedValue elem(context);
 
     /* Always one extra element, to cater for null terminated arrays */
     void **array = (void **) g_malloc((length + 1) * sizeof(gpointer));
     array[length] = NULL;
 
     for (i = 0; i < length; i++) {
-        JS::Value elem;
         GIArgument arg;
         arg.v_pointer = NULL;
 
         bool success;
 
         elem = JS::UndefinedValue();
-        if (!JS_GetElement(context, array_value.toObjectOrNull(), i, &elem)) {
+        if (!JS_GetElement(context, array_value.toObjectOrNull(), i, elem.address())) {
             g_free(array);
             gjs_throw(context,
                       "Missing array element %u",
@@ -1068,7 +1068,7 @@ type_tag_to_human_string(GITypeInfo *type_info)
 
 static void
 throw_invalid_argument(JSContext      *context,
-                       JS::Value       value,
+                       JS::HandleValue value,
                        GITypeInfo     *arginfo,
                        const char     *arg_name,
                        GjsArgumentType arg_type)
@@ -1084,7 +1084,7 @@ throw_invalid_argument(JSContext      *context,
 
 static bool
 gjs_array_to_explicit_array_internal(JSContext       *context,
-                                     JS::Value        value,
+                                     JS::HandleValue  value,
                                      GITypeInfo      *type_info,
                                      const char      *arg_name,
                                      GjsArgumentType  arg_type,
@@ -1150,7 +1150,7 @@ gjs_array_to_explicit_array_internal(JSContext       *context,
 
 bool
 gjs_value_to_g_argument(JSContext      *context,
-                        JS::Value       value,
+                        JS::HandleValue value,
                         GITypeInfo     *type_info,
                         const char     *arg_name,
                         GjsArgumentType arg_type,
@@ -1944,10 +1944,10 @@ gjs_g_argument_init_default(JSContext      *context,
 }
 
 bool
-gjs_value_to_arg(JSContext  *context,
-                 JS::Value   value,
-                 GIArgInfo  *arg_info,
-                 GArgument  *arg)
+gjs_value_to_arg(JSContext      *context,
+                 JS::HandleValue value,
+                 GIArgInfo      *arg_info,
+                 GIArgument     *arg)
 {
     GITypeInfo type_info;
 
@@ -1964,11 +1964,11 @@ gjs_value_to_arg(JSContext  *context,
 }
 
 bool
-gjs_value_to_explicit_array (JSContext  *context,
-                             JS::Value   value,
-                             GIArgInfo  *arg_info,
-                             GArgument  *arg,
-                             gsize      *length_p)
+gjs_value_to_explicit_array (JSContext      *context,
+                             JS::HandleValue value,
+                             GIArgInfo      *arg_info,
+                             GIArgument     *arg,
+                             size_t         *length_p)
 {
     GITypeInfo type_info;
 
diff --git a/gi/arg.h b/gi/arg.h
index a0ab1b6..7c96c2f 100644
--- a/gi/arg.h
+++ b/gi/arg.h
@@ -43,23 +43,23 @@ typedef enum {
     GJS_ARGUMENT_ARRAY_ELEMENT
 } GjsArgumentType;
 
-bool gjs_value_to_arg (JSContext *context,
-                       JS::Value  value,
-                       GIArgInfo *arg_info,
-                       GArgument *arg);
+bool gjs_value_to_arg(JSContext      *context,
+                      JS::HandleValue value,
+                      GIArgInfo      *arg_info,
+                      GIArgument     *arg);
 
-bool gjs_value_to_explicit_array (JSContext *context,
-                                  JS::Value  value,
-                                  GIArgInfo *arg_info,
-                                  GArgument *arg,
-                                  gsize     *length_p);
+bool gjs_value_to_explicit_array(JSContext       *context,
+                                 JS::HandleValue  value,
+                                 GIArgInfo       *arg_info,
+                                 GIArgument      *arg,
+                                 size_t          *length_p);
 
 void gjs_g_argument_init_default (JSContext      *context,
                                   GITypeInfo     *type_info,
                                   GArgument      *arg);
 
 bool gjs_value_to_g_argument (JSContext      *context,
-                              JS::Value       value,
+                              JS::HandleValue value,
                               GITypeInfo     *type_info,
                               const char     *arg_name,
                               GjsArgumentType argument_type,
diff --git a/gi/boxed.cpp b/gi/boxed.cpp
index 3e035e1..db4eff3 100644
--- a/gi/boxed.cpp
+++ b/gi/boxed.cpp
@@ -60,10 +60,10 @@ typedef struct {
 
 static bool struct_is_simple(GIStructInfo *info);
 
-static bool boxed_set_field_from_value(JSContext   *context,
-                                       Boxed       *priv,
-                                       GIFieldInfo *field_info,
-                                       JS::Value    value);
+static bool boxed_set_field_from_value(JSContext      *context,
+                                       Boxed          *priv,
+                                       GIFieldInfo    *field_info,
+                                       JS::HandleValue value);
 
 extern struct JSClass gjs_boxed_class;
 
@@ -733,10 +733,10 @@ set_nested_interface_object (JSContext   *context,
 }
 
 static bool
-boxed_set_field_from_value(JSContext   *context,
-                           Boxed       *priv,
-                           GIFieldInfo *field_info,
-                           JS::Value    value)
+boxed_set_field_from_value(JSContext      *context,
+                           Boxed          *priv,
+                           GIFieldInfo    *field_info,
+                           JS::HandleValue value)
 {
     GITypeInfo *type_info;
     GArgument arg;
diff --git a/gi/function.cpp b/gi/function.cpp
index dde7ba3..3dff737 100644
--- a/gi/function.cpp
+++ b/gi/function.cpp
@@ -182,7 +182,6 @@ gjs_callback_closure(ffi_cif *cif,
     JSObject *func_obj;
     GjsCallbackTrampoline *trampoline;
     int i, n_args, n_jsargs, n_outargs;
-    JS::Value rval;
     JSObject *this_object;
     GITypeInfo ret_type;
     bool success = false;
@@ -221,6 +220,7 @@ gjs_callback_closure(ffi_cif *cif,
     JS::AutoValueVector jsargs(context);
     jsargs.resize(n_args);
     JS::Value *args_ptr = jsargs.begin();
+    JS::RootedValue rval(context);
 
     for (i = 0, n_jsargs = 0; i < n_args; i++) {
         GIArgInfo arg_info;
@@ -294,7 +294,7 @@ gjs_callback_closure(ffi_cif *cif,
                               trampoline->js_function,
                               n_jsargs,
                               args_ptr,
-                              &rval)) {
+                              rval.address())) {
         goto out;
     }
 
@@ -345,7 +345,7 @@ gjs_callback_closure(ffi_cif *cif,
             break;
         }
     } else {
-        JS::Value elem;
+        JS::RootedValue elem(context);
         gsize elem_idx = 0;
         /* more than one of a return value or an out argument.
          * Should be an array of output values. */
@@ -353,7 +353,7 @@ gjs_callback_closure(ffi_cif *cif,
         if (!ret_type_is_void) {
             GIArgument argument;
 
-            if (!JS_GetElement(context, rval.toObjectOrNull(), elem_idx, &elem))
+            if (!JS_GetElement(context, rval.toObjectOrNull(), elem_idx, elem.address()))
                 goto out;
 
             if (!gjs_value_to_g_argument(context,
@@ -381,7 +381,7 @@ gjs_callback_closure(ffi_cif *cif,
                 continue;
 
             g_arg_info_load_type(&arg_info, &type_info);
-            if (!JS_GetElement(context, rval.toObjectOrNull(), elem_idx, &elem))
+            if (!JS_GetElement(context, rval.toObjectOrNull(), elem_idx, elem.address()))
                 goto out;
 
             if (!gjs_value_to_g_argument(context,
@@ -903,7 +903,10 @@ gjs_invoke_c_function(JSContext       *context,
                 gint array_length_pos = g_type_info_get_array_length(&ainfo);
                 gsize length;
 
-                if (!gjs_value_to_explicit_array(context, js_argv[js_arg_pos], &arg_info,
+                /* COMPAT: Avoid this extra root by changing the function's
+                 * in parameter to JS::HandleValueArray in mozjs31 */
+                JS::RootedValue v_arg(context, js_argv[js_arg_pos]);
+                if (!gjs_value_to_explicit_array(context, v_arg, &arg_info,
                                                  in_value, &length)) {
                     failed = true;
                     break;
@@ -912,7 +915,8 @@ gjs_invoke_c_function(JSContext       *context,
                 g_callable_info_load_arg(function->info, array_length_pos, &array_length_arg);
 
                 array_length_pos += is_method ? 1 : 0;
-                if (!gjs_value_to_arg(context, JS::Int32Value(length), &array_length_arg,
+                JS::RootedValue v_length(context, JS::Int32Value(length));
+                if (!gjs_value_to_arg(context, v_length, &array_length_arg,
                                       in_arg_cvalues + array_length_pos)) {
                     failed = true;
                     break;
@@ -934,14 +938,17 @@ gjs_invoke_c_function(JSContext       *context,
                 }
                 break;
             }
-            case PARAM_NORMAL:
+            case PARAM_NORMAL: {
                 /* Ok, now just convert argument normally */
                 g_assert_cmpuint(js_arg_pos, <, js_argc);
-                if (!gjs_value_to_arg(context, js_argv[js_arg_pos], &arg_info,
-                                      in_value)) {
+                /* COMPAT: Avoid this extra root by changing the function's
+                 * in parameter to JS::HandleValueArray in mozjs31 */
+                JS::RootedValue v_arg(context, js_argv[js_arg_pos]);
+                if (!gjs_value_to_arg(context, v_arg, &arg_info, in_value))
                     failed = true;
-                    break;
-                }
+
+                break;
+            }
 
             default:
                 ;


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