[gjs] js: Root gjs_object_require_property()



commit 04de94e75487269f2d5a02c79a07e84a6caadab8
Author: Philip Chimento <philip endlessm com>
Date:   Mon Oct 24 17:21:17 2016 -0700

    js: Root gjs_object_require_property()
    
    Starting out with gjs_object_require_property(), we do another cascade of
    GC rooting changes.
    
    This requires making some changes to the private structs of Boxed and
    Fundamental. Since they contain members of type jsid, which are subject
    to garbage collection, those members must be traced. JSClass provides a
    trace callback for this purpose.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=742249

 gi/arg.cpp                  |   20 ++++----
 gi/boxed.cpp                |   52 ++++++++++++++-------
 gi/fundamental.cpp          |   25 ++++++++--
 gi/gerror.cpp               |   16 ++++---
 gi/object.cpp               |   14 +++---
 gi/param.cpp                |    3 +-
 gi/repo.cpp                 |  107 ++++++++++++++++++++----------------------
 gi/repo.h                   |    5 +-
 gi/value.cpp                |    8 ++--
 gjs/importer.cpp            |    8 ++--
 gjs/jsapi-dynamic-class.cpp |   12 ++--
 gjs/jsapi-util.cpp          |   10 ++--
 gjs/jsapi-util.h            |   13 +++--
 13 files changed, 161 insertions(+), 132 deletions(-)
