Stage 1 Draft / September 10, 2020

Builtin Modules

Introduction

Proposal to add a mechanism for enabling a more extensive standard library in JavaScript via a collection of built in modules. With this infrastructure in place it will be possible to start iterating on standard library features as additional modules.

1 Scope

This Standard defines the ECMAScript 2021 general-purpose programming language.

2 ECMAScript Language: Scripts and Modules

2.1 Scripts

...

2.2 Modules

Syntax

Module:ModuleBodyopt ModuleBody:ModuleItemList ModuleItemList:ModuleItem ModuleItemListModuleItem ModuleItem:ImportDeclaration ExportDeclaration StatementListItem[~Yield, ~Await, ~Return]

2.2.1 Module Semantics

2.2.1.1 Abstract Module Records

A Module Record encapsulates structural information about the imports and exports of a single module. This information is used to link the imports and exports of sets of connected modules. A Module Record includes four fields that are only used when evaluating a module.

For specification purposes Module Record values are values of the Record specification type and can be thought of as existing in a simple object-oriented hierarchy where Module Record is an abstract class with both abstract and concrete subclasses. This specification defines the abstract subclass named Cyclic Module Record and its concrete subclass named Source Text Module Record. Other specifications and implementations may define additional Module Record subclasses corresponding to alternative module definition facilities that they defined.

Module Record defines the fields listed in Table 1. All Module Definition subclasses include at least those fields. Module Record also defines the abstract method list in Table 2. All Module definition subclasses must provide concrete implementations of these abstract methods.

Table 1: Module Record Fields
Field Name Value Type Meaning
[[Realm]] Realm Record | undefined The Realm within which this module was created. undefined if not yet assigned.
[[Environment]] module Environment Record | undefined The Environment Record containing the top level bindings for this module. This field is set when the module is linked.
[[Namespace]] Object | undefined The Module Namespace Object (26.3) if one has been created for this module. Otherwise undefined.
[[HostDefined]] Any, default value is undefined. Field reserved for use by host environments that need to associate additional information with a module.
Table 2: Abstract Methods of Module Records
Method Purpose
GetExportedNames([exportStarSet]) Return a list of all names that are either directly or indirectly exported from this module.
ResolveExport(exportName [, resolveSet])

Return the binding of a name exported by this module. Bindings are represented by a ResolvedBinding Record, of the form { [[Module]]: Module Record, [[BindingName]]: String }. If the export is a Module Namespace Object without a direct binding in any module, [[BindingName]] will be set to "*namespace*". Return null if the name cannot be resolved, or "ambiguous" if multiple bindings were found.

Each time this operation is called with a specific exportName, resolveSet pair as arguments it must return the same result if it completes normally.

Link()

Prepare the module for evaluation by transitively resolving all module dependencies and creating a module Environment Record.

Evaluate()

If this module has already been evaluated successfully, return undefined; if it has already been evaluated unsuccessfully, throw the exception that was produced. Otherwise, transitively evaluate all module dependencies of this module and then evaluate this module.

Link must have completed successfully prior to invoking this method.

2.2.1.2 Synthetic Module Records

A Synthetic Module Record is used to represent information about a module that is defined by specifications. Its exports are derived from a pair of lists, of string keys and of ECMAScript values. The set of exported names is static, and determined at creation time (as an argument to CreateSyntheticModule), while the set of exported values can be changed over time using SetModuleExport. It has no imports or dependencies.

Note
A Synthetic Module Record could be used for defining a variety of module types: for example, built-in modules, or JSON modules, or CSS modules.

In addition to the fields defined in Table 1, Synthetic Module Records have the additional fields listed in Table 3. Each of these fields is initially set in CreateSyntheticModule.

Table 3: Additional Fields of Synthetic Module Records
Field Name Value Type Meaning
[[ExportNames]] List of String A List of all names that are exported.
[[IsFrozen]] Boolean If true, the module cannot be modified.
[[EvaluationSteps]] An abstract operation An abstract operation that will be performed upon evaluation of the module, taking the Synthetic Module Record as its sole argument. These will usually set up the exported values, by using SetModuleExport. They must not modify [[ExportNames]]. They may return an abrupt completion.

2.2.1.2.1 CreateSyntheticModule ( exportNames, evaluationSteps, realm, hostDefined )

