TL;DR
軽量で高速なバイナリ形式の命令セットアーキテクチャ。厳密には、仮想マシンとその命令セットを定めた仮想命令セットアーキテクチャである。ブラウザでの性能向上を目的に設計されたが、ブラウザの外でも動く。
なぜ必要か
WASM は多くのプログラミング言語のビルドターゲットにできる。Rust、C、C++、Zig、Kotlin、Swift には WASM を出力するコンパイラがある。Ruby や JavaScript には、処理系ごと WASM にして動かすツールがある。
WASM の登場前は、C で書かれた機能を Web サイトで使うには JavaScript で書き直す必要があったが、WASM なら C のまま使える。拡張機能を受け付けるプラットフォームでも、拡張を書ける開発者の幅が広がる。
もう一つの利点は、作成元が信用できないコードも安全に実行できることである。
仕組み
安全に実行できる理由
WASM はサンドボックスの中で実行される。インスタンスがアクセスできるメモリ(線形メモリ)はただのバイト列で、コードはその外に置かれ、実行可能フラグもない。そのため、スタック領域を書き換えたり、データとして書き込んだコードを実行したりする攻撃が難しい。
ファイルや通信などのリソースへはシステムインタフェースを通してアクセスする。これは実行環境が用意するので、触れるリソースを実行環境の側で制限できる。
仮想マシン
WASM の仮想マシンにはレジスタがなく、メモリから読み込んだ値をスタックに積んで演算する。メモリは 64KiB のページ単位で管理される。
バイナリは、テキスト形式の WAT に変換すれば読める。
標準化
2015 年に発表され、2017 年に主要なブラウザが対応し、2019 年に W3C で仕様が勧告された。新しい仕様は Phase 0 から 5 の段階を経て標準になる。固定長の SIMD はこうして追加され、WebAssembly Component Model も議論が進んでいる。
例
- Goodnotes は、Swift で書かれた iOS 向けのアプリを、2022 年に Web、ChromeOS、Android、Windows に展開した。SwiftWasm で 10 万行を超えるコードを再利用した。
- Microsoft Flight Simulator と Shopify Functions は、拡張機能の仕組みに WASM を採用している。
- Rust のビルドターゲットを WASM にしてビルドする
注意点
登場した当初は、JavaScript より速いことが利点とされた。しかし JavaScript の処理系が改善され、線形メモリとのデータのコピーもあるので、WASM のほうが遅い場合もある。2024 年 10 月時点では、速度よりも性能のばらつきが少ないことが注目されている。
C のコードを Web で使う場合も、C 特有の機能や同期的な処理を書き直す作業は残る。
自分の理解
2015 年の発表より前から、構想自体はあったようだ。