Skip to content

Commit e46cfcc

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

File tree

3 files changed

+47
-57
lines changed

3 files changed

+47
-57
lines changed

document/js-api/index.bs

Lines changed: 26 additions & 39 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
@@ -156,6 +157,7 @@ urlPrefix: https://webassembly.github.io/spec/core/; spec: WebAssembly; type: df
156157
text: memory address; url: exec/runtime.html#syntax-memaddr
157158
text: global address; url: exec/runtime.html#syntax-globaladdr
158159
text: extern address; url: exec/runtime.html#syntax-externaddr
160+
text: extern subtype; url: valid/types.html#match-externtype
159161
text: page size; url: exec/runtime.html#page-size
160162
url: syntax/types.html#syntax-numtype
161163
text: i32
@@ -1163,7 +1165,7 @@ Note: Exported Functions do not have a \[[Construct]] method and thus it is not
11631165
1. Let |values| be [=?=] [$IteratorToList$]([=?=] [$GetIteratorFromMethod$](|ret|, |method|)).
11641166
1. Let |wasmValues| be a new, empty [=list=].
11651167
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,
1168+
1. For each |value| and |resultType| in |values| and |results|, paired linearly,
11671169
1. [=list/Append=] [=ToWebAssemblyValue=](|value|, |resultType|) to |wasmValues|.
11681170
1. Return |wasmValues|.
11691171
</div>
@@ -1388,9 +1390,11 @@ To <dfn export>parse a WebAssembly module</dfn> given a <a>byte sequence</a> |by
13881390
1. If |module| is [=error=], throw a {{CompileError}} exception.
13891391
1. [=Construct a WebAssembly module object=] from |module| and |bytes|, and let |module| be the result.
13901392
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]]),
1393+
1. For each (|moduleName|, <var ignore>name</var>, <var ignore>type</var>) in [=module_imports=](|module|.\[[Module]]),
13921394
1. [=set/Append=] |moduleName| to |requestedModules|.
13931395
1. Let |moduleRecord| be {
1396+
<!-- WebAssembly Module Records -->
1397+
\[[Instance]]: ~empty~,
13941398
<!-- Abstract Module Records -->
13951399
\[[Realm]]: |realm|,
13961400
\[[Environment]]: ~empty~,
@@ -1422,7 +1426,7 @@ The <dfn>export name list</dfn> of a WebAssembly Module Record |record| is defin
14221426

14231427
1. Let |module| be |record|'s \[[ModuleSource]] internal slot.
14241428
1. Let |exports| be an empty [=list=].
1425-
1. [=list/iterate|For each=] (|name|, <var ignore>type</var>) in [=module_exports=](|module|.\[[Module]])
1429+
1. For each (|name|, <var ignore>type</var>) in [=module_exports=](|module|.\[[Module]])
14261430
1. [=list/Append=] |name| to the end of |exports|.
14271431
1. Return |exports|.
14281432

@@ -1483,9 +1487,9 @@ WebAssembly Module Records have the following methods:
14831487
1. Let |resolutionName| be |resolution|.\[[BindingName]].
14841488
1. Let |externval| be [=instance_export=](|resolutionInstance|, |resolutionName|).
14851489
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|).
1488-
1. If [=module_extern_subtype=](|externtype|, |importtype|) is false, throw a {{LinkError}} exception.
1490+
1. Assert: [=module_exports=](|resolutionModule|) contains an element (|resolutionName|, <var ignore>type</var>).
1491+
1. Let |externtype| be the value of |type| for the element (|resolutionName|, |type|) in [=module_exports=](|resolutionModule|).
1492+
1. If |importtype| is not an [=extern subtype=] of |externtype|, throw a {{LinkError}} exception.
14891493
1. [=list/Append=] |externval| to |imports|.
14901494
1. Otherwise,
14911495
1. Let |env| be |resolution|.\[[Module]].\[[Environment]].
@@ -1500,13 +1504,15 @@ WebAssembly Module Records have the following methods:
15001504
1. Let |externfunc| be the [=external value=] [=external value|func=] |funcaddr|.
15011505
1. [=list/Append=] |externfunc| to |imports|.
15021506
1. If |importtype| is of the form [=global=] |mut| |valtype|,
1507+
1. Let |store| be the [=surrounding agent=]'s [=associated store=].
15031508
1. If |v| [=implements=] {{Global}},
15041509
1. Let |globaladdr| be |v|.\[[Global]].
1510+
1. Let |targetmut| <var ignore>valuetype</var> be [=global_type=](|store|, |globaladdr|).
1511+
1. If |mut| is [=const=] and |targetmut| is [=var=], throw a {{TypeError}}.
15051512
1. Otherwise,
1506-
1. If |valtype| is [=v128=],
1507-
1. Throw a {{LinkError}} exception.
1513+
1. If |valtype| is [=v128=], throw a {{LinkError}} exception.
1514+
1. If |mut| is [=var=], throw a {{TypeError}}.
15081515
1. Let |value| be [=?=] [=ToWebAssemblyValue=](|v|, |valtype|).
1509-
1. Let |store| be the [=surrounding agent=]'s [=associated store=].
15101516
1. Let (|store|, |globaladdr|) be [=global_alloc=](|store|, |mut| |valtype|, |value|).
15111517
1. Set the [=surrounding agent=]'s [=associated store=] to |store|.
15121518
1. Let |externglobal| be [=external value|global=] |globaladdr|.
@@ -1522,53 +1528,34 @@ WebAssembly Module Records have the following methods:
15221528
1. [=list/Append=] |externtable| to |imports|.
15231529
1. [=Instantiate the core of a WebAssembly module=] |module| with |imports|, and let |instance| be the result.
15241530
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|).
1531+
1. [=list/iterate|For each=] (|name|, |externtype|) of [=module_exports=](|module|),
15331532
1. If |externtype| is of the form [=global=] |mut| |globaltype|,
15341533
1. Assert: |externval| is of the form [=external value|global=] |globaladdr|.
15351534
1. Let [=external value|global=] |globaladdr| be |externval|.
15361535
1. Let |global_value| be [=global_read=](|store|, |globaladdr|).
15371536
1. If |globaltype| is not [=v128=],
1538-
1. Note: When integrating with shared globals, they will be excluded here similarly to v128 above.
1537+
1. Note: The condition above leaves unsupported JS values as uninitialized in TDZ and therefore as a reference error on
1538+
access. When integrating with shared globals, they may be excluded here similarly to v128 above.
15391539
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
1540+
1. If |mut| is [=var=], then associate all future mutations of |globaladdr| with the ECMA-262 binding record for |name| in
15411541
|record|.\[[Environment]], such that |record|.\[[Environment]].GetBindingValue(|resolution|.\[[BindingName]], true)
15421542
always returns [=ToJSValue=]([=global_read=](|store|, |globaladdr|)) for the current [=surrounding agent=]'s
15431543
[=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.
1544+
1. Otherwise,
1545+
1. Perform ! |record|.\[[Environment]].InitializeBinding(|name|, ! Get(|instance|.\[[Exports]], |name|)).
15601546

15611547
</div>
15621548

15631549
<h3 id="hostgetmodulesourcemodulerecord">HostGetModuleSourceModuleRecord ( |specifier| )</h3>
15641550
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,
1551+
1. If |specifier|.\[[Module]].\[[ModuleRecord]] is null,
15671552
1. Let |realm| be the current agent's realm record.
15681553
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|),
1554+
1. For each (|moduleName|, <var ignore>name</var>, <var ignore>type</var>) in [=module_imports=](|specifier|.\[[Module]]),
15701555
1. [=set/Append=] |moduleName| to |requestedModules|.
15711556
1. Let |moduleRecord| be {
1557+
<!-- WebAssembly Module Records -->
1558+
\[[Instance]]: ~empty~,
15721559
<!-- Abstract Module Records -->
15731560
\[[Realm]]: |realm|,
15741561
\[[Environment]]: ~empty~,
@@ -1591,7 +1578,7 @@ will always reflect the current mutable global export value as interpreted throu
15911578
}.
15921579
1. Set |module|.\[[ModuleRecord]] to |moduleRecord|.
15931580
1. Return |moduleRecord|.
1594-
1. Return |module|.\[[ModuleRecord]].
1581+
1. Return |specifier|.\[[Module]].\[[ModuleRecord]].
15951582
1. Return ~not-a-source~.
15961583

