WebAssembly是一种新的编码方式,可以在现代的网络浏览器中运行 - 它是一种低级的类汇编语言,具有紧凑的二进制格式,可以接近原生的性能运行,并为诸如C / C ++等语言提供一个编译目标,以便它们可以在Web上运行。它也被设计为可以与JavaScript共存,允许两者一起工作。

Go从1.11版本就开始支持将Go源码编译为wasm二进制文件,并在支持wasm的浏览器环境中运行。

不过WebAssembly绝不仅仅被设计为仅限于在Web浏览器中运行,核心的WebAssembly语言是独立于其周围环境的,WebAssembly完全可以通过API与外部世界互动。在Web上,它自然使用浏览器提供的现有Web API。然而,在浏览器之外,之前还没有一套标准的API可以让WebAssembly程序使用。这使得创建真正可移植的非Web WebAssembly程序变得困难。WebAssembly System Interface(WASI)是一个填补这一空白的倡议,它有一套干净的API,可以由多个引擎在多个平台上实现,并且不依赖于浏览器的功能(尽管它们仍然可以在浏览器中运行)。

Go 1.21将增加对WASI的支持,初期先支持WASI Preview1版本,之后会支持WASI Preview2版本,直至最终WASI API版本发布!

go 编译支持 wasi 的程序

怎么样才能编译支持 wasi 的程序呢? 我们可以使用GOOS=wasip1 GOARCH=wasm将Go源码编译为支持WASI的wasm程序。下面是一个例子:

我们先编写一个简单的 go 程序:

1
2
3
4
5
6
7
8
package main

import "fmt"

func main() {

	fmt.Println("Hello, World!")
}

使用以下命令编译:

GOARCH=wasm GOOS=wasip1 gotip build -o main.wasm main.go

编译后会得到 wasm 程序 main.wasm。

我们可以使用 wazero 运行编译后的 wasm 程序:

1
2
3
$ curl https://wazero.io/install.sh
$ wazero run main.wasm
hello

其它

wasi 接口的支持是近期才添加的功能,我还尝试了一些其它的 go 程序,发现只有部分程序能够顺利运行,猜测是对 wasi 的支持不完全导致的。

参考