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