Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Define Synthetic Module Records #722

Merged
merged 2 commits into from
May 17, 2019
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
176 changes: 176 additions & 0 deletions index.bs
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ spec: url; type: interface; text: URL
spec: dom; type: interface; text: Document
spec: ecma-262; type: dfn; for: /; text: internal method
spec: ecma-262; type: dfn; for: /; text: internal slot
spec: ecma-262; type: dfn; for: /; text:realm
</pre>

<pre class="anchors">
Expand Down Expand Up @@ -125,6 +126,10 @@ urlPrefix: https://tc39.github.io/ecma262/; spec: ECMA-262
text: CreateSetIterator; url: sec-createsetiterator
text: DefinePropertyOrThrow; url: sec-definepropertyorthrow
text: DetachArrayBuffer; url: sec-detacharraybuffer
for: Environment Record; url: table-15
text: SetMutableBinding
text: CreateMutableBinding
text: InitializeBinding
text: Get; url: sec-get-o-p
text: GetFunctionRealm; url: sec-getfunctionrealm
text: GetIterator; url: sec-getiterator
Expand All @@ -138,6 +143,7 @@ urlPrefix: https://tc39.github.io/ecma262/; spec: ECMA-262
text: IsSharedArrayBuffer; url: sec-issharedarraybuffer
text: IteratorStep; url: sec-iteratorstep
text: IteratorValue; url: sec-iteratorvalue
text: NewModuleEnvironment; url: sec-newmoduleenvironment
text: NormalCompletion; url: sec-normalcompletion
text: ObjectCreate; url: sec-objectcreate
text: OrdinaryDefineOwnProperty; url: sec-ordinarydefineownproperty
Expand Down Expand Up @@ -181,15 +187,27 @@ urlPrefix: https://tc39.github.io/ecma262/; spec: ECMA-262
text: constructor; url: constructor
text: conventions; for: ECMAScript; url: sec-algorithm-conventions
text: current Realm; url: current-realm
text: ECMAScript code execution context; url: sec-execution-contexts
for: ECMAScript code execution context; url: table-23
text: LexicalEnvironment
text: VariableEnvironment
text: element; for: ECMAScript String; url: sec-ecmascript-language-types-string-type
text: enumerable; url: sec-property-attributes
text: EnvironmentRecord; for: Lexical Environment; url: sec-lexical-environments
text: equally close values; url: sec-ecmascript-language-types-number-type
text: error objects; for: ECMAScript; url: sec-error-objects
for: Execution context; url: table-22
text: Function
text: Realm
text: ScriptOrModule
text: execution context stack; url: execution-context-stack
text: function object; url: function-object
text: immutable prototype exotic object; url: sec-immutable-prototype-exotic-objects
url: sec-object-internal-methods-and-internal-slots
text: internal method
text: internal slot
text: Module Record; url: sec-abstract-module-records
text: Module Record Fields; url: table-36
text: Number type; url: sec-ecmascript-language-types-number-type
text: Object; for: ECMAScript; url: sec-object-type
for: ordinary object; url: sec-ordinary-object-internal-methods-and-internal-slots
Expand All @@ -198,6 +216,8 @@ urlPrefix: https://tc39.github.io/ecma262/; spec: ECMA-262
text: own property; url: sec-own-property
text: Property Descriptor; url: sec-property-descriptor-specification-type
text: realm; url: realm
text: ResolvedBinding Record; url: resolvedbinding-record
text: running execution context; url: running-execution-context
</pre>

<pre class=biblio>
Expand Down Expand Up @@ -13244,6 +13264,162 @@ the exact steps to take if <dfn>an exception was thrown</dfn>, or by explicitly
</div>


<h3 id="synthetic-module-records">Synthetic module records</h3>

A <dfn export>Synthetic Module Record</dfn> 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.
Ms2ger marked this conversation as resolved.
Show resolved Hide resolved
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.
Ms2ger marked this conversation as resolved.
Show resolved Hide resolved

In addition to the [=Module Record Fields=], Synthetic Module Records have the additional fields
listed below.
Each of these fields is initially set in [$CreateSyntheticModule$].

<table id="table-synthetic-module-record-fields" class="data">
<caption>Additional Fields of Synthetic Module Records</caption>
<thead>
<tr>
<th>Field Name
<th>Value Type
<th>Meaning
<tbody>
<tr>
<td>\[[ExportNames]]
<td>List of String
<td>A List of all names that are exported.
<tr>
<td>\[[EvaluationSteps]]
<td>An abstract operation
<td>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.
</table>

<h4>CreateSyntheticModule</h4>

<div algorithm>
The abstract operation <dfn abstract-op>CreateSyntheticModule</dfn>(|exportNames|, |evaluationSteps|, |realm|, |hostDefined|) creates a [=Synthetic Module Record=] based upon
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since we are in WebIDL, I wonder if Create SyntheticModule and SetSyntheticModuleExport would be more clean if phrased as worded algorithms, e.g., "To create a synthetic module record...". HostDefined also seems redundant here when the steps can close over outer variables (as they can in web specs, but not JS).

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd prefer to keep this close to ecma-speak for now, in case we decide to move it back under the TC39 umbrella.

the given exported names and evaluation steps.
It performs the following steps:

1. Return [=Synthetic Module Record=] {
\[[Realm]]: |realm|,
\[[Environment]]: <emu-val>undefined</emu-val>,
\[[Namespace]]: <emu-val>undefined</emu-val>,
\[[HostDefined]]: |hostDefined|,
\[[ExportNames]]: |exportNames|,
\[[EvaluationSteps]]: |evaluationSteps|
}.
</div>

Note: It seems we could set up the environment either here or in Instantiate().
Ms2ger marked this conversation as resolved.
Show resolved Hide resolved
It is done in Instantiate() for symmetry with Source Text Module Records, but there doesn't seem to
be any actual requirement in that regard.

<h4>SetSyntheticModuleExport</h4>

<div algorithm>
The abstract operation <dfn abstract-op>SetSyntheticModuleExport</dfn>(|module|, |exportName|,
|exportValue|) 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 [=Lexical Environment/EnvironmentRecord=].
1. Perform |envRec|.[$Environment Record/SetMutableBinding$](|exportName|, |exportValue|,
<emu-val>true</emu-val>).
</div>

<h4 id="smr-concrete-methods">Concrete Methods</h4>

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

<h5>GetExportedNames</h5>

<div algorithm>
The <dfn abstract-op for="Synthetic Module Record">GetExportedNames</dfn>(<var
ignore>exportStarSet</var>) 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=].
1. Return |module|.\[[ExportNames]].
</div>

<h5>ResolveExport</h5>

<div algorithm>
The <dfn abstract-op for="Synthetic Module Record">ResolveExport</dfn>(|exportName|, <var
ignore>resolveSet</var>) 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=].
1. If |module|.\[[ExportNames]] does not contain |exportName|, return <emu-val>null</emu-val>.
1. Return [=ResolvedBinding Record=] { \[[Module]]: |module|, \[[BindingName]]: |exportName| }.
</div>

<h5>Instantiate</h5>

<div algorithm>
The <dfn abstract-op for="Synthetic Module Record">Instantiate</dfn>() 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=].
1. Let |realm| be |module|.\[[Realm]].
1. Assert: |realm| is not <emu-val>undefined</emu-val>.
1. Let |env| be [$NewModuleEnvironment$](|realm|.\[[GlobalEnv]]).
1. Set |module|.\[[Environment]] to |env|.
1. Let |envRec| be |env|'s [=Lexical Environment/EnvironmentRecord=].
1. For each |exportName| in |module|.\[[ExportNames]],
1. Perform [=!=] |envRec|.[$Environment Record/CreateMutableBinding$](|exportName|,
<emu-val>false</emu-val>).
1. Perform [=!=] |envRec|.[$Environment Record/InitializeBinding$](|exportName|,
<emu-val>undefined</emu-val>).
1. Return <emu-val>undefined</emu-val>.
</div>

<h5>Evaluate</h5>

<div algorithm>
The <dfn abstract-op for="Synthetic Module Record">Evaluate</dfn>() 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=].
1. Let |moduleCxt| be a new [=ECMAScript code execution context=].
1. Set the [=Execution context/Function=] of |moduleCxt| to <emu-val>null</emu-val>.
1. Assert: |module|.\[[Realm]] is not <emu-val>undefined</emu-val>.
1. Set the [=Execution context/Realm=] of |moduleCxt| to |module|.\[[Realm]].
1. Set the [=Execution context/ScriptOrModule=] of |moduleCxt| to |module|.
1. Set the [=ECMAScript code execution context/VariableEnvironment=] of |moduleCxt| to
|module|.\[[Environment]].
1. Set the [=ECMAScript code execution context/LexicalEnvironment=] of |moduleCxt| to
|module|.\[[Environment]].
1. Suspend the currently [=running execution context=].
1. Push |moduleCxt| on to the [=execution context stack=]; |moduleCxt| is now the
[=running execution context=].
1. Let |completion| be the result of performing |module|.\[[EvaluationSteps]](|module|).
1. Suspend |moduleCxt| and remove it from the [=execution context stack=].
1. Resume the context that is now on the top of the [=execution context stack=] as the
[=running execution context=].
1. Return [$Completion$](|completion|).
</div>


<h2 id="common">Common definitions</h2>

This section specifies some common definitions that all
Expand Down