[gjs/esm/static-imports: 4/5] SQUASH: Move module metadata hook into C++
- From: Philip Chimento <pchimento src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gjs/esm/static-imports: 4/5] SQUASH: Move module metadata hook into C++
- Date: Sat, 6 Feb 2021 02:26:14 +0000 (UTC)
commit a457f6e1b31129f079ad73ba3d82167f7f511768
Author: Philip Chimento <philip chimento gmail com>
Date: Fri Feb 5 15:48:43 2021 -0800
SQUASH: Move module metadata hook into C++
I found this a convoluted path:
- Call a C++ function exposed as a global to put a JS function in a global
slot
- SpiderMonkey calls a C++ function to populate the metadata
- Lookup the JS function from the global slot and call it
- Define a property to a C++ function exposed as a global
This unfortunately moves a small amount of code from JS into C++ but I
think it's worth it because of the smaller number of steps that you have
to follow across several files to figure out how it works.
gjs/atoms.h | 4 ++
gjs/global.cpp | 3 --
gjs/global.h | 2 -
gjs/internal.cpp | 79 ---------------------------------
gjs/internal.h | 8 ----
gjs/module.cpp | 91 +++++++++++++++++++++++++++++++++-----
modules/internal/.eslintrc.yml | 1 -
modules/internal/internalLoader.js | 4 --
modules/internal/loader.js | 11 -----
9 files changed, 83 insertions(+), 120 deletions(-)
---
diff --git a/gjs/atoms.h b/gjs/atoms.h
index 966999c8..7fe061f1 100644
--- a/gjs/atoms.h
+++ b/gjs/atoms.h
@@ -35,9 +35,11 @@ class JSTracer;
macro(gtype, "$gtype") \
macro(height, "height") \
macro(imports, "imports") \
+ macro(importSync, "importSync") \
macro(init, "_init") \
macro(instance_init, "_instance_init") \
macro(interact, "interact") \
+ macro(internal, "internal") \
macro(length, "length") \
macro(line_number, "lineNumber") \
macro(message, "message") \
@@ -56,6 +58,8 @@ class JSTracer;
macro(signal_id, "signalId") \
macro(stack, "stack") \
macro(to_string, "toString") \
+ macro(uri, "uri") \
+ macro(url, "url") \
macro(value_of, "valueOf") \
macro(version, "version") \
macro(versions, "versions") \
diff --git a/gjs/global.cpp b/gjs/global.cpp
index 441a2999..aeb11ad7 100644
--- a/gjs/global.cpp
+++ b/gjs/global.cpp
@@ -269,14 +269,11 @@ class GjsInternalGlobal : GjsBaseGlobal {
JS_FN("compileInternalModule", gjs_internal_compile_internal_module, 2,
0),
JS_FN("getRegistry", gjs_internal_get_registry, 1, 0),
- JS_FN("importSync", gjs_internal_global_import_sync, 1, 0),
JS_FN("loadResourceOrFile", gjs_internal_load_resource_or_file, 1, 0),
JS_FN("parseURI", gjs_internal_parse_uri, 1, 0),
JS_FN("resolveRelativeResourceOrFile",
gjs_internal_resolve_relative_resource_or_file, 2, 0),
JS_FN("setModuleLoadHook", gjs_internal_global_set_module_hook, 3, 0),
- JS_FN("setModuleMetaHook", gjs_internal_global_set_module_meta_hook, 2,
- 0),
JS_FN("setModulePrivate", gjs_internal_set_module_private, 2, 0),
JS_FN("setModuleResolveHook",
gjs_internal_global_set_module_resolve_hook, 2, 0),
diff --git a/gjs/global.h b/gjs/global.h
index f39c4c8c..f7c39ad3 100644
--- a/gjs/global.h
+++ b/gjs/global.h
@@ -41,8 +41,6 @@ enum class GjsGlobalSlot : uint32_t {
IMPORT_HOOK,
// Stores a function which creates new module objects
MODULE_HOOK,
- // Stores a function which sets the metadata on import.meta
- META_HOOK,
// Stores the module registry (a Map object)
MODULE_REGISTRY,
NATIVE_REGISTRY,
diff --git a/gjs/internal.cpp b/gjs/internal.cpp
index b24056ad..388f2406 100644
--- a/gjs/internal.cpp
+++ b/gjs/internal.cpp
@@ -171,33 +171,6 @@ bool gjs_internal_global_set_module_resolve_hook([[maybe_unused]] JSContext* cx,
return true;
}
-/**
- * gjs_internal_global_set_module_meta_hook:
- *
- * @brief Sets the META_HOOK slot of the passed passed global object.
- * Asserts that the second argument must be callable (e.g. Function).
- * The passed callable is called by gjs_populate_module_meta.
- *
- * The META_HOOK is passed two parameters, a plain object for population with
- * meta properties and the module's private object.
- *
- * @example (in JavaScript)
- * setModuleMetaHook(globalThis, (module, meta) => {
- * module // the module object
- * meta // the meta object
- * });
- *
- * @returns guaranteed to return true or assert.
- */
-bool gjs_internal_global_set_module_meta_hook([[maybe_unused]] JSContext* cx,
- unsigned argc, JS::Value* vp) {
- JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
- g_assert(args.length() == 2 && "setModuleMetaHook takes 2 arguments");
-
- set_module_hook(args, GjsGlobalSlot::META_HOOK);
- return true;
-}
-
/**
* compile_module:
*
@@ -313,58 +286,6 @@ bool gjs_internal_set_module_private(JSContext* cx, unsigned argc,
return true;
}
-/**
- * gjs_internal_global_import_sync:
- *
- * @brief Synchronously imports native "modules" from the import global's
- * native registry. This function does not do blocking I/O so it is
- * safe to call it synchronously for accessing native "modules" within
- * modules. This function is always called within the import global's
- * realm.
- *
- * @param cx the current JSContext
- * @param argc
- * @param vp
- *
- * @returns whether an error occurred while importing the native module.
- */
-bool gjs_internal_global_import_sync(JSContext* cx, unsigned argc,
- JS::Value* vp) {
- JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
- JS::UniqueChars id;
- if (!gjs_parse_call_args(cx, "importSync", args, "s", "identifier", &id))
- return false;
-
- JS::RootedObject global(cx, gjs_get_import_global(cx));
- JSAutoRealm ar(cx, global);
-
- JS::AutoSaveExceptionState exc_state(cx);
-
- JS::RootedObject native_registry(cx, gjs_get_native_registry(global));
- JS::RootedObject v_module(cx);
-
- JS::RootedId key(cx, gjs_intern_string_to_id(cx, id.get()));
- if (!gjs_global_registry_get(cx, native_registry, key, &v_module))
- return false;
-
- if (v_module) {
- args.rval().setObject(*v_module);
- return true;
- }
-
- JS::RootedObject native_obj(cx);
- if (!gjs_load_native_module(cx, id.get(), &native_obj)) {
- gjs_throw(cx, "Failed to load native module: %s", id.get());
- return false;
- }
-
- if (!gjs_global_registry_set(cx, native_registry, key, native_obj))
- return false;
-
- args.rval().setObject(*native_obj);
- return true;
-}
-
/**
* gjs_internal_get_registry:
*
diff --git a/gjs/internal.h b/gjs/internal.h
index 0e86856c..888b9033 100644
--- a/gjs/internal.h
+++ b/gjs/internal.h
@@ -24,18 +24,10 @@ bool gjs_internal_compile_internal_module(JSContext* cx, unsigned argc,
GJS_JSAPI_RETURN_CONVENTION
bool gjs_internal_get_registry(JSContext* cx, unsigned argc, JS::Value* vp);
-GJS_JSAPI_RETURN_CONVENTION
-bool gjs_internal_global_import_sync(JSContext* cx, unsigned argc,
- JS::Value* vp);
-
GJS_JSAPI_RETURN_CONVENTION
bool gjs_internal_global_set_module_hook(JSContext* cx, unsigned argc,
JS::Value* vp);
-GJS_JSAPI_RETURN_CONVENTION
-bool gjs_internal_global_set_module_meta_hook(JSContext* cx, unsigned argc,
- JS::Value* vp);
-
GJS_JSAPI_RETURN_CONVENTION
bool gjs_internal_set_module_private(JSContext* cx, unsigned argc,
JS::Value* vp);
diff --git a/gjs/module.cpp b/gjs/module.cpp
index 2b67ebca..37fdd3af 100644
--- a/gjs/module.cpp
+++ b/gjs/module.cpp
@@ -13,24 +13,31 @@
#include <gio/gio.h>
#include <glib.h>
+#include <js/CallArgs.h>
#include <js/CharacterEncoding.h> // for ConstUTF8CharsZ
#include <js/Class.h>
#include <js/CompilationAndEvaluation.h>
#include <js/CompileOptions.h>
+#include <js/Conversions.h>
#include <js/GCVector.h> // for RootedVector
+#include <js/Id.h>
#include <js/PropertyDescriptor.h>
#include <js/RootingAPI.h>
#include <js/SourceText.h>
#include <js/TypeDecls.h>
+#include <js/Utility.h> // for UniqueChars
#include <js/Value.h>
#include <js/ValueArray.h>
#include <jsapi.h> // for JS_DefinePropertyById, ...
+#include "gjs/atoms.h"
#include "gjs/context-private.h"
#include "gjs/global.h"
+#include "gjs/jsapi-util-args.h"
#include "gjs/jsapi-util.h"
#include "gjs/mem-private.h"
#include "gjs/module.h"
+#include "gjs/native.h"
#include "util/log.h"
class GjsScriptModule {
@@ -336,10 +343,66 @@ JSObject* gjs_module_load(JSContext* cx, const char* identifier,
return &result.toObject();
}
+/**
+ * import_native_module_sync:
+ *
+ * @brief Synchronously imports native "modules" from the import global's
+ * native registry. This function does not do blocking I/O so it is
+ * safe to call it synchronously for accessing native "modules" within
+ * modules. This function is always called within the import global's
+ * realm.
+ *
+ * Compare gjs_import_native_module() for the legacy importer.
+ *
+ * @param cx the current JSContext
+ * @param argc
+ * @param vp
+ *
+ * @returns whether an error occurred while importing the native module.
+ */
+static bool import_native_module_sync(JSContext* cx, unsigned argc,
+ JS::Value* vp) {
+ JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
+ JS::UniqueChars id;
+ if (!gjs_parse_call_args(cx, "importSync", args, "s", "identifier", &id))
+ return false;
+
+ JS::RootedObject global(cx, gjs_get_import_global(cx));
+ JSAutoRealm ar(cx, global);
+
+ JS::AutoSaveExceptionState exc_state(cx);
+
+ JS::RootedObject native_registry(cx, gjs_get_native_registry(global));
+ JS::RootedObject v_module(cx);
+
+ JS::RootedId key(cx, gjs_intern_string_to_id(cx, id.get()));
+ if (!gjs_global_registry_get(cx, native_registry, key, &v_module))
+ return false;
+
+ if (v_module) {
+ args.rval().setObject(*v_module);
+ return true;
+ }
+
+ JS::RootedObject native_obj(cx);
+ if (!gjs_load_native_module(cx, id.get(), &native_obj)) {
+ gjs_throw(cx, "Failed to load native module: %s", id.get());
+ return false;
+ }
+
+ if (!gjs_global_registry_set(cx, native_registry, key, native_obj))
+ return false;
+
+ args.rval().setObject(*native_obj);
+ return true;
+}
+
/**
* gjs_populate_module_meta:
*
* Hook SpiderMonkey calls to populate the import.meta object.
+ * Defines a property "import.meta.url", and additionally a method
+ * "import.meta.importSync" if this is an internal module.
*
* @param private_ref the private value for the #Module object
* @param meta_object the import.meta object
@@ -347,23 +410,27 @@ JSObject* gjs_module_load(JSContext* cx, const char* identifier,
* @returns whether an error occurred while populating the module meta.
*/
bool gjs_populate_module_meta(JSContext* cx, JS::HandleValue private_ref,
- JS::HandleObject meta_object_handle) {
+ JS::HandleObject meta) {
g_assert(private_ref.isObject());
-
- JS::RootedObject global(cx, JS::CurrentGlobalOrNull(cx));
- JS::RootedValue hook(cx,
- gjs_get_global_slot(global, GjsGlobalSlot::META_HOOK));
-
- JS::RootedObject meta(cx, meta_object_handle);
JS::RootedObject module(cx, &private_ref.toObject());
- JS::RootedValueArray<2> args(cx);
- args[0].setObject(*module);
- args[1].setObject(*meta);
- JS::RootedValue ignore_result(cx);
- if (!JS_CallFunctionValue(cx, nullptr, hook, args, &ignore_result))
+ const GjsAtoms& atoms = GjsContextPrivate::atoms(cx);
+ JS::RootedValue v_uri(cx);
+ if (!JS_GetPropertyById(cx, module, atoms.uri(), &v_uri) ||
+ !JS_DefinePropertyById(cx, meta, atoms.url(), v_uri,
+ GJS_MODULE_PROP_FLAGS))
return false;
+ JS::RootedValue v_internal(cx);
+ if (!JS_GetPropertyById(cx, module, atoms.internal(), &v_internal))
+ return false;
+ if (JS::ToBoolean(v_internal)) {
+ if (!JS_DefineFunctionById(cx, meta, atoms.importSync(),
+ import_native_module_sync, 1,
+ GJS_MODULE_PROP_FLAGS))
+ return false;
+ }
+
return true;
}
diff --git a/modules/internal/.eslintrc.yml b/modules/internal/.eslintrc.yml
index d2edebf8..6bcff33c 100644
--- a/modules/internal/.eslintrc.yml
+++ b/modules/internal/.eslintrc.yml
@@ -23,7 +23,6 @@ globals:
uriExists: readonly
resolveRelativeResourceOrFile: readonly
setModuleResolveHook: readonly
- setModuleMetaHook: readonly
setModuleLoadHook: readonly
setModulePrivate: readonly
getRegistry: readonly
diff --git a/modules/internal/internalLoader.js b/modules/internal/internalLoader.js
index 7c870f4f..e59e5c5e 100644
--- a/modules/internal/internalLoader.js
+++ b/modules/internal/internalLoader.js
@@ -200,10 +200,6 @@ setModuleResolveHook(globalThis, (priv, specifier) => {
return resolved;
});
-setModuleMetaHook(globalThis, (module, meta) => {
- meta.url = module.uri;
-});
-
setModuleLoadHook(globalThis, (id, uri) => {
const priv = new ModulePrivate(id, uri);
diff --git a/modules/internal/loader.js b/modules/internal/loader.js
index 8518c197..2c13d7a5 100644
--- a/modules/internal/loader.js
+++ b/modules/internal/loader.js
@@ -162,17 +162,6 @@ moduleLoader.registerScheme('gi', {
},
});
-/**
- * @param {ModulePrivate} module
- * @param {ImportMeta} meta
- */
-setModuleMetaHook(moduleGlobalThis, (module, meta) => {
- meta.url = module.uri;
-
- if (module.internal)
- meta.importSync = globalThis.importSync;
-});
-
/**
* @param {string} id
* @param {string} uri
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]