🧩

Wasm Component Model や WASI の概要を調べる

2024/10/11に公開

WASMの前提知識がない者が WebAssembly Component Model の概要を知ろうとしたときのメモです。

トピック概観

基盤になっているものから順に:

  • WebAssembly (Core) Specification 2.0
    • Wasmのコア仕様(Core Wasm)はかなり低水準なインタフェースしか提供しない。実際のところ各々のWasmを支援するツールチェインがその言語側やブラウザ側などに独自のバインディング用コードをたくさん生成することで成り立っている。Wasmモジュール間の相互運用性は乏しい。
  • WebAssembly Component Model
    • Wasmのための標準の高水準インタフェースを定めることで、Wasmの相互運用性などを実現しようとするもの。
    • WASI 0.2〜もこの Component Model のインタフェースに従って実現される。
  • WASI 0.1 (Preview 1) → 0.2 (Preview 2)
    • WebAssemblyのための標準APIを定めようとするもの(今まではそんなものは何もなかった)。WASI 0.2 は Component Model の仕組みに基づいて実現される。様々なプラットフォームやデバイスでなるべく共通のAPIが使えたらうれしい。
  • その他
    • 各種ツールチェイン、ライブラリ
    • WasmGC(今のところあまり関係ない?)

日本語圏で詳しそうな方:

https://zenn.dev/chikoski

https://gihyo.jp/book/2024/978-4-297-14413-5

Core Wasm

https://webassembly.github.io/spec/core/

ツール

以前からあるツール:

Bytecode AllianceによるRust製ツール&ライブラリ:

  • wasm-tools (Component Modelにも対応。Rustによるwabtのようなもの(?)でありつつ、wasm-toolsのサブクレート群はRustのライブラリとしても使える) https://github.com/bytecodealliance/wasm-tools - CLI and Rust libraries for low-level manipulation of WebAssembly modules

モジュールの構造(概要)

モジュール: https://webassembly.github.io/spec/core/syntax/modules.html

Core specではwasmのルート要素はモジュール。モジュール(テキスト形式)がもつ要素は:

  • type - 関数の型を定義する
  • func - 関数
  • table - reftype (funcref, externref) のテーブル。関数の間接呼び出しに使われる。
  • memory - メモリ
  • global - グローバル変数 (const or mut)
  • start - モジュール初期化後に実行される関数を指定できる
  • elem - テーブルの初期値を設定する
  • data - データセグメント。メモリの指定範囲に初期値を設定する
  • export - func, table, mem, global のエクスポート
  • import - func, table, mem, global のインポート

ちなみに、Wasm Component Model ではルート要素は Module でなく Component になり、まったく違う構造になる。

Wasm - Feature Extensions

Wasm 2.0 の変更点(現時点での): https://webassembly.github.io/spec/core/appendix/changes.html

Wasmの拡張機能のサポート状況:

WebAssembly Component Model

YouTube: Keynote: What is a Component (and Why)? - Luke Wagner, Distinguished Engineer, Fastly

Wasm 同士を組み合わせて使うことは難しかった。Core Wasm自体は非常に低水準なインタフェースしか持っておらず、高水準なインタフェースは標準化されていなかった。Wasm間の相互運用性は非常に乏しい。

そこで、Wasmのうえに高水準な標準インターフェースを定めようとするのが Wasm Component Model。

WASI 0.2もこの Component Model に基いて作られる。

WIT = WebAssembly Interface Type (IDL)

WebAssembly Component Model におけるインタフェース定義言語 (IDL)

https://zenn.dev/chikoski/articles/webassembly-interface-type-101

WITをもとに各言語のBindingsを生成できる。

WITに登場する概念:

  • World
    • component が従うインタフェースのセットを定める。当該の component のWorldが、対象のWorldに比べて import が過少だったり export が過剰だったりしても、そのWorldには準拠しているとみなせる。
    • World は、 Interface を import, export してもいいし、World に 関数宣言を直接置いてもいい
  • Interface
    • 再利用可能なインタフェースを定める
  • Package
    • レジストリに公開するときの単位
  • その他、データ型の定義など。

Registry

コンポーネントレジストリの仕様 warg が開発されている。

Registry(認証付きのパッケージインデクス)vs Repository

Component Model 周りの開発ツール

Bytecode Alliance が crates.io に登録したライブラリ&ツールの一覧 → https://crates.io/teams/github:bytecodealliance:wasmtime-publish?sort=new

基礎ツール&ライブラリ

各言語において

Warg 関係

WAC (WebAssembly Compositions)

components を合成(どのインポートにどのエクスポートを繋いで...)するための言語。witの拡張:

Component Modelの構成要素 (概要)

https://github.com/WebAssembly/component-model/blob/main/design/mvp/Explainer.md#grammar

  • core module - Core Specのmodule
  • core instance - インスタンス (とは何?) (core が付いているのは、モジュールを結合する仕組みとしてCore Specに入れたかったためのようだけど...今のところ保留されている模様?)
    • moduleのインスタンス化または inlineexport の列
  • core type - Core Specのtype。関数だけでなくモジュールも扱えるように拡張されている。
  • component - コンポーネントはコンポーネントをもてる(入れ子にできる)。
  • instance - core:instanceの参照
  • alias - 他のコンポーネントやモジュールがexportする定義を自コンポーネントに取り込む(?)
  • type - Component Modelの型定義
  • canon - Core wasmのfuncをCanonical ABIなfuncで包む、あるいはその逆をする。
  • start - module の start のようなもの。少し異なる点として、引数および戻り値の格納先としてComponentのvalueを使えたり、初期化中の複数時点において実行できたり。
  • import, export - インポート・エクスポート
    • Coreの、モジュール、関数型
    • Component Modelの、値、型、関数、コンポーネント、インスタンス
    • モジュールと違って、メモリを共有するなどはできない(サンドボックスの強化。WasmGCを使うコンポーネントと従来通りの線形メモリなコンポーネントの連携。など)。