The abstract operation CreateSyntheticModule creates a Synthetic Module Record based upon the given exported names and evaluation steps. It performs the following steps:

  1. Return Synthetic Module Record { [[Realm]]: realm, [[Environment]]: undefined, [[Namespace]]: undefined, [[HostDefined]]: hostDefined, [[ExportNames]]: exportNames, [[IsFrozen]]: false, [[EvaluationSteps]]: evaluationSteps }.
Editor's Note
It seems we could set up the environment either here or in Instantiate(). I've chosen to do so in Instantiate() for symmetry with Source Text Module Records, but I don't think there's any actual requirement in that regard.

2.2.1.2.2 Concrete Methods

The following are the concrete methods for Synthetic Module Record that implement the corresponding Module Record abstract methods.

Editor's Note
I find having this wrapping sub-clause cleaner and suggest we do the same for Source Text Module Records in the main spec.

2.2.1.2.2.1 Freeze ( )

The Freeze concrete method of a Synthetic Module Record implements the corresponding Module Record abstract method.

It performs the following steps:

  1. Let module be this Synthetic Module Record.
  2. Set module.[[IsFrozen]] to true.

2.2.1.2.2.2 GetExportedNames ( exportStarSet )

The GetExportedNames concrete method of a Synthetic Module Record implements the corresponding Module Record abstract method.

It performs the following steps:

  1. Let module be this Synthetic Module Record.
  2. Return module.[[ExportNames]].

2.2.1.2.2.3 ResolveExport ( exportName, resolveSet )

The ResolveExport concrete method of a Synthetic Module Record implements the corresponding Module Record abstract method.

It performs the following steps:

  1. Let module be this Synthetic Module Record.
  2. If module.[[ExportNames]] does not contain exportName, return null.
  3. Return ResolvedBinding Record { [[Module]]: module, [[BindingName]]: exportName }.

2.2.1.2.2.4 SetModuleExport ( exportName, exportValue )

The abstract operation SetModuleExport can be used to set or change the exported value for a pre-established export of a Synthetic Module Record. It performs the following steps:

  1. Let module be this Synthetic Module Record.
  2. Let envRec be module.[[Environment]]'s EnvironmentRecord.
  3. Perform envRec.SetMutableBinding(exportName, exportValue, true).

2.2.1.2.2.5 Instantiate ( )

The Instantiate concrete method of a Synthetic Module Record implements the corresponding Module Record abstract method.

It performs the following steps:

  1. Let module be this Synthetic Module Record.
  2. Let realm be module.[[Realm]].
  3. Assert: realm is not undefined.
  4. Let env be NewModuleEnvironment(realm.[[GlobalEnv]]).
  5. Set module.[[Environment]] to env.
  6. Let envRec be env's EnvironmentRecord.
  7. For each element exportName in module.[[ExportNames]], do
    1. Perform ! envRec.CreateMutableBinding(exportName, false).
    2. Perform ! envRec.InitializeBinding(exportName, undefined).
  8. Return undefined.

2.2.1.2.2.6 Evaluate ( )

The Evaluate concrete method of a Synthetic Module Record implements the corresponding Module Record abstract method.

It performs the following steps:

  1. Let module be this Synthetic Module Record.
  2. Let moduleCxt be a new ECMAScript code execution context.
  3. Set the Function of moduleCxt to null.
  4. Assert: module.[[Realm]] is not undefined.
  5. Set the Realm of moduleCxt to module.[[Realm]].
  6. Set the ScriptOrModule of moduleCxt to module.
  7. Set the VariableEnvironment of moduleCxt to module.[[Environment]].
  8. Set the LexicalEnvironment of moduleCxt to module.[[Environment]].
  9. Suspend the currently running execution context.
  10. Push moduleCxt on to the execution context stack; moduleCxt is now the running execution context.
  11. Let result be the result of performing ? module.[[EvaluationSteps]](module).
  12. Suspend moduleCxt and remove it from the execution context stack.
  13. Resume the context that is now on the top of the execution context stack as the running execution context.
  14. Return Completion(result).

2.2.1.2.3 Example uses of Synthetic Module Records

This non-normative section shows how one could define a few different Synthetic Module Records.

