tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

Modules.h (12746B)


      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/. */
      6 
      7 /* JavaScript module (as in, the syntactic construct) operations. */
      8 
      9 #ifndef js_Modules_h
     10 #define js_Modules_h
     11 
     12 #include <stdint.h>  // uint32_t
     13 
     14 #include "jstypes.h"  // JS_PUBLIC_API
     15 
     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
     22 
     23 struct JS_PUBLIC_API JSContext;
     24 class JS_PUBLIC_API JSObject;
     25 struct JS_PUBLIC_API JSRuntime;
     26 class JS_PUBLIC_API JSString;
     27 
     28 namespace JS {
     29 template <typename UnitT>
     30 class SourceText;
     31 }  // namespace JS
     32 
     33 namespace mozilla {
     34 union Utf8Unit;
     35 }
     36 
     37 namespace JS {
     38 
     39 // This enum is used to index into an array, and we assume that we have
     40 // sequential numbers starting at zero for the unknown type.
     41 enum class ModuleType : uint32_t {
     42  Unknown = 0,
     43  JavaScript,
     44  JSON,
     45  CSS,
     46  Bytes,
     47 
     48  // The specification has renamed the "javascript" module type to
     49  // "javascript-or-wasm". For now, we'll add JavaScriptOrWasm as
     50  // an alias of JavaScript. Code that's been updated to handle
     51  // wasm modules will use JavaScriptOrWasm, other code will continue
     52  // to use JavaScript. Once everything has been updated to use
     53  // JavaScriptOrWasm, we'll can just rename JavaScript to JavaScriptOrWasm.
     54  JavaScriptOrWasm = JavaScript,
     55 
     56  Limit = Bytes,
     57 };
     58 
     59 /**
     60 * The HostLoadImportedModule hook.
     61 *
     62 * See: https://tc39.es/ecma262/#sec-HostLoadImportedModule
     63 *
     64 * This embedding-defined hook is used to implement module loading. It is called
     65 * to get or create a module object corresponding to |moduleRequest| occurring
     66 * in the context of the script or module |referrer| with private value
     67 * |referencingPrivate|.
     68 *
     69 * The module specifier string for the request can be obtained by calling
     70 * JS::GetModuleRequestSpecifier.
     71 *
     72 * The private value for a script or module is set with JS::SetScriptPrivate or
     73 * JS::SetModulePrivate. It's assumed that the embedding can handle receiving
     74 * either here.
     75 *
     76 * If this call succeeds then the embedding must call
     77 * FinishLoadingImportedModule or one of the FinishLoadingImportedModuleFailed
     78 * APIs at some point in the future. This is handled by the engine if the call
     79 * returns false.
     80 *
     81 * This hook must obey the restrictions defined in the spec:
     82 *  - Each time the hook is called with the same (referrer, referencingPrivate)
     83 *    pair, then it must call FinishLoadingImportedModule with the same result
     84 *    each time.
     85 *  - The operation must treat the |payload| argument as an opaque
     86 *    value to be passed through to FinishLoadingImportedModule.
     87 */
     88 using ModuleLoadHook = bool (*)(JSContext* cx, Handle<JSScript*> referrer,
     89                                Handle<JSObject*> moduleRequest,
     90                                Handle<Value> hostDefined,
     91                                Handle<Value> payload, uint32_t lineNumber,
     92                                JS::ColumnNumberOneOrigin columnNumber);
     93 
     94 /**
     95 * Get the HostLoadImportedModule hook for the runtime.
     96 */
     97 extern JS_PUBLIC_API ModuleLoadHook GetModuleLoadHook(JSRuntime* rt);
     98 
     99 /**
    100 * Set the HostLoadImportedModule hook for the runtime to the given function.
    101 */
    102 extern JS_PUBLIC_API void SetModuleLoadHook(JSRuntime* rt, ModuleLoadHook func);
    103 
    104 using LoadModuleResolvedCallback = bool (*)(JSContext* cx,
    105                                            JS::Handle<JS::Value>);
    106 using LoadModuleRejectedCallback = bool (*)(JSContext* cx,
    107                                            JS::Handle<JS::Value> hostDefined,
    108                                            Handle<JS::Value> error);
    109 
    110 /**
    111 * https://tc39.es/ecma262/#sec-LoadRequestedModules
    112 *
    113 * Load the dependency module graph of the parameter 'module'.
    114 *
    115 * The spec defines using 'promise objects' to notify the result.
    116 * To address the synchronous loading behavior from mozJSModuleLoader, an
    117 * overloaded version that takes function callbacks to notify the result is also
    118 * provided.
    119 */
    120 extern JS_PUBLIC_API bool LoadRequestedModules(
    121    JSContext* cx, Handle<JSObject*> module, Handle<Value> hostDefined,
    122    LoadModuleResolvedCallback resolved, LoadModuleRejectedCallback rejected);
    123 
    124 extern JS_PUBLIC_API bool LoadRequestedModules(
    125    JSContext* cx, Handle<JSObject*> module, Handle<Value> hostDefined,
    126    MutableHandle<JSObject*> promiseOut);
    127 
    128 /**
    129 * The module metadata hook.
    130 *
    131 * See: https://tc39.es/ecma262/#sec-hostgetimportmetaproperties
    132 *
    133 * Populate the |metaObject| object returned when import.meta is evaluated in
    134 * the context of the script or module with private value |privateValue|.
    135 *
    136 * This is based on the spec's HostGetImportMetaProperties hook but defines
    137 * properties on the meta object directly rather than returning a list.
    138 */
    139 using ModuleMetadataHook = bool (*)(JSContext* cx, Handle<Value> privateValue,
    140                                    Handle<JSObject*> metaObject);
    141 
    142 /**
    143 * Get the hook for populating the import.meta metadata object.
    144 */
    145 extern JS_PUBLIC_API ModuleMetadataHook GetModuleMetadataHook(JSRuntime* rt);
    146 
    147 /**
    148 * Set the hook for populating the import.meta metadata object to the given
    149 * function.
    150 */
    151 extern JS_PUBLIC_API void SetModuleMetadataHook(JSRuntime* rt,
    152                                                ModuleMetadataHook func);
    153 
    154 /**
    155 * A function callback called by the host layer to indicate the call of
    156 * HostLoadImportedModule has finished.
    157 *
    158 * See https://tc39.es/ecma262/#sec-FinishLoadingImportedModule
    159 */
    160 extern JS_PUBLIC_API bool FinishLoadingImportedModule(
    161    JSContext* cx, Handle<JSScript*> referrer, Handle<JSObject*> moduleRequest,
    162    Handle<Value> payload, Handle<JSObject*> result, bool usePromise);
    163 
    164 /**
    165 * Overloaded version of FinishLoadingImportedModule for error handling.
    166 */
    167 extern JS_PUBLIC_API bool FinishLoadingImportedModuleFailed(
    168    JSContext* cx, Handle<Value> payload, Handle<Value> error);
    169 
    170 extern JS_PUBLIC_API bool FinishLoadingImportedModuleFailedWithPendingException(
    171    JSContext* cx, Handle<Value> payload);
    172 
    173 /**
    174 * Parse the given source buffer as a module in the scope of the current global
    175 * of cx and return a source text module record.
    176 */
    177 extern JS_PUBLIC_API JSObject* CompileModule(
    178    JSContext* cx, const ReadOnlyCompileOptions& options,
    179    SourceText<char16_t>& srcBuf);
    180 
    181 /**
    182 * Parse the given source buffer as a module in the scope of the current global
    183 * of cx and return a source text module record.  An error is reported if a
    184 * UTF-8 encoding error is encountered.
    185 */
    186 extern JS_PUBLIC_API JSObject* CompileModule(
    187    JSContext* cx, const ReadOnlyCompileOptions& options,
    188    SourceText<mozilla::Utf8Unit>& srcBuf);
    189 
    190 /**
    191 * Parse the given source buffer as a JSON module in the scope of the current
    192 * global of cx and return a synthetic module record.
    193 */
    194 extern JS_PUBLIC_API JSObject* CompileJsonModule(
    195    JSContext* cx, const ReadOnlyCompileOptions& options,
    196    SourceText<char16_t>& srcBuf);
    197 
    198 /**
    199 * Parse the given source buffer as a JSON module in the scope of the current
    200 * global of cx and return a synthetic module record. An error is reported if a
    201 * UTF-8 encoding error is encountered.
    202 */
    203 extern JS_PUBLIC_API JSObject* CompileJsonModule(
    204    JSContext* cx, const ReadOnlyCompileOptions& options,
    205    SourceText<mozilla::Utf8Unit>& srcBuf);
    206 
    207 /**
    208 * Create a synthetic module record that exports a single value as its default
    209 * export. The caller is responsible for providing the already-constructed
    210 * value to export.
    211 *
    212 * This matches the ECMAScript specification's definition:
    213 * https://tc39.es/ecma262/#sec-create-default-export-synthetic-module
    214 */
    215 extern JS_PUBLIC_API JSObject* CreateDefaultExportSyntheticModule(
    216    JSContext* cx, const Value& defaultExport);
    217 
    218 /**
    219 * Parse the given source buffer as a module in the scope of the current global
    220 * of cx and return a source text module record.
    221 */
    222 extern JS_PUBLIC_API JSObject* CompileWasmModule(
    223    JSContext* cx, const ReadOnlyCompileOptions& options,
    224    SourceText<char16_t>& srcBuf);
    225 
    226 /**
    227 * Parse the given source buffer as a module in the scope of the current global
    228 * of cx and return a source text module record.
    229 */
    230 extern JS_PUBLIC_API JSObject* CompileWasmModule(
    231    JSContext* cx, const ReadOnlyCompileOptions& options,
    232    SourceText<mozilla::Utf8Unit>& srcBuf);
    233 
    234 /**
    235 * Set a private value associated with a source text module record.
    236 */
    237 extern JS_PUBLIC_API void SetModulePrivate(JSObject* module,
    238                                           const Value& value);
    239 /**
    240 * Clear the private value associated with a source text module record.
    241 *
    242 * This is used during unlinking and can be called on a gray module, skipping
    243 * the usual checks.
    244 */
    245 extern JS_PUBLIC_API void ClearModulePrivate(JSObject* module);
    246 
    247 /**
    248 * Get the private value associated with a source text module record.
    249 */
    250 extern JS_PUBLIC_API Value GetModulePrivate(JSObject* module);
    251 
    252 /**
    253 * Checks if the given module is a cyclic module.
    254 */
    255 extern JS_PUBLIC_API bool IsCyclicModule(JSObject* module);
    256 
    257 /*
    258 * Perform the ModuleLink operation on the given source text module record.
    259 *
    260 * This transitively resolves all module dependencies (calling the
    261 * HostResolveImportedModule hook) and initializes the environment record for
    262 * the module.
    263 */
    264 extern JS_PUBLIC_API bool ModuleLink(JSContext* cx,
    265                                     Handle<JSObject*> moduleRecord);
    266 
    267 /*
    268 * Perform the ModuleEvaluate operation on the given source text module record
    269 * and returns a bool. A result value is returned in result and is either
    270 * undefined (and ignored) or a promise (if Top Level Await is enabled).
    271 *
    272 * If this module has already been evaluated, it returns the evaluation
    273 * promise. Otherwise, it transitively evaluates all dependences of this module
    274 * and then evaluates this module.
    275 *
    276 * ModuleLink must have completed prior to calling this.
    277 */
    278 extern JS_PUBLIC_API bool ModuleEvaluate(JSContext* cx,
    279                                         Handle<JSObject*> moduleRecord,
    280                                         MutableHandleValue rval);
    281 
    282 enum ModuleErrorBehaviour {
    283  // Report module evaluation errors asynchronously when the evaluation promise
    284  // is rejected. This is used for web content.
    285  ReportModuleErrorsAsync,
    286 
    287  // Throw module evaluation errors synchronously by setting an exception on the
    288  // context. Does not support modules that use top-level await.
    289  ThrowModuleErrorsSync
    290 };
    291 
    292 /*
    293 * If a module evaluation fails, unwrap the resulting evaluation promise
    294 * and rethrow.
    295 *
    296 * This does nothing if this module succeeds in evaluation. Otherwise, it
    297 * takes the reason for the module throwing, unwraps it and throws it as a
    298 * regular error rather than as an uncaught promise.
    299 *
    300 * ModuleEvaluate must have completed prior to calling this.
    301 */
    302 extern JS_PUBLIC_API bool ThrowOnModuleEvaluationFailure(
    303    JSContext* cx, Handle<JSObject*> evaluationPromise,
    304    ModuleErrorBehaviour errorBehaviour = ReportModuleErrorsAsync);
    305 
    306 /*
    307 * Get the module type of a requested module.
    308 */
    309 extern JS_PUBLIC_API ModuleType GetRequestedModuleType(
    310    JSContext* cx, Handle<JSObject*> moduleRecord, uint32_t index);
    311 
    312 /*
    313 * Get the top-level script for a module which has not yet been executed.
    314 */
    315 extern JS_PUBLIC_API JSScript* GetModuleScript(Handle<JSObject*> moduleRecord);
    316 
    317 extern JS_PUBLIC_API JSString* GetModuleRequestSpecifier(
    318    JSContext* cx, Handle<JSObject*> moduleRequestArg);
    319 
    320 /*
    321 * Get the module type of the specified module request.
    322 */
    323 extern JS_PUBLIC_API ModuleType
    324 GetModuleRequestType(JSContext* cx, Handle<JSObject*> moduleRequestArg);
    325 
    326 /*
    327 * Get the module record for a module script.
    328 */
    329 extern JS_PUBLIC_API JSObject* GetModuleObject(Handle<JSScript*> moduleScript);
    330 
    331 /*
    332 * Get the namespace object for a module.
    333 */
    334 extern JS_PUBLIC_API JSObject* GetModuleNamespace(
    335    JSContext* cx, Handle<JSObject*> moduleRecord);
    336 
    337 extern JS_PUBLIC_API JSObject* GetModuleForNamespace(
    338    JSContext* cx, Handle<JSObject*> moduleNamespace);
    339 
    340 extern JS_PUBLIC_API JSObject* GetModuleEnvironment(
    341    JSContext* cx, Handle<JSObject*> moduleObj);
    342 
    343 /*
    344 * Clear all bindings in a module's environment. Used during shutdown.
    345 */
    346 extern JS_PUBLIC_API void ClearModuleEnvironment(JSObject* moduleObj);
    347 
    348 extern JS_PUBLIC_API bool ModuleIsLinked(JSObject* moduleObj);
    349 
    350 }  // namespace JS
    351 
    352 #endif  // js_Modules_h