WebAssembly を使用した Node.js

WebAssembly は、C/C++、Rust、AssemblyScript など、さまざまな言語からコンパイルできる高性能なアセンブリ風言語です。現在、Chrome、Firefox、Safari、Edge、そして Node.js でサポートされています!

WebAssembly の仕様では、2 つのファイル形式が定義されています。1 つは ` .wasm ` 拡張子を持つ WebAssembly モジュールと呼ばれるバイナリ形式、もう 1 つは ` .wat ` 拡張子を持つ WebAssembly テキスト形式と呼ばれる対応するテキスト表現です。

主要な概念

  • モジュール - コンパイルされた WebAssembly バイナリ、つまり ` .wasm ` ファイル。
  • メモリ - サイズ変更可能な ArrayBuffer。
  • テーブル - メモリに格納されていない参照のサイズ変更可能な型付き配列。
  • インスタンス - メモリ、テーブル、および変数を持つモジュールのインスタンス化。

WebAssembly を使用するには、` .wasm ` バイナリファイルと、WebAssembly と通信するための一連の API が必要です。Node.js は、グローバル ` WebAssembly ` オブジェクトを介して必要な API を提供します。

console.log(WebAssembly);
/*
Object [WebAssembly] {
  compile: [Function: compile],
  validate: [Function: validate],
  instantiate: [Function: instantiate]
}
*/

WebAssembly モジュールの生成

WebAssembly バイナリファイルを生成するには、複数の方法があります。たとえば、

  • WebAssembly(` .wat `)を手書きし、wabt などのツールを使用してバイナリ形式に変換する
  • C/C++ アプリケーションで emscripten を使用する
  • Rust アプリケーションで wasm-pack を使用する
  • TypeScript 風のエクスペリエンスを好む場合は、AssemblyScript を使用する

これらのツールのいくつかは、バイナリファイルだけでなく、ブラウザで実行するための JavaScript の "接着剤" コードと対応する HTML ファイルも生成します。

使用方法

WebAssembly モジュールを作成したら、Node.js の ` WebAssembly ` オブジェクトを使用してインスタンス化できます。

// Assume add.wasm file exists that contains a single function adding 2 provided arguments
const fs = require('node:fs');

const wasmBuffer = fs.readFileSync('/path/to/add.wasm');
WebAssembly.instantiate(wasmBuffer).then(wasmModule => {
  // Exported function live under instance.exports
  const { add } = wasmModule.instance.exports;
  const sum = add(5, 6);
  console.log(sum); // Outputs: 11
});

OS との対話

WebAssembly モジュールは、単独では OS 機能に直接アクセスできません。サードパーティツールである Wasmtime を使用すると、この機能にアクセスできます。` Wasmtime ` は、WASI API を利用して OS 機能にアクセスします。

リソース