1 /* -*- mode: C++; c-basic-offset: 4; indent-tabs-mode: nil; -*- */
2 // SPDX-License-Identifier: MIT OR LGPL-2.0-or-later
3 // SPDX-FileCopyrightText: 2018 Philip Chimento <philip.chimento@gmail.com>
4 // SPDX-FileCopyrightText: 2018 Marco Trevisan <marco.trevisan@canonical.com>
5 
6 #ifndef GJS_ATOMS_H_
7 #define GJS_ATOMS_H_
8 
9 #include <config.h>
10 
11 #include <js/Id.h>
12 #include <js/RootingAPI.h>
13 #include <js/TypeDecls.h>
14 
15 #include "gjs/macros.h"
16 
17 class JSTracer;
18 
19 // clang-format off
20 #define FOR_EACH_ATOM(macro) \
21     macro(code, "code") \
22     macro(column_number, "columnNumber") \
23     macro(connect_after, "connect_after") \
24     macro(constructor, "constructor") \
25     macro(debuggee, "debuggee") \
26     macro(detail, "detail") \
27     macro(emit, "emit") \
28     macro(file, "__file__") \
29     macro(file_name, "fileName") \
30     macro(func, "func") \
31     macro(gc_bytes, "gcBytes") \
32     macro(gi, "gi") \
33     macro(gio, "Gio") \
34     macro(glib, "GLib") \
35     macro(gobject, "GObject") \
36     macro(gtype, "$gtype") \
37     macro(height, "height") \
38     macro(imports, "imports") \
39     macro(importSync, "importSync") \
40     macro(init, "_init") \
41     macro(instance_init, "_instance_init") \
42     macro(interact, "interact") \
43     macro(internal, "internal") \
44     macro(length, "length") \
45     macro(line_number, "lineNumber") \
46     macro(malloc_bytes, "mallocBytes") \
47     macro(message, "message") \
48     macro(module_init, "__init__") \
49     macro(module_name, "__moduleName__") \
50     macro(module_path, "__modulePath__") \
51     macro(name, "name") \
52     macro(new_, "new") \
53     macro(new_internal, "_new_internal") \
54     macro(overrides, "overrides") \
55     macro(param_spec, "ParamSpec") \
56     macro(parent_module, "__parentModule__") \
57     macro(program_args, "programArgs") \
58     macro(program_invocation_name, "programInvocationName") \
59     macro(program_path, "programPath") \
60     macro(prototype, "prototype") \
61     macro(search_path, "searchPath") \
62     macro(signal_id, "signalId") \
63     macro(stack, "stack") \
64     macro(to_string, "toString") \
65     macro(uri, "uri") \
66     macro(url, "url") \
67     macro(value_of, "valueOf") \
68     macro(version, "version") \
69     macro(versions, "versions") \
70     macro(width, "width") \
71     macro(window, "window") \
72     macro(x, "x") \
73     macro(y, "y") \
74     macro(zone, "zone")
75 
76 #define FOR_EACH_SYMBOL_ATOM(macro) \
77     macro(hook_up_vfunc, "__GObject__hook_up_vfunc") \
78     macro(private_ns_marker, "__gjsPrivateNS") \
79     macro(signal_find, "__GObject__signal_find") \
80     macro(signals_block, "__GObject__signals_block") \
81     macro(signals_disconnect, "__GObject__signals_disconnect") \
82     macro(signals_unblock, "__GObject__signals_unblock")
83 // clang-format on
84 
85 struct GjsAtom {
86     GJS_JSAPI_RETURN_CONVENTION bool init(JSContext* cx, const char* str);
87 
88     /* It's OK to return JS::HandleId here, to avoid an extra root, with the
89      * caveat that you should not use this value after the GjsContext has been
90      * destroyed.*/
operatorGjsAtom91     [[nodiscard]] JS::HandleId operator()() const {
92         return JS::HandleId::fromMarkedLocation(&m_jsid.get());
93     }
94 
idGjsAtom95     [[nodiscard]] JS::Heap<jsid>* id() { return &m_jsid; }
96 
97  protected:
98     JS::Heap<jsid> m_jsid;
99 };
100 
101 struct GjsSymbolAtom : GjsAtom {
102     GJS_JSAPI_RETURN_CONVENTION bool init(JSContext* cx, const char* str);
103 };
104 
105 class GjsAtoms {
106  public:
GjsAtoms(void)107     GjsAtoms(void) {}
~GjsAtoms(void)108     ~GjsAtoms(void) {}  // prevents giant destructor from being inlined
109     GJS_JSAPI_RETURN_CONVENTION bool init_atoms(JSContext* cx);
110 
111     void trace(JSTracer* trc);
112 
113 #define DECLARE_ATOM_MEMBER(identifier, str) GjsAtom identifier;
114 #define DECLARE_SYMBOL_ATOM_MEMBER(identifier, str) GjsSymbolAtom identifier;
115     FOR_EACH_ATOM(DECLARE_ATOM_MEMBER)
116     FOR_EACH_SYMBOL_ATOM(DECLARE_SYMBOL_ATOM_MEMBER)
117 #undef DECLARE_ATOM_MEMBER
118 #undef DECLARE_SYMBOL_ATOM_MEMBER
119 };
120 
121 #if !defined(GJS_USE_ATOM_FOREACH) && !defined(USE_UNITY_BUILD)
122 #    undef FOR_EACH_ATOM
123 #    undef FOR_EACH_SYMBOL_ATOM
124 #endif
125 
126 #endif  // GJS_ATOMS_H_
127