[gjs/burninate-macros: 5/13] ns: Remove JSClass macros



commit ad1566e3a50fb8db7bf57b0aca3f9e01dccb0d47
Author: Philip Chimento <philip chimento gmail com>
Date:   Tue Apr 7 17:09:45 2020 -0700

    ns: Remove JSClass macros
    
    FIXME: Add another commit moving all the methods into the class body

 gi/ns.cpp | 181 ++++++++++++++++++++++++++++++--------------------------------
 1 file changed, 88 insertions(+), 93 deletions(-)
---
diff --git a/gi/ns.cpp b/gi/ns.cpp
index 4f6f4f0f..41482fc7 100644
--- a/gi/ns.cpp
+++ b/gi/ns.cpp
@@ -45,24 +45,67 @@
 #include "gjs/mem-private.h"
 #include "util/log.h"
 
-typedef struct {
-    char *gi_namespace;
-} Ns;
+class Ns;
+using NsBase = NativeObject<Ns, Ns, GJS_GLOBAL_SLOT_PROTOTYPE_ns>;
 
-extern struct JSClass gjs_ns_class;
+class Ns : public NsBase {
+    friend NsBase;
 
-GJS_DEFINE_PRIV_FROM_JS(Ns, gjs_ns_class)
+    char* m_gi_namespace;
+
+    // Construction and retrieval
+
+    Ns(const char* gi_namespace) : m_gi_namespace(g_strdup(gi_namespace)) {
+        GJS_INC_COUNTER(ns);
+    }
+    ~Ns() {
+        g_clear_pointer(&m_gi_namespace, g_free);
+        GJS_DEC_COUNTER(ns);
+    }
+
+    // JSClass operations
+
+    GJS_JSAPI_RETURN_CONVENTION
+    bool resolve_impl(JSContext* cx, JS::HandleObject obj, JS::HandleId id,
+                      bool* resolved);
+
+    GJS_JSAPI_RETURN_CONVENTION
+    bool new_enumerate_impl(JSContext* cx, JS::HandleObject obj,
+                            JS::MutableHandleIdVector properties,
+                            bool only_enumerable);
+
+    static void finalize_impl(JSFreeOp* fop, Ns* priv);
+
+    // Properties and methods
+
+    GJS_JSAPI_RETURN_CONVENTION
+    static bool get_name(JSContext* cx, unsigned argc, JS::Value* vp);
+
+    static const JSClass klass;
+    static const JSClassOps class_ops;
+    static const JSPropertySpec proto_props[];
+
+    static constexpr js::ClassSpec class_spec = {
+        nullptr,  // createConstructor
+        nullptr,  // createPrototype
+        nullptr,  // constructorFunctions
+        nullptr,  // constructorProperties
+        nullptr,  // prototypeFunctions
+        Ns::proto_props,
+        nullptr,  // finishInit
+        js::ClassSpec::DontDefineConstructor};
+
+ public:
+    GJS_JSAPI_RETURN_CONVENTION
+    static JSObject* create(JSContext* cx, const char* ns_name);
+};
+
+decltype(Ns::class_spec) const Ns::class_spec;
 
 /* The *resolved out parameter, on success, should be false to indicate that id
  * was not resolved; and true if id was resolved. */
