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

问题描述 投票:1回答:1

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

以下代码段(摘自WebAssembly loop test cases)显示了一个嵌套循环,该循环有望返回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规范中有关循环如何运行的内容?还是编译器暗中进行了可达性分析?

webassembly
1个回答
0
投票

您正在观察的是无条件分支之后的stack becoming polymorphic。这意味着堆栈的行为就像具有验证所需的值一样。

在这种情况下,br $L0指令使堆栈多态。通常,从栈顶loop $L1掉落会在堆栈上需要i32,但是由于堆栈是多态的,因此类型检查器的行为就像是真的。

您可能会发现validation algorithm in the spec有用。我还写了关于WebAssembly type-checking a while back的文章,这可能对您有帮助。

© www.soinside.com 2019 - 2024. All rights reserved.