嵌入 WebAssembly 运行时和实例化 WebAssembly 模块的几大要素

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了嵌入 WebAssembly 运行时和实例化 WebAssembly 模块的几大要素相关的知识,希望对你有一定的参考价值。

​​嵌入 WebAssembly 运行时和实例化 WebAssembly 模块的几大要素​​


下面这段代码忽略了错误处理机制,介绍了如何在 Go 语言开发的宿主程序中嵌入 WebAssembly.

func createWasmVM(code []byte) 
engine := wasmtime.NewEngine()
module, _ := wasmtime.NewModule(engine, code)
store := wasmtime.NewStore(engine)
linker := wasmtime.NewLinker(engine)
inst, _ := linker.Instantiate(store, module)
_ = inst

这段代码涉及到几个重要的 WebAssembly 的概念,简单介绍如下:

  • 引擎(Engine):用于编译和管理 wasm 模块的全局上下文。
  • 模块(Module):已编译的 WebAssembly 模块。 该结构表示实例化后准备执行的内存中 JIT 代码。
  • 存储(Store):所有 WebAssembly 对象和主机值都将“连接”到存储。
  • 实例(Instance):一个实例化的 WebAssembly 模块,您可以从中实际获取一个函数,例如调用。实例化时,调用模块的启动函数。
  • 链接器(仅限 Wasmtime):将 wasm 模块/实例链接在一起的辅助结构。

上面的代码虽然创建了一个 WebAssembly 模块的实例,但是根据 WebAssembly 规范,start 函数会被执行。 但由于安全限制,无法输出执行结果,所以即使执行了也没效果。 因此,我们需要实现宿主程序与 WebAssembly 程序的互操作,为WebAssembly 程序提供输入/输出接口。

假设我们的 WebAssembly 程序有一个名为 sum 的函数,它接收两个整数变量作为参数并返回它们的和,宿主程序可以使用下面的代码来调用这个函数:

fn := inst.GetExport(store, "sum").Func()
r, _ := fn.Call(store, 1, 2)
fmt.Println(r.(int32))

虽然具体的调用方式与宿主程序的编程语言和所使用的WebAssembly运行时不同,但是运行时的文档一般都有相关的说明,按照文档来做就好了。

这里的难点在于如何从 WebAssembly 程序中导出 sum 函数,以便宿主程序可以找到并调用它。 前面说了,只要有编译器,任何语言都可以编译成WebAssembly,但是大部分语言在设计时都没有考虑WebAssembly的需求,也没有办法在WebAssembly中导出函数。所以这个问题只能通过特定编译器的非标准扩展来解决。也就是说,找到这个非标准扩展是解决问题最关键的一步。




2023-01-23 22:00  ​​JerryWang_汪子熙​​ 

以上是关于嵌入 WebAssembly 运行时和实例化 WebAssembly 模块的几大要素的主要内容,如果未能解决你的问题,请参考以下文章

为 Blazor WebAssembly 中的所有 blazor 页面实例化一个对象?

在 Rust 程序和嵌入式 WebAssembly 运行时之间进行通信的最佳实践是啥?

WebAssembly运行时--Wasmtime

Lua没有足够快地实例化局部变量来打印它?嵌入式ESP8266

如何在 Go 语言开发的宿主程序中嵌入 WebAssembly

Hello WebAsm:第一个WebAssembly例子