WebAssembly 期望使用 if else 无法访问代码

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

为什么 WebAssembly 不明白,当有一个

if
和一个
else
时,并且它们都返回时,就无法通过该
if
/
else
语句?

考虑以下几点。不可能通过

if
/
else
,但 wat2wasm 仍然抱怨并非所有路径都会返回
i32

(module
  (func (result i32)
    i32.const 0
    i32.const 1
    i32.gt_s
    (if
      (then
        i32.const 50
        return
      )
      (else
        i32.const 100
        return
      )
    )
  )
)

我收到的错误是:

6:5: error: type mismatch in implicit return, expected [i32] but got []
    (if

解决这个问题的唯一方法是在 if/else 之后添加显式返回,即使无法访问:


(module
  (func (result i32)
    i32.const 0
    i32.const 1
    i32.gt_s
    (if
      (then
        i32.const 50
        return
      )
      (else
        i32.const 100
        return
      )
    )
    i32.const 100
    return 
  )
)
webassembly
1个回答
0
投票

你不能这样做,因为函数末尾的堆栈上的项必须与函数的返回类型匹配,无论实际上是否有可能到达函数体的末尾。

这是标准的相关部分。它指定每个有效函数都有一个带有单个表达式的函数体。在这种情况下,表达式是函数体中的指令序列。为了使函数有效,表达式的类型必须与函数的返回类型相同。在第一个示例中,情况并非如此,因为表达式的类型为 [],而函数的返回类型为 [i32]。验证器最终并不关心是否有可能到达两个返回分支之后的代码,它只是看到类型不匹配并抛出错误。

解决此问题的更规范方法可能是使用

unreachable
指令而不是返回虚拟值:

(module
  (func (result i32)
    i32.const 0
    i32.const 1
    i32.gt_s
    (if
      (then
        i32.const 50
        return
      )
      (else
        i32.const 100
        return
      )
    )
    unreachable
  )
)
© www.soinside.com 2019 - 2024. All rights reserved.