summaryrefslogtreecommitdiffstats
path: root/js/public/Modules.h
diff options
context:
space:
mode:
Diffstat (limited to 'js/public/Modules.h')
-rw-r--r--js/public/Modules.h294
1 files changed, 294 insertions, 0 deletions
diff --git a/js/public/Modules.h b/js/public/Modules.h
new file mode 100644
index 0000000000..580962235f
--- /dev/null
+++ b/js/public/Modules.h
@@ -0,0 +1,294 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+ * vim: set ts=8 sts=2 et sw=2 tw=80:
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+/* JavaScript module (as in, the syntactic construct) operations. */
+
+#ifndef js_Modules_h
+#define js_Modules_h
+
+#include <stdint.h> // uint32_t
+
+#include "jstypes.h" // JS_PUBLIC_API
+
+#include "js/AllocPolicy.h" // js::SystemAllocPolicy
+#include "js/ColumnNumber.h" // JS::ColumnNumberOneOrigin
+#include "js/CompileOptions.h" // JS::ReadOnlyCompileOptions
+#include "js/RootingAPI.h" // JS::{Mutable,}Handle
+#include "js/Value.h" // JS::Value
+#include "js/Vector.h" // js::Vector
+
+struct JS_PUBLIC_API JSContext;
+class JS_PUBLIC_API JSObject;
+struct JS_PUBLIC_API JSRuntime;
+class JS_PUBLIC_API JSString;
+
+namespace JS {
+template <typename UnitT>
+class SourceText;
+} // namespace JS
+
+namespace mozilla {
+union Utf8Unit;
+}
+
+namespace JS {
+
+/**
+ * The HostResolveImportedModule hook.
+ *
+ * See: https://tc39.es/ecma262/#sec-hostresolveimportedmodule
+ *
+ * This embedding-defined hook is used to implement module loading. It is called
+ * to get or create a module object corresponding to |moduleRequest| occurring
+ * in the context of the script or module with private value
+ * |referencingPrivate|.
+ *
+ * The module specifier string for the request can be obtained by calling
+ * JS::GetModuleRequestSpecifier.
+ *
+ * The private value for a script or module is set with JS::SetScriptPrivate or
+ * JS::SetModulePrivate. It's assumed that the embedding can handle receiving
+ * either here.
+ *
+ * This hook must obey the restrictions defined in the spec:
+ * - Each time the hook is called with the same arguemnts, the same module must
+ * be returned.
+ * - If a module cannot be created for the given arguments, an exception must
+ * be thrown.
+ *
+ * This is a synchronous operation.
+ */
+using ModuleResolveHook = JSObject* (*)(JSContext* cx,
+ Handle<Value> referencingPrivate,
+ Handle<JSObject*> moduleRequest);
+
+/**
+ * Get the HostResolveImportedModule hook for the runtime.
+ */
+extern JS_PUBLIC_API ModuleResolveHook GetModuleResolveHook(JSRuntime* rt);
+
+/**
+ * Set the HostResolveImportedModule hook for the runtime to the given function.
+ */
+extern JS_PUBLIC_API void SetModuleResolveHook(JSRuntime* rt,
+ ModuleResolveHook func);
+
+/**
+ * The module metadata hook.
+ *
+ * See: https://tc39.es/ecma262/#sec-hostgetimportmetaproperties
+ *
+ * Populate the |metaObject| object returned when import.meta is evaluated in
+ * the context of the script or module with private value |privateValue|.
+ *
+ * This is based on the spec's HostGetImportMetaProperties hook but defines
+ * properties on the meta object directly rather than returning a list.
+ */
+using ModuleMetadataHook = bool (*)(JSContext* cx, Handle<Value> privateValue,
+ Handle<JSObject*> metaObject);
+
+/**
+ * Get the hook for populating the import.meta metadata object.
+ */
+extern JS_PUBLIC_API ModuleMetadataHook GetModuleMetadataHook(JSRuntime* rt);
+
+/**
+ * Set the hook for populating the import.meta metadata object to the given
+ * function.
+ */
+extern JS_PUBLIC_API void SetModuleMetadataHook(JSRuntime* rt,
+ ModuleMetadataHook func);
+
+/**
+ * The HostImportModuleDynamically hook.
+ *
+ * See https://tc39.es/ecma262/#sec-hostimportmoduledynamically
+ *
+ * Used to implement dynamic module import. Called when evaluating import()
+ * expressions.
+ *
+ * This starts an asynchronous operation. Some time after this hook is called
+ * the embedding must call JS::FinishDynamicModuleImport() passing the
+ * |referencingPrivate|, |moduleRequest| and |promise| arguments from the
+ * call. This must happen for both success and failure cases.
+ *
+ * In the meantime the embedding can take whatever steps it needs to make the
+ * module available. If successful, after calling FinishDynamicModuleImport()
+ * the module should be returned by the resolve hook when passed
+ * |referencingPrivate| and |moduleRequest|.
+ */
+using ModuleDynamicImportHook = bool (*)(JSContext* cx,
+ Handle<Value> referencingPrivate,
+ Handle<JSObject*> moduleRequest,
+ Handle<JSObject*> promise);
+
+/**
+ * Get the HostImportModuleDynamically hook for the runtime.
+ */
+extern JS_PUBLIC_API ModuleDynamicImportHook
+GetModuleDynamicImportHook(JSRuntime* rt);
+
+/**
+ * Set the HostImportModuleDynamically hook for the runtime to the given
+ * function.
+ *
+ * If this hook is not set (or set to nullptr) then the JS engine will throw an
+ * exception if dynamic module import is attempted.
+ */
+extern JS_PUBLIC_API void SetModuleDynamicImportHook(
+ JSRuntime* rt, ModuleDynamicImportHook func);
+
+/**
+ * This must be called after a dynamic import operation is complete.
+ *
+ * If |evaluationPromise| is rejected, the rejection reason will be used to
+ * complete the user's promise.
+ */
+extern JS_PUBLIC_API bool FinishDynamicModuleImport(
+ JSContext* cx, Handle<JSObject*> evaluationPromise,
+ Handle<Value> referencingPrivate, Handle<JSObject*> moduleRequest,
+ Handle<JSObject*> promise);
+
+/**
+ * Parse the given source buffer as a module in the scope of the current global
+ * of cx and return a source text module record.
+ */
+extern JS_PUBLIC_API JSObject* CompileModule(
+ JSContext* cx, const ReadOnlyCompileOptions& options,
+ SourceText<char16_t>& srcBuf);
+
+/**
+ * Parse the given source buffer as a module in the scope of the current global
+ * of cx and return a source text module record. An error is reported if a
+ * UTF-8 encoding error is encountered.
+ */
+extern JS_PUBLIC_API JSObject* CompileModule(
+ JSContext* cx, const ReadOnlyCompileOptions& options,
+ SourceText<mozilla::Utf8Unit>& srcBuf);
+
+/**
+ * Set a private value associated with a source text module record.
+ */
+extern JS_PUBLIC_API void SetModulePrivate(JSObject* module,
+ const Value& value);
+/**
+ * Clear the private value associated with a source text module record.
+ *
+ * This is used during unlinking and can be called on a gray module, skipping
+ * the usual checks.
+ */
+extern JS_PUBLIC_API void ClearModulePrivate(JSObject* module);
+
+/**
+ * Get the private value associated with a source text module record.
+ */
+extern JS_PUBLIC_API Value GetModulePrivate(JSObject* module);
+
+/*
+ * Perform the ModuleLink operation on the given source text module record.
+ *
+ * This transitively resolves all module dependencies (calling the
+ * HostResolveImportedModule hook) and initializes the environment record for
+ * the module.
+ */
+extern JS_PUBLIC_API bool ModuleLink(JSContext* cx,
+ Handle<JSObject*> moduleRecord);
+
+/*
+ * Perform the ModuleEvaluate operation on the given source text module record
+ * and returns a bool. A result value is returned in result and is either
+ * undefined (and ignored) or a promise (if Top Level Await is enabled).
+ *
+ * If this module has already been evaluated, it returns the evaluation
+ * promise. Otherwise, it transitively evaluates all dependences of this module
+ * and then evaluates this module.
+ *
+ * ModuleLink must have completed prior to calling this.
+ */
+extern JS_PUBLIC_API bool ModuleEvaluate(JSContext* cx,
+ Handle<JSObject*> moduleRecord,
+ MutableHandleValue rval);
+
+enum ModuleErrorBehaviour {
+ // Report module evaluation errors asynchronously when the evaluation promise
+ // is rejected. This is used for web content.
+ ReportModuleErrorsAsync,
+
+ // Throw module evaluation errors synchronously by setting an exception on the
+ // context. Does not support modules that use top-level await.
+ ThrowModuleErrorsSync
+};
+
+/*
+ * If a module evaluation fails, unwrap the resulting evaluation promise
+ * and rethrow.
+ *
+ * This does nothing if this module succeeds in evaluation. Otherwise, it
+ * takes the reason for the module throwing, unwraps it and throws it as a
+ * regular error rather than as an uncaught promise.
+ *
+ * ModuleEvaluate must have completed prior to calling this.
+ */
+extern JS_PUBLIC_API bool ThrowOnModuleEvaluationFailure(
+ JSContext* cx, Handle<JSObject*> evaluationPromise,
+ ModuleErrorBehaviour errorBehaviour = ReportModuleErrorsAsync);
+
+/*
+ * Functions to access the module specifiers of a source text module record used
+ * to request module imports.
+ *
+ * Clients can use GetRequestedModulesCount() to get the number of specifiers
+ * and GetRequestedModuleSpecifier() / GetRequestedModuleSourcePos() to get the
+ * individual elements.
+ */
+extern JS_PUBLIC_API uint32_t
+GetRequestedModulesCount(JSContext* cx, Handle<JSObject*> moduleRecord);
+
+extern JS_PUBLIC_API JSString* GetRequestedModuleSpecifier(
+ JSContext* cx, Handle<JSObject*> moduleRecord, uint32_t index);
+
+/*
+ * Get the position of a requested module's name in the source.
+ */
+extern JS_PUBLIC_API void GetRequestedModuleSourcePos(
+ JSContext* cx, Handle<JSObject*> moduleRecord, uint32_t index,
+ uint32_t* lineNumber, JS::ColumnNumberOneOrigin* columnNumber);
+
+/*
+ * Get the top-level script for a module which has not yet been executed.
+ */
+extern JS_PUBLIC_API JSScript* GetModuleScript(Handle<JSObject*> moduleRecord);
+
+extern JS_PUBLIC_API JSObject* CreateModuleRequest(
+ JSContext* cx, Handle<JSString*> specifierArg);
+extern JS_PUBLIC_API JSString* GetModuleRequestSpecifier(
+ JSContext* cx, Handle<JSObject*> moduleRequestArg);
+
+/*
+ * Get the module record for a module script.
+ */
+extern JS_PUBLIC_API JSObject* GetModuleObject(Handle<JSScript*> moduleScript);
+
+/*
+ * Get the namespace object for a module.
+ */
+extern JS_PUBLIC_API JSObject* GetModuleNamespace(
+ JSContext* cx, Handle<JSObject*> moduleRecord);
+
+extern JS_PUBLIC_API JSObject* GetModuleForNamespace(
+ JSContext* cx, Handle<JSObject*> moduleNamespace);
+
+extern JS_PUBLIC_API JSObject* GetModuleEnvironment(
+ JSContext* cx, Handle<JSObject*> moduleObj);
+
+/*
+ * Clear all bindings in a module's environment. Used during shutdown.
+ */
+extern JS_PUBLIC_API void ClearModuleEnvironment(JSObject* moduleObj);
+
+} // namespace JS
+
+#endif // js_Modules_h