Announcing the fastest WebAssembly runtime for Go: wasmer

Ivan Enderlin
May 29 · 5 min read
Go loves WebAssembly — image attributions to the original Gopher drawing.

To uphold this bold statement, each language, platform and system must be able to run WebAssembly — as fast and safely as possible.

Wasmer is a WebAssembly runtime written in Rust. It goes without saying that the runtime can be used in any Rust application. We have also successfully embedded the runtime in other languages:

Calling a WebAssembly function from Go

First, let’s install wasmer in your go environment (with cgo support).

export CGO_ENABLED=1; export CC=gcc; go install github.com/wasmerio/go-ext-wasm/wasmer
simple.rs, a small Rust program that compiles to WebAssembly.
simple.go, a small Go program that executes the WebAssembly file (result of the compilation of the Rust program).

WebAssembly calling Go funtions

A WebAssembly module exports some functions, so that they can be called from the outside world. This is the entry point to execute WebAssembly.

import.rs, the sum function implementation is in another language. Download the WebAssembly file here
  1. The sum implementation is defined in Go. Notice the //export which is the way cgo uses to map Go code to C code,
  2. NewImports is an API used to create WebAssembly imports. In this code "sum" is the WebAssembly imported function name, sum is the Go function pointer, and C.sum is the cgo function pointer,
  3. Finally, NewInstanceWithImports is the constructor to use to instantiate the WebAssembly module with imports. That’s it.
import.go, the sum implementation is written in Go.

Reading the memory

A WebAssembly instance has a linear memory. Let’s see how to read it. Consider the following Rust program:

memory.rs, a small Rust function that returns a pointer to a string.
memory.go, a Go program that reads a string based on a pointer returned by WebAssembly.

Benchmarks

So far, github.com/wasmerio/go-ext-wasm/wasmer has a nice API, but …is it fast?

  • Wagon, from Go Interpreter, a WebAssembly interpreter and toolkit.
Speed comparison between Wasmer, Wagon and Life. Benchmark suites are the n-body, Fibonacci, and Pollard’s rho algorithms. Speed is expressed in ms. Lower is better.

Conclusion

github.com/wasmerio/go-ext-wasm/wasmer is a new Go library to execute WebAssembly binaries. It embeds the Wasmer runtime. The first version supports all the required API for the most common usages.

Wasmer

Universal WebAssembly runtime

Ivan Enderlin

Written by

PhD Computer Scientist/Hacker. @mnt_io on Twitter, @hywan@fosstodon.org, https://mnt.io/

Wasmer

Wasmer

Universal WebAssembly runtime