来源:脑子进煎鱼了 最近因为各种奇怪的分钟原因,更多的搞明接触到了 WebAssembly。虽然之前很多博客也翻过写过各种文章,白快但总感觉欠些味道。速掌于是分钟今天梳理了一版,和大家一起展开学习。搞明 先来一张经典图: 以下是 Mozilla 在 MDN 上给出的定义: WebAssembly(缩写:Wasm)是一种新的编码方式,可以在现代的速掌网络浏览器中运行 - 它是一种低级的类汇编语言,具有紧凑的分钟二进制格式,可以接近原生的搞明性能运行,并为诸如 C/C++ 等语言提供一个编译目标,白快以便它们可以在 Web 上运行。速掌它也被设计为可以与 JavaScript 共存,分钟允许两者一起工作。搞明 Wasm 官网自己挑出的白快重点是: 新编码方式,可以在浏览器中运行。可以以接近原生的性能运行。可以跨语言,例如:C/C++;可以与 JavaScript 共存。 看着是一个不错的可跨平台运行的新玩具。 最早 WebAssembly1.0 基于 asm.js(Javascript 的严格子集,静态类型,取消垃圾回收机制等)的特性集实现。随后的 WebAssembly2.0 又根据新的标准进行了进一步的延伸和开发。 WebAssembly 的开发团队分别来自 Mozilla、Google、Microsoft、Apple,代表着四大网络浏览器 Firefox、Chrome、Microsoft Edge、Safari。 一些重要的时间线: 几家大厂派人一起做的,比较新,近几年才开始更多的被支持。当前还在 WebAssembly 2.0 的阶段,还在发展阶段。 直观上来看,1.0 和 2.0 最大的区别在于: WebAssembly 2.0 起,边界更大了,目标完全就是可移植、安全的高级语言。期望应用于浏览器、各编程语言、各系统中。 大有一个 JVM 的感觉: 在我们快速了解了 WebAssembly 的背景后。我们落到实处,看看 Go 语言的 WebAssembly 情况如何,又是如何使用。 Go 目前有两种使用 WebAssembly 的方式,第一种是使用 syscall/js 标准库,四舍五入算勉强支持了 WebAssembly 1.0。 代码如下: main { ) ) } 编译命令: build -o jianyu.wasm 再使用 JS 中对应 WebAssembly 的调用就可以了。 第二种使用方式,是使用开源库 tinygo-org/tinygo[1],其基于 LLM,支持了 WebAssembly1.0/2.0 (WASM/WASI)。 tinygo brew 安装方式: $ brew tap tinygo-org/tools $ brew install tinygo 如果安装成功,执行 tinygo version 就可以看到版本信息。 Go wasm 代码如下: import ( ) HelloWorld () { ) myFigure.Print() } () { } 编译命令: tinygo build -o module.wasm -target wasi . 运行成功后,将会在对应目录编译出 module.wasm 二进制文件,可以由其他的平台、语言进行使用。 如果你希望在 Go 或其他语言中调用所生成的 .wasm,需要找到对应符合 WASI 的库和规则。 下面是 Go wasmer-go 调用 .wasm 的代码: ( ) { ) store := wasmer.NewStore(wasmer.NewEngine()) module, _ := wasmer.NewModule(store, wasmBytes) ). Finalize() importObject, err := wasiEnv.GenerateImportObject(store, module) check(err) instance, err := wasmer.NewInstance(module, importObject) check(err) start, err := instance.Exports.GetWasiStartFunction() check(err) start() ) check(err) result, _ := HelloWorld() fmt.Println(result) } { { (e) } } 运行成功后会输出 “Hello World”。 Go 标准库 syscall/js 标准库只支持 WebAssembly1.0,只能应用于 JS 相关的场景,并不能被其他语言所集成。 其中 tinygo 实现了 WASI,借助 WASI 这一标准接口与其他平台语言互相集成。但 tinygo 并没有支持所有的 Go 语法特性,具体可以查看 Go language features[2]。 这块需要特别注意,不同语言对 WebAssembly(WASI)的支持程度均不一样。 带火 WebAssembly 的还有一个重要的因素,那就是在各种云原生的组件上都可以集成和使用,进一步延伸了场景。 例如在 Envoy 和 Istio 上,可以使用 wasm 很方便的将自定义 filter 集成到 Envoy 中,实现 Envoy 代理的功能增强。 今天我们快速的对 WebAssembly 进行了背景了解、Go 快速上手、扩展场景了解等。虽然 WebAssembly 是一个新轮子,也号称可以借助 WASI 集成和被集成。 但实际上现在各语言对 WebAssembly 的支持程度都不一样,像 Go 官方自己提供的标准库就维护的不怎么样,WASI 的 issues 也没有继续推进。 甚至在其他语言的互通,现在仍然有着或多或少会导致阻塞无法应用的问题。可能,还需要再过个 3~5 年? 但如此多语言的库维护,能否长久的迭代和维护。也是一个更大的问题。 tinygo-org/tinygo: https://github.com/tinygo-org/tinygo Go language features: https://tinygo.org/docs/reference/lang-support/WebAssembly 是什么
由哪家研发
1.0 和 2.0 区别之一
Go 快速上手
其他应用场景
总结
参考资料
[1]