[gjs: 8/10] atoms: use structs with operator()() override to init atoms



commit ebe8e112716be87dc3ae3766cda1b65f675a7eb0
Author: Marco Trevisan (TreviƱo) <mail 3v1n0 net>
Date:   Sun Oct 14 07:51:38 2018 +0200

    atoms: use structs with operator()() override to init atoms
    
    Use the minimum amount of meta-programming via macros, but use instead
    c++ structs and just call few methods from the container class.

 gjs/atoms.cpp | 32 ++++++++++++++++----------------
 gjs/atoms.h   | 46 ++++++++++++++++++++++++++++++++--------------
 2 files changed, 48 insertions(+), 30 deletions(-)
---
diff --git a/gjs/atoms.cpp b/gjs/atoms.cpp
index 799840d3..2eef10a9 100644
--- a/gjs/atoms.cpp
+++ b/gjs/atoms.cpp
@@ -1,6 +1,7 @@
 /* -*- mode: C++; c-basic-offset: 4; indent-tabs-mode: nil; -*- */
 /*
  * Copyright (c) 2018 Philip Chimento <philip chimento gmail com>
+ *                    Marco Trevisan <marco trevisan canonical com>
  *
  * Permission is hereby granted, free of charge, to any person obtaining a copy
  * of this software and associated documentation files (the "Software"), to
@@ -21,38 +22,37 @@
  * IN THE SOFTWARE.
  */
 
+#define GJS_USE_ATOM_FOREACH
+
 #include "gjs/atoms.h"
 #include "gjs/jsapi-wrapper.h"
 
+void GjsAtom::init(JSContext* cx, const char* str) {
+    m_jsid = INTERNED_STRING_TO_JSID(cx, JS_AtomizeAndPinString(cx, str));
+}
+
+void GjsSymbolAtom::init(JSContext* cx, const char* str) {
+    JS::RootedString descr(cx, JS_AtomizeAndPinString(cx, str));
+    m_jsid = SYMBOL_TO_JSID(JS::NewSymbol(cx, descr));
+}
+
+#define INITIALIZE_ATOM(identifier, str) identifier.init(cx, str);
+
 GjsAtoms::GjsAtoms(JSContext* cx) {
     JSAutoRequest ar(cx);
-    JSString* atom;
-
-#define INITIALIZE_ATOM(identifier, str)    \
-    atom = JS_AtomizeAndPinString(cx, str); \
-    m_##identifier = INTERNED_STRING_TO_JSID(cx, atom);
     FOR_EACH_ATOM(INITIALIZE_ATOM)
-#undef INITIALIZE_ATOM
 }
 
 /* Requires a current compartment. Unlike the atoms initialized in the
  * constructor, this can GC, so it needs to be done after the tracing has been
  * set up. */
 void GjsAtoms::init_symbols(JSContext* cx) {
-    JS::RootedString descr(cx);
-    JS::Symbol* symbol;
-
-#define INITIALIZE_SYMBOL_ATOM(identifier, str) \
-    descr = JS_AtomizeAndPinString(cx, str);    \
-    symbol = JS::NewSymbol(cx, descr);          \
-    m_##identifier = SYMBOL_TO_JSID(symbol);
-    FOR_EACH_SYMBOL_ATOM(INITIALIZE_SYMBOL_ATOM)
-#undef INITIALIZE_SYMBOL_ATOM
+    FOR_EACH_SYMBOL_ATOM(INITIALIZE_ATOM)
 }
 
 void GjsAtoms::trace(JSTracer* trc) {
 #define TRACE_ATOM(identifier, str) \
-    JS::TraceEdge<jsid>(trc, &m_##identifier, "Atom " str);
+    JS::TraceEdge<jsid>(trc, identifier.id(), "Atom " str);
     FOR_EACH_ATOM(TRACE_ATOM)
     FOR_EACH_SYMBOL_ATOM(TRACE_ATOM)
 #undef TRACE_ATOM
diff --git a/gjs/atoms.h b/gjs/atoms.h
index 4c8ae52c..f7c80015 100644
--- a/gjs/atoms.h
+++ b/gjs/atoms.h
@@ -1,6 +1,7 @@
 /* -*- mode: C++; c-basic-offset: 4; indent-tabs-mode: nil; -*- */
 /*
  * Copyright (c) 2018 Philip Chimento <philip chimento gmail com>
+ *                    Marco Trevisan <marco trevisan canonical com>
  *
  * Permission is hereby granted, free of charge, to any person obtaining a copy
  * of this software and associated documentation files (the "Software"), to
@@ -74,27 +75,44 @@
     macro(private_ns_marker, "__gjsPrivateNS")
 // clang-format on
 
-class GjsAtoms {
-#define DECLARE_ATOM_MEMBER(identifier, str) JS::Heap<jsid> m_##identifier;
-    FOR_EACH_ATOM(DECLARE_ATOM_MEMBER)
-    FOR_EACH_SYMBOL_ATOM(DECLARE_ATOM_MEMBER)
-#undef DECLARE_ATOM_MEMBER
+struct GjsAtom {
+    void init(JSContext* cx, const char* str);
+
+    /* It's OK to return JS::HandleId here, to avoid an extra root, with the
+     * caveat that you should not use this value after the GjsContext has been
+     * destroyed.*/
+    JS::HandleId operator()() const {
+        return JS::HandleId::fromMarkedLocation(&m_jsid.get());
+    }
+
+    JS::Heap<jsid>* id() { return &m_jsid; }
+
+ protected:
+    JS::Heap<jsid> m_jsid;
+};
 
+struct GjsSymbolAtom : GjsAtom {
+    void init(JSContext* cx, const char* str);
+};
+
+class GjsAtoms {
  public:
     explicit GjsAtoms(JSContext* cx);
     void init_symbols(JSContext* cx);
 
     void trace(JSTracer* trc);
 
-/* It's OK to return JS::HandleId here, to avoid an extra root, with the caveat
- * that you should not use this value after the GjsContext has been destroyed.*/
-#define DECLARE_ATOM_ACCESSOR(identifier, str)                          \
-    JS::HandleId identifier(void) const {                               \
-        return JS::HandleId::fromMarkedLocation(&m_##identifier.get()); \
-    }
-    FOR_EACH_ATOM(DECLARE_ATOM_ACCESSOR)
-    FOR_EACH_SYMBOL_ATOM(DECLARE_ATOM_ACCESSOR)
-#undef DECLARE_ATOM_ACCESSOR
+#define DECLARE_ATOM_MEMBER(identifier, str) GjsAtom identifier;
+#define DECLARE_SYMBOL_ATOM_MEMBER(identifier, str) GjsSymbolAtom identifier;
+    FOR_EACH_ATOM(DECLARE_ATOM_MEMBER)
+    FOR_EACH_SYMBOL_ATOM(DECLARE_SYMBOL_ATOM_MEMBER)
+#undef DECLARE_ATOM_MEMBER
+#undef DECLARE_SYMBOL_ATOM_MEMBER
 };
 
+#ifndef GJS_USE_ATOM_FOREACH
+#    undef FOR_EACH_ATOM
+#    undef FOR_EACH_SYMBOL_ATOM
+#endif
+
 #endif  // GJS_ATOMS_H_


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