为什么 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
)
)
你不能这样做,因为函数末尾的堆栈上的项必须与函数的返回类型匹配,无论实际上是否有可能到达函数体的末尾。
这是标准的相关部分。它指定每个有效函数都有一个带有单个表达式的函数体。在这种情况下,表达式是函数体中的指令序列。为了使函数有效,表达式的类型必须与函数的返回类型相同。在第一个示例中,情况并非如此,因为表达式的类型为 [],而函数的返回类型为 [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
)
)