[gjs: 5/9] gerror: Split private struct into ErrorPrototype/ErrorInstance



commit 603b695aa92ea07fe929af341089d023f4270b30
Author: Philip Chimento <philip chimento gmail com>
Date:   Mon Dec 10 22:00:15 2018 -0800

    gerror: Split private struct into ErrorPrototype/ErrorInstance
    
    This continues the ports of GObject introspection wrappers to the new
    framework introduced in wrapperutils.h.
    
    As part of being ported to the new code, GError objects now gain a
    $gtype property, as all the rest of the GObject introspection wrappers
    have. This property will always be equal to G_TYPE_ERROR.

 gi/gerror.cpp     | 332 ++++++++++++++++++------------------------------------
 gi/gerror.h       | 101 +++++++++++++++++
 gjs/mem-private.h |   3 +-
 gjs/mem.cpp       |   6 +-
 4 files changed, 216 insertions(+), 226 deletions(-)
---
diff --git a/gi/gerror.cpp b/gi/gerror.cpp
index f7c28ed4..7501de4a 100644
--- a/gi/gerror.cpp
+++ b/gi/gerror.cpp
@@ -39,62 +39,40 @@
 
 #include <girepository.h>
 
-typedef struct {
-    GIEnumInfo *info;
-    GQuark domain;
-    GError *gerror; /* NULL if we are the prototype and not an instance */
-} Error;
-
-extern struct JSClass gjs_error_class;
-
-GJS_DEFINE_PRIV_FROM_JS(Error, gjs_error_class)
-
-GJS_NATIVE_CONSTRUCTOR_DECLARE(error)
-{
-    GJS_NATIVE_CONSTRUCTOR_VARIABLES(error)
-    Error *priv;
-    Error *proto_priv;
-    int32_t code;
-
-    /* Check early to avoid allocating memory for nothing */
-    if (argc != 1 || !argv[0].isObject()) {
-        gjs_throw(context, "Invalid parameters passed to GError constructor, expected one object");
-        return false;
-    }
-
-    GJS_NATIVE_CONSTRUCTOR_PRELUDE(error);
-
-    priv = g_slice_new0(Error);
+ErrorPrototype::ErrorPrototype(GIEnumInfo* info, GType gtype)
+    : GIWrapperPrototype(info, gtype),
+      m_domain(g_quark_from_string(g_enum_info_get_error_domain(info))) {
+    GJS_INC_COUNTER(gerror_prototype);
+}
 
-    GJS_INC_COUNTER(gerror);
+ErrorPrototype::~ErrorPrototype(void) { GJS_DEC_COUNTER(gerror_prototype); }
 
-    g_assert(priv_from_js(context, object) == NULL);
-    JS_SetPrivate(object, priv);
+ErrorInstance::ErrorInstance(JSContext* cx, JS::HandleObject obj)
+    : GIWrapperInstance(cx, obj) {
+    GJS_INC_COUNTER(gerror_instance);
+}
 
-    gjs_debug_lifecycle(GJS_DEBUG_GERROR,
-                        "GError constructor, obj %p priv %p",
-                        object.get(), priv);
+ErrorInstance::~ErrorInstance(void) {
+    g_clear_error(&m_ptr);
+    GJS_DEC_COUNTER(gerror_instance);
+}
 
-    JS::RootedObject proto(context);
-    JS_GetPrototype(context, object, &proto);
-    gjs_debug_lifecycle(GJS_DEBUG_GERROR, "GError instance __proto__ is %p",
-                        proto.get());
+/*
+ * ErrorBase::domain:
+ *
+ * Fetches ErrorPrototype::domain() for instances as well as prototypes.
+ */
+GQuark ErrorBase::domain(void) const { return get_prototype()->domain(); }
 
-    /* If we're the prototype, then post-construct we'll fill in priv->info.
-     * If we are not the prototype, though, then we'll get ->info from the
-     * prototype and then create a GObject if we don't have one already.
-     */
-    proto_priv = priv_from_js(context, proto);
-    if (proto_priv == NULL) {
-        gjs_debug(GJS_DEBUG_GERROR,
-                  "Bad prototype set on GError? Must match JSClass of object. JS error should have been 
reported.");
+// See GIWrapperBase::constructor().
+bool ErrorInstance::constructor_impl(JSContext* context,
+                                     JS::HandleObject object,
+                                     const JS::CallArgs& argv) {
+    if (argv.length() != 1 || !argv[0].isObject()) {
+        gjs_throw(context, "Invalid parameters passed to GError constructor, expected one object");
         return false;
     }
 
-    priv->info = proto_priv->info;
-    g_base_info_ref( (GIBaseInfo*) priv->info);
-    priv->domain = proto_priv->domain;
-
     JS::RootedObject params_obj(context, &argv[0].toObject());
     JS::UniqueChars message;
     const GjsAtoms& atoms = GjsContextPrivate::atoms(context);
@@ -102,101 +80,55 @@ GJS_NATIVE_CONSTRUCTOR_DECLARE(error)
                                      atoms.message(), &message))
         return false;
 
+    int32_t code;
     if (!gjs_object_require_property(context, params_obj, "GError constructor",
                                      atoms.code(), &code))
         return false;
 
-    priv->gerror = g_error_new_literal(priv->domain, code, message.get());
+    m_ptr = g_error_new_literal(domain(), code, message.get());
 
     /* We assume this error will be thrown in the same line as the constructor */
-    if (!gjs_define_error_properties(context, object))
-        return false;
-
-    GJS_NATIVE_CONSTRUCTOR_FINISH(boxed);
-
-    return true;
+    return gjs_define_error_properties(context, object);
 }
 
-static void
-error_finalize(JSFreeOp *fop,
-               JSObject *obj)
-{
-    Error *priv;
-
-    priv = (Error*) JS_GetPrivate(obj);
-    gjs_debug_lifecycle(GJS_DEBUG_GERROR,
-                        "finalize, obj %p priv %p", obj, priv);
-    if (priv == NULL)
-        return; /* wrong class? */
-
-    g_clear_error (&priv->gerror);
-
-    if (priv->info) {
-        g_base_info_unref( (GIBaseInfo*) priv->info);
-        priv->info = NULL;
-    }
-
-    GJS_DEC_COUNTER(gerror);
-    g_slice_free(Error, priv);
-}
-
-GJS_JSAPI_RETURN_CONVENTION
-static bool
-error_get_domain(JSContext *context,
-                 unsigned   argc,
-                 JS::Value *vp)
-{
-    GJS_GET_PRIV(context, argc, vp, args, obj, Error, priv);
-
-    if (priv == NULL)
-        return false;
-
-    args.rval().setInt32(priv->domain);
+/*
+ * ErrorBase::get_domain:
+ *
+ * JSNative property getter for `domain`. This property works on prototypes as
+ * well as instances.
+ */
+bool ErrorBase::get_domain(JSContext* cx, unsigned argc, JS::Value* vp) {
+    GJS_GET_WRAPPER_PRIV(cx, argc, vp, args, obj, ErrorBase, priv);
+    args.rval().setInt32(priv->domain());
     return true;
 }
 
-GJS_JSAPI_RETURN_CONVENTION
-static bool
-error_get_message(JSContext *context,
-                  unsigned   argc,
-                  JS::Value *vp)
-{
-    GJS_GET_PRIV(context, argc, vp, args, obj, Error, priv);
-
-    if (priv == NULL)
+// JSNative property getter for `message`.
+bool ErrorBase::get_message(JSContext* cx, unsigned argc, JS::Value* vp) {
+    GJS_GET_WRAPPER_PRIV(cx, argc, vp, args, obj, ErrorBase, priv);
+    if (!priv->check_is_instance(cx, "get a field"))
         return false;
 
-    if (priv->gerror == NULL) {
-        /* Object is prototype, not instance */
-        gjs_throw(context, "Can't get a field from a GError prototype");
-        return false;
-    }
-
-    return gjs_string_from_utf8(context, priv->gerror->message, args.rval());
+    return gjs_string_from_utf8(cx, priv->to_instance()->message(),
+                                args.rval());
 }
 
-GJS_JSAPI_RETURN_CONVENTION
-static bool
-error_get_code(JSContext *context,
-               unsigned   argc,
-               JS::Value *vp)
-{
-    GJS_GET_PRIV(context, argc, vp, args, obj, Error, priv);
-
-    if (priv == NULL)
+// JSNative property getter for `code`.
+bool ErrorBase::get_code(JSContext* cx, unsigned argc, JS::Value* vp) {
+    GJS_GET_WRAPPER_PRIV(cx, argc, vp, args, obj, ErrorBase, priv);
+    if (!priv->check_is_instance(cx, "get a field"))
         return false;
 
-    if (priv->gerror == NULL) {
-        /* Object is prototype, not instance */
-        gjs_throw(context, "Can't get a field from a GError prototype");
-        return false;
-    }
-
-    args.rval().setInt32(priv->gerror->code);
+    args.rval().setInt32(priv->to_instance()->code());
     return true;
 }
 
 bool gjs_gerror_to_string(JSContext* context, unsigned argc, JS::Value* vp) {
+    return ErrorBase::to_string(context, argc, vp);
+}
+
+// JSNative implementation of `toString()`.
+bool ErrorBase::to_string(JSContext* context, unsigned argc, JS::Value* vp) {
     GJS_GET_THIS(context, argc, vp, rec, self);
 
     GjsAutoChar descr;
@@ -213,37 +145,26 @@ bool gjs_gerror_to_string(JSContext* context, unsigned argc, JS::Value* vp) {
         return gjs_string_from_utf8(context, descr, rec.rval());
     }
 
-    if (!do_base_typecheck(context, self, true))
-        return false;
-    Error* priv = priv_from_js(context, self);
+    ErrorBase* priv = ErrorBase::for_js_typecheck(context, self, rec);
     if (priv == NULL)
         return false;
 
     /* We follow the same pattern as standard JS errors, at the expense of
        hiding some useful information */
 
-    if (priv->gerror == NULL) {
-        descr = g_strdup_printf("%s.%s",
-                                g_base_info_get_namespace(priv->info),
-                                g_base_info_get_name(priv->info));
+    if (priv->is_prototype()) {
+        descr = g_strdup_printf("%s.%s", priv->ns(), priv->name());
     } else {
-        descr = g_strdup_printf("%s.%s: %s",
-                                g_base_info_get_namespace(priv->info),
-                                g_base_info_get_name(priv->info),
-                                priv->gerror->message);
+        descr = g_strdup_printf("%s.%s: %s", priv->ns(), priv->name(),
+                                priv->to_instance()->message());
     }
 
     return gjs_string_from_utf8(context, descr, rec.rval());
 }
 
-GJS_JSAPI_RETURN_CONVENTION
-static bool
-error_constructor_value_of(JSContext *context,
-                           unsigned   argc,
-                           JS::Value *vp)
-{
+// JSNative implementation of `valueOf()`.
+bool ErrorBase::value_of(JSContext* context, unsigned argc, JS::Value* vp) {
     GJS_GET_THIS(context, argc, vp, rec, self);
-    Error *priv;
     JS::RootedObject prototype(context);
     const GjsAtoms& atoms = GjsContextPrivate::atoms(context);
 
@@ -256,99 +177,75 @@ error_constructor_value_of(JSContext *context,
         return false;
     }
 
-    priv = priv_from_js(context, prototype);
-
+    ErrorBase* priv = ErrorBase::for_js_typecheck(context, prototype, rec);
     if (priv == NULL)
         return false;
 
-    rec.rval().setInt32(priv->domain);
+    rec.rval().setInt32(priv->domain());
     return true;
 }
 
-
-/* The bizarre thing about this vtable is that it applies to both
- * instances of the object, and to the prototype that instances of the
- * class have.
- */
-static const struct JSClassOps gjs_error_class_ops = {
+// clang-format off
+const struct JSClassOps ErrorBase::class_ops = {
     nullptr,  // addProperty
     nullptr,  // deleteProperty
     nullptr,  // enumerate
     nullptr,  // newEnumerate
     nullptr,  // resolve
     nullptr,  // mayResolve
-    error_finalize};
+    &ErrorBase::finalize,
+};
 
-struct JSClass gjs_error_class = {
+const struct JSClass ErrorBase::klass = {
     "GLib_Error",
     JSCLASS_HAS_PRIVATE | JSCLASS_BACKGROUND_FINALIZE,
-    &gjs_error_class_ops
+    &ErrorBase::class_ops
 };
 
 /* We need to shadow all fields of GError, to prevent calling the getter from GBoxed
    (which would trash memory accessing the instance private data) */
-JSPropertySpec gjs_error_proto_props[] = {
-    JS_PSG("domain", error_get_domain, GJS_MODULE_PROP_FLAGS),
-    JS_PSG("code", error_get_code, GJS_MODULE_PROP_FLAGS),
-    JS_PSG("message", error_get_message, GJS_MODULE_PROP_FLAGS),
+JSPropertySpec ErrorBase::proto_properties[] = {
+    JS_PSG("domain", &ErrorBase::get_domain, GJS_MODULE_PROP_FLAGS),
+    JS_PSG("code", &ErrorBase::get_code, GJS_MODULE_PROP_FLAGS),
+    JS_PSG("message", &ErrorBase::get_message, GJS_MODULE_PROP_FLAGS),
     JS_PS_END
 };
 
-JSFunctionSpec gjs_error_proto_funcs[] = {
-    JS_FN("toString", gjs_gerror_to_string, 0, GJS_MODULE_PROP_FLAGS),
-    JS_FS_END};
+JSFunctionSpec ErrorBase::static_methods[] = {
+    JS_FN("valueOf", &ErrorBase::value_of, 0, GJS_MODULE_PROP_FLAGS),
+    JS_FS_END
+};
+// clang-format on
 
-static JSFunctionSpec gjs_error_constructor_funcs[] = {
-    JS_FN("valueOf", error_constructor_value_of, 0, GJS_MODULE_PROP_FLAGS),
-    JS_FS_END};
+// Overrides GIWrapperPrototype::get_parent_proto().
+bool ErrorPrototype::get_parent_proto(JSContext* cx,
+                                      JS::MutableHandleObject proto) const {
+    g_irepository_require(nullptr, "GLib", "2.0", GIRepositoryLoadFlags(0),
+                          nullptr);
+    GjsAutoStructInfo glib_error_info =
+        g_irepository_find_by_name(nullptr, "GLib", "Error");
+    proto.set(gjs_lookup_generic_prototype(cx, glib_error_info));
+    return !!proto;
+}
 
 bool gjs_define_error_class(JSContext* context, JS::HandleObject in_object,
                             GIEnumInfo* info) {
-    const char *constructor_name;
     JS::RootedObject prototype(context), constructor(context);
-    Error *priv;
-
-    /* See the comment in gjs_define_boxed_class() for an
-     * explanation of how this all works; Error is pretty much the
-     * same as Boxed (except that we inherit from GLib.Error).
-     */
-
-    constructor_name = g_base_info_get_name( (GIBaseInfo*) info);
-
-    g_irepository_require(NULL, "GLib", "2.0", (GIRepositoryLoadFlags) 0, NULL);
-    GjsAutoStructInfo glib_error_info =
-        g_irepository_find_by_name(nullptr, "GLib", "Error");
-    JS::RootedObject parent_proto(context,
-        gjs_lookup_generic_prototype(context, glib_error_info));
-
-    if (!parent_proto ||
-        !gjs_init_class_dynamic(
-            context, in_object, parent_proto, g_base_info_get_namespace(info),
-            constructor_name, &gjs_error_class, gjs_error_constructor, 1,
-            gjs_error_proto_props,  // props of prototype
-            gjs_error_proto_funcs,  // funcs of prototype
-            nullptr,  // props of constructor, MyConstructor.myprop
-            gjs_error_constructor_funcs,  // funcs of constructor,
-                                          // MyConstructor.myfunc()
-            &prototype, &constructor)) {
+    if (!ErrorPrototype::create_class(context, in_object, info, G_TYPE_ERROR,
+                                      &constructor, &prototype))
         return false;
-    }
-
-    GJS_INC_COUNTER(gerror);
-    priv = g_slice_new0(Error);
-    priv->info = info;
-    g_base_info_ref( (GIBaseInfo*) priv->info);
-    priv->domain = g_quark_from_string (g_enum_info_get_error_domain(priv->info));
 
-    JS_SetPrivate(prototype, priv);
-
-    gjs_debug(GJS_DEBUG_GBOXED, "Defined class %s prototype is %p class %p in object %p",
-              constructor_name, prototype.get(), JS_GetClass(prototype),
-              in_object.get());
+    // Define a toString() on the prototype, as it does not exist on the
+    // prototype of GLib.Error; and create_class() will not define it since we
+    // supply a parent in get_parent_proto().
+    const GjsAtoms& atoms = GjsContextPrivate::atoms(context);
+    if (!JS_DefineFunctionById(context, prototype, atoms.to_string(),
+                               &ErrorBase::to_string, 0, GJS_MODULE_PROP_FLAGS))
+        return false;
 
-    return gjs_define_enum_values(context, constructor, priv->info) &&
+    return gjs_define_enum_values(context, constructor, info) &&
            gjs_define_static_methods<InfoType::Enum>(context, constructor,
-                                                     G_TYPE_ERROR, priv->info);
+                                                     G_TYPE_ERROR, info);
 }
 
 GJS_USE
@@ -458,8 +355,6 @@ gjs_error_from_gerror(JSContext             *context,
                       GError                *gerror,
                       bool                   add_stack)
 {
-    Error *priv;
-    Error *proto_priv;
     GIEnumInfo *info;
 
     if (gerror == NULL)
@@ -488,18 +383,14 @@ gjs_error_from_gerror(JSContext             *context,
                       g_base_info_get_name((GIBaseInfo *)info));
 
     JS::RootedObject proto(context, gjs_lookup_generic_prototype(context, info));
-    proto_priv = priv_from_js(context, proto);
 
     JS::RootedObject obj(context,
         JS_NewObjectWithGivenProto(context, JS_GetClass(proto), proto));
+    if (!obj)
+        return nullptr;
 
-    GJS_INC_COUNTER(gerror);
-    priv = g_slice_new0(Error);
-    JS_SetPrivate(obj, priv);
-    priv->info = info;
-    priv->domain = proto_priv->domain;
-    g_base_info_ref( (GIBaseInfo*) priv->info);
-    priv->gerror = g_error_copy(gerror);
+    ErrorInstance* priv = ErrorInstance::new_for_js_object(context, obj);
+    priv->copy_gerror(gerror);
 
     if (add_stack && !gjs_define_error_properties(context, obj))
         return nullptr;
@@ -511,8 +402,6 @@ GError*
 gjs_gerror_from_error(JSContext       *context,
                       JS::HandleObject obj)
 {
-    Error *priv;
-
     if (!obj)
         return NULL;
 
@@ -522,20 +411,15 @@ gjs_gerror_from_error(JSContext       *context,
     if (gjs_typecheck_boxed (context, obj, NULL, G_TYPE_ERROR, false))
         return (GError*) gjs_c_struct_from_boxed (context, obj);
 
-    priv = priv_from_js(context, obj);
+    ErrorBase* priv = ErrorBase::for_js_typecheck(context, obj);
 
     if (priv == NULL)
         return NULL;
 
-    if (priv->gerror == NULL) {
-        gjs_throw(context,
-                  "Object is %s.%s.prototype, not an object instance - cannot convert to a boxed instance",
-                  g_base_info_get_namespace( (GIBaseInfo*) priv->info),
-                  g_base_info_get_name( (GIBaseInfo*) priv->info));
+    if (!priv->check_is_instance(context, "convert to a boxed instance"))
         return NULL;
-    }
 
-    return priv->gerror;
+    return priv->to_instance()->ptr();
 }
 
 bool
@@ -546,7 +430,9 @@ gjs_typecheck_gerror (JSContext       *context,
     if (gjs_typecheck_boxed (context, obj, NULL, G_TYPE_ERROR, false))
         return true;
 
-    return do_base_typecheck(context, obj, throw_error);
+    if (throw_error)
+        return !!ErrorBase::for_js_typecheck(context, obj);
+    return !!ErrorBase::for_js(context, obj);
 }
 
 GError *
diff --git a/gi/gerror.h b/gi/gerror.h
index db0e9072..c516a2b0 100644
--- a/gi/gerror.h
+++ b/gi/gerror.h
@@ -28,9 +28,110 @@
 #include <glib.h>
 #include <girepository.h>
 
+#include "gi/wrapperutils.h"
 #include "gjs/jsapi-util.h"
 #include "gjs/macros.h"
 
+class ErrorPrototype;
+class ErrorInstance;
+
+/* To conserve memory, we have two different kinds of private data for GError
+ * JS wrappers: ErrorInstance, and ErrorPrototype. Both inherit from ErrorBase
+ * for their common functionality. For more information, see the notes in
+ * wrapperutils.h.
+ *
+ * ErrorPrototype, unlike the other GIWrapperPrototype subclasses, represents a
+ * single error domain instead of a single GType. All Errors have a GType of
+ * G_TYPE_ERROR.
+ *
+ * Note that in some situations GError structs can show up as BoxedInstance
+ * instead of ErrorInstance. We have some special cases in this code to deal
+ * with that.
+ */
+
+class ErrorBase
+    : public GIWrapperBase<ErrorBase, ErrorPrototype, ErrorInstance> {
+    friend class GIWrapperBase;
+
+ protected:
+    explicit ErrorBase(ErrorPrototype* proto = nullptr)
+        : GIWrapperBase(proto) {}
+    ~ErrorBase(void) {}
+
+    static const GjsDebugTopic debug_topic = GJS_DEBUG_GERROR;
+    static constexpr const char* debug_tag = "gerror";
+
+    static const struct JSClassOps class_ops;
+    static const struct JSClass klass;
+    static JSPropertySpec proto_properties[];
+    static JSFunctionSpec static_methods[];
+
+    // Accessors
+
+ public:
+    GJS_USE GQuark domain(void) const;
+
+    // Property getters
+
+ protected:
+    GJS_JSAPI_RETURN_CONVENTION
+    static bool get_domain(JSContext* cx, unsigned argc, JS::Value* vp);
+    GJS_JSAPI_RETURN_CONVENTION
+    static bool get_message(JSContext* cx, unsigned argc, JS::Value* vp);
+    GJS_JSAPI_RETURN_CONVENTION
+    static bool get_code(JSContext* cx, unsigned argc, JS::Value* vp);
+
+    // JS methods
+
+    GJS_JSAPI_RETURN_CONVENTION
+    static bool value_of(JSContext* cx, unsigned argc, JS::Value* vp);
+
+ public:
+    GJS_JSAPI_RETURN_CONVENTION
+    static bool to_string(JSContext* cx, unsigned argc, JS::Value* vp);
+};
+
+class ErrorPrototype : public GIWrapperPrototype<ErrorBase, ErrorPrototype,
+                                                 ErrorInstance, GIEnumInfo> {
+    friend class GIWrapperPrototype;
+    friend class GIWrapperBase;
+
+    GQuark m_domain;
+
+    explicit ErrorPrototype(GIEnumInfo* info, GType gtype);
+    ~ErrorPrototype(void);
+
+    GJS_JSAPI_RETURN_CONVENTION
+    bool get_parent_proto(JSContext* cx, JS::MutableHandleObject proto) const;
+
+ public:
+    GJS_USE GQuark domain(void) const { return m_domain; }
+};
+
+class ErrorInstance : public GIWrapperInstance<ErrorBase, ErrorPrototype,
+                                               ErrorInstance, GError> {
+    friend class GIWrapperInstance;
+    friend class GIWrapperBase;
+
+    explicit ErrorInstance(JSContext* cx, JS::HandleObject obj);
+    ~ErrorInstance(void);
+
+ public:
+    void copy_gerror(GError* other) { m_ptr = g_error_copy(other); }
+
+    // Accessors
+
+    GJS_USE const char* message(void) const { return m_ptr->message; }
+    GJS_USE int code(void) const { return m_ptr->code; }
+
+    // JS constructor
+
+ private:
+    GJS_JSAPI_RETURN_CONVENTION
+    bool constructor_impl(JSContext* cx, JS::HandleObject obj,
+                          const JS::CallArgs& args);
+};
+
 G_BEGIN_DECLS
 
 GJS_JSAPI_RETURN_CONVENTION
diff --git a/gjs/mem-private.h b/gjs/mem-private.h
index dbc97083..75da541b 100644
--- a/gjs/mem-private.h
+++ b/gjs/mem-private.h
@@ -41,7 +41,8 @@ GJS_DECLARE_COUNTER(closure)
 GJS_DECLARE_COUNTER(function)
 GJS_DECLARE_COUNTER(fundamental_instance)
 GJS_DECLARE_COUNTER(fundamental_prototype)
-GJS_DECLARE_COUNTER(gerror)
+GJS_DECLARE_COUNTER(gerror_instance)
+GJS_DECLARE_COUNTER(gerror_prototype)
 GJS_DECLARE_COUNTER(importer)
 GJS_DECLARE_COUNTER(interface)
 GJS_DECLARE_COUNTER(module)
diff --git a/gjs/mem.cpp b/gjs/mem.cpp
index a23581ba..2e3a3e9b 100644
--- a/gjs/mem.cpp
+++ b/gjs/mem.cpp
@@ -41,7 +41,8 @@ GJS_DEFINE_COUNTER(closure)
 GJS_DEFINE_COUNTER(function)
 GJS_DEFINE_COUNTER(fundamental_instance)
 GJS_DEFINE_COUNTER(fundamental_prototype)
-GJS_DEFINE_COUNTER(gerror)
+GJS_DEFINE_COUNTER(gerror_instance)
+GJS_DEFINE_COUNTER(gerror_prototype)
 GJS_DEFINE_COUNTER(importer)
 GJS_DEFINE_COUNTER(interface)
 GJS_DEFINE_COUNTER(module)
@@ -64,7 +65,8 @@ static GjsMemCounter* counters[] = {
     GJS_LIST_COUNTER(function),
     GJS_LIST_COUNTER(fundamental_instance),
     GJS_LIST_COUNTER(fundamental_prototype),
-    GJS_LIST_COUNTER(gerror),
+    GJS_LIST_COUNTER(gerror_instance),
+    GJS_LIST_COUNTER(gerror_prototype),
     GJS_LIST_COUNTER(importer),
     GJS_LIST_COUNTER(interface),
     GJS_LIST_COUNTER(module),


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