Editor's Note
Although these seem somewhat verbose, that is largely because ECMAScript specification text doesn't generally allow "closures" where you would define an algorithm or set of steps inline. Host environment specification styles are different, and hosts could write their synthetic module creation more compactly and concisely by inlining instead of using separately-defined evaluation steps.

2.2.1.2.3.1 A module wrapping a single object

The following algorithm, given an object object, creates a Synthetic Module Record which default-exports the object. This might be useful, for example, for JSON or CSS modules.

  1. Return CreateSyntheticModule"default" », ExampleObjectWrapperModuleEvaluation, the current Realm Record, object).

2.2.1.2.3.1.1 ExampleObjectWrapperModuleEvaluation ( module )

  1. Perform module.SetModuleExport( "default", module.[[HostDefined]]).

2.2.1.2.3.2 A "builtin module" for addition

The following algorithm creates a Synthetic Module Record with a single export, "add", which provides a built-in function object that adds its two arguments.

  1. Return CreateSyntheticModule"add" », ExampleAdderModuleEvaluation, the current Realm Record, undefined).

2.2.1.2.3.2.1 ExampleAdderModuleEvaluation ( module )

  1. Let adderSteps be the algorithm steps defined in Example Adder Functions.
  2. Let adderFunction be CreateBuiltinFunction(adderSteps).
  3. Perform moduleSetModuleExport( "add", adderFunction).

2.2.1.2.3.2.2 Example Adder Functions

An example adder function is an anonymous built-in function. When called with arguments arg1 and arg2, the following steps are taken:

  1. Set arg1 to ? ToNumber(arg1).
  2. Set arg2 to ? ToNumber(arg2).
  3. Return arg1 + arg2.

2.2.1.3 Runtime Semantics: HostHasBuiltinModule ( referencingScriptOrModule, specifier )

HostHasBuiltinModule is a host-defined abstract operation that provides a means check for a module registered with ModuleSpecifier String, specifier, occurring within the context of the script or module represented by the Script Record or Module Record referencingScriptOrModule. referencingScriptOrModule may also be null, if the resolution is being performed in the context of an import() expression, and there is no active script or module at that time.

The implementation of HostResolveBuiltinModule must conform to the following requirements:

  • The normal return value is a Boolean, true if a mtching module can be found and false otherwise.

Multiple different referencingScriptOrModule, specifier pairs may map to the same Module Record instance. The actual mapping semantic is host-defined but typically a normalization process is applied to specifier as part of the mapping process. A typical normalization process would include actions such as alphabetic case folding and expansion of relative and abbreviated path specifiers.

2.2.1.4 Runtime Semantics: HostCreateBuiltinModule ( referencingScriptOrModule, specifier, module )

HostCreateBuiltinModule is a host-defined abstract operation that adds a module defined by the Synthetic Module Record, module, with the key ModuleSpecifier String, specifier, within the context of the script or module represented by the Script Record or Module Record referencingScriptOrModule.

The implementation of HostCreateBuiltinModule must conform to the following requirements:

  • The value of referencingScriptOrModule must not be null.
  • If a Module Record corresponding to the pair referencingScriptOrModule, specifier already exists, it is replaced.

2.2.1.5 Runtime Semantics: HostResolveBuiltinModule ( referencingScriptOrModule, specifier )

HostResolveBuiltinModule is a host-defined abstract operation that provides the Synthetic Module Record instance that corresponds to the ModuleSpecifier String, specifier, occurring within the context of the script or module represented by the Script Record or Module Record referencingScriptOrModule. referencingScriptOrModule may also be null, if the resolution is being performed in the context of an import() expression, and there is no active script or module at that time.

Note

It is possible for a host to implement this abstract operation with HostResolveImportedModule.

The implementation of HostResolveBuiltinModule must conform to the following requirements:

  • The normal return value must be an instance of a Synthetic Module Record.
  • If a Module Record corresponding to the pair referencingScriptOrModule, specifier does not exist or cannot be created, an exception must be thrown.
  • Each time this operation is called with a specific referencingScriptOrModule, specifier pair as arguments it must return the same Module Record instance if it completes normally.

Multiple different referencingScriptOrModule, specifier pairs may map to the same Module Record instance. The actual mapping semantic is host-defined but typically a normalization process is applied to specifier as part of the mapping process. A typical normalization process would include actions such as alphabetic case folding and expansion of relative and abbreviated path specifiers.

