WebAssemblyが機能するためには、2つの主要コンポーネントが必要です。コードをWebAssembly形式のバイナリにアセンブルするツールと、このバイナリをダウンロードして実行できるブラウザです。 どちらもまだ完全には作成されておらず、 WebAssembly 仕様の作業を完了することに大きく依存していますが、一般にこれらは別個のコンポーネントであり、開発は並行して行われます。 この分離は良いことです。コンパイラーはどのブラウザーでも実行できるWebAssemblyアプリケーションを作成でき、ブラウザーはコンパイラーによる作成方法に関係なくWebAssemblyプログラムを実行できます。 言い換えれば、開発ツールとブラウザの間で開かれた競争が行われ、これによりすべてが前進し、エンドユーザーに優れた選択肢がもたらされます。 さらに、この分離により、ツールキットおよびブラウザー開発者のチームは、並行して独立して作業できます。
今日お話ししたい新しいWebAssemblyツールキットプロジェクトはBinaryenと呼ばれます 。 Binaryenは、コンパイラでWebAssemblyをサポートするためのライブラリで、C ++で記述されています。 WebAssemblyコンパイラで個人的に作業していない場合、おそらくBinaryenについて直接知る必要はありません。 WebAssemblyコンパイラを使用している場合、おそらく内部でBinaryenを使用しています。以下の例を見てみましょう。
Binaryenライブラリの中核は、WebAssemblyの解析と生成、およびそのコードを抽象構文ツリー(AST)として表現することです。 これらの機能に基づいて、次の有用なユーティリティが作成されました。
- WebAssemblyモジュールをロードして解析し、そのコードをインタープリターとして実行できる(アクションを実行し、結果をコンソールに出力する)コマンドライン用のユーティリティ。 モジュールをロードして結果を出力するには、接尾辞.wastが付いたs-expressionsの一時的な表記が使用されます( バイナリWebAssemblyモジュールを表すための最終フォーマットはまだ開発中です)。
- asm2wasm-asm.jsをWebAssemblyにコンパイルするためのユーティリティ。
- wasm2asm-asm.jsでWebAssemblyをコンパイルするためのユーティリティ(まだ開発中)
- s2wasm。.sファイル( LLVMのWebAssemblyの新しいバックエンドによって作成された形式)をWebAssemblyにコンパイルします。
- wasm.js-Binaryen JavaScriptポート。 これにより、上記のすべてのツールをブラウザーで直接実行できます。
Binaryenについては、 これらのスライドを見ることができます。
WebAssemblyがアクティブな設計中であることをもう一度思い出します。つまり、入力および出力のBinaryen形式(.wast、.s)は最終的なものではありません。 Binaryenは、WebAssembly仕様を更新するために常に更新されています。 変更のカーディナリティの度合いは時間の経過とともに減少しますが、もちろん、誰も互換性を保証できません。
Binaryenが役に立ついくつかの領域を見てみましょう。
Emscriptenを使用したWebAssemblyでのコンパイル
Emscriptenはasm.jsでCコードをコンパイルでき、Binaryen(asm2wasmユーティリティを使用)はWebAssemblyでasm.jsをコンパイルできるため、Emscripten + Binaryenバンドルは、WebAssemblyでCおよびC ++コードをコンパイルするための完全なツールセットを提供します。 asm.jsコードでasm2wasmを実行できますが、次のようにEmscriptenに実行させる方が簡単です:
emcc file.cpp -o file.js -s 'BINARYEN=”path-to-binaryen”'
Emscriptenはfile.cppをコンパイルし、出力はJavaScriptファイルに加えて、WebAssemblyを含む別の.wastファイルを提供します。 内部では、Emscriptenはasm.jsでコードをコンパイルし、asm2wasmを実行して結果を保存します。 これについては、EmscriptenプロジェクトのWikiで詳しく説明されています。
しかし、ブラウザがまだサポートしていない場合、WebAssemblyで何かをコンパイルする意味は何ですか? いい質問です! :)はい、まだこのコードをどのブラウザでも実行できません。 しかし、私たちはすでにそれで何かをテストできます。 そのため、正しいバイナリがEmscripten + Binaryenバンドルを作成したかどうかを確認します。 これを行う方法? このために、Emscriptがemcc呼び出しコマンドで受信した出力.jsファイルに統合したwasm.jsを使用できます(上記を参照)。 wasm.jsには、インタープリターを含むJavascriptのBinaryenポートが含まれています。 file.jsを(node.jsまたはブラウザで)実行すると、WebAssemblyの実行結果が得られます。 これにより、コンパイルされたWebAssemblyバイナリが正しく機能していることを実際に確認できます。 このようなプログラムの例を見ることができます。さらに、テスト目的のために、リポジトリにさらにいくつかの例があります。
もちろん、私たちはこれらのすべてのツールを使用してまだ安定した地位にありません。 テスト環境は奇妙です。 C ++コードはWebAssemblyにコンパイルされ、WebAssemblyインタープリターで実行されます。インタープリター自体はC ++で記述されていますが、JavaScriptに移植されています。 そして、これまでのところ、すべてを実行する他の方法はありません。 しかし、結果を信じるにはいくつかの理由があります。
- 出力コードはすべてのEmscriptenテストに合格します。 これには、多くの実際のコードベース(Python、zlib、SQLite)の処理に加えて、CおよびC ++の多くの「疑わしい」状況が含まれます。 経験から、Emscriptenテストがこれらのすべてのケースに合格した場合、Emscriptenによって処理された他のコードは正常に動作すると言えます
- Binaryenインタープリターは、すべての内部WebAssemblyテストに合格して、WebAssemblyが正しく実行されているかどうかを判断します。 言い換えると、ブラウザーでWebAssemblyのサポートを取得する場合、ブラウザーは同じ方法で動作する必要があります(ただし、高速である場合を除きます)。
- ほとんどの作業はEmscriptenによって行われます。Emscriptenは、本番環境で長い間使用されてきた安定したコンパイラであり、その上で比較的小さな部分だけがBinaryenを使用して実行されます(コードは数千行です)。 コードが少ないほど、バグが少なくなります。
これはすべて、すでに何らかの結果が得られていることを示しています。CおよびC ++コードをWebAssemblyにコンパイルし、なんとか起動することができます。
WebAssemblyは単なる別の新機能であり、それから気をそらされ、Emscriptenの他のすべてが引き続き機能することに注意してください。 .d。 その結果、Emscriptenを既に使用しているプロジェクトは、新しいコマンドラインパラメーターを追加するだけでWebAssemblyに切り替えることができます。 これにより、C ++プロジェクトをWebAssemblyにコンパイルし、ブラウザで簡単に作業できるようになります。
EmscriptenでWebAssemblyの新しいLLVM実験的バックエンドを使用する
Emscriptenの開発に新たな重要な段階があり、WebAssemblyモジュールを作成し、それらの作業をテストする機会を彼に与えました。 しかし、作業はそこで終わりではありません。asm2wasmユーティリティと共に、現在のasm.jsコンパイラを使用するだけでした。 LLVM for WebAssemblyの新しいバックエンドがあります(むしろ、まだではありませんが、積極的に作成されています)-LLVMのメイン開発ブランチにあります。 そして、まだ実際に使用する準備ができていませんが、時間が経つにつれて非常に重要なツールになるでしょう。 Binaryenは出力形式をサポートしています。
WebAssemblyのLLVMバックエンドは、ほとんどのLLVMバックエンドと同様に、この場合は特別な.s形式でアセンブリコードを作成します。 この形式はWebAssemblyに近いですが、WebAssemblyの直接構文とは異なります-WebAssemblyの抽象構文ツリーよりも、Cコンパイラの出力(命令の線形リスト、1行に1命令)に似ています。 この.sファイルは、かなり簡単な方法でWebAssemblyに変換できます(一般に、Binaryenにはs2wasmユーティリティが含まれています。 これを単独で実行するか、Emscriptenを使用して、新しいWASM_BACKENDオプションをサポートするようになりました。次のように使用できます。
emcc file.cpp -o file.js -s 'BINARYEN=”path-to-binaryen”' -s WASM_BACKEND=1
s2wasmはBinaryenの一部であるため、BINARYENオプションも使用する必要があることに注意してください。 これらのオプションをすべて指定すると、Emscriptenはasm.jsコンパイラーを使用する代わりに、WebAssemblyの新しいバックエンドを使用します。 バックエンドを呼び出し、そこから.s形式のファイルを受け取った後、Emscriptenはs2wasmを呼び出してWebAssemblyに変換します。 この方法で既にビルドできるプログラムのいくつかの例は、Emscriptenプロジェクトwikiにあります 。
したがって、Binaryenを使用してWebAssemblyモジュールを構築するには2つの方法があります。
- Emscripten + asm.jsバックエンド+ asm2wasm 、これは現在動作しており、比較的単純で受け入れ可能なオプションです
- Emscripten + WebAssemblyの新しいバックエンド+ s2wasmは 、まだ完全には動作していませんが、WebAssemblyのバックエンドの開発が前面に出ています。
現時点での目標は、最初の方法から2番目の方法への移行をできるだけ難しくしないことです。 理想的には、すべてをコマンドラインの1つの引数に置き換えるだけに減らす必要があります。
したがって、明確な計画があります。
- Emscriptenを使用してasm.jsコードを生成します(今日)
- asm2wasmを使用してWebAssemblyを生成します(ブラウザーは既に可能ですが、ブラウザーはまだ準備ができていません)
- 新しいLLVMバックエンドを通じてWebAssemblyを生成します(準備ができ次第)
各ステップはユーザーに新しい利点をもたらします(スピード!)そして、開発者にとって実際に問題を引き起こすことはありません。
結論として、この記事は、Emscriptenを使用するという文脈でBinaryenについて書かれていますが、一般的な使用のためのWebAssemblyの別個のライブラリであると言いたいと思います。 WebAssemblyを操作するためのツールを作成するためのアイデアがある場合は、Binaryenライブラリを使用して、Emscripten、LLVM、または他のものを見ずに作業できます。