[gjs: 2/4] Use standard allocator for JS private data




commit 3aa7c4286101b16651c91d0f373ca32c89252052
Author: Marco Trevisan (TreviƱo) <mail 3v1n0 net>
Date:   Tue Nov 26 11:12:09 2019 -0800

    Use standard allocator for JS private data
    
    It will allows to get memory counters working
    
    Also requires initializing all the private data structs in their
    constructors

 gi/ns.cpp                 |  28 +++++-------
 gi/param.cpp              |  23 ++++++----
 gi/repo.cpp               |  14 ++----
 gi/wrapperutils.h         |   3 +-
 gjs/importer.cpp          |  19 ++++-----
 modules/cairo-context.cpp | 106 ++++++++++++++++++++--------------------------
 modules/cairo-path.cpp    |  21 +++++----
 modules/cairo-pattern.cpp |  16 ++++---
 modules/cairo-region.cpp  |  34 +++++++++------
 modules/cairo-surface.cpp |  16 ++++---
 10 files changed, 137 insertions(+), 143 deletions(-)
---
diff --git a/gi/ns.cpp b/gi/ns.cpp
index 422aba34..cb90913d 100644
--- a/gi/ns.cpp
+++ b/gi/ns.cpp
@@ -26,9 +26,10 @@
 #include "gjs/mem-private.h"
 #include "util/log.h"
 
-typedef struct {
-    char *gi_namespace;
-} Ns;
+struct Ns : GjsAutoChar {
+    explicit Ns(const char* ns_name)
+        : GjsAutoChar(const_cast<char*>(ns_name), GjsAutoTakeOwnership()) {}
+};
 
 extern struct JSClass gjs_ns_class;
 
@@ -77,7 +78,7 @@ ns_resolve(JSContext       *context,
     }
 
     GjsAutoBaseInfo info =
