1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2 * vim: set ts=8 sts=2 et sw=2 tw=80:
3 * This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 /* JavaScript module (as in, the syntactic construct) operations. */
12 #include <stdint.h> // uint32_t
14 #include "jstypes.h" // JS_PUBLIC_API
16 #include "js/AllocPolicy.h" // js::SystemAllocPolicy
17 #include "js/ColumnNumber.h" // JS::ColumnNumberOneOrigin
18 #include "js/CompileOptions.h" // JS::ReadOnlyCompileOptions
19 #include "js/RootingAPI.h" // JS::{Mutable,}Handle
20 #include "js/Value.h" // JS::Value
21 #include "js/Vector.h" // js::Vector
23 struct JS_PUBLIC_API JSContext
;
24 class JS_PUBLIC_API JSObject
;
25 struct JS_PUBLIC_API JSRuntime
;
26 class JS_PUBLIC_API JSString
;
29 template <typename UnitT
>
40 * The HostResolveImportedModule hook.
42 * See: https://tc39.es/ecma262/#sec-hostresolveimportedmodule
44 * This embedding-defined hook is used to implement module loading. It is called
45 * to get or create a module object corresponding to |moduleRequest| occurring
46 * in the context of the script or module with private value
47 * |referencingPrivate|.
49 * The module specifier string for the request can be obtained by calling
50 * JS::GetModuleRequestSpecifier.
52 * The private value for a script or module is set with JS::SetScriptPrivate or
53 * JS::SetModulePrivate. It's assumed that the embedding can handle receiving
56 * This hook must obey the restrictions defined in the spec:
57 * - Each time the hook is called with the same arguemnts, the same module must
59 * - If a module cannot be created for the given arguments, an exception must
62 * This is a synchronous operation.
64 using ModuleResolveHook
= JSObject
* (*)(JSContext
* cx
,
65 Handle
<Value
> referencingPrivate
,
66 Handle
<JSObject
*> moduleRequest
);
69 * Get the HostResolveImportedModule hook for the runtime.
71 extern JS_PUBLIC_API ModuleResolveHook
GetModuleResolveHook(JSRuntime
* rt
);
74 * Set the HostResolveImportedModule hook for the runtime to the given function.
76 extern JS_PUBLIC_API
void SetModuleResolveHook(JSRuntime
* rt
,
77 ModuleResolveHook func
);
80 * The module metadata hook.
82 * See: https://tc39.es/ecma262/#sec-hostgetimportmetaproperties
84 * Populate the |metaObject| object returned when import.meta is evaluated in
85 * the context of the script or module with private value |privateValue|.
87 * This is based on the spec's HostGetImportMetaProperties hook but defines
88 * properties on the meta object directly rather than returning a list.
90 using ModuleMetadataHook
= bool (*)(JSContext
* cx
, Handle
<Value
> privateValue
,
91 Handle
<JSObject
*> metaObject
);
94 * Get the hook for populating the import.meta metadata object.
96 extern JS_PUBLIC_API ModuleMetadataHook
GetModuleMetadataHook(JSRuntime
* rt
);
99 * Set the hook for populating the import.meta metadata object to the given
102 extern JS_PUBLIC_API
void SetModuleMetadataHook(JSRuntime
* rt
,
103 ModuleMetadataHook func
);
106 * The HostImportModuleDynamically hook.
108 * See https://tc39.es/ecma262/#sec-hostimportmoduledynamically
110 * Used to implement dynamic module import. Called when evaluating import()
113 * This starts an asynchronous operation. Some time after this hook is called
114 * the embedding must call JS::FinishDynamicModuleImport() passing the
115 * |referencingPrivate|, |moduleRequest| and |promise| arguments from the
116 * call. This must happen for both success and failure cases.
118 * In the meantime the embedding can take whatever steps it needs to make the
119 * module available. If successful, after calling FinishDynamicModuleImport()
120 * the module should be returned by the resolve hook when passed
121 * |referencingPrivate| and |moduleRequest|.
123 using ModuleDynamicImportHook
= bool (*)(JSContext
* cx
,
124 Handle
<Value
> referencingPrivate
,
125 Handle
<JSObject
*> moduleRequest
,
126 Handle
<JSObject
*> promise
);
129 * Get the HostImportModuleDynamically hook for the runtime.
131 extern JS_PUBLIC_API ModuleDynamicImportHook
132 GetModuleDynamicImportHook(JSRuntime
* rt
);
135 * Set the HostImportModuleDynamically hook for the runtime to the given
138 * If this hook is not set (or set to nullptr) then the JS engine will throw an
139 * exception if dynamic module import is attempted.
141 extern JS_PUBLIC_API
void SetModuleDynamicImportHook(
142 JSRuntime
* rt
, ModuleDynamicImportHook func
);
145 * This must be called after a dynamic import operation is complete.
147 * If |evaluationPromise| is rejected, the rejection reason will be used to
148 * complete the user's promise.
150 extern JS_PUBLIC_API
bool FinishDynamicModuleImport(
151 JSContext
* cx
, Handle
<JSObject
*> evaluationPromise
,
152 Handle
<Value
> referencingPrivate
, Handle
<JSObject
*> moduleRequest
,
153 Handle
<JSObject
*> promise
);
156 * Parse the given source buffer as a module in the scope of the current global
157 * of cx and return a source text module record.
159 extern JS_PUBLIC_API JSObject
* CompileModule(
160 JSContext
* cx
, const ReadOnlyCompileOptions
& options
,
161 SourceText
<char16_t
>& srcBuf
);
164 * Parse the given source buffer as a module in the scope of the current global
165 * of cx and return a source text module record. An error is reported if a
166 * UTF-8 encoding error is encountered.
168 extern JS_PUBLIC_API JSObject
* CompileModule(
169 JSContext
* cx
, const ReadOnlyCompileOptions
& options
,
170 SourceText
<mozilla::Utf8Unit
>& srcBuf
);
173 * Set a private value associated with a source text module record.
175 extern JS_PUBLIC_API
void SetModulePrivate(JSObject
* module
,
178 * Clear the private value associated with a source text module record.
180 * This is used during unlinking and can be called on a gray module, skipping
183 extern JS_PUBLIC_API
void ClearModulePrivate(JSObject
* module
);
186 * Get the private value associated with a source text module record.
188 extern JS_PUBLIC_API Value
GetModulePrivate(JSObject
* module
);
191 * Perform the ModuleLink operation on the given source text module record.
193 * This transitively resolves all module dependencies (calling the
194 * HostResolveImportedModule hook) and initializes the environment record for
197 extern JS_PUBLIC_API
bool ModuleLink(JSContext
* cx
,
198 Handle
<JSObject
*> moduleRecord
);
201 * Perform the ModuleEvaluate operation on the given source text module record
202 * and returns a bool. A result value is returned in result and is either
203 * undefined (and ignored) or a promise (if Top Level Await is enabled).
205 * If this module has already been evaluated, it returns the evaluation
206 * promise. Otherwise, it transitively evaluates all dependences of this module
207 * and then evaluates this module.
209 * ModuleLink must have completed prior to calling this.
211 extern JS_PUBLIC_API
bool ModuleEvaluate(JSContext
* cx
,
212 Handle
<JSObject
*> moduleRecord
,
213 MutableHandleValue rval
);
215 enum ModuleErrorBehaviour
{
216 // Report module evaluation errors asynchronously when the evaluation promise
217 // is rejected. This is used for web content.
218 ReportModuleErrorsAsync
,
220 // Throw module evaluation errors synchronously by setting an exception on the
221 // context. Does not support modules that use top-level await.
222 ThrowModuleErrorsSync
226 * If a module evaluation fails, unwrap the resulting evaluation promise
229 * This does nothing if this module succeeds in evaluation. Otherwise, it
230 * takes the reason for the module throwing, unwraps it and throws it as a
231 * regular error rather than as an uncaught promise.
233 * ModuleEvaluate must have completed prior to calling this.
235 extern JS_PUBLIC_API
bool ThrowOnModuleEvaluationFailure(
236 JSContext
* cx
, Handle
<JSObject
*> evaluationPromise
,
237 ModuleErrorBehaviour errorBehaviour
= ReportModuleErrorsAsync
);
240 * Functions to access the module specifiers of a source text module record used
241 * to request module imports.
243 * Clients can use GetRequestedModulesCount() to get the number of specifiers
244 * and GetRequestedModuleSpecifier() / GetRequestedModuleSourcePos() to get the
245 * individual elements.
247 extern JS_PUBLIC_API
uint32_t
248 GetRequestedModulesCount(JSContext
* cx
, Handle
<JSObject
*> moduleRecord
);
250 extern JS_PUBLIC_API JSString
* GetRequestedModuleSpecifier(
251 JSContext
* cx
, Handle
<JSObject
*> moduleRecord
, uint32_t index
);
254 * Get the position of a requested module's name in the source.
256 extern JS_PUBLIC_API
void GetRequestedModuleSourcePos(
257 JSContext
* cx
, Handle
<JSObject
*> moduleRecord
, uint32_t index
,
258 uint32_t* lineNumber
, JS::ColumnNumberOneOrigin
* columnNumber
);
261 * Get the top-level script for a module which has not yet been executed.
263 extern JS_PUBLIC_API JSScript
* GetModuleScript(Handle
<JSObject
*> moduleRecord
);
265 extern JS_PUBLIC_API JSObject
* CreateModuleRequest(
266 JSContext
* cx
, Handle
<JSString
*> specifierArg
);
267 extern JS_PUBLIC_API JSString
* GetModuleRequestSpecifier(
268 JSContext
* cx
, Handle
<JSObject
*> moduleRequestArg
);
271 * Get the module record for a module script.
273 extern JS_PUBLIC_API JSObject
* GetModuleObject(Handle
<JSScript
*> moduleScript
);
276 * Get the namespace object for a module.
278 extern JS_PUBLIC_API JSObject
* GetModuleNamespace(
279 JSContext
* cx
, Handle
<JSObject
*> moduleRecord
);
281 extern JS_PUBLIC_API JSObject
* GetModuleForNamespace(
282 JSContext
* cx
, Handle
<JSObject
*> moduleNamespace
);
284 extern JS_PUBLIC_API JSObject
* GetModuleEnvironment(
285 JSContext
* cx
, Handle
<JSObject
*> moduleObj
);
288 * Clear all bindings in a module's environment. Used during shutdown.
290 extern JS_PUBLIC_API
void ClearModuleEnvironment(JSObject
* moduleObj
);
294 #endif // js_Modules_h