The input is a Wasm module, and the output is a single Go source file, with no dependencies beyond the standard library.
To translate a Wasm module to Go use the following command:
wasm2go < input.wasm > output.go
The Go file forms a self contained package,
that exports a structure called Module,
and a New function to initialize it.
The methods of the Module structure are the Wasm module's exports,
whereas imports are interfaces New consumes.
We assume the input Wasm modules can be trusted. At a minimum, you should run Wasm modules through a verifier before attempting to convert an untrusted module.
The current target is a useful subset of Wasm produced by clang,
including the following features:
- bulk memory instructions and reference types;
- non-trapping float-to-int conversions;
- sign-extension instructions;
- multi-value results;
- 64-bit address space;
- extended constant expressions.
Generating human readable Go code is a non-goal:
- Wasm names must be mangled into Go identifiers;
- Wasm control flow is implemented with
gotoand labels; - Go's distinction between
boolandint32requires spurious control flow and type conversions; - Go's untyped numeric literals require explicit type conversions;
- Go's constant evaluator does not match Wasm semantics, requiring workarounds to avoid constant folding/propagation;
- float operations require type conversions to avoid being combined;
- float literals can't represent negative zero, infinities, or
NaN; - Go forbids unused variables/labels/etc.
Many of these introduce unnecessary verbosity, but they're necessary for semantic correctness.
Judge the output by the assembly generated by the Go compiler, not by how a human would read it.
For some CPUs, you can generate faster code by using unsafe.
Despite the scary name, the generated code abides by the
rules of unsafe,
and all memory accesses are bounds checked.
Another knob is whether to attempt to ensure float operations
canonicalize NaNs.
This is tested to work on both amd64 and arm64,
but is known to be broken on most other architectures.
Usage: wasm2go [options] [input.wasm]
-embed
go:embed data sections from a .dat file
-nanbox
whether to try to canonicalize NaNs
-nohost
disable generating interfaces for imports
-noopt
disable all optimization passes
-o string
output file (default stdout)
-unsafe
allow importing unsafe
If you suspect wasm2go is producing invalid code,
please try noopt before submitting a bug report.