[gjs/wip/ptomato/mozjs31prep: 10/11] WIP - js: Root gjs_object_get_property_const()



commit f5997b2af53b6fd04b46b81009835c2d5dba0274
Author: Philip Chimento <philip endlessm com>
Date:   Tue Oct 18 15:54:07 2016 -0700

    WIP - js: Root gjs_object_get_property_const()
    
    Starting with gjs_object_get_property_const() and working backwards, we
    cause another cascade of GC rooting changes.
    
    One disadvantage of JS::MutableHandle is that it's not so easy to make an
    optional out parameter for a function. Previously, for example, a
    JSObject** parameter could be NULL to indicate the caller wasn't
    interested in the return value. e.g.,
    
        if (out_obj != NULL) { do_some_op(); *out_obj = something; }
    
    Now we have a few options. SpiderMonkey doesn't really have any examples
    of this in the JSAPI so it's hard to tell what is most idiomatic and from
    asking on IRC it seems that they are pretty equivalent:
    
    - Use JS::MutableHandle* - should be OK but not really done in SM
    - Use mozilla::Maybe<JS::MutableHandle>
      https://dxr.mozilla.org/mozilla-beta/source/mfbt/Maybe.h
    - Use overloading; define a function prototype with and without the
      parameter
    - Pass in an explicitly ignored object, which is what I've done in this
      patch (grep for "ignored".)
    
    Ignored object seems to be the least invasive route but before
    committing this patch we should pick one of the above.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=742249

 gi/boxed.cpp                |    2 +-
 gi/fundamental.cpp          |   21 +++++++----------
 gi/fundamental.h            |   11 +++++----
 gi/gerror.cpp               |    4 +-
 gi/interface.cpp            |   16 +++++--------
 gi/interface.h              |   10 ++++----
 gi/object.cpp               |   36 +++++++++++++-----------------
 gi/object.h                 |   10 ++++----
 gi/param.cpp                |    9 +++----
 gi/repo.cpp                 |   24 +++++++++++++-------
 gi/union.cpp                |    2 +-
 gjs/context.cpp             |   13 +++++------
 gjs/jsapi-dynamic-class.cpp |   34 +++++++++++++----------------
 gjs/jsapi-util.cpp          |   25 +++++++++++----------
 gjs/jsapi-util.h            |   46 ++++++++++++++++++++-------------------
 gjs/stack.cpp               |   50 ++++++++++++++++--------------------------
 modules/cairo-region.cpp    |    8 ++++--
 17 files changed, 152 insertions(+), 169 deletions(-)
