WebAssembly
https://scrapbox.io/files/673b4c0ef086f4eda218bc7d.png
そのままだと人間には読めないので、WAT に変換する必要がある 当初は Web ブラウザ でのパフォーマンスの向上を目的として設計されていたが、ブラウザ以外でも利用できる 2015 年発表
構想自体はその前からあったっぽい radish-miyazaki.icon
特徴
ビルドターゲットとすることが可能
また、処理系を WASM としてビルドし、その上で実行するプログラムをデータとして WASM に追加することで、Ruby や JavaScript などのプログラムを WASM に変換するツールもある 様々なプログラミング言語でビルドできるため、たとえば C で書かれたプログラムをが持つ機能を利用した Web サイトを作ることが容易になった warning.icon ただし、WASM を用いたとしても C 特有の機能や、同期的に書かれている部分を非同期処理に対応するように書き直す作業は発生するので、書き直しの労力が 0 になるわけではない また、サードパーティのプログラムを拡張して実行するようなプラットフォームでも恩恵を受けられる
これを WASM にすると、プログラミング言語の選択肢の幅が広がり、その分多くのプログラマが実装できるようになる
具体例
作成元が信用できないコードも安全に実行できる
WASM も JavaScript 同様、Web ブラウザで実行される場合はブラウザとは異なる環境(サンドボックス)で実行 される この一端を WASM のメモリ構造から確認できる
WASM インスタンス(実行中の WASMファイル)からアクセスできるメモリを線形メモリと呼ぶ
線形メモリは単なるバイトの配列
そのため、スタック領域を不正に操作して、任意コードを実行する攻撃が難しい
コンパイラによっては、WASM の線形メモリの一部をスタック領域のように利用するものもある
この場合でも、WASM のコードは WASM インスタンスからアクセスできない領域に保存されており、実行可能フラグのようなものも線形メモリには無い
そのため、不正なコードをメモリ上にデータとして書き込み、実行可能フラグを設定することで実行する攻撃も難しい
また、システムが管理するリソースへのアクセスも制限 されている
リソースへのアクセスは システムインタフェース を介して行うが、システムインタフェースは Web ブラウザのような WASM の実行環境が用意している そのため、 WASM の実行環境を用意する側で、WASM がアクセスできるリソースを制限できる
e.g. WASM CLI はプログラムを起動する API を持たない
そのため、shell のように他のプログラムを起動するには、WASM CLI とは別のシステムインタフェースを実行環境に用意する必要がある バイナリ ファイルをテキスト形式(WAT)に変換でき、ソースコードとして読むことが可能 仮想マシンの概要
実マシンでプログラムを実行する場合
その後、レジスタに読み込まれた値に対して命令に応じた演算を行い、結果を必要に応じて メインメモリ に書き戻す メモリからデータをロードして、ロードされた値に対して命令に応じた演算を行う
ただし、上記の場合にデータは スタック にロードされる WASM の仮想マシンには レジスタ は無く、演算はすべてスタックを対象に行われる WASM からアクセスできるメモリは最大 2GiB まで
なぜ 2GiB か?
メモリはページと呼ばれる 64 KiB(65536 Byte)で管理される
このページのインデックス(アドレス空間)は 32 bit で表現される 64 bit にする仕様が現在策定されている
もし 64 bit になると、wasm32 ではなく wasm64 というビルドターゲットが表示されるはず
そのため本来であれば 4GiB になるはずである
code:latex
2 ^ {32} = 4,294,967,296 Byte
しかし、ページインデックスの最上位ビットはエラー処理のために利用されるため、その半分の 2 GiB になる
ユースケース
『プラットフォームやプログラミング言語に依存しないビルドターゲットである』という特性を活かしたユースケース
なぜ WASM を採用したか
10 万行を超えるコードを再利用するため
あるプラットフォームで行われたパフォーマンス改善やバグ修正を、他のプラットフォームでも活用できるため
既存の資産を生かしたWeb サービスを提供するため
幅広い開発者に開発やエコシステムに参加してもらうため
『作成元が信用できないコードも安全に実行できる』という特性を活かしたユースケース
アプリケーションの拡張機能
機能拡張の問題点
機能拡張が必要ということは、実現したいことが設定ファイルで記述できる範疇を超えて多様であることを意味する
そのため、拡張機能を有効にすると、何らかの別のプログラムが動作する
ここで問題になるのが、動かしたプログラムが安全であるか どうか
もし、開発元に認定された開発者だけが機能拡張を作成できるように制限した場合、プログラムが安全であることを確認することは、そうでない場合と比較して容易である
しかし、第三者が機能拡張を作成できるようにした場合はその限りではない
WASM を用いると、上記の問題を解決できる
WASM の実行環境はサンドボックス内部で WASM にビルドされたプログラムを動作させるため
その他のメリット
ビルドターゲットとできる点も機能拡張の多様さや開発者の確保という点で有利に働く
ライブラリとして提供されている WASM の実行環境も用意されている
これにより、1 から実行環境を実装しなくても、WASM を利用した拡張機能をサポートできる
採用例
Microsoft Flight Simulator
WASM のアプリケーションの機能拡張として WASM を採用
Shopify Functions
サービスの機能拡張として WASM を採用
Web ブラウザの搭載する JavaScript の処理系(e.g. V8)は、実行時に適用される 最適化 手法や段階によってパフォーマンスが異なるケースがある 一方、WASM はパフォーマンスのばらつきが少なく、JavaScript よりも安定したパフォーマンスを発揮する
warning.icon WASM 登場当初は、JavaScript よりも高速である点がメリットとして挙げられていた
しかし、JavaScript 処理系の改善に加え、線形メモリと JavaScript のオブジェクトとの間でデータコピーが発生するぶん WASM のほうが処理速度が遅い ケースもある
そのため、2024 年 10 月現在では、処理速度よりも安定したパフォーマンスのほうに着目されることが多くなった
標準化プロセス
標準化は W3C で行われる
これは、仕様の策定ができるのは WG に限られるという制約があるため
WG は企業が主なメンバーになっているのに対して、CG は個人も多く参加している
仕様の標準化は以下の 6 つのフェーズがある
Phase 0 - Pre-Proposal (CG)
CG に属する個人が WASM に追加したい仕様のアイデアを、GitHub リポジトリの Issue として登録する
Phase 1 - Feature Proposal (CG)
Pre-Proposal のうち、CG から広く興味を得た提案
提案が CG のスコープに含まれることや実現性を検討する
Phase 2 - Proposed Spec Text Available (CG + WG)
仕様を明文化する
Phase 3 - Implementation Phase (CG + WG)
仕様を実装する
これは、標準化するためには 2 つ以上の実装が必要となるため
実装をもとに再度仕様を再検討するケースもある
Phase 4 - Standardize the Feature (WG)
仕様の標準化
WG 内で議論する
Phase 5 - The Feature is Standardized (WG)
追加された仕様の例
メモリ領域に対する操作
JavaScript に存在する BigInt と WASM の符号付き 64 bit 整数との相互変換方法を定めたもの
コンポーネントモデル(Component Model)
長くなったので別ページに切り出した radish-miyazaki.icon
参考