我正在玩弄写一个 WebAssembly 编译器。 我正在查看测试https://github.com/WebAssembly/spec/blob/634f0d9009404f498ef8d8bd510bd6f0941219cc/test/core/br_if.wast#L272看起来像这样扩展了一点:
(module
(func
$type-arg-void-vs-num-nested
(result i32)
block i32
(i32.const 0)
block
(i32.const 1)
(br_if 1)
end
end
)
)
我得到的错误是:
Error: check failed:
test.wast:10:12
type stack size too small at br_if value. got 0, expected at least 1
(br_if 1)
^^^^^^^
我认为当它达到br_if
时的堆栈大小是 2,这意味着它为条件弹出 1,然后剩下一个来满足外部块。 我认为(i32.const 0)
会落入嵌套块。 我缺少哪个部分? 提前致谢。
是的,wabt 的错误报告可以在这里改进。 即使堆栈上有两个i32
,操作符也永远不会弹出块的开头,因此实际上只有一个。
这是否意味着每个块都有自己的堆栈? 我对语义文档中的以下语句感到困惑:
执行块或循环指令对值堆栈没有影响。
也许应该改为:
执行块或循环指令对值堆栈没有影响,但执行块之外的所有堆栈值都是不可访问的。
还是我误会了?
这是否意味着每个块都有自己的堆栈?
我不会说他们有自己的堆栈,只是可以弹出的内容是有限的。 这实际上是它在 wabt 中的实现方式,有一个值堆栈和一个“标签”堆栈。 每个标签存储一个“限制”,它是推送标签时值堆栈的大小。 然后,无论何时弹出,您都会检查顶部标签的限制。
执行块或循环指令对值堆栈没有影响。
也许应该改为:
执行块或循环指令对值堆栈没有影响,但块执行块之外的所有堆栈值都是不可访问的。
还是我误会了?
是的,在 Semantics.md 中可能值得一提。 虽然我应该提到,也有关于正式散文规范的工作。
>
这是否意味着每个块都有自己的堆栈?
我不会说他们有自己的筹码,只是有一个限制
什么可以弹出。 这实际上是它在 wabt 中的实现方式,有
是一个值堆栈和一个“标签”堆栈。 每个标签存储一个“限制”,它是
压入标签时值堆栈的大小。 那么每当你
弹出,您检查顶部标签的限制。
两者都是有效的观点。 从语义上讲,“块本地堆栈”视图具有
优点是它不需要额外的不变量。 使用“单栈”
额外的正确性假设是必要的,例如所有限制
出现在标签堆栈中必须在当前操作数堆栈的边界内
高度,它们必须以(不一定严格)递增的顺序出现,并且
标签栈不能为空。
谢谢(你的)信息。 我正在关闭它,因为它没有任何可操作的东西,并且正在出现更正式的规范来说明这一点。
最有用的评论
>
两者都是有效的观点。 从语义上讲,“块本地堆栈”视图具有
优点是它不需要额外的不变量。 使用“单栈”
额外的正确性假设是必要的,例如所有限制
出现在标签堆栈中必须在当前操作数堆栈的边界内
高度,它们必须以(不一定严格)递增的顺序出现,并且
标签栈不能为空。