diff --git a/docs/development/current/main/phase133_consolebox_llvm_integration.md b/docs/development/current/main/phase133_consolebox_llvm_integration.md new file mode 100644 index 00000000..62b449a9 --- /dev/null +++ b/docs/development/current/main/phase133_consolebox_llvm_integration.md @@ -0,0 +1,369 @@ +# Phase 133: ConsoleBox LLVM 統合 & JoinIR→LLVM 第3章クローズ + +## 🎯 ゴール + +ConsoleBox(log/println 系)の振る舞いを **LLVM backend でも Rust VM と完全一致** させる。 + +目的: +- JoinIR → MIR → LLVM → nyrt の経路で、ConsoleBox メソッド呼び出しが一貫した ABI で動く状態にする +- Phase 130 の 7 本ベースラインうち「ConsoleBox 由来の失敗」をすべて緑にする(**7/7 達成**) +- JoinIR → LLVM 第3章の完全クローズ + +``` +Phase 132: PHI 順序バグ修正(6/7 達成)✅ + ↓ +Phase 133: ConsoleBox LLVM 統合 ← ← ここ! + ↓ +JoinIR → LLVM 第3章 完全クローズ 🎉 +``` + +--- + +## 📋 スコープ(やること・やらないこと) + +### ✅ やること +- LLVM backend 内の ConsoleBox / CoreMethodId / BoxCall lowering を整理 +- **「ConsoleBox.{log,println,…} → 1 本の LLVM runtime 関数群」** に統一 +- 既存の Rust VM 側 ConsoleService / logging_policy.md と意味論を揃える(出力文字列と順序) +- Phase 130/131/132 の代表 .hako ケースで LLVM 実行を検証し、Rust VM と結果を比較 + +### ❌ やらないこと +- JoinIR や MIR の意味論変更(BoxCall lowering 以前の層には触れない) +- Ring0 / FileBox / Logger 設計を変えること(今の三層構造はそのまま) +- LLVM backend 全体の最適化/別機能(PHI 以外の opcode は Phase 133 では触らない) + +--- + +## 🏗️ 6 つのタスク + +### Task 1: 設計ドキュメント作成 + +**ファイル**: `docs/development/current/main/phase133_consolebox_llvm_integration.md`(このファイル) + +**書く内容**: + +#### 現状整理 + +**Rust VM 経路**: +- ConsoleBox メソッドは CoreMethodId::ConsoleLog などにマップ +- log/println の alias は TypeRegistry / CoreMethodId 側で SSOT 管理済み(Phase 122) +- 実際の出力は ConsoleService → Ring0.log → stderr/stdout + +**LLVM 経路**: +- BoxCall(ConsoleBox, method) がどう LLVM IR に落ちているか + - printf 直叩き or 未実装 or stub +- どのファイルが Console を扱っているか + - 候補: `src/backend/llvm/*box*` / `src/backend/llvm/*call*` など BoxCall lowering 周辺 + +#### 目指す構造 + +**Console LLVM Bridge 箱** を定義するイメージ図: + +``` +BoxCall(ConsoleBox, method) + ↓ +CoreMethodId / メソッド種別判定 + ↓ +ConsoleLlvmBridge 箱 + ↓ +LLVM 外部関数 @ny_console_log / @ny_console_warn … に lowering +``` + +**Rust VM と LLVM の間で一致すべき項目**: +- 文字列 API(i8* + len) +- 改行有無(println の扱い) +- ログレベル(log/warn/error) + +#### ABI 方針 + +**LLVM 側の runtime 関数 signature**(例): +```llvm +declare void @ny_console_log(i8* %ptr, i64 %len) +declare void @ny_console_warn(i8* %ptr, i64 %len) +declare void @ny_console_error(i8* %ptr, i64 %len) +``` + +**nyrt(C/Rust ランタイム)側の実装**: +- 今の ConsoleService と同じポリシーで出力 +- println は log + 改行 or そのまま log として扱う(設計書で明文化) + +--- + +### Task 2: 現状実装の棚卸し(ConsoleBox ↔ LLVM) + +**対象候補ファイル**: +```bash +# BoxCall lowering 周辺 +rg "BoxCall" src/backend/llvm/ --type rust + +# ConsoleBox の CoreMethodId マッピング +rg "ConsoleLog|ConsolePrintln" src/runtime/type_registry.rs +``` + +**やること**: + +1. **ConsoleBox 関連の lowering の現状把握**: + - 文字列をそのまま printf に渡しているか + - 未実装で panic/log を吐いているか + - CoreMethodId ベースか、Box 名+メソッド名の文字列ベースか + +2. **Phase 122 のエイリアス統一の反映確認**: + - println/log エイリアスが LLVM 経路でも共有されているか + - 共有されていない場合は「どこで divergence しているか」をメモ + +**結果記録**: +- この Task の結果は、そのまま phase133 ドキュメントの「現状問題点」セクションに追記 + +--- + +### Task 3: ConsoleLlvmBridge(仮)設計 & 実装 + +**目的**: Console 関連 BoxCall lowering を **1 箇所に集約した「箱」** に閉じ込める + +**実装方針**: + +#### 箱の設計 +**場所**: `src/backend/llvm/console_bridge.rs`(新規モジュール) + +**役割**: +1. CoreBoxId / CoreMethodId から「Console メソッド種別」を判定 + - 例: ConsoleLog, ConsoleWarn, ConsoleError, ConsoleClear, ConsolePrintln +2. 文字列引数(Nyash の StringBox or i8* + len)を LLVM IR 上の (i8*, i64) に変換 +3. 対応する runtime 関数呼び出しを生成 + +#### BoxCall lowering 側の修正 +**最小限の分岐に集約**: +```rust +// BoxCall lowering 側(例) +if box_id == CoreBoxId::Console { + ConsoleLlvmBridge::emit_call(builder, method_id, args)?; + return; +} +``` + +**箱化の効果**: +- 解析やログ文字列構築を BoxCall lowering から追い出す +- Console 関連のロジックが 1 箇所に集約される +- テストしやすく、後でレガシー削除しやすい + +#### 注意点 +- **既に nyrt / LLVM runtime に似た関数があれば、それに合わせる**(新規関数を増やさずに統合) +- なければ、最小限の関数だけ追加し、Phase 133 のドキュメントに ABI を記録 + +--- + +### Task 4: 代表ケースでの JoinIR→LLVM 実行確認 + +**代表 .hako**: + +Phase 130/131 で使っていた 7 本から、Console 出力を含むものを **最低 3 本** 選ぶ: +- `apps/tests/esc_dirname_smoke.hako`(Console 出力あり) +- `apps/tests/peek_expr_block.hako`(軽量) +- `apps/tests/loop_min_while.hako`(ループ + Console) + +**検証手順**: + +1. **Rust VM 実行(baseline)**: + ```bash + ./target/release/nyash --backend vm apps/tests/esc_dirname_smoke.hako + ``` + +2. **LLVM 実行**: + ```bash + LLVM_SYS_180_PREFIX=$(llvm-config-18 --prefix) \ + NYASH_LLVM_USE_HARNESS=1 \ + ./target/release/nyash --backend llvm apps/tests/esc_dirname_smoke.hako + ``` + +3. **両者の標準出力を比較**: + - 最低限、行数と大まかなメッセージ一致を確認 + - 差分があれば原因調査 + +**期待**: +- Phase 132 で PHI 順序は整っているので、ConsoleBox を含む代表ケースは LLVM でも成功するはず +- Phase 130 で「Rust VM OK / LLVM NG」だったうち Console 起因のものは緑にしたい + +--- + +### Task 5: テスト追加(LLVM 専用 or 統合テスト) + +**テスト戦略**: + +#### Option A: Rust 側に小さな LLVM 専用テスト追加 +**入力**: 簡単な MIR/JoinIR(ConsoleBox.log/println を 1–2 回呼ぶだけ) +**出力**: +- LLVM IR text を dump して、@ny_console_log への call が生成されていること +- 実行したときに期待メッセージが出ること + +#### Option B: スクリプトでの手動テスト +もしテストが重くなる場合: +- Phase 130 の手動スクリプトを使って、最低限の再現手順を docs に書く +- `tools/test_phase133_console_llvm.sh` のようなスクリプトを用意できればベスト + +**実装例**: +```bash +#!/bin/bash +# tools/test_phase133_console_llvm.sh + +set -e + +test_cases=( + "apps/tests/esc_dirname_smoke.hako" + "apps/tests/peek_expr_block.hako" + "apps/tests/loop_min_while.hako" +) + +echo "=== Phase 133: ConsoleBox LLVM Integration Test ===" + +for case in "${test_cases[@]}"; do + echo "Testing: $case" + + # VM baseline + vm_output=$(./target/release/nyash --backend vm "$case" 2>&1) + + # LLVM execution + llvm_output=$(NYASH_LLVM_USE_HARNESS=1 \ + ./target/release/nyash --backend llvm "$case" 2>&1) + + # Compare + if [ "$vm_output" == "$llvm_output" ]; then + echo "✅ $case PASS" + else + echo "❌ $case FAIL" + echo "VM output:" + echo "$vm_output" + echo "LLVM output:" + echo "$llvm_output" + exit 1 + fi +done + +echo "All tests PASSED! 🎉" +``` + +--- + +### Task 6: ドキュメント / CURRENT_TASK 更新 + +**やること**: + +1. **phase133_consolebox_llvm_integration.md に追記**: + ```markdown + ## Phase 133 実装結果 + + ### 修正ファイル + - `src/backend/llvm/console_bridge.rs`: ConsoleLlvmBridge 箱(新規) + - `src/backend/llvm/boxcall_lowering.rs`: Console 分岐を箱に委譲 + - `src/llvm_py/runtime.py`: @ny_console_log 等の外部関数実装 + + ### ABI 設計 + | 関数名 | Signature | 用途 | + |--------|----------|------| + | @ny_console_log | void(i8*, i64) | ログ出力 | + | @ny_console_warn | void(i8*, i64) | 警告出力 | + | @ny_console_error | void(i8*, i64) | エラー出力 | + + ### テスト結果 + | ケース | Rust VM | LLVM (Phase 132) | LLVM (Phase 133) | + |--------|---------|------------------|------------------| + | esc_dirname_smoke.hako | ✅ | ❌ | ✅ | + | peek_expr_block.hako | ✅ | ✅ | ✅ | + | loop_min_while.hako | ✅ | ❌ | ✅ | + + ### 成果 + - ConsoleBox LLVM 統合完了 + - JoinIR → LLVM 経路が 7/7 動作確認 + - JoinIR → LLVM 第3章完全クローズ 🎉 + ``` + +2. **CURRENT_TASK.md 更新**: + ```markdown + ### Phase 133: ConsoleBox LLVM 統合 & JoinIR→LLVM 第3章クローズ ✅ + + **完了内容**: + - ConsoleLlvmBridge 箱化モジュール実装 + - ConsoleBox.{log,println,warn,error} の LLVM runtime 関数統一 + - Phase 130 代表ケース 7/7 LLVM 実行成功 + + **修正箇所**: + - src/backend/llvm/console_bridge.rs: 新規箱化モジュール + - src/backend/llvm/boxcall_lowering.rs: Console 分岐を箱に委譲 + - src/llvm_py/runtime.py: @ny_console_* 外部関数実装 + + **テスト結果**: + - 修正前: LLVM 6/7 実行可能(ConsoleBox 未統合) + - 修正後: LLVM 7/7 実行可能(完全一致) + + **成果**: + - JoinIR → LLVM 第3章完全クローズ + - PHI 順序(Phase 132)+ ConsoleBox 統合(Phase 133)で「JoinIR-heavy .hako の LLVM 実行ライン確立」 + + **次フェーズ**: selfhost Stage-4 拡張 or 次の大型改善へ + ``` + +3. **30-Backlog.md 更新**: + ```markdown + ### JoinIR → LLVM 第3章完全クローズ ✅ + + Phase 130-133 で以下を達成: + - Phase 130: ベースライン確立(観測フェーズ) + - Phase 131: LLVM backend re-enable(1/7 達成) + - Phase 132: PHI 順序バグ修正(6/7 達成) + - Phase 133: ConsoleBox LLVM 統合(7/7 達成) + + 完了条件: + - ✅ 7/7 テストが Rust VM と LLVM で実行成功 + - ✅ PHI 順序バグ構造的修正 + - ✅ ConsoleBox 箱化モジュール統合 + - ✅ JoinIR → LLVM 経路完全確立 + ``` + +--- + +## ✅ 完成チェックリスト(Phase 133) + +- [ ] ConsoleBox LLVM 統合の設計ドキュメント作成 +- [ ] 現状実装の棚卸し(BoxCall lowering 周辺) +- [ ] ConsoleLlvmBridge 箱化モジュール実装(新規 or 既存統合) +- [ ] ConsoleBox メソッドの LLVM runtime 関数マッピング実装 +- [ ] BoxCall lowering 側を箱に委譲(分岐削除・レガシー削除) +- [ ] 代表ケース 3 本以上で LLVM 実行成功確認 +- [ ] phase133_consolebox_llvm_integration.md に実装結果追記 +- [ ] CURRENT_TASK.md & Backlog 更新(第3章クローズ宣言) +- [ ] git commit で記録 + +--- + +## 所要時間 + +**4〜5 時間程度** + +- Task 1-2 (設計ドキュメント & 棚卸し): 1時間 +- Task 3 (ConsoleLlvmBridge 実装): 2時間 +- Task 4-5 (実行確認 & テスト): 1時間 +- Task 6 (ドキュメント更新): 30分 + +--- + +## 次のステップ + +**JoinIR → LLVM 第3章完全クローズ後**: + +Phase 133 が完了すると: +- ✅ JoinIR / selfhost / hako_check(第2章) +- ✅ JoinIR → LLVM(第3章)の「最低限動くベースライン」確立 + +次の方向性: +- selfhost Stage-4 拡張(より複雑なパターン対応) +- LLVM backend 最適化(Phase 134 以降) +- 別の大型改善フェーズへ + +--- + +## 進捗 + +- ✅ Phase 130: JoinIR → LLVM ベースライン確立(完了) +- ✅ Phase 131: LLVM backend re-enable & PHI 問題発見(完了) +- ✅ Phase 132: LLVM PHI 命令順序バグ修正(完了) +- 🎯 Phase 133: ConsoleBox LLVM 統合 & 第3章クローズ(← **現在のフェーズ**) +- 📋 Phase 134+: 次の改善フェーズ(予定)