私は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をポップし、外側のブロックを満たすために1つ残っていることを意味します。 (i32.const 0)
がネストされたブロックに落ちると思いました。 どの部分が欠けていますか? 前もって感謝します。
はい、wabtのエラー報告はここで改善できます。 スタックに2つのi32
がある場合でも、演算子がブロックの先頭を超えてポップすることはないため、事実上1つしかありません。
これは、各ブロックが独自のスタックを取得することを意味しますか? セマンティクスドキュメントの次のステートメントに混乱しました。
ブロックまたはループ命令を実行しても、値スタックには影響しません。
多分それは次のように変わるはずです:
ブロックまたはループ命令を実行しても値スタックには影響しませんが、実行ブロック外のすべてのスタック値にアクセスできません。
それとも私は誤解していますか?
これは、各ブロックが独自のスタックを取得することを意味しますか?
私は彼らが彼ら自身のスタックを手に入れるとは言いません、ただポップできるものに制限があるというだけです。 これが実際にwabtに実装されている方法であり、値スタックと「ラベル」スタックがあります。 各ラベルには、ラベルがプッシュされたときの値スタックのサイズである「制限」が格納されます。 次に、ポップするたびに、トップラベルの制限を確認します。
ブロックまたはループ命令を実行しても、値スタックには影響しません。
多分それは次のように変わるはずです:
ブロックまたはループ命令を実行しても値スタックには影響しませんが、ブロック実行ブロックの外側にあるすべてのスタック値にアクセスできません。
それとも私は誤解していますか?
はい、Semantics.mdでそのようなことを言及する価値があるでしょう。 正式な散文仕様についても作業が行われていることは言うまでもありません。
>>
これは、各ブロックが独自のスタックを取得することを意味しますか?
私は彼らが彼ら自身のスタックを手に入れるとは言いません、ただ限界があるというだけです
ポップできるものに。 それが実際にwabtで実装されている方法です
は値スタックと「ラベル」スタックです。 各ラベルには「制限」が格納されています。
ラベルがプッシュされたときの値スタックのサイズ。 その後、いつでも
ポップ、トップラベルの制限をチェックします。
どちらも有効なビューです。 意味的には、「ブロックローカルスタック」ビューには
追加の不変条件を必要としないという利点。 「シングルスタック」付き
すべての制限など、追加の正確性の仮定が必要です
ラベルスタックで発生するのは、現在のオペランドスタックの範囲内である必要があります
高さ、それらは(必ずしも厳密ではない)昇順で発生する必要があり、
ラベルスタックは決して空であってはなりません。
情報をありがとう。 これから来る実用的なものはなく、これを詳しく説明するためのより正式な仕様が出てきているので、これを閉じます。
最も参考になるコメント
>>
どちらも有効なビューです。 意味的には、「ブロックローカルスタック」ビューには
追加の不変条件を必要としないという利点。 「シングルスタック」付き
すべての制限など、追加の正確性の仮定が必要です
ラベルスタックで発生するのは、現在のオペランドスタックの範囲内である必要があります
高さ、それらは(必ずしも厳密ではない)昇順で発生する必要があり、
ラベルスタックは決して空であってはなりません。