WebAssembly 手書きで base122.wasm を作った 2017/9/9

これは何か

base122.wasm は Base-122 の encoder/decoder 実装 by WebAssembly テキスト形式。

学習用に書捨てたコード。

Base-122

みなさん Base-122 をご存知だろうか。 詳細はリンク先を参照してもらうとして、これを簡単に説明するなら名前からわかるように Base64 の変種だ。

私は POSTD の翻訳記事 で知った。 初めて読んだとき、着眼点の面白さとコーディング方式のエレガントさに惚れ込んだ。私達の問題を解決するものでなくても、惚れることってあるよね……。 知らなかったら今すぐ読もう。日本語だし、明確なステップで説明が書かれている良い記事なので。

WebAssembly

みなさん WebAssembly をご存知だろうか。 こちらは注目されている技術なので知っている方は多いと思う。これを簡単に説明するなら Web でバイナリも配布して動かせれば色々メリットあるよね、という仕様だ。

実用的な応用例はいくらでも考えられて、Unity とか WebDNN とか既に動いているらしくて「すげー」ぐらいに認識しているが、私にとっては使いたくなるシーンがなく他人事の技術だった。いつか Web フロントエンドのフレームワークのバックエンド (ややこしい……) が WebAssembly で動くようになれば、デバッグ時に読むかも、ぐらいだ。

base122.wasm

Base-122 + (手書き) WebAssembly = 「勝った」

この組み合わせを思いついたとき、この図式が頭の中に浮かんだ。 ネタ的な面白さと勉強の題材としての丁度良さが自画自賛せざるを得なかった。

base122.wasm が何をするかというと、Base-122 をエンコード/デコードするための API を WebAssembly テキスト形式で書く、というものだ。 出力した WebAssembly はブラウザで動き、Base-122 のエンコード/デコードができる。

感想

WebAssembly テキスト形式 (.wat) を書いているときはツラさしかなかった。 元々、WebAssembly は C++ などの高級言語からコンパイルして出力される実行バイナリのフォーマットを決めるための仕様だ。WebAssembly テキスト形式を自分で書くというのは、言い換えればアセンブリ直書きなんだからそりゃツライ。そういったレイヤーの専門家はいるとは聞くが、私は素人なのでひたすら根気との闘いだった。

言い換えれば根気があれば普通に書ける。 他の CPU 命令や VM を知らないのでイメージでしか語れないが、WebAssembly の仕様は (現状) 非常に小さい。データ型は i32, i64, f32, f64 の 4 種しかなく、命令もサラッと読めてしまう程度のものしかない (その後 LLVM IR のフォーマットを読もうとして腰を抜かした)。 なんでそうなっているか、みたいな話も まとめられてて 面白そうだが、専門外の領域なので読んでもよくわからない部分が多かった。

やって良かった点が、なぜグルーコードと呼ばれるものが必要なのか、というのが肌で感じられたことだった。 手を動かさなくても仕様をしっかり理解していればわかることだろうけど、手を動かすのが最も仕様を理解するモチベーションになるので。 グルーコードというのは WebAssembly と JavaScript を橋渡しするもの。上記通り WebAssembly にはデータ型が数値 4 種しかないため、WebAssembly で文字列を扱いたい、となっても素の WebAssembly が公開する関数は文字列を返せない。両方から触れるメモリ空間を利用したりしてやりとりするわけだけど、その変換をしたりする。その他、DOM を触ったり WebGL を呼び出したりは全部グルーコード (JavaScript) のお仕事。 今まで Emscripten で WebAssembly を出力するとなんで一緒に JavaScript がくっついてくるんだ、と謎に思っていたがわかってよかった。

まとめ