Open3

読者コミュニティ|RustでWasm Runtimeを実装する

ktz_aliasktz_alias

丁寧な記述と、それでいてハッとさせられるテクニックが散りばめられた書籍の提供に感謝します。

ところで、番外編について2、3質問があります。

一つ目

記載されたフィボナッチ数のWATをそのまま使ってテストしたところ、ifの後にthenがない的なエラーが発生しました。

mdnで構文を確認したところ、

(if (then ...))

と書かれており、フィボナッチ数の計算で使用している構文とは異なっていました。

https://developer.mozilla.org/en-US/docs/WebAssembly/Reference/Control_flow/if...else

ndmの内容に従って訂正したところ、エラーなく計算を終わらせることができました。
番外編のWATソースは、なにか古い時代の構文なのでしょうか?

2つ目

「if/returnの実装」の節において、

なのでend命令を処理する際にif/block/loopなのか、関数の終わりなのかを判定する必要がある。
判定方法はシンプルで、if/block/loopのときはラベルが積まれるので、ラベルが空の場合は関数の終わりというふうに判定できる。

と本文に書かれていますが、returnに対して判定処理をしており、endは特に変えていないように見えます。
WASMの公式サイトを確認すると

The instruction is a shortcut for an unconditional branch to the outermost block, which implicitly is the body of the current function.
https://webassembly.github.io/spec/core/syntax/instructions.html#control-instructions

とあり、Instruction::EndInstruction::Returnの評価が逆になっているように見えます。

3つ目

同じ説のifの評価について

ifの条件式が真の場合、今のフレームのPCLabelに退避し、ブロックから脱出する際、退避したPCを今のフレームのPCに戻しているように見受けられます。

退避の際のPCはIfの位置を指しているため、ブロックを脱出するとまたIfの位置に戻ってくるような気がします(無限ループしそう)。

ここは、EndのPCを退避するのが正しいように見えます(今回elseを扱わないため、ブロック脱出でPCの再設定自体不要な気も・・・)。


以上の疑問点については、それっぽく訂正して、それっぽく動くことは確認しました。

ゴリラ@時代はRustですゴリラ@時代はRustです

@ktz_alias ありがとうございます
(if (then ...))の件ですが、もしかしたら使っているwatクレートが新しいかもです
一応今回wat = "=1.0.67"で固定していて、このバージョンでは問題なく動きます
今使っているwatのバージョンはいくつでしょうか?

「if/returnの実装」の節において、
同じ説のifの評価について

おっしゃるとおり、実装がおかしかったので本・リファレンス実装を修正しました
ありがとうございます:bow: