Skip to content

Commit 3feb1ba

Browse files
nicolo-ribaudoljharb
authored andcommitted
Normative: Add JSON modules (#3391)
1 parent 4e3450e commit 3feb1ba

File tree

1 file changed

+193
-0
lines changed

1 file changed

+193
-0
lines changed

spec.html

+193
Original file line numberDiff line numberDiff line change
@@ -28527,6 +28527,192 @@ <h1>
2852728527
</emu-clause>
2852828528
</emu-clause>
2852928529

28530+
<emu-clause id="sec-synthetic-module-records">
28531+
<h1>Synthetic Module Records</h1>
28532+
28533+
<p>A <dfn variants="Synthetic Module Records">Synthetic Module Record</dfn> is used to represent information about a module that is defined by specifications. Its exported names are statically defined at creation, while their corresponding values can change over time using SetSyntheticModuleExport. It has no imports or dependencies.</p>
28534+
28535+
<emu-note>A Synthetic Module Record could be used for defining a variety of module types: for example, JSON modules or CSS modules.</emu-note>
28536+
28537+
<p>In addition to the fields defined in <emu-xref href="#table-module-record-fields"></emu-xref> Synthetic Module Records have the additional fields listed in <emu-xref href="#table-synthetic-module-record-fields"></emu-xref>.</p>
28538+
28539+
<emu-table id="table-synthetic-module-record-fields" caption="Additional Fields of Synthetic Module Records">
28540+
<table>
28541+
<thead>
28542+
<tr>
28543+
<th>Field Name</th>
28544+
<th>Value Type</th>
28545+
<th>Meaning</th>
28546+
</tr>
28547+
</thead>
28548+
<tr>
28549+
<td>[[ExportNames]]</td>
28550+
<td>a List of Strings</td>
28551+
<td>The names of the exports of the module. This list does not contain duplicates.</td>
28552+
</tr>
28553+
<tr>
28554+
<td>[[EvaluationSteps]]</td>
28555+
<td>an Abstract Closure</td>
28556+
<td>The initialization logic to perform upon evaluation of the module, taking the Synthetic Module Record as its sole argument. It must not modify [[ExportNames]]. It may return an abrupt completion.</td>
28557+
</tr>
28558+
</table>
28559+
</emu-table>
28560+
28561+
<emu-clause id="sec-create-default-export-synthetic-module" type="abstract operation">
28562+
<h1>
28563+
CreateDefaultExportSyntheticModule (
28564+
_defaultExport_: an ECMAScript language value,
28565+
): a Synthetic Module Record
28566+
</h1>
28567+
<dl class="header">
28568+
<dt>description</dt>
28569+
<dd>It creates a Synthetic Module Record whose default export is _defaultExport_.</dd>
28570+
</dl>
28571+
<emu-alg>
28572+
1. Let _realm_ be the current Realm Record.
28573+
1. Let _setDefaultExport_ be a new Abstract Closure with parameters (_module_) that captures _defaultExport_ and performs the following steps when called:
28574+
1. Perform SetSyntheticModuleExport(_module_, *"default"*, _defaultExport_).
28575+
1. Return NormalCompletion(~unused~).
28576+
1. Return the Synthetic Module Record { [[Realm]]: _realm_, [[Environment]]: ~empty~, [[Namespace]]: ~empty~, [[HostDefined]]: *undefined*, [[ExportNames]]: « *"default"* », [[EvaluationSteps]]: _setDefaultExport_ }.
28577+
</emu-alg>
28578+
</emu-clause>
28579+
28580+
<emu-clause id="sec-parse-json-module" type="abstract operation">
28581+
<h1>
28582+
ParseJSONModule (
28583+
_source_: a String,
28584+
): either a normal completion containing a Synthetic Module Record, or a throw completion
28585+
</h1>
28586+
<dl class="header">
28587+
<dt>description</dt>
28588+
<dd></dd>
28589+
</dl>
28590+
28591+
<emu-alg>
28592+
1. Let _json_ be ? Call(%JSON.parse%, *undefined*, « _source_ »).
28593+
1. Return CreateDefaultExportSyntheticModule(_json_).
28594+
</emu-alg>
28595+
</emu-clause>
28596+
28597+
<emu-clause id="sec-setsyntheticmoduleexport" type="abstract operation">
28598+
<h1>
28599+
SetSyntheticModuleExport (
28600+
_module_: a Synthetic Module Record,
28601+
_exportName_: a String,
28602+
_exportValue_: an ECMAScript language value,
28603+
): ~unused~
28604+
</h1>
28605+
<dl class="header">
28606+
<dt>description</dt>
28607+
<dd>It can be used to set or change the exported value for an existing export of a Synthetic Module Record.</dd>
28608+
</dl>
28609+
28610+
<emu-alg>
28611+
1. Assert: _module_.[[ExportNames]] contains _exportName_.
28612+
1. Let _envRec_ be _module_.[[Environment]].
28613+
1. Assert: _envRec_ is not ~empty~.
28614+
1. Perform _envRec_.SetMutableBinding(_exportName_, _exportValue_, *true*).
28615+
1. Return ~unused~.
28616+
</emu-alg>
28617+
</emu-clause>
28618+
28619+
<emu-clause id="sec-smr-module-record-methods">
28620+
<h1>Implementation of Module Record Abstract Methods</h1>
28621+
28622+
<p>The following are the concrete methods for Synthetic Module Record that implement the corresponding Module Record abstract methods defined in <emu-xref href="#table-abstract-methods-of-module-records"></emu-xref>.</p>
28623+
28624+
<emu-clause id="sec-smr-LoadRequestedModules" type="concrete method">
28625+
<h1>LoadRequestedModules ( ): a Promise</h1>
28626+
<dl class="header">
28627+
<dt>for</dt>
28628+
<dd>a Synthetic Module Record _module_</dd>
28629+
</dl>
28630+
28631+
<emu-alg>
28632+
1. Return ! PromiseResolve(%Promise%, *undefined*).
28633+
</emu-alg>
28634+
28635+
<emu-note>
28636+
Synthetic Module Records have no dependencies.
28637+
</emu-note>
28638+
</emu-clause>
28639+
28640+
<emu-clause id="sec-smr-getexportednames" type="concrete method">
28641+
<h1>GetExportedNames ( ): a List of Strings</h1>
28642+
<dl class="header">
28643+
<dt>for</dt>
28644+
<dd>a Synthetic Module Record _module_</dd>
28645+
</dl>
28646+
28647+
<emu-alg>
28648+
1. Return _module_.[[ExportNames]].
28649+
</emu-alg>
28650+
</emu-clause>
28651+
28652+
<emu-clause id="sec-smr-resolveexport" type="concrete method">
28653+
<h1>
28654+
ResolveExport (
28655+
_exportName_: a String,
28656+
): a ResolvedBinding Record or *null*
28657+
</h1>
28658+
<dl class="header">
28659+
<dt>for</dt>
28660+
<dd>a Synthetic Module Record _module_</dd>
28661+
</dl>
28662+
28663+
<emu-alg>
28664+
1. If _module_.[[ExportNames]] does not contain _exportName_, return *null*.
28665+
1. Return ResolvedBinding Record { [[Module]]: _module_, [[BindingName]]: _exportName_ }.
28666+
</emu-alg>
28667+
</emu-clause>
28668+
28669+
<emu-clause id="sec-smr-Link" type="concrete method">
28670+
<h1>Link ( ): a normal completion containing ~unused~</h1>
28671+
<dl class="header">
28672+
<dt>for</dt>
28673+
<dd>a Synthetic Module Record _module_</dd>
28674+
</dl>
28675+
28676+
<emu-alg>
28677+
1. Let _realm_ be _module_.[[Realm]].
28678+
1. Let _env_ be NewModuleEnvironment(_realm_.[[GlobalEnv]]).
28679+
1. Set _module_.[[Environment]] to _env_.
28680+
1. For each String _exportName_ of _module_.[[ExportNames]], do
28681+
1. Perform ! _env_.CreateMutableBinding(_exportName_, *false*).
28682+
1. Perform ! _env_.InitializeBinding(_exportName_, *undefined*).
28683+
1. Return NormalCompletion(~unused~).
28684+
</emu-alg>
28685+
</emu-clause>
28686+
28687+
<emu-clause id="sec-smr-Evaluate" type="concrete method">
28688+
<h1>Evaluate ( ): a Promise</h1>
28689+
<dl class="header">
28690+
<dt>for</dt>
28691+
<dd>a Synthetic Module Record _module_</dd>
28692+
</dl>
28693+
28694+
<emu-alg>
28695+
1. Let _moduleContext_ be a new ECMAScript code execution context.
28696+
1. Set the Function of _moduleContext_ to *null*.
28697+
1. Set the Realm of _moduleContext_ to _module_.[[Realm]].
28698+
1. Set the ScriptOrModule of _moduleContext_ to _module_.
28699+
1. Set the VariableEnvironment of _moduleContext_ to _module_.[[Environment]].
28700+
1. Set the LexicalEnvironment of _moduleContext_ to _module_.[[Environment]].
28701+
1. Suspend the running execution context.
28702+
1. Push _moduleContext_ onto the execution context stack; _moduleContext_ is now the running execution context.
28703+
1. Let _steps_ be _module_.[[EvaluationSteps]].
28704+
1. Let _result_ be Completion(_steps_(_module_)).
28705+
1. Suspend _moduleContext_ and remove it from the execution context stack.
28706+
1. Resume the context that is now on the top of the execution context stack as the running execution context.
28707+
1. Let _pc_ be ! NewPromiseCapability(%Promise%).
28708+
1. IfAbruptRejectPromise(_result_, _pc_).
28709+
1. Perform ! Call(_pc_.[[Resolve]], *undefined*, « *undefined* »).
28710+
1. Return _pc_.[[Promise]].
28711+
</emu-alg>
28712+
</emu-clause>
28713+
</emu-clause>
28714+
</emu-clause>
28715+
2853028716
<emu-clause id="sec-GetImportedModule" type="abstract operation">
2853128717
<h1>
2853228718
GetImportedModule (
@@ -28582,12 +28768,19 @@ <h1>
2858228768
</ul>
2858328769
<p>and it performs FinishLoadingImportedModule(_referrer_, _moduleRequest_, _payload_, _result_) where _result_ is a normal completion, then it must perform FinishLoadingImportedModule(_referrer_, _moduleRequest_, _payload_, _result_) with the same _result_ each time.</p>
2858428770
</li>
28771+
<li>
28772+
<p>If _moduleRequest_.[[Attributes]] has an entry _entry_ such that _entry_.[[Key]] is *"type"* and _entry_.[[Value]] is *"json"*, when the host environment performs FinishLoadingImportedModule(_referrer_, _moduleRequest_, _payload_, _result_), _result_ must either be the Completion Record returned by an invocation of ParseJSONModule or a throw completion.</p>
28773+
</li>
2858528774
<li>
2858628775
The operation must treat _payload_ as an opaque value to be passed through to FinishLoadingImportedModule.
2858728776
</li>
2858828777
</ul>
2858928778

2859028779
<p>The actual process performed is host-defined, but typically consists of performing whatever I/O operations are necessary to load the appropriate Module Record. Multiple different (_referrer_, _moduleRequest_.[[Specifier]], _moduleRequest_.[[Attributes]]) triples may map to the same Module Record instance. The actual mapping semantics 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 expansion of relative and abbreviated path specifiers.</p>
28780+
28781+
<emu-note>
28782+
<p>The above text requires that hosts support JSON modules when imported with `type: "json"` (and HostLoadImportedModule completes normally), but it does not prohibit hosts from supporting JSON modules when imported without `type: "json"`.</p>
28783+
</emu-note>
2859128784
</emu-clause>
2859228785

2859328786
<emu-clause id="sec-FinishLoadingImportedModule" type="abstract operation" oldids="sec-finishdynamicimport">

0 commit comments

Comments
 (0)