WebAssemblyチャレンジ2

とりあえず作ってみた。
WebAssemblyのバイナリフォーマットを見ながらそのまま書いただけなのでさほど難しくない。

LEB128

ちょっと変わっているのはwasm内での値の表現がLEB128というエンコーディングで表現されているところ。これは可変長整数の表現方法で、値は下位7bitで表現して、最上位の1bitが1の場合は次のbyteに続く、という意味になる。1byteで表現できる範囲が127までに減ってしまうが、int32で持っていても入る値はたいがい1桁か2桁程度のことが多いので効率が良い。
デコードは遅くなるがバイナリサイズを小さくすることを優先しているあたり、WebAssemblyがネット上の転送時間を気にしている感じである。

出力データについて

前回の足し算を元ネタとして、必要最低限のセクションのみ出力するようにしてみた。テーブルとメモリのセクションは使っていないので省略して、あとなぜかエクスポートされていたメモリも省略。関数の中身は掛け算にして名称をmulに変更。
ということで11あるセクションのうち4つしか出力していないので短い。あと実行するコードはベタでバイナリ記述になっていて、これを生成するのが最終的な目標になるのだが、そういう技術は持ち合わせていないのでどうなることやら。
プログラムの出力はこんな感じ。

00 61 73 6D 01 00 00 00 01 07 01 60 02 7F 7F 01
7F 03 02 01 00 07 07 01 03 6D 75 6C 00 00 0A 09
01 07 00 20 01 20 00 6C 0B

最後の0x0bは関数の終了で、その前の0x6cが掛け算命令である。前回はここが足し算の0x6aだった。

結果

まあ、こんな感じで掛け算できるようになった。

現状では使ってないセクションが多いので、それらをどうにかする必要があるが、サンプルにするバイナリも無いし、どうしたものかなーと。