--- title: WebAssemblyコードのロードと実行 slug: WebAssembly/Loading_and_running tags: - Fetch - JavaScript - WebAssembly - XMLHttpRequest - バイトコード translation_of: WebAssembly/Loading_and_running ---
JavaScript で WebAssembly を使用するには、まずコンパイル/インスタンス化の前にモジュールをメモリにプルする必要があります。この記事では、WebAssembly バイトコードをフェッチするために使用できるさまざまなメカニズムのリファレンスと、それをコンパイル/インスタンス化して実行する方法について説明します。
WebAssemblyは <script type='module'>
または ES2015 の import
文とまだ統合されていないため、インポートを使用してブラウザでモジュールをフェッチする組み込みの方法はありません。
以前の {{jsxref("WebAssembly.compile")}}/{{jsxref("WebAssembly.instantiate")}} メソッドでは、生のバイトをフェッチした後 WebAssembly モジュールのバイナリを含む {{domxref("ArrayBuffer")}} を作成し、コンパイル/インスタンス化する必要があります。これは文字列(JavaScript ソースコード) をバイトの配列バッファ (WebAssembly ソースコード)で置き換えることを除いて、new Function(string)
に似ています。
新しい {{jsxref("WebAssembly.compileStreaming")}}/{{jsxref("WebAssembly.instantiateStreaming")}} メソッドは、より効率的です。ネットワークからの生のバイトストリームに対して直接アクションを実行し、 {{domxref("ArrayBuffer")}} ステップの必要性がなくなりました。
では、どのようにバイト列を配列バッファに読み込んでコンパイルするのでしょうか? 次の章で説明します。
Fetch はネットワークリソースを取得するための便利でモダンな API です。
wasm モジュールをフェッチする最も簡単で効率的な方法は、新しい {{jsxref("WebAssembly.instantiateStreaming()")}} メソッドを使用することです。このメソッドは最初の引数として fetch()
を呼び出すことができ、1つのステップでフェッチ、モジュールをインスタンス化し、サーバからストリームされる生のバイトコードにアクセスします。
WebAssembly.instantiateStreaming(fetch('simple.wasm'), importObject) .then(results => { // Do something with the results! });
直接ストリームでは動作しない古い {{jsxref("WebAssembly.instantiate()")}} メソッドを使用した場合、フェッチされたバイトコードを {{domxref("ArrayBuffer")}} に変換する必要があります。次のようにです:
fetch('module.wasm').then(response => response.arrayBuffer() ).then(bytes => WebAssembly.instantiate(bytes, importObject) ).then(results => { // コンパイルされた結果(results)で何かする! });
{{jsxref("WebAssembly.instantiate()")}} 関数は2つのオーバーロードを持ちます — 1つ目 (上の例を参照)はバイトコードを受け取ってプロミスを返します。解決されたプロミスでコンパイルされたモジュールと、それをインスタンス化したものを含むオブジェクトとして受け取ります。オブジェクトの構造は以下のようになります:
{ module : Module // コンパイルされた WebAssembly.Module オブジェクト, instance : Instance // モジュールオブジェクトから生成された WebAssembly.Instance }
注: 通常はインスタンスのみを気にしますが、キャッシュする場合や、postMessage()
を使用して別のワーカーやウィンドウと共有する場合や、インスタンスをさらに作成したい場合に備えて、モジュールを用意すると便利です。
注: 2番目のオーバーロードフォームは {{jsxref("WebAssembly.Module")}} オブジェクトを引数としてとり、結果としてインスタンスオブジェクトを直接含む Promise を返します。2番目のオーバーロードの例を参照してください。
JavaScript 内で WebAssembly インスタンスが 有効になったら {{jsxref("WebAssembly.Instance/exports", "WebAssembly.Instance.exports")}} プロパティを通してエクスポートされた機能を使い始める事ができます。コードは以下のようになるでしょう:
WebAssembly.instantiateStreaming(fetch('myModule.wasm'), importObject) .then(obj => { // Call an exported function: obj.instance.exports.exported_func(); // or access the buffer contents of an exported memory: var i32 = new Uint32Array(obj.instance.exports.memory.buffer); // or access the elements of an exported table: var table = obj.instance.exports.table; console.log(table.get(0)()); })
注: WebAssembly モジュールからのエクスポートの仕組みの詳細については WebAssembly JavaScript API の使用 と WebAssemblyテキストフォーマットを理解する を参照してください。
XMLHttpRequest
は Fetch よりやや古いですが、引き続き型付き配列を取得するために適切に使用することができます。繰り返しますが、モジュール名は simple.wasm
とします:
GET
に設定し、フェッチするためのパスを宣言します。'arraybuffer'
にすることです。最終的なコードは以下のようになります:
request = new XMLHttpRequest(); request.open('GET', 'simple.wasm'); request.responseType = 'arraybuffer'; request.send(); request.onload = function() { var bytes = request.response; WebAssembly.instantiate(bytes, importObject).then(results => { results.instance.exports.exported_func(); }); };
注: 動作例は xhr-wasm.html を参照してください。