Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Wasmの今とこれから

Avatar for Tan1 Tan1
July 02, 2024
8

 Wasmの今とこれから

社内勉強会で使用

Avatar for Tan1

Tan1

July 02, 2024

Transcript

  1. WASM とは WebAssembly( 略称: Wasm) は、スタックベースの仮想マシンのため のバイナリ命令フォーマットです。Wasm は、プログラミング言語の ポータブルなコンパイルターゲットとして設計されており、クライア ントおよびサーバーアプリケーションのWeb

    上での展開を可能にしま す。(DeepL) WebAssembly (abbreviated Wasm) is a binary instruction format for a stack-based virtual machine. Wasm is designed as a portable compilation target for programming languages, enabling deployment on the web for client and server applications. https://webassembly.org/ “ “ 2
  2. WASM とは JavaScript に続くWeb 言語としての紹介されることが多い ( しかし現状はJS 無しではブラウザ上で動かせない) 歴史については以下のまとめがわかりやすい https://zenn.dev/hodagi/articles/4925afbeb3c4dc

    現在は1.0 でインストールされているブラウザの96% がサポートしてい る https://caniuse.com/wasm 2.0 は現在Draft https://webassembly.github.io/spec/core/ 3
  3. WASI WebAssembly System Interface は、モノリシックな標準システムイン ターフェイスではなく、標準化されたAPI のモジュラーコレクションで ある。どのAPI も、準拠したランタイムを持つために実装することを 要求されることはありません。その代わり、ホスト環境は自分たちの

    ユースケースにとって意味のあるAPI を選択することができます。 (DeepL) The WebAssembly System Interface is not a monolithic standard system interface, but is instead a modular collection of standardized APIs. None of the APIs are required to be implemented to have a compliant runtime. Instead, host environments can choose which APIs make sense for their use cases. https://github.com/WebAssembly/WASI “ “ 5
  4. WASI 現在はPreview1 がリリースされており、一般的にはPreview1 を元にし た開発がメインとなっている( 本番運用しているプロジェクトあり) go1.21 で対応されるwasi 対応もPreview1 を使用

    https://tip.golang.org/doc/go1.21 現在はPreview2 の標準化が進められている 今後API が変更されてもライブラリなどの手法によって過去のAPI を呼 び出すことができるようになると期待しているとのこと (Bytecode Alliance にてPreview2 対応時にPreview1 対応のバイナリを Preview2 対応に変換するツールの提供が予定されている) 6
  5. ランタイム wasmtime bytecode alliance Rust wasmedge Cloud native, edge computing,

    decentralized. serverless C++ wazero zero dependency runtime Go wasmer wasmerio Rust . 9
  6. Bytecode Alliance Bytecode Alliance は、WebAssembly やWebAssembly System Interface (WASI) などの標準をベースに、安全な新しいソフトウェア基

    盤を作ることを目的とした非営利団体です。 私たちは、すべてのプラットフォームでセキュアバイデフォルトの WebAssembly エコシステムを実現するビジョンを掲げています。 (DeepL) The Bytecode Alliance is a nonprofit organization dedicated to creating secure new software foundations, building on standards such as WebAssembly and WebAssembly System Interface (WASI). We have a vision for a secure-by-default WebAssembly ecosystem for all platforms. https://bytecodealliance.org/ “ “ . 10
  7. Bytecode Alliance プロジェクト Wasmtime wasm 専用ランタイム Rust/C/Python/.NET/Go/Bash/Ruby/Elixir に 組み込むことができる Cranelift

    主にwasm 向けのコンパイラ WAMR (WebAssembly Micro Runtime) 軽量のインタプリタベースのwasm ランタイム 組み込みやIoT など向け . 11
  8. WASM の仕様 値の種類 num, vec, ref テーブル 関数やグローバル変数の参照配列 IDL: WIT

    (Wasm Interface Type) WebAssembly Component Model に統合 https://github.com/WebAssembly/component- model/blob/main/design/mvp/WIT.md 全体的な標準化されている内容としては以下 https://webassembly.github.io/spec/core/exec/runtime.html . 14
  9. WASM の仕様 基本的にコードとしての単位はmodule (module (func $add (param $lhs i32) (param

    $rhs i32) (result i32) local.get $lhs local.get $rhs i32.add) (export "add" (func $add)) ) wasm の実行はスタックマシンとして定義されます。スタックマシンの基本的な考え方は、すべ ての命令がスタックから特定の数の i32/i64/f32/f64 値をプッシュ、ポップするようにすること です。 https://developer.mozilla.org/ja/docs/WebAssembly/Understanding_the_text_format# スタッ クマシン “ “ 引用: https://developer.mozilla.org/ja/docs/WebAssembly/Understanding_the_text_format 16
  10. WASM の仕様 別の関数を呼び出す場合 (module (func $getAnswer (result i32) i32.const 42)

    (func (export "getAnswerPlus1") (result i32) call $getAnswer i32.const 1 i32.add)) 引用: https://developer.mozilla.org/ja/docs/WebAssembly/Understanding_the_text_format 17
  11. WASM の仕様 複数の値を返す (module (func $get_two_numbers (result i32 i32) i32.const

    1 i32.const 2 ) (func (export "add_two_numbers") (result i32) call $get_two_numbers i32.add ) ) 引用: https://developer.mozilla.org/ja/docs/WebAssembly/Understanding_the_text_format 18
  12. WASM の仕様 メモリはページという単位で表現され、1 ページ = 64KB module 間での共有も可能 JavaScript 上だと通常はArrayBuffer

    で共有メモリにすると SharedArrayBuffer になる 以下は 初期10 ページ、最大100 ページ, 共有可能としての定義 (640KB ~ 6.4MB) let memory = new WebAssembly.Memory({initial:10, maximum:100, shared: true}); 引用: https://developer.mozilla.org/ja/docs/WebAssembly/Understanding_the_text_format 19
  13. WASM の仕様 var memory = new WebAssembly.Memory({initial:1}); var importObject =

    { console: { log: consoleLogString }, js: { mem: memory } }; WebAssembly.instantiateStreaming(fetch('logger2.wasm'), importObject) .then(obj => { obj.instance.exports.writeHi(); }); function consoleLogString(offset, length) { var bytes = new Uint8Array(memory.buffer, offset, length); var string = new TextDecoder('utf8').decode(bytes); console.log(string); } 引用: https://developer.mozilla.org/ja/docs/WebAssembly/Understanding_the_text_format 20
  14. WASM の仕様 (module (import "console" "log" (func $log (param i32

    i32))) (import "js" "mem" (memory 1)) (data (i32.const 0) "Hi") (func (export "writeHi") i32.const 0 ;; pass offset 0 to log i32.const 2 ;; pass length 2 to log call $log)) 引用: https://developer.mozilla.org/ja/docs/WebAssembly/Understanding_the_text_format 21
  15. WASM の仕様 テーブルとはWebAssembly コードからインデックスでアクセスでき るリサイズ可能な参照の配列 WebAssembly は anyfunc 型 (

    任意のシグニチャの関数を保持できるため "any") を追加すること ができましたが、あいにくセキュリティ上の理由から anyfunc 型は線形メモリーに格納できませ んでした。線形メモリーは格納された値の生の内容をバイト列として公開し、これによって wasm コンテンツが生の関数ポインターを自由に観察できて破損させることができてしまいま す。これはウェブ上では許可できません。 “ “ 解決方法は関数参照をテーブルに格納し、代わりにテーブルのインデックスを渡すことでした。 これは単なる i32 値です。call_indirect のオペランドは単純に i32 のインデックス値にすること ができます。 “ “ 引用: https://developer.mozilla.org/ja/docs/WebAssembly/Understanding_the_text_format 22
  16. WASM の仕様 テーブルの定義 (module (table 2 funcref) ;; 初期サイズ2 で要素型がの関数参照であることの宣言

    (elem (i32.const 0) $f1 $f2) ;; オフセット0 でf1, f2 の順に参照の格納 (func $f1 (result i32) i32.const 42) (func $f2 (result i32) i32.const 13) ... ) 引用: https://developer.mozilla.org/ja/docs/WebAssembly/Understanding_the_text_format 23
  17. WASM の仕様 function() { // table section var tbl =

    new WebAssembly.Table({initial:2, element:"anyfunc"}); // function sections: var f1 = ... /* some imported WebAssembly function */ var f2 = ... /* some imported WebAssembly function */ // elem section tbl.set(0, f1); tbl.set(1, f2); }; 引用: https://developer.mozilla.org/ja/docs/WebAssembly/Understanding_the_text_format 24
  18. WASM の仕様 (type $return_i32 (func (result i32))) ;; i32 ではない場合は型チェックに失敗

    (func (export "callByIndex") (param $i i32) (result i32) local.get $i call_indirect (type $return_i32)) 引用: https://developer.mozilla.org/ja/docs/WebAssembly/Understanding_the_text_format 25
  19. WASM の仕様 WIT による定義 (Interface) interface host { log: func(msg:

    string) } コンポーネントにimport (component (import "host" (instance $host (export "log" (func (param "msg" string))) )) ) . 26
  20. WASM の仕様 interface wasi-fs { use pkg.types.{errno} record stat {

    ino: u64, size: u64, // ... } stat-file: func(path: string) -> result<stat, errno> } . 27
  21. WASM の仕様 World (import とexport を行う最上位定義) world my-world { import

    host: interface { log: func(param: string) } export run: func() } (type $my-world (component (import "host" (instance (export "log" (func (param "param" string))) )) (export "run" (func)) )) . 28
  22. WASM の仕様 package wasi:cli world command { import wasi:clocks/wall-clock ...

    import stderr export run } 各種ツール vscode-wit vscode 拡張機能 wit-deps 依存関係周りのマネージャ . 29
  23. WASI Preview1 -> Preview2 Preview1 はPOSIX like な最小限のAPI proc_exit, fd_write,

    environ_get etc.. Preview2 でPreview1 を超える実装が進められており、目玉として Compoenent model の強化がある コンポーネント レジストリ WARG (WebAssembly registry) プロトコル https://warg.io/ . 30
  24. Cloud Cloudflare Workers Amazon CloudFront Deno Deploy Fastly Compute@Edge AKS

    (WasmNodePoolPreview) wasi-cloud-core World が現在提案中 Preview2 が出たら各大手Cloud も対応をするかも? https://github.com/WebAssembly/WASI/issues/520 . 31