Lesson 1: Wasmを始める

最初のレッスンでは、WebAssembly (Wasm) を始めるための基本を説明します。 このレッスンを終えることで、CまたはRustで簡単なWebAssemblyモジュールを書き、Wasmバイナリ形式にコンパイルして、Node.js上で実行できるようになります。

Wasmとその利点の紹介

WebAssemblyは、安全で効率的、かつさまざまなプラットフォームで動作する (ポータブルな) コードをWeb上で実行できるバイナリ命令形式です。 すべての主要なウェブブラウザと互換性があるように設計されており、開発者がJavaScript以外の言語で高性能なアプリケーションを書くための方法を提供します。

Web開発において、WebAssemblyは様々な面で有用です。 ここではそのいくつかを紹介します:

  • 高いパフォーマンス: WebAssemblyのコードはマシンコードにコンパイルされるため、インタプリタで動作するJavaScriptのコードよりもしばしば高速に実行することができます。
  • 移植性: WebAssemblyモジュールは、デスクトップやモバイルデバイスなど、WebAssembly規格をサポートするあらゆるプラットフォームで実行できるようにコンパイルすることができます。
  • 安全性 WebAssemblyは、サンドボックス環境で実行されます。つまり、割り当てられたメモリ空間以外のリソースにアクセスしたり、変更したりすることはできません。
  • 相互運用性: WebAssemblyモジュールは、WebAssemblyバイナリフォーマットにコンパイル可能なあらゆる言語で記述することができるため、既存のコードを簡単に再利用することができます。

Wasmの開発環境の構築

WebAssemblyの開発を始めるには、いくつかのツールが必要です。

エディター: まず、コードエディターを準備しましょう。 Visual Studio Code はWebAssemblyの開発環境としてよく使われており、公式サイトなどから無償でダウンロードすることができます。

コンパイラ: 次に、WebAssemblyのコードを生成できるコンパイラが必要です。ここでは、C/C++とRustそれぞれの開発環境を整える手順を紹介します。

C/C++ (Emscripten)

CとC++の場合は、C/C++コードをWebAssemblyにコンパイルするための一般的なツールチェーンである Emscripten を使用します。 最も簡単なインストール方法は、以下のようなコミュニティのパッケージを使用する方法です。

Rust

Rustの場合は、Rustコンパイラ (rustc) で wasm32-unknown-unknown ターゲットを指定することでRustのコードをWebAssemblyにコンパイルすることができます。

  • まず、 https://www.rust-lang.org/tools/install の指示に従って、Rust と Cargo をインストールします。
  • 次に、コマンド rustup target add wasm32-unknown-unknown を実行して、WebAssembly ターゲットを追加します。

コードエディタとコンパイラをインストールしたら、WebAssemblyのコードを書き始める準備は完了です。 次のセクションでは、CまたはRustで簡単なWebAssemblyモジュールを書いてみます。

CまたはRustで簡単なWasmモジュールを作成する

WebAssemblyにコンパイルできる、単純な add() 関数をCまたはRustで書いてみましょう。

C言語のコード (add.c)
int add(int a, int b) {
    return a + b;
}
Rustのコード (add.rs)
#[no_mangle]
pub extern "C" fn add(a: i32, b: i32) -> i32 {
    a + b
}

モジュールをWasmのバイナリ形式にコンパイルする

C言語または Rust で add() 関数のファイルを作成したら、コンパイラを使って WebAssembly のバイナリ形式にコンパイルします。 コンパイルするには以下のコマンドを実行します。

C言語 (Emscripten)
emcc add.c -s WASM=1 -s SIDE_MODULE=1 -O2 -o add.wasm
Rust
rustc --target wasm32-unknown-unknown -O --crate-type=cdylib add.rs

これらのコマンドによって、Node.jsやブラウザ上で実行できる最小限のWasmバイナリファイルが add.wasm という名前で生成されます。

Node.jsでモジュールを実行する

Node.jsでWebAssemblyモジュールを実行するためには、モジュールのバイナリファイルを読み込んだ後、モジュールをコンパイルし、さらにインスタンス化する必要があります。 コンパイルやインスタンス化は、WebAssembly グローバルオブジェクトを使って行います。 例えば、Node.js で add() 関数を読み込んで実行するコードは以下のようになります:

sample_add.js
const fs = require('fs');
 
(async () => {
  const buffer = fs.readFileSync('add.wasm');
  const module = await WebAssembly.compile(buffer);
  const instance = await WebAssembly.instantiate(module, {});
  console.log(instance.exports.add(2, 3)); // Output: 5
})();
実行例
$ node sample_add.js
5

このコードでは add.wasm ファイルを読み込んでコンパイルし、それをインスタンス化しています。 最後に、引数に 23 を指定して add() 関数を呼び出し、結果 5 をコンソールに出力します。

まとめ

これで、簡単なWebAssemblyモジュールを書き、Wasmバイナリ形式にコンパイルし、Node.jsで実行することができました。 次のレッスンでは、WebAssemblyモジュールの構造を深く掘り下げ、WebAssemblyコードで関数を宣言してエクスポートする方法について学びます。

このレッスンはどうでしたか?