# Phase 15.8: LLVM→WASM実装(WebAssembly出力) **期間**: 2025-10-01 ~ 2025-10-22 (3週間) **前提**: Phase 15.7完了(MIR18命令凍結) **目標**: MIR18命令をWASMに変換し、ブラウザ/エッジ環境で実行可能にする --- ## 🎯 **目的と範囲** ### **主目的** 1. **LLVM→WASM変換パイプライン構築** - llvmlite経由でLLVM IR生成 - LLVM toolchain(llc, wasm-ld)でWASM変換 - クリーンなMIR18命令セットでWASM実装 2. **ブラウザ/エッジ環境対応** - WASI(WebAssembly System Interface)基本対応 - Node.js/Deno runtime対応 - 基本I/O(print, error)動作確認 3. **Parity確認** - VM/LLVM/WASMで同一出力 - スモークテスト全グリーン維持 ### **非目標(Phase 16以降に延期)** - ❌ WASM GC統合(WASM GC proposal待ち) - ❌ 最適化・バンドルサイズ削減(Phase 17) - ❌ フル非同期runtime(Promise完全統合はPhase 17) - ❌ DOM API連携(Phase 18) --- ## 📊 **技術スタック** ### **ビルドチェーン** ``` MIR(JSON v0) ↓ (llvmlite Python) LLVM IR (.ll) ↓ (llc --march=wasm32) WASM Object (.o) ↓ (wasm-ld) WASM Binary (.wasm) ↓ (Node.js/Deno/Browser) 実行 ``` ### **依存関係** - **必須**: - Python 3.8+ + llvmlite - LLVM toolchain 14+ (llc, wasm-ld) - Node.js 18+ or Deno 1.30+(テスト用) - **オプション**: - wabt tools(wasm2wat, wat2wasm - デバッグ用) - wasm-opt(最適化 - Phase 17) --- ## 🗓️ **タイムラインと成果物** ### **Week 1: LLVM→WASM変換パイプライン** (2025-10-01 ~ 10-07) ✅ **完了** #### 成果物 - ✅ `tools/build_wasm.sh` - WASMビルドスクリプト - ✅ `tools/wasm_runner.js` - Node.js実行確認スクリプト - ✅ `tools/test_wasm_init.sh` - 統合テストスクリプト(Phase 1.1+1.2+1.3) - ✅ `src/llvm_py/llvm_builder.py` - WASM target対応(wasm32-unknown-wasi) - ✅ **重要発見**: llvmliteだけでWASM生成可能(LLC/wasm-ld不要) ### **Week 2: MIR命令実装 + PHI処理** (2025-10-08 ~ 10-14) ✅ **完了** #### 成果物 - ✅ WASI runtime実装(fd_write, proc_exit) - ✅ 文字列constants処理(グローバルリテラル生成) - ✅ binop全演算WASM動作確認 - ✅ 箱理論LLVM/WASM分離設計(targets/モジュール) - ✅ 制御フロー完全動作(compare/branch/jump) - ✅ 回帰テスト体制確立(3スモークテスト) ### **Week 3: selfhost統合 + PHI修正** (2025-10-15 ~ 10-21) ✅ **完了** #### 成果物 - ✅ **selfhostブランチ統合完了** 🎉 - PHI統一ポリシー適用(wiring.py) - PyVM values[]対応(ops_core.py) - call.py resolver優先順序変更 - WASMツール強化(wasm_inspect.py, wasm_runner.js) - ✅ **PHI incoming dict形式完全対応** - common.py: dict/array両形式サポート - analysis.py/tagging.py: インデント修正 - phi_handler.py: import修正 - wiring.py: 自己ループPHI対応 - ✅ **if-PHI完全動作**: 200返却成功 🎉 #### 🐛 **残存問題** - **loop-PHI重複生成**: PhiHandlerが自己ループforward reference未対応 - `phi_2.1`(不完全)と`phi_2`(完全)の重複 - 対策: ChatGPT報告(PhiHandler自己ループ対応) - 📝 `apps/tests/hello_wasm.hkr` - 保留(Week 2で関数エクスポート解決後) **Week 1完了報告**: - 🎉 llvmliteだけでWASMバイナリ生成成功(LLC/wasm-ld不要) - ✅ Native/WASMコンパイル両対応(--target native/wasm32) - ✅ WASM triple検証PASS(wasm32-unknown-wasi) - ⚠️ 関数エクスポート制限(LLVM toolchain or wabt後処理で解決予定) --- ### **Week 2: MIR18命令WASM変換完成** (2025-10-08 ~ 10-14) ✅ **Week 2完了!** (2025-10-01) #### 目標 - MIR18命令すべてWASM変換対応 - Const, BinOp, Branch, Jump, Return, Phi動作確認 #### Week 2実績(2025-10-01完了) **🎉 予定以上の成果達成!** **Phase 2.1-2.3完了**: 1. ✅ **関数エクスポート完全解決** - wasm_add_export.py実装(Python自己完結型) - WASI runtime実装(fd_write, proc_exit) - wasm_runner.js更新(BigInt対応) 2. ✅ **Hello World WASM実行成功** - "Hello, WASM!" 完全出力確認 - 文字列constants処理実装(40行追加) **Phase 2.4-2.6完了**: 3. ✅ **binop全演算WASM動作確認** - 算術演算: +, -, *, /, % - ビット演算: &, |, ^, <<, >> - テスト: 44 = 15+12+12+5 ✓ 4. ✅ **制御フロー完全動作** - compare演算: 10 > 5 = true (1) → 100 ✓ - branch分岐: if (10 > 5) then 100 else 200 → 100 ✓ - jump無条件: jump to block → 42 ✓ **Phase 2.7完了**: 5. ✅ **スモークテスト整備** - arithmetic_smoke.json(算術演算) - compare_smoke.json(比較演算) - control_flow_smoke.json(制御フロー) - run_wasm_smoke_tests.sh(一括実行) **Phase 3.1完了**: 6. ✅ **PHI処理完全修正** - 根本原因3つ特定・解決 - PhiHandler箱化実装(197行) - InstructionContext箱化(98行) - if文PHIテスト完全成功 **Phase 3.2完了** (2025-10-01): 7. ✅ **PHI 'values'形式統一** - selfhostブランチから移植完了 - "incoming": [[v,b]] → "values": [{"value":v, "block":b}] - 後方互換性確保(incoming_pairs_vb) - WASM生成成功(535バイト) #### 残タスク(Week 3へ繰越) 1. ⏸️ **ループPHI実装** - while/loop with PHI - 複雑制御フロー(nested loops) 2. ⏸️ **メモリ命令対応** (Load, Store) 3. ⏸️ **Box命令拡充** (MirCall完全対応) 4. ⏸️ **ベンチマークシステム構築** #### 成果物 ✅ - ✅ `tools/wasm_add_export.py`: 関数エクスポートツール - ✅ `src/llvm_py/phi_wiring/common.py`: incoming_pairs_vb実装 - ✅ `src/llvm_py/phi_wiring/analysis.py`: values形式対応 - ✅ スモークテスト3本(arithmetic/compare/control_flow) - ✅ run_wasm_smoke_tests.sh: 一括実行スクリプト --- ### **Week 3: ループPHI + ベンチマーク + Parity確認** (2025-10-02 ~ 10-08) #### 目標 - ループPHI実装完成 - ベンチマークシステム構築 - VM/LLVM/WASMパリティ確認 #### Phase 3.3: ループPHI実装(調査中) 🔥 **目標**: while/loopでのPHI命令完全動作 **✅ 実装完了**: 1. **ループPHIテスト作成完了** - ✅ test_phi_loop.json: シンプルwhile(counter PHI) - ⏸️ test_phi_nested.json: ネストループ(2重PHI) 2. **PHI wiring完全実装** - ✅ ループback-edge対応(PhiHandler.incomplete_phis) - ✅ 複数predecessor処理(process_phi_instructions) - ✅ forward reference解決(complete_incomplete_phis) **🐛 発見された問題** (2025-10-02): - **LLVM IR構文エラー**: `phi i64 [0, %"bb0"]` ← 生の数値 - **期待**: `phi i64 [%const_1, %"bb0"]` ← Constant参照 - **原因仮説**: llvmlite の phi.add_incoming() 動作、または block_end_values 取得問題 - **次の調査**: val の型確認、llvmlite 内部動作調査 **📋 残タスク**: 1. ⏸️ LLVM IR構文エラー修正 2. ⏸️ test_phi_nested.json作成 3. ⏸️ WASM実行成功確認(0→1→2→...→10) #### Phase 3.4: ベンチマークシステム構築 ✅ **完了!** (2025-10-03) **✅ 達成事項**: 1. **Hakoベンチマーク作成**: apps/benchmarks/wasm/basic/{factorial,fibonacci,sum_loop}.hako 2. **実行スクリプト**: tools/run_wasm_benchmarks.sh(Hako→MIR→WASM完全パイプライン) 3. **手書きベンチマーク**: 7/7テストPASS(i32範囲内で安定動作) 4. **ベンチマークガイド**: docs/guides/wasm-benchmarks.md **🚨 Hakoコンパイラバグ発見**: - **問題**: 不正なPHI命令生成(到達不能ブロックがPHI predecessorに含まれる) - **再現**: tmp/phi_bug_minimal.{hako,json,ll} - **対処**: ✅ selfhostブランチでがちがちに修正完了 → マージ完了! **📊 WASM対応状況(MIR18命令)**: - ✅ **実装済み(8/18)**: const, binop, compare, branch, jump, ret, phi, copy - ❌ **未実装(10/18)**: call, boxcall, newbox, load/store, externcall(一部), typeop, safepoint, barrier, loopform, unop - ⚠️ **制限**: i64オーバーフロー、StringBox操作未対応 **🎉 手書きベンチマーク成功**: factorial_12/power_2_30/sum_10k全PASS --- #### Phase 3.4(当初計画) **ディレクトリ構造**: ``` apps/benchmarks/ wasm/ basic/ factorial.nyash # 階乗計算(再帰) fibonacci.nyash # フィボナッチ(再帰) sum_loop.nyash # ループ合計 array/ array_push.nyash # 配列push操作 array_search.nyash # 線形探索 array_sort.nyash # バブルソート string/ string_concat.nyash # 文字列結合 string_repeat.nyash # 文字列繰り返し control/ nested_if.nyash # 深いif-else switch_case.nyash # match式ベンチ call/ mutual_recursion.nyash # 相互再帰 deep_call.nyash # 深い関数呼び出し ``` **実装計画**: 1. **基本ベンチ3本** (P0) - factorial(20): 再帰深さ確認 - fibonacci(30): 指数的再帰 - sum_loop(100000): ループPHI性能 2. **配列ベンチ2本** (P1) - array_push(1000): メモリ確認 - array_search(1000): 線形探索 3. **制御ベンチ1本** (P2) - nested_if(10): 分岐予測 **ベンチマーク実行**: ```bash # 一括ベンチマーク ./tools/run_wasm_benchmarks.sh # 個別実行 ./tools/build_wasm.sh apps/benchmarks/wasm/basic/factorial.nyash -o /tmp/factorial.wasm node tools/wasm_runner.js /tmp/factorial.wasm ``` #### Phase 3.5: Parity確認 1. **WASI runtime完全連携** - fd_write (print) - ✅ 完了 - fd_read (基本入力 - optional) - clock_time_get (now関数) 2. **Parity テスト** - 既存quickスモーク → WASM変換 - VM/LLVM/WASM同一出力確認 3. **ドキュメント整備** - WASM実行ガイド - ベンチマークガイド - トラブルシューティング #### 成果物 - ✅ test_phi_loop.json: ループPHIテスト - ✅ apps/benchmarks/wasm/: ベンチマークスイート - ✅ tools/run_wasm_benchmarks.sh: ベンチマーク実行スクリプト - ✅ docs/guides/wasm-benchmarks.md: ベンチマークガイド - ⏸️ `tools/smokes/v2/profiles/wasm/`: WASM専用スモークプロファイル(Week 4) - ⏸️ `docs/guides/wasm-execution.md`: WASM実行ガイド(Week 4) - ⏸️ Parity確認レポート(VM/LLVM/WASM)(Week 4) --- ### **Week 3総括** (2025-10-03完了) 🎉 **達成事項**: - 🏆 **selfhostブランチ統合**: PHI生成バグがちがちに修正 - 🏆 **ベンチマークシステム構築完了**: 手書きMIR JSON 7/7 PASS - 🏆 **Hakoベンチマーク作成**: factorial/fibonacci/sum_loop.hako - 🏆 **ガイドドキュメント完成**: docs/guides/wasm-benchmarks.md - 📝 **バグ再現コード**: tmp/phi_bug_minimal.{hako,json,ll} **重要発見**: - ✅ PHI修正完璧(到達不能predecessor除外) - ⚠️ **MIR18命令対応は8/18のみ**(call/boxcall/newbox等未実装) - ⚠️ Hakoベンチマークは**call命令実装待ち** **技術革新**: - PhiMergeHelper箱化(112行) - is_block_terminated()ヘルパー - 単一predecessor時PHI最適化(直接代入) --- ### **Phase 3.5以降の計画** 🚀 #### **Phase 3.5: call命令実装**(最優先) **目標**: 関数呼び出し機構WASM対応 - function_table構築 - call indirect実装 - Hakoベンチマーク(factorial/fibonacci)動作確認 #### **Phase 3.6: externcall拡充** **目標**: StringBox操作WASM対応 - nyash.string.to_i8p_h実装 - nyash.string.concat_hh実装 - nyash.box.from_i8_string実装 - WASI import整備 #### **Phase 3.7: boxcall/newbox実装** **目標**: メソッド呼び出し・インスタンス生成対応 - boxcall命令WASM実装 - newbox命令WASM実装 - vtable機構構築 --- ### **Week 4: WASM最終統合**(延期) (2025-10-09 ~ 10-15) #### 目標 - WASM専用スモークプロファイル完成 - ドキュメント完全整備 - Phase 15.8完了 #### タスク 1. **スモークプロファイル作成** - tools/smokes/v2/profiles/wasm/ - quickプロファイルWASM変換 - 自動パリティ確認 2. **ドキュメント整備** - docs/guides/wasm-execution.md - docs/guides/wasm-benchmarks.md - トラブルシューティングガイド 3. **パリティ確認完了** - VM/LLVM/WASM同一出力確認 - パリティ確認レポート作成 4. **Phase 15.8完了判定** - P0条件すべて満たす - Phase 16準備(WASM GC検証) #### 成果物 - ✅ tools/smokes/v2/profiles/wasm/ - ✅ docs/guides/wasm-execution.md - ✅ Parity確認レポート(VM/LLVM/WASM) - ✅ Phase 15.8完了報告書 --- ## 🎨 **設計方針** ### **MIR18命令 → WASM変換戦略** #### **基本演算 (5命令)** ``` Const(Int) → i32.const Const(Float) → f64.const BinOp(Add) → i32.add / f64.add Compare(Lt) → i32.lt_s / f64.lt TypeOp(Cast) → i32.wrap_i64 / f64.promote_f32 ``` #### **制御フロー (4命令)** ``` Branch(cond, then, else) → (block $else (block $then (br_if $then (local.get $cond)) (br $else) ) ... then_block ... (br $merge) ) ... else_block ... (block $merge) Jump(target) → br $target Return(val) → (local.get $val) (return) Phi(inputs) → WASM locals + edge-copy materialization ``` #### **Box/外部 (6命令)** ``` MirCall → Method: call_indirect $table_index → Global: call $builtin_function → Extern: import "wasi_snapshot_preview1" "fd_write" Safepoint → (call $gc_safepoint) // WASM GC proposal待ち Barrier → nop // 将来WASM GC対応 ``` ### **Memory Model** ``` WASM Linear Memory: [0..1MB] : Stack (local variables) [1MB..16MB] : Heap (Box instances) [16MB..] : Reserved GC Strategy (Phase 15.8): - Manual reference counting(WASM GC proposal未対応) - Phase 16でWASM GC proposal採用検討 ``` --- ## 🚀 **実行方法** ### **ビルド** ```bash # WASM生成 ./tools/build_wasm.sh apps/tests/hello.hkr -o hello.wasm # 詳細: MIR JSON経由 ./target/release/hakorune --emit-mir-json hello.json apps/tests/hello.hkr python3 src/llvm_py/wasm_emitter.py hello.json -o hello.wasm ``` ### **実行** ```bash # Node.js node --experimental-wasi-unstable-preview1 tools/wasm_runner.js hello.wasm # Deno deno run --allow-read tools/wasm_runner.ts hello.wasm # Browser(開発サーバー必要) python3 -m http.server 8000 # → http://localhost:8000/wasm_demo.html ``` --- ## 📋 **成功条件と進捗** (2025-10-01更新) ### **P0(必須)** - 7/7完了 ✅ 1. ✅ Hello World WASM実行成功 - **完了** (Week 2) 2. ✅ MIR18基本命令WASM変換対応 - **完了** (Week 2) - ✅ Const, BinOp, Compare ✓ - ✅ Branch, Jump, Return ✓ - ✅ Phi (if分岐) ✓ - ⏸️ Phi (ループ) - Week 3 3. ✅ 基本演算/制御フローのパリティ確認(VM/LLVM/WASM)- **完了** (Week 2) - ✅ 算術演算: 44 = 15+12+12+5 ✓ - ✅ 比較演算: 10 > 5 = 1 ✓ - ✅ 制御フロー: if-then-else ✓ 4. ✅ print関数(fd_write)動作 - **完了** (Week 2) 5. ✅ 関数エクスポート解決 - **完了** (Week 2, wasm_add_export.py) 6. ✅ PHI処理完全修正 - **完了** (Week 2, PhiHandler箱化) 7. ✅ PHI 'values'形式統一 - **完了** (Week 2, selfhost移植) ### **P1(推奨)** - 0/6完了 1. ⏸️ ループPHI実装 - Week 3優先タスク 2. ⏸️ ベンチマークシステム構築(6ベンチ) - Week 3 3. ⏸️ 既存quickスモーク10本WASM変換成功 - Week 4 4. ⏸️ WASI clock_time_get対応(now関数) - Week 4 5. ⏸️ エラー処理(panic, error)動作 - Week 4 6. ⏸️ WASMスモークプロファイル - Week 4 ### **P2(オプション)** - Phase 16以降 1. ⏸️ async/await基本対応(Promise連携 - Phase 17推奨) 2. ⏸️ バンドルサイズ<100KB(最適化 - Phase 17推奨) 3. ⏸️ WASM GC proposal検証(Phase 16推奨) ### **進捗サマリー** - **Week 1**: 完了 ✅ (llvmlite WASM初期化) - **Week 2**: 完了 ✅ (基本命令 + PHI if + values形式統一) - **Week 3**: 進行中 🚀 (ループPHI + ベンチマーク) - **Week 4**: 計画 📋 (スモークプロファイル + ドキュメント) --- ## 🔧 **開発環境セットアップ** ### **Linux/WSL** ```bash # LLVM toolchain sudo apt install llvm-14 lld-14 # llvmlite pip install llvmlite # Node.js (WASI対応版) nvm install 18 nvm use 18 # wabt (optional) sudo apt install wabt ``` ### **macOS** ```bash # LLVM brew install llvm # llvmlite pip3 install llvmlite # Node.js brew install node # wabt brew install wabt ``` --- ## 📚 **参考資料** ### **WASM仕様** - [WebAssembly Core Specification](https://webassembly.github.io/spec/core/) - [WASI (WebAssembly System Interface)](https://github.com/WebAssembly/WASI) - [WASM GC Proposal](https://github.com/WebAssembly/gc) ### **LLVM→WASM** - [LLVM WebAssembly Backend](https://llvm.org/docs/WebAssembly.html) - [Emscripten Documentation](https://emscripten.org/) - [llvmlite WASM target](https://llvmlite.readthedocs.io/) ### **参考実装** - AssemblyScript (TypeScript → WASM) - Rust wasm32-wasi target - Go WASM target --- ## 🚨 **既知の課題と制約** ### **Phase 15.8制約** 1. **WASM GC未対応** - 手動reference counting使用 - メモリリーク可能性あり(短時間実行のみ推奨) 2. **async/await制限** - Promise連携は基本のみ - フル非同期はPhase 17 3. **パフォーマンス** - 最適化なし(デバッグビルド相当) - Phase 17で最適化パス追加 ### **回避策** - 長時間実行: LLVM native推奨 - GC重要: Rust VM推奨 - 本番環境: Phase 16以降推奨 --- ## 📝 **関連ドキュメント** - [MIR18命令セット](../../mir/INSTRUCTION_SET.md) - [LLVM Backend実装](../../../guides/llvm-backend.md) - [スモークテスト v2](../../../../tools/smokes/v2/README.md) - [Phase 15.7完了報告](../phase-15.7/README.md)