Component Modelの値

値型(コピー渡し)とリソース型(ハンドル渡し)がある。

値型(コピー渡し):

  • bool, s8, s16, s32, s64, u8, u16, u32, u64, f32, f64
  • char — Unicode Scalar Value
  • record — 名前付きタプル (特殊形: tuple, flags)
  • variant — Tagged Unions (特殊形: enum, option, result)
  • list — シーケンス (特殊形: string = list char)

リソース型(ハンドル渡し)。リソースの実体は各コンポーネントのインスタンス内にあり、直接触れることはできない。あくまでもハンドルで参照する。

  • own — 所有しているリソースのハンドル。ドロップ時に解放処理 (dtor) を呼ばなければならない
  • borrow — 借用しているリソースのハンドル。現在のexport callを超えた取り回しをしてはならない。

リソースはコンポーネントインスタンスごとに用意されるハンドルテーブルで管理される。ハンドルテーブルは u32 のハンドル値を u32(たいていはメモリアドレス?)に変換するもの。

関連記事

https://zenn.dev/mizchi/articles/wasm-component-model-futures

WASI 0.2

https://github.com/WebAssembly/WASI

WASI 0.1 (Preview 1。古いWASI) はWASIの初期開発段階。すでに広く使われていて、対応しているランタイムも多い。WASI 0.1 は WITX というIDLを使っていた。WITXは、WebAssembly Text Format のうちimportとexportだけを持つようなもの。WASIリポジトリのlegacyに残っている。

WASI 0.2 (Preview 2) からは、独自のIDLでなく、今後の標準技術となる WebAssembly Component Model に従う。Component Model による標準化の恩恵をそのまま受けられる。言いかえれば、WASIの役割は、Component Modelにおいて「様々なWorldで一般的に使われるインタフェース(ファイルシステム、etc.)を標準化すること」である。

WASI 0.3 (Preview 3) は async まわり (future, stream) のサポートを目指す?など → 0.3 が WASI version 1 として標準化される予定?

wasi.dev

解説サイト https://wasi.dev/ (内容はまだあまりない)

wasi.dev が語る夢:

  • 「言語間をつなぐためにHTTPベースのマイクロサービスのような不確かなインタフェースは要らなくなる」
  • 「プラグイン機構のあるアプリケーションはみんなWASI使えばいいと信じてる」
  • 「複数の言語にSDKを提供するプロジェクトにも適する」

誰のためのもの?

  • web app
  • plugins
  • serverless functions
  • user-defined functions in database
  • embedded controller
  • sidecar networking filters
  • etc.

WASIに対応しているランタイム:

Wasmtime, WAMR, WasmEdge, wazero, Wasmer, wasmi, wasm3、など

  • WAMR -> IoT, Embedded, Edge, etc.
  • Wasmtime -> server-side, non-web embeddings, etc.

WASI 0.2

WASI 0.2 以降の WASI は WebAssembly Component Model に基づく。つまり WASI は WIT (WebAssembly Interface Type) で定められる。WASIの具体的な実装はそれぞれの環境が提供する。

WASI Preview 2 は以下のAPIを含んでいる:

  • wasi:io 0.2
  • wasi:clocks 0.2
  • wasi:random 0.2
  • wasi:filesystem 0.2
  • wasi:sockets 0.2
  • wasi:cli 0.2
  • wasi:http 0.2

その他の未成熟なPhaseのAPI一覧: https://github.com/WebAssembly/WASI/blob/main/Proposals.md

API Proposals

提案されているAPIは、 WASI GitHub repository にある。

Wasm Runtime

事例

Component Model / WASI

その他Wasm

トーク

https://www.youtube.com/results?search_query=webassembly+component+model

Keynote: What is a Component (and Why)? - Luke Wagner, Distinguished Engineer, Fastly

https://www.youtube.com/watch?v=tAACYA1Mwv4

  • a component is an (emerging) standard portable lightweight finely-sandboxed cross-language compositional module.
  • components:
    • SDKs for free -- "app" と "platform" をつなぐための大量の仕事が要らなくなる。なおかつ任意の言語に対応できる。
    • secure polyglot packages -- 異なる言語の部品を自由に組み合わせられる +強力なサンドボックス
    • modularity without microservices
    • virtual platform layering -- インタフェースによる、低オーバヘッドで強力な分離 → プラットフォームのレイヤ分け

WebAssembly Component Model: What? How? And why you should not ignore it! by Thorsten Hans @ Wasm IO

https://www.youtube.com/watch?v=NFbjQNqWi94

The next evolution of WebAssembly - the component model

https://www.youtube.com/watch?v=MWPNMOVkm2Y

Deconstructing WebAssembly Components by Ryan Levick @ Wasm I/O 2024

https://www.youtube.com/watch?v=zqfF7Ssa2QI

Keynote: View from Above: A Birds-eye View of the Wasm Landscape and Where... Bailey Elizabeth Hayes

https://www.youtube.com/watch?v=7Pk1Exrqp50

Wasmコンポーネントモデル、完成間近!WebAssemblyの最新動向についてchikoskiさんに聞いてきた!

https://www.youtube.com/watch?v=whJLWdHLssg

MIERUNEのZennブログ

Discussion