Files
hakorune/docs/private/roadmap/phases/phase-15.8

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 toolchainllc, wasm-ldでWASM変換
    • クリーンなMIR18命令セットでWASM実装
  2. ブラウザ/エッジ環境対応

    • WASIWebAssembly System Interface基本対応
    • Node.js/Deno runtime対応
    • 基本I/Oprint, error動作確認
  3. Parity確認

    • VM/LLVM/WASMで同一出力
    • スモークテスト全グリーン維持

非目標Phase 16以降に延期

  • WASM GC統合WASM GC proposal待ち
  • 最適化・バンドルサイズ削減Phase 17
  • フル非同期runtimePromise完全統合は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 toolswasm2wat, 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検証PASSwasm32-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 ✓
  1. 制御フロー完全動作
    • 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: シンプルwhilecounter 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.shHako→MIR→WASM完全パイプライン
  3. 手書きベンチマーク: 7/7テストPASSi32範囲内で安定動作
  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): 分岐予測

ベンチマーク実行:

# 一括ベンチマーク
./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/WASMWeek 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 countingWASM 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完了

  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

# 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制約

  1. WASM GC未対応

    • 手動reference counting使用
    • メモリリーク可能性あり(短時間実行のみ推奨)
  2. async/await制限

    • Promise連携は基本のみ
    • フル非同期はPhase 17
  3. パフォーマンス

    • 最適化なし(デバッグビルド相当)
    • Phase 17で最適化パス追加

回避策

  • 長時間実行: LLVM native推奨
  • GC重要: Rust VM推奨
  • 本番環境: Phase 16以降推奨

📝 関連ドキュメント