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 程序:

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 程序:

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

其它

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

参考