お題
WebAssembly text formatからwasmバイナリをつくる環境を整える - @ledsun blogで、watからwasmが作れるようになりました。 すこし複雑な例をつかってwasmバイナリを生成して読んでみましょう。 WebAssembly テキスト形式の理解 - WebAssembly | MDNにwatのサンプルがあります。 今回は最初のサンプルを使います。
(module (memory 1) (func))
手法
これをwat2wasm
でwasmバイナリに変換します。
~/wabt/bin/wat2wasm example_one.wat -o example_one.wasm
バイナリを読む
出力されたバイナリを見てみます。
►hexdump -C example_one.wasm 00000000 00 61 73 6d 01 00 00 00 01 04 01 60 00 00 03 02 |.asm.......`....| 00000010 01 00 05 03 01 00 01 0a 04 01 02 00 0b |.............| 0000001d
00 61 73 6d 01 00 00 00
がプリアンブルです。
01 04 01
以降がセクションです。
ふたつの違和感
ここで違和感があります。
セクションは1バイトのidに続いて4バイトのサイズがあると思っています。
4バイトのサイズというのは04 01 60 00
のことです。
これはいくら何でも大きすぎます。
次に(memory 1)
をコンパイルしたので、memoryセクションのid 05
があるはずです*1。
05 03 01 00 01 0a 04 01 02 00 0b
のあたりがmemoryセクションのようです。
これも値1を表すには長すぎます。
セクションの並び順
そういえばwat上ではmemoryセクションが前にあったのに、wasmでは後ろにずれています。 これはwasmのセクションはid順に並ぶためのようです。 そう思ってみると、01と05の間に03セクションがあるように思えます。
01(typeセクション) は 01 04 01 60 00 00
ではないでしょうか?
そう考えるとスッキリします。
- 01 : id
- 04 : size
- 01 60 00 00 : cont
と読むと良さそうです。
サイズは1バイト
sizeは4バイトだと思ってましたが、1バイトでした。 *2
そうやって見るとこのバイナリには次のセクションが含まれていることがわかります。
01 04 01 60 00 00
: type03 02 01 00
: function05 03 01 00 01
: memory0a 04 01 02 00 0b
: code
なにやら、それっぽいです。 wasmバイナリが読めるようになった気がしてきました。
*1:セクションのIDの意味はModules — WebAssembly 2.0 (Draft 2023-09-06)のテーブルを見るとわかります。
*2:wasmバイナリのカスタムセクションを書いてみる - @ledsun blog でsizeを4ではダメで、7にするとよい理由がわかりました。