繁体   English   中英

WebAssembly:编译返回值不符合预期的循环

[英]WebAssembly: compilation of loops with return values not behaving as expected

我正在编写一个 WebAssembly 字节码分析器,并且遇到了一些关于各种 WebAssembly 编译器如何处理循环指令的行为,我发现这些指令很难与 WebAssembly 规范相协调。

以下代码段(取自WebAssembly 循环测试用例)显示了一个嵌套循环,该循环预计将返回一个 i32 整数。

(module
  (type $t0 (func (result i32)))
  (func $cont-inner (export "cont-inner") (type $t0) (result i32)
    (local $l0 i32)
    i32.const 0
    local.set $l0
    local.get $l0
    loop $L0 (result i32)
      loop $L1 (result i32)
        br $L0
      end
    end
    i32.add
    local.set $l0

对上述内容的直观分析表明,此语法并不严格符合规范(据我所知),因为循环体没有任何要返回的堆栈值。

当然,上述循环形成了一个无限循环,因此在执行时程序实际上不会退出最外层循环。

但是我试过的几个编译器编译这个没有任何问题,例如 webassembly.studio。 相反,如果无条件分支被条件分支替换,那么编译器实际上会按照我的预期运行并抱怨缺少返回值。

我是否遗漏了 WebAssembly 规范中关于循环如何运行的内容? 或者编译器是否隐式地进行了一些可达性分析?

您观察到的是堆栈在无条件分支之后变成多态的。 这意味着堆栈的行为就像它具有验证所需的值一样。

在这种情况下, br $L0指令使堆栈多态。 通常脱离结束loop $L1将需要堆栈上的i32 ,但由于堆栈是多态的,类型检查器的行为就好像这是真的。

您可能会发现规范中验证算法很有用。 不久前我还写了关于WebAssembly 类型检查的文章,这可能对您有用。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM