Skip to content

Commit 36b6a94

Browse files
authored
Update readme with some wasm2js docs and other stuff (#2086)
1 parent f10bc3e commit 36b6a94

1 file changed

Lines changed: 58 additions & 42 deletions

File tree

README.md

Lines changed: 58 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -131,21 +131,22 @@ Notes when working with Binaryen IR:
131131

132132
This repository contains code that builds the following tools in `bin/`:
133133

134-
* **wasm-shell**: A shell that can load and interpret WebAssembly code. It can
135-
also run the spec test suite.
134+
* **wasm-opt**: Loads WebAssembly and runs Binaryen IR passes on it.
136135
* **wasm-as**: Assembles WebAssembly in text format (currently S-Expression
137136
format) into binary format (going through Binaryen IR).
138137
* **wasm-dis**: Un-assembles WebAssembly in binary format into text format
139138
(going through Binaryen IR).
140-
* **wasm-opt**: Loads WebAssembly and runs Binaryen IR passes on it.
139+
* **wasm2js**: A WebAssembly-to-JS compiler. This is used by Emscripten to
140+
generate JavaScript as an alternative to WebAssembly.
141+
* **wasm-shell**: A shell that can load and interpret WebAssembly code. It can
142+
also run the spec test suite.
143+
* **wasm-emscripten-finalize**: Takes a wasm binary produced by llvm+lld and
144+
performs emscripten-specific passes over it.
141145
* **asm2wasm**: An asm.js-to-WebAssembly compiler, using Emscripten's asm
142146
optimizer infrastructure. This is used by Emscripten in Binaryen mode when it
143147
uses Emscripten's fastcomp asm.js backend.
144-
* **wasm2js**: A WebAssembly-to-JS compiler (still experimental).
145148
* **wasm-ctor-eval**: A tool that can execute C++ global constructors ahead of
146149
time. Used by Emscripten.
147-
* **wasm-emscripten-finalize**: Takes a wasm binary produced by llvm+lld and
148-
performs emscripten-specific passes over it.
149150
* **binaryen.js**: A standalone JavaScript library that exposes Binaryen methods for [creating and optimizing WASM modules](https://github.com/WebAssembly/binaryen/blob/master/test/binaryen.js/hello-world.js). For builds, see [binaryen.js on npm](https://www.npmjs.com/package/binaryen) (or download it directly from [github](https://raw.githubusercontent.com/AssemblyScript/binaryen.js/master/index.js), [rawgit](https://cdn.rawgit.com/AssemblyScript/binaryen.js/master/index.js), or [unpkg](https://unpkg.com/binaryen@latest/index.js)).
150151

151152
Usage instructions for each are below.
@@ -224,9 +225,59 @@ Some more notes:
224225
* See `bin/wasm-opt --help` for the full list of options and passes.
225226
* Passing `--debug` will emit some debugging info.
226227

228+
### wasm2js
229+
230+
Run
231+
232+
```
233+
bin/wasm2js [input.wasm file]
234+
```
235+
236+
This will print out JavaScript to the console.
237+
238+
For example, try
239+
240+
```
241+
$ bin/wasm2js test/hello_world.wast
242+
```
243+
244+
That output contains
245+
246+
```
247+
function add(x, y) {
248+
x = x | 0;
249+
y = y | 0;
250+
return x + y | 0 | 0;
251+
}
252+
```
253+
254+
as a translation of
255+
256+
```
257+
(func $add (; 0 ;) (type $0) (param $x i32) (param $y i32) (result i32)
258+
(i32.add
259+
(local.get $x)
260+
(local.get $y)
261+
)
262+
)
263+
```
264+
265+
You can also tell wasm2js to optimize, using the normal optimization flags
266+
wasm-opt and other tools receive (such as `-Os`). For optimal code size,
267+
you should both optimize and run a JavaScript minifier afterwards.
268+
269+
Things to keep in mind with wasm2js's output:
270+
271+
* It is not possible to match WebAssemblty semantics 100% precisely with fast
272+
JavaScript code. For example, every load and store may trap, and to make
273+
JavaScript do the same we'd need to add checks everywhere, which would be
274+
large and slow. Instead, wasm2js assumes loads and stores do not trap, that
275+
int/float conversions do not trap, and so forth. There may also be slight
276+
differences in corner cases of conversions, like non-trapping float to int.
277+
227278
### asm2wasm
228279

229-
run
280+
Run
230281

231282
```
232283
bin/asm2wasm [input.asm.js file]
@@ -315,41 +366,6 @@ The `check.py` script supports some options:
315366

316367
## FAQ
317368

318-
* How does `asm2wasm` relate to the new WebAssembly backend which is being
319-
developed in upstream LLVM?
320-
321-
This is separate from that. `asm2wasm` focuses on compiling asm.js to
322-
WebAssembly, as emitted by Emscripten's asm.js backend. This is useful because
323-
while in the long term Emscripten hopes to use the new WebAssembly backend, the
324-
`asm2wasm` route is a very quick and easy way to generate WebAssembly output.
325-
It will also be useful for benchmarking the new backend as it progresses.
326-
327-
* How about compiling WebAssembly to asm.js (the opposite direction of
328-
`asm2wasm`)? Wouldn't that be useful for polyfilling?
329-
330-
Experimentation with this is happening, in `wasm2js`.
331-
332-
This would be useful, but it is a much harder task, due to some decisions made
333-
in WebAssembly. For example, WebAssembly can have control flow nested inside
334-
expressions, which can't directly map to asm.js. It could be supported by
335-
outlining the code to another function, or to compiling it down into new basic
336-
blocks and control-flow-free instructions, but it is hard to do so in a way that
337-
is both fast to do and emits code that is fast to execute. On the other hand,
338-
compiling asm.js to WebAssembly is almost straightforward.
339-
340-
We just have to do more work on `wasm2js` and see how efficient we can make it.
341-
342-
* Can `asm2wasm` compile any asm.js code?
343-
344-
Almost. Some decisions made in WebAssembly preclude that, for example, there are
345-
no global variables. That means that `asm2wasm` has to map asm.js global
346-
variables onto locations in memory, but then it must know of a safe zone in
347-
memory in which to do so, and that information is not directly available in
348-
asm.js.
349-
350-
`asm2wasm` do some integration with Emscripten in order to work around these
351-
issues, like asking Emscripten to reserve same space for the globals, etc.
352-
353369
* Why the weird name for the project?
354370

355371
"Binaryen" is a combination of **binary** - since WebAssembly is a binary format

0 commit comments

Comments
 (0)