夏休みだョ!WebAssembly Proposal全員集合!!
はじめに
こんにちは。カブクで虚無を担当しているあんどうです。日増しに夏めいて来た今日このごろ、皆さん如何お過ごしでしょうか。私はこの湿気がもう駄目なので週末に北海道に飛ぶ予定でしたが、どうやら台風が来ているようです。困る。
さて、先日参加したW3C Workshop on Web Gamesの「WebAssembly: status, Web IDL bindings, and roadmap」というセッションで、WebAssemblyから直接DOMを触れるようにしようという提案があることを知りました。なかなかアグレッシブな提案に衝撃を受けると共に、そう言えば「WebAssemblyの仕様策定プロセス何も知らんな」とか「今はどんな提案があるんだろう」とかいろいろ疑問が浮かんだのでざっと調べてみました。
なお、ここの内容はEmscripten & WebAssembly night !! #8のLTで話したものとほぼ同じです。次回は9月のTPAC後に開催予定らしいのでみんな参加するといいと思います。
仕様策定プロセス
WebAssemblyの標準化プロセスはこちらにまとまっていますが、W3CやTC39などいわゆるウェブ標準のプロセスとほぼ同じです。まず、コミュニティグループ(CG)でオープンに仕様について議論し、ワーキンググループ(WG)で限られたメンバーが標準化に向けた作業を進めます。
標準化は、まだリポジトリも用意されていない単なるアイデア状態のフェーズ0から標準化作業が完了したフェーズ5まで、全6フェーズに分かれています。以下に各フェーズの大まかな内容をまとめます。なお正式な事前条件、事後条件などについてはドキュメントを参照してください。
- フェーズ0 提案準備(Pre-Proposal) [CG]
- アイデアに対し、コミュニティグループで提案のスコープと実現可能性について投票を行い、問題がなければリポジトリを用意する
- フェーズ1 提案(Feature Proposal) [CG]
- プルリクやイシューを軸に機能の設計について議論する。概要を記した提案書を作成し、大まかな合意を目指す
- フェーズ2 提案書作成(Proposed Spec Text Available) [CG+WG]
- 包括的なテストとその確認が可能なプロトタイプを作成する。参照インタプリタがテストを通過する必要はないが、テストを通過する実装が必要
- フェーズ3 実装(Implementation Phase) [CG+WG]
- 仕様を更新し、参照インタプリタに機能の実装を追加、ツールチェーンに組み込む。コミュニティグループとしては機能について合意に達する
- フェーズ4 標準化準備(Standardize the Feature) [WG]
- エッジケースに関して議論する。仕様について大きな変更が生じる場合はコミュニティグループに差し戻される。ワーキンググループとして合意に達する
- フェーズ5 標準化(The Feature is Standardized) [WG]
- W3Cのリポジトリに登録する
提案
グランドデザイン
個々の提案を見ていく前に、WebAssembly自体がどういうものになろうとしているかをざっくりと理解しておいたほうがいいでしょう。それについてはMozillaの以下の記事にある図が非常によくまとまっています。
https://hacks.mozilla.org/2018/10/webassemblys-post-mvp-future/
現在のWebAssemblyはMVP(Minimum Viable Product)、つまり「かろうじて実用に足る仕様」という位置づけですが、今後は以下の3つの分野で本格的に利用されるようになるであろうと想定されています。
- 本格的なアプリケーション
- JSから呼び出せるライブラリ
- 高級言語のコンパイルターゲット
これから現在提案されている仕様を標準化が近いものから順に紹介しますが、それぞれどの分野をターゲットにした提案なのかを意識すると理解しやすいでしょう。
フェーズ4 標準化準備
フェーズ4の提案はオペコードの追加だけでそれほど面白くありません。(個人の感想です)
- Non-trapping float-to-int conversions
- 浮動小数点数の小数点以下を切り捨てて整数にする際、結果の値が範囲外の場合に対象の型の上限値または下限値を返す
trunc_sat_fmm_sx
命令を追加しようという提案 - Sign-extension operators
- 符号付き整数をより大きなビット数の符号付き整数に変換する
imm.extendm_sx
命令を追加しようという提案
フェーズ3 実装
フェーズ3の提案はプログラミング言語としてのWASMを使いやすくする提案が多いようです。
- Multi-value
- 関数や命令、ブロックで多値を返せるようにしようという提案
(func $swap (param i32 i32) (result i32 i32) (get_local 1) (get_local 0) )
- Reference Types
- 任意のJSの値をglobalもしくはTableで受け取れるように参照型を追加しようという提案
WebIDL Bindingや例外処理の提案で使用 - Tail call
- 現在は末尾呼出し最適化を明示的に禁じているが(私の認識違いかも?)、これを可能にしようという提案
- Bulk memory operations
- パフォーマンス向上を目的にMemoryやTableの内容をまとめて更新する
memory.copy
命令やtable.copy
命令などを追加しようという提案
フェーズ2 提案書作成
フェーズ2の提案は大規模な開発や込み入ったプログラムの開発に使用できそうな提案が多い印象です。
- JavaScript BigInt to WebAssembly i64 integration
- WebAssemblyの
i64
をJSのBigInt
として受け渡せるようにしようという提案 - Threads
- WebWorkerとメインスレッドでWebAssemblyを並列処理できるように、共有メモリや、アトミックなメモリアクセスを追加しようという提案
SharedArrayBufferの巻き添えでペンディング中let memory = new WebAssembly.Memory({initial:1, maximum:1, shared:true}); (func (export "lockMutex") (param $mutexAddr i32) (block $done (loop $retry (call $tryLockMutex (local.get $mutexAddr)) (br_if $done) (i32.atomic.wait (local.get $mutexAddr) ;; mutex address (i32.const 1) ;; expected value (1 => locked) (i64.const -1)) ;; infinite timeout (drop) (br $retry) ) ) )
- ECMAScript module integration
- ES Moduleとしてwasmをインポートできるようにしようという提案
// これが let wasmMod = fetch("./myModule.wasm"); WebAssembly.instantiateStreaming(wasmMod) // こうなる import {foo} from "./myModule.wasm";
- Fixed-width SIMD
- 128ビットのSIMD命令を使用するために
v128
という型と、その操作のためのi8x16.add
、i16x8.add
などの命令を導入しようという提案
フェーズ1 提案
フェーズ1の提案は数も多く内容も多彩です。例外処理やガベージコレクション、WebIDLサポートなど、大それた提案があります。
- Custom Annotation Syntax in the Text Format
- バイナリフォーマットはカスタムセクションに任意のメタデータを持てるが、テキストフォーマットには対応する機能がないのでアノテーションを設定できるようにしようという提案
WebIDL Bindingの提案でも使用module (@name "Gümüsü") (func $lambda (@name "λ") (param $x (@name "α βγ δ") i32) (result i32) (get_local $x)) )
- Exception handling
- 例外を処理するため、
try
、catch
、throw
、rethrow
などの命令を追加しようという提案 - Type Imports
- 参照型のための型定義をインポート/エクスポートできるようにしようという提案
(type $Buf (struct (field $pos i64) (field $buf (array $char)))) (import "buf" "Buf" (type $buf)) (func $readPos (param $f (buf $Buf)) (result i64) ... )
- Garbage collection
- 高級言語の実装やブラウザとのやり取りを容易にするためにGCを導入しようという提案
- Web IDL Bindings
- WebIDLに対応する参照型をWebAssembly側に定義しようという提案
- Type Reflection for WebAssembly JavaScript API
- JavaScript側からWebAssembly内部で定義されている型情報にアクセスできるようにしようという提案
- WebAssembly C and C++ API
- WasmエンジンをC/C++アプリケーションに組み込むためのAPIを定義しようという提案
- Typed Function References
- 関数参照を利用できるようにしようという提案
(type $i32-i32 (func (param i32) (result i32))) (func $hof (param $f (ref $i32-i32)) (result i32) (i32.add (i32.const 10) (call_ref (i32.const 42) (local.get $f))) )
- Feature Detection
- WebAssemblyに機能がサポートされているかどうかを確認する手段を用意しようという提案
- Extended Name Section
- バイナリフォーマットのelemセグメントとdataセグメントにもnameセクションを追加しようという提案
フェーズ0 提案準備
CSPはわかる、funcletはモチベーションがよくわからん、という感じです。
- Web Content Security Policy
- CSPの参照元として
wasm-unsafe-eval
を追加し、WebAssembly.compile
、WebAssembly.instantiate
などもCSPに従うようにしようという提案 - Funclets: Flexible Intraprocedural Control Flow
- 末尾呼出し可能な小関数であるfuncletのシーケンスとしてfunclet regionという制御フローを導入しようという提案
さいごに
EcmaScriptの年初時点での全提案についても「お正月だョ!ECMAScript Proposal全員集合!!」でまとめてあります。合わせてご覧ください。
株式会社カブクでは弊社業務でのWebAssemblyの使いどころを一緒に探してくれるフロントエンドエンジニアを募集しています。
その他の記事
Other Articles
関連職種
Recruit