Skip to content

Commit 1fd242e

Browse files
committed
simplify: remove cyclic binding handling
1 parent 6e393ee commit 1fd242e

File tree

4 files changed

+73
-57
lines changed

4 files changed

+73
-57
lines changed

document/core/appendix/embedding.rst

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,37 @@ Modules
137137
\F{module\_validate}(m) &=& \ERROR && (\otherwise) \\
138138
\end{array}
139139
140+
.. index:: matching, external type
141+
.. _embed-extern-subtype:
142+
143+
:math:`\F{module\_extern\_subtype}(\externtype_1, \externtype_2) : \bool`
144+
.........................................................................
145+
146+
1. If :math:`\externtype_1` and :math:`\externtype_2` are both of the form :math:`\ETFUNC~\functype_1` and :math:`\ETFUNC~\functype_2` respectively:
147+
148+
a. Return true if and only if :math:`\vdashexterntypematch \ETFUNC~\functype_1 \matchesexterntype \ETFUNC~\functype_2`.
149+
150+
2. If :math:`\externtype_1` and :math:`\externtype_2` are both of the form :math:`\ETTABLE~\tabletype_1` and :math:`\ETTABLE~\tabletype_2` respectively:
151+
152+
a. Return true if and only if :math:`\vdashexterntypematch \ETTABLE~\tabletype_1 \matchesexterntype \ETTABLE~\tabletype_2`.
153+
154+
3. If :math:`\externtype_1` and :math:`\externtype_2` are both of the form :math:`\ETMEM~\memtype_1` and :math:`\ETMEM~\memtype_2` respectively:
155+
156+
a. Return true if and only if :math:`\vdashexterntypematch \ETMEM~\memtype_1 \matchesexterntype \ETMEM~\memtype_2`.
157+
158+
4. If :math:`\externtype_1` and :math:`\externtype_2` are both of the form :math:`\ETGLOBAL~\globaltype_1` and :math:`\ETGLOBAL~\globaltype_2` respectively:
159+
160+
a. Return true if and only if :math:`\vdashexterntypematch \ETGLOBAL~\globaltype_1 \matchesexterntype \ETGLOBAL~\globaltype_2`.
161+
162+
5. Return false.
163+
164+
.. math::
165+
\begin{array}{lclll}
166+
\F{module\_extern\_subtype}(\externtype_1, \externtype_2) &\iff& \vdashexterntypematch \externtype_1 \matchesexterntype \externtype_2 \\
167+
\end{array}
168+
.. note::
169+
This function encapsulates the external type matching relation defined in the :ref:`Import Subtyping <match>` of the validation section, where the :math:`\vdashexterntypematch \externtype_1 \matchesexterntype \externtype_2` judgment establishes compatibility between external types. This allows for explicit checking of type compatibility when linking modules or validating imports against exports.
170+
140171

141172
.. index:: instantiation, module instance
142173
.. _embed-module-instantiate:

document/js-api/index.bs

