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 的支持不完全导致的。