2.2.1.6 Runtime Semantics: HostResolveImportedModule ( referencingScriptOrModule, specifier )

HostResolveImportedModule is a host-defined abstract operation that provides the concrete Module Record subclass instance that corresponds to the ModuleSpecifier String, specifier, occurring within the context of the script or module represented by the Script Record or Module Record referencingScriptOrModule. referencingScriptOrModule may also be null, if the resolution is being performed in the context of an import() expression, and there is no active script or module at that time.

Note

An example of when referencingScriptOrModule can be null is in a web browser host. There, if a user clicks on a control given by

<button type="button" onclick="import('./foo.mjs')">Click me</button>

there will be no active script or module at the time the import() expression runs. More generally, this can happen in any situation where the host pushes execution contexts with null ScriptOrModule components onto the execution context stack.

The implementation of HostResolveImportedModule must conform to the following requirements:

  • The normal return value must be an instance of a concrete subclass of Module Record.
  • If a Module Record corresponding to the pair referencingScriptOrModule, specifier does not exist or cannot be created, an exception must be thrown.
  • Each time this operation is called with a specific referencingScriptOrModule, specifier pair as arguments it must return the same Module Record instance if it completes normally.

Multiple different referencingScriptOrModule, specifier pairs may map to the same Module Record instance. The actual mapping semantic is host-defined but typically a normalization process is applied to specifier as part of the mapping process. A typical normalization process would include actions such as alphabetic case folding and expansion of relative and abbreviated path specifiers.

2.2.1.7 Runtime Semantics: HostImportModuleDynamically ( referencingScriptOrModule, specifier, promiseCapability )

HostImportModuleDynamically is a host-defined abstract operation that performs any necessary setup work in order to make available the module corresponding to the ModuleSpecifier String, specifier, occurring within the context of the script or module represented by the Script Record or Module Record referencingScriptOrModule. (referencingScriptOrModule may also be null, if there is no active script or module when the import() expression occurs.) It then performs FinishDynamicImport to finish the dynamic import process.

The implementation of HostImportModuleDynamically must conform to the following requirements:

  • The abstract operation must always complete normally with undefined. Success or failure must instead be signaled as discussed below.
  • The host environment must conform to one of the two following sets of requirements:
    Success path
    • At some future time, the host environment must perform FinishDynamicImport(referencingScriptOrModule, specifier, promiseCapability, NormalCompletion(undefined)).
    • Any subsequent call to HostResolveImportedModule after FinishDynamicImport has completed, given the arguments referencingScriptOrModule and specifier, must complete normally.
    • The completion value of any subsequent call to HostResolveImportedModule after FinishDynamicImport has completed, given the arguments referencingScriptOrModule and specifier, must be a module which has already been evaluated, i.e. whose Evaluate concrete method has already been called and returned a normal completion.
    Failure path
  • If the host environment takes the success path once for a given referencingScriptOrModule, specifier pair, it must always do so for subsequent calls.
  • The operation must not call promiseCapability.[[Resolve]] or promiseCapability.[[Reject]], but instead must treat promiseCapability as an opaque identifying value to be passed through to FinishDynamicImport.

The actual process performed is host-defined, but typically consists of performing whatever I/O operations are necessary to allow HostResolveImportedModule to synchronously retrieve the appropriate Module Record, and then calling its Evaluate concrete method. This might require performing similar normalization as HostResolveImportedModule does.

2.2.1.8 Runtime Semantics: FinishDynamicImport ( referencingScriptOrModule, specifier, promiseCapability, completion )

The abstract operation FinishDynamicImport takes arguments referencingScriptOrModule, specifier, promiseCapability (a PromiseCapability Record), and completion. FinishDynamicImport completes the process of a dynamic import originally started by an import() call, resolving or rejecting the promise returned by that call as appropriate according to completion. It is performed by host environments as part of HostImportModuleDynamically. It performs the following steps when called:

  1. If completion is an abrupt completion, then perform ! Call(promiseCapability.[[Reject]], undefined, « completion.[[Value]] »).
  2. Else,
    1. Assert: completion is a normal completion and completion.[[Value]] is undefined.
    2. Let moduleRecord be ! HostResolveImportedModule(referencingScriptOrModule, specifier).
    3. Assert: Evaluate has already been invoked on moduleRecord and successfully completed.
    4. Let namespace be GetModuleNamespace(moduleRecord).
    5. If namespace is an abrupt completion, perform ! Call(promiseCapability.[[Reject]], undefined, « namespace.[[Value]] »).
    6. Else, perform ! Call(promiseCapability.[[Resolve]], undefined, « namespace.[[Value]] »).

