首页 > 其他分享 >WASI support in Go

WASI support in Go

时间:2023-09-15 20:48:05浏览次数:44  
标签:support WASI go wasip1 Wasm Go wasm

原文在这里

由 Johan Brandhorst-Satzkorn, Julien Fabre, Damian Gryski, Evan Phoenix, and Achille Roussel 发布于 2023年9月13日

Go 1.21添加了一个新的端口,通过新的GOOS值wasip1来定位WASI预览1系统调用API。该端口建立在Go 1.11引入的现有WebAssembly端口的基础上。

WebAssembly 是什么

WebAssembly(Wasm)是一种最初设计用于Web的二进制指令格式。它代表了一个标准,允许开发人员在Web浏览器中以接近本机速度直接运行高性能、低级别的代码。

Go首次在1.11版本中添加了对编译成Wasm的支持,通过js/wasm端口实现。这允许使用Go编译器编译的Go代码在Web浏览器中执行,但需要一个JavaScript执行环境。

随着Wasm的使用增加,除了在浏览器之外的用例也增多。许多云提供商现在提供服务,允许用户直接执行Wasm可执行文件,利用新的WebAssembly系统接口(WASI)系统调用API。

WebAssembly 系统接口

WASI定义了一个用于Wasm可执行文件的系统调用API,允许它们与系统资源进行交互,如文件系统、系统时钟、随机数据工具等等。WASI规范的最新版本被称为wasi_snapshot_preview1,从中我们派生出了GOOS名称wasip1。新版本的API正在开发中,未来在Go编译器中支持它们可能意味着添加一个新的GOOS。

WASI的创建使得许多Wasm运行时(宿主)能够围绕其标准化它们的系统调用API。一些Wasm/WASI宿主的示例包括WasmtimeWazeroWasmEdgeWasmerNodeJS。还有许多云提供商提供Wasm/WASI可执行文件的托管服务。

Go 中如何使用 WebAssembly

请确保已安装至少1.21版本的Go。对于此演示,我们将使用Wasmtime主机来执行我们的二进制文件。让我们从一个简单的 main.go 开始:

package main

import "fmt"

func main() {
    fmt.Println("Hello world!")
}

使用如下命令进行编译:

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

这将会生成一个名为 main.wasm 的文件,我们可以使用 wasmtime 执行:

$ wasmtime main.wasm
Hello world!

这就是开始使用Wasm/WASI所需的全部!几乎所有Go的功能都可以在 wasip1 上正常工作。要了解有关WASI如何与Go一起工作的详细信息,请参阅提案

测试 wasip1

构建和运行二进制文件很容易,但有时我们希望能够直接运行 go test,而无需手动构建和执行二进制文件。与 js/wasm 端口类似,Go安装中包含的标准库分发版本附带一个文件,使这个过程变得非常简单。在运行Go测试时,将 misc/wasm 目录添加到 PATH 中,它将使用你选择的Wasm主机来运行测试。这是通过 go test 在PATH中找到此文件时自动执行 misc/wasm/go_wasip1_wasm_exec 来实现的:

$ export PATH=$PATH:$(go env GOROOT)/misc/wasm
$ GOOS=wasip1 GOARCH=wasm go test ./...

