Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
RustでWasm Runtimeを書いた in WebAssembly night #11
Search
skanehira
September 15, 2023
Programming
0
870
RustでWasm Runtimeを書いた in WebAssembly night #11
https://emsn.connpass.com/event/290430/
skanehira
September 15, 2023
Tweet
Share
More Decks by skanehira
See All by skanehira
Rustから学ぶ 非同期処理の仕組み
skanehira
1
150
about_gorilla.vim.pdf
skanehira
0
97
if let temporary scopeについて
skanehira
0
190
build-debugger-in-rust.pdf
skanehira
1
250
Findy感謝祭2024 LT
skanehira
0
130
Rustではじめる負荷試験
skanehira
6
2.1k
Wellcome Vim World
skanehira
3
650
VimConf 2023 Tiny
skanehira
1
760
Deno Fest 2023
skanehira
0
260
Other Decks in Programming
See All in Programming
旅行プランAIエージェント開発の裏側
ippo012
2
930
速いWebフレームワークを作る
yusukebe
5
1.7k
Updates on MLS on Ruby (and maybe more)
sylph01
1
180
Introducing ReActionView: A new ActionView-compatible ERB Engine @ Rails World 2025, Amsterdam
marcoroth
0
710
私の後悔をAWS DMSで解決した話
hiramax
4
210
機能追加とリーダー業務の類似性
rinchoku
2
1.3k
Platformに“ちょうどいい”責務ってどこ? 関心の熱さにあわせて考える、責務分担のプラクティス
estie
1
140
Azure SRE Agentで運用は楽になるのか?
kkamegawa
0
2.5k
testingを眺める
matumoto
1
140
RDoc meets YARD
okuramasafumi
4
170
Swift Updates - Learn Languages 2025
koher
2
510
API Platform 4.2: Redefining API Development
soyuka
0
110
Featured
See All Featured
Producing Creativity
orderedlist
PRO
347
40k
It's Worth the Effort
3n
187
28k
個人開発の失敗を避けるイケてる考え方 / tips for indie hackers
panda_program
113
20k
Put a Button on it: Removing Barriers to Going Fast.
kastner
60
4k
Practical Orchestrator
shlominoach
190
11k
Building Flexible Design Systems
yeseniaperezcruz
329
39k
Exploring the Power of Turbo Streams & Action Cable | RailsConf2023
kevinliebholz
34
6k
Code Reviewing Like a Champion
maltzj
525
40k
Build your cross-platform service in a week with App Engine
jlugia
231
18k
Designing for Performance
lara
610
69k
Embracing the Ebb and Flow
colly
87
4.8k
Speed Design
sergeychernyshev
32
1.1k
Transcript
RustでWasm Runtimeを書いた (株)テックリード ゴリラ
QSPGJMF \ OBNFΰϦϥ KPC< ΤϯδχΞ ձࣾܦӦ >
MJLFT< 3VTU (P 5ZQF4DSJQU %FOP 7JN 8BTN %PDLFS LT > TOT< 9 5XJUUFS IUUQTUXJUUFSDPNHPSJMMB (JU)VCIUUQTHJUIVCDPNTLBOFIJSB [FOOIUUQT[FOOEFWTLBOFIJSB > >
Wasm Runtimeを書いたモチベ
Wasm 面白そうだけど どう動いているのか よくわからん
実装して完全理解するしかない ↓ 実装してみた https://github.com/skanehira/chibiwasm ※https://www.w3.org/TR/wasm-core-1/ の仕様まで
デモ
あらためて... Wasm(WebAssembly)とは?
https://developer.mozilla.org/ja/docs/WebAssembly より
狭義的にWasmはブラウザでも動く 仮想命令セット ※文脈によってエコシステム周辺も含めてwasmと呼ぶこともある
命令セットはCPU命令の集まり x86・ARMなどがある
仮想命令セットは CPUに依存しない命令セット
RubyやJVMといった仮想マシンで動作する言語は それぞれが定義した仮想命令セットで動いている
Wasmの仮想命令セットは ただのバイトコード
00000000: 0061 736d 0100 0000 0107 0160 027f 7f01 .asm.......`....
00000010: 7f03 0201 000a 0901 0700 2000 2001 6a0b .......... . .j. 00000020: 0a . WATからWasmバイナリを生成
None
Wasm Runtimeは Ruby VMやJVMのような仮想マシン
Wasm Runtimeは スタックベースの仮想マシン
*.wasmが実行されるまでの流れ
1. *.wasmからRustのデータ構造に落とし込む 2. 1のデータ構造から実行用のデータ構造を生成する 3. Wasm Runtimeのメモリの確保や命令処理などを行う
*.wasmのデータ構造
先頭8バイトがmagic number とversion情報 残りが各種セクション情報 各種セクションは実行時に 必要な情報を持つ 8BTNNPEVMF E
NBHJDOVNCFS aBTN WFSTJPO TFDUJPODPEF TFDUJPOTJ[F BYY TFDUJPOEBUB TFDUJPODPEF TFDUJPOTJ[F YY TFDUJPOEBUB EYY
例) type_section 関数シグネチャ情報 code_section 関数の命令群
TFDUJPO5ZQF TFDUJPODPEF TFDUJPOTJ[F B OVNUZQFT C GVOD
D OVNQBSBNT EG J FG J G OVNSFTVMUT G J TFDUJPO$PEF B TFDUJPODPEF TFDUJPOTJ[F OVNGVODUJPOT GVODCPEZTJ[F MPDBMEFDMDPVOU B MPDBMHFU C MPDBMJOEFY D MPDBMHFU E MPDBMJOEFY FB JBEE GC FOE
例) type_section 関数シグネチャ情報 code_section 関数の命令群 import_section 他モジュールからインポートす る関数やメモリなどの情報
code section をデコード処理する例 TFDUJPO$PEF B TFDUJPODPEF TFDUJPOTJ[F
OVNGVODUJPOT GVODCPEZTJ[F MPDBMEFDMDPVOU B MPDBMHFU C MPDBMJOEFY D MPDBMHFU E MPDBMJOEFY FB JBEE GC FOE
実行時データ構造
Store 実行時に必要なインスタンス達を持つ 例)関数やメモリのインスタンス Runtime VMそのものと思ってOK Runtime::stack 処理時の値を保持する Runtime::call_stack 関数呼び出しのフレームを保持する
フレームごとに命令などの情報をもつ
命令処理の実装を説明する前に スタックマシンについて復習
スタックマシン 10 + 13 をスタックを使って計算する場合
これをRustで表現する
*OTUSVDUJPO 8BTNͷ໋ྩ܈ 7BMVF 8BTNͰѻ͑Δ JJɺGͳͲ 3VOUJNFTUBDL
ॲཧ࣌ͷΛอ࣋ 3VOUJNFFYFDVUF ໋ྩΛॲཧ͢Δؔ QD ϓϩάϥϜΧϯλ ࣍ͷ໋ྩͷ൪ʢΠϯσοΫεʣ
'SBNF ؔͷݺͼग़͠ͷʹੜ͢Δ ྫ͑ɺ" # ͷΑ͏ͳؔݺͼग़͠
͕͋Δ߹ɺ" ͷॲཧதʹ# ͷ໋ྩΛ ॲཧ͠ɺͦΕ͕ऴΘͬͨΒ" ʹΔࡍʹ " ͷQDʹ͢ඞཁ͕͋Δ ؔ͝ͱʹQDͱ໋ྩΛ·ͱΊͯ'SBNFͰ ཧ͢Δ͜ͱͰɺݺͼग़͠ݩʹΔͱ͖ ͷॲཧ'SBNFΛΓସ͑Δ͚ͩͰࡁΉ
最終的なFrame
-BCFM JGMPPQͱ͍ͬͨͷ੍ޚߏจΛॲཧ͢ΔͨΊͷใ ྫ͑ελοΫΛר͖ͨ͢ΊͷελοΫϙΠϯλ ͳͲΛ࣋ͭ BSJUZ Γͷ
MPPQΓΛฦ͢͜ͱ͕Ͱ͖ΔͨΊɺ -BCFMBSJUZΛ࣋ͭ MPDBMT ؔͷҾϩʔΧϧมͷ ͦͷଞɺॾʑͷ࣮ͷৄࡉˣͷهࣄΛࢀর IUUQT[FOOEFWTLBOFIJSBBSUJDMFT SVTUXBTNSVOUJNF
ͪͳΈʹ໋ྩͷҎ্͋Δ ͷͰϚΫϩΛۦ࣮ͯ͠ྔΛ͑ͨ 3VTUͷϚΫϩ͜͏͍͏ͱ͖ʹศར
実はWasm Runtimeは 数値の計算とメモリの操作 しかできない
ファイルといったOSのリソース の操作は仕様にない
WebAssembly System Interface 通称 WASI
WASIは雑にいうと システムコールの仕様
POSIX Likeな関数の集まり 例) sock_accept(fd, flags) : ソケット新規接続受け入れ fd_write(fd, iovec_array): fdにデータを書き込む
fd_read(fd, iovec_array) : fdからデータを読み取る
WASIを使えば、ファイルといった OSのリソースを扱えるようになる
つまり... WASIをRuntimeに実装することで ファイルIOの処理が可能になる
WASIはpreview 1と2がある
preview 1の関数一覧 https://github.com/WebAssembly/WASI/blob/main/legacy/preview1/docs.md
文字を出力するにはpreview 1の fd_write()を実装する必要がある
fd_write()はWasm Runtimeが持つ メモリ上のデータをfdに書き込む
ϝϞϦ͔ΒσʔλΛಡΈऔΔ ಡΈऔͬͨόΠτྻΛGEʹ ॻ͖ग़͢
Wasmから見てWASIは wasi_snapshot_preview1という モジュール そのモジュールが持っている fd_write()関数を使う fd_write()を使うとき
ドキュメントを読んでもどう実装したら良いのかさっぱり分からなかった WASIの実装の余談 なので↓のdenoのwasiモジュールを見ながらRustで実装した https://deno.land/std/wasi/snapshot_preview1.ts 今なら、GoのWASI実装を参考にできるかも? https://github.com/golang/go/blob/master/src/net/fd_wasip1.go
宣伝 同人誌「作って理解 Wasm Runtimeのしくみ」を執筆中です Rustで"Hello World"を出力できるWasm RuntimeをRustで実装し ていく本になります 来年のどこかの技術書典などに出せたらと思っています
ありがとうございました