[gjs/wip/ptomato/mozjs31prep: 5/5] WIP - rooting in constructors - buggy



commit 339e6d9f6ad00aca9380a31d7bc03c6dd7c9e686
Author: Philip Chimento <philip chimento gmail com>
Date:   Sat Sep 24 22:19:48 2016 -0700

    WIP - rooting in constructors - buggy

 gi/arg.cpp                        |   76 ++++++++++-----------
 gi/boxed.cpp                      |   39 ++++++-----
 gi/boxed.h                        |    4 +-
 gi/function.cpp                   |   61 ++++++++---------
 gi/function.h                     |   24 ++++----
 gi/fundamental.cpp                |   70 +++++++++-----------
 gi/fundamental.h                  |   16 +++--
 gi/gerror.cpp                     |   23 +++----
 gi/gerror.h                       |    4 +-
 gi/gtype.cpp                      |   20 +++---
 gi/gtype.h                        |    6 +-
 gi/keep-alive.cpp                 |   11 +--
 gi/ns.cpp                         |    3 +-
 gi/object.cpp                     |  132 +++++++++++++++++--------------------
 gi/object.h                       |   21 ++++---
 gi/param.cpp                      |   12 ++--
 gi/param.h                        |   15 +++--
 gi/repo.cpp                       |    3 +-
 gi/union.cpp                      |   34 +++++-----
 gi/union.h                        |    8 ++-
 gi/value.cpp                      |   20 +++---
 gjs/byteArray.cpp                 |   96 +++++++++++----------------
 gjs/byteArray.h                   |   22 +++---
 gjs/importer.cpp                  |    4 +-
 gjs/jsapi-util.cpp                |   40 +++++++-----
 gjs/jsapi-util.h                  |   18 +++---
 modules/cairo-context.cpp         |   50 +++++++-------
 modules/cairo-image-surface.cpp   |    9 +--
 modules/cairo-linear-gradient.cpp |    5 +-
 modules/cairo-path.cpp            |    4 +-
 modules/cairo-pattern.cpp         |    2 +-
 modules/cairo-pdf-surface.cpp     |    5 +-
 modules/cairo-private.h           |    6 +-
 modules/cairo-ps-surface.cpp      |    5 +-
 modules/cairo-radial-gradient.cpp |    5 +-
 modules/cairo-region.cpp          |   25 ++++----
 modules/cairo-solid-pattern.cpp   |    5 +-
 modules/cairo-surface-pattern.cpp |    5 +-
 modules/cairo-surface.cpp         |    7 +-
 modules/cairo-svg-surface.cpp     |    5 +-
 modules/system.cpp                |    5 +-
 41 files changed, 445 insertions(+), 480 deletions(-)