这将使用 Wasmtime 运行 go test。可以使用环境变量 GOWASIRUNTIME 来控制所使用的Wasm主机。目前支持的变量值包括 wazerowasmedgewasmtimewasmer。请注意,Go wasip1 二进制文件在所有主机上尚不能完美执行(参见#59907#60097)。

也可以使用 go run来执行上面的程序:

$ GOOS=wasip1 GOARCH=wasm go run ./main.go
Hello world!

使用go:wasmimport在Go中包装Wasm函数

除了新的 wasip1/wasm 端口外,Go 1.21还引入了一个新的编译器指令:go:wasmimport。它指示编译器将对带有注释的函数的调用转换为对由主机模块名称和函数名称指定的函数的调用。这个新的编译器功能允许我们在Go中定义wasip1系统调用API,以支持新的端口,但它不限于在标准库中使用。

例如,wasip1系统调用API定义了 random_get 函数,并通过runtime包中定义的函数包装器暴露给Go标准库。它看起来像这样:

//go:wasmimport wasi_snapshot_preview1 random_get
//go:noescape
func random_get(buf unsafe.Pointer, bufLen size) errno

然后,将这个函数包装器包装在标准库中供使用的更人性化的函数中:

func getRandomData(r []byte) {
    if random_get(unsafe.Pointer(&r[0]), size(len(r))) != 0 {
        throw("random_get failed")
    }
}

这样,用户可以使用字节切片调用 getRandomData ,并最终将其传递给主机定义的 random_get 函数。同样,用户可以为主机函数定义自己的包装器。

要了解如何在Go中包装Wasm函数的复杂性的更多细节,请参阅go:wasmimport提案

局限性

虽然wasip1端口通过了所有标准库测试,但Wasm架构有一些显着的基本限制,可能会让用户感到惊讶。

Wasm是一个没有并行性的单线程架构。调度器仍然可以调度goroutine以并发运行,标准输入/输出/错误是非阻塞的,因此一个goroutine可以在另一个读取或写入时执行,但是任何主机函数调用(例如使用上面的示例请求随机数据)都会导致所有goroutine阻塞,直到主机函数调用返回。

wasip1 API中一个显着缺失的功能是完整的网络套接字实现。wasip1只定义了对已经打开的套接字进行操作的函数,这使得无法支持Go标准库的一些最流行的功能,如HTTP服务器。像Wasmer和WasmEdge这样的主机实现了wasip1 API的扩展,允许打开网络套接字。尽管Go编译器没有实现这些扩展,但存在第三方库,github.com/stealthrocket/net,使用go:wasmimport允许在支持的Wasm主机上使用net.Dial和net.Listen。这允许在使用此包时创建net/http服务器和其他与网络相关的功能。

Go中的Wasm的未来

wasip1/wasm 端口的添加只是我们希望引入Go的Wasm功能的开端。请密切关注问题跟踪器,了解有关将Go函数导出到Wasm(go:wasmexport)、32位端口和未来WASI API兼容性的提案。

参与其中

如果你正在尝试并希望为Wasm和Go做出贡献,请参与其中!Go问题跟踪器跟踪所有正在进行的工作,Gophers Slack上的 #webassembly 频道是讨论Go和WebAssembly的好地方。我们期待听到你的声音!


孟斯特

声明:本作品采用署名-非商业性使用-相同方式共享 4.0 国际 (CC BY-NC-SA 4.0)进行许可,使用时请注明出处。
Author: mengbin
blog: mengbin
Github: mengbin92
cnblogs: 恋水无意


标签:support,WASI,go,wasip1,Wasm,Go,wasm
From: https://www.cnblogs.com/lianshuiwuyi/p/17705889.html

相关文章

  • 测试行业面临的问题及RunnerGo在工具层面如何解决的
    RunnerGo致力于打造成一款企业级全栈测试平台,旨在实现产品生命周期的闭环管理,帮助企业在整个产品生命周期中确保质量、降低风险,并提供卓越的用户体验。采用了较为宽松的Apache-2.0license开源协议,方便志同道合的朋友一起为开源贡献力量。 目前测试行业所面临的问题场景共享......
  • MongoDB 语法大全
    文章目录前言MongoDB语法大全01、mongodb数据库链接02、help查看命令提示03、如果数据库存在,则切换到指定的数据库;如果数据库不存在,则创建数据库04、查询所有的数据库05、查看当前数据库05::01查看当前数据库状态05::02查看当前数据库版本05::03查看当前数据库链接机器06、插......
  • go包依赖管理-构建完整的依赖项目:目录结构及包的调用
    目录结构:<home>/|--greetings/|--hello/1.分别进入对应目录创建以上目录结构//bash切换到用户主目录 cd$HOMEPAHT$ //bash新建greetings目录并进入该目录mkdirgreetingscdgreetings//bash创建模组example.com/greetings$gomodinitexample.com/greetingsgo:......
  • django—实现前端页面批量删除功能
    views.py代码:fromdjango.shortcutsimportrender,redirectfrom.modelsimportYourModel#使用你实际的模型名称替换defbatch_delete(request):ifrequest.method=='POST':ids=request.POST.get('ids')ifids:......
  • Technical support website(URL)
    Thissoftwarerespectsandprotectsthepersonalprivacyofallusersusingtheservice.Inordertoprovideyouwithmoreaccurateandpersonalizedservices,thissoftwarewilluseanddiscloseyourpersonalinformationinaccordancewiththeprovisions......
  • Nodejs+Express+MongoDB实战
    项目安装安装express脚手架:npminstallexpress-generator-g创建项目:express-eproject-e代表使用ejs模板,project是项目名称进入项目:npminstall下载依赖包安装nodemon:npminstallnodemon-g使用nodemon来启动项目,不用node来启动启动项目:npmstart,端口号在www启动文件中可以......
  • nodejs+koa2+mongodb 从0到1搭建自己的项目
    nodejs+koa2+mongodb从0到1搭建自己的项目YDJFE2018-09-2811:2419207   相信这对于想要入门写nodejs的朋友来说,一定会有所收获,那么,下面开始我们的正题(这里不使用koa-generator脚手架,我们直接自己搭建项目,适用于前后端分离)一:创建项目可以在全局中安装koa依赖包......
  • golang工具值generate
     示例:大家经常碰到命名错误码、状态码的同时,又要同步写码对应的翻译,有没有感觉很无聊。这里举一个例子:packagemain​import"fmt"​//定义错误码const(ERR_CODE_OK=0//OKERR_CODE_INVALID_PARAMS=1//无效参数ERR_CODE_TIMEOUT......
  • ERROR OGG-01224 Oracle GoldenGate Capture for Oracle, p_lion.prm: Address al
    我的ogg版本OracleGoldenGateCommandInterpreterforOracleVersion12.3.0.1.4OGGCORE_12.3.0.1.0_PLATFORMS_180415.0359_FBOLinux,x64,64bit(optimized),Oracle11gonApr15201821:16:09OperatingsystemcharactersetidentifiedasUTF-8.报错信息2023......
  • gopup:Python公开数据仓库
    GoPUP支持Python3.7+,旨在使获取数据尽可能方便,主要用于学术研究目的。GoPUP项目所采集的数据皆来自公开的数据源,不涉及任何个人隐私数据和非公开数据。同时本项目提供的数据接口及相关数据仅用于学术研究,任何个人、机构及团体使用本项目的数据接口及相关数据请注意商业风险。......