This repository was archived by the owner on Jun 30, 2020. It is now read-only.
-
-
Notifications
You must be signed in to change notification settings - Fork 8
/
Copy pathspec.html
237 lines (210 loc) · 11.7 KB
/
spec.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
<!DOCTYPE html>
<meta charset="utf-8">
<pre class="metadata">
title: 'Dynamic Modules'
status: proposal
location: https://guybedford.github.io/proposal-dynamic-modules/
copyright: false
</pre>
<script src="ecmarkup.js" defer></script>
<link rel="stylesheet" href="ecmarkup.css">
<emu-intro id="introduction">
<h1>Introduction</h1>
<p>Dynamic Modules allow non-source-text module records to be created and used by host environments.</p>
<p>In addition, they provide late definition of export bindings at the execution phase, to support named exports compatibility with legacy module systems.</p>
</emu-intro>
<emu-clause id="sec-dynamic-module-records">
<h1><ins>Dynamic Module Records</ins></h1>
<p>A <dfn id="dynamicmodule-record">Dynamic Module Record</dfn> is used to represent information about a module that is defined programatically. Its fields contain digested information about the names that are exported by the module and its concrete methods use this digest to link, instantiate, and evaluate the module alongside other Abstract Module Records.</p>
<p>Dependency cycles with Source Text Module Records are avoided since these modules can only export, and not import from other Abstract Module Records.</p>
<p>Dynamic Module Records support late export binding, in that export names are only validated after execution.</p>
<p>In addition to the fields, defined in <emu-xref href="#table-36"></emu-xref>, Dynamic Module Records have the additional fields listed in <emu-xref href="#table-X"></emu-xref>. Each of these fields is initially set in CreateDynamicModule.</p>
<emu-table id="table-X" caption="Additional Fields of Dynamic Module Records">
<table>
<tbody>
<tr>
<th>
Field Name
</th>
<th>
Value Type
</th>
<th>
Meaning
</th>
</tr>
<tr>
<td>
[[ExportNames]]
</td>
<td>
A string List of exported names.
</td>
<td>
The list of export bindings associated with this Dynamic Module Record.
</td>
</tr>
<tr>
<td>
[[EvaluationError]]
</td>
<td>
An abrupt completion | *undefined*
</td>
<td>
A completion of type ~throw~ representing the exception that occurred during evaluation. *undefined* if no exception occurred or if [[Status]] is not `"evaluated"`.
</td>
</tr>
</tbody>
</table>
</emu-table>
<emu-clause id="sec-createdynamicmodule" aoid="CreateDynamicModule">
<h1>CreateDynamicModule ( _realm_, _hostDefined_ )</h1>
<p>This method would be expected to be called by the host when constructing a Module Record in _HostResolveImportedModule_.</p>
<p>The abstract operation CreateDynamicModule with arguments _realm_, and _hostDefined_ creates a new Dynamic Module Record performing the following steps:</p>
<emu-alg>
1. Let _exportNames_ be a new empty List.
1. Let _nsModules_ be a new empty List.
1. Let _module_ be the Dynamic Module Record { [[Realm]]: _realm_, [[Environment]]: *undefined*, [[Namespace]]: *undefined*, [[Status]]: `"uninstantiated"`, [[ExportNames]]: _exportNames_, [[EvaluationError]]: *undefined*, [[HostDefined]]: _hostDefined_ }.
1. Return _module_.
</emu-alg>
</emu-clause>
<p>The following definitions specify the required concrete methods for Dynamic Module Records.</p>
<emu-clause id="sec-dynamicgetexportednames">
<h1>GetExportedNames ( _exportStarSet_, _nsModule_ ) Concrete Method</h1>
<p>The GetExportedNames concrete method of a Dynamic Module Record implements the corresponding Module Record abstract method.</p>
<p>Any modules exporting names from this Dynamic Module Record are stored so their exports can be amended on execution of this Dynamic Module.</p>
<p>It performs the following steps:</p>
<emu-alg>
1. Let _module_ be this Dynamic Module Record.
1. If _module_ is not equal to _nsModule_ or _module_.[[Status]] is not `"evaluated"`, then
1. Return *null*.
1. Return _module_.[[exportNames]].
</emu-alg>
<emu-note>
<p>The *null* return results in an error being thrown for star exports from dynamic modules, and creating an "unfinalized" namespace in the case of an uninstantiated dynamic namespace creation in cycles.</p>
</emu-note>
</emu-clause>
<emu-clause id="sec-dynamicresolveexport">
<h1>ResolveExport ( _exportName_, _resolveSet_ ) Concrete Method</h1>
<p>The ResolveExport concrete method of a Dynamic Module Record implements the corresponding Module Record abstract method.</p>
<p>ResolveExport ensures that a binding is created for the dynamic Module Record, lazily creating a binding if needed.</p>
<p>This abstract method performs the following steps:</p>
<emu-alg>
1. Let _module_ be this Dynamic Module Record.
1. If _module_.[[Status]] is `"uninstantiated"` then,
1. Perform ? _module_.Instantiate().
1. Let _exportNames_ be _module_.[[ExportNames]].
1. If _exportNames_ does not contain _exportName_ then,
1. Let _envRec_ be the Module Environment Record _module_.[[Environment]]
1. If _envRec_ does not already have a binding for _exportName_ then,
1. Perform ! _envRec_.CreateMutableBinding(_exportName_, *false*).
1. Append _exportName_ to the end of _exportNames_.
1. Return ResolvedBinding Record { [[Module]]: _module_, [[BindingName]]: _exportName_ }.
</emu-alg>
</emu-clause>
<emu-clause id="sec-dynamicmoduledeclarationinstantiation">
<h1>Instantiate ( ) Concrete Method</h1>
<p>The Instantiate concrete method of a Dynamic Module Record implements the corresponding Module Record abstract method.</p>
<p>On success, Instantiate transitions this module's [[Status]] from `"uninstantiated"` to `"instantiated"`. On failure, an exception is thrown and this module's [[Status]] remains `"uninstantiated"`.</p>
<p>This abstract method performs the following steps:</p>
<emu-alg>
1. Let _module_ be this Dynamic Module Record.
1. If _module_.[[Status]] is "instantiated", or "evaluated", then
1. Return *undefined*.
1. Assert: _module_.[[Status]] is not `"instantiating"` or `"evaluating"`.
1. Let _realm_ be module.[[Realm]].
1. Assert: _realm_ is a valid Realm.
1. Let _env_ be NewModuleEnvironment(_realm_.[[GlobalEnv]]).
1. Set _module_.[[Environment]] to _env_.
1. Set _module_.[[Status]] to `"instantiated"`.
1. Return *undefined*.
</emu-alg>
</emu-clause>
<emu-clause id="sec-dynamicmoduleevaluation">
<h1>Evaluate ( ) Concrete Method</h1>
<p>The Evaluate concrete method of a Dynamic Module Record implements the corresponding Module Record abstract method.</p>
<p>Evaluate transitions this module's [[Status]] from `"instantiated"` to `"evaluated"`.</p>
<p>If execution results in an exception, that exception is recorded in the [[EvaluationError]] field and rethrown by future invocations of Evaluate.</p>
<p>Evaluation of dynamic modules calls out to _HostEvaluateDynamicModule_, before finalising the export names of the dynamic modules. Any uninitialized export bindings throw a reference error at this stage.</p>
<p>This abstract method performs the following steps:</p>
<emu-alg>
1. Let _m_ be this Dynamic Module Record.
1. If _m_.[[Status]]_ is `"evaluated"` then,
1. Return _m_.[[EvaluationError]].
1. Assert: _m_.[[Status]] is `"instantiated"`.
1. Set _m_.[[Status]] to `"evaluating"`.
1. Let _result_ be HostEvaluateDynamicModule(_m_).
1. If _result_ is an abrupt completion, then
1. Assert: _m_.[[Status]] is `"evaluating"`.
1. Set _m_.[[Status]] to `"evaluated"`.
1. Set _m_.[[EvaluationError]] to _result_.
1. Return _result_.
1. Let _envRec_ be the value of _module_.[[Environment]].
1. For each string _exportName_ in _m_.[[ExportNames]], do
1. Assert: _envRec_ has a binding for _exportName_.
1. If the binding for _exportName_ in _envRec_ is uninitialized then,
1. Let _error_ be a *ReferenceError* exception.
1. Set _m_.[[Status]] to `"evaluated"`.
1. Set _m_.[[EvaluationError]] to _error_.
1. Return _error_.
1. Let _ns_ be ? GetModuleNamespace(_m_).
1. Assert: _ns_ is a Module Namespace Exotic Object.
1. Assert: _ns_.[[Exports]] is *null*.
1. Let _exportedNames_ be ? _m_.GetExportedNames(« », _m_).
1. Assert: _exportedNames_ is not *null*.
1. Let _unambiguousNames_ be a new empty List.
1. For each _name_ that is an element of _exportedNames_, do
1. Let _resolution_ be ? _m_.ResolveExport(_name_, « »).
1. If _resolution_ is a ResolvedBinding Record, append _name_ to _unambiguousNames_.
1. Let _sortedExports_ be a new List containing the same values as the list _unambiguousNames_ where the values are ordered as if an Array of the same values had been sorted using `Array.prototype.sort` using *undefined* as _comparefn_.
1. Set _ns_.[[Exports]] to _sortedExports_.
1. Set _m_.[[Status]] to `"evaluated"`.
1. Assert: _m_.[[EvaluationError]] is *undefined*.
1. Return *undefined*.
</emu-alg>
</emu-clause>
<emu-clause id="sec-setdynamicexportbinding">
<h1>SetDynamicExportBinding ( _name_, _value_ ) Concrete Method</h1>
<p>The SetDynamicExportBinding concrete method of a Dynamic Module Record implements the corresponding Module Record abstract method for a string _name_ and initialization value _value_.</p>
<p>After execution completion, only binding mutation is supported.</p>
<p>This method can return an error on abrupt completion.</p>
<emu-alg>
1. Let _module_ be this Dynamic Module Record.
1. Let _envRec_ be the module Environment Record _module_.[[Environment]].
1. If _module_.[[exportNames]] does not contain _name_ then,
1. If _module_.[[Status]] is `"evaluated"` then,
1. Let _error_ be a *ReferenceError* exception.
1. Return _error_.
1. Append _name_ to the end of _module_.[[exportNames]].
1. Perform _envRec_.CreateMutableBinding(_name_, *false*).
1. Perform _envRec_.InitializeBinding(_name_, _value_).
1. Otherwise,
1. Assert: _envRec_ has a binding for _name_.
1. If the binding for _name_ in _envRec_ has not been initialized then,
1. If _module_.[[Status]] is `"evaluated"` then,
1. Let _error_ be a *ReferenceError* exception.
1. Return _error_.
1. Perform _envRec_.InitializeBinding(_name_, _value_).
1. Otherwise,
1. Perform _envRec_.SetMutableBinding(_name_, _value_, *true*).
1. Return *undefined*.
</emu-alg>
</emu-clause>
</emu-clause>
<emu-clause id="sec-hostevaluatedynamicmodule" aoid="HostEvaluateDynamicModule">
<h1><ins>Runtime Semantics: HostEvaluateDynamicModule ( _dynamicModule_ )</ins></h1>
<p>HostEvaluateDynamicModule is an implementation-defined abstract operation that performs programmatic execution of a Dynamic Module Record, _dynamicModule_.</p>
<p>The implementation of HostEvaluateDynamicModule must conform to the following requirements:</p>
<ul>
<li>
HostEvaluateDynamicModule will call the SetDynamicExportBinding concrete method on the _dynamicModule_ to initialize the export bindings.
</li>
<li>
If there is an evaluation error, it must be thrown.
</li>
</ul>
<emu-note>
<p>HostEvaluateDynamicModule must not itself rely on checking what lexical bindings have already been initialized for the module. It is important that the bindings defined in evaluation are fully independent of what bindings are imported.</p>
</emu-note>
</emu-clause>