[gjs/esm/static-imports] Cleanup global finalizers.



commit 6aa36707c10911f0b761d4dd786909d8a04a7068
Author: Evan Welsh <noreply evanwelsh com>
Date:   Mon Jun 15 12:26:15 2020 -0500

    Cleanup global finalizers.

 gjs/context.cpp  |  8 ++++--
 gjs/global.cpp   | 86 ++++++++++++++++++++++++++++++++++++++++++++------------
 gjs/global.h     |  7 ++---
 gjs/internal.cpp |  5 ++--
 gjs/module.cpp   |  6 ++--
 5 files changed, 82 insertions(+), 30 deletions(-)
---
diff --git a/gjs/context.cpp b/gjs/context.cpp
index 109bbb38..b3e45557 100644
--- a/gjs/context.cpp
+++ b/gjs/context.cpp
@@ -1199,17 +1199,19 @@ bool GjsContextPrivate::register_module(const char* identifier,
 
     auto esm_registry = gjs_get_esm_registry(m_cx);
 
-    auto it = esm_registry->lookupForAdd(filename);
+    auto it = esm_registry->lookupForAdd(identifier);
 
     if (it.found()) {
-        gjs_throw(m_cx, "Module '%s' already registered", filename);
+        gjs_throw(m_cx, "Module '%s' already registered", identifier);
         return false;
     }
 
     JS::RootedObject module_record(m_cx,
                                    module->compile(m_cx, script, script_len));
 
-    if (module_record && !esm_registry->add(it, identifier, module_record)) {
+    GjsAutoChar iden(g_strdup(identifier));
+
+    if (module_record && !esm_registry->add(it, iden.get(), module_record)) {
         JS_ReportOutOfMemory(m_cx);
         return false;
     }
diff --git a/gjs/global.cpp b/gjs/global.cpp
index 381deef4..7af976b5 100644
--- a/gjs/global.cpp
+++ b/gjs/global.cpp
@@ -296,13 +296,35 @@ static bool gjs_argv(JSContext* cx, unsigned argc, JS::Value* vp) {
 const JSClassOps defaultclassops = JS::DefaultGlobalClassOps;
 
 class GjsGlobal {
+    static void finalize(JSFreeOp* op G_GNUC_UNUSED, JSObject* obj) {
+        delete static_cast<GjsModuleRegistry*>(
+            gjs_get_global_slot(obj, GjsGlobalSlot::MODULE_REGISTRY)
+                .toPrivate());
+        delete static_cast<GjsModuleRegistry*>(
+            gjs_get_global_slot(obj, GjsGlobalSlot::NATIVE_REGISTRY)
+                .toPrivate());
+    }
+
+    static constexpr JSClassOps classops = {nullptr,  // addProperty
+                                            nullptr,  // deleteProperty
+                                            nullptr,  // enumerate
+                                            JS_NewEnumerateStandardClasses,
+                                            JS_ResolveStandardClass,
+                                            JS_MayResolveStandardClass,
+                                            GjsGlobal::finalize,
+                                            nullptr,  // call
+                                            nullptr,  // hasInstance
+                                            nullptr,  // construct
+                                            JS_GlobalObjectTraceHook};
+
     static constexpr JSClass klass = {
         // Keep this as "GjsGlobal" until Jasmine is upgraded to support
         // globalThis
         "GjsGlobal",
-        JSCLASS_HAS_PRIVATE | JSCLASS_GLOBAL_FLAGS_WITH_SLOTS(
-                                  static_cast<uint32_t>(GjsGlobalSlot::LAST)),
-        &defaultclassops,
+        JSCLASS_FOREGROUND_FINALIZE | JSCLASS_HAS_PRIVATE |
+            JSCLASS_GLOBAL_FLAGS_WITH_SLOTS(
+                static_cast<uint32_t>(GjsGlobalSlot::LAST)),
+        &classops,
     };
 
     static constexpr JSFunctionSpec static_funcs[] = {
@@ -349,9 +371,16 @@ class GjsGlobal {
     static bool define_properties(JSContext* cx, JS::HandleObject global,
                                   const char* realm_name,
                                   const char* bootstrap_script) {
-        gjs_set_global_slot(global, GjsGlobalSlot::ES_MODULE_REGISTRY,
+        JS::Realm* realm = JS::GetObjectRealmOrNull(global);
+        g_assert(realm && "Global object must be associated with a realm");
+        // const_cast is allowed here if we never free the realm data
+        JS::SetRealmPrivate(realm, const_cast<char*>(realm_name));
+
+        JSAutoRealm ar(cx, global);
+
+        gjs_set_global_slot(global, GjsGlobalSlot::MODULE_REGISTRY,
                             JS::PrivateValue(new GjsModuleRegistry()));
-        gjs_set_global_slot(global, GjsGlobalSlot::NATIVE_MODULE_REGISTRY,
+        gjs_set_global_slot(global, GjsGlobalSlot::NATIVE_REGISTRY,
                             JS::PrivateValue(new GjsModuleRegistry()));
 
         const GjsAtoms& atoms = GjsContextPrivate::atoms(cx);
@@ -360,11 +389,6 @@ class GjsGlobal {
             !JS_DefineFunctions(cx, global, GjsGlobal::static_funcs))
             return false;
 
-        JS::Realm* realm = JS::GetObjectRealmOrNull(global);
-        g_assert(realm && "Global object must be associated with a realm");
-        // const_cast is allowed here if we never free the realm data
-        JS::SetRealmPrivate(realm, const_cast<char*>(realm_name));
-
         JS::Value v_importer =
             gjs_get_global_slot(global, GjsGlobalSlot::IMPORTS);
         g_assert(((void)"importer should be defined before passing null "
@@ -458,11 +482,33 @@ class GjsInternalGlobal {
         JS_FN("setModuleResolveHook", SetModuleResolveHook, 1, 0),
         JS_FS_END};
 
+    static void finalize(JSFreeOp* op G_GNUC_UNUSED, JSObject* obj) {
+        delete static_cast<GjsModuleRegistry*>(
+            gjs_get_global_slot(obj, GjsInternalGlobalSlot::SCRIPT_REGISTRY)
+                .toPrivate());
+        delete static_cast<GjsModuleRegistry*>(
+            gjs_get_global_slot(obj, GjsGlobalSlot::MODULE_REGISTRY)
+                .toPrivate());
+    }
+
+    static constexpr JSClassOps classops = {nullptr,  // addProperty
+                                            nullptr,  // deleteProperty
+                                            nullptr,  // enumerate
+                                            JS_NewEnumerateStandardClasses,
+                                            JS_ResolveStandardClass,
+                                            JS_MayResolveStandardClass,
+                                            GjsInternalGlobal::finalize,
+                                            nullptr,  // call
+                                            nullptr,  // hasInstance
+                                            nullptr,  // construct
+                                            JS_GlobalObjectTraceHook};
+
     static constexpr JSClass klass = {
         "GjsInternalGlobal",
-        JSCLASS_GLOBAL_FLAGS_WITH_SLOTS(
-            static_cast<uint32_t>(GjsInternalGlobalSlot::LAST)),
-        &JS::DefaultGlobalClassOps,
+        JSCLASS_FOREGROUND_FINALIZE |
+            JSCLASS_GLOBAL_FLAGS_WITH_SLOTS(
+                static_cast<uint32_t>(GjsInternalGlobalSlot::LAST)),
+        &classops,
     };
 
  public:
@@ -480,11 +526,6 @@ class GjsInternalGlobal {
     static bool define_properties(JSContext* cx, JS::HandleObject global,
                                   const char* realm_name,
                                   const char* bootstrap_script G_GNUC_UNUSED) {
-        gjs_set_global_slot(global, GjsInternalGlobalSlot::SCRIPT_REGISTRY,
-                            JS::PrivateValue(new GjsModuleRegistry()));
-        gjs_set_global_slot(global, GjsInternalGlobalSlot::MODULE_REGISTRY,
-                            JS::PrivateValue(new GjsModuleRegistry()));
-
         const GjsAtoms& atoms = GjsContextPrivate::atoms(cx);
 
         JS::Realm* realm = JS::GetObjectRealmOrNull(global);
@@ -492,6 +533,13 @@ class GjsInternalGlobal {
         // const_cast is allowed here if we never free the realm data
         JS::SetRealmPrivate(realm, const_cast<char*>(realm_name));
 
+        JSAutoRealm ar(cx, global);
+
+        gjs_set_global_slot(global, GjsInternalGlobalSlot::SCRIPT_REGISTRY,
+                            JS::PrivateValue(new GjsModuleRegistry()));
+        gjs_set_global_slot(global, GjsGlobalSlot::MODULE_REGISTRY,
+                            JS::PrivateValue(new GjsModuleRegistry()));
+
         if (!JS_DefineFunctions(cx, global, static_funcs)) {
             return false;
         }
@@ -674,6 +722,7 @@ template JS::Value gjs_get_global_slot(JSObject* global,
                                        GjsInternalGlobalSlot slot);
 
 decltype(GjsGlobal::klass) constexpr GjsGlobal::klass;
+decltype(GjsGlobal::classops) constexpr GjsGlobal::classops;
 decltype(GjsGlobal::static_funcs) constexpr GjsGlobal::static_funcs;
 
 decltype(GjsDebuggerGlobal::klass) constexpr GjsDebuggerGlobal::klass;
@@ -681,5 +730,6 @@ decltype(
     GjsDebuggerGlobal::static_funcs) constexpr GjsDebuggerGlobal::static_funcs;
 
 decltype(GjsInternalGlobal::klass) constexpr GjsInternalGlobal::klass;
+decltype(GjsInternalGlobal::classops) constexpr GjsInternalGlobal::classops;
 decltype(
     GjsInternalGlobal::static_funcs) constexpr GjsInternalGlobal::static_funcs;
diff --git a/gjs/global.h b/gjs/global.h
index 88842c93..41bbff3b 100644
--- a/gjs/global.h
+++ b/gjs/global.h
@@ -41,8 +41,8 @@ enum class GjsGlobalType {
 enum class GjsGlobalSlot : uint32_t {
     GLOBAL_TYPE = 0,
     IMPORTS,
-    ES_MODULE_REGISTRY,
-    NATIVE_MODULE_REGISTRY,
+    MODULE_REGISTRY,
+    NATIVE_REGISTRY,
     PROTOTYPE_gtype,
     PROTOTYPE_importer,
     PROTOTYPE_function,
@@ -67,8 +67,7 @@ enum class GjsGlobalSlot : uint32_t {
 };
 
 enum class GjsInternalGlobalSlot : uint32_t {
-    MODULE_REGISTRY = static_cast<uint32_t>(GjsGlobalSlot::LAST),
-    SCRIPT_REGISTRY,
+    SCRIPT_REGISTRY = static_cast<uint32_t>(GjsGlobalSlot::LAST),
     IMPORT_HOOK,
     LAST
 };
diff --git a/gjs/internal.cpp b/gjs/internal.cpp
index ffd0abe5..6742bd52 100644
--- a/gjs/internal.cpp
+++ b/gjs/internal.cpp
@@ -329,8 +329,9 @@ static bool register_internal_module(JSContext* cx, const char* identifier,
     JS::RootedObject module_record(
         cx, internal_module->compile(cx, module, module_len));
 
-    if (module_record &&
-        !internal_registry->add(it, identifier, module_record)) {
+    GjsAutoChar iden(g_strdup(identifier));
+
+    if (module_record && !internal_registry->add(it, iden, module_record)) {
         JS_ReportOutOfMemory(cx);
         return false;
     }
diff --git a/gjs/module.cpp b/gjs/module.cpp
index bbe21afd..62ad616f 100644
--- a/gjs/module.cpp
+++ b/gjs/module.cpp
@@ -310,7 +310,7 @@ decltype(GjsScriptModule::class_ops) constexpr GjsScriptModule::class_ops;
 GjsModuleRegistry* gjs_get_native_module_registry(JSContext* js_context) {
     auto global = gjs_get_import_global(js_context);
     auto native_registry =
-        gjs_get_global_slot(global, GjsGlobalSlot::NATIVE_MODULE_REGISTRY);
+        gjs_get_global_slot(global, GjsGlobalSlot::NATIVE_REGISTRY);
 
     return static_cast<GjsModuleRegistry*>(native_registry.toPrivate());
 }
@@ -318,7 +318,7 @@ GjsModuleRegistry* gjs_get_native_module_registry(JSContext* js_context) {
 GjsModuleRegistry* gjs_get_esm_registry(JSContext* js_context) {
     auto global = gjs_get_import_global(js_context);
     auto esm_registry =
-        gjs_get_global_slot(global, GjsGlobalSlot::ES_MODULE_REGISTRY);
+        gjs_get_global_slot(global, GjsGlobalSlot::MODULE_REGISTRY);
 
     return static_cast<GjsModuleRegistry*>(esm_registry.toPrivate());
 }
@@ -334,7 +334,7 @@ GjsModuleRegistry* gjs_get_internal_script_registry(JSContext* js_context) {
 GjsModuleRegistry* gjs_get_internal_module_registry(JSContext* js_context) {
     auto global = gjs_get_internal_global(js_context);
     auto script_registry =
-        gjs_get_global_slot(global, GjsInternalGlobalSlot::MODULE_REGISTRY);
+        gjs_get_global_slot(global, GjsGlobalSlot::MODULE_REGISTRY);
 
     return static_cast<GjsModuleRegistry*>(script_registry.toPrivate());
 }


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