Bug 1885489 - Part 9: Add SnapshotIterator::readObject(). r=iain
[gecko.git] / js / public / Modules.h
blob4a8d45acb07dee2985e701c3c21bc7ab997da242
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. */
9 #ifndef js_Modules_h
10 #define js_Modules_h
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;
28 namespace JS {
29 template <typename UnitT>
30 class SourceText;
31 } // namespace JS
33 namespace mozilla {
34 union Utf8Unit;
37 namespace JS {
39 enum class ModuleType : uint32_t { Unknown = 0, JavaScript, JSON };
41 /**
42 * The HostResolveImportedModule hook.
44 * See: https://tc39.es/ecma262/#sec-hostresolveimportedmodule
46 * This embedding-defined hook is used to implement module loading. It is called
47 * to get or create a module object corresponding to |moduleRequest| occurring
48 * in the context of the script or module with private value
49 * |referencingPrivate|.
51 * The module specifier string for the request can be obtained by calling
52 * JS::GetModuleRequestSpecifier.
54 * The private value for a script or module is set with JS::SetScriptPrivate or
55 * JS::SetModulePrivate. It's assumed that the embedding can handle receiving
56 * either here.
58 * This hook must obey the restrictions defined in the spec:
59 * - Each time the hook is called with the same arguemnts, the same module must
60 * be returned.
61 * - If a module cannot be created for the given arguments, an exception must
62 * be thrown.
64 * This is a synchronous operation.
66 using ModuleResolveHook = JSObject* (*)(JSContext* cx,
67 Handle<Value> referencingPrivate,
68 Handle<JSObject*> moduleRequest);
70 /**
71 * Get the HostResolveImportedModule hook for the runtime.
73 extern JS_PUBLIC_API ModuleResolveHook GetModuleResolveHook(JSRuntime* rt);
75 /**
76 * Set the HostResolveImportedModule hook for the runtime to the given function.
78 extern JS_PUBLIC_API void SetModuleResolveHook(JSRuntime* rt,
79 ModuleResolveHook func);
81 /**
82 * The module metadata hook.
84 * See: https://tc39.es/ecma262/#sec-hostgetimportmetaproperties
86 * Populate the |metaObject| object returned when import.meta is evaluated in
87 * the context of the script or module with private value |privateValue|.
89 * This is based on the spec's HostGetImportMetaProperties hook but defines
90 * properties on the meta object directly rather than returning a list.
92 using ModuleMetadataHook = bool (*)(JSContext* cx, Handle<Value> privateValue,
93 Handle<JSObject*> metaObject);
95 /**
96 * Get the hook for populating the import.meta metadata object.
98 extern JS_PUBLIC_API ModuleMetadataHook GetModuleMetadataHook(JSRuntime* rt);
101 * Set the hook for populating the import.meta metadata object to the given
102 * function.
104 extern JS_PUBLIC_API void SetModuleMetadataHook(JSRuntime* rt,
105 ModuleMetadataHook func);
108 * The HostImportModuleDynamically hook.
110 * See https://tc39.es/ecma262/#sec-hostimportmoduledynamically
112 * Used to implement dynamic module import. Called when evaluating import()
113 * expressions.
115 * This starts an asynchronous operation. Some time after this hook is called
116 * the embedding must call JS::FinishDynamicModuleImport() passing the
117 * |referencingPrivate|, |moduleRequest| and |promise| arguments from the
118 * call. This must happen for both success and failure cases.
120 * In the meantime the embedding can take whatever steps it needs to make the
121 * module available. If successful, after calling FinishDynamicModuleImport()
122 * the module should be returned by the resolve hook when passed
123 * |referencingPrivate| and |moduleRequest|.
125 using ModuleDynamicImportHook = bool (*)(JSContext* cx,
126 Handle<Value> referencingPrivate,
127 Handle<JSObject*> moduleRequest,
128 Handle<JSObject*> promise);
131 * Get the HostImportModuleDynamically hook for the runtime.
133 extern JS_PUBLIC_API ModuleDynamicImportHook
134 GetModuleDynamicImportHook(JSRuntime* rt);
137 * Set the HostImportModuleDynamically hook for the runtime to the given
138 * function.
140 * If this hook is not set (or set to nullptr) then the JS engine will throw an
141 * exception if dynamic module import is attempted.
143 extern JS_PUBLIC_API void SetModuleDynamicImportHook(
144 JSRuntime* rt, ModuleDynamicImportHook func);
147 * This must be called after a dynamic import operation is complete.
149 * If |evaluationPromise| is rejected, the rejection reason will be used to
150 * complete the user's promise.
152 extern JS_PUBLIC_API bool FinishDynamicModuleImport(
153 JSContext* cx, Handle<JSObject*> evaluationPromise,
154 Handle<Value> referencingPrivate, Handle<JSObject*> moduleRequest,
155 Handle<JSObject*> promise);
158 * Parse the given source buffer as a module in the scope of the current global
159 * of cx and return a source text module record.
161 extern JS_PUBLIC_API JSObject* CompileModule(
162 JSContext* cx, const ReadOnlyCompileOptions& options,
163 SourceText<char16_t>& srcBuf);
166 * Parse the given source buffer as a module in the scope of the current global
167 * of cx and return a source text module record. An error is reported if a
168 * UTF-8 encoding error is encountered.
170 extern JS_PUBLIC_API JSObject* CompileModule(
171 JSContext* cx, const ReadOnlyCompileOptions& options,
172 SourceText<mozilla::Utf8Unit>& srcBuf);
175 * Parse the given source buffer as a JSON module in the scope of the current
176 * global of cx and return a synthetic module record.
178 extern JS_PUBLIC_API JSObject* CompileJsonModule(
179 JSContext* cx, const ReadOnlyCompileOptions& options,
180 SourceText<char16_t>& srcBuf);
183 * Set a private value associated with a source text module record.
185 extern JS_PUBLIC_API void SetModulePrivate(JSObject* module,
186 const Value& value);
188 * Clear the private value associated with a source text module record.
190 * This is used during unlinking and can be called on a gray module, skipping
191 * the usual checks.
193 extern JS_PUBLIC_API void ClearModulePrivate(JSObject* module);
196 * Get the private value associated with a source text module record.
198 extern JS_PUBLIC_API Value GetModulePrivate(JSObject* module);
201 * Perform the ModuleLink operation on the given source text module record.
203 * This transitively resolves all module dependencies (calling the
204 * HostResolveImportedModule hook) and initializes the environment record for
205 * the module.
207 extern JS_PUBLIC_API bool ModuleLink(JSContext* cx,
208 Handle<JSObject*> moduleRecord);
211 * Perform the ModuleEvaluate operation on the given source text module record
212 * and returns a bool. A result value is returned in result and is either
213 * undefined (and ignored) or a promise (if Top Level Await is enabled).
215 * If this module has already been evaluated, it returns the evaluation
216 * promise. Otherwise, it transitively evaluates all dependences of this module
217 * and then evaluates this module.
219 * ModuleLink must have completed prior to calling this.
221 extern JS_PUBLIC_API bool ModuleEvaluate(JSContext* cx,
222 Handle<JSObject*> moduleRecord,
223 MutableHandleValue rval);
225 enum ModuleErrorBehaviour {
226 // Report module evaluation errors asynchronously when the evaluation promise
227 // is rejected. This is used for web content.
228 ReportModuleErrorsAsync,
230 // Throw module evaluation errors synchronously by setting an exception on the
231 // context. Does not support modules that use top-level await.
232 ThrowModuleErrorsSync
236 * If a module evaluation fails, unwrap the resulting evaluation promise
237 * and rethrow.
239 * This does nothing if this module succeeds in evaluation. Otherwise, it
240 * takes the reason for the module throwing, unwraps it and throws it as a
241 * regular error rather than as an uncaught promise.
243 * ModuleEvaluate must have completed prior to calling this.
245 extern JS_PUBLIC_API bool ThrowOnModuleEvaluationFailure(
246 JSContext* cx, Handle<JSObject*> evaluationPromise,
247 ModuleErrorBehaviour errorBehaviour = ReportModuleErrorsAsync);
250 * Functions to access the module specifiers of a source text module record used
251 * to request module imports.
253 * Clients can use GetRequestedModulesCount() to get the number of specifiers
254 * and GetRequestedModuleSpecifier() / GetRequestedModuleSourcePos() to get the
255 * individual elements.
257 extern JS_PUBLIC_API uint32_t
258 GetRequestedModulesCount(JSContext* cx, Handle<JSObject*> moduleRecord);
260 extern JS_PUBLIC_API JSString* GetRequestedModuleSpecifier(
261 JSContext* cx, Handle<JSObject*> moduleRecord, uint32_t index);
264 * Get the position of a requested module's name in the source.
266 extern JS_PUBLIC_API void GetRequestedModuleSourcePos(
267 JSContext* cx, Handle<JSObject*> moduleRecord, uint32_t index,
268 uint32_t* lineNumber, JS::ColumnNumberOneOrigin* columnNumber);
271 * Get the top-level script for a module which has not yet been executed.
273 extern JS_PUBLIC_API JSScript* GetModuleScript(Handle<JSObject*> moduleRecord);
275 extern JS_PUBLIC_API JSObject* CreateModuleRequest(
276 JSContext* cx, Handle<JSString*> specifierArg);
277 extern JS_PUBLIC_API JSString* GetModuleRequestSpecifier(
278 JSContext* cx, Handle<JSObject*> moduleRequestArg);
281 * Get the module record for a module script.
283 extern JS_PUBLIC_API JSObject* GetModuleObject(Handle<JSScript*> moduleScript);
286 * Get the namespace object for a module.
288 extern JS_PUBLIC_API JSObject* GetModuleNamespace(
289 JSContext* cx, Handle<JSObject*> moduleRecord);
291 extern JS_PUBLIC_API JSObject* GetModuleForNamespace(
292 JSContext* cx, Handle<JSObject*> moduleNamespace);
294 extern JS_PUBLIC_API JSObject* GetModuleEnvironment(
295 JSContext* cx, Handle<JSObject*> moduleObj);
298 * Clear all bindings in a module's environment. Used during shutdown.
300 extern JS_PUBLIC_API void ClearModuleEnvironment(JSObject* moduleObj);
302 extern JS_PUBLIC_API bool ModuleIsLinked(JSObject* moduleObj);
304 } // namespace JS
306 #endif // js_Modules_h