---
diff --git a/gi/boxed.cpp b/gi/boxed.cpp
index a05a490..e64d57c 100644
--- a/gi/boxed.cpp
+++ b/gi/boxed.cpp
@@ -1111,7 +1111,7 @@ gjs_define_boxed_class(JSContext    *context,
 {
     const char *constructor_name;
     JSObject *prototype;
-    JSObject *constructor;
+    JS::RootedObject constructor(context);
     JS::Value value;
     Boxed *priv;
 
diff --git a/gi/fundamental.cpp b/gi/fundamental.cpp
index 383f2fa..3478d44 100644
--- a/gi/fundamental.cpp
+++ b/gi/fundamental.cpp
@@ -565,9 +565,7 @@ gjs_lookup_fundamental_prototype(JSContext    *context,
                                  GType         gtype)
 {
     JSObject *in_object;
-    JSObject *constructor;
     const char *constructor_name;
-    JS::Value value;
 
     if (info) {
         in_object = gjs_lookup_namespace_object(context, (GIBaseInfo*) info);
@@ -580,9 +578,11 @@ gjs_lookup_fundamental_prototype(JSContext    *context,
     if (G_UNLIKELY (!in_object))
         return NULL;
 
-    if (!JS_GetProperty(context, in_object, constructor_name, &value))
+    JS::RootedValue value(context);
+    if (!JS_GetProperty(context, in_object, constructor_name, value.address()))
         return NULL;
 
+    JS::RootedObject constructor(context);
     if (value.isUndefined()) {
         /* In case we're looking for a private type, and we don't find it,
            we need to define it first.
@@ -624,11 +624,11 @@ gjs_lookup_fundamental_prototype_from_gtype(JSContext *context,
 }
 
 bool
-gjs_define_fundamental_class(JSContext     *context,
-                             JSObject      *in_object,
-                             GIObjectInfo  *info,
-                             JSObject     **constructor_p,
-                             JSObject     **prototype_p)
+gjs_define_fundamental_class(JSContext              *context,
+                             JSObject               *in_object,
+                             GIObjectInfo           *info,
+                             JS::MutableHandleObject constructor,
+                             JSObject              **prototype_p)
 {
     const char *constructor_name;
     JSObject *prototype;
@@ -636,7 +636,6 @@ gjs_define_fundamental_class(JSContext     *context,
     jsid js_constructor_name = JSID_VOID;
     JSObject *parent_proto;
     Fundamental *priv;
-    JSObject *constructor;
     GType parent_gtype;
     GType gtype;
     GIFunctionInfo *constructor_info;
@@ -677,7 +676,7 @@ gjs_define_fundamental_class(JSContext     *context,
                                 /* funcs of constructor, MyConstructor.myfunc() */
                                 NULL,
                                 &prototype,
-                                &constructor)) {
+                                constructor)) {
         gjs_log_exception(context);
         g_error("Can't init class %s", constructor_name);
     }
@@ -722,8 +721,6 @@ gjs_define_fundamental_class(JSContext     *context,
     JS_DefineProperty(context, constructor, "$gtype", value,
                       NULL, NULL, JSPROP_PERMANENT);
 
-    if (constructor_p)
-        *constructor_p = constructor;
     if (prototype_p)
         *prototype_p = prototype;
 
diff --git a/gi/fundamental.h b/gi/fundamental.h
index dec8fcf..9e334dc 100644
--- a/gi/fundamental.h
+++ b/gi/fundamental.h
@@ -32,11 +32,12 @@
 
 G_BEGIN_DECLS
 
-bool      gjs_define_fundamental_class       (JSContext     *context,
-                                              JSObject      *in_object,
-                                              GIObjectInfo  *info,
-                                              JSObject     **constructor_p,
-                                              JSObject     **prototype_p);
+bool gjs_define_fundamental_class(JSContext              *context,
+                                  JSObject               *in_object,
+                                  GIObjectInfo           *info,
+                                  JS::MutableHandleObject constructor,
+                                  JSObject              **prototype_p);
+
 JSObject* gjs_object_from_g_fundamental      (JSContext     *context,
                                               GIObjectInfo  *info,
                                               void          *fobj);
diff --git a/gi/gerror.cpp b/gi/gerror.cpp
index b1c0136..8202e1e 100644
--- a/gi/gerror.cpp
+++ b/gi/gerror.cpp
@@ -317,7 +317,7 @@ gjs_define_error_class(JSContext    *context,
     const char *constructor_name;
     GIBoxedInfo *glib_error_info;
     JSObject *prototype, *parent_proto;
-    JSObject *constructor;
+    JS::RootedObject constructor(context);
     Error *priv;
 
     /* See the comment in gjs_define_boxed_class() for an
@@ -401,7 +401,7 @@ define_error_properties(JSContext *context,
                         JSObject  *obj)
 {
     jsid stack_name, filename_name, linenumber_name;
-    JS::Value stack, fileName, lineNumber;
+    JS::RootedValue stack(context), fileName(context), lineNumber(context);
 
     if (!gjs_context_get_frame_info (context,
                                      &stack,
diff --git a/gi/interface.cpp b/gi/interface.cpp
index d06199a..476cc18 100644
--- a/gi/interface.cpp
+++ b/gi/interface.cpp
@@ -181,16 +181,15 @@ JSFunctionSpec gjs_interface_proto_funcs[] = {
 };
 
 bool
-gjs_define_interface_class(JSContext       *context,
-                           JSObject        *in_object,
-                           GIInterfaceInfo *info,
-                           GType            gtype,
-                           JSObject       **constructor_p)
+gjs_define_interface_class(JSContext              *context,
+                           JSObject               *in_object,
+                           GIInterfaceInfo        *info,
+                           GType                   gtype,
+                           JS::MutableHandleObject constructor)
 {
     Interface *priv;
     const char *constructor_name;
     const char *ns;
-    JSObject *constructor;
     JSObject *prototype;
     JS::Value value;
 
@@ -212,7 +211,7 @@ gjs_define_interface_class(JSContext       *context,
                                 /* funcs of constructor, MyConstructor.myfunc() */
                                 NULL,
                                 &prototype,
-                                &constructor)) {
+                                constructor)) {
         g_error("Can't init class %s", constructor_name);
     }
 
@@ -232,9 +231,6 @@ gjs_define_interface_class(JSContext       *context,
     JS_DefineProperty(context, constructor, "$gtype", value,
                       NULL, NULL, JSPROP_PERMANENT);
 
-    if (constructor_p)
-        *constructor_p = constructor;
-
     return true;
 }
 
diff --git a/gi/interface.h b/gi/interface.h
index 0dc5e56..ba5a6f1 100644
--- a/gi/interface.h
+++ b/gi/interface.h
@@ -32,11 +32,11 @@
 
 G_BEGIN_DECLS
 
-bool gjs_define_interface_class (JSContext       *context,
-                                 JSObject        *in_object,
-                                 GIInterfaceInfo *info,
-                                 GType            gtype,
-                                 JSObject       **constructor_p);
+bool gjs_define_interface_class(JSContext              *context,
+                                JSObject               *in_object,
+                                GIInterfaceInfo        *info,
+                                GType                   gtype,
+                                JS::MutableHandleObject constructor);
 
 bool gjs_lookup_interface_constructor(JSContext             *context,
                                       GType                  gtype,
diff --git a/gi/object.cpp b/gi/object.cpp
index 05c7a8a..19412a2 100644
--- a/gi/object.cpp
+++ b/gi/object.cpp
@@ -1477,7 +1477,6 @@ gjs_lookup_object_constructor_from_info(JSContext    *context,
                                         GType         gtype)
 {
     JSObject *in_object;
-    JSObject *constructor;
     const char *constructor_name;
     JS::Value value;
 
@@ -1495,6 +1494,7 @@ gjs_lookup_object_constructor_from_info(JSContext    *context,
     if (!JS_GetProperty(context, in_object, constructor_name, &value))
         return NULL;
 
+    JS::RootedObject constructor(context);
     if (value.isUndefined()) {
         /* In case we're looking for a private type, and we don't find it,
            we need to define it first.
@@ -1517,14 +1517,13 @@ gjs_lookup_object_prototype_from_info(JSContext    *context,
                                       GIObjectInfo *info,
                                       GType         gtype)
 {
-    JSObject *constructor;
-    JS::Value value;
-
-    constructor = gjs_lookup_object_constructor_from_info(context, info, gtype);
+    JS::RootedObject constructor(context,
+        gjs_lookup_object_constructor_from_info(context, info, gtype));
 
     if (G_UNLIKELY (constructor == NULL))
         return NULL;
 
+    JS::RootedValue value(context);
     if (!gjs_object_get_property_const(context, constructor,
                                        GJS_STRING_PROTOTYPE, &value))
         return NULL;
@@ -1895,15 +1894,14 @@ gjs_object_define_static_methods(JSContext    *context,
 }
 
 void
-gjs_define_object_class(JSContext      *context,
-                        JSObject       *in_object,
-                        GIObjectInfo   *info,
-                        GType           gtype,
-                        JSObject      **constructor_p)
+gjs_define_object_class(JSContext              *context,
+                        JSObject               *in_object,
+                        GIObjectInfo           *info,
+                        GType                   gtype,
+                        JS::MutableHandleObject constructor)
 {
     const char *constructor_name;
     JSObject *prototype;
-    JSObject *constructor;
     JSObject *parent_proto;
     JSObject *global;
 
@@ -1977,7 +1975,7 @@ gjs_define_object_class(JSContext      *context,
                                 /* funcs of constructor, MyConstructor.myfunc() */
                                 NULL,
                                 &prototype,
-                                &constructor)) {
+                                constructor)) {
         g_error("Can't init class %s", constructor_name);
     }
 
@@ -1999,9 +1997,6 @@ gjs_define_object_class(JSContext      *context,
     value = JS::ObjectValue(*gjs_gtype_create_gtype_wrapper(context, gtype));
     JS_DefineProperty(context, constructor, "$gtype", value,
                       NULL, NULL, JSPROP_PERMANENT);
-
-    if (constructor_p)
-        *constructor_p = constructor;
 }
 
 static JSObject*
@@ -2589,7 +2584,7 @@ gjs_object_custom_init(GTypeInstance *instance,
     GjsContext *gjs_context;
     JSContext *context;
     ObjectInstance *priv;
-    JS::Value v, r;
+    JS::Value r;
 
     if (!object_init_list)
       return;
@@ -2613,6 +2608,7 @@ gjs_object_custom_init(GTypeInstance *instance,
 
     associate_js_gobject(context, object, G_OBJECT (instance));
 
+    JS::RootedValue v(context);
     if (!gjs_object_get_property_const(context, object,
                                        GJS_STRING_INSTANCE_INIT, &v)) {
         gjs_log_exception(context);
@@ -2748,8 +2744,8 @@ gjs_register_interface(JSContext *cx,
 {
     JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
     char *name = NULL;
-    JS::RootedObject interfaces(cx), properties(cx);
-    JSObject *constructor, *module;
+    JS::RootedObject interfaces(cx), properties(cx), constructor(cx);
+    JSObject *module;
     guint32 i, n_interfaces, n_properties;
     GType *iface_types;
     GType interface_type;
@@ -2828,8 +2824,8 @@ gjs_register_type(JSContext *cx,
 {
     JS::CallArgs argv = JS::CallArgsFromVp (argc, vp);
     gchar *name;
-    JS::RootedObject parent(cx), interfaces(cx), properties(cx);
-    JSObject *constructor, *module;
+    JS::RootedObject parent(cx), interfaces(cx), properties(cx), constructor(cx);
+    JSObject *module;
     GType instance_type, parent_type;
     GTypeQuery query;
     GTypeModule *type_module;
diff --git a/gi/object.h b/gi/object.h
index f09d473..2906a96 100644
--- a/gi/object.h
+++ b/gi/object.h
@@ -31,11 +31,11 @@
 
 G_BEGIN_DECLS
 
-void      gjs_define_object_class       (JSContext     *context,
-                                         JSObject      *in_object,
-                                         GIObjectInfo  *info,
-                                         GType          gtype,
-                                         JSObject     **constructor_p);
+void gjs_define_object_class(JSContext              *context,
+                             JSObject               *in_object,
+                             GIObjectInfo           *info,
+                             GType                   gtype,
+                             JS::MutableHandleObject constructor);
 
 bool gjs_lookup_object_constructor(JSContext             *context,
                                    GType                  gtype,
diff --git a/gi/param.cpp b/gi/param.cpp
index a35c5f5..ad40abd 100644
--- a/gi/param.cpp
+++ b/gi/param.cpp
@@ -183,9 +183,7 @@ static JSObject*
 gjs_lookup_param_prototype(JSContext    *context)
 {
     JSObject *in_object;
-    JSObject *constructor;
     jsid gobject_name;
-    JS::Value value;
 
     gobject_name = gjs_intern_string_to_id(context, "GObject");
     in_object = gjs_lookup_namespace_object_by_name(context, gobject_name);
@@ -193,13 +191,14 @@ gjs_lookup_param_prototype(JSContext    *context)
     if (G_UNLIKELY (!in_object))
         return NULL;
 
-    if (!JS_GetProperty(context, in_object, "ParamSpec", &value))
+    JS::RootedValue value(context);
+    if (!JS_GetProperty(context, in_object, "ParamSpec", value.address()))
         return NULL;
 
     if (G_UNLIKELY (!value.isObject()))
         return NULL;
 
-    constructor = &value.toObject();
+    JS::RootedObject constructor(context, &value.toObject());
     g_assert(constructor != NULL);
 
     if (!gjs_object_get_property_const(context, constructor,
@@ -219,7 +218,7 @@ gjs_define_param_class(JSContext    *context,
     const char *constructor_name;
     JSObject *prototype;
     JS::Value value;
-    JSObject *constructor;
+    JS::RootedObject constructor(context);
     GIObjectInfo *info;
 
     constructor_name = "ParamSpec";
diff --git a/gi/repo.cpp b/gi/repo.cpp
index 1b60039..2c8ade5 100644
--- a/gi/repo.cpp
+++ b/gi/repo.cpp
@@ -471,9 +471,12 @@ gjs_define_info(JSContext  *context,
             if (g_type_is_a (gtype, G_TYPE_PARAM)) {
                 gjs_define_param_class(context, in_object);
             } else if (g_type_is_a (gtype, G_TYPE_OBJECT)) {
-                gjs_define_object_class(context, in_object, (GIObjectInfo*) info, gtype, NULL);
+                JS::RootedObject ignored(context);
+                gjs_define_object_class(context, in_object,
+                                        (GIObjectInfo *) info, gtype, &ignored);
             } else if (G_TYPE_IS_INSTANTIATABLE(gtype)) {
-                if (!gjs_define_fundamental_class(context, in_object, (GIObjectInfo*)info, NULL, NULL)) {
+                JS::RootedObject ignored(context);
+                if (!gjs_define_fundamental_class(context, in_object, (GIObjectInfo*)info, &ignored, NULL)) {
                     gjs_throw (context,
                                "Unsupported fundamental class creation for type %s",
                                g_type_name(gtype));
@@ -522,9 +525,13 @@ gjs_define_info(JSContext  *context,
             return false;
         break;
     case GI_INFO_TYPE_INTERFACE:
-        gjs_define_interface_class(context, in_object, (GIInterfaceInfo *) info,
-                                   g_registered_type_info_get_g_type((GIRegisteredTypeInfo *) info),
-                                   NULL);
+        {
+            JS::RootedObject ignored(context);
+            gjs_define_interface_class(context, in_object,
+                                       (GIInterfaceInfo *) info,
+                                       g_registered_type_info_get_g_type((GIRegisteredTypeInfo *) info),
+                                       &ignored);
+        }
         break;
     default:
         gjs_throw(context, "API of type %s not implemented, cannot define %s.%s",
@@ -784,13 +791,12 @@ JSObject *
 gjs_lookup_generic_prototype(JSContext  *context,
                              GIBaseInfo *info)
 {
-    JSObject *constructor;
-    JS::Value value;
-
-    constructor = gjs_lookup_generic_constructor(context, info);
+    JS::RootedObject constructor(context,
+                                 gjs_lookup_generic_constructor(context, info));
     if (G_UNLIKELY (constructor == NULL))
         return NULL;
 
+    JS::RootedValue value(context);
     if (!gjs_object_get_property_const(context, constructor,
                                        GJS_STRING_PROTOTYPE, &value))
         return NULL;
diff --git a/gi/union.cpp b/gi/union.cpp
index 8515612..76663e7 100644
--- a/gi/union.cpp
+++ b/gi/union.cpp
@@ -332,7 +332,7 @@ gjs_define_union_class(JSContext    *context,
     JS::Value value;
     Union *priv;
     GType gtype;
-    JSObject *constructor;
+    JS::RootedObject constructor(context);
 
     /* For certain unions, we may be able to relax this in the future by
      * directly allocating union memory, as we do for structures in boxed.c
diff --git a/gjs/context.cpp b/gjs/context.cpp
index ff39cd1..7596345 100644
--- a/gjs/context.cpp
+++ b/gjs/context.cpp
@@ -750,14 +750,13 @@ gjs_context_get_const_string(JSContext      *context,
 }
 
 bool
-gjs_object_get_property_const(JSContext      *context,
-                              JSObject       *obj,
-                              GjsConstString  property_name,
-                              JS::Value      *value_p)
+gjs_object_get_property_const(JSContext             *cx,
+                              JS::HandleObject       obj,
+                              GjsConstString         property_name,
+                              JS::MutableHandleValue value_p)
 {
-    jsid pname;
-    pname = gjs_context_get_const_string(context, property_name);
-    return JS_GetPropertyById(context, obj, pname, value_p);
+    JS::RootedId pname(cx, gjs_context_get_const_string(cx, property_name));
+    return JS_GetPropertyById(cx, obj, pname, value_p.address());
 }
 
 /**
diff --git a/gjs/jsapi-dynamic-class.cpp b/gjs/jsapi-dynamic-class.cpp
index 2581b2a..84b09e8 100644
--- a/gjs/jsapi-dynamic-class.cpp
+++ b/gjs/jsapi-dynamic-class.cpp
@@ -36,26 +36,25 @@
 #include <math.h>
 
 bool
-gjs_init_class_dynamic(JSContext       *context,
-                       JSObject        *in_object,
-                       JSObject        *parent_proto,
-                       const char      *ns_name,
-                       const char      *class_name,
-                       JSClass         *clasp,
-                       JSNative         constructor_native,
-                       unsigned         nargs,
-                       JSPropertySpec  *proto_ps,
-                       JSFunctionSpec  *proto_fs,
-                       JSPropertySpec  *static_ps,
-                       JSFunctionSpec  *static_fs,
-                       JSObject       **prototype_p,
-                       JSObject       **constructor_p)
+gjs_init_class_dynamic(JSContext              *context,
+                       JSObject               *in_object,
+                       JSObject               *parent_proto,
+                       const char             *ns_name,
+                       const char             *class_name,
+                       JSClass                *clasp,
+                       JSNative                constructor_native,
+                       unsigned                nargs,
+                       JSPropertySpec         *proto_ps,
+                       JSFunctionSpec         *proto_fs,
+                       JSPropertySpec         *static_ps,
+                       JSFunctionSpec         *static_fs,
+                       JSObject              **prototype_p,
+                       JS::MutableHandleObject constructor)
 {
     JSObject *global;
     /* Force these variables on the stack, so the conservative GC will
        find them */
     JSObject * volatile prototype;
-    JSObject * volatile constructor;
     JSFunction * volatile constructor_fun;
     char *full_function_name = NULL;
     bool res = false;
@@ -102,7 +101,7 @@ gjs_init_class_dynamic(JSContext       *context,
     if (!constructor_fun)
         goto out;
 
-    constructor = JS_GetFunctionObject(constructor_fun);
+    constructor.set(JS_GetFunctionObject(constructor_fun));
 
     if (static_ps && !JS_DefineProperties(context, constructor, static_ps))
         goto out;
@@ -122,8 +121,6 @@ gjs_init_class_dynamic(JSContext       *context,
                            JS_PropertyStub, JS_StrictPropertyStub, GJS_MODULE_PROP_FLAGS))
         goto out;
 
-    if (constructor_p)
-        *constructor_p = constructor;
     if (prototype_p)
         *prototype_p = prototype;
 
@@ -131,7 +128,6 @@ gjs_init_class_dynamic(JSContext       *context,
 
     prototype = NULL;
     constructor_fun = NULL;
-    constructor = NULL;
 
  out:
     JS_EndRequest(context);
diff --git a/gjs/jsapi-util.cpp b/gjs/jsapi-util.cpp
index 0cf09b3..cd65759 100644
--- a/gjs/jsapi-util.cpp
+++ b/gjs/jsapi-util.cpp
@@ -193,14 +193,15 @@ gjs_throw_abstract_constructor_error(JSContext *context,
                                      JS::Value *vp)
 {
     JS::Value callee;
-    JS::Value prototype;
     JSClass *proto_class;
     const char *name = "anonymous";
 
     callee = JS_CALLEE(context, vp);
 
     if (callee.isObject()) {
-        if (gjs_object_get_property_const(context, &callee.toObject(),
+        JS::RootedObject callee_obj(context, &callee.toObject());
+        JS::RootedValue prototype(context);
+        if (gjs_object_get_property_const(context, callee_obj,
                                           GJS_STRING_PROTOTYPE, &prototype)) {
             proto_class = JS_GetClass(&prototype.toObject());
             name = proto_class->name;
@@ -484,25 +485,25 @@ gjs_log_exception_full(JSContext *context,
                        JS::Value  exc,
                        JSString  *message)
 {
-    JS::Value stack;
     char *utf8_exception, *utf8_message;
     bool is_syntax;
 
     JS_BeginRequest(context);
+    JS::RootedObject exc_obj(context);
 
     is_syntax = false;
 
     if (!exc.isObject()) {
         utf8_exception = utf8_exception_from_non_gerror_value(context, exc);
     } else {
-        JS::RootedObject exc_obj(context, &exc.toObject());
+        exc_obj = &exc.toObject();
         if (gjs_typecheck_boxed(context, exc_obj, NULL, G_TYPE_ERROR, false)) {
             GError *gerror = (GError *) gjs_c_struct_from_boxed(context, exc_obj);
             utf8_exception = g_strdup_printf("GLib.Error %s: %s",
                                              g_quark_to_string(gerror->domain),
                                              gerror->message);
         } else {
-            JS::Value js_name;
+            JS::RootedValue js_name(context);
             char *utf8_name;
 
             if (gjs_object_get_property_const(context, exc_obj,
@@ -527,14 +528,14 @@ gjs_log_exception_full(JSContext *context,
     */
 
     if (is_syntax) {
-        JS::Value js_lineNumber, js_fileName;
+        JS::RootedValue js_lineNumber(context), js_fileName(context);
         unsigned lineNumber;
         char *utf8_fileName;
 
-        gjs_object_get_property_const(context, &exc.toObject(),
-                                      GJS_STRING_LINE_NUMBER, &js_lineNumber);
-        gjs_object_get_property_const(context, &exc.toObject(),
-                                      GJS_STRING_FILENAME, &js_fileName);
+        gjs_object_get_property_const(context, exc_obj, GJS_STRING_LINE_NUMBER,
+                                      &js_lineNumber);
+        gjs_object_get_property_const(context, exc_obj, GJS_STRING_FILENAME,
+                                      &js_fileName);
 
         if (js_fileName.isString())
             gjs_string_to_utf8(context, js_fileName, &utf8_fileName);
@@ -554,10 +555,10 @@ gjs_log_exception_full(JSContext *context,
         g_free(utf8_fileName);
     } else {
         char *utf8_stack;
+        JS::RootedValue stack(context);
 
         if (exc.isObject() &&
-            gjs_object_get_property_const(context, &exc.toObject(),
-                                          GJS_STRING_STACK, &stack) &&
+            gjs_object_get_property_const(context, exc_obj, GJS_STRING_STACK, &stack) &&
             stack.isString())
             gjs_string_to_utf8(context, stack, &utf8_stack);
         else
diff --git a/gjs/jsapi-util.h b/gjs/jsapi-util.h
index 0b7c91f..a757965 100644
--- a/gjs/jsapi-util.h
+++ b/gjs/jsapi-util.h
@@ -307,20 +307,21 @@ bool        gjs_object_require_property      (JSContext       *context,
                                               jsid             property_name,
                                               JS::Value       *value_p);
 
-bool        gjs_init_class_dynamic           (JSContext       *context,
-                                              JSObject        *in_object,
-                                              JSObject        *parent_proto,
-                                              const char      *ns_name,
-                                              const char      *class_name,
-                                              JSClass         *clasp,
-                                              JSNative         constructor,
-                                              unsigned         nargs,
-                                              JSPropertySpec  *ps,
-                                              JSFunctionSpec  *fs,
-                                              JSPropertySpec  *static_ps,
-                                              JSFunctionSpec  *static_fs,
-                                              JSObject       **constructor_p,
-                                              JSObject       **prototype_p);
+bool gjs_init_class_dynamic(JSContext              *context,
+                            JSObject               *in_object,
+                            JSObject               *parent_proto,
+                            const char             *ns_name,
+                            const char             *class_name,
+                            JSClass                *clasp,
+                            JSNative                constructor_native,
+                            unsigned                nargs,
+                            JSPropertySpec         *ps,
+                            JSFunctionSpec         *fs,
+                            JSPropertySpec         *static_ps,
+                            JSFunctionSpec         *static_fs,
+                            JSObject              **prototype_p,
+                            JS::MutableHandleObject constructor);
+
 void gjs_throw_constructor_error             (JSContext       *context);
 void gjs_throw_abstract_constructor_error    (JSContext       *context,
                                               JS::Value       *vp);
@@ -438,10 +439,10 @@ const char* gjs_get_type_name                (JS::Value        value);
 
 void gjs_maybe_gc (JSContext *context);
 
-bool              gjs_context_get_frame_info (JSContext  *context,
-                                              JS::Value  *stack,
-                                              JS::Value  *fileName,
-                                              JS::Value  *lineNumber);
+bool gjs_context_get_frame_info(JSContext             *context,
+                                JS::MutableHandleValue stack,
+                                JS::MutableHandleValue fileName,
+                                JS::MutableHandleValue lineNumber);
 
 bool              gjs_eval_with_scope        (JSContext    *context,
                                               JSObject     *object,
@@ -482,10 +483,11 @@ typedef enum {
 
 jsid              gjs_context_get_const_string  (JSContext       *context,
                                                  GjsConstString   string);
-bool              gjs_object_get_property_const (JSContext       *context,
-                                                 JSObject        *obj,
-                                                 GjsConstString   property_name,
-                                                 JS::Value       *value_p);
+
+bool gjs_object_get_property_const(JSContext             *cx,
+                                   JS::HandleObject       obj,
+                                   GjsConstString         property_name,
+                                   JS::MutableHandleValue value_p);
 
 const char * gjs_strip_unix_shebang(const char *script,
                                     gssize     *script_len,
diff --git a/gjs/stack.cpp b/gjs/stack.cpp
index 9f2b3f5..5b00c9a 100644
--- a/gjs/stack.cpp
+++ b/gjs/stack.cpp
@@ -48,64 +48,52 @@
 #include "jsapi-util.h"
 
 bool
-gjs_context_get_frame_info (JSContext  *context,
-                            JS::Value  *stack,
-                            JS::Value  *fileName,
-                            JS::Value  *lineNumber)
+gjs_context_get_frame_info(JSContext             *context,
+                           JS::MutableHandleValue stack,
+                           JS::MutableHandleValue fileName,
+                           JS::MutableHandleValue lineNumber)
 {
     JS::Value v_constructor;
-    JSObject *err_obj;
     JSObject *global;
-    bool ret = false;
 
-    JS_BeginRequest(context);
+    JSAutoRequest ar(context);
     global = JS_GetGlobalForScopeChain(context);
     JSAutoCompartment ac(context, global);
 
     if (!JS_GetProperty(context, global, "Error", &v_constructor) ||
         !v_constructor.isObject()) {
         g_error("??? Missing Error constructor in global object?");
-        goto out;
+        return false;
     }
 
-    err_obj = JS_New(context, &v_constructor.toObject(), 0, NULL);
+    JS::RootedObject err_obj(context,
+                             JS_New(context, &v_constructor.toObject(), 0, NULL));
 
-    if (stack != NULL) {
-        if (!gjs_object_get_property_const(context, err_obj,
-                                           GJS_STRING_STACK, stack))
-            goto out;
-    }
-
-    if (fileName != NULL) {
-        if (!gjs_object_get_property_const(context, err_obj,
-                                           GJS_STRING_FILENAME, fileName))
-            goto out;
-    }
+    if (!gjs_object_get_property_const(context, err_obj, GJS_STRING_STACK, stack))
+        return false;
 
-    if (lineNumber != NULL) {
-        if (!gjs_object_get_property_const(context, err_obj,
-                                           GJS_STRING_LINE_NUMBER, lineNumber))
-            goto out;
-    }
+    if (!gjs_object_get_property_const(context, err_obj, GJS_STRING_FILENAME,
+        fileName))
+        return false;
 
-    ret = true;
+    if (!gjs_object_get_property_const(context, err_obj, GJS_STRING_LINE_NUMBER,
+        lineNumber))
+        return false;
 
- out:
-    JS_EndRequest(context);
-    return ret;
+    return true;
 }
 
 void
 gjs_context_print_stack_stderr(GjsContext *context)
 {
     JSContext *cx = (JSContext*) gjs_context_get_native_context(context);
-    JS::Value v_stack;
+    JS::RootedValue v_stack(cx), ignored(cx);
     char *stack;
 
     g_printerr("== Stack trace for context %p ==\n", context);
 
     /* Stderr is locale encoding, so we use string_to_filename here */
-    if (!gjs_context_get_frame_info(cx, &v_stack, NULL, NULL) ||
+    if (!gjs_context_get_frame_info(cx, &v_stack, &ignored, &ignored) ||
         !gjs_string_to_filename(cx, v_stack, &stack)) {
         g_printerr("No stack trace available\n");
         return;
diff --git a/modules/cairo-region.cpp b/modules/cairo-region.cpp
index ecee331..f941374 100644
--- a/modules/cairo-region.cpp
+++ b/modules/cairo-region.cpp
@@ -51,7 +51,8 @@ get_region(JSContext       *context,
 }
 
 static bool
-fill_rectangle(JSContext *context, JSObject *obj,
+fill_rectangle(JSContext             *context,
+               JS::HandleObject       obj,
                cairo_rectangle_int_t *rect);
 
 #define PRELUDE                                                       \
@@ -113,10 +114,11 @@ REGION_DEFINE_RECT_FUNC(intersect)
 REGION_DEFINE_RECT_FUNC(xor)
 
 static bool
-fill_rectangle(JSContext *context, JSObject *obj,
+fill_rectangle(JSContext             *context,
+               JS::HandleObject       obj,
                cairo_rectangle_int_t *rect)
 {
-    JS::Value val;
+    JS::RootedValue val(context);
 
     if (!gjs_object_get_property_const(context, obj, GJS_STRING_X, &val))
         return false;


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