-GJS_JSAPI_RETURN_CONVENTION
-static bool
-ns_resolve(JSContext       *context,
-           JS::HandleObject obj,
-           JS::HandleId     id,
-           bool            *resolved)
-{
-    Ns *priv;
+bool Ns::resolve_impl(JSContext* context, JS::HandleObject obj, JS::HandleId id,
+                      bool* resolved) {
     bool defined;
 
     if (!JSID_IS_STRING(id)) {
@@ -77,15 +120,9 @@ ns_resolve(JSContext       *context,
         return true;
     }
 
-    priv = priv_from_js(context, obj);
-    gjs_debug_jsprop(GJS_DEBUG_GNAMESPACE,
-                     "Resolve prop '%s' hook, obj %s, priv %p",
-                     gjs_debug_id(id).c_str(), gjs_debug_object(obj).c_str(), priv);
-
-    if (!priv) {
-        *resolved = false;  /* we are the prototype, or have the wrong class */
-        return true;
-    }
+    gjs_debug_jsprop(
+        GJS_DEBUG_GNAMESPACE, "Resolve prop '%s' hook, obj %s, priv %p",
+        gjs_debug_id(id).c_str(), gjs_debug_object(obj).c_str(), this);
 
     JS::UniqueChars name;
     if (!gjs_get_string_id(context, id, &name))
@@ -96,7 +133,7 @@ ns_resolve(JSContext       *context,
     }
 
     GjsAutoBaseInfo info =
-        g_irepository_find_by_name(nullptr, priv->gi_namespace, name.get());
+        g_irepository_find_by_name(nullptr, m_gi_namespace, name.get());
     if (!info) {
         *resolved = false; /* No property defined, but no error either */
         return true;
@@ -117,17 +154,10 @@ ns_resolve(JSContext       *context,
     return true;
 }
 
-GJS_JSAPI_RETURN_CONVENTION
-static bool ns_new_enumerate(JSContext* cx, JS::HandleObject obj,
-                             JS::MutableHandleIdVector properties,
-                             bool only_enumerable G_GNUC_UNUSED) {
-    Ns* priv = priv_from_js(cx, obj);
-
-    if (!priv) {
-        return true;
-    }
-
-    int n = g_irepository_get_n_infos(nullptr, priv->gi_namespace);
+bool Ns::new_enumerate_impl(JSContext* cx, JS::HandleObject obj G_GNUC_UNUSED,
+                            JS::MutableHandleIdVector properties,
+                            bool only_enumerable G_GNUC_UNUSED) {
+    int n = g_irepository_get_n_infos(nullptr, m_gi_namespace);
     if (!properties.reserve(properties.length() + n)) {
         JS_ReportOutOfMemory(cx);
         return false;
@@ -135,7 +165,7 @@ static bool ns_new_enumerate(JSContext* cx, JS::HandleObject obj,
 
     for (int k = 0; k < n; k++) {
         GjsAutoBaseInfo info =
-            g_irepository_get_info(nullptr, priv->gi_namespace, k);
+            g_irepository_get_info(nullptr, m_gi_namespace, k);
         const char* name = info.name();
 
         jsid id = gjs_intern_string_to_id(cx, name);
@@ -147,97 +177,62 @@ static bool ns_new_enumerate(JSContext* cx, JS::HandleObject obj,
     return true;
 }
 
-GJS_JSAPI_RETURN_CONVENTION
-static bool
-get_name (JSContext *context,
-          unsigned   argc,
-          JS::Value *vp)
-{
-    GJS_GET_PRIV(context, argc, vp, args, obj, Ns, priv);
+bool Ns::get_name(JSContext* cx, unsigned argc, JS::Value* vp) {
+    GJS_GET_THIS(cx, argc, vp, args, this_obj);
 
+    Ns* priv = Ns::for_js(cx, this_obj, args);
     if (!priv)
         return false;
 
-    return gjs_string_from_utf8(context, priv->gi_namespace, args.rval());
+    return gjs_string_from_utf8(cx, priv->m_gi_namespace, args.rval());
 }
 
-GJS_NATIVE_CONSTRUCTOR_DEFINE_ABSTRACT(ns)
-
-static void ns_finalize(JSFreeOp*, JSObject* obj) {
-    Ns *priv;
-
-    priv = (Ns *)JS_GetPrivate(obj);
-    gjs_debug_lifecycle(GJS_DEBUG_GNAMESPACE,
-                        "finalize, obj %p priv %p", obj, priv);
-    if (!priv)
-        return; /* we are the prototype, not a real instance */
+void Ns::finalize_impl(JSFreeOp*, Ns* priv) {
+    g_assert(priv && "Finalize called on wrong object");
 
-    if (priv->gi_namespace)
-        g_free(priv->gi_namespace);
-
-    GJS_DEC_COUNTER(ns);
-    g_slice_free(Ns, priv);
+    delete priv;
 }
 
-/* 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.
- */
 // clang-format off
-static const struct JSClassOps gjs_ns_class_ops = {
+const JSClassOps Ns::class_ops = {
     nullptr,  // addProperty
     nullptr,  // deleteProperty
     nullptr,  // enumerate
-    ns_new_enumerate,
-    ns_resolve,
+    &Ns::new_enumerate,
+    &Ns::resolve,
     nullptr,  // mayResolve
-    ns_finalize};
+    &Ns::finalize,
+};
 
-struct JSClass gjs_ns_class = {
+const JSClass Ns::klass = {
     "GIRepositoryNamespace",
     JSCLASS_HAS_PRIVATE | JSCLASS_FOREGROUND_FINALIZE,
-    &gjs_ns_class_ops
+    &Ns::class_ops
 };
 
-static JSPropertySpec gjs_ns_proto_props[] = {
-    JS_PSG("__name__", get_name, GJS_MODULE_PROP_FLAGS),
+const JSPropertySpec Ns::proto_props[] = {
+    JS_PSG("__name__", &Ns::get_name, GJS_MODULE_PROP_FLAGS),
     JS_PS_END
 };
 // clang-format on
 
-static JSFunctionSpec *gjs_ns_proto_funcs = nullptr;
-static JSFunctionSpec *gjs_ns_static_funcs = nullptr;
-
-GJS_DEFINE_PROTO_FUNCS(ns)
-
-GJS_JSAPI_RETURN_CONVENTION
-static JSObject*
-ns_new(JSContext    *context,
-       const char   *ns_name)
-{
-    Ns *priv;
-
-    JS::RootedObject proto(context);
-    if (!gjs_ns_define_proto(context, nullptr, &proto))
+JSObject* Ns::create(JSContext* cx, const char* ns_name) {
+    JS::RootedObject proto(cx, Ns::create_prototype(cx));
+    if (!proto)
         return nullptr;
 
-    JS::RootedObject ns(context,
-        JS_NewObjectWithGivenProto(context, &gjs_ns_class, proto));
+    JS::RootedObject ns(cx, JS_NewObjectWithGivenProto(cx, &Ns::klass, proto));
     if (!ns)
         return nullptr;
 
-    priv = g_slice_new0(Ns);
-
-    GJS_INC_COUNTER(ns);
+    Ns* priv = new Ns(ns_name);
 
-    g_assert(!priv_from_js(context, ns));
+    g_assert(!JS_GetPrivate(ns));
     JS_SetPrivate(ns, priv);
 
     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;
 }
 
@@ -245,5 +240,5 @@ JSObject*
 gjs_create_ns(JSContext    *context,
               const char   *ns_name)
 {
-    return ns_new(context, ns_name);
+    return Ns::create(context, ns_name);
 }


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