Lines changed: 24 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,7 @@ urlPrefix: https://webassembly.github.io/spec/core/; spec: WebAssembly; type: df
123123
text: store_init; url: appendix/embedding.html#embed-store-init
124124
text: module_decode; url: appendix/embedding.html#embed-module-decode
125125
text: module_validate; url: appendix/embedding.html#embed-module-validate
126+
text: module_extern_subtype; url: appendix/embedding.html#embed-module-extern-subtype
126127
text: module_instantiate; url: appendix/embedding.html#embed-module-instantiate
127128
text: module_imports; url: appendix/embedding.html#embed-module-imports
128129
text: module_exports; url: appendix/embedding.html#embed-module-exports
@@ -1163,7 +1164,7 @@ Note: Exported Functions do not have a \[[Construct]] method and thus it is not
11631164
1. Let |values| be [=?=] [$IteratorToList$]([=?=] [$GetIteratorFromMethod$](|ret|, |method|)).
11641165
1. Let |wasmValues| be a new, empty [=list=].
11651166
1. If |values|'s [=list/size=] is not |resultsSize|, throw a {{TypeError}} exception.
1166-
1. [=list/iterate|For each=] |value| and |resultType| in |values| and |results|, paired linearly,
1167+
1. For each |value| and |resultType| in |values| and |results|, paired linearly,
11671168
1. [=list/Append=] [=ToWebAssemblyValue=](|value|, |resultType|) to |wasmValues|.
11681169
1. Return |wasmValues|.
11691170
</div>
@@ -1388,9 +1389,11 @@ To <dfn export>parse a WebAssembly module</dfn> given a <a>byte sequence</a> |by
13881389
1. If |module| is [=error=], throw a {{CompileError}} exception.
13891390
1. [=Construct a WebAssembly module object=] from |module| and |bytes|, and let |module| be the result.
13901391
1. Let |requestedModules| be a set.
1391-
1. [=list/iterate|For each=] (|moduleName|, <var ignore>name</var>, <var ignore>type</var>) in [=module_imports=](|module|.\[[Module]]),
1392+
1. For each (|moduleName|, <var ignore>name</var>, <var ignore>type</var>) in [=module_imports=](|module|.\[[Module]]),
13921393
1. [=set/Append=] |moduleName| to |requestedModules|.
13931394
1. Let |moduleRecord| be {
1395+
<!-- WebAssembly Module Records -->
1396+
\[[Instance]]: ~empty~,
13941397
<!-- Abstract Module Records -->
13951398
\[[Realm]]: |realm|,
13961399
\[[Environment]]: ~empty~,
@@ -1422,7 +1425,7 @@ The <dfn>export name list</dfn> of a WebAssembly Module Record |record| is defin
14221425

14231426
1. Let |module| be |record|'s \[[ModuleSource]] internal slot.
14241427
1. Let |exports| be an empty [=list=].
1425-
1. [=list/iterate|For each=] (|name|, <var ignore>type</var>) in [=module_exports=](|module|.\[[Module]])
1428+
1. For each (|name|, <var ignore>type</var>) in [=module_exports=](|module|.\[[Module]])
14261429
1. [=list/Append=] |name| to the end of |exports|.
14271430
1. Return |exports|.
14281431

@@ -1483,8 +1486,8 @@ WebAssembly Module Records have the following methods:
14831486
1. Let |resolutionName| be |resolution|.\[[BindingName]].
14841487
1. Let |externval| be [=instance_export=](|resolutionInstance|, |resolutionName|).
14851488
1. Assert: |externval| is not [=error=].
1486-
1. Assert: [=module_direct_exports=](|resolutionModule|) contains an element (|resolutionName|, <var ignore>type</var>).
1487-
1. Let |externtype| be the value of |type| for the element (|resolutionName|, |type|) in [=module_direct_exports=](|resolutionModule|).
1489+
1. Assert: [=module_exports=](|resolutionModule|) contains an element (|resolutionName|, <var ignore>type</var>).
1490+
1. Let |externtype| be the value of |type| for the element (|resolutionName|, |type|) in [=module_exports=](|resolutionModule|).
14881491
1. If [=module_extern_subtype=](|externtype|, |importtype|) is false, throw a {{LinkError}} exception.
14891492
1. [=list/Append=] |externval| to |imports|.
14901493
1. Otherwise,
@@ -1500,13 +1503,15 @@ WebAssembly Module Records have the following methods:
15001503
1. Let |externfunc| be the [=external value=] [=external value|func=] |funcaddr|.
15011504
1. [=list/Append=] |externfunc| to |imports|.
15021505
1. If |importtype| is of the form [=global=] |mut| |valtype|,
1506+
1. Let |store| be the [=surrounding agent=]'s [=associated store=].
15031507
1. If |v| [=implements=] {{Global}},
15041508
1. Let |globaladdr| be |v|.\[[Global]].
1509+
1. Let |targetmut| <var ignore>valuetype</var> be [=global_type=](|store|, |globaladdr|).
1510+
1. If |mut| is [=const=] and |targetmut| is [=var=], throw a {{TypeError}}.
15051511
1. Otherwise,
1506-
1. If |valtype| is [=v128=],
1507-
1. Throw a {{LinkError}} exception.
1512+
1. If |valtype| is [=v128=], throw a {{LinkError}} exception.
1513+
1. If |mut| is [=var=], throw a {{TypeError}}.
15081514
1. Let |value| be [=?=] [=ToWebAssemblyValue=](|v|, |valtype|).
1509-
1. Let |store| be the [=surrounding agent=]'s [=associated store=].
15101515
1. Let (|store|, |globaladdr|) be [=global_alloc=](|store|, |mut| |valtype|, |value|).
15111516
1. Set the [=surrounding agent=]'s [=associated store=] to |store|.
15121517
1. Let |externglobal| be [=external value|global=] |globaladdr|.
@@ -1522,53 +1527,34 @@ WebAssembly Module Records have the following methods:
15221527
1. [=list/Append=] |externtable| to |imports|.
15231528
1. [=Instantiate the core of a WebAssembly module=] |module| with |imports|, and let |instance| be the result.
15241529
1. Set |record|.\[[Instance]] to |instance|.
1525-
1. [=list/iterate|For each=] (|name|, |externtype|) of [=module_direct_exports=](|module|),
1526-
1. Let |externval| be [=instance_export=](|instance|, |name|).
1527-
1. Assert: |externval| is not [=error=].
1528-
1. If |externtype| is of the form [=func=] <var ignore>functype</var>,
1529-
1. Assert: |externval| is of the form [=external value|func=] |funcaddr|.
1530-
1. Let [=external value|func=] |funcaddr| be |externval|.
1531-
1. Let |func| be the result of creating [=a new Exported Function=] from |funcaddr|.
1532-
1. Perform [=!=] |record|.\[[Environment]].InitializeBinding(|name|, |func|).
1530+
1. [=list/iterate|For each=] (|name|, |externtype|) of [=module_exports=](|module|),
15331531
1. If |externtype| is of the form [=global=] |mut| |globaltype|,
15341532
1. Assert: |externval| is of the form [=external value|global=] |globaladdr|.
15351533
1. Let [=external value|global=] |globaladdr| be |externval|.
15361534
1. Let |global_value| be [=global_read=](|store|, |globaladdr|).
15371535
1. If |globaltype| is not [=v128=],
1538-
1. Note: When integrating with shared globals, they will be excluded here similarly to v128 above.
1536+
1. Note: The condition above leaves unsupported JS values as uninitialized in TDZ and therefore as a reference error on
1537+
access. When integrating with shared globals, they may be excluded here similarly to v128 above.
15391538
1. Perform [=!=] |record|.\[[Environment]].InitializeBinding(|name|, [=ToJSValue=](|global_value|)).
1540-
1. Associate all future mutations to the mutable value at |globaladdr| with the ECMA-262 binding record for |name| in
1539+
1. If |mut| is [=var=], then associate all future mutations of |globaladdr| with the ECMA-262 binding record for |name| in
15411540
|record|.\[[Environment]], such that |record|.\[[Environment]].GetBindingValue(|resolution|.\[[BindingName]], true)
15421541
always returns [=ToJSValue=]([=global_read=](|store|, |globaladdr|)) for the current [=surrounding agent=]'s
15431542
[=associated store=] |store|.
1544-
1. If |externtype| is of the form [=mem=] <var ignore>memtype</var>,
1545-
1. Assert: |externval| is of the form [=external value|mem=] |memaddr|.
1546-
1. Let [=external value|mem=] |memaddr| be |externval|.
1547-
1. Let |memory| be [=create a memory object|a new Memory object=] created from |memaddr|.
1548-
1. Perform [=!=] |record|.\[[Environment]].InitializeBinding(|name|, |memory|).
1549-
1. If |externtype| is of the form [=table=] <var ignore>tabletype</var>,
1550-
1. Assert: |externval| is of the form [=external value|table=] |tableaddr|.
1551-
1. Let [=external value|table=] |tableaddr| be |externval|.
1552-
1. Let |table| be [=create a Table object|a new Table object=] created from |tableaddr|.
1553-
1. Perform [=!=] |record|.\[[Environment]].InitializeBinding(|name|, |table|).
1554-
1555-
Note: The export bindings for a WebAssembly Module Record are designed to mirror the live bindings of all directly exported values. Values not
1556-
supported in JS are left uninitialized and in TDZ, while still being accesible to Wasm importers. Indirect exports (re-exports) referencing
1557-
JavaScript values will capture the [=ToWebAssemblyValue=] interpretation at the time of execution, while indirect exports resolving to other Wasm
1558-
modules will support Wasm live bindings. For exported mutable globals that are supported in JavaScript, the live bindings on the environment record
1559-
will always reflect the current mutable global export value as interpreted through the infallible [=ToJSValue=] interpretation.
1543+
1. Otherwise,
1544+
1. Perform ! |record|.\[[Environment]].InitializeBinding(|name|, ! Get(|instance|.\[[Exports]], |name|)).
15601545

15611546
</div>
15621547

15631548
<h3 id="hostgetmodulesourcemodulerecord">HostGetModuleSourceModuleRecord ( |specifier| )</h3>
15641549
1. If |specifier| is a WebAssembly {{Module}} object with a \[[Module]] internal slot,
1565-
1. Let |module| be |specifier|.\[[Module]].
1566-
1. If |module|.\[[ModuleRecord]] is null,
1550+
1. If |specifier|.\[[Module]].\[[ModuleRecord]] is null,
15671551
1. Let |realm| be the current agent's realm record.
15681552
1. Let |requestedModules| be a set.
1569-
1. [=list/iterate|For each=] (|moduleName|, <var ignore>name</var>, <var ignore>type</var>) in [=module_imports=](|module|),
1553+
1. For each (|moduleName|, <var ignore>name</var>, <var ignore>type</var>) in [=module_imports=](|specifier|.\[[Module]]),
15701554
1. [=set/Append=] |moduleName| to |requestedModules|.
15711555
1. Let |moduleRecord| be {
1556+
<!-- WebAssembly Module Records -->
1557+
\[[Instance]]: ~empty~,
15721558
<!-- Abstract Module Records -->
15731559
\[[Realm]]: |realm|,
15741560
\[[Environment]]: ~empty~,
@@ -1591,7 +1577,7 @@ will always reflect the current mutable global export value as interpreted throu
15911577
}.
15921578
1. Set |module|.\[[ModuleRecord]] to |moduleRecord|.
15931579
1. Return |moduleRecord|.
1594-
1. Return |module|.\[[ModuleRecord]].
1580+
1. Return |specifier|.\[[Module]].\[[ModuleRecord]].
15951581
1. Return ~not-a-source~.
15961582

15971583
Note: See corresponding modifications to HTML in <a href="https://github.com/whatwg/html/pull/10380">PR #10380</a>.

proposals/esm-integration/EXAMPLES.md

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -177,7 +177,7 @@ Wasm exports can be imported as accurate, immutable bindings to other wasm modul
177177

178178
### wasm imports <- JS re-exports <- wasm exports
179179

180-
Any wasm exports that are re-exported via a JS module will be available to the other wasm module as accurate bindings. If the binding is a mutable global, then that binding will be a live export binding in JS reflecting changes to the Wasm global value. When imported from JS, the first and second Wasm modules will yield the same Wasm identities for the multiply exported Wasm objects.
180+
Any wasm exports that are re-exported via a JS module will be available to the other wasm module as accurate, immutable bindings. The wasm export gets wrapped into a JS object (e.g. `WebAssembly.Global`) and then unwrapped to the wasm import in the importing wasm module. When imported from JS, the first and second Wasm modules will yield the same object identities for the multiply exported Wasm objects.
181181

182182
#### Example
183183

@@ -213,7 +213,7 @@ export {memoryExport} from "./b.wasm";
213213

214214
1. JS module is parsed
215215
1. wasm module is parsed
216-
1. wasm module has a lexical environment created for its exports. All direct exports are initially in TDZ, indirect exports are available as they resolve.
216+
1. wasm module has a lexical environment created for its exports. All exports are initially in TDZ.
217217
1. JS module is instantiated. All imports (including functions) from the wasm module are memory locations holding undefined.
218218
1. wasm module is instantiated and evaluated. Snapshots of imports are taken. Export bindings are initialized.
219219
1. JS module is evaluated.
@@ -250,9 +250,9 @@ export function functionExport() {
250250

251251
1. wasm module is parsed
252252
1. JS module is parsed
253-
1. JS module is instantiated.
254-
1. wasm module has a lexical environment created for its exports. All direct exports are initially in TDZ, indirect exports are available as they resolve.
255-
1. JS module is evaluated. wasm exports in TDZ lead to a ReferenceError if used.
253+
1. JS module is instantiated.
254+
1. wasm module has a lexical environment created for its exports. All exports are initially in TDZ.
255+
1. JS module is evaluated. wasm exports lead to a ReferenceError if used.
256256
1. wasm module is instantiated and evaluated; wasm-exported bindings are updated to their appropriate JS API-exposed values.
257257

258258
#### Examples

0 commit comments

Comments
 (0)