Skip to content

Commit 1a3226b

Browse files
committed
Update overview
1 parent 33ee736 commit 1a3226b

File tree

1 file changed

+33
-23
lines changed

1 file changed

+33
-23
lines changed

proposals/compact-import-section/Overview.md

Lines changed: 33 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -6,27 +6,10 @@ The binary format for the import section today must redundantly specify both the
66

77
This problem is exacerbated by [JS String Builtins](https://github.com/WebAssembly/js-string-builtins), as modules can have a very large number of imports to handle all the string constants needed in the module. This can be mitigated somewhat by network compression, but this cost must still be paid at parsing time after decompression.
88

9-
In addition, the JS API specifies an algorithm for ["reading the imports"](https://webassembly.github.io/spec/js-api/#read-the-imports) which suffers from the redundancy in the binary format. For every import we must issue two separate [[Get]] operations. In practice the first one is redundant and could be optimized away; however, [[Get]] is observable to JS code and so special care must be taken to only skip it if nothing could observe it.
10-
119
## Proposal
1210

1311
This proposal aims to solve this problem through a small change to the binary format, encoding the module name only once, followed by a list of `(item name, externtype)` pairs. (Currently imports are encoded as `(module name, item name, externtype)` triples.)
1412

15-
### Syntax
16-
17-
The AST for imports is extended to include both "imports" and "import modules", separating the module and item names:
18-
19-
```
20-
;; Before
21-
import ::== name name externtype
22-
module ::== ... import* ...
23-
24-
;; After
25-
import ::== name externtype
26-
importmod ::== name import*
27-
module ::== ... importmod* ...
28-
```
29-
3013
### Binary
3114

3215
An import module with multiple imports is encoded by: the byte sequence `0x01 0xFF`, the module name, and a [list](https://webassembly.github.io/spec/core/binary/conventions.html#binary-list) (vec) of imports. The previous encoding is redefined to produce an import module with a single import.
@@ -62,15 +45,42 @@ The existing import abbreviations, e.g. `(global (import "foo" "bar") ...)`, wil
6245

6346
It is expected that the different text encodings and the different binary encodings will be one-to-one; that is, the `item` format always corresponds to the compact import encoding, and the legacy abbreviation always corresponds to the non-compact encoding. This ensures that data will round-trip correctly through the text format.
6447

65-
### Validation & Execution
48+
### Syntax, Validation, Execution
6649

67-
No significant changes are necessary to validation and execution.
50+
No changes are made to the syntax, validation, or execution sections.
6851

69-
### JS API
7052

71-
The ["read the imports"](https://webassembly.github.io/spec/js-api/index.html#read-the-imports) step in the JS API is updated to perform one [[Get]] per import module name and one [[Get]] per import name within an import module.
53+
## Alternatives
7254

55+
### Update the AST of modules
7356

74-
## Alternatives
57+
It would be possible to manifest this change in the structure of a WebAssembly module like so:
58+
59+
```
60+
;; Before
61+
import ::== name name externtype
62+
module ::== ... import* ...
63+
64+
;; After
65+
import ::== name externtype
66+
importmod ::== name import*
67+
module ::== ... importmod* ...
68+
```
69+
70+
Depending on implementation, this could potentially reduce the size of modules in memory. In addition, the ["read the imports"](https://webassembly.github.io/spec/js-api/#read-the-imports) section of the JS API could be updated to reflect the AST, dispatching only one [[Get]] to the imports object for each `importmod`, resulting in fewer object accesses overall. This could potentially have performance improvements in JS engines.
71+
72+
However, this change to the AST would complicate various aspects of the spec, including some changes to validation and execution, and particularly impacting the `module_imports` function in the Embedding appendix. In addition, it clashes with existing host APIs for imports, particularly the JS API's [Module.imports](https://webassembly.github.io/spec/js-api/index.html#dom-module-imports) function, which returns `{"module": "...", "name": "...", "kind": "..."}` triples. It would presumably be best to change the return value of this function if the structure of imports were to change, but this would be a quite incompatible change.
73+
74+
### Add a new section ID
75+
76+
Instead of using an invalid `name` (`0x01 0xFF`) to signify a run of compact imports, we could introduce a new section ID to the binary encoding. This would result in a cleaner and (very) slightly more compact encoding, but both forms of the import section would need to remain in the spec.
77+
78+
Also, if adding a new section ID, it is less clear how the binary encoding would map to the text encoding. This proposal specifies that `(import "foo" (item "bar" ...))` will use the compact encoding, and `(import "foo" "bar" ...)` will use the non-compact encoding. Consider, then, this set of imports in the text format:
79+
80+
```
81+
(import "foo" "bar" ...)
82+
(import "baz" (item "im1" ...) (item "im2" ...))
83+
(import "beep" "boop" ...)
84+
```
7585

76-
TODO
86+
If the encodings are mixed, but must appear in separate sections, then it will not be possible to preserve the order of imports when round-tripping through the binary format. Either additional ordering information would be required, which would be superfluous, or perhaps the non-`(item)` form would simply use the compact encoding as well, which may actually bloat the binary due to the sentinel name appearing repeatedly.

0 commit comments

Comments
 (0)