Phase 15.8: LLVM→WASM実装(WebAssembly出力)
期間: 2025-10-01 ~ 2025-10-22 (3週間) 前提: Phase 15.7完了(MIR18命令凍結) 目標: MIR18命令をWASMに変換し、ブラウザ/エッジ環境で実行可能にする
🎯 目的と範囲
主目的
-
LLVM→WASM変換パイプライン構築
- llvmlite経由でLLVM IR生成
- LLVM toolchain(llc, wasm-ld)でWASM変換
- クリーンなMIR18命令セットでWASM実装
-
ブラウザ/エッジ環境対応
- WASI(WebAssembly System Interface)基本対応
- Node.js/Deno runtime対応
- 基本I/O(print, error)動作確認
-
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完了:
- ✅ 関数エクスポート完全解決
- wasm_add_export.py実装(Python自己完結型)
- WASI runtime実装(fd_write, proc_exit)
- wasm_runner.js更新(BigInt対応)
- ✅ Hello World WASM実行成功
- "Hello, WASM!" 完全出力確認
- 文字列constants処理実装(40行追加)
Phase 2.4-2.6完了: 3. ✅ binop全演算WASM動作確認
- 算術演算: +, -, *, /, %
- ビット演算: &, |, ^, <<, >>
- テスト: 44 = 15+12+12+5 ✓
- ✅ 制御フロー完全動作
- 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へ繰越)
- ⏸️ ループPHI実装
- while/loop with PHI
- 複雑制御フロー(nested loops)
- ⏸️ メモリ命令対応 (Load, Store)
- ⏸️ Box命令拡充 (MirCall完全対応)
- ⏸️ ベンチマークシステム構築
成果物 ✅
- ✅
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命令完全動作
✅ 実装完了:
- ループPHIテスト作成完了
- ✅ test_phi_loop.json: シンプルwhile(counter PHI)
- ⏸️ test_phi_nested.json: ネストループ(2重PHI)
- 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 内部動作調査
📋 残タスク:
- ⏸️ LLVM IR構文エラー修正
- ⏸️ test_phi_nested.json作成
- ⏸️ WASM実行成功確認(0→1→2→...→10)
Phase 3.4: ベンチマークシステム構築 ✅ 完了! (2025-10-03)
✅ 達成事項:
- Hakoベンチマーク作成: apps/benchmarks/wasm/basic/{factorial,fibonacci,sum_loop}.hako
- 実行スクリプト: tools/run_wasm_benchmarks.sh(Hako→MIR→WASM完全パイプライン)
- 手書きベンチマーク: 7/7テストPASS(i32範囲内で安定動作)
- ベンチマークガイド: 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 # 深い関数呼び出し
実装計画:
- 基本ベンチ3本 (P0)
- factorial(20): 再帰深さ確認
- fibonacci(30): 指数的再帰
- sum_loop(100000): ループPHI性能
- 配列ベンチ2本 (P1)
- array_push(1000): メモリ確認
- array_search(1000): 線形探索
- 制御ベンチ1本 (P2)
- nested_if(10): 分岐予測
ベンチマーク実行:
# 一括ベンチマーク
./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確認
- WASI runtime完全連携
- fd_write (print) - ✅ 完了
- fd_read (基本入力 - optional)
- clock_time_get (now関数)
- Parity テスト
- 既存quickスモーク → WASM変換
- VM/LLVM/WASM同一出力確認
- ドキュメント整備
- 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完了
タスク
- スモークプロファイル作成
- tools/smokes/v2/profiles/wasm/
- quickプロファイルWASM変換
- 自動パリティ確認
- ドキュメント整備
- docs/guides/wasm-execution.md
- docs/guides/wasm-benchmarks.md
- トラブルシューティングガイド
- パリティ確認完了
- VM/LLVM/WASM同一出力確認
- パリティ確認レポート作成
- 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採用検討
🚀 実行方法
ビルド
# 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
実行
# 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完了 ✅
- ✅ Hello World WASM実行成功 - 完了 (Week 2)
- ✅ MIR18基本命令WASM変換対応 - 完了 (Week 2)
- ✅ Const, BinOp, Compare ✓
- ✅ Branch, Jump, Return ✓
- ✅ Phi (if分岐) ✓
- ⏸️ Phi (ループ) - Week 3
- ✅ 基本演算/制御フローのパリティ確認(VM/LLVM/WASM)- 完了 (Week 2)
- ✅ 算術演算: 44 = 15+12+12+5 ✓
- ✅ 比較演算: 10 > 5 = 1 ✓
- ✅ 制御フロー: if-then-else ✓
- ✅ print関数(fd_write)動作 - 完了 (Week 2)
- ✅ 関数エクスポート解決 - 完了 (Week 2, wasm_add_export.py)
- ✅ PHI処理完全修正 - 完了 (Week 2, PhiHandler箱化)
- ✅ PHI 'values'形式統一 - 完了 (Week 2, selfhost移植)
P1(推奨) - 0/6完了
- ⏸️ ループPHI実装 - Week 3優先タスク
- ⏸️ ベンチマークシステム構築(6ベンチ) - Week 3
- ⏸️ 既存quickスモーク10本WASM変換成功 - Week 4
- ⏸️ WASI clock_time_get対応(now関数) - Week 4
- ⏸️ エラー処理(panic, error)動作 - Week 4
- ⏸️ WASMスモークプロファイル - Week 4
P2(オプション) - Phase 16以降
- ⏸️ async/await基本対応(Promise連携 - Phase 17推奨)
- ⏸️ バンドルサイズ<100KB(最適化 - Phase 17推奨)
- ⏸️ WASM GC proposal検証(Phase 16推奨)
進捗サマリー
- Week 1: 完了 ✅ (llvmlite WASM初期化)
- Week 2: 完了 ✅ (基本命令 + PHI if + values形式統一)
- Week 3: 進行中 🚀 (ループPHI + ベンチマーク)
- Week 4: 計画 📋 (スモークプロファイル + ドキュメント)
🔧 開発環境セットアップ
Linux/WSL
# 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
# LLVM
brew install llvm
# llvmlite
pip3 install llvmlite
# Node.js
brew install node
# wabt
brew install wabt
📚 参考資料
WASM仕様
LLVM→WASM
参考実装
- AssemblyScript (TypeScript → WASM)
- Rust wasm32-wasi target
- Go WASM target
🚨 既知の課題と制約
Phase 15.8制約
-
WASM GC未対応
- 手動reference counting使用
- メモリリーク可能性あり(短時間実行のみ推奨)
-
async/await制限
- Promise連携は基本のみ
- フル非同期はPhase 17
-
パフォーマンス
- 最適化なし(デバッグビルド相当)
- Phase 17で最適化パス追加
回避策
- 長時間実行: LLVM native推奨
- GC重要: Rust VM推奨
- 本番環境: Phase 16以降推奨