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