[gjs/mozjs102: 58/59] (TODOs) js: Replace class private pointers with reserved slots




commit da6a6504c11f457128a79a332d1fb29dc0afa8ff
Author: Evan Welsh <contact evanwelsh com>
Date:   Fri Jul 22 10:52:28 2022 -0700

    (TODOs) js: Replace class private pointers with reserved slots
    
    TODO: install 0 slot?
    TODO: check if this can be implemented in mozjs91 with an open-coded
      GetMaybePtrFromReservedSlot
    TODO: write description
    TODO: remove cx argument from param_value()

 gi/boxed.cpp              |  5 ++---
 gi/cwrapper.h             | 20 +++++++++++++-------
 gi/function.cpp           | 10 ++++++----
 gi/fundamental.cpp        |  2 +-
 gi/gerror.cpp             |  2 +-
 gi/gtype.cpp              |  7 +++++--
 gi/interface.cpp          |  2 +-
 gi/ns.cpp                 |  9 +++++----
 gi/object.cpp             |  5 +++--
 gi/param.cpp              | 17 +++++++++--------
 gi/union.cpp              |  2 +-
 gi/wrapperutils.h         | 19 ++++++++++++-------
 gjs/context.cpp           |  2 +-
 gjs/module.cpp            |  8 +++++---
 modules/cairo-context.cpp |  3 ++-
 modules/cairo-path.cpp    |  5 +++--
 modules/cairo-pattern.cpp |  2 +-
 modules/cairo-private.h   | 36 ++++++++++++++++++++++--------------
 modules/cairo-surface.cpp |  2 +-
 test/gjs-test-rooting.cpp | 13 +++++++------
 20 files changed, 101 insertions(+), 70 deletions(-)
---
diff --git a/gi/boxed.cpp b/gi/boxed.cpp
index e92fffe86..c10c92eee 100644
--- a/gi/boxed.cpp
+++ b/gi/boxed.cpp
@@ -505,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;
@@ -771,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
diff --git a/gi/cwrapper.h b/gi/cwrapper.h
index dfafd6479..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);
     }
 };
 
@@ -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;
@@ -259,7 +264,8 @@ class CWrapper : public CWrapperPointerOps<Base, Wrapped> {
         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 = {
@@ -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 b3d2ac58a..d1cc5b928 100644
--- a/gi/function.cpp
+++ b/gi/function.cpp
@@ -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
@@ -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 78be6f7b4..26ac2dd76 100644
--- a/gi/fundamental.cpp
+++ b/gi/fundamental.cpp
@@ -248,7 +248,7 @@ const struct JSClassOps FundamentalBase::class_ops = {
 
 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 accfd649b..1b25c4b26 100644
--- a/gi/gtype.cpp
+++ b/gi/gtype.cpp
@@ -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 543b4c87b..e9554effc 100644
--- a/gi/interface.cpp
+++ b/gi/interface.cpp
@@ -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 97f5925e1..43b1d935f 100644
--- a/gi/ns.cpp
+++ b/gi/ns.cpp
@@ -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 9bf644080..0790a053d 100644
--- a/gi/object.cpp
+++ b/gi/object.cpp
@@ -2536,7 +2536,7 @@ const struct JSClassOps ObjectBase::class_ops = {
 
 const struct JSClass ObjectBase::klass = {
     "GObject_Object",
-    JSCLASS_HAS_PRIVATE | JSCLASS_FOREGROUND_FINALIZE,
+    JSCLASS_HAS_RESERVED_SLOTS(1) | JSCLASS_FOREGROUND_FINALIZE,
     &ObjectBase::class_ops
 };
 
@@ -2723,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/param.cpp b/gi/param.cpp
index 75de894b7..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;
 }
 
@@ -114,14 +114,15 @@ static bool gjs_param_constructor(JSContext* cx, unsigned argc, JS::Value* vp) {
 }
 
 static void param_finalize(JS::GCContext*, JSObject* obj) {
-    Param* priv = static_cast<Param*>(JS::GetPrivate(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/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 dc088281d..747e72699 100644
--- a/gi/wrapperutils.h
+++ b/gi/wrapperutils.h
@@ -409,7 +409,8 @@ class GIWrapperBase : public CWrapperPointerOps<Base> {
             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;
@@ -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;
     }
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/module.cpp b/gjs/module.cpp
index d22a35670..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;
     }
 
@@ -226,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/modules/cairo-context.cpp b/modules/cairo-context.cpp
index 09414f1bc..762b74e48 100644
--- a/modules/cairo-context.cpp
+++ b/modules/cairo-context.cpp
@@ -363,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 b6b3945b2..2ae3f72b5 100644
--- a/modules/cairo-path.cpp
+++ b/modules/cairo-path.cpp
@@ -38,8 +38,9 @@ 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");
 
diff --git a/modules/cairo-pattern.cpp b/modules/cairo-pattern.cpp
index 3280d0316..4135cad26 100644
--- a/modules/cairo-pattern.cpp
+++ b/modules/cairo-pattern.cpp
@@ -135,5 +135,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 9c14afe16..8f59e2f3e 100644
--- a/modules/cairo-private.h
+++ b/modules/cairo-private.h
@@ -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};
 };
 
@@ -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};
 };
 
@@ -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:
@@ -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,7 +229,8 @@ 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) {
@@ -268,7 +269,8 @@ 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) {
@@ -313,7 +315,8 @@ 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) {
@@ -358,7 +361,8 @@ 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) {
@@ -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; }
@@ -459,7 +463,7 @@ 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(JS::GCContext*, cairo_pattern_t*) {}
@@ -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) {
@@ -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) {
@@ -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) {
@@ -605,7 +612,8 @@ 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) {
diff --git a/modules/cairo-surface.cpp b/modules/cairo-surface.cpp
index c4e1932e0..7c4663df2 100644
--- a/modules/cairo-surface.cpp
+++ b/modules/cairo-surface.cpp
@@ -271,7 +271,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/test/gjs-test-rooting.cpp b/test/gjs-test-rooting.cpp
index 37946e855..8044dd763 100644
--- a/test/gjs-test-rooting.cpp
+++ b/test/gjs-test-rooting.cpp
@@ -38,7 +38,7 @@ struct GjsRootingFixture {
 };
 
 static void test_obj_finalize(JS::GCContext*, JSObject* obj) {
-    bool* finalized_p = static_cast<bool*>(JS::GetPrivate(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;
 }
 


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