WebAssembly是一种基于堆栈的二进制类汇编语言,可以接近原生的性能运行,可以在Web浏览器上运行,并且C/C++、Rust、Golang、C#等语言可以直接编译为Wasm,大大提高了Web平台的扩展性。

wasi

Wasm的初始目标是为Web浏览器服务,但是随着Wasm的发展,一个新的标准出现了,WASI(WebAssembly System Interface),WASI将wasm带到了Web浏览器之外的地方,做到了真正的one build, run everything,不过目前还有很多局限性,例如IO、网络都有很大的限制,基本不能使用。

wazero 是一个WebAssembly的运行时实现,基于Pure Golang实现,可以无缝的交叉编译到各个平台,由于Wasi的标准的缺失,目前只可以运行一些非网络IO的代码,内置的运行时对网络请求支持有限,几乎不可用,不过wazero支持HostFunc 映射到wasm里,对于网络请求,可以通过HostFunc映射到wasm外运行,这对于自已目前需要 的插件系统提供了可能性。

目前Golang刚发布了Go 1.24,对Wasi提供了进一步的支持,目前可以通过//go:wasmexport exportname来导出wasm func,并且支持了wasip1作为build参数,例如GOOS=wasip1 GOARCH=wasm -buildmode=c-shared,可以将某个函数导出后进行调用,由于wasm是单线程架构,如果在一个goroutinue执行了阻塞的代码,那么其余的goroutinue将不会再继续运行,类似非抢占式调度,必须由goroutinue主动去释放后其他goroutinue才能继续运行。 支持了更多的参数,如下

Go types        Wasm types
bool            i32
int32, uint32   i32
int64, uint64   i64
float32         f32
float64         f64
unsafe.Pointer  i32
pointer         i32 (more restrictions below)
string          (i32, i32) (only permitted as a parameters, not a result)

wazero_net

wazero_net 为wazero提供了网络的支持,Conn.Read 时,由于wasm的单线程架构,read阻塞后将导致其他goutinue的write操作将会卡住,不会在被调度,因为在read时,需要设置对应的deadline timeout,调用runtime.GoSched将运行权调度到其他goroutinue