見出し画像

Rust and WebAssembly Game of Life -Debug -

#こどもってなんであんなに愛おしいのでしょうね

Rust and WebAssembly book4.5. Testing Conway's Game of Life に引き続き、 4.6. Debugging に続きます。

コンパイル時エラー

Rust はもともと、変数の寿命というものにかなり神経質なところがあり、所有権という概念を厳格に(?)規定しています。変数Xを変数Yに代入した場合、変数の型にコピー機能が実装されていないと、以降変数Xが参照できなくなります(もちろん、やり方はあります)。

また、配列の値を参照する場合で、添字に配列のサイズを超えた数字を使用していた場合も、コンパイル時のエラーとなります。寿命をチェックしているため(?)、配列のサイズと添字の関係もチェックしてくれているのです。

Panic!

しかしならが、添字に変数を使用する場合は、その値がどうなるのかは実行時にしかわかりません。そして、Rustではその実行時エラーは Panic という表現でレポートされます。例えば次のような感じ。配列のサイズは4096なのに、添字に4105が指定された、と言われています。

panicked at 'index out of bounds: the len is 4096 but the index is 4105'

Rust and WebAssembly Panic!

さて、このチュートリアルをここまで進めてきたのですが、 WASM としては Panic はまだソースコードに組み込まれていません。実際に、今のソースコードに含まれている配列添字を、配列サイズより大きいものを指定するように変更すると、開発者ツールのコンソールに以下がレポートされます。

Uncaught RuntimeError: unreachable
at 04a8a6cf139627dc813c.module.wasm:0x6329
at 04a8a6cf139627dc813c.module.wasm:0x6af2
at 04a8a6cf139627dc813c.module.wasm:0x7ca1
at 04a8a6cf139627dc813c.module.wasm:0x795f
at 04a8a6cf139627dc813c.module.wasm:0x7d03
at 04a8a6cf139627dc813c.module.wasm:0x70e4
at 04a8a6cf139627dc813c.module.wasm:0x37a1
at universe_tick (04a8a6cf139627dc813c.module.wasm:0x7aa4)
at Universe.tick (wasm_game_of_life_bg.js:142)
at renderLoop (index.js:22)

はい。もうさっぱり何がなんだか。
ということで、 4.6. Debugging に記載されている通りpanicを有効にする記述を追加してあげると、レポートに以下が追加されました。

panicked at 'index out of bounds: the len is 4096 but the index is 4105', src/lib.rs:46:26
Stack:
Error
at Module.__wbg_new_59cb74e423758ede (http://localhost:8080/0.bootstrap.js:266:15)

めでたしめでたし。

Rust/WebAssembly でコンソールへのログ出力2

今回はつまづきポイントもなく、少しあっけなく終わってしまったので、コンソールへのログ出力その2について記録します。(じつはここでつまづきましたが、おまけなのでノーカウントです)

以前、Rustソースコード上で以下の関数を使用することで、ブラウザの開発者ツールのコンソールにログを出力できることをお話ししました。

web_sys::console::log_1(&"Universe.new is called.".into());

これは log_1 とあるので、引数を1つ指定して使用するログ関数です。
ここでは引数を2つ指定する log_2 を使ってみます。 Life データ配列の添字10 のデータが Alive なら 1 を、 そうでないなら 0 をコンソールに出力します。 into() がついている引数が2つありますね。

if next[10] == Cell::Alive {
   web_sys::console::log_2(&"next cells[10] = ".into(), &(1.into()));
} else {
   web_sys::console::log_2(&"next cells[10] = ".into(), &(0.into()));
}

これをコンパイルし、開発者ツールのコンソールを確認すると、以下のように "next cells[10] = 1 (or 0)" が記録されていることがわかります。
同じメッセージが連続して出力されると、回数を表示してまとめられるのですね。見やすい。

画像1

おわりに

今回はデバッグ機能の利用ということで、チュートリアルとしてはつまづきポイントはありませんでした。自分で何か作ろうと思ったら、デバッグ手段の確保は必須なので、今後役立つときは来ることでしょう。

最後まで読んでいただき、ありがとうございました。

この記事が気に入ったらサポートをしてみませんか?