---
diff --git a/gi/arg.cpp b/gi/arg.cpp
index 4f90602..81719da 100644
--- a/gi/arg.cpp
+++ b/gi/arg.cpp
@@ -633,7 +633,8 @@ gjs_gtypearray_to_array(JSContext   *context,
         if (!elem.isObjectOrNull())
             goto err;
 
-        gtype = gjs_gtype_get_actual_gtype(context, elem.toObjectOrNull());
+        JS::RootedObject elem_obj(context, elem.toObjectOrNull());
+        gtype = gjs_gtype_get_actual_gtype(context, elem_obj);
         if (gtype == G_TYPE_INVALID)
             goto err;
 
@@ -1276,7 +1277,8 @@ gjs_value_to_g_argument(JSContext      *context,
     case GI_TYPE_TAG_GTYPE:
         if (value.isObjectOrNull()) {
             GType gtype;
-            gtype = gjs_gtype_get_actual_gtype(context, value.toObjectOrNull());
+            JS::RootedObject obj(context, value.toObjectOrNull());
+            gtype = gjs_gtype_get_actual_gtype(context, obj);
             if (gtype == G_TYPE_INVALID)
                 wrong = true;
             arg->v_ssize = gtype;
@@ -1324,8 +1326,9 @@ gjs_value_to_g_argument(JSContext      *context,
         if (value.isNull()) {
             arg->v_pointer = NULL;
         } else if (value.isObject()) {
-            if (gjs_typecheck_gerror(context, &value.toObject(), true)) {
-                arg->v_pointer = gjs_gerror_from_error(context, &value.toObject());
+            JS::RootedObject obj(context, &value.toObject());
+            if (gjs_typecheck_gerror(context, obj, true)) {
+                arg->v_pointer = gjs_gerror_from_error(context, obj);
 
                 if (transfer != GI_TRANSFER_NOTHING)
                     arg->v_pointer = g_error_copy ((const GError *) arg->v_pointer);
@@ -1413,12 +1416,13 @@ gjs_value_to_g_argument(JSContext      *context,
             } else if (value.isNull()) {
                 arg->v_pointer = NULL;
             } else if (value.isObject()) {
+                JS::RootedObject obj(context, &value.toObject());
                 if (interface_type == GI_INFO_TYPE_STRUCT &&
                     g_struct_info_is_gtype_struct((GIStructInfo*)interface_info)) {
                     GType actual_gtype;
                     gpointer klass;
 
-                    actual_gtype = gjs_gtype_get_actual_gtype(context, &value.toObject());
+                    actual_gtype = gjs_gtype_get_actual_gtype(context, obj);
 
                     if (actual_gtype == G_TYPE_NONE) {
                         wrong = true;
@@ -1442,27 +1446,24 @@ gjs_value_to_g_argument(JSContext      *context,
                     /* Handle Struct/Union first since we don't necessarily need a GType for them */
                     /* We special case Closures later, so skip them here */
                     !g_type_is_a(gtype, G_TYPE_CLOSURE)) {
-                    JSObject *obj = &value.toObject();
 
                     if (g_type_is_a(gtype, G_TYPE_BYTES)
                         && gjs_typecheck_bytearray(context, obj, false)) {
                         arg->v_pointer = gjs_byte_array_get_bytes(context, obj);
                     } else if (g_type_is_a(gtype, G_TYPE_ERROR)) {
-                        if (!gjs_typecheck_gerror(context, &value.toObject(), true)) {
+                        if (!gjs_typecheck_gerror(context, obj, true)) {
                             arg->v_pointer = NULL;
                             wrong = true;
                         } else {
-                            arg->v_pointer = gjs_gerror_from_error(context,
-                                                                   &value.toObject());
+                            arg->v_pointer = gjs_gerror_from_error(context, obj);
                         }
                     } else {
-                        if (!gjs_typecheck_boxed(context, &value.toObject(),
-                                                 interface_info, gtype, true)) {
+                        if (!gjs_typecheck_boxed(context, obj, interface_info,
+                                                 gtype, true)) {
                             arg->v_pointer = NULL;
                             wrong = true;
                         } else {
-                            arg->v_pointer = gjs_c_struct_from_boxed(context,
-                                                                     &value.toObject());
+                            arg->v_pointer = gjs_c_struct_from_boxed(context, obj);
                         }
                     }
 
@@ -1480,10 +1481,8 @@ gjs_value_to_g_argument(JSContext      *context,
                     }
 
                 } else if (interface_type == GI_INFO_TYPE_UNION) {
-                    if (gjs_typecheck_union(context, &value.toObject(),
-                                            interface_info, gtype, true)) {
-                        arg->v_pointer = gjs_c_union_from_union(context,
-                                                                &value.toObject());
+                    if (gjs_typecheck_union(context, obj, interface_info, gtype, true)) {
+                        arg->v_pointer = gjs_c_union_from_union(context, obj);
 
                         if (transfer != GI_TRANSFER_NOTHING) {
                             if (g_type_is_a(gtype, G_TYPE_BOXED))
@@ -1503,9 +1502,8 @@ gjs_value_to_g_argument(JSContext      *context,
 
                 } else if (gtype != G_TYPE_NONE) {
                     if (g_type_is_a(gtype, G_TYPE_OBJECT)) {
-                        if (gjs_typecheck_object(context, &value.toObject(), gtype, true)) {
-                            arg->v_pointer = gjs_g_object_from_object(context,
-                                                                      &value.toObject());
+                        if (gjs_typecheck_object(context, obj, gtype, true)) {
+                            arg->v_pointer = gjs_g_object_from_object(context, obj);
 
                             if (transfer != GI_TRANSFER_NOTHING)
                                 g_object_ref(G_OBJECT(arg->v_pointer));
@@ -1514,8 +1512,8 @@ gjs_value_to_g_argument(JSContext      *context,
                             wrong = true;
                         }
                     } else if (g_type_is_a(gtype, G_TYPE_PARAM)) {
-                        if (gjs_typecheck_param(context, &value.toObject(), gtype, true)) {
-                            arg->v_pointer = gjs_g_param_from_param(context, &value.toObject());
+                        if (gjs_typecheck_param(context, obj, gtype, true)) {
+                            arg->v_pointer = gjs_g_param_from_param(context, obj);
                             if (transfer != GI_TRANSFER_NOTHING)
                                 g_param_spec_ref(G_PARAM_SPEC(arg->v_pointer));
                         } else {
@@ -1537,9 +1535,8 @@ gjs_value_to_g_argument(JSContext      *context,
                                       interface_type);
                         }
                     } else if (G_TYPE_IS_INSTANTIATABLE(gtype)) {
-                        if (gjs_typecheck_fundamental(context, &value.toObject(), gtype, true)) {
-                            arg->v_pointer = gjs_g_fundamental_from_object(context,
-                                                                           &value.toObject());
+                        if (gjs_typecheck_fundamental(context, obj, gtype, true)) {
+                            arg->v_pointer = gjs_g_fundamental_from_object(context, obj);
 
                             if (transfer != GI_TRANSFER_NOTHING)
                                 gjs_fundamental_ref(context, arg->v_pointer);
@@ -1550,19 +1547,19 @@ gjs_value_to_g_argument(JSContext      *context,
                     } else if (G_TYPE_IS_INTERFACE(gtype)) {
                         /* Could be a GObject interface that's missing a prerequisite, or could
                            be a fundamental */
-                        if (gjs_typecheck_object(context, &value.toObject(), gtype, false)) {
-                            arg->v_pointer = gjs_g_object_from_object(context, &value.toObject());
+                        if (gjs_typecheck_object(context, obj, gtype, false)) {
+                            arg->v_pointer = gjs_g_object_from_object(context, obj);
 
                             if (transfer != GI_TRANSFER_NOTHING)
                                 g_object_ref(arg->v_pointer);
-                        } else if (gjs_typecheck_fundamental(context, &value.toObject(), gtype, false)) {
-                            arg->v_pointer = gjs_g_fundamental_from_object(context, &value.toObject());
+                        } else if (gjs_typecheck_fundamental(context, obj, gtype, false)) {
+                            arg->v_pointer = gjs_g_fundamental_from_object(context, obj);
 
                             if (transfer != GI_TRANSFER_NOTHING)
                                 gjs_fundamental_ref(context, arg->v_pointer);
                         } else {
                             /* Call again with throw=true to set the exception */
-                            gjs_typecheck_object(context, &value.toObject(), gtype, true);
+                            gjs_typecheck_object(context, obj, gtype, true);
                             arg->v_pointer = NULL;
                             wrong = true;
                         }
@@ -1737,17 +1734,16 @@ gjs_value_to_g_argument(JSContext      *context,
         /* First, let's handle the case where we're passed an instance
          * of our own byteArray class.
          */
-        if (value.isObjectOrNull() &&
-            gjs_typecheck_bytearray(context, value.toObjectOrNull(), false))
-            {
-                JSObject *bytearray_obj = value.toObjectOrNull();
-                if (array_type == GI_ARRAY_TYPE_BYTE_ARRAY) {
-                    arg->v_pointer = gjs_byte_array_get_byte_array(context, bytearray_obj);
-                    break;
-                } else {
-                    /* Fall through, !handled */
-                }
+        if (value.isObjectOrNull()) {
+            JS::RootedObject bytearray_obj(context, value.toObjectOrNull());
+            if (gjs_typecheck_bytearray(context, bytearray_obj, false)
+                && array_type == GI_ARRAY_TYPE_BYTE_ARRAY) {
+                arg->v_pointer = gjs_byte_array_get_byte_array(context, bytearray_obj);
+                break;
+            } else {
+                /* Fall through, !handled */
             }
+        }
 
         if (!gjs_array_to_explicit_array_internal(context,
                                                   value,
diff --git a/gi/boxed.cpp b/gi/boxed.cpp
index e2af668..a0fdf3f 100644
--- a/gi/boxed.cpp
+++ b/gi/boxed.cpp
@@ -204,7 +204,8 @@ boxed_get_copy_source(JSContext *context,
     if (!value.isObject())
         return false;
 
-    if (!priv_from_js_with_typecheck(context, &value.toObject(), &source_priv))
+    JS::RootedObject object(context, &value.toObject());
+    if (!priv_from_js_with_typecheck(context, object, &source_priv))
         return false;
 
     if (!g_base_info_equal((GIBaseInfo*) priv->info, (GIBaseInfo*) source_priv->info))
@@ -427,7 +428,7 @@ GJS_NATIVE_CONSTRUCTOR_DECLARE(boxed)
     GJS_NATIVE_CONSTRUCTOR_VARIABLES(boxed)
     Boxed *priv;
     Boxed *proto_priv;
-    JSObject *proto;
+    JS::RootedObject proto(context);
     Boxed *source_priv;
     JS::Value actual_rval;
     bool retval;
@@ -445,7 +446,7 @@ GJS_NATIVE_CONSTRUCTOR_DECLARE(boxed)
                         "boxed constructor, obj %p priv %p",
                         object, priv);
 
-    JS_GetPrototype(context, object, &proto);
+    JS_GetPrototype(context, object, proto.address());
     gjs_debug_lifecycle(GJS_DEBUG_GBOXED, "boxed instance __proto__ is %p", proto);
     /* If we're the prototype, then post-construct we'll fill in priv->info.
      * If we are not the prototype, though, then we'll get ->info from the
@@ -583,7 +584,6 @@ get_nested_interface_object (JSContext   *context,
                              JS::Value   *value)
 {
     JSObject *obj;
-    JSObject *proto;
     int offset;
     Boxed *priv;
     Boxed *proto_priv;
@@ -596,7 +596,9 @@ get_nested_interface_object (JSContext   *context,
         return false;
     }
 
-    proto = gjs_lookup_generic_prototype(context, (GIBoxedInfo*) interface_info);
+    JS::RootedObject proto(context,
+                           gjs_lookup_generic_prototype(context,
+                                                        (GIBoxedInfo*) interface_info));
     proto_priv = priv_from_js(context, proto);
 
     offset = g_field_info_get_offset (field_info);
@@ -707,7 +709,6 @@ set_nested_interface_object (JSContext   *context,
                              GIBaseInfo  *interface_info,
                              JS::Value    value)
 {
-    JSObject *proto;
     int offset;
     Boxed *proto_priv;
     Boxed *source_priv;
@@ -720,14 +721,17 @@ set_nested_interface_object (JSContext   *context,
         return false;
     }
 
-    proto = gjs_lookup_generic_prototype(context, (GIBoxedInfo*) interface_info);
+    JS::RootedObject proto(context,
+                           gjs_lookup_generic_prototype(context,
+                                                        (GIBoxedInfo*) interface_info));
     proto_priv = priv_from_js(context, proto);
 
     /* If we can't directly copy from the source object we need
      * to construct a new temporary object.
      */
     if (!boxed_get_copy_source(context, proto_priv, value, &source_priv)) {
-        JSObject *tmp_object = gjs_construct_object_dynamic(context, proto, 1, &value);
+        JS::RootedObject tmp_object(context,
+                                    gjs_construct_object_dynamic(context, proto, 1, &value));
         if (!tmp_object)
             return false;
 
@@ -893,7 +897,7 @@ to_string_func(JSContext *context,
                JS::Value *vp)
 {
     JS::CallReceiver rec = JS::CallReceiverFromVp(vp);
-    JSObject *obj = rec.thisv().toObjectOrNull();
+    JS::RootedObject obj(context, rec.thisv().toObjectOrNull());
 
     Boxed *priv;
     bool ret = false;
@@ -1196,7 +1200,6 @@ gjs_boxed_from_c_struct(JSContext             *context,
                         GjsBoxedCreationFlags  flags)
 {
     JSObject *obj;
-    JSObject *proto;
     Boxed *priv;
     Boxed *proto_priv;
 
@@ -1207,7 +1210,7 @@ gjs_boxed_from_c_struct(JSContext             *context,
                       "Wrapping struct %s %p with JSObject",
                       g_base_info_get_name((GIBaseInfo *)info), gboxed);
 
-    proto = gjs_lookup_generic_prototype(context, info);
+    JS::RootedObject proto(context, gjs_lookup_generic_prototype(context, info));
     proto_priv = priv_from_js(context, proto);
 
     obj = JS_NewObjectWithGivenProto(context,
@@ -1248,8 +1251,8 @@ gjs_boxed_from_c_struct(JSContext             *context,
 }
 
 void*
-gjs_c_struct_from_boxed(JSContext    *context,
-                        JSObject     *obj)
+gjs_c_struct_from_boxed(JSContext       *context,
+                        JS::HandleObject obj)
 {
     Boxed *priv;
 
@@ -1264,11 +1267,11 @@ gjs_c_struct_from_boxed(JSContext    *context,
 }
 
 bool
-gjs_typecheck_boxed(JSContext     *context,
-                    JSObject      *object,
-                    GIStructInfo  *expected_info,
-                    GType          expected_type,
-                    bool           throw_error)
+gjs_typecheck_boxed(JSContext       *context,
+                    JS::HandleObject object,
+                    GIStructInfo    *expected_info,
+                    GType            expected_type,
+                    bool             throw_error)
 {
     Boxed *priv;
     bool result;
diff --git a/gi/boxed.h b/gi/boxed.h
index f9cfcae..698ed59 100644
--- a/gi/boxed.h
+++ b/gi/boxed.h
@@ -47,13 +47,13 @@ void      gjs_define_boxed_class       (JSContext             *context,
 JSObject* gjs_lookup_boxed_prototype   (JSContext             *context,
                                         GIBoxedInfo           *info);
 void*     gjs_c_struct_from_boxed      (JSContext             *context,
-                                        JSObject              *obj);
+                                        JS::HandleObject       obj);
 JSObject* gjs_boxed_from_c_struct      (JSContext             *context,
                                         GIStructInfo          *info,
                                         void                  *gboxed,
                                         GjsBoxedCreationFlags  flags);
 bool      gjs_typecheck_boxed          (JSContext             *context,
-                                        JSObject              *obj,
+                                        JS::HandleObject       obj,
                                         GIStructInfo          *expected_info,
                                         GType                  expected_type,
                                         bool                   throw_error);
diff --git a/gi/function.cpp b/gi/function.cpp
index fe650ad..f44666e 100644
--- a/gi/function.cpp
+++ b/gi/function.cpp
@@ -537,10 +537,10 @@ get_length_from_arg (GArgument *arg, GITypeTag tag)
 }
 
 static bool
-gjs_fill_method_instance (JSContext  *context,
-                          JSObject   *obj,
-                          Function   *function,
-                          GIArgument *out_arg)
+gjs_fill_method_instance(JSContext       *context,
+                         JS::HandleObject obj,
+                         Function        *function,
+                         GIArgument      *out_arg)
 {
     GIBaseInfo *container = g_base_info_get_container((GIBaseInfo *) function->info);
     GIInfoType type = g_base_info_get_type(container);
@@ -665,13 +665,13 @@ gjs_fill_method_instance (JSContext  *context,
  * providing a @r_value argument.
  */
 static bool
-gjs_invoke_c_function(JSContext      *context,
-                      Function       *function,
-                      JSObject       *obj, /* "this" object */
-                      unsigned        js_argc,
-                      JS::Value      *js_argv,
-                      JS::Value      *js_rval,
-                      GArgument      *r_value)
+gjs_invoke_c_function(JSContext       *context,
+                      Function        *function,
+                      JS::HandleObject obj, /* "this" object */
+                      unsigned         js_argc,
+                      JS::Value       *js_argv,
+                      JS::Value       *js_rval,
+                      GArgument       *r_value)
 {
     /* These first four are arrays which hold argument pointers.
      * @in_arg_cvalues: C values which are passed on input (in or inout)
@@ -1300,8 +1300,8 @@ function_call(JSContext *context,
               JS::Value *vp)
 {
     JS::CallArgs js_argv = JS::CallArgsFromVp (js_argc, vp);
-    JSObject *object = js_argv.thisv().toObjectOrNull();
-    JSObject *callee = &js_argv.callee();
+    JS::RootedObject object(context, js_argv.thisv().toObjectOrNull()),
+        callee(context, &js_argv.callee());
 
     bool success;
     Function *priv;
@@ -1309,8 +1309,8 @@ function_call(JSContext *context,
 
     priv = priv_from_js(context, callee);
     gjs_debug_marshal(GJS_DEBUG_GFUNCTION,
-                      "Call callee %p priv %p this obj %p %s", callee, priv,
-                      object,
+                      "Call callee %p priv %p this obj %p %s", callee.address(),
+                      priv, object,
                       JS_GetTypeName(context, JS_TypeOfValue(context, JS::ObjectOrNullValue(object))));
 
     if (priv == NULL)
@@ -1401,7 +1401,6 @@ function_to_string (JSContext *context,
     Function *priv;
     gchar *string;
     bool free;
-    JSObject *self;
     JS::Value retval;
     bool ret = false;
     int i, n_args, n_jsargs;
@@ -1414,7 +1413,7 @@ function_to_string (JSContext *context,
         gjs_throw(context, "this cannot be null");
         return false;
     }
-    self = &rec.thisv().toObject();
+    JS::RootedObject self(context, &rec.thisv().toObject());
 
     priv = priv_from_js (context, self);
     if (priv == NULL) {
@@ -1661,7 +1660,6 @@ function_new(JSContext      *context,
              GType           gtype,
              GICallableInfo *info)
 {
-    JSObject *function;
     JSObject *global;
     Function *priv;
     JSBool found;
@@ -1709,7 +1707,8 @@ function_new(JSContext      *context,
                   gjs_function_class.name, prototype);
     }
 
-    function = JS_NewObject(context, &gjs_function_class, NULL, global);
+    JS::RootedObject function(context,
+                              JS_NewObject(context, &gjs_function_class, NULL, global));
     if (function == NULL) {
         gjs_debug(GJS_DEBUG_GFUNCTION, "Failed to construct function");
         return NULL;
@@ -1781,12 +1780,12 @@ gjs_define_function(JSContext      *context,
 
 
 bool
-gjs_invoke_c_function_uncached (JSContext      *context,
-                                GIFunctionInfo *info,
-                                JSObject       *obj,
-                                unsigned        argc,
-                                JS::Value      *argv,
-                                JS::Value      *rval)
+gjs_invoke_c_function_uncached(JSContext       *context,
+                               GIFunctionInfo  *info,
+                               JS::HandleObject obj,
+                               unsigned         argc,
+                               JS::Value       *argv,
+                               JS::Value       *rval)
 {
   Function function;
   bool result;
@@ -1801,12 +1800,12 @@ gjs_invoke_c_function_uncached (JSContext      *context,
 }
 
 bool
-gjs_invoke_constructor_from_c (JSContext      *context,
-                               JSObject       *constructor,
-                               JSObject       *obj,
-                               unsigned        argc,
-                               JS::Value      *argv,
-                               GArgument      *rvalue)
+gjs_invoke_constructor_from_c(JSContext       *context,
+                              JS::HandleObject constructor,
+                              JS::HandleObject obj,
+                              unsigned         argc,
+                              JS::Value       *argv,
+                              GArgument       *rvalue)
 {
     Function *priv;
 
diff --git a/gi/function.h b/gi/function.h
index 48469a4..8b7c0be 100644
--- a/gi/function.h
+++ b/gi/function.h
@@ -67,19 +67,19 @@ JSObject* gjs_define_function   (JSContext      *context,
                                  GType           gtype,
                                  GICallableInfo *info);
 
-bool      gjs_invoke_c_function_uncached (JSContext      *context,
-                                          GIFunctionInfo *info,
-                                          JSObject       *obj,
-                                          unsigned        argc,
-                                          JS::Value      *argv,
-                                          JS::Value      *rval);
+bool      gjs_invoke_c_function_uncached(JSContext        *context,
+                                          GIFunctionInfo  *info,
+                                          JS::HandleObject obj,
+                                          unsigned         argc,
+                                          JS::Value       *argv,
+                                          JS::Value       *rval);
 
-bool      gjs_invoke_constructor_from_c (JSContext      *context,
-                                         JSObject       *constructor,
-                                         JSObject       *obj,
-                                         unsigned        argc,
-                                         JS::Value      *argv,
-                                         GArgument      *rvalue);
+bool      gjs_invoke_constructor_from_c(JSContext       *context,
+                                        JS::HandleObject constructor,
+                                        JS::HandleObject obj,
+                                        unsigned         argc,
+                                        JS::Value       *argv,
+                                        GArgument       *rvalue);
 
 void     gjs_init_cinvoke_profiling (void);
 
diff --git a/gi/fundamental.cpp b/gi/fundamental.cpp
index 8e4b1a2..7dc3521 100644
--- a/gi/fundamental.cpp
+++ b/gi/fundamental.cpp
@@ -132,14 +132,14 @@ static inline Fundamental *
 proto_priv_from_js(JSContext *context,
                    JSObject  *obj)
 {
-    JSObject *proto;
-    JS_GetPrototype(context, obj, &proto);
+    JS::RootedObject proto(context);
+    JS_GetPrototype(context, obj, proto.address());
     return (Fundamental*) priv_from_js(context, proto);
 }
 
 static FundamentalInstance *
-init_fundamental_instance(JSContext *context,
-                          JSObject  *object)
+init_fundamental_instance(JSContext       *context,
+                          JS::HandleObject object)
 {
     Fundamental *proto_priv;
     FundamentalInstance *priv;
@@ -168,10 +168,10 @@ init_fundamental_instance(JSContext *context,
 }
 
 static void
-associate_js_instance_to_fundamental(JSContext *context,
-                                     JSObject  *object,
-                                     void      *gfundamental,
-                                     bool       owned_ref)
+associate_js_instance_to_fundamental(JSContext       *context,
+                                     JS::HandleObject object,
+                                     void            *gfundamental,
+                                     bool             owned_ref)
 {
     FundamentalInstance *priv;
 
@@ -382,14 +382,13 @@ fundamental_instance_new_resolve(JSContext  *context,
 static bool
 fundamental_invoke_constructor(FundamentalInstance *priv,
                                JSContext           *context,
-                               JSObject            *obj,
+                               JS::HandleObject     obj,
                                unsigned             argc,
                                JS::Value           *argv,
                                GArgument           *rvalue)
 {
     JS::Value js_constructor, js_constructor_func;
     jsid constructor_const;
-    bool ret = false;
 
     constructor_const = gjs_context_get_const_string(context, GJS_STRING_CONSTRUCTOR);
     if (!gjs_object_require_property(context, obj, NULL,
@@ -399,7 +398,7 @@ fundamental_invoke_constructor(FundamentalInstance *priv,
                    "Couldn't find a constructor for type %s.%s",
                    g_base_info_get_namespace((GIBaseInfo*) priv->prototype->info),
                    g_base_info_get_name((GIBaseInfo*) priv->prototype->info));
-        goto end;
+        return false;
     }
 
     if (!gjs_object_require_property(context, js_constructor.toObjectOrNull(), NULL,
@@ -408,13 +407,11 @@ fundamental_invoke_constructor(FundamentalInstance *priv,
                    "Couldn't find a constructor for type %s.%s",
                    g_base_info_get_namespace((GIBaseInfo*) priv->prototype->info),
                    g_base_info_get_name((GIBaseInfo*) priv->prototype->info));
-        goto end;
+        return false;
     }
 
-    ret = gjs_invoke_constructor_from_c(context, js_constructor_func.toObjectOrNull(), obj, argc, argv, 
rvalue);
-
- end:
-    return ret;
+    JS::RootedObject constructor(context, js_constructor_func.toObjectOrNull());
+    return gjs_invoke_constructor_from_c(context, constructor, obj, argc, argv, rvalue);
 }
 
 /* If we set JSCLASS_CONSTRUCT_PROTOTYPE flag, then this is called on
@@ -501,7 +498,7 @@ to_string_func(JSContext *context,
                JS::Value *vp)
 {
     JS::CallReceiver rec = JS::CallReceiverFromVp(vp);
-    JSObject *obj = rec.thisv().toObjectOrNull();
+    JS::RootedObject obj(context, rec.thisv().toObjectOrNull());
 
     FundamentalInstance *priv;
     bool ret = false;
@@ -753,12 +750,11 @@ gjs_object_from_g_fundamental(JSContext    *context,
                               void         *gfundamental)
 {
     JSObject *proto;
-    JSObject *object;
 
     if (gfundamental == NULL)
         return NULL;
 
-    object = _fundamental_lookup_object(gfundamental);
+    JS::RootedObject object(context, _fundamental_lookup_object(gfundamental));
     if (object)
         return object;
 
@@ -791,11 +787,11 @@ gjs_fundamental_from_g_value(JSContext    *context,
                              const GValue *value,
                              GType         gtype)
 {
-    JSObject *proto;
     Fundamental *proto_priv;
     void *fobj;
 
-    proto = gjs_lookup_fundamental_prototype_from_gtype(context, gtype);
+    JS::RootedObject proto(context,
+                           gjs_lookup_fundamental_prototype_from_gtype(context, gtype));
     if (!proto)
         return NULL;
 
@@ -812,8 +808,8 @@ gjs_fundamental_from_g_value(JSContext    *context,
 }
 
 void*
-gjs_g_fundamental_from_object(JSContext *context,
-                              JSObject  *obj)
+gjs_g_fundamental_from_object(JSContext       *context,
+                              JS::HandleObject obj)
 {
     FundamentalInstance *priv;
 
@@ -824,7 +820,7 @@ gjs_g_fundamental_from_object(JSContext *context,
 
     if (priv == NULL) {
         gjs_throw(context,
-                  "No introspection information for %p", obj);
+                  "No introspection information for %p", obj.address());
         return NULL;
     }
 
@@ -840,18 +836,18 @@ gjs_g_fundamental_from_object(JSContext *context,
 }
 
 bool
-gjs_typecheck_is_fundamental(JSContext     *context,
-                             JSObject      *object,
-                             bool           throw_error)
+gjs_typecheck_is_fundamental(JSContext       *context,
+                             JS::HandleObject object,
+                             bool             throw_error)
 {
     return do_base_typecheck(context, object, throw_error);
 }
 
 bool
-gjs_typecheck_fundamental(JSContext *context,
-                          JSObject  *object,
-                          GType      expected_gtype,
-                          bool       throw_error)
+gjs_typecheck_fundamental(JSContext       *context,
+                          JS::HandleObject object,
+                          GType            expected_gtype,
+                          bool             throw_error)
 {
     FundamentalInstance *priv;
     bool result;
@@ -901,11 +897,9 @@ void *
 gjs_fundamental_ref(JSContext     *context,
                     void          *gfundamental)
 {
-    JSObject *proto;
     Fundamental *proto_priv;
-
-    proto = gjs_lookup_fundamental_prototype_from_gtype(context,
-                                                        G_TYPE_FROM_INSTANCE(gfundamental));
+    JS::RootedObject proto(context,
+        gjs_lookup_fundamental_prototype_from_gtype(context, G_TYPE_FROM_INSTANCE(gfundamental)));
 
     proto_priv = (Fundamental *) priv_from_js(context, proto);
 
@@ -916,11 +910,9 @@ void
 gjs_fundamental_unref(JSContext    *context,
                       void         *gfundamental)
 {
-    JSObject *proto;
     Fundamental *proto_priv;
-
-    proto = gjs_lookup_fundamental_prototype_from_gtype(context,
-                                                        G_TYPE_FROM_INSTANCE(gfundamental));
+    JS::RootedObject proto(context,
+        gjs_lookup_fundamental_prototype_from_gtype(context, G_TYPE_FROM_INSTANCE(gfundamental)));
 
     proto_priv = (Fundamental *) priv_from_js(context, proto);
 
diff --git a/gi/fundamental.h b/gi/fundamental.h
index 31bd2d0..dec8fcf 100644
--- a/gi/fundamental.h
+++ b/gi/fundamental.h
@@ -40,15 +40,19 @@ bool      gjs_define_fundamental_class       (JSContext     *context,
 JSObject* gjs_object_from_g_fundamental      (JSContext     *context,
                                               GIObjectInfo  *info,
                                               void          *fobj);
-void*     gjs_g_fundamental_from_object      (JSContext     *context,
-                                              JSObject      *obj);
+
+void     *gjs_g_fundamental_from_object(JSContext       *context,
+                                        JS::HandleObject obj);
+
 JSObject *gjs_fundamental_from_g_value       (JSContext     *context,
                                               const GValue  *value,
                                               GType          gtype);
-bool      gjs_typecheck_fundamental          (JSContext     *context,
-                                              JSObject      *object,
-                                              GType          expected_gtype,
-                                              bool           throw_error);
+
+bool      gjs_typecheck_fundamental(JSContext       *context,
+                                    JS::HandleObject object,
+                                    GType            expected_gtype,
+                                    bool             throw_error);
+
 bool      gjs_typecheck_is_fundamental       (JSContext     *context,
                                               JSObject      *object,
                                               bool           throw_error);
diff --git a/gi/gerror.cpp b/gi/gerror.cpp
index a6c6ec9..0af9909 100644
--- a/gi/gerror.cpp
+++ b/gi/gerror.cpp
@@ -60,7 +60,6 @@ GJS_NATIVE_CONSTRUCTOR_DECLARE(error)
     GJS_NATIVE_CONSTRUCTOR_VARIABLES(error)
     Error *priv;
     Error *proto_priv;
-    JSObject *proto;
     jsid message_name, code_name;
     JS::Value v_message, v_code;
     gchar *message;
@@ -84,7 +83,8 @@ GJS_NATIVE_CONSTRUCTOR_DECLARE(error)
                         "GError constructor, obj %p priv %p",
                         object, priv);
 
-    JS_GetPrototype(context, object, &proto);
+    JS::RootedObject proto(context);
+    JS_GetPrototype(context, object, proto.address());
     gjs_debug_lifecycle(GJS_DEBUG_GERROR, "GError instance __proto__ is %p", proto);
 
     /* If we're the prototype, then post-construct we'll fill in priv->info.
@@ -211,7 +211,6 @@ error_to_string(JSContext *context,
                 JS::Value *vp)
 {
     JS::Value v_self;
-    JSObject *self;
     Error *priv;
     JS::Value v_out;
     gchar *descr;
@@ -225,7 +224,7 @@ error_to_string(JSContext *context,
         return false;
     }
 
-    self = &v_self.toObject();
+    JS::RootedObject self(context, &v_self.toObject());
     priv = priv_from_js(context, self);
 
     if (priv == NULL)
@@ -290,7 +289,8 @@ error_constructor_value_of(JSContext *context,
         return false;
     }
 
-    priv = priv_from_js(context, &v_prototype.toObject());
+    JS::RootedObject prototype(context, &v_prototype.toObject());
+    priv = priv_from_js(context, prototype);
 
     if (priv == NULL)
         return false;
@@ -473,7 +473,6 @@ gjs_error_from_gerror(JSContext             *context,
                       bool                   add_stack)
 {
     JSObject *obj;
-    JSObject *proto;
     Error *priv;
     Error *proto_priv;
     GIEnumInfo *info;
@@ -500,7 +499,7 @@ gjs_error_from_gerror(JSContext             *context,
                       "Wrapping struct %s with JSObject",
                       g_base_info_get_name((GIBaseInfo *)info));
 
-    proto = gjs_lookup_generic_prototype(context, info);
+    JS::RootedObject proto(context, gjs_lookup_generic_prototype(context, info));
     proto_priv = priv_from_js(context, proto);
 
     obj = JS_NewObjectWithGivenProto(context,
@@ -522,8 +521,8 @@ gjs_error_from_gerror(JSContext             *context,
 }
 
 GError*
-gjs_gerror_from_error(JSContext    *context,
-                      JSObject     *obj)
+gjs_gerror_from_error(JSContext       *context,
+                      JS::HandleObject obj)
 {
     Error *priv;
 
@@ -553,9 +552,9 @@ gjs_gerror_from_error(JSContext    *context,
 }
 
 bool
-gjs_typecheck_gerror (JSContext *context,
-                      JSObject  *obj,
-                      bool       throw_error)
+gjs_typecheck_gerror (JSContext       *context,
+                      JS::HandleObject obj,
+                      bool             throw_error)
 {
     if (gjs_typecheck_boxed (context, obj, NULL, G_TYPE_ERROR, false))
         return true;
diff --git a/gi/gerror.h b/gi/gerror.h
index 7c9fde0..46e2862 100644
--- a/gi/gerror.h
+++ b/gi/gerror.h
@@ -36,12 +36,12 @@ void      gjs_define_error_class       (JSContext             *context,
                                         JSObject              *in_object,
                                         GIEnumInfo            *info);
 GError*   gjs_gerror_from_error        (JSContext             *context,
-                                        JSObject              *obj);
+                                        JS::HandleObject       obj);
 JSObject* gjs_error_from_gerror        (JSContext             *context,
                                         GError                *gerror,
                                         bool                   add_stack);
 bool      gjs_typecheck_gerror         (JSContext             *context,
-                                        JSObject              *obj,
+                                        JS::HandleObject       obj,
                                         bool                   throw_error);
 
 G_END_DECLS
diff --git a/gi/gtype.cpp b/gi/gtype.cpp
index f148a78..a9fca23 100644
--- a/gi/gtype.cpp
+++ b/gi/gtype.cpp
@@ -67,7 +67,7 @@ to_string_func(JSContext *context,
                JS::Value *vp)
 {
     JS::CallReceiver rec = JS::CallReceiverFromVp(vp);
-    JSObject *obj = rec.thisv().toObjectOrNull();
+    JS::RootedObject obj(context, rec.thisv().toObjectOrNull());
 
     GType gtype;
     gchar *strval;
@@ -157,9 +157,9 @@ gjs_gtype_create_gtype_wrapper (JSContext *context,
 }
 
 static GType
-_gjs_gtype_get_actual_gtype (JSContext *context,
-                             JSObject  *object,
-                             int        recurse)
+_gjs_gtype_get_actual_gtype(JSContext       *context,
+                            JS::HandleObject object,
+                            int              recurse)
 {
     GType gtype = G_TYPE_INVALID;
     JS::Value gtype_val = JS::UndefinedValue();
@@ -181,8 +181,10 @@ _gjs_gtype_get_actual_gtype (JSContext *context,
             goto out;
     }
 
-    if (recurse > 0 && gtype_val.isObject())
-        gtype = _gjs_gtype_get_actual_gtype(context, &gtype_val.toObject(), recurse - 1);
+    if (recurse > 0 && gtype_val.isObject()) {
+        JS::RootedObject gtype_obj(context, &gtype_val.toObject());
+        gtype = _gjs_gtype_get_actual_gtype(context, gtype_obj, recurse - 1);
+    }
 
  out:
     JS_EndRequest(context);
@@ -190,8 +192,8 @@ _gjs_gtype_get_actual_gtype (JSContext *context,
 }
 
 GType
-gjs_gtype_get_actual_gtype (JSContext *context,
-                            JSObject  *object)
+gjs_gtype_get_actual_gtype(JSContext       *context,
+                           JS::HandleObject object)
 {
     /* 2 means: recurse at most three times (including this
        call).
@@ -206,7 +208,7 @@ gjs_gtype_get_actual_gtype (JSContext *context,
 
 bool
 gjs_typecheck_gtype (JSContext             *context,
-                     JSObject              *obj,
+                     JS::HandleObject       obj,
                      bool                   throw_error)
 {
     return do_base_typecheck(context, obj, throw_error);
diff --git a/gi/gtype.h b/gi/gtype.h
index c3b999b..f9fa179 100644
--- a/gi/gtype.h
+++ b/gi/gtype.h
@@ -40,11 +40,11 @@ JS::Value   gjs_gtype_create_proto         (JSContext       *context,
 JSObject * gjs_gtype_create_gtype_wrapper (JSContext *context,
                                            GType      gtype);
 
-GType      gjs_gtype_get_actual_gtype (JSContext *context,
-                                       JSObject  *object);
+GType       gjs_gtype_get_actual_gtype(JSContext       *context,
+                                       JS::HandleObject object);
 
 bool        gjs_typecheck_gtype         (JSContext             *context,
-                                         JSObject              *obj,
+                                         JS::HandleObject       obj,
                                          bool                   throw_error);
 
 const char *gjs_get_names_from_gtype_and_gi_info(GType        gtype,
diff --git a/gi/keep-alive.cpp b/gi/keep-alive.cpp
index ae98a44..3276bac 100644
--- a/gi/keep-alive.cpp
+++ b/gi/keep-alive.cpp
@@ -178,7 +178,6 @@ JSObject*
 gjs_keep_alive_new(JSContext *context)
 {
     KeepAlive *priv;
-    JSObject *keep_alive = NULL;
     JSObject *global;
     JSBool found;
 
@@ -190,14 +189,14 @@ gjs_keep_alive_new(JSContext *context)
 
     g_assert(context != NULL);
 
-    JS_BeginRequest(context);
+    JSAutoRequest ar(context);
 
     global = gjs_get_import_global(context);
 
     g_assert(global != NULL);
 
     if (!JS_HasProperty(context, global, gjs_keep_alive_class.name, &found))
-        goto out;
+        return NULL;
 
     if (!found) {
         JSObject *prototype;
@@ -239,7 +238,8 @@ gjs_keep_alive_new(JSContext *context)
               "Creating new keep-alive object for context %p global %p",
               context, global);
 
-    keep_alive = JS_NewObject(context, &gjs_keep_alive_class, NULL, global);
+    JS::RootedObject keep_alive(context,
+                                JS_NewObject(context, &gjs_keep_alive_class, NULL, global));
     if (keep_alive == NULL) {
         gjs_log_exception(context);
         g_error("Failed to create keep_alive object");
@@ -254,9 +254,6 @@ gjs_keep_alive_new(JSContext *context)
     gjs_debug_lifecycle(GJS_DEBUG_KEEP_ALIVE,
                         "keep_alive constructor, obj %p priv %p", keep_alive, priv);
 
- out:
-    JS_EndRequest(context);
-
     return keep_alive;
 }
 
diff --git a/gi/ns.cpp b/gi/ns.cpp
index 2000fd8..897353f 100644
--- a/gi/ns.cpp
+++ b/gi/ns.cpp
@@ -203,7 +203,6 @@ static JSObject*
 ns_new(JSContext    *context,
        const char   *ns_name)
 {
-    JSObject *ns;
     JSObject *global;
     Ns *priv;
     JSBool found;
@@ -244,7 +243,7 @@ ns_new(JSContext    *context,
                   gjs_ns_class.name, prototype);
     }
 
-    ns = JS_NewObject(context, &gjs_ns_class, NULL, global);
+    JS::RootedObject ns(context, JS_NewObject(context, &gjs_ns_class, NULL, global));
     if (ns == NULL)
         g_error("No memory to create ns object");
 
diff --git a/gi/object.cpp b/gi/object.cpp
index 4ad689d..08b9c8c 100644
--- a/gi/object.cpp
+++ b/gi/object.cpp
@@ -242,8 +242,8 @@ static inline ObjectInstance *
 proto_priv_from_js(JSContext *context,
                    JSObject  *obj)
 {
-    JSObject *proto;
-    JS_GetPrototype(context, obj, &proto);
+    JS::RootedObject proto(context);
+    JS_GetPrototype(context, obj, proto.address());
     return priv_from_js(context, proto);
 }
 
@@ -1147,8 +1147,8 @@ gjs_object_prepare_shutdown (JSContext *context)
 }
 
 static ObjectInstance *
-init_object_private (JSContext *context,
-                     JSObject  *object)
+init_object_private (JSContext       *context,
+                     JS::HandleObject object)
 {
     ObjectInstance *proto_priv;
     ObjectInstance *priv;
@@ -1178,9 +1178,9 @@ init_object_private (JSContext *context,
 }
 
 static void
-associate_js_gobject (JSContext      *context,
-                      JSObject       *object,
-                      GObject        *gobj)
+associate_js_gobject (JSContext       *context,
+                      JS::HandleObject object,
+                      GObject         *gobj)
 {
     ObjectInstance *priv;
 
@@ -1240,25 +1240,24 @@ disassociate_js_gobject (GObject   *gobj)
 }
 
 static bool
-object_instance_init (JSContext *context,
-                      JSObject **object,
-                      unsigned   argc,
-                      JS::Value *argv)
+object_instance_init (JSContext              *context,
+                      JS::MutableHandleObject object,
+                      unsigned                argc,
+                      JS::Value              *argv)
 {
     ObjectInstance *priv;
     GType gtype;
     GParameter *params;
     int n_params;
     GTypeQuery query;
-    JSObject *old_jsobj;
     GObject *gobj;
 
-    priv = (ObjectInstance *) JS_GetPrivate(*object);
+    priv = (ObjectInstance *) JS_GetPrivate(object);
 
     gtype = priv->gtype;
     g_assert(gtype != G_TYPE_NONE);
 
-    if (!object_instance_props_to_g_parameters(context, *object, argc, argv,
+    if (!object_instance_props_to_g_parameters(context, object, argc, argv,
                                                gtype,
                                                &params, &n_params)) {
         return false;
@@ -1269,14 +1268,14 @@ object_instance_init (JSContext *context,
        down.
     */
     if (g_type_get_qdata(gtype, gjs_is_custom_type_quark()))
-        object_init_list = g_slist_prepend(object_init_list, *object);
+        object_init_list = g_slist_prepend(object_init_list, object.address());
 
     gobj = (GObject*) g_object_newv(gtype, n_params, params);
 
     free_g_params(params, n_params);
 
-    old_jsobj = peek_js_obj(gobj);
-    if (old_jsobj != NULL && old_jsobj != *object) {
+    JS::RootedObject old_jsobj(context, peek_js_obj(gobj));
+    if (old_jsobj != NULL && old_jsobj != object) {
         /* g_object_newv returned an object that's already tracked by a JS
          * object. Let's assume this is a singleton like IBus.IBus and return
          * the existing JS wrapper object.
@@ -1286,7 +1285,7 @@ object_instance_init (JSContext *context,
          * we're not actually using it, so just let it get collected. Avoiding
          * this would require a non-trivial amount of work.
          * */
-        *object = old_jsobj;
+        object.set(old_jsobj);
         g_object_unref(gobj); /* We already own a reference */
         gobj = NULL;
         goto out;
@@ -1312,7 +1311,7 @@ object_instance_init (JSContext *context,
     }
 
     if (priv->gobj == NULL)
-        associate_js_gobject(context, *object, gobj);
+        associate_js_gobject(context, object, gobj);
     /* We now have both a ref and a toggle ref, we only want the
      * toggle ref. This may immediately remove the GC root
      * we just added, since refcount may drop to 1.
@@ -1564,7 +1563,7 @@ real_connect_func(JSContext *context,
                   bool       after)
 {
     JS::CallArgs argv = JS::CallArgsFromVp (argc, vp);
-    JSObject *obj = argv.thisv().toObjectOrNull();
+    JS::RootedObject obj(context, argv.thisv().toObjectOrNull());
 
     ObjectInstance *priv;
     GClosure *closure;
@@ -1666,7 +1665,7 @@ emit_func(JSContext *context,
           JS::Value *vp)
 {
     JS::CallArgs argv = JS::CallArgsFromVp (argc, vp);
-    JSObject *obj = argv.thisv().toObjectOrNull();
+    JS::RootedObject obj(context, argv.thisv().toObjectOrNull());
 
     ObjectInstance *priv;
     guint signal_id;
@@ -1789,7 +1788,7 @@ to_string_func(JSContext *context,
                JS::Value *vp)
 {
     JS::CallReceiver rec = JS::CallReceiverFromVp(vp);
-    JSObject *obj = rec.thisv().toObjectOrNull();
+    JS::RootedObject obj(context, rec.thisv().toObjectOrNull());
 
     ObjectInstance *priv;
     bool ret = false;
@@ -1841,7 +1840,7 @@ init_func (JSContext *context,
            JS::Value *vp)
 {
     JS::CallArgs argv = JS::CallArgsFromVp (argc, vp);
-    JSObject *obj = argv.thisv().toObjectOrNull();
+    JS::RootedObject obj(context, argv.thisv().toObjectOrNull());
 
     bool ret;
 
@@ -2061,13 +2060,12 @@ JSObject*
 gjs_object_from_g_object(JSContext    *context,
                          GObject      *gobj)
 {
-    JSObject *obj;
     JSObject *global;
 
     if (gobj == NULL)
         return NULL;
 
-    obj = peek_js_obj(gobj);
+    JS::RootedObject obj(context, peek_js_obj(gobj));
 
     if (obj == NULL) {
         /* We have to create a wrapper */
@@ -2104,8 +2102,8 @@ gjs_object_from_g_object(JSContext    *context,
 }
 
 GObject*
-gjs_g_object_from_object(JSContext    *context,
-                         JSObject     *obj)
+gjs_g_object_from_object(JSContext       *context,
+                         JS::HandleObject obj)
 {
     ObjectInstance *priv;
 
@@ -2117,18 +2115,18 @@ gjs_g_object_from_object(JSContext    *context,
 }
 
 bool
-gjs_typecheck_is_object(JSContext     *context,
-                        JSObject      *object,
-                        bool           throw_error)
+gjs_typecheck_is_object(JSContext       *context,
+                        JS::HandleObject object,
+                        bool             throw_error)
 {
     return do_base_typecheck(context, object, throw_error);
 }
 
 bool
-gjs_typecheck_object(JSContext     *context,
-                     JSObject      *object,
-                     GType          expected_type,
-                     bool           throw_error)
+gjs_typecheck_object(JSContext       *context,
+                     JS::HandleObject object,
+                     GType            expected_type,
+                     bool             throw_error)
 {
     ObjectInstance *priv;
     bool result;
@@ -2267,7 +2265,7 @@ gjs_hook_up_vfunc(JSContext *cx,
 {
     JS::CallArgs argv = JS::CallArgsFromVp (argc, vp);
     gchar *name;
-    JSObject *object;
+    JS::RootedObject object(cx);
     JSObject *function;
     ObjectInstance *priv;
     GType gtype, info_gtype;
@@ -2278,7 +2276,7 @@ gjs_hook_up_vfunc(JSContext *cx,
 
     if (!gjs_parse_call_args(cx, "hook_up_vfunc",
                         "oso", argv,
-                        "object", &object,
+                        "object", object.address(),
                         "name", &name,
                         "function", &function))
         return false;
@@ -2520,14 +2518,14 @@ gjs_override_property(JSContext *cx,
 {
     JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
     gchar *name = NULL;
-    JSObject *type;
+    JS::RootedObject type(cx);
     GParamSpec *pspec;
     GParamSpec *new_pspec;
     GType gtype;
 
     if (!gjs_parse_call_args(cx, "override_property", "so", args,
                              "name", &name,
-                             "type", &type))
+                             "type", type.address()))
         return false;
 
     if ((gtype = gjs_gtype_get_actual_gtype(cx, type)) == G_TYPE_INVALID) {
@@ -2622,14 +2620,16 @@ gjs_object_custom_init(GTypeInstance *instance,
 {
     GjsContext *gjs_context;
     JSContext *context;
-    JSObject *object;
     ObjectInstance *priv;
     JS::Value v, r;
 
     if (!object_init_list)
       return;
 
-    object = (JSObject*) object_init_list->data;
+    gjs_context = gjs_context_get_current();
+    context = (JSContext*) gjs_context_get_native_context(gjs_context);
+
+    JS::RootedObject object(context, (JSObject*) object_init_list->data);
     priv = (ObjectInstance*) JS_GetPrivate(object);
 
     if (priv->gtype != G_TYPE_FROM_INSTANCE (instance)) {
@@ -2642,9 +2642,6 @@ gjs_object_custom_init(GTypeInstance *instance,
     object_init_list = g_slist_delete_link(object_init_list,
                                            object_init_list);
 
-    gjs_context = gjs_context_get_current();
-    context = (JSContext*) gjs_context_get_native_context(gjs_context);
-
     associate_js_gobject(context, object, G_OBJECT (instance));
 
     if (!gjs_object_get_property_const(context, object,
@@ -2724,7 +2721,8 @@ get_interface_gtypes(JSContext *cx,
             return false;
         }
 
-        iface_type = gjs_gtype_get_actual_gtype(cx, &iface_val.toObject());
+        JS::RootedObject iface(cx, &iface_val.toObject());
+        iface_type = gjs_gtype_get_actual_gtype(cx, iface);
         if (iface_type == G_TYPE_INVALID) {
             gjs_throw (cx, "Invalid parameter interfaces (element %d was not a GType)", i);
             return false;
@@ -2860,7 +2858,8 @@ gjs_register_type(JSContext *cx,
 {
     JS::CallArgs argv = JS::CallArgsFromVp (argc, vp);
     gchar *name;
-    JSObject *parent, *constructor, *interfaces, *properties, *module;
+    JS::RootedObject parent(cx);
+    JSObject *constructor, *interfaces, *properties, *module;
     GType instance_type, parent_type;
     GTypeQuery query;
     GTypeModule *type_module;
@@ -2887,7 +2886,7 @@ gjs_register_type(JSContext *cx,
 
     if (!gjs_parse_call_args(cx, "register_type",
                         "osoo", argv,
-                        "parent", &parent,
+                        "parent", parent.address(),
                         "name", &name,
                         "interfaces", &interfaces,
                         "properties", &properties))
@@ -2968,26 +2967,22 @@ gjs_signal_new(JSContext *cx,
                JS::Value *vp)
 {
     JS::CallArgs argv = JS::CallArgsFromVp (argc, vp);
-    JSObject *obj;
     GType gtype;
-    gchar *signal_name = NULL;
+    g_autofree char *signal_name = NULL;
     GSignalAccumulator accumulator;
     gint signal_id;
     guint i, n_parameters;
     GType *params, return_type;
-    bool ret;
 
     if (argc != 6)
         return false;
 
-    JS_BeginRequest(cx);
+    JSAutoRequest ar(cx);
 
-    if (!gjs_string_to_utf8(cx, argv[1], &signal_name)) {
-        ret = false;
-        goto out;
-    }
+    if (!gjs_string_to_utf8(cx, argv[1], &signal_name))
+        return false;
 
-    obj = &argv[0].toObject();
+    JS::RootedObject obj(cx, &argv[0].toObject());
     if (!gjs_typecheck_gtype(cx, obj, true))
         return false;
 
@@ -3004,29 +2999,28 @@ gjs_signal_new(JSContext *cx,
         accumulator = NULL;
     }
 
-    return_type = gjs_gtype_get_actual_gtype(cx, &argv[4].toObject());
+    JS::RootedObject gtype_obj(cx, &argv[4].toObject());
+    return_type = gjs_gtype_get_actual_gtype(cx, gtype_obj);
 
     if (accumulator == g_signal_accumulator_true_handled && return_type != G_TYPE_BOOLEAN) {
         gjs_throw (cx, "GObject.SignalAccumulator.TRUE_HANDLED can only be used with boolean signals");
-        ret = false;
-        goto out;
+        return false;
     }
 
-    if (!JS_GetArrayLength(cx, &argv[5].toObject(), &n_parameters)) {
-        ret = false;
-        goto out;
-    }
+    if (!JS_GetArrayLength(cx, &argv[5].toObject(), &n_parameters))
+        return false;
+
     params = g_newa(GType, n_parameters);
     for (i = 0; i < n_parameters; i++) {
         JS::Value gtype_val;
         if (!JS_GetElement(cx, &argv[5].toObject(), i, &gtype_val) ||
             !gtype_val.isObject()) {
             gjs_throw(cx, "Invalid signal parameter number %d", i);
-            ret = false;
-            goto out;
+            return false;
         }
 
-        params[i] = gjs_gtype_get_actual_gtype(cx, &gtype_val.toObject());
+        JS::RootedObject gtype(cx, &gtype_val.toObject());
+        params[i] = gjs_gtype_get_actual_gtype(cx, gtype);
     }
 
     gtype = gjs_gtype_get_actual_gtype(cx, obj);
@@ -3043,13 +3037,7 @@ gjs_signal_new(JSContext *cx,
                               params);
 
     argv.rval().setInt32(signal_id);
-    ret = true;
-
- out:
-    JS_EndRequest(cx);
-
-    free (signal_name);
-    return ret;
+    return true;
 }
 
 static JSFunctionSpec module_funcs[] = {
diff --git a/gi/object.h b/gi/object.h
index 01ca87d..4eb77a5 100644
--- a/gi/object.h
+++ b/gi/object.h
@@ -41,15 +41,18 @@ bool      gjs_lookup_object_constructor (JSContext     *context,
                                          JS::Value     *value_p);
 JSObject* gjs_object_from_g_object      (JSContext     *context,
                                          GObject       *gobj);
-GObject*  gjs_g_object_from_object      (JSContext     *context,
-                                         JSObject      *obj);
-bool      gjs_typecheck_object          (JSContext     *context,
-                                         JSObject      *obj,
-                                         GType          expected_type,
-                                         bool           throw_error);
-bool      gjs_typecheck_is_object       (JSContext     *context,
-                                         JSObject      *obj,
-                                         bool           throw_error);
+
+GObject  *gjs_g_object_from_object(JSContext       *context,
+                                   JS::HandleObject obj);
+
+bool      gjs_typecheck_object(JSContext       *context,
+                               JS::HandleObject obj,
+                               GType            expected_type,
+                               bool             throw_error);
+
+bool      gjs_typecheck_is_object(JSContext       *context,
+                                  JS::HandleObject obj,
+                                  bool             throw_error);
 
 void      gjs_object_prepare_shutdown   (JSContext     *context);
 
diff --git a/gi/param.cpp b/gi/param.cpp
index c6e08f5..934387d 100644
--- a/gi/param.cpp
+++ b/gi/param.cpp
@@ -294,8 +294,8 @@ gjs_param_from_g_param(JSContext    *context,
 }
 
 GParamSpec*
-gjs_g_param_from_param(JSContext    *context,
-                       JSObject     *obj)
+gjs_g_param_from_param(JSContext       *context,
+                       JS::HandleObject obj)
 {
     Param *priv;
 
@@ -308,10 +308,10 @@ gjs_g_param_from_param(JSContext    *context,
 }
 
 bool
-gjs_typecheck_param(JSContext     *context,
-                    JSObject      *object,
-                    GType          expected_type,
-                    bool           throw_error)
+gjs_typecheck_param(JSContext       *context,
+                    JS::HandleObject object,
+                    GType            expected_type,
+                    bool             throw_error)
 {
     Param *priv;
     bool result;
diff --git a/gi/param.h b/gi/param.h
index abf3f39..c957818 100644
--- a/gi/param.h
+++ b/gi/param.h
@@ -33,14 +33,17 @@ G_BEGIN_DECLS
 
 void        gjs_define_param_class     (JSContext  *context,
                                         JSObject   *in_object);
-GParamSpec* gjs_g_param_from_param     (JSContext  *context,
-                                        JSObject   *obj);
+
+GParamSpec *gjs_g_param_from_param (JSContext       *context,
+                                    JS::HandleObject obj);
+
 JSObject*   gjs_param_from_g_param     (JSContext  *context,
                                         GParamSpec *param);
-bool        gjs_typecheck_param        (JSContext  *context,
-                                        JSObject   *obj,
-                                        GType       expected_type,
-                                        bool        throw_error);
+
+bool        gjs_typecheck_param(JSContext       *context,
+                                JS::HandleObject obj,
+                                GType            expected_type,
+                                bool             throw_error);
 
 G_END_DECLS
 
diff --git a/gi/repo.cpp b/gi/repo.cpp
index 2a15439..9900a0e 100644
--- a/gi/repo.cpp
+++ b/gi/repo.cpp
@@ -256,7 +256,6 @@ static JSObject*
 repo_new(JSContext *context)
 {
     Repo *priv;
-    JSObject *repo;
     JSObject *global;
     JSObject *versions;
     JSObject *private_ns;
@@ -298,7 +297,7 @@ repo_new(JSContext *context)
                   gjs_repo_class.name, prototype);
     }
 
-    repo = JS_NewObject(context, &gjs_repo_class, NULL, global);
+    JS::RootedObject repo(context, JS_NewObject(context, &gjs_repo_class, NULL, global));
     if (repo == NULL) {
         gjs_throw(context, "No memory to create repo object");
         return NULL;
diff --git a/gi/union.cpp b/gi/union.cpp
index 1506c58..b381fd9 100644
--- a/gi/union.cpp
+++ b/gi/union.cpp
@@ -139,9 +139,9 @@ union_new_resolve(JSContext *context,
 }
 
 static void*
-union_new(JSContext   *context,
-          JSObject    *obj, /* "this" for constructor */
-          GIUnionInfo *info)
+union_new(JSContext       *context,
+          JS::HandleObject obj, /* "this" for constructor */
+          GIUnionInfo     *info)
 {
     int n_methods;
     int i;
@@ -172,10 +172,12 @@ union_new(JSContext   *context,
              * creates a JSObject wrapper for the union that we immediately
              * discard.
              */
-            if (rval.isNull())
+            if (rval.isNull()) {
                 return NULL;
-            else
-                return gjs_c_union_from_union(context, &rval.toObject());
+            } else {
+                JS::RootedObject rval_obj(context, &rval.toObject());
+                return gjs_c_union_from_union(context, rval_obj);
+            }
         }
 
         g_base_info_unref((GIBaseInfo*) func_info);
@@ -192,7 +194,7 @@ GJS_NATIVE_CONSTRUCTOR_DECLARE(union)
     GJS_NATIVE_CONSTRUCTOR_VARIABLES(union)
     Union *priv;
     Union *proto_priv;
-    JSObject *proto;
+    JS::RootedObject proto(context);
     void *gboxed;
 
     GJS_NATIVE_CONSTRUCTOR_PRELUDE(union);
@@ -208,7 +210,7 @@ GJS_NATIVE_CONSTRUCTOR_DECLARE(union)
                         "union constructor, obj %p priv %p",
                         object, priv);
 
-    JS_GetPrototype(context, object, &proto);
+    JS_GetPrototype(context, object, proto.address());
     gjs_debug_lifecycle(GJS_DEBUG_GBOXED, "union instance __proto__ is %p", proto);
 
     /* If we're the prototype, then post-construct we'll fill in priv->info.
@@ -285,7 +287,7 @@ to_string_func(JSContext *context,
                JS::Value *vp)
 {
     JS::CallReceiver rec = JS::CallReceiverFromVp(vp);
-    JSObject *obj = rec.thisv().toObjectOrNull();
+    JS::RootedObject obj(context, rec.thisv().toObjectOrNull());
 
     Union *priv;
     bool ret = false;
@@ -442,8 +444,8 @@ gjs_union_from_c_union(JSContext    *context,
 }
 
 void*
-gjs_c_union_from_union(JSContext    *context,
-                       JSObject     *obj)
+gjs_c_union_from_union(JSContext       *context,
+                       JS::HandleObject obj)
 {
     Union *priv;
 
@@ -456,11 +458,11 @@ gjs_c_union_from_union(JSContext    *context,
 }
 
 bool
-gjs_typecheck_union(JSContext     *context,
-                    JSObject      *object,
-                    GIStructInfo  *expected_info,
-                    GType          expected_type,
-                    bool           throw_error)
+gjs_typecheck_union(JSContext       *context,
+                    JS::HandleObject object,
+                    GIStructInfo    *expected_info,
+                    GType            expected_type,
+                    bool             throw_error)
 {
     Union *priv;
     bool result;
diff --git a/gi/union.h b/gi/union.h
index 6332d63..fabc065 100644
--- a/gi/union.h
+++ b/gi/union.h
@@ -34,13 +34,15 @@ G_BEGIN_DECLS
 bool      gjs_define_union_class       (JSContext    *context,
                                         JSObject     *in_object,
                                         GIUnionInfo  *info);
-void*     gjs_c_union_from_union       (JSContext    *context,
-                                        JSObject     *obj);
+
+void     *gjs_c_union_from_union(JSContext       *context,
+                                 JS::HandleObject obj);
+
 JSObject* gjs_union_from_c_union       (JSContext    *context,
                                         GIUnionInfo  *info,
                                         void         *gboxed);
 bool      gjs_typecheck_union          (JSContext             *context,
-                                        JSObject              *obj,
+                                        JS::HandleObject       obj,
                                         GIStructInfo          *expected_info,
                                         GType                  expected_type,
                                         bool                   throw_error);
diff --git a/gi/value.cpp b/gi/value.cpp
index c1e855b..42bcb8d 100644
--- a/gi/value.cpp
+++ b/gi/value.cpp
@@ -355,8 +355,10 @@ gjs_value_guess_g_type(JSContext *context,
     if (value.isBoolean())
         return G_TYPE_BOOLEAN;
 
-    if (value.isObject())
-        return gjs_gtype_get_actual_gtype(context, &value.toObject());
+    if (value.isObject()) {
+        JS::RootedObject obj(context, &value.toObject());
+        return gjs_gtype_get_actual_gtype(context, obj);
+    }
 
     return G_TYPE_INVALID;
 }
@@ -492,8 +494,7 @@ gjs_value_to_g_value_internal(JSContext    *context,
         if (value.isNull()) {
             /* nothing to do */
         } else if (value.isObject()) {
-            JSObject *obj;
-            obj = &value.toObject();
+            JS::RootedObject obj(context, &value.toObject());
 
             if (!gjs_typecheck_object(context, obj, gtype, true))
                 return false;
@@ -554,8 +555,7 @@ gjs_value_to_g_value_internal(JSContext    *context,
         if (value.isNull()) {
             /* nothing to do */
         } else if (value.isObject()) {
-            JSObject *obj;
-            obj = &value.toObject();
+            JS::RootedObject obj(context, &value.toObject());
 
             if (g_type_is_a(gtype, G_TYPE_ERROR)) {
                 /* special case GError */
@@ -623,7 +623,7 @@ gjs_value_to_g_value_internal(JSContext    *context,
         if (value.isNull()) {
             /* nothing to do */
         } else if (value.isObject()) {
-            JSObject *obj = &value.toObject();
+            JS::RootedObject obj(context, &value.toObject());
 
             if (!gjs_typecheck_boxed(context, obj, NULL, G_TYPE_VARIANT, true))
                 return false;
@@ -687,8 +687,7 @@ gjs_value_to_g_value_internal(JSContext    *context,
         if (value.isNull()) {
             /* nothing to do */
         } else if (value.isObject()) {
-            JSObject *obj;
-            obj = &value.toObject();
+            JS::RootedObject obj(context, &value.toObject());
 
             if (!gjs_typecheck_param(context, obj, gtype, true))
                 return false;
@@ -712,7 +711,8 @@ gjs_value_to_g_value_internal(JSContext    *context,
             return false;
         }
 
-        type = gjs_gtype_get_actual_gtype(context, &value.toObject());
+        JS::RootedObject obj(context, &value.toObject());
+        type = gjs_gtype_get_actual_gtype(context, obj);
         g_value_set_gtype(gvalue, type);
     } else if (g_type_is_a(gtype, G_TYPE_POINTER)) {
         if (value.isNull()) {
diff --git a/gjs/byteArray.cpp b/gjs/byteArray.cpp
index e69eb85..28d014c 100644
--- a/gjs/byteArray.cpp
+++ b/gjs/byteArray.cpp
@@ -71,9 +71,9 @@ struct JSClass gjs_byte_array_class = {
 };
 
 bool
-gjs_typecheck_bytearray(JSContext     *context,
-                        JSObject      *object,
-                        bool           throw_error)
+gjs_typecheck_bytearray(JSContext       *context,
+                        JS::HandleObject object,
+                        bool             throw_error)
 {
     return do_base_typecheck(context, object, throw_error);
 }
@@ -414,7 +414,7 @@ to_string_func(JSContext *context,
                JS::Value *vp)
 {
     JS::CallArgs argv = JS::CallArgsFromVp (argc, vp);
-    JSObject *object = argv.thisv().toObjectOrNull();
+    JS::RootedObject object(context, argv.thisv().toObjectOrNull());
     ByteArrayInstance *priv;
     char *encoding;
     bool encoding_is_utf8;
@@ -512,7 +512,7 @@ to_gbytes_func(JSContext *context,
                JS::Value *vp)
 {
     JS::CallReceiver rec = JS::CallReceiverFromVp(vp);
-    JSObject *object = rec.thisv().toObjectOrNull();
+    JS::RootedObject object(context, rec.thisv().toObjectOrNull());
     ByteArrayInstance *priv;
     JSObject *ret_bytes_obj;
     GIBaseInfo *gbytes_info;
@@ -554,11 +554,11 @@ byte_array_get_prototype(JSContext *context)
 static JSObject*
 byte_array_new(JSContext *context)
 {
-    JSObject *array;
     ByteArrayInstance *priv;
 
-    array = JS_NewObject(context, &gjs_byte_array_class,
-                         byte_array_get_prototype(context), NULL);
+    JS::RootedObject array(context,
+                           JS_NewObject(context, &gjs_byte_array_class,
+                                        byte_array_get_prototype(context), NULL));
 
     priv = g_slice_new0(ByteArrayInstance);
 
@@ -578,15 +578,11 @@ from_string_func(JSContext *context,
     ByteArrayInstance *priv;
     char *encoding;
     bool encoding_is_utf8;
-    JSObject *obj;
-    bool retval = false;
+    JS::RootedObject obj(context, byte_array_new(context));
 
-    obj = byte_array_new(context);
     if (obj == NULL)
         return false;
 
-    JS_AddObjectRoot(context, &obj);
-
     priv = priv_from_js(context, obj);
     g_assert (priv != NULL);
 
@@ -597,12 +593,12 @@ from_string_func(JSContext *context,
     if (!argv[0].isString()) {
         gjs_throw(context,
                   "byteArray.fromString() called with non-string as first arg");
-        goto out;
+        return false;
     }
 
     if (argc > 1 && argv[1].isString()) {
         if (!gjs_string_to_utf8(context, argv[1], &encoding))
-            goto out;
+            return false;
 
         /* maybe we should be smarter about utf8 synonyms here.
          * doesn't matter much though. encoding_is_utf8 is
@@ -627,7 +623,7 @@ from_string_func(JSContext *context,
         if (!gjs_string_to_utf8(context,
                                 argv[0],
                                 &utf8))
-            goto out;
+            return false;
 
         g_byte_array_set_size(priv->array, 0);
         g_byte_array_append(priv->array, (guint8*) utf8, strlen(utf8));
@@ -641,7 +637,7 @@ from_string_func(JSContext *context,
 
         u16_chars = JS_GetStringCharsAndLength(context, argv[0].toString(), &u16_len);
         if (u16_chars == NULL)
-            goto out;
+            return false;
 
         error = NULL;
         encoded = g_convert((char*) u16_chars,
@@ -655,7 +651,7 @@ from_string_func(JSContext *context,
         if (encoded == NULL) {
             /* frees the GError */
             gjs_throw_g_error(context, error);
-            goto out;
+            return false;
         }
 
         g_byte_array_set_size(priv->array, 0);
@@ -665,11 +661,7 @@ from_string_func(JSContext *context,
     }
 
     argv.rval().setObject(*obj);
-
-    retval = true;
- out:
-    JS_RemoveObjectRoot(context, &obj);
-    return retval;
+    return true;
 }
 
 /* fromArray() function implementation */
@@ -682,15 +674,11 @@ from_array_func(JSContext *context,
     ByteArrayInstance *priv;
     guint32 len;
     guint32 i;
-    JSObject *obj;
-    bool ret = false;
+    JS::RootedObject obj(context, byte_array_new(context));
 
-    obj = byte_array_new(context);
     if (obj == NULL)
         return false;
 
-    JS_AddObjectRoot(context, &obj);
-
     priv = priv_from_js(context, obj);
     g_assert (priv != NULL);
 
@@ -701,13 +689,13 @@ from_array_func(JSContext *context,
     if (!JS_IsArrayObject(context, &argv[0].toObject())) {
         gjs_throw(context,
                   "byteArray.fromArray() called with non-array as first arg");
-        goto out;
+        return false;
     }
 
     if (!JS_GetArrayLength(context, &argv[0].toObject(), &len)) {
         gjs_throw(context,
                   "byteArray.fromArray() can't get length of first array arg");
-        goto out;
+        return false;
     }
 
     g_byte_array_set_size(priv->array, len);
@@ -721,23 +709,20 @@ from_array_func(JSContext *context,
             /* this means there was an exception, while elem.isUndefined()
              * means no element found
              */
-            goto out;
+            return false;
         }
 
         if (elem.isUndefined())
             continue;
 
         if (!gjs_value_to_byte(context, elem, &b))
-            goto out;
+            return false;
 
         g_array_index(priv->array, guint8, i) = b;
     }
 
-    ret = true;
     argv.rval().setObject(*obj);
- out:
-    JS_RemoveObjectRoot(context, &obj);
-    return ret;
+    return true;
 }
 
 static JSBool
@@ -746,14 +731,12 @@ from_gbytes_func(JSContext *context,
                  JS::Value *vp)
 {
     JS::CallArgs argv = JS::CallArgsFromVp (argc, vp);
-    JSObject *bytes_obj;
+    JS::RootedObject bytes_obj(context);
     GBytes *gbytes;
     ByteArrayInstance *priv;
-    JSObject *obj;
-    bool ret = false;
 
     if (!gjs_parse_call_args(context, "overrides_gbytes_to_array", "o", argv,
-                        "bytes", &bytes_obj))
+                             "bytes", bytes_obj.address()))
         return false;
 
     if (!gjs_typecheck_boxed(context, bytes_obj, NULL, G_TYPE_BYTES, true))
@@ -761,7 +744,7 @@ from_gbytes_func(JSContext *context,
 
     gbytes = (GBytes*) gjs_c_struct_from_boxed(context, bytes_obj);
 
-    obj = byte_array_new(context);
+    JS::RootedObject obj(context, byte_array_new(context));
     if (obj == NULL)
         return false;
     priv = priv_from_js(context, obj);
@@ -769,23 +752,22 @@ from_gbytes_func(JSContext *context,
 
     priv->bytes = g_bytes_ref(gbytes);
 
-    ret = true;
     argv.rval().setObject(*obj);
-    return ret;
+    return true;
 }
 
 JSObject *
 gjs_byte_array_from_byte_array (JSContext *context,
                                 GByteArray *array)
 {
-    JSObject *object;
     ByteArrayInstance *priv;
 
     g_return_val_if_fail(context != NULL, NULL);
     g_return_val_if_fail(array != NULL, NULL);
 
-    object = JS_NewObject(context, &gjs_byte_array_class,
-                          byte_array_get_prototype(context), NULL);
+    JS::RootedObject object(context,
+                            JS_NewObject(context, &gjs_byte_array_class,
+                                         byte_array_get_prototype(context), NULL));
     if (!object) {
         gjs_throw(context, "failed to create byte array");
         return NULL;
@@ -805,14 +787,14 @@ JSObject *
 gjs_byte_array_from_bytes (JSContext *context,
                            GBytes    *bytes)
 {
-    JSObject *object;
     ByteArrayInstance *priv;
 
     g_return_val_if_fail(context != NULL, NULL);
     g_return_val_if_fail(bytes != NULL, NULL);
 
-    object = JS_NewObject(context, &gjs_byte_array_class,
-                          byte_array_get_prototype(context), NULL);
+    JS::RootedObject object(context,
+                            JS_NewObject(context, &gjs_byte_array_class,
+                                         byte_array_get_prototype(context), NULL));
     if (!object) {
         gjs_throw(context, "failed to create byte array");
         return NULL;
@@ -827,8 +809,8 @@ gjs_byte_array_from_bytes (JSContext *context,
 }
 
 GBytes *
-gjs_byte_array_get_bytes (JSContext  *context,
-                          JSObject   *object)
+gjs_byte_array_get_bytes (JSContext       *context,
+                          JS::HandleObject object)
 {
     ByteArrayInstance *priv;
     priv = priv_from_js(context, object);
@@ -840,8 +822,8 @@ gjs_byte_array_get_bytes (JSContext  *context,
 }
 
 GByteArray *
-gjs_byte_array_get_byte_array (JSContext   *context,
-                               JSObject    *obj)
+gjs_byte_array_get_byte_array (JSContext       *context,
+                               JS::HandleObject obj)
 {
     ByteArrayInstance *priv;
     priv = priv_from_js(context, obj);
@@ -853,10 +835,10 @@ gjs_byte_array_get_byte_array (JSContext   *context,
 }
 
 void
-gjs_byte_array_peek_data (JSContext  *context,
-                          JSObject   *obj,
-                          guint8    **out_data,
-                          gsize      *out_len)
+gjs_byte_array_peek_data (JSContext       *context,
+                          JS::HandleObject obj,
+                          guint8         **out_data,
+                          gsize           *out_len)
 {
     ByteArrayInstance *priv;
     priv = priv_from_js(context, obj);
diff --git a/gjs/byteArray.h b/gjs/byteArray.h
index e969059..b001946 100644
--- a/gjs/byteArray.h
+++ b/gjs/byteArray.h
@@ -34,9 +34,9 @@
 
 G_BEGIN_DECLS
 
-bool          gjs_typecheck_bytearray    (JSContext     *context,
-                                          JSObject      *obj,
-                                          bool           throw_error);
+bool        gjs_typecheck_bytearray(JSContext       *context,
+                                    JS::HandleObject obj,
+                                    bool             throw_error);
 
 bool          gjs_define_byte_array_stuff    (JSContext  *context,
                                               JSObject  **module_out);
@@ -46,16 +46,16 @@ JSObject *    gjs_byte_array_from_byte_array (JSContext  *context,
 JSObject *    gjs_byte_array_from_bytes (JSContext  *context,
                                          GBytes *bytes);
 
-GByteArray *   gjs_byte_array_get_byte_array (JSContext  *context,
-                                              JSObject   *object);
+GByteArray *gjs_byte_array_get_byte_array(JSContext       *context,
+                                          JS::HandleObject object);
 
-GBytes *      gjs_byte_array_get_bytes (JSContext  *context,
-                                        JSObject   *object);
+GBytes     *gjs_byte_array_get_bytes(JSContext       *context,
+                                     JS::HandleObject object);
 
-void          gjs_byte_array_peek_data (JSContext  *context,
-                                        JSObject   *object,
-                                        guint8    **out_data,
-                                        gsize      *out_len);
+void        gjs_byte_array_peek_data(JSContext       *context,
+                                     JS::HandleObject object,
+                                     guint8         **out_data,
+                                     gsize           *out_len);
 
 G_END_DECLS
 
diff --git a/gjs/importer.cpp b/gjs/importer.cpp
index 9ecea53..b9cefba 100644
--- a/gjs/importer.cpp
+++ b/gjs/importer.cpp
@@ -936,7 +936,6 @@ static JSObject*
 importer_new(JSContext *context,
              bool       is_root)
 {
-    JSObject *importer;
     Importer *priv;
     JSObject *global;
     JSBool found;
@@ -977,7 +976,8 @@ importer_new(JSContext *context,
                   gjs_importer_class.name, prototype);
     }
 
-    importer = JS_NewObject(context, &gjs_importer_class, NULL, global);
+    JS::RootedObject importer(context,
+                              JS_NewObject(context, &gjs_importer_class, NULL, global));
     if (importer == NULL)
         g_error("No memory to create importer importer");
 
diff --git a/gjs/jsapi-util.cpp b/gjs/jsapi-util.cpp
index c4c85fc..4cb972d 100644
--- a/gjs/jsapi-util.cpp
+++ b/gjs/jsapi-util.cpp
@@ -473,13 +473,23 @@ gjs_explain_scope(JSContext  *context,
     JS_EndRequest(context);
 }
 
+static char *
+utf8_exception_from_non_gerror_value(JSContext *cx,
+                                     JS::Value  exc)
+{
+    char *utf8_exception = NULL;
+    JSString *exc_str = JS_ValueToString(cx, exc);
+    if (exc_str != NULL)
+        gjs_string_to_utf8(cx, JS::StringValue(exc_str), &utf8_exception);
+    return utf8_exception;
+}
+
 bool
 gjs_log_exception_full(JSContext *context,
                        JS::Value  exc,
                        JSString  *message)
 {
     JS::Value stack;
-    JSString *exc_str;
     char *utf8_exception, *utf8_message;
     bool is_syntax;
 
@@ -487,32 +497,28 @@ gjs_log_exception_full(JSContext *context,
 
     is_syntax = false;
 
-    if (exc.isObject() &&
-        gjs_typecheck_boxed(context, &exc.toObject(), NULL, G_TYPE_ERROR, false)) {
-        GError *gerror;
-
-        gerror = (GError*) gjs_c_struct_from_boxed(context, &exc.toObject());
-        utf8_exception = g_strdup_printf("GLib.Error %s: %s",
-                                         g_quark_to_string(gerror->domain),
-                                         gerror->message);
+    if (!exc.isObject()) {
+        utf8_exception = utf8_exception_from_non_gerror_value(context, exc);
     } else {
-        if (exc.isObject()) {
+        JS::RootedObject exc_obj(context, &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;
             char *utf8_name;
 
-            if (gjs_object_get_property_const(context, &exc.toObject(),
+            if (gjs_object_get_property_const(context, exc_obj,
                                               GJS_STRING_NAME, &js_name) &&
                 js_name.isString() &&
                 gjs_string_to_utf8(context, js_name, &utf8_name)) {
                 is_syntax = strcmp("SyntaxError", utf8_name) == 0;
             }
-        }
 
-        exc_str = JS_ValueToString(context, exc);
-        if (exc_str != NULL)
-            gjs_string_to_utf8(context, JS::StringValue(exc_str), &utf8_exception);
-        else
-            utf8_exception = NULL;
+            utf8_exception = utf8_exception_from_non_gerror_value(context, exc);
+        }
     }
 
     if (message != NULL)
diff --git a/gjs/jsapi-util.h b/gjs/jsapi-util.h
index ef7b216..4b8ab01 100644
--- a/gjs/jsapi-util.h
+++ b/gjs/jsapi-util.h
@@ -80,15 +80,15 @@ typedef struct GjsRootedArray GjsRootedArray;
  */
 #define GJS_DEFINE_PRIV_FROM_JS(type, klass)                          \
     __attribute__((unused)) static inline bool                          \
-    do_base_typecheck(JSContext *context,                               \
-                      JSObject  *object,                                \
-                      bool       throw_error)                           \
+    do_base_typecheck(JSContext       *context,                         \
+                      JS::HandleObject object,                          \
+                      bool             throw_error)                     \
     {                                                                   \
         return gjs_typecheck_instance(context, object, &klass, throw_error);  \
     }                                                                   \
     static inline type *                                                \
-    priv_from_js(JSContext *context,                                    \
-                 JSObject  *object)                                     \
+    priv_from_js(JSContext       *context,                              \
+                 JS::HandleObject object)                               \
     {                                                                   \
         type *priv;                                                     \
         JS_BeginRequest(context);                                       \
@@ -97,9 +97,9 @@ typedef struct GjsRootedArray GjsRootedArray;
         return priv;                                                    \
     }                                                                   \
     __attribute__((unused)) static bool                                 \
-    priv_from_js_with_typecheck(JSContext *context,                     \
-                                JSObject  *object,                      \
-                                type      **out)                        \
+    priv_from_js_with_typecheck(JSContext       *context,               \
+                                JS::HandleObject object,                \
+                                type           **out)                   \
     {                                                                   \
         if (!do_base_typecheck(context, object, false))                 \
             return false;                                               \
@@ -220,7 +220,7 @@ gjs_##name##_constructor(JSContext  *context,           \
  * be at the very top.
  */
 #define GJS_NATIVE_CONSTRUCTOR_VARIABLES(name)          \
-    JSObject *object = NULL;                                            \
+    JS::RootedObject object(context, NULL);                         \
     JS::CallArgs argv G_GNUC_UNUSED = JS::CallArgsFromVp(argc, vp);
 
 /**
diff --git a/modules/cairo-context.cpp b/modules/cairo-context.cpp
index 8fca420..d1f4c1b 100644
--- a/modules/cairo-context.cpp
+++ b/modules/cairo-context.cpp
@@ -37,7 +37,7 @@ mname##_func(JSContext *context,                    \
               JS::Value *vp)                        \
 {                                                   \
     JS::CallArgs argv = JS::CallArgsFromVp (argc, vp);             \
-    JSObject *obj = argv.thisv().toObjectOrNull();  \
+    JS::RootedObject obj(context, argv.thisv().toObjectOrNull());  \
     cairo_t *cr;
 
 #define _GJS_CAIRO_CONTEXT_DEFINE_FUNC_END                               \
@@ -253,9 +253,9 @@ GJS_DEFINE_PROTO_WITH_GTYPE("CairoContext", cairo_context, CAIRO_GOBJECT_TYPE_CO
 GJS_DEFINE_PRIV_FROM_JS(GjsCairoContext, gjs_cairo_context_class);
 
 static void
-_gjs_cairo_context_construct_internal(JSContext *context,
-                                      JSObject *obj,
-                                      cairo_t *cr)
+_gjs_cairo_context_construct_internal(JSContext       *context,
+                                      JS::HandleObject obj,
+                                      cairo_t         *cr)
 {
     GjsCairoContext *priv;
 
@@ -407,7 +407,7 @@ dispose_func(JSContext *context,
              JS::Value *vp)
 {
     JS::CallReceiver rec = JS::CallReceiverFromVp(vp);
-    JSObject *obj = rec.thisv().toObjectOrNull();
+    JS::RootedObject obj(context, rec.thisv().toObjectOrNull());
 
     GjsCairoContext *priv;
 
@@ -426,7 +426,7 @@ appendPath_func(JSContext *context,
                 JS::Value *vp)
 {
     JS::CallArgs argv = JS::CallArgsFromVp (argc, vp);
-    JSObject *obj = argv.thisv().toObjectOrNull();
+    JS::RootedObject obj(context, argv.thisv().toObjectOrNull());
 
     JSObject *path_wrapper;
     cairo_path_t *path;
@@ -454,7 +454,7 @@ copyPath_func(JSContext *context,
               JS::Value *vp)
 {
     JS::CallArgs argv = JS::CallArgsFromVp (argc, vp);
-    JSObject *obj = argv.thisv().toObjectOrNull();
+    JS::RootedObject obj(context, argv.thisv().toObjectOrNull());
 
     cairo_path_t *path;
     cairo_t *cr;
@@ -474,7 +474,7 @@ copyPathFlat_func(JSContext *context,
                   JS::Value *vp)
 {
     JS::CallArgs argv = JS::CallArgsFromVp (argc, vp);
-    JSObject *obj = argv.thisv().toObjectOrNull();
+    JS::RootedObject obj(context, argv.thisv().toObjectOrNull());
 
     cairo_path_t *path;
     cairo_t *cr;
@@ -494,7 +494,7 @@ mask_func(JSContext *context,
           JS::Value *vp)
 {
     JS::CallArgs argv = JS::CallArgsFromVp (argc, vp);
-    JSObject *obj = argv.thisv().toObjectOrNull();
+    JS::RootedObject obj(context, argv.thisv().toObjectOrNull());
 
     JSObject *pattern_wrapper;
     cairo_pattern_t *pattern;
@@ -526,7 +526,7 @@ maskSurface_func(JSContext *context,
                  JS::Value *vp)
 {
     JS::CallArgs argv = JS::CallArgsFromVp (argc, vp);
-    JSObject *obj = argv.thisv().toObjectOrNull();
+    JS::RootedObject obj(context, argv.thisv().toObjectOrNull());
 
     JSObject *surface_wrapper;
     double x, y;
@@ -562,7 +562,7 @@ setDash_func(JSContext *context,
              JS::Value *vp)
 {
     JS::CallArgs argv = JS::CallArgsFromVp (argc, vp);
-    JSObject *obj = argv.thisv().toObjectOrNull();
+    JS::RootedObject obj(context, argv.thisv().toObjectOrNull());
 
     guint i;
     cairo_t *cr;
@@ -627,7 +627,7 @@ setSource_func(JSContext *context,
                JS::Value *vp)
 {
     JS::CallArgs argv = JS::CallArgsFromVp (argc, vp);
-    JSObject *obj = argv.thisv().toObjectOrNull();
+    JS::RootedObject obj(context, argv.thisv().toObjectOrNull());
 
     JSObject *pattern_wrapper;
     cairo_pattern_t *pattern;
@@ -661,7 +661,7 @@ setSourceSurface_func(JSContext *context,
                       JS::Value *vp)
 {
     JS::CallArgs argv = JS::CallArgsFromVp (argc, vp);
-    JSObject *obj = argv.thisv().toObjectOrNull();
+    JS::RootedObject obj(context, argv.thisv().toObjectOrNull());
 
     JSObject *surface_wrapper;
     double x, y;
@@ -698,7 +698,7 @@ showText_func(JSContext *context,
               JS::Value *vp)
 {
     JS::CallArgs argv = JS::CallArgsFromVp (argc, vp);
-    JSObject *obj = argv.thisv().toObjectOrNull();
+    JS::RootedObject obj(context, argv.thisv().toObjectOrNull());
 
     char *utf8;
     cairo_t *cr;
@@ -726,7 +726,7 @@ selectFontFace_func(JSContext *context,
                     JS::Value *vp)
 {
     JS::CallArgs argv = JS::CallArgsFromVp (argc, vp);
-    JSObject *obj = argv.thisv().toObjectOrNull();
+    JS::RootedObject obj(context, argv.thisv().toObjectOrNull());
 
     char *family;
     cairo_font_slant_t slant;
@@ -757,7 +757,7 @@ popGroup_func(JSContext *context,
               JS::Value *vp)
 {
     JS::CallReceiver rec = JS::CallReceiverFromVp(vp);
-    JSObject *obj = rec.thisv().toObjectOrNull();
+    JS::RootedObject obj(context, rec.thisv().toObjectOrNull());
 
     cairo_t *cr;
     cairo_pattern_t *pattern;
@@ -790,7 +790,7 @@ getSource_func(JSContext *context,
                JS::Value *vp)
 {
     JS::CallReceiver rec = JS::CallReceiverFromVp(vp);
-    JSObject *obj = rec.thisv().toObjectOrNull();
+    JS::RootedObject obj(context, rec.thisv().toObjectOrNull());
 
     cairo_t *cr;
     cairo_pattern_t *pattern;
@@ -824,7 +824,7 @@ getTarget_func(JSContext *context,
                JS::Value *vp)
 {
     JS::CallReceiver rec = JS::CallReceiverFromVp(vp);
-    JSObject *obj = rec.thisv().toObjectOrNull();
+    JS::RootedObject obj(context, rec.thisv().toObjectOrNull());
 
     cairo_t *cr;
     cairo_surface_t *surface;
@@ -858,7 +858,7 @@ getGroupTarget_func(JSContext *context,
                     JS::Value *vp)
 {
     JS::CallReceiver rec = JS::CallReceiverFromVp(vp);
-    JSObject *obj = rec.thisv().toObjectOrNull();
+    JS::RootedObject obj(context, rec.thisv().toObjectOrNull());
 
     cairo_t *cr;
     cairo_surface_t *surface;
@@ -992,9 +992,8 @@ JSObject *
 gjs_cairo_context_from_context(JSContext *context,
                                cairo_t *cr)
 {
-    JSObject *object;
-
-    object = JS_NewObject(context, &gjs_cairo_context_class, NULL, NULL);
+    JS::RootedObject object(context,
+                            JS_NewObject(context, &gjs_cairo_context_class, NULL, NULL));
     if (!object)
         return NULL;
 
@@ -1004,8 +1003,8 @@ gjs_cairo_context_from_context(JSContext *context,
 }
 
 cairo_t *
-gjs_cairo_context_get_context(JSContext *context,
-                              JSObject *object)
+gjs_cairo_context_get_context(JSContext       *context,
+                              JS::HandleObject object)
 {
     GjsCairoContext *priv;
     priv = priv_from_js(context, object);
@@ -1024,10 +1023,9 @@ context_to_g_argument(JSContext      *context,
                       bool            may_be_null,
                       GArgument      *arg)
 {
-    JSObject *obj;
+    JS::RootedObject obj(context, value.toObjectOrNull());
     cairo_t *cr;
 
-    obj = value.toObjectOrNull();
     cr = gjs_cairo_context_get_context(context, obj);
     if (!cr)
         return false;
diff --git a/modules/cairo-image-surface.cpp b/modules/cairo-image-surface.cpp
index f3e08dc..645257f 100644
--- a/modules/cairo-image-surface.cpp
+++ b/modules/cairo-image-surface.cpp
@@ -76,7 +76,6 @@ createFromPNG_func(JSContext *context,
     JS::CallArgs argv = JS::CallArgsFromVp (argc, vp);
     char *filename;
     cairo_surface_t *surface;
-    JSObject *surface_wrapper;
 
     if (!gjs_parse_call_args(context, "createFromPNG", "s", argv,
                         "filename", &filename))
@@ -87,7 +86,8 @@ createFromPNG_func(JSContext *context,
     if (!gjs_cairo_check_status(context, cairo_surface_status(surface), "surface"))
         return false;
 
-    surface_wrapper = JS_NewObject(context, &gjs_cairo_image_surface_class, NULL, NULL);
+    JS::RootedObject surface_wrapper(context,
+                                     JS_NewObject(context, &gjs_cairo_image_surface_class, NULL, NULL));
     if (!surface_wrapper) {
         gjs_throw(context, "failed to create surface");
         return false;
@@ -217,13 +217,12 @@ JSObject *
 gjs_cairo_image_surface_from_surface(JSContext       *context,
                                      cairo_surface_t *surface)
 {
-    JSObject *object;
-
     g_return_val_if_fail(context != NULL, NULL);
     g_return_val_if_fail(surface != NULL, NULL);
     g_return_val_if_fail(cairo_surface_get_type(surface) == CAIRO_SURFACE_TYPE_IMAGE, NULL);
 
-    object = JS_NewObject(context, &gjs_cairo_image_surface_class, NULL, NULL);
+    JS::RootedObject object(context,
+                            JS_NewObject(context, &gjs_cairo_image_surface_class, NULL, NULL));
     if (!object) {
         gjs_throw(context, "failed to create image surface");
         return NULL;
diff --git a/modules/cairo-linear-gradient.cpp b/modules/cairo-linear-gradient.cpp
index 27e346d..37b9f92 100644
--- a/modules/cairo-linear-gradient.cpp
+++ b/modules/cairo-linear-gradient.cpp
@@ -77,13 +77,12 @@ JSObject *
 gjs_cairo_linear_gradient_from_pattern(JSContext       *context,
                                        cairo_pattern_t *pattern)
 {
-    JSObject *object;
-
     g_return_val_if_fail(context != NULL, NULL);
     g_return_val_if_fail(pattern != NULL, NULL);
     g_return_val_if_fail(cairo_pattern_get_type(pattern) == CAIRO_PATTERN_TYPE_LINEAR, NULL);
 
-    object = JS_NewObject(context, &gjs_cairo_linear_gradient_class, NULL, NULL);
+    JS::RootedObject object(context,
+                            JS_NewObject(context, &gjs_cairo_linear_gradient_class, NULL, NULL));
     if (!object) {
         gjs_throw(context, "failed to create linear gradient pattern");
         return NULL;
diff --git a/modules/cairo-path.cpp b/modules/cairo-path.cpp
index 87eb600..7921a3f 100644
--- a/modules/cairo-path.cpp
+++ b/modules/cairo-path.cpp
@@ -69,13 +69,13 @@ JSObject *
 gjs_cairo_path_from_path(JSContext    *context,
                          cairo_path_t *path)
 {
-    JSObject *object;
     GjsCairoPath *priv;
 
     g_return_val_if_fail(context != NULL, NULL);
     g_return_val_if_fail(path != NULL, NULL);
 
-    object = JS_NewObject(context, &gjs_cairo_path_class, NULL, NULL);
+    JS::RootedObject object(context,
+                            JS_NewObject(context, &gjs_cairo_path_class, NULL, NULL));
     if (!object) {
         gjs_throw(context, "failed to create path");
         return NULL;
diff --git a/modules/cairo-pattern.cpp b/modules/cairo-pattern.cpp
index 186b347..ac60af6 100644
--- a/modules/cairo-pattern.cpp
+++ b/modules/cairo-pattern.cpp
@@ -105,7 +105,7 @@ JSFunctionSpec gjs_cairo_pattern_proto_funcs[] = {
  */
 void
 gjs_cairo_pattern_construct(JSContext       *context,
-                            JSObject        *object,
+                            JS::HandleObject object,
                             cairo_pattern_t *pattern)
 {
     GjsCairoPattern *priv;
diff --git a/modules/cairo-pdf-surface.cpp b/modules/cairo-pdf-surface.cpp
index f971a3b..0aee113 100644
--- a/modules/cairo-pdf-surface.cpp
+++ b/modules/cairo-pdf-surface.cpp
@@ -83,13 +83,12 @@ JSObject *
 gjs_cairo_pdf_surface_from_surface(JSContext       *context,
                                    cairo_surface_t *surface)
 {
-    JSObject *object;
-
     g_return_val_if_fail(context != NULL, NULL);
     g_return_val_if_fail(surface != NULL, NULL);
     g_return_val_if_fail(cairo_surface_get_type(surface) == CAIRO_SURFACE_TYPE_PDF, NULL);
 
-    object = JS_NewObject(context, &gjs_cairo_pdf_surface_class, NULL, NULL);
+    JS::RootedObject object(context,
+                            JS_NewObject(context, &gjs_cairo_pdf_surface_class, NULL, NULL));
     if (!object) {
         gjs_throw(context, "failed to create pdf surface");
         return NULL;
diff --git a/modules/cairo-private.h b/modules/cairo-private.h
index 3879f4c..97e3380 100644
--- a/modules/cairo-private.h
+++ b/modules/cairo-private.h
@@ -42,7 +42,7 @@ JS::Value        gjs_cairo_context_create_proto         (JSContext       *contex
                                                          const char      *proto_name,
                                                          JSObject        *parent);
 cairo_t *        gjs_cairo_context_get_context          (JSContext       *context,
-                                                         JSObject        *object);
+                                                         JS::HandleObject object);
 JSObject *       gjs_cairo_context_from_context         (JSContext       *context,
                                                          cairo_t         *cr);
 void             gjs_cairo_context_init                 (JSContext       *context);
@@ -65,7 +65,7 @@ JS::Value        gjs_cairo_surface_create_proto         (JSContext       *contex
                                                          const char      *proto_name,
                                                          JSObject        *parent);
 void             gjs_cairo_surface_construct            (JSContext       *context,
-                                                         JSObject        *object,
+                                                         JS::HandleObject object,
                                                          cairo_surface_t *surface);
 void             gjs_cairo_surface_finalize_surface     (JSFreeOp        *fop,
                                                          JSObject        *object);
@@ -120,7 +120,7 @@ JS::Value        gjs_cairo_pattern_create_proto         (JSContext       *contex
                                                          const char      *proto_name,
                                                          JSObject        *parent);
 void             gjs_cairo_pattern_construct            (JSContext       *context,
-                                                         JSObject        *object,
+                                                         JS::HandleObject object,
                                                          cairo_pattern_t *pattern);
 void             gjs_cairo_pattern_finalize_pattern     (JSFreeOp        *fop,
                                                          JSObject        *object);
diff --git a/modules/cairo-ps-surface.cpp b/modules/cairo-ps-surface.cpp
index b33b85e..a7e4736 100644
--- a/modules/cairo-ps-surface.cpp
+++ b/modules/cairo-ps-surface.cpp
@@ -92,13 +92,12 @@ JSObject *
 gjs_cairo_ps_surface_from_surface(JSContext       *context,
                                   cairo_surface_t *surface)
 {
-    JSObject *object;
-
     g_return_val_if_fail(context != NULL, NULL);
     g_return_val_if_fail(surface != NULL, NULL);
     g_return_val_if_fail(cairo_surface_get_type(surface) == CAIRO_SURFACE_TYPE_PS, NULL);
 
-    object = JS_NewObject(context, &gjs_cairo_ps_surface_class, NULL, NULL);
+    JS::RootedObject object(context,
+                            JS_NewObject(context, &gjs_cairo_ps_surface_class, NULL, NULL));
     if (!object) {
         gjs_throw(context, "failed to create ps surface");
         return NULL;
diff --git a/modules/cairo-radial-gradient.cpp b/modules/cairo-radial-gradient.cpp
index f5c21ec..9df421e 100644
--- a/modules/cairo-radial-gradient.cpp
+++ b/modules/cairo-radial-gradient.cpp
@@ -79,13 +79,12 @@ JSObject *
 gjs_cairo_radial_gradient_from_pattern(JSContext       *context,
                                        cairo_pattern_t *pattern)
 {
-    JSObject *object;
-
     g_return_val_if_fail(context != NULL, NULL);
     g_return_val_if_fail(pattern != NULL, NULL);
     g_return_val_if_fail(cairo_pattern_get_type(pattern) == CAIRO_PATTERN_TYPE_RADIAL, NULL);
 
-    object = JS_NewObject(context, &gjs_cairo_radial_gradient_class, NULL, NULL);
+    JS::RootedObject object(context,
+                            JS_NewObject(context, &gjs_cairo_radial_gradient_class, NULL, NULL));
     if (!object) {
         gjs_throw(context, "failed to create radial gradient pattern");
         return NULL;
diff --git a/modules/cairo-region.cpp b/modules/cairo-region.cpp
index 1745f17..74688da 100644
--- a/modules/cairo-region.cpp
+++ b/modules/cairo-region.cpp
@@ -40,8 +40,9 @@ GJS_DEFINE_PROTO_WITH_GTYPE("CairoRegion", cairo_region, CAIRO_GOBJECT_TYPE_REGI
 GJS_DEFINE_PRIV_FROM_JS(GjsCairoRegion, gjs_cairo_region_class);
 
 static cairo_region_t *
-get_region(JSContext *context,
-           JSObject *obj) {
+get_region(JSContext       *context,
+           JS::HandleObject obj)
+{
     GjsCairoRegion *priv = priv_from_js(context, obj);
     if (priv == NULL)
         return NULL;
@@ -55,7 +56,7 @@ fill_rectangle(JSContext *context, JSObject *obj,
 
 #define PRELUDE                                                 \
     JS::CallArgs argv = JS::CallArgsFromVp (argc, vp);          \
-    JSObject *obj = argv.thisv().toObjectOrNull();              \
+    JS::RootedObject obj(context, argv.thisv().toObjectOrNull()); \
     cairo_region_t *this_region = get_region(context, obj);
 
 #define RETURN_STATUS                                           \
@@ -68,10 +69,10 @@ fill_rectangle(JSContext *context, JSObject *obj,
                   JS::Value *vp)                                \
     {                                                           \
         PRELUDE;                                                \
-        JSObject *other_obj;                                    \
+        JS::RootedObject other_obj(context);                    \
         cairo_region_t *other_region;                           \
         if (!gjs_parse_call_args(context, #method, "o", argv,   \
-                            "other_region", &other_obj))        \
+                                 "other_region", other_obj.address())) \
             return false;                                       \
                                                                 \
         this_region = get_region(context, obj);                 \
@@ -221,9 +222,9 @@ JSFunctionSpec gjs_cairo_region_proto_funcs[] = {
 };
 
 static void
-_gjs_cairo_region_construct_internal(JSContext *context,
-                                     JSObject *obj,
-                                     cairo_region_t *region)
+_gjs_cairo_region_construct_internal(JSContext       *context,
+                                     JS::HandleObject obj,
+                                     cairo_region_t  *region)
 {
     GjsCairoRegion *priv;
 
@@ -274,9 +275,8 @@ static JSObject *
 gjs_cairo_region_from_region(JSContext *context,
                              cairo_region_t *region)
 {
-    JSObject *object;
-
-    object = JS_NewObject(context, &gjs_cairo_region_class, NULL, NULL);
+    JS::RootedObject object(context,
+                            JS_NewObject(context, &gjs_cairo_region_class, NULL, NULL));
     if (!object)
         return NULL;
 
@@ -294,10 +294,9 @@ region_to_g_argument(JSContext      *context,
                      bool            may_be_null,
                      GArgument      *arg)
 {
-    JSObject *obj;
+    JS::RootedObject obj(context, &value.toObject());
     cairo_region_t *region;
 
-    obj = &value.toObject();
     region = get_region(context, obj);
     if (!region)
         return false;
diff --git a/modules/cairo-solid-pattern.cpp b/modules/cairo-solid-pattern.cpp
index 8ecb1a4..3b8673d 100644
--- a/modules/cairo-solid-pattern.cpp
+++ b/modules/cairo-solid-pattern.cpp
@@ -107,13 +107,12 @@ JSObject *
 gjs_cairo_solid_pattern_from_pattern(JSContext       *context,
                                      cairo_pattern_t *pattern)
 {
-    JSObject *object;
-
     g_return_val_if_fail(context != NULL, NULL);
     g_return_val_if_fail(pattern != NULL, NULL);
     g_return_val_if_fail(cairo_pattern_get_type(pattern) == CAIRO_PATTERN_TYPE_SOLID, NULL);
 
-    object = JS_NewObject(context, &gjs_cairo_solid_pattern_class, NULL, NULL);
+    JS::RootedObject object(context,
+                            JS_NewObject(context, &gjs_cairo_solid_pattern_class, NULL, NULL));
     if (!object) {
         gjs_throw(context, "failed to create solid pattern");
         return NULL;
diff --git a/modules/cairo-surface-pattern.cpp b/modules/cairo-surface-pattern.cpp
index 4598e5a..13f885b 100644
--- a/modules/cairo-surface-pattern.cpp
+++ b/modules/cairo-surface-pattern.cpp
@@ -190,13 +190,12 @@ JSObject *
 gjs_cairo_surface_pattern_from_pattern(JSContext       *context,
                                        cairo_pattern_t *pattern)
 {
-    JSObject *object;
-
     g_return_val_if_fail(context != NULL, NULL);
     g_return_val_if_fail(pattern != NULL, NULL);
     g_return_val_if_fail(cairo_pattern_get_type(pattern) == CAIRO_PATTERN_TYPE_SURFACE, NULL);
 
-    object = JS_NewObject(context, &gjs_cairo_surface_pattern_class, NULL, NULL);
+    JS::RootedObject object(context,
+                            JS_NewObject(context, &gjs_cairo_surface_pattern_class, NULL, NULL));
     if (!object) {
         gjs_throw(context, "failed to create surface pattern");
         return NULL;
diff --git a/modules/cairo-surface.cpp b/modules/cairo-surface.cpp
index 82848a0..5d51022 100644
--- a/modules/cairo-surface.cpp
+++ b/modules/cairo-surface.cpp
@@ -145,7 +145,7 @@ JSFunctionSpec gjs_cairo_surface_proto_funcs[] = {
  */
 void
 gjs_cairo_surface_construct(JSContext       *context,
-                            JSObject        *object,
+                            JS::HandleObject object,
                             cairo_surface_t *surface)
 {
     GjsCairoSurface *priv;
@@ -196,8 +196,6 @@ JSObject *
 gjs_cairo_surface_from_surface(JSContext       *context,
                                cairo_surface_t *surface)
 {
-    JSObject *object;
-
     g_return_val_if_fail(context != NULL, NULL);
     g_return_val_if_fail(surface != NULL, NULL);
 
@@ -214,7 +212,8 @@ gjs_cairo_surface_from_surface(JSContext       *context,
             break;
     }
 
-    object = JS_NewObject(context, &gjs_cairo_surface_class, NULL, NULL);
+    JS::RootedObject object(context,
+                            JS_NewObject(context, &gjs_cairo_surface_class, NULL, NULL));
     if (!object) {
         gjs_throw(context, "failed to create surface");
         return NULL;
diff --git a/modules/cairo-svg-surface.cpp b/modules/cairo-svg-surface.cpp
index d95d00c..3b3eb6c 100644
--- a/modules/cairo-svg-surface.cpp
+++ b/modules/cairo-svg-surface.cpp
@@ -83,13 +83,12 @@ JSObject *
 gjs_cairo_svg_surface_from_surface(JSContext       *context,
                                    cairo_surface_t *surface)
 {
-    JSObject *object;
-
     g_return_val_if_fail(context != NULL, NULL);
     g_return_val_if_fail(surface != NULL, NULL);
     g_return_val_if_fail(cairo_surface_get_type(surface) == CAIRO_SURFACE_TYPE_SVG, NULL);
 
-    object = JS_NewObject(context, &gjs_cairo_svg_surface_class, NULL, NULL);
+    JS::RootedObject object(context,
+                            JS_NewObject(context, &gjs_cairo_svg_surface_class, NULL, NULL));
     if (!object) {
         gjs_throw(context, "failed to create svg surface");
         return NULL;
diff --git a/modules/system.cpp b/modules/system.cpp
index 333f86a..22b5a86 100644
--- a/modules/system.cpp
+++ b/modules/system.cpp
@@ -63,10 +63,11 @@ gjs_refcount(JSContext *context,
              JS::Value *vp)
 {
     JS::CallArgs argv = JS::CallArgsFromVp (argc, vp);
-    JSObject *target_obj;
+    JS::RootedObject target_obj(context);
     GObject *obj;
 
-    if (!gjs_parse_call_args(context, "refcount", "o", argv, "object", &target_obj))
+    if (!gjs_parse_call_args(context, "refcount", "o", argv,
+                             "object", target_obj.address()))
         return false;
 
     if (!gjs_typecheck_object(context, target_obj, G_TYPE_OBJECT, true))


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