2.2.1.9 Runtime Semantics: GetModuleNamespace ( module )

The abstract operation GetModuleNamespace takes argument module. It retrieves the Module Namespace Object representing module's exports, lazily creating it the first time it was requested, and storing it in module.[[Namespace]] for future retrieval. It performs the following steps when called:

  1. Assert: module is an instance of a concrete subclass of Module Record.
  2. Assert: If module is a Cyclic Module Record, then module.[[Status]] is not unlinked.
  3. Let namespace be module.[[Namespace]].
  4. If namespace is undefined, then
    1. Let exportedNames be ? module.GetExportedNames().
    2. Let unambiguousNames be a new empty List.
    3. For each element name of exportedNames, do
      1. Let resolution be ? module.ResolveExport(name).
      2. If resolution is a ResolvedBinding Record, append name to unambiguousNames.
    4. Set namespace to ModuleNamespaceCreate(module, unambiguousNames).
  5. Return namespace.
Note

The only way GetModuleNamespace can throw is via one of the triggered HostResolveImportedModule calls. Unresolvable names are simply excluded from the namespace at this point. They will lead to a real linking error later unless they are all ambiguous star exports that are not explicitly requested anywhere.

2.2.1.10 Runtime Semantics: Evaluation

Module:[empty]
  1. Return NormalCompletion(undefined).
ModuleBody:ModuleItemList
  1. Let result be the result of evaluating ModuleItemList.
  2. If result.[[Type]] is normal and result.[[Value]] is empty, then
    1. Return NormalCompletion(undefined).
  3. Return Completion(result).
ModuleItemList:ModuleItemListModuleItem
  1. Let sl be the result of evaluating ModuleItemList.
  2. ReturnIfAbrupt(sl).
  3. Let s be the result of evaluating ModuleItem.
  4. Return Completion(UpdateEmpty(s, sl)).
Note

The value of a ModuleItemList is the value of the last value-producing item in the ModuleItemList.

ModuleItem:ImportDeclaration
  1. Return NormalCompletion(empty).

3 ECMAScript Language: Standard Library

The Standard Library contains a set of modules builtin within the implementation. These builtin library modules may reside within the ECMAScript language implementation or they may be part of the containing host.

3.1 Standard Library Imports

Importing a library follows the same syntax as importing any other type of module. The difference is the format of the StringLiteral of a standard library begins with a ModuleDomain that specifies where the module resides. For ECMAScript modules, the ModuleDomain is js:. Host environments can define additional ModuleDomains.

Syntax

ModuleSpecifier:ModuleDomainStringLiteral ModuleDomain:js:

Builtin Module List

A Map of provided builtin modules is included in the global environment. That Map contains a Builtin Module Record for each builtin module availble within the implementation. The fields of Builtin Module Records are specified in Table 4.

Table 4: Builtin Module Record Fields
Field Name Value Meaning
[[Identifier]] String The name used to refer to this Builtin Library. This must be unique in the Map of builtin library modules.
[[SyntheticModuleRecord]] ModuleRecord The module record for builtin library.
[[HostDefined]] Any, default value is undefined. Field reserved for use by host environments that need to associate additional information with this Library.

Loaders

A Loader provides the means of resolving and loading builtin modules stored in an implementation defined way. There can be multiple loaders, each responsible for resolving and loading builtin modules. Multiple loaders can resolve the modules specified with the same ModuleSpecifier. A loader must implement the methods described in Table 7. The base ECMAScript loader is included in the global environment.

Global Environment

The following additional fields are provided on the global environment as described in Table 5.

Table 5: Additional Global Environment Fields
Field Name Value Meaning
[[BuiltinModuleMap]] A List of Record { [[Identifier]]: String, [[ModuleRecord]]: Builtin Module Record } Each Identifier is the same identifier of the associated Builtin Module Record.
[[Loader]] The ECMAScript language Loader. The Loader that implements the builtin module resolution and loading.

A Builtin Module Resolution Record is used to represent information during the loading of a module built in to the host. Resolution and loading of these modules occurs locally.