15971584
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: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -123,13 +123,17 @@ for (let index = 0; index < length; index++)
123123
| table | `WebAssembly.Table` object |
124124
| function | WebAssembly exported function |
125125

126+
Wasm bindings cannot be reassigned as it can in JS, so the exported value will not change in their object identity. But the value that it points to (e.g. `.value` in the case of `WebAssembly.Global`) can change.
127+
126128
1. JS module is parsed
127129
1. wasm module is parsed
128130
1. wasm module has a lexical environment created for its exports. All exports are initially in TDZ.
129131
1. JS module is instantiated. Imports are bound to the same memory locations.
130132
1. wasm module is instantiated evaluated. Functions are initialized. Memories and tables are initialized and filled with data/elem sections. Globals are initialized and initializer expressions are evaluated. The start function runs.
131133
1. JS module is evaluated. All values are available.
132134

135+
The value of the export for `WebAssembly.Global` is provided directly on the JS namespace object, with mutable globals reflected as live bindings to JS.
136+
133137
#### Example
134138

135139
```js
@@ -177,7 +181,7 @@ Wasm exports can be imported as accurate, immutable bindings to other wasm modul
177181

178182
### wasm imports <- JS re-exports <- wasm exports
179183

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.
184+
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.
181185

182186
#### Example
183187

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

214218
1. JS module is parsed
215219
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.
220+
1. wasm module has a lexical environment created for its exports. All exports are initially in TDZ.
217221
1. JS module is instantiated. All imports (including functions) from the wasm module are memory locations holding undefined.
218222
1. wasm module is instantiated and evaluated. Snapshots of imports are taken. Export bindings are initialized.
219223
1. JS module is evaluated.
@@ -251,8 +255,8 @@ export function functionExport() {
251255
1. wasm module is parsed
252256
1. JS module is parsed
253257
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.
258+
1. wasm module has a lexical environment created for its exports. All exports are initially in TDZ.
259+
1. JS module is evaluated. wasm exports lead to a ReferenceError if used.
256260
1. wasm module is instantiated and evaluated; wasm-exported bindings are updated to their appropriate JS API-exposed values.
257261

258262
#### Examples

0 commit comments

Comments
 (0)