[この記事は米国 Mozilla HACKS ブログの記事 "A WebAssembly Milestone: Experimental Support in Multiple Browsers" の抄訳です]
WebAsssembly は策定が進んでいる標準の一つで、その目的は安全性とポータビリティを維持しつつ、サイズとロード時間の面で効率的なバイナリフォーマットの定義です。WebAssembly はコンパイラによって出力され、ネイティブに近い性能で動作します。言い換えるならば、WebAssembly のゴールとはWeb のための仮想 CPU の定義です。現在は Mozilla、Microsoft、Google そして Apple を含むメンバーで構成される W3C のコミュニティグループ (CG) で議論されています。
WebAssembly が重要なマイルストーンへと達したことをアナウンスさせてください。それは、複数のブラウザが、WebAssembly を相互運用可能な形でのサポートを開始しました[1][2]。これは実験的なものであり、標準実装にもいくつかの未実装な機能があります。しかしこれまでの成果を公開し、フィードバックを集め、次になすべきことに関する議論をするには良い機会であると言えます。
WebAssembly を導入する理由
JavaScript の低水準な部分集合である asm.js によって、ブラウザがサンドボックスによる安全性を保ちつつネイティブに近い計算性能を出せることが示されました。同時に、これらの機能に対する需要が非常に大きいことも認識されるようになった結果、ゲームや CAD、画像処理や顔認識といった、多様で多くのアプリケーションがEmscripten コンパイラを通じて asm.js を利用するようになりました。
昨年結成された WebAssembly コミュニティグループは、バイナリフォーマットの標準化によりWeb を次の段階へと進めました。このフォーマットにより、JavaScript で可能な限界を超えてファイルサイズを小さくし、ロード時間を短縮させることが可能となりました。また独立した新しい標準となることで、WebAssembly は低水準な機能を JavaScript の進化とは別に取り入れることが可能となりました。
そうはいっても WebAssembly が Web の一部分であり続けることの重要性も認識しています。既存の Web API へアクセスや、JavaScript で定義された関数との相互呼び出しといった、JavaScript との密な結合性は維持されねばならないと考えています。古典的なプラグインモデルと異なり、WebAssembly は JavaScript によるアプリケーションやライブラリと、asm.js がそうであるように、簡単に結合できます。
WebAssembly の初期設計へと至る、Emscripten と asm.js に関する経験は [3] [4] [5] [6] [7] [8] [9] で参照できます。またモダンブラウザが asm.js を高速に動作させられるため、対応していないブラウザで WebAssembly を利用するためのポリフィルも作成されました。これを利用することで、各ブラウザの WebAssembly へ対応が十分なされるのを待たなくても、WebAssembly を利用した開発を行えます。
進捗
過去の話はこれくらいにしておいて、今日へと話を戻します。コミュニティグループは以下の目覚ましい成果を達成しています。すべてのドキュメントは WebAssemby の GitHub organization で公開されています:
- 初期の機能セットと将来的なプランに関して、理論的根拠も含めた説明を行った
- 仕様を定め、レファレンス実装を行った
- インタプリタとブラウザの振る舞いを検証するために、 13,000 行に及ぶテストを実装した
- バイナリフォーマットに関する最初の草案を作成した
さらには 4 つのブラウザエンジンを作成するエンジニアが、WebAssembly のプロトタイプ実装を行いました 10111213。Firefox に関しては、私(訳注:原文著者である Luke Wagner)が asm.js の最適化パイプラインをリファクタリングし、構文解析を行うスレッドからバックグラウンドのコンパイラスレッドへ渡される asm.js のコード表現を WebAssembly のバイナリフォーマットに変更しました。
この変更により、asm.js の並列コンパイルの性能が相当向上しました。MIR 生成とコード生成という 2 つの重たい処理を、シーケンシャルなクリティカルパスから分離できたに分けられたためです。最適化処理パイプラインのリファクタリングによって、信頼できないバイトコードの検証を行うための小さなフロントエンドを追加するだけで、WebAssembly のデコード部分が実装できました。
上記で利用した用語の定義や、JS と asm.js のコンパイルに関する背景知識については、こちらのブログ記事を参照してください。
WebAssembly の試用
すべてのピースが揃い、複数の実験的な実装上で WebAssembly のデモを動作させられるようになりました。「実験的」である 2 つの要素、バイナリフォーマットと WebAssembly に対する JavaScript バインディングには、最初の標準が出来上がるまでの向こう数ヶ月間にいくつかの変更が加わると予想されます。また現在の処理系の実装が、ベンチマークやストレステストに耐えうるレベルまで成熟しているとも思われません。しかし、すべてのブラウザが足並みを揃えたところに、今回のマイルストーンの重要性があります。今後も協調して開発を続けていけるでしょう。
上述した通り、複数のブラウザ上で実際に動作するデモが用意されています:
特にこのデモには感傷的な価値があります:AngryBots は Unity のチュートリアルプロジェクトで、我々は Unity の WebGL 出力を作り上げる際にスモークテストとして利用していました。懐かしい、良い思い出です :)
このデモを動かすためには、Firefox の Nightly ビルドをダウンロードし、about:config で javascript.options.wasm に true を設定してください。
リリースまでの道のり
さて次は?安定した最初のリリースを行う前に、やるべきことがまだまだあります。コミュニティグループは、以下に挙げる事柄を大きなタスクだと考えています:
- オフィシャルな WebAssembly のテキスト表現の定義
- バイナリフォーマットのサイズのさらなる縮小。現在のバイナリフォーマットは圧縮されていない asm.js と比べて 42% 小さくなっています(gzip 圧縮時は 12%)。以前行ったバイナリフォーマットに関する作業の結果、さらに大幅に小さくできることがわかっています
- WebAssembly JavaScript API の改善。現在の実験的なビルドには、Wasm.instantiateModule という同期的な関数一つだけが定義されています。これはコンパイルと、インスタンスの作成の二つを行います。暫定的な計画では、これら二つの処理を分離し、構造化され複製可能なコードオブジェクトを出力する関数を用意することになっています。新たに用意される関数は、同期的に実行するものに加えて、非同期的に実行されるものも同様に用意されます。これにより、現在の暗黙的に行われる asm.js のマシンコードのキャッシュよりはるかに柔軟にコンパイルとマシンコードのキャッシュをコントロールできるようになります。
- コンパイラ作者、ツール製作者、ハッカーそして学生にとって、より読みやすいドキュメントの整備
- テストスイートの充実
Firefox に関しては、以下を計画しています:
- デバッガとプロファイラを含む、開発ツールの WebAssembly 対応。JavaScriptでは、Firefox に組み込まれている開発ツールと Firebug のチームは協力して、新しく、抽象的で、単体テスト可能な Debugger API を利用す方向に進んでいます。私たちはこの API を WebAssembly 向けにも実装しようとしています。実装はすでに始まっており、前述のデモを実行中にデバッガのタブを開くと、バイナリフォーマットから生成されたテキストフォーマットを見るためのプレースホルダーが置かれていることに気づくかと思います(オフィシャルなテキストフォーマットが定義された時点で、それに置き換わります)
- コールドロードにかかる時間の短縮。16 個の 2.4 GHz のコアを持つ Linux マシンで測定した結果、WebAssembly になった AngryBots のコンパイル時間は、asm.js のそれに比べて 52% 減少しました。これは最初としては良い結果で、WebAssembly のデコードでコードは asm.js の構文解析より 10 倍程度高速であることによる結果です。コンパイルパイプラインの他の部分を改良することにより、コールドロードのさらなる短縮が見込めます
- WebAssembly で定義されている演算子の実装の完了と、テストスイートの導入
全速で進みます
WebAssembly の進歩は、これまでのところ常に前向きなものでした。WebAssembly コミュニティグループのコラボレーションを促す空気には驚きと感謝が絶えません。より詳しく知りたい方は、GitHub のページをご覧ください。ここから始めるのが最善です。Happy hacking!
Luke Wagner について
Luke Wagner は Mozilla のリサーチエンジニアで、WebAssmebly と asm.js を Mozilla の JavaScript エンジンに組み込む活動を行っています。
Luke Wagner による、その他の記事はこちら。