---
diff --git a/gi/arg.cpp b/gi/arg.cpp
index b336454..3df4437 100644
--- a/gi/arg.cpp
+++ b/gi/arg.cpp
@@ -1095,7 +1095,6 @@ gjs_array_to_explicit_array_internal(JSContext       *context,
 {
     bool ret = false;
     GITypeInfo *param_info;
-    jsid length_name;
     JSBool found_length;
 
     param_info = g_type_info_get_param_type(type_info, 0);
@@ -1103,10 +1102,12 @@ gjs_array_to_explicit_array_internal(JSContext       *context,
     if ((value.isNull() && !may_be_null) ||
         (!value.isString() && !value.isObjectOrNull())) {
         throw_invalid_argument(context, value, param_info, arg_name, arg_type);
-        goto out;
+        g_base_info_unref((GIBaseInfo*) param_info);
+        return false;
     }
 
-    length_name = gjs_context_get_const_string(context, GJS_STRING_LENGTH);
+    JS::RootedId length_name(context,
+        gjs_context_get_const_string(context, GJS_STRING_LENGTH));
 
     if (value.isNull()) {
         *contents = NULL;
@@ -1119,11 +1120,10 @@ gjs_array_to_explicit_array_internal(JSContext       *context,
     } else if (JS_HasPropertyById(context, &value.toObject(), length_name, &found_length) &&
                found_length) {
         JS::RootedValue length_value(context);
+        JS::RootedObject array_obj(context, &value.toObject());
         guint32 length;
 
-        if (!gjs_object_require_property(context,
-                                         &value.toObject(), NULL,
-                                         length_name,
+        if (!gjs_object_require_property(context, array_obj, NULL, length_name,
                                          &length_value) ||
             !JS::ToUint32(context, length_value, &length)) {
             goto out;
@@ -1636,10 +1636,10 @@ gjs_value_to_g_argument(JSContext      *context,
 
     case GI_TYPE_TAG_GLIST:
     case GI_TYPE_TAG_GSLIST: {
-        jsid length_name;
         JSBool found_length;
 
-        length_name = gjs_context_get_const_string(context, GJS_STRING_LENGTH);
+        JS::RootedId length_name(context,
+            gjs_context_get_const_string(context, GJS_STRING_LENGTH));
 
         /* nullable_type=false; while a list can be NULL in C, that
          * means empty array in JavaScript, it doesn't mean null in
@@ -1649,10 +1649,10 @@ gjs_value_to_g_argument(JSContext      *context,
             JS_HasPropertyById(context, &value.toObject(), length_name, &found_length) &&
             found_length) {
             JS::RootedValue length_value(context);
+            JS::RootedObject array_obj(context, &value.toObject());
             guint32 length;
 
-            if (!gjs_object_require_property(context,
-                                             &value.toObject(), NULL,
+            if (!gjs_object_require_property(context, array_obj, NULL,
                                              length_name,
                                              &length_value) ||
                 !JS::ToUint32(context, length_value, &length)) {
diff --git a/gi/boxed.cpp b/gi/boxed.cpp
index 227b88d..977622b 100644
--- a/gi/boxed.cpp
+++ b/gi/boxed.cpp
@@ -44,9 +44,9 @@ typedef struct {
     GIBoxedInfo *info;
     GType gtype;
     gint zero_args_constructor; /* -1 if none */
-    jsid zero_args_constructor_name;
+    JS::Heap<jsid> zero_args_constructor_name;
     gint default_constructor; /* -1 if none */
-    jsid default_constructor_name;
+    JS::Heap<jsid> default_constructor_name;
 
     /* instance info */
     void *gboxed; /* NULL if we are the prototype and not an instance */
@@ -262,9 +262,7 @@ boxed_init_from_props(JSContext   *context,
                       Boxed       *priv,
                       JS::Value    props_value)
 {
-    JSObject *props;
     JSObject *iter;
-    jsid prop_id;
     bool success = false;
 
     if (!props_value.isObject()) {
@@ -272,7 +270,7 @@ boxed_init_from_props(JSContext   *context,
         return false;
     }
 
-    props = &props_value.toObject();
+    JS::RootedObject props(context, &props_value.toObject());
 
     iter = JS_NewPropertyIterator(context, props);
     if (iter == NULL) {
@@ -283,8 +281,8 @@ boxed_init_from_props(JSContext   *context,
     if (!priv->field_map)
         priv->field_map = get_field_map(priv->info);
 
-    prop_id = JSID_VOID;
-    if (!JS_NextProperty(context, iter, &prop_id))
+    JS::RootedId prop_id(context, JSID_VOID);
+    if (!JS_NextProperty(context, iter, prop_id.address()))
         goto out;
 
     while (!JSID_IS_VOID(prop_id)) {
@@ -313,7 +311,7 @@ boxed_init_from_props(JSContext   *context,
             goto out;
 
         prop_id = JSID_VOID;
-        if (!JS_NextProperty(context, iter, &prop_id))
+        if (!JS_NextProperty(context, iter, prop_id.address()))
             goto out;
     }
 
@@ -326,18 +324,19 @@ boxed_init_from_props(JSContext   *context,
 
 static bool
 boxed_invoke_constructor(JSContext             *context,
-                         JSObject              *obj,
-                         jsid                   constructor_name,
+                         JS::HandleObject       obj,
+                         JS::HandleId           constructor_name,
                          JS::CallArgs&          args)
 {
     JS::RootedValue js_constructor(context), js_constructor_func(context);
-    jsid constructor_const;
+    JS::RootedId constructor_const(context,
+        gjs_context_get_const_string(context, GJS_STRING_CONSTRUCTOR));
 
-    constructor_const = gjs_context_get_const_string(context, GJS_STRING_CONSTRUCTOR);
     if (!gjs_object_require_property(context, obj, NULL, constructor_const, &js_constructor))
         return false;
 
-    if (!gjs_object_require_property(context, &js_constructor.toObject(), NULL,
+    JS::RootedObject js_constructor_obj(context, &js_constructor.toObject());
+    if (!gjs_object_require_property(context, js_constructor_obj, NULL,
                                      constructor_name, &js_constructor_func))
         return false;
 
@@ -347,16 +346,15 @@ boxed_invoke_constructor(JSContext             *context,
 
 static bool
 boxed_new(JSContext             *context,
-          JSObject              *obj, /* "this" for constructor */
+          JS::HandleObject       obj, /* "this" for constructor */
           Boxed                 *priv,
           JS::CallArgs&          args)
 {
     if (priv->gtype == G_TYPE_VARIANT) {
-        jsid constructor_name;
-
         /* Short-circuit construction for GVariants by calling into the JS packing
            function */
-        constructor_name = gjs_context_get_const_string(context, GJS_STRING_NEW_INTERNAL);
+        JS::RootedId constructor_name(context,
+            gjs_context_get_const_string(context, GJS_STRING_NEW_INTERNAL));
         return boxed_invoke_constructor(context, obj, constructor_name, args);
     }
 
@@ -887,6 +885,18 @@ to_string_func(JSContext *context,
                                      priv->gboxed, rec.rval());
 }
 
+static void
+boxed_trace(JSTracer *tracer,
+            JSObject *obj)
+{
+    Boxed *priv = reinterpret_cast<Boxed *>(JS_GetPrivate(obj));
+
+    JS_CallHeapIdTracer(tracer, &priv->zero_args_constructor_name,
+                        "Boxed::zero_args_constructor_name");
+    JS_CallHeapIdTracer(tracer, &priv->default_constructor_name,
+                        "Boxed::default_constructor_name");
+}
+
 /* The bizarre thing about this vtable is that it applies to both
  * instances of the object, and to the prototype that instances of the
  * class have.
@@ -909,7 +919,11 @@ struct JSClass gjs_boxed_class = {
     (JSResolveOp) boxed_new_resolve, /* needs cast since it's the new resolve signature */
     JS_ConvertStub,
     boxed_finalize,
-    JSCLASS_NO_OPTIONAL_MEMBERS
+    NULL,  /* checkAccess */
+    NULL,  /* call */
+    NULL,  /* hasInstance */
+    NULL,  /* construct */
+    boxed_trace
 };
 
 JSPropertySpec gjs_boxed_proto_props[] = {
@@ -1047,7 +1061,9 @@ boxed_fill_prototype_info(JSContext *context,
 
     priv->gtype = g_registered_type_info_get_g_type( (GIRegisteredTypeInfo*) priv->info);
     priv->zero_args_constructor = -1;
+    priv->zero_args_constructor_name = JSID_VOID;
     priv->default_constructor = -1;
+    priv->default_constructor_name = JSID_VOID;
 
     if (priv->gtype != G_TYPE_NONE) {
         /* If the structure is registered as a boxed, we can create a new instance by
diff --git a/gi/fundamental.cpp b/gi/fundamental.cpp
index d87b939..569ae26 100644
--- a/gi/fundamental.cpp
+++ b/gi/fundamental.cpp
@@ -56,7 +56,7 @@ typedef struct _Fundamental {
     GIObjectInfoGetValueFunction  get_value_function;
     GIObjectInfoSetValueFunction  set_value_function;
 
-    jsid                          constructor_name;
+    JS::Heap<jsid>                constructor_name;
     GICallableInfo               *constructor_info;
 } Fundamental;
 
@@ -389,9 +389,9 @@ fundamental_invoke_constructor(FundamentalInstance *priv,
                                GArgument           *rvalue)
 {
     JS::RootedValue js_constructor(context), js_constructor_func(context);
-    jsid constructor_const;
+    JS::RootedId constructor_const(context,
+        gjs_context_get_const_string(context, GJS_STRING_CONSTRUCTOR));
 
-    constructor_const = gjs_context_get_const_string(context, GJS_STRING_CONSTRUCTOR);
     if (!gjs_object_require_property(context, obj, NULL,
                                      constructor_const, &js_constructor) ||
         priv->prototype->constructor_name == JSID_VOID) {
@@ -402,7 +402,8 @@ fundamental_invoke_constructor(FundamentalInstance *priv,
         return false;
     }
 
-    if (!gjs_object_require_property(context, js_constructor.toObjectOrNull(), NULL,
+    JS::RootedObject js_constructor_obj(context, js_constructor.toObjectOrNull());
+    if (!gjs_object_require_property(context, js_constructor_obj, NULL,
                                      priv->prototype->constructor_name, &js_constructor_func)) {
         gjs_throw (context,
                    "Couldn't find a constructor for type %s.%s",
@@ -521,6 +522,16 @@ to_string_func(JSContext *context,
     return true;
 }
 
+static void
+fundamental_trace(JSTracer *tracer,
+                  JSObject *obj)
+{
+    Fundamental *priv = reinterpret_cast<Fundamental *>(JS_GetPrivate(obj));
+
+    JS_CallHeapIdTracer(tracer, &priv->constructor_name,
+                        "Fundamental::constructor_name");
+}
+
 /* The bizarre thing about this vtable is that it applies to both
  * instances of the object, and to the prototype that instances of the
  * class have.
@@ -547,7 +558,11 @@ struct JSClass gjs_fundamental_instance_class = {
     (JSResolveOp) fundamental_instance_new_resolve, /* needs cast since it's the new resolve signature */
     JS_ConvertStub,
     fundamental_finalize,
-    JSCLASS_NO_OPTIONAL_MEMBERS
+    NULL,  /* checkAccess */
+    NULL,  /* call */
+    NULL,  /* hasInstance */
+    NULL,  /* construct */
+    fundamental_trace
 };
 
 static JSPropertySpec gjs_fundamental_instance_proto_props[] = {
diff --git a/gi/gerror.cpp b/gi/gerror.cpp
index 57274d0..c0042c7 100644
--- a/gi/gerror.cpp
+++ b/gi/gerror.cpp
@@ -53,7 +53,6 @@ GJS_NATIVE_CONSTRUCTOR_DECLARE(error)
     GJS_NATIVE_CONSTRUCTOR_VARIABLES(error)
     Error *priv;
     Error *proto_priv;
-    jsid message_name, code_name;
     gchar *message;
 
     /* Check early to avoid allocating memory for nothing */
@@ -96,12 +95,15 @@ GJS_NATIVE_CONSTRUCTOR_DECLARE(error)
     priv->domain = proto_priv->domain;
 
     JS::RootedValue v_message(context), v_code(context);
-    message_name = gjs_context_get_const_string(context, GJS_STRING_MESSAGE);
-    code_name = gjs_context_get_const_string(context, GJS_STRING_CODE);
-    if (!gjs_object_require_property(context, &argv[0].toObject(),
+    JS::RootedObject params_obj(context, &argv[0].toObject());
+    JS::RootedId message_name(context,
+        gjs_context_get_const_string(context, GJS_STRING_MESSAGE));
+    JS::RootedId code_name(context,
+        gjs_context_get_const_string(context, GJS_STRING_CODE));
+    if (!gjs_object_require_property(context, params_obj,
                                      "GError constructor", message_name, &v_message))
         return false;
-    if (!gjs_object_require_property(context, &argv[0].toObject(),
+    if (!gjs_object_require_property(context, params_obj,
                                      "GError constructor", code_name, &v_code))
         return false;
     if (!gjs_string_to_utf8 (context, v_message, &message))
@@ -246,9 +248,9 @@ error_constructor_value_of(JSContext *context,
     GJS_GET_THIS(context, argc, vp, rec, self);
     JS::RootedValue v_prototype(context);
     Error *priv;
-    jsid prototype_name;
+    JS::RootedId prototype_name(context,
+        gjs_context_get_const_string(context, GJS_STRING_PROTOTYPE));
 
-    prototype_name = gjs_context_get_const_string(context, GJS_STRING_PROTOTYPE);
     if (!gjs_object_require_property(context, self, "constructor",
                                      prototype_name, &v_prototype))
         return false;
diff --git a/gi/object.cpp b/gi/object.cpp
index bdb8b0c..54412d5 100644
--- a/gi/object.cpp
+++ b/gi/object.cpp
@@ -674,13 +674,14 @@ object_instance_props_to_g_parameters(JSContext               *context,
                                       GType                    gtype,
                                       std::vector<GParameter>& gparams)
 {
-    JSObject *props;
     JSObject *iter;
-    jsid prop_id;
 
     if (argc == 0 || argv[0].isUndefined())
         return true;
 
+    JS::RootedObject props(context);
+    JS::RootedId prop_id(context);
+
     if (!argv[0].isObject()) {
         gjs_throw(context, "argument should be a hash with props to set");
         goto free_array_and_fail;
@@ -694,8 +695,7 @@ object_instance_props_to_g_parameters(JSContext               *context,
         goto free_array_and_fail;
     }
 
-    prop_id = JSID_VOID;
-    if (!JS_NextProperty(context, iter, &prop_id))
+    if (!JS_NextProperty(context, iter, prop_id.address()))
         goto free_array_and_fail;
 
     while (!JSID_IS_VOID(prop_id)) {
@@ -731,7 +731,7 @@ object_instance_props_to_g_parameters(JSContext               *context,
         gparams.push_back(gparam);
 
         prop_id = JSID_VOID;
-        if (!JS_NextProperty(context, iter, &prop_id))
+        if (!JS_NextProperty(context, iter, prop_id.address()))
             goto free_array_and_fail;
     }
 
@@ -1319,7 +1319,6 @@ GJS_NATIVE_CONSTRUCTOR_DECLARE(object_instance)
     GJS_NATIVE_CONSTRUCTOR_VARIABLES(object_instance)
     bool ret;
     JS::RootedValue initer(context);
-    jsid object_init_name;
 
     GJS_NATIVE_CONSTRUCTOR_PRELUDE(object_instance);
 
@@ -1328,7 +1327,8 @@ GJS_NATIVE_CONSTRUCTOR_DECLARE(object_instance)
      * might be traced and we will end up dereferencing a null pointer */
     init_object_private(context, object);
 
-    object_init_name = gjs_context_get_const_string(context, GJS_STRING_GOBJECT_INIT);
+    JS::RootedId object_init_name(context,
+        gjs_context_get_const_string(context, GJS_STRING_GOBJECT_INIT));
     if (!gjs_object_require_property(context, object, "GObject instance", object_init_name, &initer))
         return false;
 
diff --git a/gi/param.cpp b/gi/param.cpp
index bd9e7d1..179988f 100644
--- a/gi/param.cpp
+++ b/gi/param.cpp
@@ -183,9 +183,8 @@ static JSObject*
 gjs_lookup_param_prototype(JSContext    *context)
 {
     JSObject *in_object;
-    jsid gobject_name;
 
-    gobject_name = gjs_intern_string_to_id(context, "GObject");
+    JS::RootedId gobject_name(context, gjs_intern_string_to_id(context, "GObject"));
     in_object = gjs_lookup_namespace_object_by_name(context, gobject_name);
 
     if (G_UNLIKELY (!in_object))
diff --git a/gi/repo.cpp b/gi/repo.cpp
index cd52d10..9a3b6f9 100644
--- a/gi/repo.cpp
+++ b/gi/repo.cpp
@@ -54,20 +54,20 @@ extern struct JSClass gjs_repo_class;
 
 GJS_DEFINE_PRIV_FROM_JS(Repo, gjs_repo_class)
 
-static JSObject * lookup_override_function(JSContext *, jsid);
+static JSObject *lookup_override_function(JSContext *, JS::HandleId);
 
 static bool
-get_version_for_ns (JSContext *context,
-                    JSObject  *repo_obj,
-                    jsid       ns_id,
-                    char     **version)
+get_version_for_ns (JSContext       *context,
+                    JS::HandleObject repo_obj,
+                    jsid             ns_id,
+                    char           **version)
 {
-    jsid versions_name;
     JS::RootedValue versions_val(context);
     JSObject *versions;
-    JS::Value version_val;
+    JS::RootedValue version_val(context);
+    JS::RootedId versions_name(context,
+        gjs_context_get_const_string(context, GJS_STRING_GI_VERSIONS));
 
-    versions_name = gjs_context_get_const_string(context, GJS_STRING_GI_VERSIONS);
     if (!gjs_object_require_property(context, repo_obj, "GI repository object", versions_name, 
&versions_val) ||
         !versions_val.isObject()) {
         gjs_throw(context, "No 'versions' property in GI repository object");
@@ -77,7 +77,7 @@ get_version_for_ns (JSContext *context,
     versions = &versions_val.toObject();
 
     *version = NULL;
-    if (JS_GetPropertyById(context, versions, ns_id, &version_val) &&
+    if (JS_GetPropertyById(context, versions, ns_id, version_val.address()) &&
         version_val.isString()) {
         gjs_string_to_utf8(context, version_val, version);
     }
@@ -86,10 +86,10 @@ get_version_for_ns (JSContext *context,
 }
 
 static bool
-resolve_namespace_object(JSContext  *context,
-                         JSObject   *repo_obj,
-                         jsid        ns_id,
-                         const char *ns_name)
+resolve_namespace_object(JSContext       *context,
+                         JS::HandleObject repo_obj,
+                         JS::HandleId     ns_id,
+                         const char      *ns_name)
 {
     GIRepository *repo;
     GError *error;
@@ -143,7 +143,7 @@ resolve_namespace_object(JSContext  *context,
 
     gjs_debug(GJS_DEBUG_GNAMESPACE,
               "Defined namespace '%s' %p in GIRepository %p", ns_name,
-              gi_namespace.get(), repo_obj);
+              gi_namespace.get(), repo_obj.get());
 
     gjs_schedule_gc_if_needed(context);
     return true;
@@ -554,9 +554,8 @@ gjs_define_info(JSContext  *context,
 JSObject*
 gjs_lookup_private_namespace(JSContext *context)
 {
-    jsid ns_name;
-
-    ns_name = gjs_context_get_const_string(context, GJS_STRING_PRIVATE_NS_MARKER);
+    JS::RootedId ns_name(context,
+        gjs_context_get_const_string(context, GJS_STRING_PRIVATE_NS_MARKER));
     return gjs_lookup_namespace_object_by_name(context, ns_name);
 }
 
@@ -566,7 +565,6 @@ gjs_lookup_namespace_object(JSContext  *context,
                             GIBaseInfo *info)
 {
     const char *ns;
-    jsid ns_name;
 
     ns = g_base_info_get_namespace(info);
     if (ns == NULL) {
@@ -577,76 +575,78 @@ gjs_lookup_namespace_object(JSContext  *context,
         return NULL;
     }
 
-    ns_name = gjs_intern_string_to_id(context, ns);
+    JS::RootedId ns_name(context, gjs_intern_string_to_id(context, ns));
     return gjs_lookup_namespace_object_by_name(context, ns_name);
 }
 
 static JSObject*
-lookup_override_function(JSContext  *context,
-                         jsid        ns_name)
+lookup_override_function(JSContext   *cx,
+                         JS::HandleId ns_name)
 {
-    JS::Value importer;
-    JS::RootedValue overridespkg(context), module(context), function(context);
-    jsid overrides_name, object_init_name;
+    JSAutoRequest ar(cx);
 
-    JS_BeginRequest(context);
-
-    importer = gjs_get_global_slot(context, GJS_GLOBAL_SLOT_IMPORTS);
+    JS::RootedValue importer(cx, gjs_get_global_slot(cx, GJS_GLOBAL_SLOT_IMPORTS));
     g_assert(importer.isObject());
 
-    overrides_name = gjs_context_get_const_string(context, GJS_STRING_GI_OVERRIDES);
-    if (!gjs_object_require_property(context, &importer.toObject(), "importer",
+    JS::RootedValue overridespkg(cx), module(cx), function(cx);
+    JS::RootedId overrides_name(cx,
+        gjs_context_get_const_string(cx, GJS_STRING_GI_OVERRIDES));
+    JS::RootedId object_init_name(cx,
+        gjs_context_get_const_string(cx, GJS_STRING_GOBJECT_INIT));
+    JS::RootedObject overridespkg_obj(cx), module_obj(cx);
+    JS::RootedObject importer_obj(cx, &importer.toObject());
+
+    if (!gjs_object_require_property(cx, importer_obj, "importer",
                                      overrides_name, &overridespkg) ||
         !overridespkg.isObject())
         goto fail;
 
-    module = JS::UndefinedValue();
-    if (!gjs_object_require_property(context, &overridespkg.toObject(), "GI repository object", ns_name, 
&module)
+    overridespkg_obj = &overridespkg.toObject();
+    if (!gjs_object_require_property(cx, overridespkg_obj,
+                                     "GI repository object", ns_name, &module)
         || !module.isObject())
         goto fail;
 
-    object_init_name = gjs_context_get_const_string(context, GJS_STRING_GOBJECT_INIT);
-    if (!gjs_object_require_property(context, &module.toObject(), "override module",
+    module_obj = &module.toObject();
+    if (!gjs_object_require_property(cx, module_obj, "override module",
                                      object_init_name, &function) ||
         !function.isObjectOrNull())
         goto fail;
 
-    JS_EndRequest(context);
     return function.toObjectOrNull();
 
  fail:
-    JS_ClearPendingException(context);
-    JS_EndRequest(context);
+    /* COMPAT: Use JS::AutoSaveExceptionState and move rooting to be late */
+    JS_ClearPendingException(cx);
     return NULL;
 }
 
 JSObject*
 gjs_lookup_namespace_object_by_name(JSContext      *context,
-                                    jsid            ns_name)
+                                    JS::HandleId    ns_name)
 {
-    JSObject *repo_obj;
-    JS::Value importer;
-    JS::RootedValue girepository(context), ns_obj(context);
-    jsid gi_name;
-
-    JS_BeginRequest(context);
+    JSAutoRequest ar(context);
 
-    importer = gjs_get_global_slot(context, GJS_GLOBAL_SLOT_IMPORTS);
+    JS::RootedValue importer(context,
+        gjs_get_global_slot(context, GJS_GLOBAL_SLOT_IMPORTS));
     g_assert(importer.isObject());
 
-    gi_name = gjs_context_get_const_string(context, GJS_STRING_GI_MODULE);
-    if (!gjs_object_require_property(context, &importer.toObject(), "importer",
+    JS::RootedId gi_name(context,
+        gjs_context_get_const_string(context, GJS_STRING_GI_MODULE));
+    JS::RootedObject importer_obj(context, &importer.toObject());
+    JS::RootedValue girepository(context);
+    if (!gjs_object_require_property(context, importer_obj, "importer",
                                      gi_name, &girepository) ||
         !girepository.isObject()) {
         gjs_log_exception(context);
         gjs_throw(context, "No gi property in importer");
-        goto fail;
+        return NULL;
     }
 
-    repo_obj = &girepository.toObject();
-
+    JS::RootedObject repo_obj(context, &girepository.toObject());
+    JS::RootedValue ns_obj(context);
     if (!gjs_object_require_property(context, repo_obj, "GI repository object", ns_name, &ns_obj)) {
-        goto fail;
+        return NULL;
     }
 
     if (!ns_obj.isObject()) {
@@ -656,15 +656,10 @@ gjs_lookup_namespace_object_by_name(JSContext      *context,
         gjs_throw(context, "Namespace '%s' is not an object?", name);
 
         g_free(name);
-        goto fail;
+        return NULL;
     }
 
-    JS_EndRequest(context);
     return &ns_obj.toObject();
-
- fail:
-    JS_EndRequest(context);
-    return NULL;
 }
 
 const char*
diff --git a/gi/repo.h b/gi/repo.h
index eceef09..0a4200b 100644
--- a/gi/repo.h
+++ b/gi/repo.h
@@ -42,8 +42,9 @@ const char* gjs_info_type_name                  (GIInfoType      type);
 JSObject*   gjs_lookup_private_namespace        (JSContext      *context);
 JSObject*   gjs_lookup_namespace_object         (JSContext      *context,
                                                  GIBaseInfo     *info);
-JSObject*   gjs_lookup_namespace_object_by_name (JSContext      *context,
-                                                 jsid            name);
+
+JSObject *gjs_lookup_namespace_object_by_name(JSContext   *context,
+                                              JS::HandleId name);
 
 JSObject *  gjs_lookup_generic_constructor      (JSContext      *context,
                                                  GIBaseInfo     *info);
diff --git a/gi/value.cpp b/gi/value.cpp
index 1efd267..0be77ab 100644
--- a/gi/value.cpp
+++ b/gi/value.cpp
@@ -485,19 +485,19 @@ gjs_value_to_g_value_internal(JSContext    *context,
 
         g_value_set_object(gvalue, gobj);
     } else if (gtype == G_TYPE_STRV) {
-        jsid length_name;
         JSBool found_length;
+        JS::RootedId length_name(context,
+            gjs_context_get_const_string(context, GJS_STRING_LENGTH));
 
-        length_name = gjs_context_get_const_string(context, GJS_STRING_LENGTH);
         if (value.isNull()) {
             /* do nothing */
         } else if (JS_HasPropertyById(context, &value.toObject(), length_name, &found_length) &&
                    found_length) {
             JS::RootedValue length_value(context);
+            JS::RootedObject array_obj(context, &value.toObject());
             guint32 length;
 
-            if (!gjs_object_require_property(context,
-                                             &value.toObject(), NULL,
+            if (!gjs_object_require_property(context, array_obj, NULL,
                                              length_name,
                                              &length_value) ||
                 !JS::ToUint32(context, length_value, &length)) {
diff --git a/gjs/importer.cpp b/gjs/importer.cpp
index 5682a61..bf022e6 100644
--- a/gjs/importer.cpp
+++ b/gjs/importer.cpp
@@ -416,11 +416,11 @@ do_import(JSContext       *context,
     guint32 i;
     bool result;
     GPtrArray *directories;
-    jsid search_path_name;
     GFile *gfile;
     bool exists;
 
-    search_path_name = gjs_context_get_const_string(context, GJS_STRING_SEARCH_PATH);
+    JS::RootedId search_path_name(context,
+        gjs_context_get_const_string(context, GJS_STRING_SEARCH_PATH));
     if (!gjs_object_require_property(context, obj, "importer", search_path_name, &search_path_val)) {
         return false;
     }
@@ -665,7 +665,6 @@ importer_new_enumerate(JSContext  *context,
         JS::RootedValue search_path_val(context);
         guint32 search_path_len;
         guint32 i;
-        jsid search_path_name;
 
         statep.setNull();
 
@@ -677,7 +676,8 @@ importer_new_enumerate(JSContext  *context,
             /* we are enumerating the prototype properties */
             return true;
 
-        search_path_name = gjs_context_get_const_string(context, GJS_STRING_SEARCH_PATH);
+        JS::RootedId search_path_name(context,
+            gjs_context_get_const_string(context, GJS_STRING_SEARCH_PATH));
         if (!gjs_object_require_property(context, object, "importer", search_path_name, &search_path_val))
             return false;
 
diff --git a/gjs/jsapi-dynamic-class.cpp b/gjs/jsapi-dynamic-class.cpp
index e6e5204..3965f59 100644
--- a/gjs/jsapi-dynamic-class.cpp
+++ b/gjs/jsapi-dynamic-class.cpp
@@ -167,19 +167,19 @@ gjs_typecheck_instance(JSContext *context,
 }
 
 JSObject*
-gjs_construct_object_dynamic(JSContext      *context,
-                             JSObject       *proto,
-                             unsigned        argc,
-                             JS::Value      *argv)
+gjs_construct_object_dynamic(JSContext       *context,
+                             JS::HandleObject proto,
+                             unsigned         argc,
+                             JS::Value       *argv)
 {
     JSObject *constructor;
     JSObject *result = NULL;
     JS::RootedValue value(context);
-    jsid constructor_name;
 
     JS_BeginRequest(context);
 
-    constructor_name = gjs_context_get_const_string(context, GJS_STRING_CONSTRUCTOR);
+    JS::RootedId constructor_name(context,
+        gjs_context_get_const_string(context, GJS_STRING_CONSTRUCTOR));
     if (!gjs_object_require_property(context, proto, "prototype",
                                      constructor_name, &value))
         goto out;
diff --git a/gjs/jsapi-util.cpp b/gjs/jsapi-util.cpp
index 3d1539d..b33e1d8 100644
--- a/gjs/jsapi-util.cpp
+++ b/gjs/jsapi-util.cpp
@@ -137,10 +137,10 @@ gjs_get_global_slot (JSContext     *context,
  * Requires request.
  */
 bool
-gjs_object_require_property(JSContext       *context,
-                            JSObject        *obj,
-                            const char      *obj_description,
-                            jsid             property_name,
+gjs_object_require_property(JSContext             *context,
+                            JS::HandleObject       obj,
+                            const char            *obj_description,
+                            JS::HandleId           property_name,
                             JS::MutableHandleValue value)
 {
     char *name;
@@ -166,7 +166,7 @@ gjs_object_require_property(JSContext       *context,
     else
         gjs_throw(context,
                   "No property '%s' in object %p (or its value was undefined)",
-                  name, obj);
+                  name, obj.address());
 
     g_free(name);
     return false;
diff --git a/gjs/jsapi-util.h b/gjs/jsapi-util.h
index 28e25d9..45b6503 100644
--- a/gjs/jsapi-util.h
+++ b/gjs/jsapi-util.h
@@ -304,9 +304,9 @@ void        gjs_set_global_slot              (JSContext       *context,
                                               JS::Value        value);
 
 bool gjs_object_require_property(JSContext             *context,
-                                 JSObject              *obj,
+                                 JS::HandleObject       obj,
                                  const char            *obj_description,
-                                 jsid                   property_name,
+                                 JS::HandleId           property_name,
                                  JS::MutableHandleValue value);
 
 bool gjs_init_class_dynamic(JSContext              *context,
@@ -333,10 +333,11 @@ bool        gjs_typecheck_instance            (JSContext  *context,
                                                JSClass    *static_clasp,
                                                bool        _throw);
 
-JSObject*   gjs_construct_object_dynamic     (JSContext       *context,
-                                              JSObject        *proto,
-                                              unsigned         argc,
-                                              JS::Value       *argv);
+JSObject *gjs_construct_object_dynamic(JSContext       *context,
+                                       JS::HandleObject proto,
+                                       unsigned         argc,
+                                       JS::Value       *argv);
+
 JSObject*   gjs_build_string_array           (JSContext       *context,
                                               gssize           array_length,
                                               char           **array_values);


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