[gjs/ewlsh/whatwg-console: 1/3] modules: Convert initial bootstrap into an ES module




commit d17f9b9a371a31079dc3b1fada17a6bf7adfc521
Author: Evan Welsh <contact evanwelsh com>
Date:   Wed Jun 9 20:38:13 2021 -0700

    modules: Convert initial bootstrap into an ES module

 gjs/context.cpp                               | 54 +++++++++++++--------------
 gjs/global.cpp                                | 17 +++++++++
 gjs/module.cpp                                |  9 ++++-
 gjs/module.h                                  |  5 ++-
 js.gresource.xml                              |  3 +-
 modules/{script => esm}/_bootstrap/default.js | 12 +++---
 modules/internal/internalLoader.js            |  4 +-
 7 files changed, 66 insertions(+), 38 deletions(-)
---
diff --git a/gjs/context.cpp b/gjs/context.cpp
index 948ca8c6..b0c41010 100644
--- a/gjs/context.cpp
+++ b/gjs/context.cpp
@@ -550,33 +550,6 @@ GjsContextPrivate::GjsContextPrivate(JSContext* cx, GjsContext* public_context)
 
     m_global = global;
 
-    {
-        JSAutoRealm ar(cx, global);
-
-        std::vector<std::string> paths;
-        if (m_search_path)
-            paths = {m_search_path,
-                     m_search_path + g_strv_length(m_search_path)};
-        JS::RootedObject importer(m_cx, gjs_create_root_importer(m_cx, paths));
-        if (!importer) {
-            gjs_log_exception(cx);
-            g_error("Failed to create root importer");
-        }
-
-        g_assert(
-            gjs_get_global_slot(global, GjsGlobalSlot::IMPORTS).isUndefined() &&
-            "Someone else already created root importer");
-
-        gjs_set_global_slot(global, GjsGlobalSlot::IMPORTS,
-                            JS::ObjectValue(*importer));
-
-        if (!gjs_define_global_properties(m_cx, global, GjsGlobalType::DEFAULT,
-                                          "GJS", "default")) {
-            gjs_log_exception(m_cx);
-            g_error("Failed to define properties on global object");
-        }
-    }
-
     JS::SetModuleResolveHook(rt, gjs_module_resolve);
     JS::SetModuleDynamicImportHook(rt, gjs_dynamic_module_resolve);
     JS::SetModuleMetadataHook(rt, gjs_populate_module_meta);
@@ -611,6 +584,33 @@ GjsContextPrivate::GjsContextPrivate(JSContext* cx, GjsContext* public_context)
         gjs_log_exception(cx);
         g_error("Failed to evaluate module loader module.");
     }
