[gjs/ewlsh/fix-threading-with-logging: 1/2] Initial port to mozjs102




commit de8d431b08cdb44c1cad34c3f57f69f05487fb68
Author: Evan Welsh <contact evanwelsh com>
Date:   Sun Jul 3 17:24:18 2022 -0400

    Initial port to mozjs102

 gi/boxed.cpp                      | 21 ++++++-------
 gi/cwrapper.h                     | 28 ++++++++++-------
 gi/function.cpp                   | 14 +++++----
 gi/fundamental.cpp                |  3 +-
 gi/gerror.cpp                     |  2 +-
 gi/gtype.cpp                      |  9 ++++--
 gi/interface.cpp                  |  6 ++--
 gi/ns.cpp                         | 13 ++++----
 gi/object.cpp                     | 38 +++++++++++------------
 gi/object.h                       | 15 +++++----
 gi/param.cpp                      | 19 ++++++------
 gi/repo.cpp                       |  4 +--
 gi/union.cpp                      |  2 +-
 gi/wrapperutils.h                 | 29 ++++++++++--------
 gjs/atoms.cpp                     |  2 +-
 gjs/context.cpp                   |  2 +-
 gjs/engine.cpp                    |  9 ++----
 gjs/global.cpp                    |  3 +-
 gjs/importer.cpp                  | 12 ++++----
 gjs/jsapi-util-root.h             | 13 ++++----
 gjs/jsapi-util-string.cpp         |  6 ++--
 gjs/module.cpp                    | 12 +++++---
 meson.build                       |  5 +--
 modules/cairo-context.cpp         | 17 ++++-------
 modules/cairo-path.cpp            |  7 +++--
 modules/cairo-pattern.cpp         |  6 ++--
 modules/cairo-private.h           | 64 ++++++++++++++++++++++-----------------
 modules/cairo-region.cpp          |  2 +-
 modules/cairo-surface.cpp         |  6 ++--
 modules/core/overrides/GObject.js |  2 +-
 test/gjs-test-rooting.cpp         | 20 ++++++------
 31 files changed, 208 insertions(+), 183 deletions(-)
