Wasm Runtime的创作: Build Wasm Runtime

因为NGIN的contract系统也就是智能合约上需要嵌入的wasm engine支持fee cost on opcode(instr),因此需要从wasmtime迁移到其他引擎。

虽然说找到了life完全符合我们的需要,但毕竟是人家的项目而且在host func嵌入的方面不如wasmtime顺手。

既然是从头做起(from scratch)的项目,那么再多做个wasm runtime应该也不过分。

Compilation/Execution modes

awesome-wasm-runtimes的项目介绍里可以看到life的编译/执行模式是Interpreted,而wasmtime是JIT。

其实还有个叫AOT的,像Lucet这个引擎就是用的AOT。

Interpreted顾名思义就是被“解释”,就类似脚本语言那样一句一句地输入并执行。换句话说就是引擎会读取源码或IR(介于高级语言和二进制机器码之间的中间表达,比如bytecode,wasm binary可以认为是IR)并立即把这些语句执行掉。

JIT一边读取源代码或IR,一边对已读取内容飞速编译再执行,即在执行时编译。可以认为是JIT是对内容与当前执行环境做了优化之后再进行执行。

AOT则接近gcc这种编译器。AOT在程序执行之前进行完整编译。

所以很明显JIT引擎在优化后很容易比Interpreted快很多,wagon和wasmtime,wasmer的速度根本没法比(虽然也有语言速度上差距)。但是从wasmtime的issue记录来看负优化也不是没有。

因此从当前目标来看其实我们只需要先完成一个解释器,然后再通过编写compiler去对内容再做优化(JIT)。

基本内容

这里我们选择的是w3c的wasm标准,也就是version1。

其中的Values,Modules等内容在别的wasm内容中也提过了所以不多说。

最为关键的在于如何将一个Module给实例化为Instance且通过Call一个mainFunc的方式跑起来。

Compile/Interpret

本质上就是需要将wasm解释为机械码然后跑起来。

在将module实力化之前,我们需要对module中内容进行解析,构建出一个索引空间,用来快速访问我们需要的内容(其实也就function,global,table,memory)。这个内容也可能是外部module提供的,因此也需要提供externModules。