X

曜彤.手记

随记,关于互联网技术、产品与创业

WebAssembly - Multi-value Extension

今天来看的提案是 - “Multi-value Extension”,GitHub 链接在这里。该提案对 MVP 中原有的函数类型,以及 blockloopif 三种块结构的能力进行了扩展,使它们可以接收多个输入参数,或产生多个结果值。这增加了指令的灵活性,使其拥有更贴近高级语言特性的指令执行流。来看下面这个例子:

(module
  (func (export "accumulate") (param $param i32) (result i32 i32)
    (local $var i32)
    (local.set $var (local.get $param))

    ;; Stack slot for storing accumulation result.
    (i32.const 0)  
    (loop $loop (param i32) (result i32)
      ;; Plus the i32 on the stack with the value of $var.
      (i32.add (local.get $var))  
      (local.tee $var (i32.sub (local.get $var) (i32.const 1)))
      (i32.gt_u (i32.const 0))
      br_if $loop
    )
    (local.get $param)
  )
)

这段 Wasm 代码中主要定义了名为 “accumulate” 的函数,该函数接收一个 i32 参数,并返回两个 i32 结果值。其中第一个结果值是由给定输入参数值经过阶加(也有人叫“阶和”)后得到的结果值(如输入参数 3,则计算 “3 + 2 + 1”,结果为 6);第二个参数值为原方不动的输入参数,这里我们直接返回。

函数的实现逻辑很简单,其中需要注意的不同点是函数的返回值类型 “(result i32 i32)”,以及函数体中循环结构 loop 的参数和返回值部分 “(param i32) (result i32)”,新的 “Multi-value Extension” 提案可以使我们像这样来使用函数和各类块结构。不同于函数参数,块结构的输入参数不作为 local 使用,而是直接通过栈来传递,因此代码第 9 行 “(i32.add (local.get $var))” 我们只为 i32.add 指令提供了一个操作数,另一个操作数则直接从栈上获取,该值也即为 loop 结构的输入参数。

WebAssembly.instantiate(wasmModule).then((instance) => { 
  const { accumulate } = instance.exports;
  console.log(accumulate(5));  // "[15, 5]".
}); 

模块的使用方式很简单,可以参考上述 JavaScript 代码。




评论 | Comments


Loading ...