上面这段代码疏忽了错误处理机制,介绍了如何在 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中导出函数。所以这个问题只能通过特定编译器的非标准扩大来解决。也就是说,找到这个非标准扩大是解决问题最要害的一步。