+
+    {
+        JSAutoRealm ar(cx, global);
+
+        std::vector<std::string> paths;
+        if (m_search_path)
+            paths = {m_search_path,
+                     m_search_path + g_strv_length(m_search_path)};
+        JS::RootedObject importer(m_cx, gjs_create_root_importer(m_cx, paths));
+        if (!importer) {
+            gjs_log_exception(cx);
+            g_error("Failed to create root importer");
+        }
+
+        g_assert(
+            gjs_get_global_slot(global, GjsGlobalSlot::IMPORTS).isUndefined() &&
+            "Someone else already created root importer");
+
+        gjs_set_global_slot(global, GjsGlobalSlot::IMPORTS,
+                            JS::ObjectValue(*importer));
+
+        if (!gjs_define_global_properties(m_cx, global, GjsGlobalType::DEFAULT,
+                                          "GJS", "default")) {
+            gjs_log_exception(m_cx);
+            g_error("Failed to define properties on global object");
+        }
+    }
 }
 
 void GjsContextPrivate::set_args(std::vector<std::string>&& args) {
diff --git a/gjs/global.cpp b/gjs/global.cpp
index 1883c445..9d14ce67 100644
--- a/gjs/global.cpp
+++ b/gjs/global.cpp
@@ -17,6 +17,7 @@
 #include <js/CompilationAndEvaluation.h>
 #include <js/CompileOptions.h>
 #include <js/Id.h>
+#include <js/Modules.h>
 #include <js/PropertyDescriptor.h>  // for JSPROP_PERMANENT, JSPROP_RE...
 #include <js/PropertySpec.h>
 #include <js/Realm.h>  // for GetObjectRealmOrNull, SetRealmPrivate
@@ -33,6 +34,7 @@
 #include "gjs/global.h"
 #include "gjs/internal.h"
 #include "gjs/jsapi-util.h"
+#include "gjs/module.h"
 #include "gjs/native.h"
 
 namespace mozilla {
@@ -215,6 +217,21 @@ class GjsGlobal : GjsBaseGlobal {
 
         return true;
     }
+
+    GJS_JSAPI_RETURN_CONVENTION
+    static bool run_bootstrap(JSContext* cx, const char* bootstrap_script,
+                              JS::HandleObject global) {
+        JSAutoRealm ar(cx, global);
+        GjsAutoChar uri = g_strdup_printf(
+            "resource:///org/gnome/gjs/modules/esm/_bootstrap/%s.js",
+            bootstrap_script);
+        JS::RootedObject module(cx, gjs_module_load(cx, uri, uri, true));
+        if (!module)
+            return false;
+
+        return JS::ModuleInstantiate(cx, module) &&
+               JS::ModuleEvaluate(cx, module);
+    }
 };
 
 class GjsDebuggerGlobal : GjsBaseGlobal {
diff --git a/gjs/module.cpp b/gjs/module.cpp
index 2c0840f7..d1d2b830 100644
--- a/gjs/module.cpp
+++ b/gjs/module.cpp
@@ -347,7 +347,7 @@ JSObject* gjs_get_module_registry(JSObject* global) {
  * @returns whether an error occurred while resolving the specifier.
  */
 JSObject* gjs_module_load(JSContext* cx, const char* identifier,
-                          const char* file_uri) {
+                          const char* file_uri, std::optional<bool> internal) {
     g_assert((gjs_global_is_type(cx, GjsGlobalType::DEFAULT) ||
               gjs_global_is_type(cx, GjsGlobalType::INTERNAL)) &&
              "gjs_module_load can only be called from module-enabled "
@@ -368,10 +368,15 @@ JSObject* gjs_module_load(JSContext* cx, const char* identifier,
     if (!uri)
         return nullptr;
 
-    JS::RootedValueArray<2> args(cx);
+    JS::RootedValueArray<3> args(cx);
     args[0].setString(id);
     args[1].setString(uri);
 
+    if (internal.has_value())
+        args[2].setBoolean(internal.value());
+    else
+        args[2].setUndefined();
+
     gjs_debug(GJS_DEBUG_IMPORTER,
               "Module resolve hook for module '%s' (%s), global %p", identifier,
               file_uri, global.get());
diff --git a/gjs/module.h b/gjs/module.h
index 39d550b4..65480b4f 100644
--- a/gjs/module.h
+++ b/gjs/module.h
@@ -9,6 +9,8 @@
 
 #include <gio/gio.h>
 
+#include <optional>
+
 #include <js/TypeDecls.h>
 
 #include "gjs/macros.h"
@@ -32,7 +34,8 @@ JSObject* gjs_get_module_registry(JSObject* global);
 
 GJS_JSAPI_RETURN_CONVENTION
 JSObject* gjs_module_load(JSContext* cx, const char* identifier,
-                          const char* uri);
+                          const char* uri,
+                          std::optional<bool> internal = std::nullopt);
 
 GJS_JSAPI_RETURN_CONVENTION
 JSObject* gjs_module_resolve(JSContext* cx, JS::HandleValue mod_val,
diff --git a/js.gresource.xml b/js.gresource.xml
index fc55e597..6f58d0d3 100644
--- a/js.gresource.xml
+++ b/js.gresource.xml
@@ -8,14 +8,15 @@
     <file>modules/internal/loader.js</file>
 
     <!-- ESM-based modules -->
+    <file>modules/esm/_bootstrap/default.js</file>
     <file>modules/esm/cairo.js</file>
+    <file>modules/esm/console.js</file>
     <file>modules/esm/gettext.js</file>
     <file>modules/esm/gi.js</file>
     <file>modules/esm/system.js</file>
 
     <!-- Script-based Modules -->
     <file>modules/script/_bootstrap/debugger.js</file>
-    <file>modules/script/_bootstrap/default.js</file>
     <file>modules/script/_bootstrap/coverage.js</file>
 
     <file>modules/script/tweener/equations.js</file>
diff --git a/modules/script/_bootstrap/default.js b/modules/esm/_bootstrap/default.js
similarity index 75%
rename from modules/script/_bootstrap/default.js
rename to modules/esm/_bootstrap/default.js
index 952d7fe3..21f29f1a 100644
--- a/modules/script/_bootstrap/default.js
+++ b/modules/esm/_bootstrap/default.js
@@ -3,17 +3,19 @@
 // SPDX-FileCopyrightText: 2020 Evan Welsh <contact evanwelsh com>
 
 (function (exports) {
-    'use strict';
-
-    const {print, printerr, log, logError} = imports._print;
+    const {print, printerr, log, logError} = import.meta.importSync('_print');
+    let system = null;
 
     Object.defineProperties(exports, {
         ARGV: {
             configurable: false,
             enumerable: true,
             get() {
-                // Wait until after bootstrap or programArgs won't be set.
-                return imports.system.programArgs;
+                // Wait until after initial bootstrap or programArgs won't be set.
+                if (!system)
+                    system = import.meta.importSync('system');
+
+                return system.programArgs;
             },
         },
         print: {
diff --git a/modules/internal/internalLoader.js b/modules/internal/internalLoader.js
index b1023132..43309122 100644
--- a/modules/internal/internalLoader.js
+++ b/modules/internal/internalLoader.js
@@ -206,8 +206,8 @@ export class InternalModuleLoader {
         return resolved;
     }
 
-    moduleLoadHook(id, uri) {
-        const priv = new ModulePrivate(id, uri);
+    moduleLoadHook(id, uri, internal = false) {
+        const priv = new ModulePrivate(id, uri, internal);
 
         const result = this.loadURI(parseURI(uri));
         // result can only be null if `this` is InternalModuleLoader. If `this`


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