Builtin Module Records are specified in Table 6

Table 6: Builtin Module Resolution Record
Field Name Value Type Meaning
[[Status]] String Initially "uninitialized". Transitions to "resolving", "resolved", "loading", "loaded" (in that order) as the module progresses throughout the loading process.
[[ResolvingLoaders]] List of Loaders The list of all Loaders that can resolve and load this module. The list is sorted from highest priority to lowest.

Builtin Module Resolution Records are used with the methods specified in Table 7

Table 7: Builtin Module Resolution Methods
Method Purpose
ResolveModuleIdentifier() Determine if an imported can resolve a module.
LoadModuleIdentifier() Load a module from the current importer.

3.1.1 ResolveModuleIdentifier ( ModuleIdentifier, ReferencingModule )

The ResolveModuleIdentifier concrete method implements the module resolution part of the Builtin Module import process.

Each Loader needs to provide this method to participate in the Builtin Module resolution and loading process. The abstract method described here is what is required for the ECMAScript language implementation. Hosts that provide additional Loaders must provide a ResolveModuleIdentifier method each Loader.

If the Loader is able to successfully resolve the module identified by ModuleIdentifier, it sets this ResolveModuleResolutionRecord's [[Status]] to "resolved" and adds the current Loader to the front of the [[ResolvingLoaders]] list.

This abstract method performs the following steps:

  1. Let resolution be this Builtin Module Resolution Record.
  2. Assert: resolution.[[Status]] is "resolving " or "resolved".
  3. If ModuleIdentifier does not begin with "js:", then
    1. Return.
  4. Let localModuleIdentifier be a substring of ModuleIdentifier from the index after "js:".
  5. Let globalEnvironment be the global environment of ReferencingModule.[[Environment]].
  6. If globalEnvironment.[[BuiltinModuleMap]] contains an entry e such that e.[[Identifier]] is localModuleIdentifier, then
    1. Set resolution.[[Status]] to "resolved".
  7. Let loader be globalEnvironment.[[Loader]].
  8. Push loader on the front of resolution.[[ResolvingLoaders]].
  9. Return.

3.1.2 LoadModuleIdentifier ( ModuleIdentifier, ReferencingModule )

The LoadModuleIdentifier concrete method implements the module loading part of the Builtin Module import process.

Each Loader needs to provide this method to participate in the Builtin Module resolution and loading process. The abstract method described here is what is required for the ECMAScript language implementation. Hosts that provide additional Loaders must provide a ResolveModuleIdentifier method each Loader.

If the Loader is able to successfully load the module, it ResolveModuleIdentifier set module's [[Status]] to "resolved" and adds the current Loader to the front of the [[ResolvingLoaders]] list.

This abstract method performs the following steps:

  1. Let resolution be this Builtin Module Resolution Record.
  2. Assert: resolution.[[Status]] is "loading".
  3. Assert: resolution.[[ResolvingLoaders]] has at least one element.
  4. Let loader be the first element of resolution.[[ResolvingLoaders]].
  5. If loaderglobalEnvironment.[[Loader]], then
    1. Return undefined.
  6. Assert: ModuleIdentifier begins with "js:".
  7. Let localModuleIdentifier be a substring of ModuleIdentifier from the index after "js:".
  8. Let globalEnvironment be the global environment of _ReferencingModule.[[Environment]].
  9. Let moduleMap be globalEnvironment.[[BuiltinModuleMap]].
  10. Assert: moduleMap contains an entry e such that e.[[Identifer]] is localModuleIdentifier.
  11. Let moduleRecord be e.[[ModuleRecord]].
  12. Perform moduleRecord.Instantiate().
  13. Return moduleRecord.Evaluate().

3.1.3 Importing

Importing a Builtin Module involves resolving where the module can be loaded from and then actually loading the module. One or more Loaders can participate in the importing process.

A List of loaders in available in an implementation defined way. The first loader in that list must be the ECMAScript loader. Subsequent loaders in that list appear in decending resolution order. Loading priority order starts from the back of the list.

3.1.3.1 ImportBuiltinModule ( ModuleIdentifier, ReferencingModule )

ImportBuiltinModule is the abstract operation that returns the concrete Module Record instance that corresponds to the ModuleSpecifier String, specifier, occurring within the context of the module represented by the Module Record referencingModule.

