You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: proposals/compact-import-section/Overview.md
+33-23Lines changed: 33 additions & 23 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -6,27 +6,10 @@ The binary format for the import section today must redundantly specify both the
6
6
7
7
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.
8
8
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
-
11
9
## Proposal
12
10
13
11
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.)
14
12
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
-
30
13
### Binary
31
14
32
15
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
62
45
63
46
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.
64
47
65
-
### Validation & Execution
48
+
### Syntax, Validation, Execution
66
49
67
-
No significant changes are necessary to validation and execution.
50
+
No changes are made to the syntax, validation, or execution sections.
68
51
69
-
### JS API
70
52
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
72
54
55
+
### Update the AST of modules
73
56
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
+
```
75
85
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