Skip to content

ncruces/wasm2go

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

158 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

A Wasm to Go translator

To translate a Wasm module to Go, use the following command:

wasm2go < input.wasm > output.go

The input is a Wasm module, and the output is a single Go source file, with no dependencies beyond the standard library.

Overview

The generated 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 that 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.

Supported features

The current target is a useful subset of Wasm produced by clang, including the following features:

Generated code

Generating human-readable Go code is a non-goal:

  • Wasm names must be mangled into Go identifiers;
  • Wasm control flow is implemented with goto and labels;
  • Go's distinction between bool and int32 requires spurious if statements and type conversions;
  • Go's distinction between signed and unsigned integers requires frequent 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 still 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 CPU architectures.

Usage

Usage: wasm2go [option]... [input.wasm]
  -dwarfline
        use line numbers from DWARF metadata
  -embed
        go:embed data sections from a .dat file
  -nanbox
        attempt to canonicalize NaNs
  -nohost
        don't generate interfaces for imports
  -noopt
        disable all optimization passes
  -o string
        output file (default stdout)
  -pkg string
        package name (default module name, or wasm2go)
  -provided value
        file containing provided import functions
  -tags string
        go:build tags to include in the generated file
  -unsafe
        allow importing unsafe
  -version
        print version and exit

Bugs

If you suspect wasm2go is producing invalid code, please try noopt before submitting a bug report.

Users

Projects using code generated by wasm2go are listed in USERS.md.

Footnotes

  1. wasm2go does not guarantee tail behavior; judge for yourself if using tail calls generates better code.

About

A Wasm to Go translator

Topics

Resources

License

Stars

Watchers

Forks

Sponsor this project

Packages

 
 
 

Contributors