This abstract operation performs the following steps.

  1. Let resolution be Builtin Module Record { [[Status]]: "uninitialized", [[ResolvingLoaders]]: "[ ]" }.
  2. Let loaders be the host-defined List of Loaders.
  3. For each element loader in loaders, in List order, do
    1. Perform loader.ResolveModuleIdentifier( ModuleIdentifier, ReferencingModule ).
  4. For each element loader in loaders, in reverse List order, do
    1. Let loadResult be loader.LoadModuleIdentifier( ModuleIdentifier, ReferencingModule ).
    2. If _loadResult ≠ undefined, then
      1. Return loadResult.
  5. Return undefined.

4 The Global Object

...

4.1 Other Properties of the Global Object

4.1.1 Atomics

See 24.4.

4.1.2 JSON

See 24.5.

4.1.3 Math

See 20.3.

4.1.4 Reflect

See 26.1.

4.1.5 BuiltinModule

See 5.

5 BuiltinModule Object

The BuiltinModule Object

The BuiltinModule object:

  • is the initial value of the "BuiltinModule" property of the global object.
  • is an ordinary object.
  • has a [[Prototype]] internal slot whose value is %Object.prototype%.
  • is not a function object.
  • does not have a [[Construct]] internal method; it cannot be used as a constructor with the new operator.
  • does not have a [[Call]] internal method; it cannot be invoked as a function.

5.1 BuiltinModule.export ( moduleSpecifier, exports )

When the export function is called with arguments moduleSpecifier, and exports, the following steps are taken:

  1. Let moduleExists be HostHasBuiltinModule( scriptContext.ScriptOrModule, moduleSpecifier ).
  2. Let exportNames be exports.[[OwnPropertyKeys]].
  3. If moduleExists, then
    1. Let module be HostResolveBuiltinModule( scriptContext.ScriptOrModule, moduleSpecifier ).
    2. Set module.[[ExportNames]] to exportNames.
  4. Else,
    1. Let module be CreateSyntheticModule( exportNames, builtin evaluation steps, the current Realm Record, undefined).
  5. Call HostCreateBuiltinModule( scriptContext.ScriptOrModule, moduleSpecifier, module ).

5.2 BuiltinModule.freezeModule ( moduleSpecifier )

When the freezeModule function is called with arguments moduleSpecifier, the following steps are taken:

Note
Freezing probably needs to be done in a script or execution context table instead of for the whole host.
  1. Let module be HostResolveBuiltinModule( scriptContext.ScriptOrModule, moduleSpecifier ).
  2. Assert: module is a SyntheticModuleRecord.
  3. Perform ? module.Freeze().

5.3 BuiltinModule.freezeAllModules ( )

When the freezeAllModules function is called, the following steps are taken:

Note
Freezing probably needs to be done in a script or execution context table instead of for the whole host.
  1. Freeze all modules for scriptContext.ScriptOrModule.

5.4 BuiltinModule.hasModule ( moduleSpecifier )

When the hasModule function is called with arguments moduleSpecifier the following steps are taken:

  1. Let moduleExists be HostHasBuiltinModule( scriptContext.ScriptOrModule, moduleSpecifier).
  2. Return moduleExists.

5.5 BuiltinModule.import ( moduleSpecifier )

When the export function is called with arguments moduleSpecifier, the following steps are taken:

  1. Let module be HostResolveBuiltinModule( scriptContext.ScriptOrModule, moduleSpecifier).
  2. Assert: module is a SyntheticModuleRecord.
  3. Perform ? module.Evaluate().
  4. Let namespace be GetModuleNamespace( module ).
  5. Return namespace.

A Host Layering Points

A.1 Host Hooks

HostCallJobCallback(...)

HostEnqueueFinalizationRegistryCleanupJob(...)

HostEnqueuePromiseJob(...)

HostEnsureCanCompileStrings(...)

HostFinalizeImportMeta(...)

HostGetImportMetaProperties(...)

HostHasSourceTextAvailable(...)

HostImportModuleDynamically(...)

HostMakeJobCallback(...)

HostPromiseRejectionTracker(...)

HostHasBuiltinModule(...)

HostCreateBuiltinModule(...)

HostResolveBuiltinModule(...)

HostResolveImportedModule(...)

InitializeHostDefinedRealm(...)