By Marco Fioretti
WebAssembly 略称 Wasm は、Webでの利用に適した実行可能ソフトウェア形式で、プログラマーに最大限の柔軟性を与えるように設計されています。 Wasmバイナリ モジュールは、一度コンパイルすれば、単独でも他のアプリケーションに組み込んでも、どこでも安全に実行できます。実はWasmはそれを実現するために少なくとも3つの主要なコンポーネントを必要とします。そのうちの2つが、このシリーズですでに紹介されている WebAssembly System Interface (WASI) と Wasm Interface Typesです。
WASIは、Wasmモジュールに、言語に依存しない標準の方法を提供して、それらが到達する可能性のあるホスト環境と対話します。そのインターフェイス タイプは標準化された定義ですが、あらゆる種類のソフトウェア変数に対応しています。それらを使用することにより、Wasmモジュールは、別々のプログラマーがまったく異なるソース言語で作成した複雑なデータ構造でも、破損することなくやりとりできます。このパズルの他の主要な部分は モジュール リンクと呼ばれます。これにより、異なるバイナリファイルが、たとえば互いの関数を使用して、同じソースコードの異なるセクションとして記述され、一緒にコンパイルされたかのように直接対話できるようになります。
Wasmモジュールをリンクすることの長所と短所
Wasmモジュールをリンクする最初の理由は、プログラミングのすべての領域で常に有効なもの、つまり再利用です。たとえば、数学関数やネットワーク関数のライブラリを一度作成(および保守)できるが、何千人ものプログラマーがほとんどまたはまったく労力をかけずにそれを使用できるようにすれば、誰もが勝ちます。
もう1つの理由はさらに単純ですが、Wasmのような形式では特に重要です:速度。少なくとも当面の間、ほとんどのWasmモジュールは、リモートサーバーによって、場合によっては低速のモバイルリンクにダウンロードされ、オンザフライで実行されます。このような場合はすべて、コードのダウンロードと準備に1秒余分に費やすと違いが生じる可能性があります。大規模なWasmアプリケーションが個別の相互リンク可能なモジュールに分割されている場合、そのホストは、自身のユーザーが必要とするものだけをダウンロードできます。 実際に それらが必要です。ダウンロードをさらに減らすために、頻繁に要求されるモジュールをローカルにキャッシュすることもできます。
もちろん、良いことは多すぎる可能性があります。特に多くの独立したソースからの多くのモジュールを使用すると、ソフトウェア開発がスピードアップしますが、 メンテナンス 長期的にはより複雑です。同時に、安定したネットワークでは、複数のモジュールをダウンロードしてリンクするのに、ほとんど定義上、ただ取得するよりも時間がかかります。 一 まったく同じことを行うコードのブロブ。さらに、リンクされたWasmモジュール間の関数呼び出し 「1つのモジュール内の関数呼び出しよりも遅くなる可能性があります」。全体として、これらすべての要因により、実際のパフォーマンスが数パーセントポイント低下する可能性があります。多くの場合、これは非常にリーズナブルな価格です。
モジュールをリンクするWasmの方法
独立して開発されたWasmモジュールは、コンパイル時に無数のソフトウェアアプリケーションで使用されるのと同じ方法で常に「リンク」できます。これにより、必要なすべての機能を備え、Wasm / WASI準拠の仮想マシン内で実行できる1つの実行可能ファイルが生成されます。ただし、各実行可能ファイルの生成に使用される特定の言語とツールチェーンに依存することに加えて、これは 静的 リンクは、望ましい結果のほぼ反対です。 「ポータブルで、ホストおよび言語に依存しないエコシステム」 必要に応じて構成可能なWebAssemblyモジュールの 後、それらをダウンロードする前ではなく、それらがどこから来たかに関係なく。
まず、この方向への小さな一歩がすでに述べたものを使用することからなる場合 Wasm Interface Types:実際、異なるWasmモジュールを交換させることができます コピー 実際にそれらを共有することなく、それらが同じプログラムの一部であるかのように、それらのデータ構造の。モジュール間のこの限定された形式の連携は、「シェアードナッシングリンク」と呼ばれます。
ただし、Wasmのコア哲学と実際に一致する種類のリンクは、それが本当に必要な場合にのみ発生し、リソースを浪費せず、とりわけ、Wasmのプロバイダーに不必要な制約を課しません。モジュール。リンクは、つまり、実際にリンクを必要とするホストで発生する必要がありますが、 それなし リンクされているモジュールの準備、またはモジュールを作成したプログラマー向けのアプリケーション固有のカスタマイズが必要です。
つまり、Wasmバイナリは、仮想化手法を使用して、リンクする他のモジュール(またはモジュールの一部)を宣言およびインポートする必要があります。 「リンク時仮想化」と呼ばれるこのメカニズムにより、最終的にはいわゆる「Shared-Everything Dynamic Linking」が可能になり、リンクされたすべてのモジュールが重複することなくメモリとデータテーブルを直接共有できるようになります。このアプローチの低レベルで残酷な詳細は、公式の対応するセクションで説明されています Wasmモジュールをリンクするための説明。ここでは、すべての「純粋なWasm」リンクソリューションに含める必要がある2つの一般的なプロパティまたは制約についてのみ説明します。
最初のものは 「最小権限の原則」、これにより、すべてのWasmモジュールは常にホストに公開するか、ホストに要求する必要があります。これにより、ジョブを実行するために必要な機能の可能な限り最小のサブセットのみが公開されます。もう1つは、簡単に言うと、モジュールをリンクすることで、 Wasmのガベージコレクション すでにあるよりも複雑です。
実際には:Emscripten、JavaScript API、WAPM
ゼロからリンクされたWasmモジュールを作成して使用するための最も基本的なツールは、CまたはC ++のdlopen()、またはJavaScriptでは同等のWebAssemblyAPIのような関数です。適切な指示があれば、 Emscriptenツールチェーン JavaScript仮想マシンにWasmコードをロードして実行させるグルーロジックに、 dynamicLibraries ダウンロードしてリンクする必要のあるすべてのモジュールを一覧表示する配列。代わりに完全なリンク可能なモジュールを研究または使用するには、の公式レジストリを確認してください。 WebAssemblyパッケージマネージャー(WAPM)、その目的がまさにそのようなモジュールの公開とインストールを容易にすることであるオープンソースツール。