首页 > 其他分享 >嵌入 WebAssembly 运行时和实例化 WebAssembly 模块的几大要素

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

时间:2023-01-28 10:36:53浏览次数:57  
标签:WebAssembly 嵌入 函数 wasmtime 程序 实例 模块

​​嵌入 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,嵌入,函数,wasmtime,程序,实例,模块
From: https://blog.51cto.com/jerrywangsap/6024731

相关文章