1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330
|
/* -*- 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 {
// This enum is used to index into an array, and we assume that we have
// sequential numbers starting at zero for the unknown type.
enum class ModuleType : uint32_t {
Unknown = 0,
JavaScript,
JSON,
CSS,
Bytes,
Limit = Bytes,
};
/**
* The HostLoadImportedModule hook.
*
* See: https://tc39.es/ecma262/#sec-HostLoadImportedModule
*
* 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 |referrer| 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.
*
* If this call succeeds then the embedding must call
* FinishLoadingImportedModule or one of the FinishLoadingImportedModuleFailed
* APIs at some point in the future. This is handled by the engine if the call
* returns false.
*
* This hook must obey the restrictions defined in the spec:
* - Each time the hook is called with the same (referrer, referencingPrivate)
* pair, then it must call FinishLoadingImportedModule with the same result
* each time.
* - The operation must treat the |payload| argument as an opaque
* value to be passed through to FinishLoadingImportedModule.
*/
using ModuleLoadHook = bool (*)(JSContext* cx, Handle<JSScript*> referrer,
Handle<JSObject*> moduleRequest,
Handle<Value> hostDefined,
Handle<Value> payload, uint32_t lineNumber,
JS::ColumnNumberOneOrigin columnNumber);
/**
* Get the HostLoadImportedModule hook for the runtime.
*/
extern JS_PUBLIC_API ModuleLoadHook GetModuleLoadHook(JSRuntime* rt);
/**
* Set the HostLoadImportedModule hook for the runtime to the given function.
*/
extern JS_PUBLIC_API void SetModuleLoadHook(JSRuntime* rt, ModuleLoadHook func);
using LoadModuleResolvedCallback = bool (*)(JSContext* cx,
JS::Handle<JS::Value>);
using LoadModuleRejectedCallback = bool (*)(JSContext* cx,
JS::Handle<JS::Value> hostDefined,
Handle<JS::Value> error);
/**
* https://tc39.es/ecma262/#sec-LoadRequestedModules
*
* Load the dependency module graph of the parameter 'module'.
*
* The spec defines using 'promise objects' to notify the result.
* To address the synchronous loading behavior from mozJSModuleLoader, an
* overloaded version that takes function callbacks to notify the result is also
* provided.
*/
extern JS_PUBLIC_API bool LoadRequestedModules(
JSContext* cx, Handle<JSObject*> module, Handle<Value> hostDefined,
LoadModuleResolvedCallback resolved, LoadModuleRejectedCallback rejected);
extern JS_PUBLIC_API bool LoadRequestedModules(
JSContext* cx, Handle<JSObject*> module, Handle<Value> hostDefined,
MutableHandle<JSObject*> promiseOut);
/**
* 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);
/**
* A function callback called by the host layer to indicate the call of
* HostLoadImportedModule has finished.
*
* See https://tc39.es/ecma262/#sec-FinishLoadingImportedModule
*/
extern JS_PUBLIC_API bool FinishLoadingImportedModule(
JSContext* cx, Handle<JSScript*> referrer, Handle<JSObject*> moduleRequest,
Handle<Value> payload, Handle<JSObject*> result, bool usePromise);
/**
* Overloaded version of FinishLoadingImportedModule for error handling.
*/
extern JS_PUBLIC_API bool FinishLoadingImportedModuleFailed(
JSContext* cx, Handle<Value> payload, Handle<Value> error);
extern JS_PUBLIC_API bool FinishLoadingImportedModuleFailedWithPendingException(
JSContext* cx, Handle<Value> payload);
/**
* 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);
/**
* Parse the given source buffer as a JSON module in the scope of the current
* global of cx and return a synthetic module record.
*/
extern JS_PUBLIC_API JSObject* CompileJsonModule(
JSContext* cx, const ReadOnlyCompileOptions& options,
SourceText<char16_t>& srcBuf);
/**
* Parse the given source buffer as a JSON module in the scope of the current
* global of cx and return a synthetic module record. An error is reported if a
* UTF-8 encoding error is encountered.
*/
extern JS_PUBLIC_API JSObject* CompileJsonModule(
JSContext* cx, const ReadOnlyCompileOptions& options,
SourceText<mozilla::Utf8Unit>& srcBuf);
/**
* Create a synthetic module record that exports a single value as its default
* export. The caller is responsible for providing the already-constructed
* value to export.
*
* This matches the ECMAScript specification's definition:
* https://tc39.es/ecma262/#sec-create-default-export-synthetic-module
*/
extern JS_PUBLIC_API JSObject* CreateDefaultExportSyntheticModule(
JSContext* cx, const Value& defaultExport);
/**
* 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);
/**
* Checks if the given module is a cyclic module.
*/
extern JS_PUBLIC_API bool IsCyclicModule(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);
/*
* Get the module type of a requested module.
*/
extern JS_PUBLIC_API ModuleType GetRequestedModuleType(
JSContext* cx, Handle<JSObject*> moduleRecord, uint32_t index);
/*
* 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, ModuleType moduleType);
extern JS_PUBLIC_API JSString* GetModuleRequestSpecifier(
JSContext* cx, Handle<JSObject*> moduleRequestArg);
/*
* Get the module type of the specified module request.
*/
extern JS_PUBLIC_API ModuleType
GetModuleRequestType(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);
extern JS_PUBLIC_API bool ModuleIsLinked(JSObject* moduleObj);
} // namespace JS
#endif // js_Modules_h
|