---
diff --git a/gi/boxed.cpp b/gi/boxed.cpp
index bc005a540..c10c92eee 100644
--- a/gi/boxed.cpp
+++ b/gi/boxed.cpp
@@ -101,7 +101,7 @@ bool BoxedPrototype::new_enumerate_impl(JSContext* cx, JS::HandleObject,
         if (flags & GI_FUNCTION_IS_METHOD) {
             const char* name = meth_info.name();
             jsid id = gjs_intern_string_to_id(cx, name);
-            if (id == JSID_VOID)
+            if (id.isVoid())
                 return false;
             if (!properties.append(id)) {
                 JS_ReportOutOfMemory(cx);
@@ -170,8 +170,7 @@ std::unique_ptr<BoxedPrototype::FieldMap> BoxedPrototype::create_field_map(
 
         // We get the string as a jsid later, which is interned. We intern the
         // string here as well, so it will be the same string pointer
-        JS::RootedString name(cx, JS_NewStringCopyZ(cx, field_info.name()));
-        JSString* atom = JS_AtomizeAndPinJSString(cx, name);
+        JSString* atom = JS_AtomizeAndPinString(cx, field_info.name());
 
         result->putNewInfallible(atom, std::move(field_info));
     }
@@ -506,7 +505,7 @@ bool BoxedInstance::get_nested_interface_object(
     /* We never actually read the reserved slot, but we put the parent object
      * into it to hold onto the parent object.
      */
-    JS_SetReservedSlot(obj, 0, JS::ObjectValue(*parent_obj));
+    JS::SetReservedSlot(obj, 1, JS::ObjectValue(*parent_obj));
 
     value.setObject(*obj);
     return true;
@@ -761,7 +760,6 @@ const struct JSClassOps BoxedBase::class_ops = {
     nullptr,  // mayResolve
     &BoxedBase::finalize,
     nullptr,  // call
-    nullptr,  // hasInstance
     nullptr,  // construct
     &BoxedBase::trace
 };
@@ -773,8 +771,7 @@ const struct JSClassOps BoxedBase::class_ops = {
  */
 const struct JSClass BoxedBase::klass = {
     "GObject_Boxed",
-    JSCLASS_HAS_PRIVATE | JSCLASS_FOREGROUND_FINALIZE |
-        JSCLASS_HAS_RESERVED_SLOTS(1),
+    JSCLASS_HAS_RESERVED_SLOTS(2) | JSCLASS_FOREGROUND_FINALIZE,
     &BoxedBase::class_ops
 };
 // clang-format on
@@ -928,7 +925,7 @@ BoxedPrototype::BoxedPrototype(GIStructInfo* info, GType gtype)
     : GIWrapperPrototype(info, gtype),
       m_zero_args_constructor(-1),
       m_default_constructor(-1),
-      m_default_constructor_name(JSID_VOID),
+      m_default_constructor_name(JS::PropertyKey::Void()),
       m_can_allocate_directly(struct_is_simple(info)) {
     if (!m_can_allocate_directly) {
         m_can_allocate_directly_without_pointers = false;
@@ -943,8 +940,8 @@ BoxedPrototype::BoxedPrototype(GIStructInfo* info, GType gtype)
 bool BoxedPrototype::init(JSContext* context) {
     int i, n_methods;
     int first_constructor = -1;
-    jsid first_constructor_name = JSID_VOID;
-    jsid zero_args_constructor_name = JSID_VOID;
+    jsid first_constructor_name = JS::PropertyKey::Void();
+    jsid zero_args_constructor_name = JS::PropertyKey::Void();
 
     if (m_gtype != G_TYPE_NONE) {
         /* If the structure is registered as a boxed, we can create a new instance by
@@ -965,7 +962,7 @@ bool BoxedPrototype::init(JSContext* context) {
                     first_constructor = i;
                     first_constructor_name =
                         gjs_intern_string_to_id(context, func_info.name());
-                    if (first_constructor_name == JSID_VOID)
+                    if (first_constructor_name.isVoid())
                         return false;
                 }
 
@@ -974,7 +971,7 @@ bool BoxedPrototype::init(JSContext* context) {
                     m_zero_args_constructor = i;
                     zero_args_constructor_name =
                         gjs_intern_string_to_id(context, func_info.name());
-                    if (zero_args_constructor_name == JSID_VOID)
+                    if (zero_args_constructor_name.isVoid())
                         return false;
                 }
 
diff --git a/gi/cwrapper.h b/gi/cwrapper.h
index ebe1d1d7a..965f1e821 100644
--- a/gi/cwrapper.h
+++ b/gi/cwrapper.h
@@ -81,8 +81,12 @@ class CWrapperPointerOps {
      */
     [[nodiscard]] static Wrapped* for_js(JSContext* cx,
                                          JS::HandleObject wrapper) {
-        return static_cast<Wrapped*>(
-            JS_GetInstancePrivate(cx, wrapper, &Base::klass, nullptr));
+        if (!JS_InstanceOf(cx, wrapper, &Base::klass, nullptr)) {
+            return nullptr;
+        }
+        JS::RootedValue v(cx, JS::GetReservedSlot(wrapper, 0));
+
+        return JS::GetMaybePtrFromReservedSlot<Wrapped>(wrapper, 0);
     }
 
     /*
@@ -135,7 +139,7 @@ class CWrapperPointerOps {
      * (It can return null if no private data has been set yet on the wrapper.)
      */
     [[nodiscard]] static Wrapped* for_js_nocheck(JSObject* wrapper) {
-        return static_cast<Wrapped*>(JS::GetPrivate(wrapper));
+        return JS::GetMaybePtrFromReservedSlot<Wrapped>(wrapper, 0);
     }
 };
 
@@ -162,7 +166,7 @@ class CWrapperPointerOps {
  *    class_spec's flags member.
  *  - static constexpr unsigned constructor_nargs: number of arguments that the
  *    constructor takes. If you implement constructor_impl() then also add this.
- *  - void finalize_impl(JSFreeOp*, Wrapped*): called when the JS object is
+ *  - void finalize_impl(JS::GCContext*, Wrapped*): called when the JS object is
  *    garbage collected, use this to free the C pointer and do any other cleanup
  *
  * Add optional functionality by setting members of class_spec:
@@ -214,7 +218,8 @@ class CWrapper : public CWrapperPointerOps<Base, Wrapped> {
         Wrapped* priv = Base::constructor_impl(cx, args);
         if (!priv)
             return false;
-        JS::SetPrivate(object, priv);
+        // TODO: Install 0 slot
+        JS::SetReservedSlot(object, 0, JS::PrivateValue(priv));
 
         args.rval().setObject(*object);
         return true;
@@ -249,17 +254,18 @@ class CWrapper : public CWrapperPointerOps<Base, Wrapped> {
             debug_jsprop(message, gjs_debug_id(id).c_str(), obj);
     }
 
-    static void finalize(JSFreeOp* fop, JSObject* obj) {
+    static void finalize(JS::GCContext* gcx, JSObject* obj) {
         Wrapped* priv = Base::for_js_nocheck(obj);
 
         // Call only CWrapper's original method here, not any overrides; e.g.,
         // we don't want to deal with a read barrier.
         CWrapper::debug_lifecycle(priv, obj, "Finalize");
 
-        Base::finalize_impl(fop, priv);
+        Base::finalize_impl(gcx, priv);
 
         // Remove the pointer from the JSObject
-        JS::SetPrivate(obj, nullptr);
+        // TODO: Install 0 slot
+        JS::SetReservedSlot(obj, 0, JS::PrivateValue(nullptr));
     }
 
     static constexpr JSClassOps class_ops = {
@@ -466,7 +472,7 @@ class CWrapper : public CWrapperPointerOps<Base, Wrapped> {
                 in_obj = gjs_get_import_global(cx);
             JS::RootedId class_name(
                 cx, gjs_intern_string_to_id(cx, Base::klass.name));
-            if (class_name == JSID_VOID ||
+            if (class_name.isVoid() ||
                 !JS_DefinePropertyById(cx, in_obj, class_name, ctor_obj,
                                        GJS_MODULE_PROP_FLAGS))
                 return nullptr;
@@ -495,8 +501,8 @@ class CWrapper : public CWrapperPointerOps<Base, Wrapped> {
         if (!wrapper)
             return nullptr;
 
-        assert(!JS::GetPrivate(wrapper));
-        JS::SetPrivate(wrapper, Base::copy_ptr(ptr));
+        assert(!JS::GetMaybePtrFromReservedSlot<Base>(wrapper, 0));
+        JS::SetReservedSlot(wrapper, 0, JS::PrivateValue(Base::copy_ptr(ptr)));
 
         debug_lifecycle(ptr, wrapper, "from_c_ptr");
 
diff --git a/gi/function.cpp b/gi/function.cpp
index 5c4fa4a28..91af2070b 100644
--- a/gi/function.cpp
+++ b/gi/function.cpp
@@ -109,7 +109,7 @@ class Function : public CWrapper<Function> {
     GJS_JSAPI_RETURN_CONVENTION
     static bool call(JSContext* cx, unsigned argc, JS::Value* vp);
 
-    static void finalize_impl(JSFreeOp*, Function* priv);
+    static void finalize_impl(JS::GCContext* gcx, Function* priv);
 
     GJS_JSAPI_RETURN_CONVENTION
     static bool get_length(JSContext* cx, unsigned argc, JS::Value* vp);
@@ -149,8 +149,8 @@ class Function : public CWrapper<Function> {
 
     static constexpr JSClass klass = {
         "GIRepositoryFunction",
-        JSCLASS_HAS_PRIVATE | JSCLASS_BACKGROUND_FINALIZE, &Function::class_ops,
-        &Function::class_spec};
+        JSCLASS_HAS_RESERVED_SLOTS(1) | JSCLASS_BACKGROUND_FINALIZE,
+        &Function::class_ops, &Function::class_spec};
 
  public:
     GJS_JSAPI_RETURN_CONVENTION
@@ -1162,7 +1162,7 @@ Function::~Function() {
     GJS_DEC_COUNTER(function);
 }
 
-void Function::finalize_impl(JSFreeOp*, Function* priv) {
+void Function::finalize_impl(JS::GCContext*, Function* priv) {
     if (priv == NULL)
         return; /* we are the prototype, not a real instance, so constructor never called */
     delete priv;
@@ -1334,8 +1334,10 @@ JSObject* Function::create(JSContext* context, GType gtype,
 
     auto* priv = new Function(info);
 
-    g_assert(!JS::GetPrivate(function) && "Function should be a fresh object");
-    JS::SetPrivate(function, priv);
+    g_assert(!JS::GetMaybePtrFromReservedSlot<Function>(function, 0) &&
+             "Function should be a fresh object");
+    // TODO: Install 0 slot
+    JS::SetReservedSlot(function, 0, JS::PrivateValue(priv));
 
     debug_lifecycle(function, priv, "Constructor");
 
diff --git a/gi/fundamental.cpp b/gi/fundamental.cpp
index 956b7303c..26ac2dd76 100644
--- a/gi/fundamental.cpp
+++ b/gi/fundamental.cpp
@@ -242,14 +242,13 @@ const struct JSClassOps FundamentalBase::class_ops = {
     nullptr,  // mayResolve
     &FundamentalBase::finalize,
     nullptr,  // call
-    nullptr,  // hasInstance
     nullptr,  // construct
     &FundamentalBase::trace
 };
 
 const struct JSClass FundamentalBase::klass = {
     "GFundamental_Object",
-    JSCLASS_HAS_PRIVATE | JSCLASS_FOREGROUND_FINALIZE,
+    JSCLASS_HAS_RESERVED_SLOTS(1) | JSCLASS_FOREGROUND_FINALIZE,
     &FundamentalBase::class_ops
 };
 // clang-format on
diff --git a/gi/gerror.cpp b/gi/gerror.cpp
index 06ea26354..eb2667c15 100644
--- a/gi/gerror.cpp
+++ b/gi/gerror.cpp
@@ -192,7 +192,7 @@ const struct JSClassOps ErrorBase::class_ops = {
 
 const struct JSClass ErrorBase::klass = {
     "GLib_Error",
-    JSCLASS_HAS_PRIVATE | JSCLASS_BACKGROUND_FINALIZE,
+    JSCLASS_HAS_RESERVED_SLOTS(1) | JSCLASS_BACKGROUND_FINALIZE,
     &ErrorBase::class_ops
 };
 
diff --git a/gi/gtype.cpp b/gi/gtype.cpp
index d6589250d..1b25c4b26 100644
--- a/gi/gtype.cpp
+++ b/gi/gtype.cpp
@@ -47,7 +47,7 @@ class GTypeObj : public CWrapper<GTypeObj, void> {
 
     // No private data is allocated, it's stuffed directly in the private field
     // of JSObject, so nothing to free
-    static void finalize_impl(JSFreeOp*, void*) {}
+    static void finalize_impl(JS::GCContext*, void*) {}
 
     // Properties
 
@@ -97,7 +97,8 @@ class GTypeObj : public CWrapper<GTypeObj, void> {
         js::ClassSpec::DontDefineConstructor};
 
     static constexpr JSClass klass = {
-        "GIRepositoryGType", JSCLASS_HAS_PRIVATE | JSCLASS_FOREGROUND_FINALIZE,
+        "GIRepositoryGType",
+        JSCLASS_HAS_RESERVED_SLOTS(1) | JSCLASS_FOREGROUND_FINALIZE,
         &GTypeObj::class_ops, &GTypeObj::class_spec};
 
     GJS_JSAPI_RETURN_CONVENTION
@@ -171,7 +172,9 @@ class GTypeObj : public CWrapper<GTypeObj, void> {
         if (!gtype_wrapper)
             return nullptr;
 
-        JS::SetPrivate(gtype_wrapper, GSIZE_TO_POINTER(gtype));
+        // TODO: Install 0 slot
+        JS::SetReservedSlot(gtype_wrapper, 0,
+                            JS::PrivateValue(GSIZE_TO_POINTER(gtype)));
 
         gjs->gtype_table().put(gtype, gtype_wrapper);
 
diff --git a/gi/interface.cpp b/gi/interface.cpp
index dc6c018dc..f574ffb7f 100644
--- a/gi/interface.cpp
+++ b/gi/interface.cpp
@@ -9,7 +9,7 @@
 
 #include <js/Class.h>
 #include <js/ErrorReport.h>  // for JS_ReportOutOfMemory
-#include <js/Id.h>  // for JSID_VOID, PropertyKey, jsid
+#include <js/Id.h>           // for JS::PropertyKey::Void(), PropertyKey, jsid
 #include <js/TypeDecls.h>
 #include <js/Utility.h>  // for UniqueChars
 
@@ -50,7 +50,7 @@ static bool append_inferface_properties(JSContext* cx,
         if (flags & GI_FUNCTION_IS_METHOD) {
             const char* name = meth_info.name();
             jsid id = gjs_intern_string_to_id(cx, name);
-            if (id == JSID_VOID)
+            if (id.isVoid())
                 return false;
             properties.infallibleAppend(id);
         }
@@ -177,7 +177,7 @@ const struct JSClassOps InterfaceBase::class_ops = {
 
 const struct JSClass InterfaceBase::klass = {
     "GObject_Interface",
-    JSCLASS_HAS_PRIVATE | JSCLASS_BACKGROUND_FINALIZE,
+    JSCLASS_HAS_RESERVED_SLOTS(1) | JSCLASS_BACKGROUND_FINALIZE,
     &InterfaceBase::class_ops
 };
 
diff --git a/gi/ns.cpp b/gi/ns.cpp
index a5d5feb3a..5ee0dd772 100644
--- a/gi/ns.cpp
+++ b/gi/ns.cpp
@@ -145,7 +145,7 @@ class Ns : private GjsAutoChar, public CWrapper<Ns> {
             const char* name = info.name();
 
             jsid id = gjs_intern_string_to_id(cx, name);
-            if (id == JSID_VOID)
+            if (id.isVoid())
                 return false;
             properties.infallibleAppend(id);
         }
@@ -153,7 +153,7 @@ class Ns : private GjsAutoChar, public CWrapper<Ns> {
         return true;
     }
 
-    static void finalize_impl(JSFreeOp* fop [[maybe_unused]], Ns* priv) {
+    static void finalize_impl(JS::GCContext* gcx [[maybe_unused]], Ns* priv) {
         g_assert(priv && "Finalize called on wrong object");
         delete priv;
     }
@@ -203,8 +203,8 @@ class Ns : private GjsAutoChar, public CWrapper<Ns> {
 
     static constexpr JSClass klass = {
         "GIRepositoryNamespace",
-        JSCLASS_HAS_PRIVATE | JSCLASS_FOREGROUND_FINALIZE, &Ns::class_ops,
-        &Ns::class_spec};
+        JSCLASS_HAS_RESERVED_SLOTS(1) | JSCLASS_FOREGROUND_FINALIZE,
+        &Ns::class_ops, &Ns::class_spec};
 
  public:
     GJS_JSAPI_RETURN_CONVENTION
@@ -219,8 +219,9 @@ class Ns : private GjsAutoChar, public CWrapper<Ns> {
             return nullptr;
 
         auto* priv = new Ns(ns_name);
-        g_assert(!JS::GetPrivate(ns));
-        JS::SetPrivate(ns, priv);
+        g_assert(!JS::GetMaybePtrFromReservedSlot<Ns>(ns, 0));
+        // TODO: Install 0 slot
+        JS::SetReservedSlot(ns, 0, JS::PrivateValue(priv));
 
         gjs_debug_lifecycle(GJS_DEBUG_GNAMESPACE,
                             "ns constructor, obj %p priv %p", ns.get(), priv);
diff --git a/gi/object.cpp b/gi/object.cpp
index 6c85631c9..0790a053d 100644
--- a/gi/object.cpp
+++ b/gi/object.cpp
@@ -676,7 +676,7 @@ static bool interface_getter(JSContext* cx, unsigned argc, JS::Value* vp) {
         g_assert(v_override_symbol.isSymbol() &&
                  "override symbol must be a symbol");
         JS::RootedSymbol override_symbol(cx, v_override_symbol.toSymbol());
-        JS::RootedId override_id(cx, SYMBOL_TO_JSID(override_symbol));
+        JS::RootedId override_id(cx, JS::PropertyKey::Symbol(override_symbol));
 
         JS::RootedObject this_obj(cx);
         if (!args.computeThis(cx, &this_obj))
@@ -696,7 +696,7 @@ static bool interface_getter(JSContext* cx, unsigned argc, JS::Value* vp) {
     g_assert(v_prototype.isObject() && "prototype must be an object");
 
     JS::RootedObject prototype(cx, &v_prototype.toObject());
-    JS::RootedId id(cx, JS::PropertyKey::fromNonIntAtom(JS_GetFunctionId(
+    JS::RootedId id(cx, JS::PropertyKey::NonIntAtom(JS_GetFunctionId(
                             JS_GetObjectFunction(&args.callee()))));
     return JS_GetPropertyById(cx, prototype, id, args.rval());
 }
@@ -720,7 +720,7 @@ static bool interface_setter(JSContext* cx, unsigned argc, JS::Value* vp) {
     JS::RootedObject this_obj(cx);
     if (!args.computeThis(cx, &this_obj))
         return false;
-    JS::RootedId override_id(cx, SYMBOL_TO_JSID(symbol));
+    JS::RootedId override_id(cx, JS::PropertyKey::Symbol(symbol));
 
     return JS_SetPropertyById(cx, this_obj, override_id, args[0]);
 }
@@ -1122,7 +1122,7 @@ bool ObjectPrototype::new_enumerate_impl(JSContext* cx, JS::HandleObject,
             if (flags & GI_FUNCTION_IS_METHOD) {
                 const char* name = meth_info.name();
                 jsid id = gjs_intern_string_to_id(cx, name);
-                if (id == JSID_VOID)
+                if (id.isVoid())
                     return false;
                 properties.infallibleAppend(id);
             }
@@ -1136,7 +1136,7 @@ bool ObjectPrototype::new_enumerate_impl(JSContext* cx, JS::HandleObject,
             GjsAutoChar js_name = gjs_hyphen_to_underscore(prop_info.name());
 
             jsid id = gjs_intern_string_to_id(cx, js_name);
-            if (id == JSID_VOID)
+            if (id.isVoid())
                 return false;
             properties.infallibleAppend(id);
         }
@@ -1161,7 +1161,7 @@ bool ObjectPrototype::new_enumerate_impl(JSContext* cx, JS::HandleObject,
             if (flags & GI_FUNCTION_IS_METHOD) {
                 const char* name = meth_info.name();
                 jsid id = gjs_intern_string_to_id(cx, name);
-                if (id == JSID_VOID)
+                if (id.isVoid())
                     return false;
                 properties.infallibleAppend(id);
             }
@@ -1174,7 +1174,7 @@ bool ObjectPrototype::new_enumerate_impl(JSContext* cx, JS::HandleObject,
 
             GjsAutoChar js_name = gjs_hyphen_to_underscore(prop_info.name());
             jsid id = gjs_intern_string_to_id(cx, js_name);
-            if (id == JSID_VOID)
+            if (id.isVoid())
                 return false;
             properties.infallibleAppend(id);
         }
@@ -1192,7 +1192,7 @@ bool ObjectPrototype::props_to_g_parameters(JSContext* context,
     size_t ix, length;
     JS::RootedId prop_id(context);
     JS::RootedValue value(context);
-    JS::Rooted<JS::IdVector> ids(context);
+    JS::Rooted<JS::IdVector> ids(context, context);
     std::unordered_set<GParamSpec*> visited_params;
     if (!JS_Enumerate(context, props, &ids)) {
         gjs_throw(context, "Failed to create property iterator for object props hash");
@@ -1581,7 +1581,7 @@ ObjectPrototype::ObjectPrototype(GIObjectInfo* info, GType gtype)
  * Private callback, called after the JS engine finishes garbage collection, and
  * notifies when weak pointers need to be either moved or swept.
  */
-void ObjectInstance::update_heap_wrapper_weak_pointers(JSContext*,
+void ObjectInstance::update_heap_wrapper_weak_pointers(JSTracer* trc,
                                                        JS::Compartment*,
                                                        void*) {
     gjs_debug_lifecycle(GJS_DEBUG_GOBJECT, "Weak pointer update callback, "
@@ -1593,15 +1593,15 @@ void ObjectInstance::update_heap_wrapper_weak_pointers(JSContext*,
     auto locked_queue = ToggleQueue::get_default();
 
     ObjectInstance::remove_wrapped_gobjects_if(
-        std::mem_fn(&ObjectInstance::weak_pointer_was_finalized),
+        [&trc](ObjectInstance* instance) -> bool {
+            return instance->weak_pointer_was_finalized(trc);
+        },
         std::mem_fn(&ObjectInstance::disassociate_js_gobject));
 
     s_wrapped_gobject_list.shrink_to_fit();
 }
 
-bool
-ObjectInstance::weak_pointer_was_finalized(void)
-{
+bool ObjectInstance::weak_pointer_was_finalized(JSTracer* trc) {
     if (has_wrapper() && !wrapper_is_rooted()) {
         bool toggle_down_queued, toggle_up_queued;
 
@@ -1612,7 +1612,7 @@ ObjectInstance::weak_pointer_was_finalized(void)
         if (!toggle_down_queued && toggle_up_queued)
             return false;
 
-        if (!update_after_gc())
+        if (!update_after_gc(trc))
             return false;
 
         if (toggle_down_queued)
@@ -1900,14 +1900,14 @@ void ObjectPrototype::trace_impl(JSTracer* tracer) {
         Gjs::Closure::for_gclosure(closure)->trace(tracer);
 }
 
-void ObjectInstance::finalize_impl(JSFreeOp* fop, JSObject* obj) {
+void ObjectInstance::finalize_impl(JS::GCContext* gcx, JSObject* obj) {
     GTypeQuery query;
     type_query_dynamic_safe(&query);
     if (G_LIKELY(query.type))
         JS::RemoveAssociatedMemory(obj, query.instance_size,
                                    MemoryUse::GObjectInstanceStruct);
 
-    GIWrapperInstance::finalize_impl(fop, obj);
+    GIWrapperInstance::finalize_impl(gcx, obj);
 }
 
 ObjectInstance::~ObjectInstance() {
@@ -2531,13 +2531,12 @@ const struct JSClassOps ObjectBase::class_ops = {
     &ObjectBase::finalize,
     NULL,
     NULL,
-    NULL,
     &ObjectBase::trace,
 };
 
 const struct JSClass ObjectBase::klass = {
     "GObject_Object",
-    JSCLASS_HAS_PRIVATE | JSCLASS_FOREGROUND_FINALIZE,
+    JSCLASS_HAS_RESERVED_SLOTS(1) | JSCLASS_FOREGROUND_FINALIZE,
     &ObjectBase::class_ops
 };
 
@@ -2724,7 +2723,8 @@ ObjectInstance* ObjectInstance::new_for_gobject(JSContext* cx, GObject* gobj) {
 
     ObjectInstance* priv = new ObjectInstance(prototype, obj);
 
-    JS::SetPrivate(obj, priv);
+    // TODO: Install 0 slot
+    JS::SetReservedSlot(obj, 0, JS::PrivateValue(priv));
 
     g_object_ref_sink(gobj);
     priv->associate_js_gobject(cx, obj, gobj);
diff --git a/gi/object.h b/gi/object.h
index 886f13eaf..3af70b555 100644
--- a/gi/object.h
+++ b/gi/object.h
@@ -173,7 +173,8 @@ struct IdHasher {
             return js::DefaultHasher<JSString*>::hash(id.toString());
         if (id.isSymbol())
             return js::DefaultHasher<JS::Symbol*>::hash(id.toSymbol());
-        return mozilla::HashGeneric(JSID_BITS(id));
+
+        return mozilla::HashGeneric(id.asRawBits());
     }
     static bool match(jsid id1, jsid id2) { return id1 == id2; }
 };
@@ -336,17 +337,19 @@ class ObjectInstance : public GIWrapperInstance<ObjectBase, ObjectPrototype,
     void discard_wrapper(void) { m_wrapper.reset(); }
     void switch_to_rooted(JSContext* cx) { m_wrapper.switch_to_rooted(cx); }
     void switch_to_unrooted(JSContext* cx) { m_wrapper.switch_to_unrooted(cx); }
-    [[nodiscard]] bool update_after_gc() { return m_wrapper.update_after_gc(); }
+    [[nodiscard]] bool update_after_gc(JSTracer* trc) {
+        return m_wrapper.update_after_gc(trc);
+    }
     [[nodiscard]] bool wrapper_is_rooted() const { return m_wrapper.rooted(); }
     void release_native_object(void);
     void associate_js_gobject(JSContext* cx, JS::HandleObject obj,
                               GObject* gobj);
     void disassociate_js_gobject(void);
     void handle_context_dispose(void);
-    [[nodiscard]] bool weak_pointer_was_finalized();
+    [[nodiscard]] bool weak_pointer_was_finalized(JSTracer* trc);
     static void ensure_weak_pointer_callback(JSContext* cx);
-    static void update_heap_wrapper_weak_pointers(JSContext* cx,
-                                                  JS::Compartment* compartment,
+    static void update_heap_wrapper_weak_pointers(JSTracer* trc,
+                                                  JS::Compartment* comp,
                                                   void* data);
 
  public:
@@ -421,7 +424,7 @@ class ObjectInstance : public GIWrapperInstance<ObjectBase, ObjectPrototype,
     GJS_JSAPI_RETURN_CONVENTION
     bool add_property_impl(JSContext* cx, JS::HandleObject obj, JS::HandleId id,
                            JS::HandleValue value);
-    void finalize_impl(JSFreeOp* fop, JSObject* obj);
+    void finalize_impl(JS::GCContext* gcx, JSObject* obj);
     void trace_impl(JSTracer* trc);
 
     /* JS property getters/setters */
diff --git a/gi/param.cpp b/gi/param.cpp
index 7a3f88174..4fe95aecf 100644
--- a/gi/param.cpp
+++ b/gi/param.cpp
@@ -37,8 +37,8 @@ struct Param : GjsAutoParam {
 
 [[nodiscard]] static GParamSpec* param_value(JSContext* cx,
                                              JS::HandleObject obj) {
-    auto* priv = static_cast<Param*>(
-        JS_GetInstancePrivate(cx, obj, &gjs_param_class, nullptr));
+    auto* priv = JS::GetMaybePtrFromReservedSlot<Param>(obj, 0);
+
     return priv ? priv->get() : nullptr;
 }
 
@@ -113,15 +113,16 @@ static bool gjs_param_constructor(JSContext* cx, unsigned argc, JS::Value* vp) {
     return true;
 }
 
-static void param_finalize(JSFreeOp*, JSObject* obj) {
-    Param* priv = static_cast<Param*>(JS::GetPrivate(obj));
+static void param_finalize(JS::GCContext*, JSObject* obj) {
+    Param* priv = JS::GetMaybePtrFromReservedSlot<Param>(obj, 0);
     gjs_debug_lifecycle(GJS_DEBUG_GPARAM, "finalize, obj %p priv %p", obj,
                         priv);
     if (!priv)
         return; /* wrong class? */
 
     GJS_DEC_COUNTER(param);
-    JS::SetPrivate(obj, nullptr);
+    // TODO: Install 0 slot
+    JS::SetReservedSlot(obj, 0, JS::PrivateValue(nullptr));
     delete priv;
 }
 
@@ -140,9 +141,8 @@ static const struct JSClassOps gjs_param_class_ops = {
 
 struct JSClass gjs_param_class = {
     "GObject_ParamSpec",
-    JSCLASS_HAS_PRIVATE | JSCLASS_BACKGROUND_FINALIZE,
-    &gjs_param_class_ops
-};
+    JSCLASS_HAS_RESERVED_SLOTS(1) | JSCLASS_BACKGROUND_FINALIZE,
+    &gjs_param_class_ops};
 
 GJS_JSAPI_RETURN_CONVENTION
 static JSObject*
@@ -220,7 +220,8 @@ gjs_param_from_g_param(JSContext    *context,
 
     GJS_INC_COUNTER(param);
     auto* priv = new Param(gparam);
-    JS::SetPrivate(obj, priv);
+    // TODO: Install 0 slot
+    JS::SetReservedSlot(obj, 0, JS::PrivateValue(priv));
 
     gjs_debug(GJS_DEBUG_GPARAM,
               "JSObject created with param instance %p type %s", gparam,
diff --git a/gi/repo.cpp b/gi/repo.cpp
index 9f5d4e1f3..e40299587 100644
--- a/gi/repo.cpp
+++ b/gi/repo.cpp
@@ -18,7 +18,7 @@
 #include <js/Class.h>
 #include <js/ComparisonOperators.h>
 #include <js/Exception.h>
-#include <js/Id.h>                  // for JSID_VOID
+#include <js/Id.h>                  // for JS::PropertyKey::Void()
 #include <js/Object.h>              // for GetClass
 #include <js/PropertyDescriptor.h>  // for JSPROP_PERMANENT, JSPROP_RESOLVING
 #include <js/RootingAPI.h>
@@ -481,7 +481,7 @@ gjs_lookup_namespace_object(JSContext  *context,
     }
 
     JS::RootedId ns_name(context, gjs_intern_string_to_id(context, ns));
-    if (ns_name == JSID_VOID)
+    if (ns_name.isVoid())
         return nullptr;
     return gjs_lookup_namespace_object_by_name(context, ns_name);
 }
diff --git a/gi/union.cpp b/gi/union.cpp
index dca235926..e29bfbba0 100644
--- a/gi/union.cpp
+++ b/gi/union.cpp
@@ -148,7 +148,7 @@ const struct JSClassOps UnionBase::class_ops = {
 
 const struct JSClass UnionBase::klass = {
     "GObject_Union",
-    JSCLASS_HAS_PRIVATE | JSCLASS_FOREGROUND_FINALIZE,
+    JSCLASS_HAS_RESERVED_SLOTS(1) | JSCLASS_FOREGROUND_FINALIZE,
     &UnionBase::class_ops
 };
 // clang-format on
diff --git a/gi/wrapperutils.h b/gi/wrapperutils.h
index aa50cdd05..747e72699 100644
--- a/gi/wrapperutils.h
+++ b/gi/wrapperutils.h
@@ -394,7 +394,7 @@ class GIWrapperBase : public CWrapperPointerOps<Base> {
      * necessary to include a finalize_impl() function in Prototype or Instance.
      * Any needed finalization should be done in ~Prototype() and ~Instance().
      */
-    static void finalize(JSFreeOp* fop, JSObject* obj) {
+    static void finalize(JS::GCContext* gcx, JSObject* obj) {
         Base* priv = Base::for_js_nocheck(obj);
         if (!priv)
             return;  // construction didn't finish
@@ -404,12 +404,13 @@ class GIWrapperBase : public CWrapperPointerOps<Base> {
         static_cast<GIWrapperBase*>(priv)->debug_lifecycle(obj, "Finalize");
 
         if (priv->is_prototype())
-            priv->to_prototype()->finalize_impl(fop, obj);
+            priv->to_prototype()->finalize_impl(gcx, obj);
         else
-            priv->to_instance()->finalize_impl(fop, obj);
+            priv->to_instance()->finalize_impl(gcx, obj);
 
         // Remove the pointer from the JSObject
-        JS::SetPrivate(obj, nullptr);
+        // TODO: Install 0 slot
+        JS::SetReservedSlot(obj, 0, JS::PrivateValue(nullptr));
     }
 
     /*
@@ -902,7 +903,8 @@ class GIWrapperPrototype : public Base {
         // a garbage collection or error happens subsequently, then this object
         // might be traced and we would end up dereferencing a null pointer.
         Prototype* proto = priv.release();
-        JS::SetPrivate(prototype, proto);
+        // TODO: Install 0 slot
+        JS::SetReservedSlot(prototype, 0, JS::PrivateValue(proto));
 
         if (!gjs_wrapper_define_gtype_prop(cx, constructor, gtype))
             return nullptr;
@@ -949,7 +951,8 @@ class GIWrapperPrototype : public Base {
             return nullptr;
 
         Prototype* proto = priv.release();
-        JS::SetPrivate(prototype, proto);
+        // TODO: Install 0 slot
+        JS::SetReservedSlot(prototype, 0, JS::PrivateValue(proto));
 
         if (!proto->define_static_methods(cx, constructor))
             return nullptr;
@@ -1013,7 +1016,7 @@ class GIWrapperPrototype : public Base {
     // JSClass operations
 
  protected:
-    void finalize_impl(JSFreeOp*, JSObject*) { release(); }
+    void finalize_impl(JS::GCContext*, JSObject*) { release(); }
 
     // Override if necessary
     void trace_impl(JSTracer*) {}
@@ -1060,24 +1063,26 @@ class GIWrapperInstance : public Base {
      */
     [[nodiscard]] static Instance* new_for_js_object(JSContext* cx,
                                                      JS::HandleObject obj) {
-        g_assert(!JS::GetPrivate(obj));
+        g_assert(!JS::GetMaybePtrFromReservedSlot<Instance>(obj, 0));
         Prototype* prototype = Prototype::for_js_prototype(cx, obj);
         auto* priv = new Instance(prototype, obj);
 
         // Init the private variable before we do anything else. If a garbage
         // collection happens when calling the constructor, then this object
         // might be traced and we would end up dereferencing a null pointer.
-        JS::SetPrivate(obj, priv);
+        // TODO: Install 0 slot
+        JS::SetReservedSlot(obj, 0, JS::PrivateValue(priv));
 
         return priv;
     }
 
     [[nodiscard]] static Instance* new_for_js_object(Prototype* prototype,
                                                      JS::HandleObject obj) {
-        g_assert(!JS::GetPrivate(obj));
+        g_assert(!JS::GetMaybePtrFromReservedSlot<Instance>(obj, 0));
         auto* priv = new Instance(prototype, obj);
 
-        JS::SetPrivate(obj, priv);
+        // TODO: Install 0 slot
+        JS::SetReservedSlot(obj, 0, JS::PrivateValue(priv));
 
         return priv;
     }
@@ -1110,7 +1115,7 @@ class GIWrapperInstance : public Base {
     // JSClass operations
 
  protected:
-    void finalize_impl(JSFreeOp*, JSObject*) {
+    void finalize_impl(JS::GCContext*, JSObject*) {
         delete static_cast<Instance*>(this);
     }
 
diff --git a/gjs/atoms.cpp b/gjs/atoms.cpp
index 6cb04f89b..46dae1444 100644
--- a/gjs/atoms.cpp
+++ b/gjs/atoms.cpp
@@ -31,7 +31,7 @@ bool GjsSymbolAtom::init(JSContext* cx, const char* str) {
     JS::Symbol* symbol = JS::NewSymbol(cx, descr);
     if (!symbol)
         return false;
-    m_jsid = JS::Heap<jsid>{SYMBOL_TO_JSID(symbol)};
+    m_jsid = JS::Heap<jsid>{JS::PropertyKey::Symbol(symbol)};
     return true;
 }
 
diff --git a/gjs/context.cpp b/gjs/context.cpp
index 4e22825d0..a9dde93db 100644
--- a/gjs/context.cpp
+++ b/gjs/context.cpp
@@ -433,7 +433,7 @@ void GjsContextPrivate::dispose(void) {
         m_gtype_table->clear();
 
         /* Do a full GC here before tearing down, since once we do
-         * that we may not have the JS::GetPrivate() to access the
+         * that we may not have the JS::GetReservedSlot(, 0) to access the
          * context
          */
         gjs_debug(GJS_DEBUG_CONTEXT, "Final triggered GC");
diff --git a/gjs/engine.cpp b/gjs/engine.cpp
index 16d84cc19..35ac265dd 100644
--- a/gjs/engine.cpp
+++ b/gjs/engine.cpp
@@ -32,7 +32,7 @@
 #include "gjs/jsapi-util.h"
 #include "util/log.h"
 
-static void gjs_finalize_callback(JSFreeOp*, JSFinalizeStatus status,
+static void gjs_finalize_callback(JS::GCContext*, JSFinalizeStatus status,
                                   void* data) {
     auto* gjs = static_cast<GjsContextPrivate*>(data);
     gjs->set_finalize_status(status);
@@ -167,12 +167,7 @@ JSContext* gjs_create_js_context(GjsContextPrivate* uninitialized_gjs) {
     if (enable_jit) {
         gjs_debug(GJS_DEBUG_CONTEXT, "Enabling JIT");
     }
-    JS::ContextOptionsRef(cx)
-        .setAsmJS(enable_jit)
-        .setTopLevelAwait(true)
-        .setClassStaticBlocks(true)
-        .setPrivateClassFields(true)
-        .setPrivateClassMethods(true);
+    JS::ContextOptionsRef(cx).setAsmJS(enable_jit);
 
     uint32_t value = enable_jit ? 1 : 0;
 
diff --git a/gjs/global.cpp b/gjs/global.cpp
index 56fe8602b..3533e507d 100644
--- a/gjs/global.cpp
+++ b/gjs/global.cpp
@@ -74,6 +74,7 @@ class GjsBaseGlobal {
         JSContext* cx, const JSClass* clasp,
         JS::RealmCreationOptions options = JS::RealmCreationOptions()) {
         options.setNewCompartmentAndZone();
+        options.setFreezeBuiltins(false);
         return base(cx, clasp, options);
     }
 
@@ -111,7 +112,7 @@ class GjsBaseGlobal {
             return false;
 
         JS::RootedValue ignored(cx);
-        return JS::CloneAndExecuteScript(cx, compiled_script, &ignored);
+        return JS_ExecuteScript(cx, compiled_script, &ignored);
     }
 
     GJS_JSAPI_RETURN_CONVENTION
diff --git a/gjs/importer.cpp b/gjs/importer.cpp
index c8bc553ef..1a3118a30 100644
--- a/gjs/importer.cpp
+++ b/gjs/importer.cpp
@@ -171,9 +171,9 @@ define_meta_properties(JSContext       *context,
                                module_path, attrs))
         return false;
 
-    JS::RootedId to_string_tag_name(context,
-        SYMBOL_TO_JSID(JS::GetWellKnownSymbol(context,
-                                              JS::SymbolCode::toStringTag)));
+    JS::RootedId to_string_tag_name(
+        context, JS::PropertyKey::Symbol(JS::GetWellKnownSymbol(
+                     context, JS::SymbolCode::toStringTag)));
     return JS_DefinePropertyById(context, module_obj, to_string_tag_name,
                                  to_string_tag, attrs);
 }
@@ -283,7 +283,7 @@ gjs_import_native_module(JSContext       *cx,
         cx, gjs_get_native_registry(gjs_get_import_global(cx)));
 
     JS::RootedId id(cx, gjs_intern_string_to_id(cx, parse_name));
-    if (id == JSID_VOID)
+    if (id.isVoid())
         return false;
 
     JS::RootedObject module(cx);
@@ -692,7 +692,7 @@ static bool importer_new_enumerate(JSContext* context, JS::HandleObject object,
 
             if (g_file_info_get_file_type(info) == G_FILE_TYPE_DIRECTORY) {
                 jsid id = gjs_intern_string_to_id(context, filename);
-                if (id == JSID_VOID)
+                if (id.isVoid())
                     return false;
                 if (!properties.append(id)) {
                     JS_ReportOutOfMemory(context);
@@ -703,7 +703,7 @@ static bool importer_new_enumerate(JSContext* context, JS::HandleObject object,
                 GjsAutoChar filename_noext =
                     g_strndup(filename, strlen(filename) - 3);
                 jsid id = gjs_intern_string_to_id(context, filename_noext);
-                if (id == JSID_VOID)
+                if (id.isVoid())
                     return false;
                 if (!properties.append(id)) {
                     JS_ReportOutOfMemory(context);
diff --git a/gjs/jsapi-util-root.h b/gjs/jsapi-util-root.h
index 7f4e27495..80f4d875a 100644
--- a/gjs/jsapi-util-root.h
+++ b/gjs/jsapi-util-root.h
@@ -62,8 +62,9 @@ struct GjsHeapOperation {
 
 template<>
 struct GjsHeapOperation<JSObject *> {
-    [[nodiscard]] static bool update_after_gc(JS::Heap<JSObject*>* location) {
-        JS_UpdateWeakPointerAfterGC(location);
+    [[nodiscard]] static bool update_after_gc(JSTracer* trc,
+                                              JS::Heap<JSObject*>* location) {
+        JS_UpdateWeakPointerAfterGC(trc, location);
         return (location->unbarrieredGet() == nullptr);
     }
 
@@ -178,7 +179,7 @@ class GjsMaybeOwned {
     void root(JSContext* cx, const T& thing) {
         debug("root()");
         g_assert(!m_root);
-        g_assert(m_heap.get() == JS::SafelyInitialized<T>());
+        g_assert(m_heap.get() == JS::SafelyInitialized<T>::create());
         m_heap.~Heap();
         m_root = std::make_unique<JS::PersistentRooted<T>>(cx, thing);
     }
@@ -204,7 +205,7 @@ class GjsMaybeOwned {
     void reset() {
         debug("reset()");
         if (!m_root) {
-            m_heap = JS::SafelyInitialized<T>();
+            m_heap = JS::SafelyInitialized<T>::create();
             return;
         }
 
@@ -251,10 +252,10 @@ class GjsMaybeOwned {
     /* If not tracing, then you must call this method during GC in order to
      * update the object's location if it was moved, or null it out if it was
      * finalized. If the object was finalized, returns true. */
-    bool update_after_gc() {
+    bool update_after_gc(JSTracer* trc) {
         debug("update_after_gc()");
         g_assert(!m_root);
-        return GjsHeapOperation<T>::update_after_gc(&m_heap);
+        return GjsHeapOperation<T>::update_after_gc(trc, &m_heap);
     }
 
     [[nodiscard]] constexpr bool rooted() const { return m_root != nullptr; }
diff --git a/gjs/jsapi-util-string.cpp b/gjs/jsapi-util-string.cpp
index a39a0c055..89abe087e 100644
--- a/gjs/jsapi-util-string.cpp
+++ b/gjs/jsapi-util-string.cpp
@@ -437,7 +437,7 @@ bool gjs_get_string_id(JSContext* cx, jsid id, JS::UniqueChars* name_p) {
         return true;
     }
 
-    JSLinearString* lstr = JSID_TO_LINEAR_STRING(id);
+    JSLinearString* lstr = id.toLinearString();
     JS::RootedString s(cx, JS_FORGET_STRING_LINEARNESS(lstr));
     *name_p = JS_EncodeStringToUTF8(cx, s);
     return !!*name_p;
@@ -474,7 +474,7 @@ gjs_intern_string_to_id(JSContext  *cx,
 {
     JS::RootedString str(cx, JS_AtomizeAndPinString(cx, string));
     if (!str)
-        return JSID_VOID;
+        return JS::PropertyKey::Void();
     return JS::PropertyKey::fromPinnedString(str);
 }
 
@@ -661,6 +661,6 @@ std::string
 gjs_debug_id(jsid id)
 {
     if (id.isString())
-        return gjs_debug_linear_string(JSID_TO_LINEAR_STRING(id), NoQuotes);
+        return gjs_debug_linear_string(id.toLinearString(), NoQuotes);
     return gjs_debug_value(js::IdToValue(id));
 }
diff --git a/gjs/module.cpp b/gjs/module.cpp
index 3b54a3fca..471280b73 100644
--- a/gjs/module.cpp
+++ b/gjs/module.cpp
@@ -72,13 +72,15 @@ class GjsScriptModule {
     /* Private data accessors */
 
     [[nodiscard]] static inline GjsScriptModule* priv(JSObject* module) {
-        return static_cast<GjsScriptModule*>(JS::GetPrivate(module));
+        return JS::GetMaybePtrFromReservedSlot<GjsScriptModule>(module, 0);
     }
 
     /* Creates a JS module object. Use instead of the class's constructor */
     [[nodiscard]] static JSObject* create(JSContext* cx, const char* name) {
         JSObject* module = JS_NewObject(cx, &GjsScriptModule::klass);
-        JS::SetPrivate(module, new GjsScriptModule(name));
+        // TODO: Install 0 slot
+        JS::SetReservedSlot(module, 0,
+                            JS::PrivateValue(new GjsScriptModule(name)));
         return module;
     }
 
@@ -210,7 +212,9 @@ class GjsScriptModule {
         return priv(module)->resolve_impl(cx, module, id, resolved);
     }
 
-    static void finalize(JSFreeOp*, JSObject* module) { delete priv(module); }
+    static void finalize(JS::GCContext*, JSObject* module) {
+        delete priv(module);
+    }
 
     static constexpr JSClassOps class_ops = {
         nullptr,  // addProperty
@@ -224,7 +228,7 @@ class GjsScriptModule {
 
     static constexpr JSClass klass = {
         "GjsScriptModule",
-        JSCLASS_HAS_PRIVATE | JSCLASS_BACKGROUND_FINALIZE,
+        JSCLASS_HAS_RESERVED_SLOTS(1) | JSCLASS_BACKGROUND_FINALIZE,
         &GjsScriptModule::class_ops,
     };
 
diff --git a/meson.build b/meson.build
index 9f8cdacc9..5a1619847 100644
--- a/meson.build
+++ b/meson.build
@@ -127,7 +127,7 @@ gio = dependency('gio-2.0', version: glib_required_version,
 ffi = dependency('libffi', fallback: ['libffi', 'ffi_dep'])
 gi = dependency('gobject-introspection-1.0', version: '>= 1.66.0',
     fallback: ['gobject-introspection', 'girepo_dep'])
-spidermonkey = dependency('mozjs-91', version: '>= 91.3.0')
+spidermonkey = dependency('mozjs-103a1', version: '>= 103.0a1')
 
 # We might need to look for the headers and lib's for Cairo
 # manually on MSVC/clang-cl builds...
@@ -322,7 +322,8 @@ header_conf.set('ENABLE_PROFILER', build_profiler,
     description: 'Build the profiler')
 # COMPAT: SpiderMonkey headers in some places use DEBUG instead of JS_DEBUG
 # https://bugzilla.mozilla.org/show_bug.cgi?id=1261161 */
-header_conf.set('DEBUG', not nondebug_spidermonkey,
+# TODO: DEBUG is not being set properly
+header_conf.set('DEBUG', 1,
     description: 'SpiderMonkey was compiled with --enable-debug')
 header_conf.set('HAVE_DTRACE', get_option('dtrace'),
     description: 'Using dtrace probes')
diff --git a/modules/cairo-context.cpp b/modules/cairo-context.cpp
index 463e06215..762b74e48 100644
--- a/modules/cairo-context.cpp
+++ b/modules/cairo-context.cpp
@@ -86,9 +86,7 @@ _GJS_CAIRO_CONTEXT_DEFINE_FUNC_END
         return false;                                                       \
     cfunc(cr, &arg1, &arg2);                                                \
     if (cairo_status(cr) == CAIRO_STATUS_SUCCESS) {                         \
-        JS::RootedObject array(                                             \
-            context,                                                        \
-            JS::NewArrayObject(context, JS::HandleValueArray::empty()));    \
+        JS::RootedObject array(context, JS::NewArrayObject(context, 2));    \
         if (!array)                                                         \
             return false;                                                   \
         JS::RootedValue r(context, JS::NumberValue(arg1));                  \
@@ -107,9 +105,7 @@ _GJS_CAIRO_CONTEXT_DEFINE_FUNC_END
     _GJS_CAIRO_CONTEXT_CHECK_NO_ARGS(method)                             \
     cfunc(cr, &arg1, &arg2);                                             \
     if (cairo_status(cr) == CAIRO_STATUS_SUCCESS) {                      \
-        JS::RootedObject array(                                          \
-            context,                                                     \
-            JS::NewArrayObject(context, JS::HandleValueArray::empty())); \
+        JS::RootedObject array(context, JS::NewArrayObject(context, 2)); \
         if (!array)                                                      \
             return false;                                                \
         JS::RootedValue r(context, JS::NumberValue(arg1));               \
@@ -128,9 +124,7 @@ _GJS_CAIRO_CONTEXT_DEFINE_FUNC_END
     _GJS_CAIRO_CONTEXT_CHECK_NO_ARGS(method)                             \
     cfunc(cr, &arg1, &arg2, &arg3, &arg4);                               \
     {                                                                    \
-        JS::RootedObject array(                                          \
-            context,                                                     \
-            JS::NewArrayObject(context, JS::HandleValueArray::empty())); \
+        JS::RootedObject array(context, JS::NewArrayObject(context, 4)); \
         if (!array)                                                      \
             return false;                                                \
         JS::RootedValue r(context, JS::NumberValue(arg1));               \
@@ -268,7 +262,7 @@ cairo_t* CairoContext::constructor_impl(JSContext* context,
     return cr;
 }
 
-void CairoContext::finalize_impl(JSFreeOp*, cairo_t* cr) {
+void CairoContext::finalize_impl(JS::GCContext*, cairo_t* cr) {
     if (!cr)
         return;
     cairo_destroy(cr);
@@ -369,7 +363,8 @@ dispose_func(JSContext *context,
     _GJS_CAIRO_CONTEXT_GET_PRIV_CR_CHECKED(context, argc, vp, rec, obj);
 
     cairo_destroy(cr);
-    JS::SetPrivate(obj, nullptr);
+    // TODO: Install 0 slot
+    JS::SetReservedSlot(obj, 0, JS::PrivateValue(nullptr));
 
     rec.rval().setUndefined();
     return true;
diff --git a/modules/cairo-path.cpp b/modules/cairo-path.cpp
index 76a879dfa..2ae3f72b5 100644
--- a/modules/cairo-path.cpp
+++ b/modules/cairo-path.cpp
@@ -38,15 +38,16 @@ JSObject* CairoPath::take_c_ptr(JSContext* cx, cairo_path_t* ptr) {
     if (!wrapper)
         return nullptr;
 
-    g_assert(!JS::GetPrivate(wrapper));
-    JS::SetPrivate(wrapper, ptr);
+    g_assert(!JS::GetMaybePtrFromReservedSlot<cairo_path_t>(wrapper, 0));
+    // TODO: Install 0 slot
+    JS::SetReservedSlot(wrapper, 0, JS::PrivateValue(ptr));
 
     debug_lifecycle(ptr, wrapper, "take_c_ptr");
 
     return wrapper;
 }
 
-void CairoPath::finalize_impl(JSFreeOp*, cairo_path_t* path) {
+void CairoPath::finalize_impl(JS::GCContext*, cairo_path_t* path) {
     if (!path)
         return;
     cairo_path_destroy(path);
diff --git a/modules/cairo-pattern.cpp b/modules/cairo-pattern.cpp
index 1a6d07da3..b0da27b89 100644
--- a/modules/cairo-pattern.cpp
+++ b/modules/cairo-pattern.cpp
@@ -64,14 +64,14 @@ const JSFunctionSpec CairoPattern::proto_funcs[] = {
 
 /**
  * CairoPattern::finalize_impl:
- * @fop: the free op
+ * @gcx: the free op
  * @pattern: pointer to free
  *
  * Destroys the resources associated with a pattern wrapper.
  *
  * This is mainly used for subclasses.
  */
-void CairoPattern::finalize_impl(JSFreeOp*, cairo_pattern_t* pattern) {
+void CairoPattern::finalize_impl(JS::GCContext*, cairo_pattern_t* pattern) {
     if (!pattern)
         return;
     cairo_pattern_destroy(pattern);
@@ -136,5 +136,5 @@ cairo_pattern_t* CairoPattern::for_js(JSContext* cx,
         return nullptr;
     }
 
-    return static_cast<cairo_pattern_t*>(JS::GetPrivate(pattern_wrapper));
+    return JS::GetMaybePtrFromReservedSlot<cairo_pattern_t>(pattern_wrapper, 0);
 }
diff --git a/modules/cairo-private.h b/modules/cairo-private.h
index a470a94a5..1c3eb4ac9 100644
--- a/modules/cairo-private.h
+++ b/modules/cairo-private.h
@@ -55,7 +55,7 @@ class CairoRegion : public CWrapper<CairoRegion, cairo_region_t> {
     static cairo_region_t* constructor_impl(JSContext* cx,
                                             const JS::CallArgs& args);
 
-    static void finalize_impl(JSFreeOp* fop, cairo_region_t* cr);
+    static void finalize_impl(JS::GCContext* gcx, cairo_region_t* cr);
 
     static const JSFunctionSpec proto_funcs[];
     static const JSPropertySpec proto_props[];
@@ -69,7 +69,7 @@ class CairoRegion : public CWrapper<CairoRegion, cairo_region_t> {
         CairoRegion::define_gtype_prop,
     };
     static constexpr JSClass klass = {
-        "Region", JSCLASS_HAS_PRIVATE | JSCLASS_BACKGROUND_FINALIZE,
+        "Region", JSCLASS_HAS_RESERVED_SLOTS(1) | JSCLASS_BACKGROUND_FINALIZE,
         &CairoRegion::class_ops, &CairoRegion::class_spec};
 };
 
@@ -95,7 +95,7 @@ class CairoContext : public CWrapper<CairoContext, cairo_t> {
     GJS_JSAPI_RETURN_CONVENTION
     static cairo_t* constructor_impl(JSContext* cx, const JS::CallArgs& args);
 
-    static void finalize_impl(JSFreeOp* fop, cairo_t* cr);
+    static void finalize_impl(JS::GCContext* gcx, cairo_t* cr);
 
     static const JSFunctionSpec proto_funcs[];
     static const JSPropertySpec proto_props[];
@@ -109,7 +109,7 @@ class CairoContext : public CWrapper<CairoContext, cairo_t> {
         CairoContext::define_gtype_prop,
     };
     static constexpr JSClass klass = {
-        "Context", JSCLASS_HAS_PRIVATE | JSCLASS_BACKGROUND_FINALIZE,
+        "Context", JSCLASS_HAS_RESERVED_SLOTS(1) | JSCLASS_BACKGROUND_FINALIZE,
         &CairoContext::class_ops, &CairoContext::class_spec};
 };
 
@@ -130,7 +130,7 @@ class CairoPath : public CWrapper<CairoPath, cairo_path_t> {
         GjsGlobalSlot::PROTOTYPE_cairo_path;
     static constexpr GjsDebugTopic DEBUG_TOPIC = GJS_DEBUG_CAIRO;
 
-    static void finalize_impl(JSFreeOp* fop, cairo_path_t* path);
+    static void finalize_impl(JS::GCContext* gcx, cairo_path_t* path);
 
     static const JSPropertySpec proto_props[];
     static constexpr js::ClassSpec class_spec = {
@@ -143,7 +143,7 @@ class CairoPath : public CWrapper<CairoPath, cairo_path_t> {
         nullptr,  // finishInit
     };
     static constexpr JSClass klass = {
-        "Path", JSCLASS_HAS_PRIVATE | JSCLASS_BACKGROUND_FINALIZE,
+        "Path", JSCLASS_HAS_RESERVED_SLOTS(1) | JSCLASS_BACKGROUND_FINALIZE,
         &CairoPath::class_ops, &CairoPath::class_spec};
 
  public:
@@ -171,7 +171,7 @@ class CairoSurface : public CWrapper<CairoSurface, cairo_surface_t> {
 
     static GType gtype() { return CAIRO_GOBJECT_TYPE_SURFACE; }
 
-    static void finalize_impl(JSFreeOp* fop, cairo_surface_t* surface);
+    static void finalize_impl(JS::GCContext* gcx, cairo_surface_t* surface);
 
     static const JSFunctionSpec proto_funcs[];
     static const JSPropertySpec proto_props[];
@@ -185,7 +185,7 @@ class CairoSurface : public CWrapper<CairoSurface, cairo_surface_t> {
         &CairoSurface::define_gtype_prop,
     };
     static constexpr JSClass klass = {
-        "Surface", JSCLASS_HAS_PRIVATE | JSCLASS_BACKGROUND_FINALIZE,
+        "Surface", JSCLASS_HAS_RESERVED_SLOTS(1) | JSCLASS_BACKGROUND_FINALIZE,
         &CairoSurface::class_ops, &CairoSurface::class_spec};
 
     static cairo_surface_t* copy_ptr(cairo_surface_t* surface) {
@@ -229,14 +229,15 @@ class CairoImageSurface : public CWrapper<CairoImageSurface, cairo_surface_t> {
         &CairoSurface::define_gtype_prop,
     };
     static constexpr JSClass klass = {
-        "ImageSurface", JSCLASS_HAS_PRIVATE | JSCLASS_BACKGROUND_FINALIZE,
+        "ImageSurface",
+        JSCLASS_HAS_RESERVED_SLOTS(1) | JSCLASS_BACKGROUND_FINALIZE,
         &CairoSurface::class_ops, &CairoImageSurface::class_spec};
 
     static cairo_surface_t* copy_ptr(cairo_surface_t* surface) {
         return cairo_surface_reference(surface);
     }
 
-    static void finalize_impl(JSFreeOp*, cairo_surface_t*) {}
+    static void finalize_impl(JS::GCContext*, cairo_surface_t*) {}
 
     GJS_JSAPI_RETURN_CONVENTION
     static cairo_surface_t* constructor_impl(JSContext* cx,
@@ -268,14 +269,15 @@ class CairoPSSurface : public CWrapper<CairoPSSurface, cairo_surface_t> {
         &CairoSurface::define_gtype_prop,
     };
     static constexpr JSClass klass = {
-        "PSSurface", JSCLASS_HAS_PRIVATE | JSCLASS_BACKGROUND_FINALIZE,
+        "PSSurface",
+        JSCLASS_HAS_RESERVED_SLOTS(1) | JSCLASS_BACKGROUND_FINALIZE,
         &CairoSurface::class_ops, &CairoPSSurface::class_spec};
 
     static cairo_surface_t* copy_ptr(cairo_surface_t* surface) {
         return cairo_surface_reference(surface);
     }
 
-    static void finalize_impl(JSFreeOp*, cairo_surface_t*) {}
+    static void finalize_impl(JS::GCContext*, cairo_surface_t*) {}
 
     GJS_JSAPI_RETURN_CONVENTION
     static cairo_surface_t* constructor_impl(JSContext* cx,
@@ -313,14 +315,15 @@ class CairoPDFSurface : public CWrapper<CairoPDFSurface, cairo_surface_t> {
         &CairoSurface::define_gtype_prop,
     };
     static constexpr JSClass klass = {
-        "PDFSurface", JSCLASS_HAS_PRIVATE | JSCLASS_BACKGROUND_FINALIZE,
+        "PDFSurface",
+        JSCLASS_HAS_RESERVED_SLOTS(1) | JSCLASS_BACKGROUND_FINALIZE,
         &CairoSurface::class_ops, &CairoPDFSurface::class_spec};
 
     static cairo_surface_t* copy_ptr(cairo_surface_t* surface) {
         return cairo_surface_reference(surface);
     }
 
-    static void finalize_impl(JSFreeOp*, cairo_surface_t*) {}
+    static void finalize_impl(JS::GCContext*, cairo_surface_t*) {}
 
     GJS_JSAPI_RETURN_CONVENTION
     static cairo_surface_t* constructor_impl(JSContext* cx,
@@ -358,14 +361,15 @@ class CairoSVGSurface : public CWrapper<CairoSVGSurface, cairo_surface_t> {
         &CairoSurface::define_gtype_prop,
     };
     static constexpr JSClass klass = {
-        "SVGSurface", JSCLASS_HAS_PRIVATE | JSCLASS_BACKGROUND_FINALIZE,
+        "SVGSurface",
+        JSCLASS_HAS_RESERVED_SLOTS(1) | JSCLASS_BACKGROUND_FINALIZE,
         &CairoSurface::class_ops, &CairoSVGSurface::class_spec};
 
     static cairo_surface_t* copy_ptr(cairo_surface_t* surface) {
         return cairo_surface_reference(surface);
     }
 
-    static void finalize_impl(JSFreeOp*, cairo_surface_t*) {}
+    static void finalize_impl(JS::GCContext*, cairo_surface_t*) {}
 
     GJS_JSAPI_RETURN_CONVENTION
     static cairo_surface_t* constructor_impl(JSContext* cx,
@@ -410,7 +414,7 @@ class CairoPattern : public CWrapper<CairoPattern, cairo_pattern_t> {
         &CairoPattern::define_gtype_prop,
     };
     static constexpr JSClass klass = {
-        "Pattern", JSCLASS_HAS_PRIVATE | JSCLASS_BACKGROUND_FINALIZE,
+        "Pattern", JSCLASS_HAS_RESERVED_SLOTS(1) | JSCLASS_BACKGROUND_FINALIZE,
         &CairoPattern::class_ops, &CairoPattern::class_spec};
 
     static GType gtype() { return CAIRO_GOBJECT_TYPE_PATTERN; }
@@ -423,7 +427,7 @@ class CairoPattern : public CWrapper<CairoPattern, cairo_pattern_t> {
     static bool getType_func(JSContext* context, unsigned argc, JS::Value* vp);
 
  protected:
-    static void finalize_impl(JSFreeOp* fop, cairo_pattern_t* pattern);
+    static void finalize_impl(JS::GCContext* gcx, cairo_pattern_t* pattern);
 
  public:
     static cairo_pattern_t* for_js(JSContext* cx,
@@ -459,10 +463,10 @@ class CairoGradient : public CWrapper<CairoGradient, cairo_pattern_t> {
         &CairoPattern::define_gtype_prop,
     };
     static constexpr JSClass klass = {
-        "Gradient", JSCLASS_HAS_PRIVATE | JSCLASS_BACKGROUND_FINALIZE,
+        "Gradient", JSCLASS_HAS_RESERVED_SLOTS(1) | JSCLASS_BACKGROUND_FINALIZE,
         &CairoPattern::class_ops, &CairoGradient::class_spec};
 
-    static void finalize_impl(JSFreeOp*, cairo_pattern_t*) {}
+    static void finalize_impl(JS::GCContext*, cairo_pattern_t*) {}
 };
 
 class CairoLinearGradient
@@ -490,7 +494,8 @@ class CairoLinearGradient
         &CairoPattern::define_gtype_prop,
     };
     static constexpr JSClass klass = {
-        "LinearGradient", JSCLASS_HAS_PRIVATE | JSCLASS_BACKGROUND_FINALIZE,
+        "LinearGradient",
+        JSCLASS_HAS_RESERVED_SLOTS(1) | JSCLASS_BACKGROUND_FINALIZE,
         &CairoPattern::class_ops, &CairoLinearGradient::class_spec};
 
     static cairo_pattern_t* copy_ptr(cairo_pattern_t* pattern) {
@@ -501,7 +506,7 @@ class CairoLinearGradient
     static cairo_pattern_t* constructor_impl(JSContext* cx,
                                              const JS::CallArgs& args);
 
-    static void finalize_impl(JSFreeOp*, cairo_pattern_t*) {}
+    static void finalize_impl(JS::GCContext*, cairo_pattern_t*) {}
 };
 
 class CairoRadialGradient
@@ -529,7 +534,8 @@ class CairoRadialGradient
         &CairoPattern::define_gtype_prop,
     };
     static constexpr JSClass klass = {
-        "RadialGradient", JSCLASS_HAS_PRIVATE | JSCLASS_BACKGROUND_FINALIZE,
+        "RadialGradient",
+        JSCLASS_HAS_RESERVED_SLOTS(1) | JSCLASS_BACKGROUND_FINALIZE,
         &CairoPattern::class_ops, &CairoRadialGradient::class_spec};
 
     static cairo_pattern_t* copy_ptr(cairo_pattern_t* pattern) {
@@ -540,7 +546,7 @@ class CairoRadialGradient
     static cairo_pattern_t* constructor_impl(JSContext* cx,
                                              const JS::CallArgs& args);
 
-    static void finalize_impl(JSFreeOp*, cairo_pattern_t*) {}
+    static void finalize_impl(JS::GCContext*, cairo_pattern_t*) {}
 };
 
 class CairoSurfacePattern
@@ -568,7 +574,8 @@ class CairoSurfacePattern
         &CairoPattern::define_gtype_prop,
     };
     static constexpr JSClass klass = {
-        "SurfacePattern", JSCLASS_HAS_PRIVATE | JSCLASS_BACKGROUND_FINALIZE,
+        "SurfacePattern",
+        JSCLASS_HAS_RESERVED_SLOTS(1) | JSCLASS_BACKGROUND_FINALIZE,
         &CairoPattern::class_ops, &CairoSurfacePattern::class_spec};
 
     static cairo_pattern_t* copy_ptr(cairo_pattern_t* pattern) {
@@ -579,7 +586,7 @@ class CairoSurfacePattern
     static cairo_pattern_t* constructor_impl(JSContext* cx,
                                              const JS::CallArgs& args);
 
-    static void finalize_impl(JSFreeOp*, cairo_pattern_t*) {}
+    static void finalize_impl(JS::GCContext*, cairo_pattern_t*) {}
 };
 
 class CairoSolidPattern : public CWrapper<CairoSolidPattern, cairo_pattern_t> {
@@ -605,14 +612,15 @@ class CairoSolidPattern : public CWrapper<CairoSolidPattern, cairo_pattern_t> {
         &CairoPattern::define_gtype_prop,
     };
     static constexpr JSClass klass = {
-        "SolidPattern", JSCLASS_HAS_PRIVATE | JSCLASS_BACKGROUND_FINALIZE,
+        "SolidPattern",
+        JSCLASS_HAS_RESERVED_SLOTS(1) | JSCLASS_BACKGROUND_FINALIZE,
         &CairoPattern::class_ops, &CairoSolidPattern::class_spec};
 
     static cairo_pattern_t* copy_ptr(cairo_pattern_t* pattern) {
         return cairo_pattern_reference(pattern);
     }
 
-    static void finalize_impl(JSFreeOp*, cairo_pattern_t*) {}
+    static void finalize_impl(JS::GCContext*, cairo_pattern_t*) {}
 };
 
 #endif  // MODULES_CAIRO_PRIVATE_H_
diff --git a/modules/cairo-region.cpp b/modules/cairo-region.cpp
index a6333f777..99f04b679 100644
--- a/modules/cairo-region.cpp
+++ b/modules/cairo-region.cpp
@@ -219,7 +219,7 @@ cairo_region_t* CairoRegion::constructor_impl(JSContext* context,
     return cairo_region_create();
 }
 
-void CairoRegion::finalize_impl(JSFreeOp*, cairo_region_t* region) {
+void CairoRegion::finalize_impl(JS::GCContext*, cairo_region_t* region) {
     if (!region)
         return;
 
diff --git a/modules/cairo-surface.cpp b/modules/cairo-surface.cpp
index 710e8c1bf..9c5b2914c 100644
--- a/modules/cairo-surface.cpp
+++ b/modules/cairo-surface.cpp
@@ -207,14 +207,14 @@ const JSFunctionSpec CairoSurface::proto_funcs[] = {
 
 /**
  * CairoSurface::finalize_impl:
- * @fop: the free op
+ * @gcx: the free op
  * @surface: the pointer to finalize
  *
  * Destroys the resources associated with a surface wrapper.
  *
  * This is mainly used for subclasses.
  */
-void CairoSurface::finalize_impl(JSFreeOp*, cairo_surface_t* surface) {
+void CairoSurface::finalize_impl(JS::GCContext*, cairo_surface_t* surface) {
     if (!surface)
         return;
     cairo_surface_destroy(surface);
@@ -272,7 +272,7 @@ cairo_surface_t* CairoSurface::for_js(JSContext* cx,
         return nullptr;
     }
 
-    return static_cast<cairo_surface_t*>(JS::GetPrivate(surface_wrapper));
+    return JS::GetMaybePtrFromReservedSlot<cairo_surface_t>(surface_wrapper, 0);
 }
 
 [[nodiscard]] static bool surface_to_g_argument(
diff --git a/modules/core/overrides/GObject.js b/modules/core/overrides/GObject.js
index df6f9dc27..364ff2477 100644
--- a/modules/core/overrides/GObject.js
+++ b/modules/core/overrides/GObject.js
@@ -401,7 +401,7 @@ function _init() {
     };
 
     GObject.ParamSpec.jsobject = function (name, nick, blurb, flags) {
-        return GObject.param_spec_boxed(name, nick, blurb, Object.$gtype, flags);
+        return GObject.param_spec_boxed(name, nick, blurb, GObject.TYPE_JSOBJECT, flags);
     };
 
     GObject.ParamSpec.param = function (name, nick, blurb, flags, paramType) {
diff --git a/test/gjs-test-rooting.cpp b/test/gjs-test-rooting.cpp
index 7a82f70df..a015359f0 100644
--- a/test/gjs-test-rooting.cpp
+++ b/test/gjs-test-rooting.cpp
@@ -37,8 +37,8 @@ struct GjsRootingFixture {
     GjsMaybeOwned<JSObject *> *obj;  /* only used in callback test cases */
 };
 
-static void test_obj_finalize(JSFreeOp*, JSObject* obj) {
-    bool* finalized_p = static_cast<bool*>(JS::GetPrivate(obj));
+static void test_obj_finalize(JS::GCContext*, JSObject* obj) {
+    bool* finalized_p = JS::GetMaybePtrFromReservedSlot<bool>(obj, 0);
     g_assert_false(*finalized_p);
     *finalized_p = true;
 }
@@ -53,16 +53,17 @@ static const JSClassOps test_obj_class_ops = {
     test_obj_finalize};
 
 static JSClass test_obj_class = {
-    "TestObj",
-    JSCLASS_HAS_PRIVATE | JSCLASS_FOREGROUND_FINALIZE,
-    &test_obj_class_ops
-};
+    "TestObj", JSCLASS_HAS_RESERVED_SLOTS(1) | JSCLASS_FOREGROUND_FINALIZE,
+    &test_obj_class_ops};
 
 static JSObject *
 test_obj_new(GjsRootingFixture *fx)
 {
     JSObject *retval = JS_NewObject(PARENT(fx)->cx, &test_obj_class);
-    JS::SetPrivate(retval, &fx->finalized);
+    //  // TODO: Install 0 slot
+    JS::SetReservedSlot(retval, 0, JS::PrivateValue(&fx->finalized));
+    JS::SetReservedSlot(retval, 0, JS::PrivateValue(&fx->finalized));
+
     return retval;
 }
 
@@ -145,10 +146,11 @@ static void test_maybe_owned_rooted_is_collected_after_reset(
     delete obj;
 }
 
-static void update_weak_pointer(JSContext*, JS::Compartment*, void* data) {
+static void update_weak_pointer(JSTracer* trc, JS::Compartment* comp,
+                                void* data) {
     auto* obj = static_cast<GjsMaybeOwned<JSObject*>*>(data);
     if (*obj)
-        obj->update_after_gc();
+        obj->update_after_gc(trc);
 }
 
 static void test_maybe_owned_weak_pointer_is_collected_by_gc(


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