Stage 1 Draft / February 26, 2019

JavaScript Standard Library

Introduction

Background explanatory material for this specification can be found in the tc39/proposal-javascript-standard-library repository.

1Synthetic 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 SetSyntheticModuleExport. 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 37, Synthetic Module Records have the additional fields listed in Table 1. Each of these fields is initially set in CreateSyntheticModule.

Table 1: Additional Fields of Synthetic Module Records
Field Name Value Type Meaning
[[ExportNames]] List of String A List of all names that are exported.
[[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 SetSyntheticModuleExport. They must not modify [[ExportNames]]. They may return an abrupt completion.

1.1CreateSyntheticModule ( 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, [[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.

1.2SetSyntheticModuleExport ( module, exportName, exportValue )

The abstract operation SetSyntheticModuleExport 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 envRec be module.[[Environment]]'s EnvironmentRecord.
  2. Perform envRec.SetMutableBinding(exportName, exportValue, true).

1.3Concrete 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.

1.3.1GetExportedNames( 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]].

1.3.2ResolveExport( 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 }.

1.3.3Instantiate ( )

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 exportName in module.[[ExportNames]],
    1. Perform ! envRec.CreateMutableBinding(exportName, false).
    2. Perform ! envRec.InitializeBinding(exportName, undefined).
  8. Return undefined.

1.3.4Evaluate ( )

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).

1.4Example 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.

1.4.1A 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).

1.4.1.1ExampleObjectWrapperModuleEvaluation ( module )

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

1.4.2A "built-in 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).

1.4.2.1ExampleAdderModuleEvaluation ( module )

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

1.4.2.2Example 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.