WebAssembly

WebAssembly（ウェブアセンブリ、公式の略称はWasm）は、実行可能ファイルを表現するための可搬なバイナリコード形式（およびそれに対応するテキスト形式）を定め、同時にそのような実行可能プログラムとホスト環境との間のやりとりを容易にするためのソフトウェアインタフェースを提供するものである。 Wasmの当初の目的は、ウェブページ上で高パフォーマンスなアプリケーションを実現することであった。しかし「ウェブ特有の仮定は一切しておらず、ウェブ特有の機能を提供するわけでもないので、他の環境で同様に採用できる」としている。Wasmはオープン標準であり、あらゆるオペレーティングシステム上であらゆる言語をサポートすることを目指している。実際に、最も有名な言語のすべてが、少なくともいくらかのレベルでWasmに対応している。 Wasmは、仮想の命令セットアーキテクチャあるいはプログラミング言語の一種とも捉えられる。多くの場合、C/C++, Rustといったプログラミング言語のコンパイル先としてWasmバイナリが生成され、ウェブブラウザやその他のソフトウェア環境内で、スタックマシンによって実行される。ネイティブコードに近い高速さ、隔離環境でのメモリ安全な実行による安全性、仮想マシンによる可搬性やソースプログラミング言語中立性などを特徴とする。 Wasmは2015年に発表され、2017年3月に初めてリリースされたWebAssemblyは、2019年12月5日にW3C勧告となり、2021年の ACM SIGPLAN のプログラミング言語ソフトウェア賞を受賞した。World Wide Web Consortium (W3C) が技術標準を管理しており、有名な大企業なども加盟する非営利団体「Bytecode Alliance」が貢献している。 WebAssembly という命名は、1950年代にまで遡る「アセンブリ言語」の概念を想起させるためのものであり、アセンブリのようなプログラミングを、Webのクライアントサイド（つまりユーザのWebブラウザを介したユーザのコンピュータ上）で実行される世界に持ち込むことを示唆している。これを実現するために、WebAssemblyは、真のアセンブリ言語に比べて圧倒的にハードウェア非依存でなければならない。 WebAssemblyの最初のアナウンスは2015年6月17日に行われ、2016年3月15日に公開された初のデモは、主要ブラウザ (Firefox, Chromium, Google Chrome, Microsoft Edge) 上でUnityのAngry Botsを動かすものだった。前身となった技術は、Mozillaによる asm.js（英語版）と Google Native Client であり、最初の実装は asm.js の機能セットに基づいて行われた。asm.jsはすでにネイティブに近いコード実行速度を提供しており、WebAssembly非対応の環境やセキュリティ上の理由で無効化している環境での実用可能な代替とみなすことができた。 最初の目標としてCとC++からのコンパイルをサポートすることを目指し、Rustがバージョン1.14以降で、Goがバージョン1.11以降で、Kotlin/Nativeがバージョン0.4以降でで対応するなど、他のプログラミング言語のサポートも進められた。 2017年3月にMVPの設計が完了したことが宣言され、WebAssemblyに標準対応した初のブラウザとなるFirefox 52.0がリリースされた。2017年11月、MozillaはMicrosoft EdgeがWebAssemblyに対応し、すでに対応しているChromeとFirefoxを含め、主要なブラウザすべてでサポートされたことを発表した。2018年2月には、WebAssembly Working Groupが、3つのワーキングドラフト「Core Specification」「JavaScript Interface」「Web API」を公開した。 2019年6月に、Chrome 75は、WebAssemblyスレッドが有効にされた状態でリリースされた。 2019年12月5月に、W3C勧告「WebAssembly Core Specification」が策定され、WebAssemblyは正式なウェブ標準に認定された。 2022年8月から、WebAssembly 2.0がドラフトの状態になり、SIMD関連の多数の命令やv128データ型、関数が多値を返せる機能、大量のメモリの初期化・コピー、などが追加されている。 2023年10月から12月にかけて、Wasmランタイム側でガベージコレクション (GC) に対応する WebAssembly Garbage Collection (WasmGC) が、Chrome, Firefox, Edge の最新版でデフォルトで有効になった。 WebAssembly (Wasm) は当初、Webブラウザでネイティブに近いコード実行速度を実現するために設計されたものの、今ではWebブラウザの枠を出た、より一般的な文脈や用途でも価値があるとみなされている。 Wasm自体は命令セットなどの面を定めるだけであり、Linuxカーネルが提供するようなシステムコール（例: ファイルI/O）やWebブラウザが提供するようなDOMアクセスなどを提供しない。安全性や可搬性はこの特徴に由来する。応用に必要なAPIは別途に定義され、Wasmランタイムがそれを実装することでそれらの機能を提供する。これによってWasmエコシステムは高い拡張性を有する。 2017年11月にMozillaは、Microsoft Edge 16でWebAssemblyがデフォルトで有効になった後、「すべての主要なブラウザでの」Wasm対応を宣言した。この対応にはiOSとAndroidのモバイルWebブラウザも含まれる。 2024年3月 (2024-03)現在[update]。99%のブラウザがWebAssembly（バージョン1.0）をサポートしており、その前身であるasm.js（Safariなどで使えなかった）を上回っている。 バージョン2.0ドラフト標準に由来するいくつかの拡張については対応度は下がりうるが、それでも9割以上のブラウザが既にサポートしていると推測される。 Wasmのランタイム環境 (RE) は、（JVMやFlash VMと同様の）低レベルの仮想スタックマシンであり、ホストアプリケーションに埋め込むことができるため、Webブラウザにとらわれない活用の道があり、WasmtimeやWasmerといったスタンドアローンのランタイムが作られた。 WebAssembly System Interface (WASI) は、Mozillaによって設計された、どのプラットフォームにも移植できるように意図されたシンプルなインタフェース（ABIおよびAPI）である。これは、POSIXライクの機能を提供するもので、例えば「ケーパビリティベースのセキュリティによって制約されたファイルI/O」のようなものを提供する。他にもいくつかのABI/APIが提案されている。WASIは、CapsicumのCloudABIの影響を受けている。 Docker の共同創業者であるソロモン・ハイクスは2019年に、「もし2008年にWASM+WASIが存在していたらDockerを作る必要はなかっただろう、というくらい重要なものだ。サーバ上でのWebAssemblyはコンピューティングの未来だ」と書いた。 WebAssemblyはポータブルなスタックマシンであり、既存のウェブブラウザで広く用いられているJavaScriptと比べ、構文解析と実行が高速になるよう設計されている。WASM specification はWASMの言語仕様および実行ファイル形式を定義する。 Wasmは高水準のアセンブリ言語として設計されている。x64等のアセンブリ言語にみられない特徴として以下がある。 制御命令: if や loop。直接のJUMP命令が無い、安全かつ高水準の制御フローを実現（構造化プログラミング） 関数: 型・ローカル変数・ボディで定義され、call される関数。コードの組織化を実現 ローカル変数: 関数スコープの自動変数。get/set /tee 命令でアクセスでき疑似レジスタとして利用可能 値に定義される型は i32 / i64 / f32 / f64 の4種類である。char/stringは型としてサポートされない。また、高級言語のように関数が構造体型を取り回すようなコードが直接的には記述できない。 デフォルトでは外部と隔離されている（サンドボックス）。計算結果を渡したり外部関数を呼び出したりするために、WASMは imports/exports 機能を提供する。対象となるオブジェクトは関数・テーブル・メモリ・グローバル変数の4種類。exports要素に対象のインデックスを登録することで、WASM外からそのオブジェクトへアクセスできる（関数呼び出しやメモリ読み書き）。またimports要素に対象の名前と型を登録することで、WASM外に存在する対象へのアクセスをWASMランタイムが提供する。 Wasmはバイナリフォーマット（英: binary format）およびテキストフォーマット（英: text format）を定義している。フォーマットの設計方針として Compact / Modular / Efficient / Streamable / Parallelizable / Portable を掲げている。 言語のバイナリ/テキスト表現（例: オペコード）に加え、実行ファイル形式（コンテナフォーマット）を定義する。module が1つの実行ファイルに相当し、マジックナンバー等のメタ情報が冒頭に記述され、関数やexportsなど11種類のセクションが続く。セクションはサイズ情報を持っており、並行処理可能に設計されている。 以下に、C言語のソースコードが、wasmのリニアアセンブリバイトコードとバイナリにそれぞれ変換された例を示す。 内部的には、wasmコンパイラシステムは中間コードを扱うためにS式を使用している。サンプルを以下に示す。 (module (memory 256 256) (export "memory" memory) (type $FUNCSIG$dd (func (param f64) (result f64))) (import $exp "global.Math" "exp" (param f64) (result f64)) (export "doubleExp" $doubleExp) (func $doubleExp (param $0 f64) (result f64) (f64.mul (call_import $exp (get_local $0) ) (f64.const 2) ) ) ) Wasmのバージョン 2.0（ドラフト）には128ビット幅のベクトル型（v128）と、SIMD命令が追加されている。 Wasmはホスト環境に埋め込まれるサンドボックスであり、import/exportを介したホストとの連携によって意味ある結果が得られる。WasmがシンプルなVMである反面として、Wasm-ホスト間の連携にはいくつかのテクニックが必要となる。また各moduleが1つのサンドボックスとして働くため、Wasmモジュール間の連携にも同様のことが言える。 基本的な問題として、Wasm-ホスト間の型システム不一致解消（マーシャリング）を取り扱うことになる。 char/stringは型としてサポートされない。Wasm上で扱うためにはcharをintとして操作し、線形メモリ上にchar配列を構築する形になる。export関数も数値型しか返せないため、stringの表現として線形メモリのオフセットと長さを返し（intなので返せる）これに基づきランタイム側で該当メモリ区間を文字列型として読む、といった工夫が必要となる。あるいはmalloc等の外部アロケータをimportした上で線形メモリの内容を外部メモリへ割り当て、そのアドレス・参照をintでランタイムへ返す必要がある。 Emscripten - 元々asm.js向けであったが、その後、WebAssemblyにも対応した。C言語/C++からWebAssemblyへのコンパイルでは、フロントエンドにclangもしくはそのforkであるfastcomp-clangを、中間層にLLVMもしくはそのforkであるfastcompを、バックエンドにbinaryen (後述)を使用する。なお、LLVMのWebAssembly実装とFastcompのWebAssembly実装は別物である。 GCC asm.js backend - asm.js及びWebAssemblyに対応している。 LLVM - WebAssemblyバックエンドを持ち、WebAssemblyバイナリを直接出力できる。また、LLDによるWebAssemblyバイナリのリンクも可能。LLVM 8.0で正式に対応した。 Binaryen asm2wasm - asm.jsからWebAssemblyテキストへのコンバータ。 s2wasm - LLVMのWebAssembly用テキストアセンブリ (*.s)からWebAssemblyテキストへのコンバータ。 mir2wasm - Rust言語の中間レベルIR (MIR)からWebAssemblyテキストへのコンバータ。 wasm-as - WebAssemblyテキストからWebAssemblyバイナリへのコンバータ。 WABT wat2wasm - WebAssemblyテキストからWebAssemblyバイナリへのコンバータ。 wasm-link - WebAssemblyバイナリのリンカー 仮想マシンの命令セットであるWASMはコンピュータの実行ファイルではないため、そのまま機械語として実行はできない。そのためWASMファイルはランタイムを介し解釈・実行される。ランタイムにはインタプリタ/JITコンパイラ/AOTコンパイラがあり用途に合わせて選択される。 ランタイムはウェブブラウザへの組み込み（JavaScript実行環境からの呼び出し）や独立したWASMネイティブランタイム (例: CLIにおける $ wasmtime foo.wasm) として存在する。 かつて存在したランタイムにはCraneliftコンパイラベースのLucetがある。 WebAssembly Studio - WebベースのWebAssembly向け開発環境。C言語及びRustに対応している。オープンソース。 Qt for WebAssembly - アプリケーションフレームワークのQtをWebAssemblyに移植したもの。2018年4月現在、テクノロジープレビュー。 V8.dev. WebAssembly compilation pipeline. [脚注の使い方] ^ 出典URL: https://github.com/WebAssembly/spec/releases/tag/opam-2.0.0, 閲覧日: 2023年2月11日, 題名: Release 2.0, 出版日: 2022年6月1日 ^ "abbreviated Wasm ... A contraction of “WebAssembly”, not an acronym, hence not using all-caps." WebAssembly Specification Release 1.1 (Draft, Mar 12, 2021) 2021-03-26閲覧 ^ “Understanding WebAssembly text format” (英語). MDN Web Docs. 9 December 2019閲覧。 ^ “Introduction — WebAssembly 1.0”. webassembly.github.io. 18 June 2019閲覧。 “WebAssembly is an open standard...” ^ “Introduction — WebAssembly 1.0”. webassembly.github.io. 18 June 2019閲覧。 “WebAssembly is a ... code format” ^ “Conventions — WebAssembly 1.0”. webassembly.github.io. 17 May 2019閲覧。 “WebAssembly is a programming language that has multiple concrete representations (its binary format and the text format). Both map to a common structure.” ^ “Introduction — WebAssembly 1.0”. webassembly.github.io. 18 June 2019閲覧。 “... this specification is complemented by additional documents defining interfaces to specific embedding environments such as the Web. These will each define a WebAssembly application programming interface (API) suitable for a given environment.” ^ “Introduction — WebAssembly 1.1”. webassembly.github.io. 2021年2月19日閲覧。 “Its main goal is to enable high performance applications on the Web, but it does not make any Web-specific assumptions or provide Web-specific features, so it can be employed in other environments as well.” ^ Haas, Andreas; Rossberg, Andreas; Schuff, Derek L.; Titzer, Ben L.; Holman, Michael; Gohman, Dan; Wagner, Luke; Zakai, Alon et al. (14 June 2017). “Bringing the Web Up to Speed with WebAssembly”. SIGPLAN Notices 52 (6): 185–200. doi:10.1145/3140587.3062363. ISSN 0362-1340. "While the Web is the primary motivation for WebAssembly, nothing in its design depends on the Web or a JavaScript environment. It is an open standard specifically designed for embedding in multiple contexts, and we expect that stand-alone implementations will become available in the future."  ^ “Outside the web: standalone WebAssembly binaries using Emscripten · V8”. v8.dev. 2020年7月28日閲覧。 ^ “Wasmer - The Universal WebAssembly Runtime”. wasmer.io. 2021年2月19日閲覧。 “Compile everything to WebAssembly. Run it on any OS or embed it into other languages.” ^ "At its core, WebAssembly is a virtual instruction set architecture (virtual ISA)." WebAssembly Specification Release 1.1 (Draft, Mar 12, 2021) 2021-03-26閲覧 ^ "The design goals of WebAssembly are the following ... Fast: executes with near native code performance ... Safe: code is validated and executes in a memory-safe, sandboxed environment ... Hardware-independent ... Language-independent ... Platform-independent: can be embedded in browsers, run as a stand-alone VM, or integrated in other environments" WebAssembly Specification Release 1.1 (Draft, Mar 12, 2021) 2021-03-26閲覧 ^ “Programming Languages Software Award”. www.sigplan.org. 2024年3月17日閲覧。 ^ “New Bytecode Alliance Brings the Security, Ubiquity, and Interoperability of the Web to the World of Pervasive Computing” (英語). Mozilla. (12 November 2019). https://blog.mozilla.org/press/2019/11/new-bytecode-alliance-brings-the-security-ubiquity-and-interoperability-of-the-web-to-the-world-of-pervasive-computing/ 27 May 2019閲覧。  ^ Bright, Peter (18 June 2015). “The Web is getting its bytecode: WebAssembly”. Ars Technica. Condé Nast. 2017年3月11日閲覧。 ^ “Launch bug”. GitHub / WebAssembly / design (11 June 2015). 2017年3月11日閲覧。 ^ Wagner, Luke (14 March 2016). “A WebAssembly Milestone: Experimental Support in Multiple Browsers”. Mozilla Hacks. 2017年3月11日閲覧。 ^ Thompson, Seth (15 March 2016). “Experimental support for WebAssembly in V8”. V8 Blog. 2017年3月11日閲覧。 ^ Zhu, Limin (15 March 2016). “Previewing WebAssembly experiments in Microsoft Edge”. Microsoft Edge dev blog. 2017年3月11日閲覧。 ^ “Staring at the Sun: Dalvik vs. ASM.js vs. Native”. blog.mozilla.org (August 2013). 7 December 2019閲覧。 “Even discarding the one score where asm.js did better, it executes at around 70% of the speed of native C++ code.” ^ Arjun, Jangda, Abhinav Powers, Bobby Berger, Emery Guha (2019-01-25). Not So Fast: Analyzing the Performance of WebAssembly vs. Native Code. OCLC 1106328738. http://worldcat.org/oclc/1106328738  ^ a b “WebAssembly High-Level Goals”. GitHub / WebAssembly / design (11 December 2015). 2017年3月11日閲覧。 ^ “Announcing Rust 1.14”. The Rust Programming Language Blog (22 December 2016). 2017年3月11日閲覧。 ^ “Go 1.11 is released”. The Go Blog (24 August 2018). 2018年10月4日閲覧。 ^ “Kotlin/Native v0.4 released: Objective-C interop, WebAssembly and more”. KOTLIN BLOG (16 November 2017). 2019年1月12日閲覧。 ^ “Firefox、ゲームなどをネイティブ並に高速実行する「WebAssembly」を採用”. Impress Watch (2017年3月8日). 2017年3月11日閲覧。 ^ 長岡弥太郎 (2017年11月14日). “WebAssemblyが主要ブラウザでサポート - Mozilla official blog”. マイナビニュース. 2017年11月14日閲覧。 ^ 5 December 2019 — The World Wide Web Consortium (W3C) announced today that the WebAssembly Core Specification is now an official web standard, launching a powerful new language for the Web. W3C (2019). World Wide Web Consortium (W3C) brings a new language to the Web as WebAssembly becomes a W3C Recommendation. ^ “WebAssembly Specification — WebAssembly 2.0 (Draft 2022-09-01)”. webassembly.github.io. 2022年9月9日閲覧。 ^ “WebAssembly 2.0 First Public Working Drafts | W3C News” (英語) (19 April 2022). 2022年9月9日閲覧。 ^ “org/docs/non-web/ Non-Web Embeddings”. WebAssembly. 15 May 2019閲覧。 ^ “Non-Web Embeddings”. GitHub. / WebAssembly. 15 May 2019閲覧。 ^ "This document is concerned with the core ISA layer of WebAssembly. ... It does not, however, define how WebAssembly programs can interact with a specific environment they execute in" WebAssembly Specification Release 1.1 (Draft, Mar 12, 2021) 2021-03-26閲覧 ^ "Instead, this specification is complemented by additional documents defining interfaces to specific embedding environments such as the Web. These will each define a WebAssembly application programming interface (API) suitable for a given environment." WebAssembly Specification Release 1.1 (Draft, Mar 12, 2021) 2021-03-26閲覧 ^ “WebAssembly support now shipping in all major browsers” (英語). The Mozilla Blog. 21 November 2017閲覧。 ^ “Introducing new JavaScript optimizations, WebAssembly, SharedArrayBuffer, and Atomics in EdgeHTML 16” (英語). Microsoft Edge Dev Blog (31 October 2017). 21 November 2017閲覧。 ^ “WebAssembly | Can I use... Support tables for HTML5, CSS3, etc”. canIuse.com. 2024年3月1日閲覧。 ^ “WebAssembly Reference Types | Can I use... Support tables for HTML5, CSS3, etc”. caniuse.com. 2024年3月3日閲覧。 ^ “Outside the web: Standalone WebAssembly binaries using Emscripten - V8”. v8.dev. 2020年7月28日閲覧。 ^ “Wasmer - The Universal WebAssembly Runtime”. wasmer.io. 2021年2月19日閲覧。 ^ “WebAssembly System Interface”. GitHub / WebAssembly. 17 Mar 2024閲覧。 ^ “Additional background on Capabilities” (英語). GitHub. bytecodealliance. 2024年3月17日閲覧。 ^ “Standardizing WASI: A system interface to run WebAssembly outside the web – Mozilla Hacks - the Web developer blog”. Mozilla Hacks – the Web developer blog. 2024年3月17日閲覧。 ^ “WebAssembly C and C++ API”. GitHub / WebAssembly. 2024年3月17日閲覧。 ^ “The "Wasmer" WebAssembly Runtime is Generally Available” (英語). InfoQ. 2021年2月19日閲覧。 ^ “Design Rationale”. GitHub / WebAssembly / design (1 October 2016). 2017年3月11日閲覧。 ^ "Control instructions alter control flow. Control flow is structured ... well-nested constructs ... Branches can only target such constructs." WASM specification 1.0 ^ "func ::= {type typeidx, locals vec(valtype), body expr}" WASM specification 1.0 ^ "Code is organized into separate functions. Each function takes a sequence of values as parameters and returns a sequence of values as results." WASM specification 1.0 ^ "Functions may also declare mutable local variables that are usable as virtual registers." WASM specification 1.0 ^ "valtype ::= i32 | i64 | f32 | f64" WASM specification 1.0 ^ サンプルのソースコードはGitHubのWebAssemblyプロジェクトより https://github.com/WebAssembly/design/blob/master/TextFormat.md ^ http://cultureofdevelopment.com/blog/build-your-first-thing-with-web-assembly/ ^ "2.4.2. Vector Instructions Vector instructions (also known as SIMD instructions, single data multiple value) provide basic operations over values of vector type." W3C. (2022). WebAssembly Core Specification Editor’s Draft, 2 March 2022. ^ a b c d https://github.com/WebAssembly/binaryen ^ https://github.com/pipcet/asmjs/blob/everything/asmjs.org ^ 「LLVM 8.0」登場、WebAssemblyを正式サポート OSDN 2019年3月22日 ^ "V8 first compiles a WebAssembly module with its baseline compiler, Liftoff." V8.dev. WebAssembly compilation pipeline. ^ "This is why, as soon as Liftoff compilation is finished, V8 immediately starts to "tier up" the module by recompiling all functions with TurboFan, the optimizing compiler in V8 for both WebAssembly and JavaScript." V8.dev. WebAssembly compilation pipeline. ^ "SpiderMonkey is the JavaScript and WebAssembly engine in Firefox." wasmtime (2018). Cranelift in SpiderMonkey. ^ "A standalone runtime for WebAssembly" bytecodealliance/wasmtime. RAEDME.md. ^ "Wasmtime is built on the optimizing Cranelift code generator to quickly generate high-quality machine code at runtime." bytecodealliance/wasmtime. RAEDME.md. ^ "The leading WebAssembly Runtime supporting WASI and Emscripten" wasmerio/wasmer. About. ^ "Wasmer supports different compilation frameworks to best suit your needs (LLVM, Cranelift...)." wasmerio/wasmer. About. ^ " you can execute a WebAssembly file" wastime. Using the wasmtime CLI. ^ "Lucet uses, and is developed in collaboration with, the Bytecode Alliance's Cranelift code generator." bytecodealliance/lucet. README.md. ^ "Lucet is a native WebAssembly compiler and runtime." bytecodealliance/lucet. README.md. ^ Aw, all grown up: Mozilla moves WebAssembly into sparsely furnished Studio apartment The Register 2018年4月11日 ^ “New Bytecode Alliance Brings the Security, Ubiquity, and Interoperability of the Web to the World of Pervasive Computing” (英語). Mozilla. (12 November 2019). https://blog.mozilla.org/press/2019/11/new-bytecode-alliance-brings-the-security-ubiquity-and-interoperability-of-the-web-to-the-world-of-pervasive-computing/ 27 May 2019閲覧。  asm.js（英語版） Emscripten 公式ウェブサイト （英語） WebAssembly Community Group （英語） WebAssembly Design （英語）