-        g_irepository_find_by_name(nullptr, priv->gi_namespace, name.get());
+        g_irepository_find_by_name(nullptr, priv->get(), name.get());
     if (!info) {
         *resolved = false; /* No property defined, but no error either */
         return true;
@@ -108,15 +109,14 @@ static bool ns_new_enumerate(JSContext* cx, JS::HandleObject obj,
         return true;
     }
 
-    int n = g_irepository_get_n_infos(nullptr, priv->gi_namespace);
+    int n = g_irepository_get_n_infos(nullptr, priv->get());
     if (!properties.reserve(properties.length() + n)) {
         JS_ReportOutOfMemory(cx);
         return false;
     }
 
     for (int k = 0; k < n; k++) {
-        GjsAutoBaseInfo info =
-            g_irepository_get_info(nullptr, priv->gi_namespace, k);
+        GjsAutoBaseInfo info = g_irepository_get_info(nullptr, priv->get(), k);
         const char* name = info.name();
 
         jsid id = gjs_intern_string_to_id(cx, name);
@@ -139,7 +139,7 @@ get_name (JSContext *context,
     if (!priv)
         return false;
 
-    return gjs_string_from_utf8(context, priv->gi_namespace, args.rval());
+    return gjs_string_from_utf8(context, priv->get(), args.rval());
 }
 
 GJS_NATIVE_CONSTRUCTOR_DEFINE_ABSTRACT(ns)
@@ -153,11 +153,8 @@ static void ns_finalize(JSFreeOp*, JSObject* obj) {
     if (!priv)
         return; /* we are the prototype, not a real instance */
 
-    if (priv->gi_namespace)
-        g_free(priv->gi_namespace);
-
     GJS_DEC_COUNTER(ns);
-    g_free(priv);
+    delete priv;
 }
 
 /* The bizarre thing about this vtable is that it applies to both
@@ -197,8 +194,6 @@ static JSObject*
 ns_new(JSContext    *context,
        const char   *ns_name)
 {
-    Ns *priv;
-
     JS::RootedObject proto(context);
     if (!gjs_ns_define_proto(context, nullptr, &proto))
         return nullptr;
@@ -208,8 +203,7 @@ ns_new(JSContext    *context,
     if (!ns)
         return nullptr;
 
-    priv = g_new0(Ns, 1);
-
+    auto* priv = new Ns(ns_name);
     GJS_INC_COUNTER(ns);
 
     g_assert(!priv_from_js(context, ns));
@@ -218,8 +212,6 @@ ns_new(JSContext    *context,
     gjs_debug_lifecycle(GJS_DEBUG_GNAMESPACE, "ns constructor, obj %p priv %p",
                         ns.get(), priv);
 
-    priv = priv_from_js(context, ns);
-    priv->gi_namespace = g_strdup(ns_name);
     return ns;
 }
 
diff --git a/gi/param.cpp b/gi/param.cpp
index b44d2a70..5f96cc8e 100644
--- a/gi/param.cpp
+++ b/gi/param.cpp
@@ -28,7 +28,12 @@
 
 extern struct JSClass gjs_param_class;
 
-GJS_DEFINE_PRIV_FROM_JS(GParamSpec, gjs_param_class)
+struct Param : GjsAutoParam {
+    explicit Param(GParamSpec* param)
+        : GjsAutoParam(param, GjsAutoTakeOwnership()) {}
+};
+
+GJS_DEFINE_PRIV_FROM_JS(Param, gjs_param_class)
 
 /*
  * The *resolved out parameter, on success, should be false to indicate that id
@@ -91,14 +96,15 @@ GJS_NATIVE_CONSTRUCTOR_DECLARE(param)
 }
 
 static void param_finalize(JSFreeOp*, JSObject* obj) {
-    GjsAutoParam param = static_cast<GParamSpec*>(JS_GetPrivate(obj));
+    Param* priv = static_cast<Param*>(JS_GetPrivate(obj));
     gjs_debug_lifecycle(GJS_DEBUG_GPARAM, "finalize, obj %p priv %p", obj,
-                        param.get());
-    if (!param)
+                        priv);
+    if (!priv)
         return; /* wrong class? */
 
     GJS_DEC_COUNTER(param);
     JS_SetPrivate(obj, nullptr);
+    delete priv;
 }
 
 
@@ -212,8 +218,8 @@ gjs_param_from_g_param(JSContext    *context,
     obj = JS_NewObjectWithGivenProto(context, JS_GetClass(proto), proto);
 
     GJS_INC_COUNTER(param);
-    JS_SetPrivate(obj, gparam);
-    g_param_spec_ref (gparam);
+    auto* priv = new Param(gparam);
+    JS_SetPrivate(obj, priv);
 
     gjs_debug(GJS_DEBUG_GPARAM,
               "JSObject created with param instance %p type %s", gparam,
@@ -229,7 +235,8 @@ gjs_g_param_from_param(JSContext       *context,
     if (!obj)
         return nullptr;
 
-    return priv_from_js(context, obj);
+    auto* priv = priv_from_js(context, obj);
+    return priv ? priv->get() : nullptr;
 }
 
 bool
@@ -243,7 +250,7 @@ gjs_typecheck_param(JSContext       *context,
     if (!do_base_typecheck(context, object, throw_error))
         return false;
 
-    GParamSpec* param = priv_from_js(context, object);
+    GParamSpec* param = gjs_g_param_from_param(context, object);
 
     if (!param) {
         if (throw_error) {
diff --git a/gi/repo.cpp b/gi/repo.cpp
index ed725ca6..ca42bf15 100644
--- a/gi/repo.cpp
+++ b/gi/repo.cpp
@@ -44,13 +44,10 @@
 #include "gjs/mem-private.h"
 #include "util/log.h"
 
-typedef struct {
-    void *dummy;
-
-} Repo;
-
 extern struct JSClass gjs_repo_class;
 
+struct Repo {};
+
 GJS_DEFINE_PRIV_FROM_JS(Repo, gjs_repo_class)
 
 GJS_JSAPI_RETURN_CONVENTION
@@ -209,7 +206,7 @@ static void repo_finalize(JSFreeOp*, JSObject* obj) {
         return; /* we are the prototype, not a real instance */
 
     GJS_DEC_COUNTER(repo);
-    g_free(priv);
+    delete priv;
 }
 
 /* The bizarre thing about this vtable is that it applies to both
@@ -246,8 +243,6 @@ GJS_JSAPI_RETURN_CONVENTION
 static JSObject*
 repo_new(JSContext *context)
 {
-    Repo *priv;
-
     JS::RootedObject proto(context);
     if (!gjs_repo_define_proto(context, nullptr, &proto))
         return nullptr;
@@ -257,8 +252,7 @@ repo_new(JSContext *context)
     if (repo == nullptr)
         return nullptr;
 
-    priv = g_new0(Repo, 1);
-
+    auto* priv = new Repo();
     GJS_INC_COUNTER(repo);
 
     g_assert(priv_from_js(context, repo) == NULL);
diff --git a/gi/wrapperutils.h b/gi/wrapperutils.h
index def68332..93b7df4a 100644
--- a/gi/wrapperutils.h
+++ b/gi/wrapperutils.h
@@ -10,7 +10,6 @@
 
 #include <stdint.h>
 
-#include <new>
 #include <string>
 
 #include <girepository.h>
@@ -1027,7 +1026,7 @@ class GIWrapperInstance : public Base {
     Wrapped* m_ptr = nullptr;
 
     explicit GIWrapperInstance(JSContext* cx, JS::HandleObject obj)
-        : Base(Prototype::for_js_prototype(cx, obj)) {
+        : Base(Prototype::for_js_prototype(cx, obj)), m_ptr(nullptr) {
         Base::m_proto->acquire();
         Base::GIWrapperBase::debug_lifecycle(obj, "Instance constructor");
     }
diff --git a/gjs/importer.cpp b/gjs/importer.cpp
index efa55261..6cdfd11d 100644
--- a/gjs/importer.cpp
+++ b/gjs/importer.cpp
@@ -47,17 +47,18 @@
 
 #define MODULE_INIT_FILENAME "__init__.js"
 
-typedef struct {
-    bool is_root;
-} Importer;
-
 extern const JSClass gjs_importer_class;
 
-GJS_DEFINE_PRIV_FROM_JS(Importer, gjs_importer_class)
+struct Importer {
+    explicit Importer(bool root) : is_root(root) {}
+
+    bool is_root : 1;
+};
 
 GJS_JSAPI_RETURN_CONVENTION
 static JSObject* gjs_define_importer(JSContext*, JS::HandleObject, const char*,
                                      const std::vector<std::string>&, bool);
+GJS_DEFINE_PRIV_FROM_JS(Importer, gjs_importer_class)
 
 GJS_JSAPI_RETURN_CONVENTION
 static bool
@@ -769,7 +770,7 @@ static void importer_finalize(JSFreeOp*, JSObject* obj) {
         return; /* we are the prototype, not a real instance */
 
     GJS_DEC_COUNTER(importer);
-    g_free(priv);
+    delete priv;
 }
 
 /* The bizarre thing about this vtable is that it applies to both
@@ -809,8 +810,6 @@ static JSObject*
 importer_new(JSContext *context,
              bool       is_root)
 {
-    Importer *priv;
-
     JS::RootedObject proto(context);
     if (!gjs_importer_define_proto(context, nullptr, &proto))
         return nullptr;
@@ -820,9 +819,7 @@ importer_new(JSContext *context,
     if (!importer)
         return nullptr;
 
-    priv = g_new0(Importer, 1);
-    priv->is_root = is_root;
-
+    auto* priv = new Importer(is_root);
     GJS_INC_COUNTER(importer);
 
     g_assert(priv_from_js(context, importer) == NULL);
diff --git a/modules/cairo-context.cpp b/modules/cairo-context.cpp
index a8049b1c..bc6176ae 100644
--- a/modules/cairo-context.cpp
+++ b/modules/cairo-context.cpp
@@ -33,13 +33,19 @@
 #include "gjs/macros.h"
 #include "modules/cairo-private.h"
 
-#define _GJS_CAIRO_CONTEXT_DEFINE_FUNC_BEGIN(mname)              \
-    GJS_JSAPI_RETURN_CONVENTION                                  \
-    static bool mname##_func(JSContext* context, unsigned argc,  \
-                             JS::Value* vp) {                    \
-        GJS_GET_PRIV(context, argc, vp, argv, obj, cairo_t, cr); \
-        if (!cr)                                                 \
-            return true;
+struct GjsCairoContext;
+
+#define _GJS_CAIRO_CONTEXT_GET_PRIV_CR_CHECKED(cx, argc, vp, argv, obj) \
+    GJS_GET_PRIV(context, argc, vp, argv, obj, GjsCairoContext, priv);  \
+    cairo_t* cr = priv->get();                                          \
+    if (!cr)                                                            \
+        return true;
+
+#define _GJS_CAIRO_CONTEXT_DEFINE_FUNC_BEGIN(mname)             \
+    GJS_JSAPI_RETURN_CONVENTION                                 \
+    static bool mname##_func(JSContext* context, unsigned argc, \
+                             JS::Value* vp) {                   \
+        _GJS_CAIRO_CONTEXT_GET_PRIV_CR_CHECKED(context, argc, vp, argv, obj)
 
 #define _GJS_CAIRO_CONTEXT_DEFINE_FUNC_END                               \
     return gjs_cairo_check_status(context, cairo_status(cr), "context"); \
@@ -243,14 +249,22 @@ _GJS_CAIRO_CONTEXT_DEFINE_FUNC_END
 
 [[nodiscard]] static JSObject* gjs_cairo_context_get_proto(JSContext*);
 
+struct GjsCairoContext
+    : GjsAutoPointer<cairo_t, cairo_t, cairo_destroy, cairo_reference> {
+    explicit GjsCairoContext(cairo_t* cr)
+        : GjsAutoPointer(cr, GjsAutoTakeOwnership()) {}
+};
+
 GJS_DEFINE_PROTO_WITH_GTYPE("Context", cairo_context,
                             CAIRO_GOBJECT_TYPE_CONTEXT,
                             JSCLASS_BACKGROUND_FINALIZE)
-GJS_DEFINE_PRIV_FROM_JS(cairo_t, gjs_cairo_context_class);
+GJS_DEFINE_PRIV_FROM_JS(GjsCairoContext, gjs_cairo_context_class);
 
-static void _gjs_cairo_context_construct_internal(JSObject* obj, cairo_t* cr) {
-    g_assert(!JS_GetPrivate(obj));
-    JS_SetPrivate(obj, cairo_reference(cr));
+static void _gjs_cairo_context_construct_internal(JSContext* context,
+                                                  JS::HandleObject obj,
+                                                  cairo_t* cr) {
+    g_assert(!priv_from_js(context, obj));
+    JS_SetPrivate(obj, new GjsCairoContext(cr));
 }
 
 GJS_NATIVE_CONSTRUCTOR_DECLARE(cairo_context)
@@ -275,7 +289,7 @@ GJS_NATIVE_CONSTRUCTOR_DECLARE(cairo_context)
     if (!gjs_cairo_check_status(context, cairo_status(cr), "context"))
         return false;
 
-    _gjs_cairo_context_construct_internal(object, cr);
+    _gjs_cairo_context_construct_internal(context, object, cr);
     cairo_destroy(cr);
 
     GJS_NATIVE_CONSTRUCTOR_FINISH(cairo_context);
@@ -284,8 +298,7 @@ GJS_NATIVE_CONSTRUCTOR_DECLARE(cairo_context)
 }
 
 static void gjs_cairo_context_finalize(JSFreeOp*, JSObject* obj) {
-    using AutoCairoContext = GjsAutoPointer<cairo_t, cairo_t, cairo_destroy>;
-    AutoCairoContext cr = static_cast<cairo_t*>(JS_GetPrivate(obj));
+    delete static_cast<GjsCairoContext*>(JS_GetPrivate(obj));
     JS_SetPrivate(obj, nullptr);
 }
 
@@ -381,9 +394,7 @@ dispose_func(JSContext *context,
              unsigned   argc,
              JS::Value *vp)
 {
-    GJS_GET_PRIV(context, argc, vp, rec, obj, cairo_t, cr);
-    if (!cr)
-        return true;
+    _GJS_CAIRO_CONTEXT_GET_PRIV_CR_CHECKED(context, argc, vp, rec, obj);
 
     cairo_destroy(cr);
     JS_SetPrivate(obj, nullptr);
@@ -398,9 +409,7 @@ appendPath_func(JSContext *context,
                 unsigned   argc,
                 JS::Value *vp)
 {
-    GJS_GET_PRIV(context, argc, vp, argv, obj, cairo_t, cr);
-    if (!cr)
-        return true;
+    _GJS_CAIRO_CONTEXT_GET_PRIV_CR_CHECKED(context, argc, vp, argv, obj);
 
     JS::RootedObject path_wrapper(context);
 
@@ -423,9 +432,7 @@ copyPath_func(JSContext *context,
               unsigned   argc,
               JS::Value *vp)
 {
-    GJS_GET_PRIV(context, argc, vp, argv, obj, cairo_t, cr);
-    if (!cr)
-        return true;
+    _GJS_CAIRO_CONTEXT_GET_PRIV_CR_CHECKED(context, argc, vp, argv, obj);
 
     cairo_path_t *path;
 
@@ -443,9 +450,7 @@ copyPathFlat_func(JSContext *context,
                   unsigned   argc,
                   JS::Value *vp)
 {
-    GJS_GET_PRIV(context, argc, vp, argv, obj, cairo_t, cr);
-    if (!cr)
-        return true;
+    _GJS_CAIRO_CONTEXT_GET_PRIV_CR_CHECKED(context, argc, vp, argv, obj);
 
     cairo_path_t *path;
 
@@ -463,9 +468,7 @@ mask_func(JSContext *context,
           unsigned   argc,
           JS::Value *vp)
 {
-    GJS_GET_PRIV(context, argc, vp, argv, obj, cairo_t, cr);
-    if (!cr)
-        return true;
+    _GJS_CAIRO_CONTEXT_GET_PRIV_CR_CHECKED(context, argc, vp, argv, obj);
 
     JS::RootedObject pattern_wrapper(context);
 
@@ -493,9 +496,7 @@ maskSurface_func(JSContext *context,
                  unsigned   argc,
                  JS::Value *vp)
 {
-    GJS_GET_PRIV(context, argc, vp, argv, obj, cairo_t, cr);
-    if (!cr)
-        return true;
+    _GJS_CAIRO_CONTEXT_GET_PRIV_CR_CHECKED(context, argc, vp, argv, obj);
 
     JS::RootedObject surface_wrapper(context);
     double x, y;
@@ -526,9 +527,7 @@ setDash_func(JSContext *context,
              unsigned   argc,
              JS::Value *vp)
 {
-    GJS_GET_PRIV(context, argc, vp, argv, obj, cairo_t, cr);
-    if (!cr)
-        return true;
+    _GJS_CAIRO_CONTEXT_GET_PRIV_CR_CHECKED(context, argc, vp, argv, obj);
 
     guint i;
     JS::RootedObject dashes(context);
@@ -587,9 +586,7 @@ setSource_func(JSContext *context,
                unsigned   argc,
                JS::Value *vp)
 {
-    GJS_GET_PRIV(context, argc, vp, argv, obj, cairo_t, cr);
-    if (!cr)
-        return true;
+    _GJS_CAIRO_CONTEXT_GET_PRIV_CR_CHECKED(context, argc, vp, argv, obj);
 
     JS::RootedObject pattern_wrapper(context);
 
@@ -618,9 +615,7 @@ setSourceSurface_func(JSContext *context,
                       unsigned   argc,
                       JS::Value *vp)
 {
-    GJS_GET_PRIV(context, argc, vp, argv, obj, cairo_t, cr);
-    if (!cr)
-        return true;
+    _GJS_CAIRO_CONTEXT_GET_PRIV_CR_CHECKED(context, argc, vp, argv, obj);
 
     JS::RootedObject surface_wrapper(context);
     double x, y;
@@ -652,9 +647,7 @@ showText_func(JSContext *context,
               unsigned   argc,
               JS::Value *vp)
 {
-    GJS_GET_PRIV(context, argc, vp, argv, obj, cairo_t, cr);
-    if (!cr)
-        return true;
+    _GJS_CAIRO_CONTEXT_GET_PRIV_CR_CHECKED(context, argc, vp, argv, obj);
 
     JS::UniqueChars utf8;
 
@@ -678,9 +671,7 @@ selectFontFace_func(JSContext *context,
                     unsigned   argc,
                     JS::Value *vp)
 {
-    GJS_GET_PRIV(context, argc, vp, argv, obj, cairo_t, cr);
-    if (!cr)
-        return true;
+    _GJS_CAIRO_CONTEXT_GET_PRIV_CR_CHECKED(context, argc, vp, argv, obj);
 
     JS::UniqueChars family;
     cairo_font_slant_t slant;
@@ -707,9 +698,7 @@ popGroup_func(JSContext *context,
               unsigned   argc,
               JS::Value *vp)
 {
-    GJS_GET_PRIV(context, argc, vp, rec, obj, cairo_t, cr);
-    if (!cr)
-        return true;
+    _GJS_CAIRO_CONTEXT_GET_PRIV_CR_CHECKED(context, argc, vp, rec, obj);
 
     cairo_pattern_t *pattern;
     JSObject *pattern_wrapper;
@@ -740,9 +729,7 @@ getSource_func(JSContext *context,
                unsigned   argc,
                JS::Value *vp)
 {
-    GJS_GET_PRIV(context, argc, vp, rec, obj, cairo_t, cr);
-    if (!cr)
-        return true;
+    _GJS_CAIRO_CONTEXT_GET_PRIV_CR_CHECKED(context, argc, vp, rec, obj);
 
     cairo_pattern_t *pattern;
     JSObject *pattern_wrapper;
@@ -774,9 +761,7 @@ getTarget_func(JSContext *context,
                unsigned   argc,
                JS::Value *vp)
 {
-    GJS_GET_PRIV(context, argc, vp, rec, obj, cairo_t, cr);
-    if (!cr)
-        return true;
+    _GJS_CAIRO_CONTEXT_GET_PRIV_CR_CHECKED(context, argc, vp, rec, obj);
 
     cairo_surface_t *surface;
     JSObject *surface_wrapper;
@@ -808,9 +793,7 @@ getGroupTarget_func(JSContext *context,
                     unsigned   argc,
                     JS::Value *vp)
 {
-    GJS_GET_PRIV(context, argc, vp, rec, obj, cairo_t, cr);
-    if (!cr)
-        return true;
+    _GJS_CAIRO_CONTEXT_GET_PRIV_CR_CHECKED(context, argc, vp, rec, obj);
 
     cairo_surface_t *surface;
     JSObject *surface_wrapper;
@@ -949,7 +932,7 @@ gjs_cairo_context_from_context(JSContext *context,
     if (!object)
         return nullptr;
 
-    _gjs_cairo_context_construct_internal(object, cr);
+    _gjs_cairo_context_construct_internal(context, object, cr);
 
     return object;
 }
@@ -958,7 +941,8 @@ cairo_t *
 gjs_cairo_context_get_context(JSContext       *context,
                               JS::HandleObject object)
 {
-    return priv_from_js(context, object);
+    auto* priv = priv_from_js(context, object);
+    return priv ? priv->get() : nullptr;
 }
 
 [[nodiscard]] static bool context_to_g_argument(
diff --git a/modules/cairo-path.cpp b/modules/cairo-path.cpp
index cbd4317a..36dbc1b4 100644
--- a/modules/cairo-path.cpp
+++ b/modules/cairo-path.cpp
@@ -19,12 +19,16 @@
 
 [[nodiscard]] static JSObject* gjs_cairo_path_get_proto(JSContext*);
 
+struct GjsCairoPath
+    : GjsAutoPointer<cairo_path_t, cairo_path_t, cairo_path_destroy> {
+    explicit GjsCairoPath(cairo_path_t* path) : GjsAutoPointer(path) {}
+};
+
 GJS_DEFINE_PROTO_ABSTRACT("Path", cairo_path, JSCLASS_BACKGROUND_FINALIZE)
+GJS_DEFINE_PRIV_FROM_JS(GjsCairoPath, gjs_cairo_path_class);
 
 static void gjs_cairo_path_finalize(JSFreeOp*, JSObject* obj) {
-    using AutoCairoPath =
-        GjsAutoPointer<cairo_path_t, cairo_path_t, cairo_path_destroy>;
-    AutoCairoPath path = static_cast<cairo_path_t*>(JS_GetPrivate(obj));
+    delete static_cast<GjsCairoPath*>(JS_GetPrivate(obj));
     JS_SetPrivate(obj, nullptr);
 }
 
@@ -64,8 +68,8 @@ gjs_cairo_path_from_path(JSContext    *context,
         return nullptr;
     }
 
-    g_assert(!JS_GetPrivate(object));
-    JS_SetPrivate(object, path);
+    g_assert(!priv_from_js(context, object));
+    JS_SetPrivate(object, new GjsCairoPath(path));
 
     return object;
 }
@@ -82,13 +86,12 @@ cairo_path_t* gjs_cairo_path_get_path(JSContext* cx,
     g_return_val_if_fail(cx, nullptr);
     g_return_val_if_fail(path_wrapper, nullptr);
 
-    auto* path = static_cast<cairo_path_t*>(JS_GetInstancePrivate(
-        cx, path_wrapper, &gjs_cairo_path_class, nullptr));
-    if (!path) {
+    GjsCairoPath* priv;
+    if (!priv_from_js_with_typecheck(cx, path_wrapper, &priv)) {
         gjs_throw(cx, "Expected Cairo.Path but got %s",
                   JS_GetClass(path_wrapper)->name);
         return nullptr;
     }
 
-    return path;
+    return priv->get();
 }
diff --git a/modules/cairo-pattern.cpp b/modules/cairo-pattern.cpp
index f200f572..96e594d0 100644
--- a/modules/cairo-pattern.cpp
+++ b/modules/cairo-pattern.cpp
@@ -21,14 +21,19 @@
 #include "gjs/macros.h"
 #include "modules/cairo-private.h"
 
+struct GjsCairoPattern
+    : GjsAutoPointer<cairo_pattern_t, cairo_pattern_t, cairo_pattern_destroy,
+                     cairo_pattern_reference> {
+    explicit GjsCairoPattern(cairo_pattern_t* pattern)
+        : GjsAutoPointer(pattern, GjsAutoTakeOwnership()) {}
+};
+
 GJS_DEFINE_PROTO_ABSTRACT_WITH_GTYPE("Pattern", cairo_pattern,
                                      CAIRO_GOBJECT_TYPE_PATTERN,
                                      JSCLASS_BACKGROUND_FINALIZE)
 
 static void gjs_cairo_pattern_finalize(JSFreeOp*, JSObject* obj) {
-    using AutoPattern =
-        GjsAutoPointer<cairo_pattern_t, cairo_pattern_t, cairo_pattern_destroy>;
-    AutoPattern pattern = static_cast<cairo_pattern_t*>(JS_GetPrivate(obj));
+    delete static_cast<GjsCairoPattern*>(JS_GetPrivate(obj));
     JS_SetPrivate(obj, nullptr);
 }
 
@@ -90,7 +95,7 @@ void gjs_cairo_pattern_construct(JSObject* object, cairo_pattern_t* pattern) {
     g_return_if_fail(pattern);
 
     g_assert(!JS_GetPrivate(object));
-    JS_SetPrivate(object, cairo_pattern_reference(pattern));
+    JS_SetPrivate(object, new GjsCairoPattern(pattern));
 }
 
 /**
@@ -172,5 +177,6 @@ cairo_pattern_t* gjs_cairo_pattern_get_pattern(
         return nullptr;
     }
 
-    return static_cast<cairo_pattern_t*>(JS_GetPrivate(pattern_wrapper));
+    auto* priv = static_cast<GjsCairoPattern*>(JS_GetPrivate(pattern_wrapper));
+    return priv ? priv->get() : nullptr;
 }
diff --git a/modules/cairo-region.cpp b/modules/cairo-region.cpp
index effc0724..ff9e1893 100644
--- a/modules/cairo-region.cpp
+++ b/modules/cairo-region.cpp
@@ -32,16 +32,24 @@
 
 [[nodiscard]] static JSObject* gjs_cairo_region_get_proto(JSContext*);
 
+struct GjsCairoRegion
+    : GjsAutoPointer<cairo_region_t, cairo_region_t, cairo_region_destroy,
+                     cairo_region_reference> {
+    explicit GjsCairoRegion(cairo_region_t* region)
+        : GjsAutoPointer(region, GjsAutoTakeOwnership()) {}
+};
+
 GJS_DEFINE_PROTO_WITH_GTYPE("Region", cairo_region,
                             CAIRO_GOBJECT_TYPE_REGION,
                             JSCLASS_BACKGROUND_FINALIZE)
+GJS_DEFINE_PRIV_FROM_JS(GjsCairoRegion, gjs_cairo_region_class);
 
 static cairo_region_t *
 get_region(JSContext       *context,
            JS::HandleObject obj)
 {
-    return static_cast<cairo_region_t*>(
-        JS_GetInstancePrivate(context, obj, &gjs_cairo_region_class, nullptr));
+    auto* priv = priv_from_js(context, obj);
+    return priv ? priv->get() : nullptr;
 }
 
 GJS_JSAPI_RETURN_CONVENTION
@@ -50,10 +58,9 @@ fill_rectangle(JSContext             *context,
                JS::HandleObject       obj,
                cairo_rectangle_int_t *rect);
 
-#define PRELUDE                                                             \
-    GJS_GET_THIS(context, argc, vp, argv, obj);                             \
-    auto* this_region = static_cast<cairo_region_t*>(JS_GetInstancePrivate( \
-        context, obj, &gjs_cairo_region_class, nullptr));
+#define PRELUDE                                 \
+    GJS_GET_THIS(context, argc, vp, argv, obj); \
+    auto* this_region = get_region(context, obj);
 
 #define RETURN_STATUS                                           \
     return gjs_cairo_check_status(context, cairo_region_status(this_region), "region");
@@ -228,10 +235,11 @@ JSFunctionSpec gjs_cairo_region_proto_funcs[] = {
 
 JSFunctionSpec gjs_cairo_region_static_funcs[] = { JS_FS_END };
 
-static void _gjs_cairo_region_construct_internal(JSObject* obj,
+static void _gjs_cairo_region_construct_internal(JSContext* context,
+                                                 JS::HandleObject obj,
                                                  cairo_region_t* region) {
-    g_assert(!JS_GetPrivate(obj));
-    JS_SetPrivate(obj, cairo_region_reference(region));
+    g_assert(!priv_from_js(context, obj));
+    JS_SetPrivate(obj, new GjsCairoRegion(region));
 }
 
 GJS_NATIVE_CONSTRUCTOR_DECLARE(cairo_region)
@@ -246,7 +254,7 @@ GJS_NATIVE_CONSTRUCTOR_DECLARE(cairo_region)
 
     region = cairo_region_create();
 
-    _gjs_cairo_region_construct_internal(object, region);
+    _gjs_cairo_region_construct_internal(context, object, region);
     cairo_region_destroy(region);
 
     GJS_NATIVE_CONSTRUCTOR_FINISH(cairo_region);
@@ -255,9 +263,7 @@ GJS_NATIVE_CONSTRUCTOR_DECLARE(cairo_region)
 }
 
 static void gjs_cairo_region_finalize(JSFreeOp*, JSObject* obj) {
-    using AutoCairoRegion =
-        GjsAutoPointer<cairo_region_t, cairo_region_t, cairo_region_destroy>;
-    AutoCairoRegion region = static_cast<cairo_region_t*>(JS_GetPrivate(obj));
+    delete static_cast<GjsCairoRegion*>(JS_GetPrivate(obj));
     JS_SetPrivate(obj, nullptr);
 }
 
@@ -272,7 +278,7 @@ gjs_cairo_region_from_region(JSContext *context,
     if (!object)
         return nullptr;
 
-    _gjs_cairo_region_construct_internal(object, region);
+    _gjs_cairo_region_construct_internal(context, object, region);
 
     return object;
 }
diff --git a/modules/cairo-surface.cpp b/modules/cairo-surface.cpp
index 0f0f1f5d..e6bdbc55 100644
--- a/modules/cairo-surface.cpp
+++ b/modules/cairo-surface.cpp
@@ -27,14 +27,19 @@
 #include "gjs/macros.h"
 #include "modules/cairo-private.h"
 
+struct GjsCairoSurface
+    : GjsAutoPointer<cairo_surface_t, cairo_surface_t, cairo_surface_destroy,
+                     cairo_surface_reference> {
+    explicit GjsCairoSurface(cairo_surface_t* surface)
+        : GjsAutoPointer(surface, GjsAutoTakeOwnership()) {}
+};
+
 GJS_DEFINE_PROTO_ABSTRACT_WITH_GTYPE("Surface", cairo_surface,
                                      CAIRO_GOBJECT_TYPE_SURFACE,
                                      JSCLASS_BACKGROUND_FINALIZE)
 
 static void gjs_cairo_surface_finalize(JSFreeOp*, JSObject* obj) {
-    using AutoSurface =
-        GjsAutoPointer<cairo_surface_t, cairo_surface_t, cairo_surface_destroy>;
-    AutoSurface surface = static_cast<cairo_surface_t*>(JS_GetPrivate(obj));
+    delete static_cast<GjsCairoSurface*>(JS_GetPrivate(obj));
     JS_SetPrivate(obj, nullptr);
 }
 
@@ -134,7 +139,7 @@ void gjs_cairo_surface_construct(JSObject* object, cairo_surface_t* surface) {
     g_return_if_fail(surface);
 
     g_assert(!JS_GetPrivate(object));
-    JS_SetPrivate(object, cairo_surface_reference(surface));
+    JS_SetPrivate(object, new GjsCairoSurface(surface));
 }
 
 /**
@@ -219,7 +224,8 @@ cairo_surface_t* gjs_cairo_surface_get_surface(
         return nullptr;
     }
 
-    return static_cast<cairo_surface_t*>(JS_GetPrivate(surface_wrapper));
+    auto* priv = static_cast<GjsCairoSurface*>(JS_GetPrivate(surface_wrapper));
+    return priv ? priv->get() : nullptr;
 }
 
 [[nodiscard]] static bool surface_to_g_argument(


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