# Self Current Task — Now (main) ## Current: Phase 277(P2)— PHI関連環境変数の統合・整理 ✅ - 目的: PHI関連環境変数を **8個 → 3個** に統合してユーザビリティ向上・保守性向上 - 完了日: 2025-12-22 - 達成内容: - ✅ `debug_helper.py` 作成(環境変数チェックのSSOT) - ✅ 3つの統合関数実装: - `is_phi_debug_enabled()`: 一般デバッグ(LLVM_PHI_DEBUG + PHI_TYPE_DEBUG + PHI_ORDERING_DEBUG 統合) - `is_phi_trace_enabled()`: 詳細トレース(LLVM_TRACE_PHI + LLVM_VMAP_TRACE 統合) - `is_phi_strict_enabled()`: 厳格モード(既存維持) - ✅ 全PHI関連ファイル修正完了(9ファイル): - `phi_wiring/wiring.py`, `phi_wiring/tagging.py`, `phi_wiring/common.py` - `phi_placement.py`, `trace.py`, `instructions/phi.py` - `resolver.py`, `utils/values.py`, `builders/block_lower.py` 他 - ✅ 後方互換性対応(非推奨警告付き、Phase 278で削除予定) - ✅ ドキュメント更新: - `docs/reference/environment-variables.md` に詳細セクション追加 - 使用例・出力例・移行ガイド記載 - 効果: - ユーザビリティ向上(覚える変数 8個→3個) - ドキュメント簡潔化(環境変数セクションが短く) - 保守性向上(関連設定が1つに) - SSOT原則適用(環境変数チェックロジック統一) ## 2025-12-22: Phase 276(P0)— Quick Win 改善(型取得SSOT化) ✅ - 目的: Phase 275 P0 完了後の堅牢性改善(デバッグコード削減・型取得ロジックSSOT化・警告強化) - 完了ドキュメント: `docs/development/current/main/phases/phase-276/P0-COMPLETION.md` - 達成内容: - ✅ デバッグスタックトレース削除(wiring.py) - ✅ box_from_f64 使用確認(削除可能と判断) - ✅ 型取得ロジックSSOT化(type_helper.py 作成、3ファイル統一) - ✅ 型不一致CRITICAL警告強化(PhiManager連携) - 効果: - 型取得ロジックの重複削除(3箇所 → 1箇所) - SSOT原則適用(バグ防止・拡張性向上) - デバッグ性向上(CRITICAL警告で早期発見) ## 2025-12-22:Phase 275(P0)— coercion SSOT rollout(truthiness / `==` / `+`) ✅ - 完了: Phase 274 P3 で確定した coercion ルール(A1/B2/C2)を VM/LLVM に実装 - Decision (SSOT): `docs/development/current/main/phases/phase-274/P3-DECISIONS.md` - 実装ガイド: `docs/development/current/main/phases/phase-275/P0-INSTRUCTIONS.md` - 重要修正: - Float型PHI完全対応(MIR型伝播 → LLVM IR double生成) - 型取得ロジック3箇所統一(type_helper.py) - 型不一致警告強化(CRITICAL表示) - fixture/smoke: - `apps/tests/phase275_p0_float_phi_min.hako` (想定) - LLVM harness で exit=3 動作確認済み ### 過去の Blocker: 型伝播パイプラインの二重化(lifecycle vs JoinIR) - 現状、型伝播/PHI 型解決の順序が経路により異なり、同一 fixture が別ルートで壊れ得る(実質 "2本のコンパイラ")。 - 対処(SSOT): Phase 276 P0 で型取得ロジックをSSOT化(部分対応完了) - Phase 276 本体: type propagation pipeline 完全統一(長期計画) - 予定: `docs/development/current/main/phases/phase-276/README.md` ## 2025-12-22:Phase 274(P1)— TypeOp(is/as)を Rust VM で実行可能にする ✅ - 完了: Rust VM が `MirInstruction::TypeOp`(Check/Cast)を実行可能 - fixture/smoke: - `apps/tests/phase274_p1_typeop_is_as_min.hako` - `tools/smokes/v2/profiles/integration/apps/phase274_p1_typeop_is_as_vm.sh` ## 2025-12-22:Phase 274(P2)— LLVM TypeOp alignment ✅ - 完了: LLVM harness でも `TypeOp(Check/Cast)` が SSOT(Rust VM)と一致 - 重要修正: MIR JSON emitter(bin)で `typeop` が欠落していたため、JSON に `op:"typeop"` を出力するよう修正 - fixture/smoke(LLVM): - `apps/tests/phase274_p2_typeop_primitives_only.hako` - `tools/smokes/v2/profiles/integration/apps/phase274_p2_typeop_is_as_llvm.sh` ## 2025-12-22:Phase 272(P0.2)— Pattern7 Frag+emit_frag 移行 ✅ - 目的: Pattern7(split scan)を `Frag + emit_frag()` 経路へ移行し、terminator emission を SSOT に集約する(副作用 `result.push` を含む) - 状況: Phase 272 P0.1(Pattern6)+ P0.2(Pattern7)ともに ✅ 完了 - 入口 fixture/smoke: - Pattern7: `apps/tests/phase256_p0_split_min.hako` + `tools/smokes/v2/profiles/integration/apps/phase256_p0_split_vm.sh` - SSOT: `docs/development/current/main/design/edgecfg-fragments.md`(合成則/bridge撤去条件) - 詳細: `docs/development/current/main/phases/phase-272/README.md` ## 2025-12-22:Phase 271(docs-only)— Bridge pattern 撤去条件SSOT ✅ - 変更: - `docs/development/current/main/design/edgecfg-fragments.md` に bridge contract(テンプレ)+ `Pattern9_AccumConstLoop` 撤去条件を追記 - `docs/development/current/main/30-Backlog.md` の Phase 271 成果物を明文化 ## 2025-12-22:Phase 269 P1.2(this/me in loop)— Static Call 正規化SSOT ✅ - 目的: static box 内の `this.method(...)` / `me.method(...)` を runtime receiver にせず、compile-time に static call へ正規化する(NewBox 禁止 / by-name ハードコード禁止) - SSOT: `comp_ctx.current_static_box` と `BoxName.method/arity`(canonical key) - 実装: MethodCall 共通入口で `This/Me` receiver を最優先で検出し、static call へ正規化(ハードコード無し) - fixture/smoke: - `apps/tests/phase269_p1_2_this_method_in_loop_min.hako` - `tools/smokes/v2/profiles/integration/apps/phase269_p1_2_this_method_in_loop_vm.sh` - 受け入れ: MIR dump に receiver `const "StringUtils"` が出ない / `call_method StringUtils.is_digit/1`(同等の static call)になる ## 2025-12-22:Phase 269 P1(Pattern8 EdgeCFG lowering)— SSA を閉じる ✅ - 完了: header に `i_current = phi [i_init, preheader], [i_next, step_bb]` を入れて SSA を閉じ、header/body/step の参照を `i_current` に統一 - 検証: `tools/smokes/v2/profiles/integration/apps/phase269_p0_pattern8_frag_vm.sh` PASS(+ 回帰 `phase259_p0_is_integer_vm` PASS) - 詳細: `docs/development/current/main/phases/phase-269/README.md` ## 2025-12-21:Phase 270(P0+P1)— JoinIR-only minimal loop SSOT ✅ - 目的: `loop(i < 3)` + `sum=sum+i` + `i=i+1` を JoinIR 経路で通すことを fixture/smoke で固定 - 結果: Pattern1 は test-only stub のため不適合 → Pattern9(AccumConstLoop)を橋渡しとして追加し、fixture は exit=3 で PASS - 制約: `cf_loop` は JoinIR-only(非JoinIR loop 経路や env-var 分岐は追加しない) - 詳細: `docs/development/current/main/phases/phase-270/README.md` ## 2025-12-21:Phase 269 P1(Pattern8 EdgeCFG lowering)✅ **目的**: Pattern8(BoolPredicateScan)を JoinIR ではなく **EdgeCFG Frag + emit_frag()** で “本当に”動かす(層境界は維持) **スコープ**: Pattern8 内だけ差し替え(merge/EdgeCFG plumbing/Pattern6/7/9 は触らない、cf_loop hard-freeze維持) **完了内容(P1)**: - ✅ emission 入口 `loop_predicate_scan` を追加し、Frag 構築 + `emit_frag()` を配線 - ✅ 5ブロック構成(header/body/step/after/ret_false)で terminator を生成 - ✅ header に PHI を挿入して `i` の SSA を閉じた(`i_current`) - ✅ early-exit `return false` は Return wire、`return true` は loop 後 AST に任せる - ✅ Pattern8 lower は当面 `emit_void(builder)`(loop-statement 扱い) **詳細**: `docs/development/current/main/phases/phase-269/README.md` ## 2025-12-21:Phase 269 P1.1(call_method return type)— 署名SSOTで型注釈 ✅ - 問題: `call_method BoxName.method/N(...)` の戻り値型が既定 `String` になり、Bool を返すメソッドが誤動作する - 修正方針: `emit_unified_call_impl` の直後で、`BoxName.method/arity` の canonical key を構築し、 `MirFunction.signature.return_type`(SSOT)から dst の型を注釈する(ハードコード禁止) ## 2025-12-21:Phase 267 P0(BranchStub + emit_frag)✅ **目的**: Frag に Branch を第一級で追加し、wires(Jump/Return)と同様に MIR terminator へ落とせる入口(SSOT)を作る **結果**: `emit_frag()` により、`wires + branches` を BasicBlockId 層で PoC 証明(unit tests)まで完了 - ✅ `BranchStub` 追加 + `Frag.branches` 追加 - ✅ `compose::if_` が header→then/else の `BranchStub` を生成 - ✅ `emit_frag(function, frag)` 追加(`verify_frag_invariants_strict` を先頭で実行、1 block = 1 terminator を Fail-Fast) - ✅ `cargo test -p nyash-rust --lib` PASS **注意(P1)**: NormalizedShadow/JoinIR への実適用は層ミスマッチがあるため Phase 268 に繰り越し **詳細**: `docs/development/current/main/phases/phase-267/README.md` ## 2025-12-21:Phase 268 P1(compose::if_ entry edge-args SSOT化)✅ **目的**: compose::if_() の then/else entry edge-args を呼び出し側 SSOT にし、TODO 削除(Phase 267 P2+ からの継続) **実装完了内容**: - ✅ compose::if_() シグネチャ変更(then_entry_args, else_entry_args パラメータ追加) - ✅ emission/branch.rs::emit_conditional_edgecfg() から空 EdgeArgs を then/else 両方に渡す - ✅ EdgeCFG テスト更新(compose.rs 2箇所、emit.rs 1箇所) - ✅ TODO コメント削除完了(Phase 267 P2+ TODO 解消) **テスト結果**: - ✅ cargo build --release: **成功**(0エラー) - ✅ cargo test --lib --release: **1444/1444 PASS** - ✅ quick smoke: **45/46 PASS**(既存状態維持) **核心的な設計判断**: 1. **SSOT 原則**: compose::if_() 内部で then/else entry edge-args を "勝手に空 Vec で生成" しない → 呼び出し側が明示的に渡す 2. **P0 との整合性**: P0 で emission/branch.rs に薄いラッパーを作ったので、edge-args も同じ層で SSOT として渡す **次フェーズへの橋渡し**: - Phase 269: Pattern6/7/8 への Frag 適用 + fixture/smoke test **詳細**: `docs/development/current/main/phases/phase-268/README.md` ## 2025-12-21:Phase 266(wires → MIR terminator 生成 - 最小 PoC)✅ **目的**: wires を MIR terminator に変換する最小 PoC を実装し、Phase 267 での本格適用に備える **実装完了内容**: - ✅ emit.rs 作成(emit_wires 実装 + unit test 4個) - from ごとにグループ化して1本だけ許可(1 block = 1 terminator 制約) - Return は target=None を許可(意味を持たない) - Jump/Return 対応(Branch は Phase 267) - ✅ verify_frag_invariants_strict() 追加(段階導入を壊さない) - 既存の verify_frag_invariants() は変更なし(警告のまま) - wires/exits 分離契約を Err 化(Return の target=None は許可) - ✅ mod.rs 更新(emit module エクスポート) **テスト結果**: - ✅ edgecfg::api::emit テスト: **4/4 PASS** - test_emit_wires_jump_basic - test_emit_wires_return_basic - test_emit_wires_unwired_stub_fails - test_emit_wires_multiple_from_same_block_fails - ✅ 全 lib テスト: **1392/1392 PASS**(既存 1388 + 新規 4個、退行なし) **核心的な設計判断**: 1. **from グループ化**: 同じ block に複数 terminator を設定すると上書き → BTreeMap で from ごとにグループ化し、1本だけ許可 2. **Return の target=None 許可**: Return は呼び出し元に戻るので target が意味を持たない → Normal/Break/Continue/Unwind のみ target 必須 3. **verify strict 版**: 既存の verify_frag_invariants() を Err 化すると既存コードが壊れる → 新規に strict 版を追加し、段階導入 4. **Phase 260 terminator 語彙ルール厳守**: Jump は set_jump_with_edge_args()、Return は set_terminator() + set_return_env() **重要**: JoinIR/NormalizedShadow には触らない(Phase 267)。Branch terminator 生成も Phase 267 に繰り越し。 **次フェーズへの橋渡し**: - Phase 267: NormalizedShadow への Frag 適用 + Pattern6/7/8 を Frag 化 + Branch 生成 **詳細**: `docs/development/current/main/design/edgecfg-fragments.md` ## 2025-12-21:Phase 265 P2(seq/if_ 実装 - wires/exits 分離)✅ **目的**: 「解決済み配線(wires)」と「未解決 exit(exits)」を分離し、Frag 合成の基本パターンを完成させる **実装完了内容**: - ✅ Frag に `wires: Vec` フィールド追加 - ✅ wires/exits 分離設計確立 - **exits**: target = None のみ(未配線、外へ出る exit) - **wires**: target = Some(...) のみ(配線済み、内部配線) - ✅ loop_() を wires 対応に更新(Break/Continue → wires) - ✅ seq(a, b) 実装完了(a.Normal → b.entry が wires、seq の Normal exit は b の Normal) - ✅ if_(header, cond, t, e, join_frag) 実装完了(t/e.Normal → join が wires、if の exit は join_frag.exits) - ✅ verify_frag_invariants() に wires/exits 分離契約追加(警告のみ、Err化は Phase 266) **テスト結果**: - ✅ edgecfg::api テスト: **13/13 PASS**(frag 3個 + compose 9個 + verify 1個) - ✅ 全 lib テスト: **1388/1388 PASS**(退行なし) **核心的な設計判断**: 1. **wires/exits 分離**: 解決済み配線と未解決 exit を混ぜると再配線バグが起きる → 分離して不変条件強化 2. **if_ は join_frag 受け取り**: join: BasicBlockId では「join block」か「join 以降」か曖昧 → join_frag: Frag で明確化 3. **verify は警告のみ**: P2 は wires/exits 分離の証明に集中、Err 化は Phase 266 で MIR 生成時に実施 **重要**: - MIR 命令生成の **PoC(emit_wires)**は Phase 266 で完了。 - Pattern6/7/8 や NormalizedShadow への **実適用**は Phase 267 以降(層境界維持)。 **次フェーズへの橋渡し**: - Phase 266: wires を MIR terminator に落とす(PoC: emit_wires)✅ - Phase 267: NormalizedShadow/JoinIR への適用 + Pattern6/7/8 を Frag 化 + Branch 生成 **詳細**: `docs/development/current/main/phases/phase-265/` + `docs/development/current/main/design/edgecfg-fragments.md` ## 2025-12-21:Phase 263 P0.2(Pattern2 promotion API SSOT)✅ - **Goal**: Pattern2 の “Reject/continue/fallback の揺れ” を **型 + 入口SSOT**で封じ、部分続行(後段で落ちる)を構造で不可能にする - **実装**: - `PromoteDecision::{Promoted, NotApplicable, Freeze}`(Option 多重を撤去) - `pattern2/api/` を入口SSOTとして新設し、`try_promote(...)` を **単一参照点**に固定 - **効果**: - `NotApplicable` は **必ず** `Ok(None)` で Pattern2 全体を抜ける(後続経路へ) - `Freeze` は **必ず** Fail-Fast(close-but-unsupported のみ即死) - **検証結果**: - cargo test --lib: **1368/1368 PASS** ✅ - quick smoke: **45/46 PASS** ✅(既知 1 件は別論点) - **Commits**: - `abdb860e7`(P0.1): PromoteDecision 導入(Option 揺れの撤去) - `e17902a44`(P0.2): `pattern2/api/` で入口SSOT物理固定 - **詳細**: `docs/development/current/main/phases/phase-263/README.md` ## 2025-12-21:Phase 264 P0(EdgeCFG Fragment 入口作成)✅ **目的**: Frag/ExitKind を一次概念にする入口APIを用意(実装置換は次フェーズ) **完了内容**: - 入口フォルダ作成: `src/mir/builder/control_flow/edgecfg/api/` - コア型定義: `ExitKind`, `EdgeStub`, `Frag` - 合成関数シグネチャ: `seq`, `if_`, `loop_`, `cleanup`(中身TODO) - 最小テスト: 3個のユニットテスト追加 - ドキュメント連動: `edgecfg-fragments.md` に入口情報追記 **重要**: 既存実装(pattern6/7/8, merge/EdgeCFG)は未改変。 入口だけ固定し、適用は quick 復旧後の次フェーズで実施。 **次のステップ**: - Phase 265: Pattern8 を Frag 合成に移行(最小適用) - Phase 266: Pattern6/7 への展開(再利用確認) **詳細**: `docs/development/current/main/phases/phase-264/README.md` + `docs/development/current/main/design/edgecfg-fragments.md` ## 2025-12-21:Phase 265 P0(compose/verify 最小実装)✅ **目的**: 入口SSOTを触って迷子防止(compose/verify の形を固める) **完了内容**: - `compose::loop_()` 最小実装(exit集合の分類のみ、配線はP1以降) - `verify_frag_invariants()` 最小実装(デバッグガード付き) - compose::loop_() のユニットテスト 2個追加 **重要**: Pattern8への適用はP0ではやらない(偽Fragを避ける)。 配線ロジックはP1で実装、Pattern8適用もP1から。 **次のステップ**: - Phase 265 P1: 配線ロジック実装 + Pattern8適用 - Phase 265 P2: seq/if_ 実装(pattern番号分岐削減の見通し) **詳細**: `docs/development/current/main/phases/phase-265/README.md` ## 2025-12-21:Phase 265 P1(compose 配線ロジック実装)✅ **目的**: Frag/ExitKind が BasicBlockId 層で配線できることを証明 **完了内容**: - EdgeStub に `target: Option` 追加 - compose::loop_() 配線ロジック実装(Continue → header, Break → after) - verify_frag_invariants() 配線契約検証追加 - test-only PoC で実証完了(5個のテスト: 既存2個更新 + 新規3個追加) **配線契約**: - Continue(loop_id) の EdgeStub.target = Some(header) - Break(loop_id) の EdgeStub.target = Some(after) - Normal/Return/Unwind の EdgeStub.target = None(上位へ伝搬) **重要**: - MIR 命令生成はまだしない(Frag 層の配線能力証明に集中) - NormalizedShadow/JoinIR層への適用は Phase 266 に繰り越し(層境界を守る) **次のステップ**: - Phase 265 P2: seq/if_ 実装(順次合成・条件分岐合成) - Phase 266: JoinIR-VM Bridge 改修後、NormalizedShadow への適用 **詳細**: `docs/development/current/main/phases/phase-265/README.md` ## Next (planned) - Phase 265(planned): Pattern8 を Frag 合成に移行し、ExitKind+Frag の実装適用を開始(`compose::loop_` 実装) - Phase 266(planned): catch/cleanup / cleanup/defer / async を "exit-edge 正規化" で追加できる形へ(設計: `docs/development/current/main/design/exception-cleanup-async.md`) - Phase 141 P2+: Call/MethodCall 対応(effects + typing を分離して段階投入、ANF を前提に順序固定) - Phase 143-loopvocab P3+: 条件スコープ拡張(impure conditions 対応) - 詳細: `docs/development/current/main/30-Backlog.md` ## Phase 260(大工事)ロードマップ(要約) - P0: edge-args を MIR terminator operand として **併存導入**(Branch を含むので参照点は `out_edges()` 系に一本化) - P1: terminator更新APIを一本化し、successors/preds 同期漏れを構造で潰す - P2: `BasicBlock.jump_args` を削除(terminator operand を SSOT 化) - P3: spans を `Vec>` に収束(段階導入) ## Phase 261 P0 チェックリスト(legacy-only 経路の棚卸し) - `src/mir/basic_block.rs:119` — reason: legacy layout の初期値が None(空メタ); expected: OK(legacy 未設定時の既定) - `src/mir/basic_block.rs:239` — reason: out_edges が legacy fallback を持つ; expected: Jump/Branch で edge-args を書く経路を増やし、verify で legacy-only を検出 - `src/mir/basic_block.rs:254` — reason: legacy setter API; expected: writer 側は edge-args を併記する経路に統一 - `src/mir/basic_block.rs:281` — reason: legacy edge-args 生成 API; expected: read-side の移行完了後に削除(P2) - `src/mir/basic_block.rs:337` — reason: legacy edge-args fallback; expected: verify で legacy-only を検出し、P2で撤去 ## Current First FAIL (SSOT) - **After Phase 260 P0.3**: `core_direct_array_oob_set_rc_vm / Stage-B compile / JoinIR Pattern2 LoopBodyLocal(seg)` ### FAIL Details (既知・Phase 260 scope外) - **Test**: `core_direct_array_oob_set_rc_vm` - **Status**: **既知 / Phase 260 scope外**(JoinIR Pattern2 LoopBodyLocal promotion 未実装) - **Phase**: Stage‑B compile (`stageb_compile_to_json`) - **Error**: `[cf_loop/pattern2] Cannot promote LoopBodyLocal variables ["seg"]: No promotable pattern detected (tried A-3 Trim, A-4 DigitPos); read-only-slot rejected: [joinir/freeze] [pattern2/body_local_slot/contract/not_readonly] 'seg' must be read-only (assignment detected in loop body)` - **Expected**: Stage-B compile succeeds (bundle_resolver loop compiles) - **Actual**: MIR compilation error (LoopBodyLocal "seg" cannot be promoted - A-3/A-4 patterns not detected) - **Reproduce**: ```bash ./tools/smokes/v2/run.sh --profile quick # または bash tools/smokes/v2/profiles/quick/core/core_direct_array_oob_set_rc_vm.sh ``` - **Root Cause**: Pattern2 の LoopBodyLocal promotion(A-3 Trim / A-4 DigitPos)に依存しており、Stage‑B の bundle_resolver 系のループで露出している。 - **Next Action**: **Phase 260 完了**(P0.3まで完了)→ **今後は機能側のPhaseへ**(Pattern2 LoopBodyLocal promotion 機能実装) - **分類**: JoinIR Pattern2 機能拡張(compiler機能側、CFG基盤整備は完了) ### 次の次(構造で迷子を潰す) Phase 263(Pattern2 LoopBodyLocal “seg”)が片付いたら、Pattern2 の「Reject/continue/fallback の揺れ」を構造で潰す。 - ねらい: “Reject でも続行して後段で落ちる” を型/APIで不可能にする - 方針(最小): - `PromoteStepBox::try_promote(...) -> Result` - `PromoteDecision::{Promoted, NotApplicable, Freeze}` - orchestrator が `NotApplicable` を受け取ったら **Pattern2 全体を `Ok(None)` で抜けて fallback**(SSOT) - “部分続行” を禁止(Fail-Fast/SSOTを維持) ## 2025-12-21:Phase 260 P2(BasicBlock.jump_args 完全削除)✅ - **EdgeCFG SSOT確立完了**: `BasicBlock.jump_args` フィールド削除、edge-args SSOTをterminator operand側に一本化 - **フィールド変更**: `jump_args` → `return_env`(Return専用metadata、terminator operandなし) - **API簡略化**: legacy helper 8個削除、terminator更新API保持(successors同期漏れ防止) - **Verification簡素化**: dual-source検証削除(cfg.rs 62行削除) - **テスト結果**: - cargo test --lib: 1368 PASS - quick smoke: 45/46 PASS - phase258 tail call: PASS(Return env保持確認) - **検証**: `rg 'jump_args' src/` = 0件(コメント除く) - **修正ファイル**: 9ファイル(basic_block.rs、handlers 4件、verification、test) - **詳細**: `docs/development/current/main/phases/phase-260/README.md` ## 2025-12-21:Phase 260 P0.2/P0.3(モジュール化大工事)✅ - **P0.2**: instruction_rewriter モジュール化 - Commits: `cbed040a7`, `aa3fdf3c1`, `c2e8099ff`, `84cd653ae`, `875bfee1b`, `666de9d3e` - 抽出: exit_collection, block_allocator, merge_variable_handler, call_generator, handlers/(8ファイル) - **P0.3**: joinir_block_converter モジュール化 - Commits: `e7f9adcfe`, `2c01a7335` - Phase 1: terminator_builder, block_finalizer - Phase 2: handlers/(call, jump, conditional_method_call, if_merge, nested_if_merge) - **成果**: 15モジュール、約3941行、53単体テスト全てpass、45/46統合テストpass - **SSOT維持確認**: jump_args直参照ゼロ、out_edges()/edge_args_to() SSOT維持 - **詳細**: `docs/development/current/main/phases/phase-260/README.md` ## 2025-12-20:Phase 260 P0/P0.1(edge-args Strangler)✅ - P0: MIR terminator の edge-args 併存導入(読む側 SSOT を `out_edges()`/`edge_args_to()` へ寄せた) - P0.1: legacy layout の未設定を禁止(verify fail-fast)+ terminator 直代入を `set_terminator*()` へ寄せた - Commits: - P0: `4dfe3349b` - P0.1: `1fe5be347` ## 2025-12-21:Phase 259 P0(Pattern8 BoolPredicateScan)✅ - Phase 259 README: `docs/development/current/main/phases/phase-259/README.md` - Result: `StringUtils.is_integer/1` を Pattern8(新規)で受理 - Fixtures: - `apps/tests/phase259_p0_is_integer_min.hako`(expected exit 7) - Smokes: - `tools/smokes/v2/profiles/integration/apps/phase259_p0_is_integer_vm.sh` ✅ PASS - `tools/smokes/v2/profiles/integration/apps/phase259_p0_is_integer_llvm_exe.sh`(LLVM harness 要設定) - Key Implementation: - `src/mir/builder/control_flow/joinir/patterns/pattern8_scan_bool_predicate.rs`(新規) - `src/mir/join_ir/lowering/scan_bool_predicate_minimal.rs`(新規) - Design Decision: Pattern8 を新設(Pattern6 拡張ではなく分離) - Pattern6: "見つける" scan(返り値: Integer) - Pattern8: "全部検証する" predicate scan(返り値: Boolean) - Note: json_lint_vm はまだ FAIL だが、is_integer 自体は解決済み。残りは nested-loop with break パターン(Pattern2 の別問題) ## 2025-12-20:Phase 258(index_of_string/2 dynamic window scan)✅ - Phase 258 README: `docs/development/current/main/phases/phase-258/README.md` - Result: `index_of_string/2` を JoinIR で受理し、quick の first FAIL を `is_integer/1` へ進めた ## 2025-12-20:Phase 257(Pattern6 reverse scan + PHI/CFG stabilization)✅ - Phase 257 README: `docs/development/current/main/phases/phase-257/README.md` - Result: `last_index_of/2` を Pattern6(reverse scan)で受理し、PHI predecessor mismatch を fail-fast + 自動補正で根治 ## 2025-12-19:Phase 146/147 完了 ✅ - Phase 146 README: `docs/development/current/main/phases/phase-146/README.md` - Fixtures: - `apps/tests/phase146_p0_if_cond_unified_min.hako`(P0: pure cond, expected exit 7) - `apps/tests/phase146_p1_if_cond_intrinsic_min.hako`(P1: `s.length() == 3`, expected exit 7) - Smokes: - `tools/smokes/v2/profiles/integration/apps/phase146_p0_if_cond_unified_vm.sh` - `tools/smokes/v2/profiles/integration/apps/phase146_p0_if_cond_unified_llvm_exe.sh` - `tools/smokes/v2/profiles/integration/apps/phase146_p1_if_cond_intrinsic_vm.sh` - `tools/smokes/v2/profiles/integration/apps/phase146_p1_if_cond_intrinsic_llvm_exe.sh` - Flags: - `HAKO_ANF_DEV=1`(dev-only: ANF routing 有効化) - `HAKO_ANF_ALLOW_PURE=1`(dev-only: PureOnly scope で ANF 有効化) ## 2025-12-19:Phase 251 Fix(JoinIR 条件変数抽出 / デバッグ出力整理)✅ - Phase 251 README: `docs/development/current/main/phases/phase-251/README.md` - Fix: - `collect_variables_recursive()` を拡張し、`MethodCall/FieldAccess/Index/Call` の基底変数を ConditionEnv に登録できるようにした - `loop_with_if_phi_if_sum.rs` の無条件 `eprintln!` を `is_joinir_debug()` ガードに移した(デフォルトは clean output) - Status: - 元の回帰(`arr.length()` の `arr` が ConditionEnv に入らない): 解決 - `--profile quick` の `json_lint_vm` は別件で失敗が残る(JoinIR Pattern2 の break 条件で `MethodCall` が未対応) ## 2025-12-19:Phase 252 P0/P1(Pattern2 break 条件: `this.methodcall`)✅ - Phase 252 README: `docs/development/current/main/phases/phase-252/README.md` - Status: - `cargo check` は通過(0 errors) - `--profile quick` は次の FAIL が残る → Phase 253(`[joinir/mutable-acc-spec]`) ## 2025-12-19:Phase 255(Multi-param loop wiring)✅ - Phase 255 README: `docs/development/current/main/phases/phase-255/README.md` - Status: - Pattern6/index_of が VM/LLVM で PASS - `loop_invariants` を導入して ConditionOnly 誤用を根治 ## 2025-12-19:Phase 256(StringUtils.split/2 可変 step ループ)✅ - Phase 256 README: `docs/development/current/main/phases/phase-256/README.md` - Status: - `StringUtils.split/2` は VM `--verify` / integration smoke まで PASS - `--profile quick` の最初の FAIL は Phase 257(`StringUtils.last_index_of/2`)へ移動 - 設計SSOT: `docs/development/current/main/design/join-explicit-cfg-construction.md` - 直近の主要fix: - `ValueId(57)` undefined は根治(原因は `const_1` 未初期化)。 - SSA undef(`%49/%67`)は P1.7 で根治(continuation 関数名の SSOT 不一致)。 - P1.8で ExitLine/jump_args の余剰許容と関数名マッピングを整流。 - P1.9で `JoinInst::Jump` を tail call として bridge に落とし、`jump_args` を SSOT として保持。 - P1.10で DCE が `jump_args` を used 扱いし、`instruction_spans` を同期(SPAN MISMATCH 根治)。 - P1.11で ExitArgsCollector の expr_result slot 判定を明確化し、split が `--verify` / integration smoke まで PASS。 - P1.5-DBG: boundary entry params の契約チェックを追加(VM実行前 fail-fast)。 - P1.6: 契約チェックの薄い集約 `run_all_pipeline_checks()` を導入(pipeline の責務を縮退)。 - P1.13: Pattern2 boundary entry params を `join_module.entry.params` SSOT へ寄せた(ValueId 推測生成の撤去)。 - P1.13.5(= Phase 256.8.5): Boundary SSOT 統一(Pattern4/6/7 横展開 + hardcoded ValueId/PARAM_MIN 撤去)。 - Known issue(非ブロッカー): Pattern7 integration smoke の `phi predecessor mismatch` は残存(今回の修正とは独立)。 ## 2025-12-20:Phase 257(last_index_of early return loop)🔜 - Phase 257 README: `docs/development/current/main/phases/phase-257/README.md` - Goal: `StringUtils.last_index_of/2` を JoinIR で受理し、`--profile quick` を緑に戻す - Investigation(最小再現/論点): `docs/development/current/main/investigations/phase-257-last-index-of-loop-shape.md` - Status: Pattern6 reverse scan + PHI/CFG 安定化は完了(最初の FAIL は次へ移動) - Current first FAIL: `json_lint_vm / StringUtils.index_of_string/2`(dynamic window scan, unsupported) ## 2025-12-20:Phase 258(is_integer nested-if + loop)🔜 - Phase 258 README: `docs/development/current/main/phases/phase-258/README.md` - Status: `index_of_string/2` を対象(dynamic window scan) ## 2025-12-20:Phase 259(is_integer nested-if + loop)🔜 - Phase 259 README: `docs/development/current/main/phases/phase-259/README.md` ## 2025-12-19:Phase 254(index_of loop pattern)✅ 完了(Blocked by Phase 255) - Phase 254 README: `docs/development/current/main/phases/phase-254/README.md` - Status: **Pattern 6 実装完了、ただし実行失敗(Phase 255 で unblock)** - 完了項目: - ✅ Pattern 6 DetectorBox 実装(`Pattern6_ScanWithInit MATCHED`) - ✅ extract_scan_with_init_parts() - 構造抽出 - ✅ scan_with_init_minimal.rs - JoinIR lowerer(main/loop_step/k_exit 生成) - ✅ MirBuilder 統合 - boundary 構築と merge 実行 - ✅ substring を BoxCall として init-time に emit - ブロッカー: - JoinIR→MIR merge/boundary が複数ループ変数(s, ch, i)に未対応 - PHI ノードが 1つしか作られず、undefined value エラー - **Phase 254 の受け入れ境界**: Pattern 6 検出+JoinIR 生成まで ✅ - **実行 PASS は Phase 255 の範囲** ## 2025-12-19:Phase 253(mutable-acc-spec)✅ - Phase 253 README: `docs/development/current/main/phases/phase-253/README.md` - Goal: `--profile quick` を緑に戻す(対処療法なし、analyzer 契約の整理で直す) ## 2025-12-19:Phase 145-anf P0/P1/P2 完了 ✅ - SSOT docs: - `docs/development/current/main/phases/phase-145-anf/README.md` - `docs/development/current/main/phases/phase-144-anf/INSTRUCTIONS.md` - 実装 SSOT: - `src/mir/control_tree/normalized_shadow/anf/` - 入口(接続箇所 SSOT): `src/mir/control_tree/normalized_shadow/common/expr_lowerer_box.rs` - 環境変数: - `HAKO_ANF_DEV=1`(dev-only: ANF 有効化) - `HAKO_ANF_STRICT=1`(dev-only: ANF fail-fast) - Fixtures & smokes(VM/LLVM EXE parity): - `apps/tests/phase145_p1_anf_length_min.hako` → exit 12 - `apps/tests/phase145_p2_compound_expr_binop_min.hako` → exit 18 - `apps/tests/phase145_p2_compound_expr_double_intrinsic_min.hako` → exit 5 ## 2025-12-19:Phase 143-loopvocab P2 完了 ✅ - 対象: else 対称化(B-C / C-B) - Fixtures & smokes(VM/LLVM EXE parity): - `apps/tests/phase143_p2_loop_true_if_bc_min.hako` → exit 8 - `apps/tests/phase143_p2_loop_true_if_cb_min.hako` → exit 9 ## 2025-12-19:Phase 143 実行系契約修正 ✅ **問題**: normalized_helpers が env params を `ValueId(1,2...)` で割り当てていた(PHI Reserved 領域 0-99)。 **根本原因**: JoinValueSpace 契約では Param 領域は 100-999。4つの normalized shadow モジュールが全て間違った領域に params を割り当てていた。 **修正**: - `NormalizedHelperBox::alloc_env_params_param_region()` 新規追加(100+ 開始) - 4 ファイルの normalized shadow 生成を更新: - `loop_true_if_break_continue.rs` - `loop_true_break_once.rs` - `if_as_last_join_k.rs` - `post_if_post_k.rs` - `instruction_rewriter.rs` 型ミスマッチ修正(`func.signature.params` → `func.params`) **検証**: - VM exit=7 ✅(phase143_loop_true_if_break_vm.sh PASS) - LLVM EXE exit=7 ✅(phase143_loop_true_if_break_llvm_exe.sh PASS、timeout 解消) - Unit tests: 69/69 PASS **ValueId Space Contract (Phase 201)**: | Region | Range | Purpose | |--------|-------|---------| | PHI Reserved | 0-99 | Loop header PHI dst | | **Param** | **100-999** | **env params (flag, counter, etc.)** | | Local | 1000+ | Const, BinOp, condition results | ## 2025-12-19:Phase 143.5 + P1 完了 ✅ **Phase 143.5: NormalizedHelperBox 箱化(リファクタリング)** - 目的: 120+ 行のヘルパー関数重複を消去(4 ファイル共通化) - 実装: `src/mir/control_tree/normalized_shadow/common/normalized_helpers.rs` (151行+6テスト) - 効果: 136行追加 - 149行削除 = **-13行**(保守性大幅向上) - 統計: 67/67 tests PASS(新規テスト 6個含む) - 検証: cargo check 0 errors, cargo test 100% green **Phase 143 P1: Continue Support(条件付きループ継続)** - 目的: `loop(true) { if(cond_pure) continue }` パターン追加 - 実装: Loop-If-Exit contract enum 駆動(break/continue 弁別) - 変更: - `extract_pattern_shape()`: Err-based pattern matching to LoopIfExitShape - `extract_exit_action()`: Break/Continue を enum variant として識別 - `loop_cond_check`: match shape.then で Jump target を動的決定 - Fixtures & Tests: - `apps/tests/phase143_loop_true_if_continue_min.hako` - `tools/smokes/v2/profiles/integration/apps/phase143_loop_true_if_continue_vm.sh` - `tools/smokes/v2/profiles/integration/apps/phase143_loop_true_if_continue_llvm_exe.sh` - 検証: 契約ベース(shape.validate_for_p1() で P1 制約チェック) - 注記: Phase 131 Pattern matching Issue 既知(ルーティング層の pre-existing failure) ## 2025-12-19:Phase 143-loopvocab P0 完了 ✅ **Phase 143-loopvocab P0: Conditional Break Vocabulary Extension** - 目的: `loop(true) { if(cond_pure) break }` パターンを Normalized shadow で実装(Phase 131 の条件付き拡張) - 仕様: - Loop条件: `true` リテラルのみ - ループ本体: 単一 if statement(else なし) - If then: `break` のみ(no continue, no nested if) - 条件: pure expression のみ(変数/リテラル/算術/比較、Method call なし) - Out-of-scope は `Ok(None)` で graceful fallback - 実装 SSOT: - `src/mir/control_tree/normalized_shadow/loop_true_if_break_continue.rs` - 6-function JoinModule(main → loop_step → loop_cond_check → Jump/Call → k_exit → Ret) - Jump: if true → k_exit, if false → fall through to Call(loop_step) - Fixtures: - `apps/tests/phase143_loop_true_if_break_min.hako`(expected exit code 7) - Smoke tests: - VM: `tools/smokes/v2/profiles/integration/apps/phase143_loop_true_if_break_vm.sh` ✅ PASS - LLVM EXE: `tools/smokes/v2/profiles/integration/apps/phase143_loop_true_if_break_llvm_exe.sh` ✅ PASS - Regression: Phase 131-142 green(no regressions) - 統計: +400 lines(loop_true_if_break_continue.rs), 0 change to existing code - 入口: `docs/development/current/main/phases/phase-143-loopvocab/README.md` ## 2025-12-19:Phase 142-loopstmt P0 完了 ✅ **Phase 142-loopstmt P0: Statement-Level Loop Normalization** - 目的: 正規化単位を "block suffix" から "statement (loop 1個)" へ寄せてパターン爆発を防ぐ - 変更: - PlanBox: loop(true) に対して常に loop_only() を返す(consumed=1) - SuffixRouter: LoopOnly を受け入れて実行 - build_block: consumed 後も後続文を処理(break 削除) - 実装 SSOT: - `src/mir/builder/control_flow/normalization/plan_box.rs` - `src/mir/builder/control_flow/joinir/patterns/policies/normalized_shadow_suffix_router_box.rs` - `src/mir/builder/stmts.rs` - Refactoring: - LoopWithPost variant を deprecated(4 commits) - suffix_router コメント更新 - README 更新 - Tests: - Fixture: `apps/tests/phase142_loop_stmt_only_then_return_length_min.hako`(exit code 3) - VM smoke: ✅ PASS - Unit tests: ✅ 10/10 passed - Regression: ✅ Phase 131, 141 green - 統計: -38 lines net (code reduction success!) - 入口: `docs/development/current/main/phases/phase-142-loopstmt/README.md` ⚠️ **Note**: Phase 142 (Canonicalizer Pattern Extension) とは別物。SSOT 衝突回避のため phase-142-loopstmt として独立管理。 ## 2025-12-19:Phase 141 P1.5 完了 ✅ **Phase 141 P1.5: KnownIntrinsic registry + available_inputs 3-source merge + diagnostics** - 目的: “既知 intrinsic だけ” を SSOT 化しつつ、suffix 正規化が prefix の変数を見失わないようにする(既定挙動不変)。 - Task B(バグ修正): `AvailableInputsCollectorBox::collect(.., prefix_variables)` を追加し、Function params > Prefix variables > CapturedEnv の 3-source merge に変更 - Task A(SSOT化): `KnownIntrinsicRegistryBox` を追加し、intrinsic の metadata(name/arity/type_hint)を `known_intrinsics.rs` に集約 - Task C(診断): `OutOfScopeReason::IntrinsicNotWhitelisted` を追加し、Call/MethodCall の out-of-scope 理由を精密化 - 実装 SSOT: - `src/mir/control_tree/normalized_shadow/available_inputs_collector.rs` - `src/mir/control_tree/normalized_shadow/common/known_intrinsics.rs` - `src/mir/control_tree/normalized_shadow/common/expr_lowerer_box.rs` - `src/mir/control_tree/normalized_shadow/common/expr_lowering_contract.rs` - `src/mir/builder/control_flow/normalization/execute_box.rs` - 設計 SSOT: - `docs/development/current/main/design/normalized-expr-lowering.md` ## 2025-12-19:Phase 141 P1 完了 ✅ **Phase 141 P1: KnownIntrinsicOnly (length0)** - 目的: impure 導入の安全なオンランプとして、既知 intrinsic(小さな allowlist)のみを ExprLowerer に追加 - 仕様: - `ExprLoweringScope::WithImpure(ImpurePolicy::KnownIntrinsicOnly)` でのみ `receiver.length()` を lowering - それ以外の Call/MethodCall は引き続き `Ok(None)`(既定挙動不変) - Fixture: - `apps/tests/phase141_p1_if_only_post_k_return_length_min.hako`(expected exit code 3) - Smoke tests: - VM: `tools/smokes/v2/profiles/integration/apps/phase141_p1_if_only_post_k_return_length_vm.sh` - LLVM EXE: `tools/smokes/v2/profiles/integration/apps/phase141_p1_if_only_post_k_return_length_llvm_exe.sh` - 入口: `docs/development/current/main/phases/phase-141/README.md` ## 2025-12-19:Phase 141 P0 完了 ✅ **Phase 141 P0: Impure Extension Contract (Call/MethodCall stays out-of-scope)** - 目的: 次フェーズの Call/MethodCall 導入に向けて、pure/impure 境界の contract(SSOT)を型で固定 - SSOT: - `src/mir/control_tree/normalized_shadow/common/expr_lowering_contract.rs` - `src/mir/control_tree/normalized_shadow/common/expr_lowerer_box.rs` - 仕様: Call/MethodCall は引き続き `Ok(None)`(既定挙動不変) - 入口: `docs/development/current/main/phases/phase-141/README.md` ## 2025-12-19:Phase 140 完了 ✅ **Phase 140: NormalizedExprLowererBox (pure expressions)** - 目的: “return の形追加” をやめて、pure expression を AST walker で一般化して収束させる - SSOT: - `src/mir/control_tree/normalized_shadow/common/expr_lowerer_box.rs` - `src/mir/control_tree/normalized_shadow/common/return_value_lowerer_box.rs` - 仕様: - pure のみ(Variable / Integer&Bool literal / unary(not,-) / arith(+,-,*,/) / compare(==,!=,<,<=,>,>=)) - Call/MethodCall など impure は `Ok(None)`(Phase 141+) - 入口: `docs/development/current/main/phases/phase-140/README.md` ## 2025-12-19:Phase 139 完了 ✅ **Phase 139: post-if `post_k` Return Lowering Unification** - 目的: if-only `post_k` 側の return lowering を `ReturnValueLowererBox` に統一し、loop/if の出口を一本化 - 実装: - `src/mir/control_tree/normalized_shadow/post_if_post_k.rs` の return lowering を `ReturnValueLowererBox::lower_to_value_id()` に委譲 - out-of-scope は `Ok(None)` でフォールバック(既定挙動不変・dev-only) - Fixture: - `apps/tests/phase139_if_only_post_k_return_add_min.hako`(expected exit code 4) - Smoke tests: - VM: `tools/smokes/v2/profiles/integration/apps/phase139_if_only_post_k_return_add_vm.sh` - LLVM EXE: `tools/smokes/v2/profiles/integration/apps/phase139_if_only_post_k_return_add_llvm_exe.sh` - 入口: `docs/development/current/main/phases/phase-139/README.md` ## 2025-12-18:Phase 138 完了 ✅ **Phase 138: ReturnValueLowererBox - Return Lowering SSOT** - 目的: Return lowering logic を共有 Box として抽出し SSOT を確立 - 実装: - Created `common/return_value_lowerer_box.rs` (~300 lines) - Migrated `loop_true_break_once.rs` to use Box (2 call sites) - 5 comprehensive unit tests for all patterns - Code reduction: ~115 lines removed from loop_true_break_once.rs - SSOT: - `ReturnValueLowererBox::lower_to_value_id()` - Supported: Variable, Integer literal, Add expression (x + 2, 5 + 3) - Fallback: Out-of-scope patterns return `Ok(None)` - Tests: - 5 new unit tests: variable, integer literal, add (var+int), add (int+int), fallback (subtract) - All regressions PASS: Phase 137/97/131/135/136 - Design Decision: - Phase 138 P0 migrated loop paths only - Phase 139 P0 will unify post_if_post_k.rs for complete SSOT - Architecture Impact: - Single location for return lowering improvements - Isolated unit tests for return lowering logic - Easy to add new return patterns in one location - 入口: `docs/development/current/main/phases/phase-138/README.md` --- ## 2025-12-18:Phase 137 完了 ✅ **Phase 137: loop(true) break-once with return add expression** - 目的: Phase 136 を拡張し、return 時に最小 add 式をサポート - 仕様: - `return x + 2`(variable + integer literal)→ exit code 3 - `return 5 + 3`(integer literal + integer literal)→ exit code 8 - `loop(true) { x = 1; break }; x = x + 10; return x + 2` → exit code 13 - 実装: - `src/mir/control_tree/normalized_shadow/loop_true_break_once.rs`(`lower_return_value_to_vid()` 行 638-743, BinaryOp Add at 行 673) - BinaryOp Add パターン追加(LHS: Variable or Integer literal, RHS: Integer literal only) - Ok(None) fallback for out-of-scope patterns(`return x + y`, `return x - 2` 等) - Return Value Lowering SSOT: - Documentation: `loop_true_break_once.rs`(行 29-46, module-level comment) - Boxification trigger: 2+ files で同一 return lowering logic が必要になった時 - Fixtures: - `phase137_loop_true_break_once_return_add_min.hako`(期待: exit code 3) - `phase137_loop_true_break_once_return_add_const_min.hako`(期待: exit code 8) - `phase137_loop_true_break_once_post_return_add_min.hako`(期待: exit code 13) - Smoke tests: - VM: 3/3 PASS - LLVM EXE: 3/3 PASS - Regression: - Phase 97: 2/2 PASS(next_non_ws, json_loader_escape) - Phase 131/135/136: 3/3 PASS - 設計判断(Approach A 採用): - 直接拡張(boxification なし)、変更スコープ小 - post_if_post_k.rs は未変更(責任分離) - 入口: `docs/development/current/main/phases/phase-137/README.md` --- ## 2025-12-18:Phase 136 完了 ✅ **Phase 136: loop(true) break-once with return literal** - 目的: Phase 131-135 を拡張し、return integer literal をサポート - 仕様: - `loop(true) { x = 1; break }; return 7` → exit code 7 - `loop(true) { x = 1; break }; x = x + 2; return 7` → exit code 7 - PHI禁止維持、dev-only、既定挙動不変 - 実装: - `src/mir/control_tree/normalized_shadow/loop_true_break_once.rs`(`lower_return_value_to_vid()` 行 638-743, Integer literal at 行 661) - Integer literal パターン: Const generation(Phase 123 パターン再利用) - Ok(None) fallback for out-of-scope patterns(`return "hello"`, `return 3.14` 等) - Fixtures: - `phase136_loop_true_break_once_return_literal_min.hako`(期待: exit code 7) - `phase136_loop_true_break_once_post_return_literal_min.hako`(期待: exit code 7) - Smoke tests: - VM: 2/2 PASS - LLVM EXE: 2/2 PASS - Regression: - Phase 131: 2/2 PASS - Phase 135: 2/2 PASS - 入口: `docs/development/current/main/phases/phase-136/README.md` --- ## 2025-12-18:Phase 135 P0 完了 ✅ **Phase 135 P0: Normalization Plan Suffix Detection Generalization** - 目的: NormalizationPlanBox の suffix 検出を一般化し、post-loop assign が 0 回でも OK に - 背景: - Phase 133 までは `loop + assign+ + return`(assign 1回以上必須) - Phase 131 は `loop` のみ(return なし) - ギャップ: `loop + return`(0 assign)が別経路 - 改善: - `loop + assign* + return`(N >= 0 assignments)を統一パターンとして検出 - Phase 131 と Phase 132-133 を `LoopWithPost { post_assign_count }` enum で統一 - Phase 131 (loop-only, no return) は `PlanKind::LoopOnly` として独立維持 - 実装: - `src/mir/builder/control_flow/normalization/plan_box.rs`(検出ロジック修正のみ) - `post_assign_count >= 1` チェックを削除 → `>= 0` を許容 - `execute_box.rs` は変更なし(既存ロジックが 0 assigns を自然にサポート) - Fixture: `apps/tests/phase135_loop_true_break_once_post_empty_return_min.hako`(期待: exit code 1) - Smoke tests: - `phase135_loop_true_break_once_post_empty_return_vm.sh` PASS - `phase135_loop_true_break_once_post_empty_return_llvm_exe.sh` PASS - Regression: - Phase 131: 2/2 PASS(VM + LLVM EXE) - Phase 133: 2/2 PASS(VM + LLVM EXE) - Unit tests: 9/9 PASS(plan_box module) - 設計原則: - **最小変更**: plan_box.rs の検出条件のみ変更 - **SSOT 維持**: 検出ロジックは plan_box.rs に集約 - **Box-First**: PlanBox(what)と ExecuteBox(how)の責任分離維持 - 入口: `src/mir/builder/control_flow/normalization/README.md`(Phase 135 セクション追加) ## 2025-12-18:Phase 133 完了 ✅ **Phase 133: loop(true) break-once + multiple post-loop assigns(dev-only)** - 目的: Phase 132 を拡張し、post-loop で複数の assign を受理(PHI-free 維持) - 仕様: - `loop(true) { x = 1; break }; x = x + 2; x = x + 3; return x` は exit code `6`(VM/LLVM EXE parity) - post_nodes 検出を `len() == 2` から `len() >= 2` に拡張 - 複数 assign を iterative に lower(LegacyLowerer::lower_assign_stmt 再利用) - 実装: - `src/mir/control_tree/normalized_shadow/loop_true_break_once.rs`(3箇所編集、~30行追加) - Pattern detection: all_assigns + ends_with_return - Post-loop lowering: for loop で複数 assign 処理 - SSOT: env_post_k が最終値を保持(ExitMeta に反映) - Fixture: `apps/tests/phase133_loop_true_break_once_post_multi_add_min.hako`(期待: 6) - Smoke: - `phase133_loop_true_break_once_post_multi_add_vm.sh` PASS - `phase133_loop_true_break_once_post_multi_add_llvm_exe.sh` PASS - Regression: Phase 132/131/97 維持確認(全 PASS) - Unit tests: 1176/1176 PASS - 入口: `docs/development/current/main/phases/phase-133/README.md` ## 2025-12-18:Phase 130 完了 ✅ **Phase 130: if-only Normalized "Small Expr/Assign" Expansion(dev-only)** - 目的: post_k 内の最小 post-if 計算(`x = x + 3; return x`)を Normalized で通す(PHI禁止) - 実装: - P1: Assign(Variable) - `x = y` サポート(env map 直接更新) - P2: Assign(Add) - `x = x + ` サポート(Const + BinOp Add) - P3: Verifier - env map が env layout(writes + inputs)外の変数を導入しないことを検証 - `src/mir/control_tree/normalized_shadow/legacy/mod.rs` (lower_assign_stmt 拡張) - `src/mir/control_tree/normalized_shadow/normalized_verifier.rs` (verify_env_writes_discipline 追加) - Fixture: `apps/tests/phase130_if_only_post_if_add_min.hako`(期待出力: 5\n4) - Smoke: `phase130_if_only_post_if_add_vm.sh` PASS - LLVM EXE smoke: `phase130_if_only_post_if_add_llvm_exe.sh`(LLVM 前提が無い環境では SKIP) - Regression: Phase 129/128 維持確認(全 PASS) - Unit tests: 1155/1155 PASS - 入口: `docs/development/current/main/phases/phase-130/README.md` ## 2025-12-18:Phase 129-C 完了 ✅ **Phase 129-C: post-if / post_k continuation(dev-only)** - post-if(`if { x=2 }; return x`)を post_k continuation で表現 - join_k が env merge → TailCall(post_k, merged_env) - post_k が post-if statements 実行 → Ret - PHI禁止: Normalized IR 内に PHI 相当を入れず env 引数で合流 - 実装: - `src/mir/control_tree/normalized_shadow/post_if_post_k.rs`(392行、新規) - `builder.rs` に PostIfPostKBuilderBox 統合 - `normalized_verifier.rs` に post_k 構造検証追加 - `parity_contract.rs` に StructureMismatch 追加 - Fixture: `apps/tests/phase129_if_only_post_if_return_var_min.hako` - Smoke: `phase129_if_only_post_if_return_var_vm.sh` PASS - Regression: Phase 129-B, 128 維持確認(全 PASS) - Unit tests: 1155/1155 PASS - 入口: `docs/development/current/main/phases/phase-129/README.md` ## 2025-12-18:Phase 132 完了 ✅ **Phase 132: loop(true) break-once + post-loop minimal(dev-only)** - 目的: Phase 131 を拡張し、ループ後の最小 post 計算まで Normalized shadow で固定(PHI-free 維持) - 仕様: - `loop(true) { x = 1; break }; x = x + 2; return x` は exit code `3`(VM/LLVM EXE parity) - post_k continuation で post-loop statements を処理 - 実装: - **P0**: post_k 生成(loop_true_break_once.rs 拡張) - **P0.5**: StepTree が post-loop statements を保持(suffix router box 追加) - **P1**: k_exit continuation 分類修正(構造ベースの判定) - **R0**: Continuation SSOT 一本化 + legacy 隔離 + docs 整備 - SSOT: - `JoinInlineBoundary::default_continuations()` - continuation ID の集約 - `src/mir/builder/control_flow/joinir/merge/README.md` - merge 契約明文化 - `src/mir/builder/control_flow/joinir/legacy/README.md` - legacy 撤去条件 - テスト配置: `src/mir/builder/control_flow/joinir/merge/tests/continuation_contract.rs` - 検証: - `bash tools/smokes/v2/profiles/integration/apps/phase132_loop_true_break_once_post_add_vm.sh` - `bash tools/smokes/v2/profiles/integration/apps/phase132_loop_true_break_once_post_add_llvm_exe.sh` - 回帰: Phase 131/97 維持確認(全 PASS) - 入口: `docs/development/current/main/phases/phase-132/README.md` ## 2025-12-18:Phase 131 P2 完了 ✅ **Phase 131: loop(true) break-once Normalized(dev-only)** - 目的: Normalized shadow の最小ループを VM/LLVM EXE 両方で動かし、更新値が外に見えることまで固定 - 仕様: - `loop(true) { x = 1; break }; return x` は exit code `1` - DirectValue mode(PHI-free)で exit 値を `variable_map` に再接続 - 検証: - `bash tools/smokes/v2/profiles/integration/apps/phase131_loop_true_break_once_vm.sh` - `bash tools/smokes/v2/profiles/integration/apps/phase131_loop_true_break_once_llvm_exe.sh` - 環境: WSL の一時的な EXDEV(`Invalid cross-device link`)は `wsl --shutdown` 再起動で解消、上記 + `phase97_next_non_ws_llvm_exe.sh` まで PASS - 入口: `docs/development/current/main/phases/phase-131/README.md` ## 2025-12-18:Phase 127 完了 ✅ **Phase 127: unknown-read strict Fail-Fast(dev-only)** - unknown-read = reads - (writes ∪ inputs) を検出 - strict: `freeze_with_hint("phase127/unknown_read/", ...)` で即停止(hint必須) - dev-only non-strict: 理由ログ(tag + count + 先頭数件) - 入口: `docs/development/current/main/phases/phase-127/README.md` ## 2025-12-18:Phase 128 完了 ✅ **Phase 128: if-only partial assign keep/merge in Normalized (dev-only)** - StepStmtKind::Assign に value_ast 追加(Phase 128) - Normalized builder に Assign(int literal) 対応(env 更新) - Fixture: phase128_if_only_partial_assign_normalized_min.hako(簡易版) - Smoke: phase128_if_only_partial_assign_normalized_vm.sh(PASS) - Regression: Phase 121-126, 118 維持確認(全 PASS) - Unit tests: 1165/1165 PASS - 入口: `docs/development/current/main/phases/phase-128/README.md` - 実装: - `src/mir/control_tree/step_tree.rs` (value_ast 追加、14行追加) - `src/mir/control_tree/normalized_shadow/builder.rs` (Assign lowering、87行追加) - Note: 完全な join_k continuation は future work(Phase 128 は基本構造確立) ## 2025-12-18:Phase 126 完了 ✅ **Phase 126: available_inputs SSOT wiring (dev-only)** - AvailableInputsCollectorBox 実装(function params + CapturedEnv 収集) - try_lower_if_only() に available_inputs 配線(dev-only) - EnvLayout.inputs が実際に使用されるようになった - Fixture 強化: reads-only 変数の return 解決を確認 - Regression: Phase 121-125, 118 維持確認(全 PASS) - Unit tests: 28/28 PASS (including 5 new AvailableInputsCollectorBox tests) - Integration smoke: PASS (phase125_if_only_return_input_vm.sh, exit code 7) - 入口: `docs/development/current/main/phases/phase-126/README.md` - 実装: - `src/mir/control_tree/normalized_shadow/available_inputs_collector.rs` (143行、新規) - `src/mir/control_tree/normalized_shadow/builder.rs` (available_inputs 配線) - `src/mir/builder/calls/lowering.rs` (AvailableInputsCollectorBox::collect() 呼び出し) ## 2025-12-18:Phase 125 P2-P5 完了 ✅ **Phase 125 P2-P5: Reads-Only Env Inputs (dev-only, structure)** - EnvLayout 導入(writes + inputs の 2 レーン化) - from_contract: reads ∩ available_inputs で inputs を決定(決定的順序) - Return(Variable) 解決拡張: writes or inputs から解決 - Fail-Fast with hint: env に無い変数は構造化エラー - Unit tests: 18/18 PASS (including new test_return_variable_from_inputs_stub) - Integration smoke: PASS (phase125_if_only_return_input_vm.sh, exit code 7) - Regression: Phase 121-124, 118 維持確認(全 PASS) - 入口: `docs/development/current/main/phases/phase-125/README.md` - 実装: - `src/mir/control_tree/normalized_shadow/builder.rs` (EnvLayout, 186行追加) - Note: P3 (available_inputs wiring) 未実装、inputs は空(structure-only) ## 2025-12-18:Phase 124 完了 ✅ **Phase 124: Normalized reads facts + Return(Variable from env)(dev-only)** - StepTreeFacts に reads 追加(Variable 参照を AST から抽出) - StepTreeContract signature に reads 反映(決定性維持) - env マッピング(変数名 → ValueId)を writes から生成 - Return(Variable) サポート: env にある変数のみ(writes 由来) - env に無い Variable は Fail-Fast エラー(phase124 error → Ok(None) fallback) - Box-first modularization: extract_variables_from_ast() で SSOT 化 - Unit tests: 1159 tests PASS (including test_return_variable_from_env) - Integration smoke: PASS (`phase124_if_only_return_var_vm.sh`, exit code 7 許容) - 回帰: Phase 121/123/118 維持確認 - 入口: `docs/development/current/main/phases/phase-124/README.md` - 実装: - `src/mir/control_tree/step_tree_facts.rs` (reads 追加、76行) - `src/mir/control_tree/step_tree_contract_box.rs` (reads 反映、101行) - `src/mir/control_tree/step_tree.rs` (extract_variables_from_ast 追加、612行) - `src/mir/control_tree/normalized_shadow/builder.rs` (env マッピング追加、837行) ## 2025-12-18:Phase 123 完了 ✅ **Phase 123: if-only Normalized semantics(dev-only)** - Return(Integer literal) → `Const + Ret(Some(vid))` 生成 - Return(Variable) → `Ok(None)` (graceful degradation, Phase 124 で対応) - If(minimal compare) → Variable vs Integer literal のみ対応 - Graceful degradation: Phase 123 制限は `Ok(None)` で legacy に fallback - Structured error codes: `[phase123/...]` prefix で明示的エラー - Box-first modularization: parse/verify/lower 責務分離 - Unit tests: 8 tests PASS (including graceful degradation test) - Integration smoke: PASS (`phase123_if_only_normalized_semantics_vm.sh`) - 入口: `docs/development/current/main/phases/phase-123/README.md` ## 2025-12-18:Phase 121 完了 ✅ **Phase 121: StepTree→Normalized Shadow Lowering (if-only, dev-only)** - 箱化モジュール化: normalized_shadow/{contracts,builder,parity}.rs (508行、新規) - Shadow lowering: StepTree → JoinModule (Normalized方言、if-only限定) - Capability guard: Loop/Break/Continue を明示的拒否(SSOT) - Parity 検証: exit contracts + writes 比較(dev ログ / strict fail-fast) - Dev-only wiring: `joinir_dev_enabled()` のときのみ shadow 生成 - Strict fail-fast: `freeze_with_hint` で mismatch を即座に検出(hint必須) - Smoke tests: VM 3/3 PASS、LLVM スタブ(ハーネス設定必要) - 回帰: Phase 120 維持確認、全テスト PASS - 入口: `docs/development/current/main/phases/phase-121/README.md` - 設計: `docs/development/current/main/design/control-tree.md` (Phase 121章) ## 2025-12-18:Phase 120 完了 ✅ **Phase 120: StepTree "Facts→Decision→Emit" 箱化モジュール化** - 箱化モジュール化: StepTreeFacts / StepTreeContractBox の責務分離 - StepTreeBuilderBox: 構造 + facts 抽出まで(意思決定・整形・署名生成はしない) - StepTreeContractBox: facts → contract の整形のみ(idempotent, deterministic) - BTreeSet で順序決定性保証(facts は順序に依存しない) - signature_basis_string() の決定性維持(既定挙動不変) - 回帰: Phase 103/118 維持確認、全 1142 テスト PASS - 入口: `docs/development/current/main/design/control-tree.md` - 実装: - `src/mir/control_tree/step_tree_facts.rs` (63行、新規) - `src/mir/control_tree/step_tree_contract_box.rs` (168行、新規) - `src/mir/control_tree/step_tree.rs` (262→411行、リファクタリング) ## 2025-12-18:Phase 119 完了 ✅ **Phase 119: StepTree cond SSOT(AST handle)** - StepNode::If / StepNode::Loop に cond_ast (AstNodeHandle) を追加 - SSOT: cond は AST 参照を保持、cond_sig は派生(署名/ログ/差分検知) - 不変条件: cond_ast は signature_basis_string() に混ぜない(決定性維持) - 実装: Box clone(dev-only なので許容) - 回帰: Phase 103/104/118 維持確認 - 入口: `docs/development/current/main/design/control-tree.md` ## 2025-12-18:Phase 118 完了 ✅ **Phase 118: loop + if-only merge parity** - loop + if-only で条件付き変数更新 merge を VM/LLVM で固定 - Fixture: phase118_loop_nested_if_merge_min.hako (expected: 2) - Pattern3 (if-sum) 活用 - Smoke: VM + LLVM EXE parity 検証済み - Follow-up: Pattern3 carrier PHI contract(expected: 12) - Fixture: phase118_pattern3_if_sum_min.hako - Smoke: phase118_pattern3_if_sum_{vm,llvm_exe}.sh - 回帰: Phase 117 維持確認 - 入口: `docs/development/current/main/phases/phase-118/README.md` ## 2025-12-18:Phase 117 完了 ✅ **Phase 117: if-only nested-if + call merge parity** - ネストしたif-only(内側if + 外側else)で call 結果 merge を VM/LLVM で固定 - Fixture: phase117_if_only_nested_if_call_merge_min.hako (expected: 2, 3, 4) - Smoke: VM + LLVM EXE parity 検証済み - 回帰: Phase 116 維持確認 - 入口: `docs/development/current/main/phases/phase-117/README.md` ## 2025-12-18:Phase 116 完了 ✅ **Phase 116: if-only keep+call merge parity** - if-only で片側が元値保持、片側が call 結果のパターンを VM/LLVM で固定 - Fixture: phase116_if_only_keep_plus_call_min.hako (expected: 10, 2) - Smoke: VM + LLVM EXE parity 検証済み - 回帰: Phase 115 維持確認 - 入口: `docs/development/current/main/phases/phase-116/README.md` ## 2025-12-18:Phase 115 完了 ✅ **Phase 115: if-only call result merge parity** - if-only で関数呼び出し結果を merge するパターンを VM/LLVM で固定 - Fixture: phase115_if_only_call_merge_min.hako (expected: 2, 3) - Smoke: VM + LLVM EXE parity 検証済み - 回帰: Phase 103/113/114 維持確認 - 入口: `docs/development/current/main/phases/phase-115/README.md` ## 2025-12-18:Phase 114 完了 ✅ **Phase 114: if-only return+post parity** - if-only で early return + post-if statements パターンを VM/LLVM で固定 - Fixture: phase114_if_only_return_then_post_min.hako (expected: 7, 2) - Smoke: VM + LLVM EXE parity 検証済み - 回帰: Phase 103/113 維持確認 - 入口: `docs/development/current/main/phases/phase-114/README.md` ## 2025-12-18:Phase 113 完了 ✅ **Phase 113: if-only partial assign parity** - if-only(else なし)の片側代入で「保持 merge」パターンを VM/LLVM で固定 - Fixture: phase113_if_only_partial_assign_min.hako - Smoke: VM + LLVM EXE parity 検証済み ## 2025-12-18:Phase 112 完了 ✅ **Phase 112: StepTree Capability Guard (strict-only)** - StepTree の required_caps を strict mode でチェック - Allowlist: If, NestedIf, Loop, Return, Break, Continue - Deny (strict): NestedLoop, TryCatch, Throw, Lambda, While, ForRange, Match, Arrow - Error format: `[joinir/control_tree/cap_missing/] Hint: ` - Default behavior unchanged (strict=false always Ok) - 入口: `docs/development/current/main/design/control-tree.md` - 実装: - `src/mir/builder/control_flow/joinir/control_tree_capability_guard.rs` - `src/mir/builder/calls/lowering.rs` (wired into lower_function_body) ## 2025-12-18:Phase 111 完了 ✅ **Phase 111: StepTreeContract + StepTreeSignature(dev-only)** - StepTreeContract を追加(`exits` / `writes` / `required_caps` / `cond_sig`) - StepTreeSignature を追加(`signature_basis_string()` を安定 hash、Span は含めない) - dev-only parity を break/continue に加えて return まで拡張 - 入口: `docs/development/current/main/design/control-tree.md` - 実装: `src/mir/control_tree/step_tree.rs` ## 2025-12-18:Phase 110 完了 ✅ **Phase 110: ControlTree / StepTree(構造SSOT・dev-only観測)** - StepTree の語彙(Block/If/Loop/Stmt)と Feature を pure AST で実装(ValueId/PHI/CFG を混ぜない) - joinir routing 側で extractor との “分類矛盾” を dev-only で検出(strict のみ Fail-Fast) - 関数本体の StepTree を dev-only でダンプ(既定挙動不変) - 入口: `docs/development/current/main/design/control-tree.md` - 実装: - `src/mir/control_tree/step_tree.rs` - `src/mir/builder/calls/lowering.rs` - `src/mir/builder/control_flow/joinir/routing.rs` ## 2025-12-17:Phase 109 完了 ✅ **Phase 109: error_tags hints SSOT** - policy/validator エラーを "tag + message + hint" 形式に統一 - freeze_with_hint() API 追加(hint 必須、空なら panic) - Phase 107/104/100 の代表3箱を hint 対応に移行 - 入口: `docs/development/current/main/phases/phase-109/README.md` ## 2025-12-17:Phase 104 完了 ✅ **Phase 104: loop(true) + break-only digits(read_digits 系)** - read_digits_from 形の `loop(true)` を Pattern2 で受理(loop var 抽出 + break cond 正規化) - fixture: `apps/tests/phase104_read_digits_loop_true_min.hako`(expected: `2`, `1`) - smoke: `tools/smokes/v2/profiles/integration/apps/phase104_read_digits_vm.sh` / `tools/smokes/v2/profiles/integration/apps/phase104_read_digits_llvm_exe.sh` - P2: json_cur 由来の回帰面を追加(fixture+VM/LLVM EXE smoke) ## 2025-12-17:Phase 107 完了 ✅ **Phase 107: json_cur find_balanced_* depth scan(VM + LLVM EXE parity)** - depth scan + nested if + return-in-loop を Pattern2 policy で受理(hardcode なし) - fixture: - `apps/tests/phase107_find_balanced_array_end_min.hako`(expected: `1`, `3`) - `apps/tests/phase107_find_balanced_object_end_min.hako`(expected: `1`, `3`) - smoke(integration): - VM: `tools/smokes/v2/profiles/integration/apps/phase107_find_balanced_array_end_vm.sh` / `tools/smokes/v2/profiles/integration/apps/phase107_find_balanced_object_end_vm.sh` - LLVM EXE: `tools/smokes/v2/profiles/integration/apps/phase107_find_balanced_array_end_llvm_exe.sh` / `tools/smokes/v2/profiles/integration/apps/phase107_find_balanced_object_end_llvm_exe.sh` - 入口: `docs/development/current/main/phases/phase-107/README.md` ## 2025-12-17:Phase 108 完了 ✅ **Phase 108: Pattern2 policy router SSOT(薄い入口の固定)** - post-loop early return を一般 plan(`cond`/`ret_expr`)として独立し、Pattern2Inputs の依存を解消 - ApplyPolicyStepBox から “直叩き” を撤去し、policy router 1本に集約(入口SSOT) - 入口: `docs/development/current/main/phases/phase-108/README.md` ## 2025-12-17:Phase 103 P0 完了 ✅ **Phase 103: if-only regression baseline** - if-only(loop無し)の nested if + merge を fixture 化し、VM/LLVM EXE parity を integration smoke で固定 ## 2025-12-17:Phase 100 P3 完了 ✅ **Phase 100 P3: String Accumulator Captures** - String accumulator(`out = out + ch`)を最小形で固定し、VM/LLVM EXE parity を smoke で検証 - LLVM EXE 側の stringish 伝播(PHI/copy/binop)を修正し、concat の意味論を安定化 ## 2025-12-17:Phase 100 P2 完了 ✅ **Phase 100 P2: Mutable Accumulator Captures** - Mutable accumulator pattern (`out = out + ch`) を Pattern2 carrier で対応 - ScopeManager 委譲により read-only check を回避 - Numeric output validation (count=3) で fixture 固定 - VM/LLVM EXE parity 完了(smoke 追加) ## 2025-12-17:Phase 100 P1 完了 ✅ **Phase 100 P1: Pinned Local Captures** - CapturedEnv に CapturedKind (Explicit/Pinned) 拡張 - PinnedLocalAnalyzer で loop-outer read-only locals を識別 - Pinned receiver (例: s.substring()) が loop 内で使用可能に - Fixture/smoke で動作確認済み ## 2025‑12‑17:Phase 99 完了 ✅ **Phase 99: Trim/escape 実コード寄り強化(VM+LLVM EXE)** - next_non_ws を3ケース固定(`2`, `-1`, `3`)— 改行/CR/Tab混在パターン追加 - escape 末尾バックスラッシュを best-effort として固定(`hello\` そのまま出力) - VM+LLVM EXE parity 完全対応、integration smoke で検証済み 関連(設計/実装の入口): - Phase 100: `docs/development/current/main/phases/phase-100/README.md` ## 2025‑12‑15:Phase 132 完了 ✅ **Phase 132: LLVM Exit PHI=0 根治修正 完了!** - ループ exit PHI が 0 を返す問題を根治解決 - 原因(2層): (1) JoinIR/Boundary が exit 値を境界に渡していない、(2) LLVM Python が PHI を落とす/上書きする - 修正: Pattern 1 で exit 値を明示的に渡す + `predeclared_ret_phis` 使用 + `builder.vmap` の PHI 保護 - 結果: `/tmp/p1_return_i.hako` が 3 を返す(VM 一致) - 詳細: `investigations/phase132-llvm-exit-phi-wrong-result.md` **追加(Phase 132-P2): Case C の Exit PHI ValueId 衝突を修正** - 原因: `exit_phi_builder.rs` が module-level allocator を使い、同一関数内で ValueId が衝突し得た - 修正: `func.next_value_id()`(function-level)へ統一(`bd07b7f4`) - 結果: `apps/tests/llvm_stage3_loop_only.hako` が LLVM EXE でも `Result: 3`(VM 一致) - 詳細: `investigations/phase132-case-c-llvm-exe.md` **追加(Phase 132-P3): Exit PHI collision の早期検出(debug-only)** - `verify_exit_phi_no_collision()` を `contract_checks.rs` に追加し、ValueId 衝突を JoinIR merge の段階で Fail-Fast する ## 2025‑12‑15:Phase 133–136(短報) - Phase 133: promoted carrier(Trim)の `join_id` 解決を SSOT に寄せて修正(smoke は compile-only)。 - Phase 134: plugin loader best-effort loading を導入(決定的順序 + failure 集約 + 継続)。 - Phase 135: ConditionLoweringBox が allocator SSOT を無視して ValueId 衝突を起こす問題を根治。 - 詳細: `docs/development/current/main/phases/phase-135/README.md` - Phase 136: MirBuilder の Context 分割を完了し、状態の SSOT を Context に一本化。 - 詳細: `docs/development/current/main/phases/phase-136/README.md` ## 2025‑12‑16:Phase 137‑141(短報) - Loop Canonicalizer(前処理 SSOT)は Phase 141 まで完了(既定挙動は不変、dev-only 観測/strict parity あり)。 - 設計 SSOT: `docs/development/current/main/design/loop-canonicalizer.md` - 実装: `src/mir/loop_canonicalizer/mod.rs`(+ 観測: `src/mir/builder/control_flow/joinir/routing.rs`) - Phase 記録: `docs/development/current/main/phases/phase-137/README.md` ## 2025‑12‑16:Phase 92(短報) - Phase 92(ConditionalStep / P5b escape の lowering 基盤)は完了。 - 条件付き更新(`ConditionalStep`)のJoinIR表現 + Pattern2 側の委譲(emitter 箱化) - 条件式での body-local 参照(`ConditionEnv → LoopBodyLocalEnv`)+ 最小E2E smoke 固定 - Phase 記録(SSOT入口): `docs/development/current/main/phases/phase-92/README.md` - 残: P5b の “完全E2E” は body-local promotion 拡張後(スコープ外で保留) ## 2025‑12‑16:Phase 93(短報) - Trim の `is_ch_match` など「ConditionOnly(PHIで運ばない派生値)」を Derived Slot として毎イテレーション再計算できるようにした。 - SSOT: `ConditionOnlyRecipe`(運搬禁止)+ `ConditionOnlyEmitter` - schedule: `body-init → derived → break` を評価順SSOTとして強制 - Phase 記録(入口): `docs/development/current/main/phases/phase-93/README.md` ## 2025‑12‑16:Phase 94(短報) - P5b escape(`ch` 再代入 + `i` の +1/+2)を “derived(Select)” として扱い、VM E2E を固定。 - 新箱: `BodyLocalDerivedEmitter` + 明示ポリシー(strict で理由付き Fail-Fast) - integration smoke: `tools/smokes/v2/profiles/integration/apps/phase94_p5b_escape_e2e.sh` - Phase 記録(入口): `docs/development/current/main/phases/phase-94/README.md` ## 2025‑12‑16:Phase 95(短報) - MiniJsonLoader の escape ループを Phase 94 基盤で固定(派生 body-local + 条件付き skip)。 - フィクスチャ: `apps/tests/phase95_json_loader_escape_min.hako` - smoke: `tools/smokes/v2/profiles/integration/apps/phase95_json_loader_escape_vm.sh` - Phase 記録(入口): `docs/development/current/main/phases/phase-95/README.md` ## 2025‑12‑16:Phase 96(短報) - Trim系 policy 化を開始し、MiniJsonLoader の next_non_ws ループを fixtures/smoke に追加。 - フィクスチャ: `apps/tests/phase96_json_loader_next_non_ws_min.hako` - smoke: `tools/smokes/v2/profiles/integration/apps/phase96_json_loader_next_non_ws_vm.sh` - Phase 記録(入口): `docs/development/current/main/phases/phase-96/README.md` ## 2025‑12‑16:Phase 97(短報) - Phase 95/96 の MiniJsonLoader fixture を LLVM EXE ラインでも固定し、JoinIR/Trim の退行検出を強化。 - smoke: `tools/smokes/v2/profiles/integration/apps/phase97_next_non_ws_llvm_exe.sh`(next_non_ws) - smoke: `tools/smokes/v2/profiles/integration/apps/phase97_json_loader_escape_llvm_exe.sh`(escape) - Phase 記録(入口): `docs/development/current/main/phases/phase-97/README.md` ## 2025‑12‑17:Phase 98(短報) - plugin loader に strict fail-fast を導入し(HAKO_JOINIR_STRICT=1)、FileBox/MapBox の LLVM EXE parity を持続可能に。 - smoke: `tools/smokes/v2/profiles/integration/apps/phase97_next_non_ws_llvm_exe.sh` - smoke: `tools/smokes/v2/profiles/integration/apps/phase97_json_loader_escape_llvm_exe.sh` - Phase 記録(入口): `docs/development/current/main/phases/phase-98/README.md` ## 2025‑12‑17:Phase 102(短報) - real-app(MiniJsonLoader.read_quoted_from)の loop を最小抽出し、VM + LLVM EXE で regression を固定(期待: length=4)。 - フィクスチャ: `apps/tests/phase102_realapp_read_quoted_min.hako` - smoke: `tools/smokes/v2/profiles/integration/apps/phase102_realapp_read_quoted_vm.sh` - smoke: `tools/smokes/v2/profiles/integration/apps/phase102_realapp_read_quoted_llvm_exe.sh` - Phase 記録(入口): `docs/development/current/main/phases/phase-102/README.md` ## 2025‑12‑14:現状サマリ (補足)docs が増えて迷子になったときの「置き場所ルール(SSOT)」: - `docs/development/current/main/DOCS_LAYOUT.md` ### JoinIR / Loop / If ライン - LoopBuilder は Phase 186‑187 で完全削除済み。**JoinIR が唯一の loop lowering 経路**。 - LoopPattern 系は Pattern1–4 まで実装・本線化済み: - Pattern1: Simple While - Pattern2: Loop with Break - Pattern3: Loop with If‑Else PHI(break/continue なし) - Pattern4: Loop with Continue(multi‑carrier 対応) - Exit/Carrier/Boundary ラインは次の箱で SSOT 化: - `CarrierInfo` / `ExitMeta` / `ExitBindingBuilder` - `JoinInlineBoundary` + `LoopExitBinding` - If lowering は IfSelectLowerer/IfMergeLowerer を中心に整理済み。Select/PHI の扱いも Phase 189 系で橋渡し済み。 - 残課題(JoinIR ライン): - JoinIR→MIR merge の一般化(複雑な Select/PHI パターンの統合) - JsonParserBox など実アプリ側での長期運用テスト - Phase 86–90(Loop frontends)まとめ(1枚): - `docs/development/current/main/phase86-90-loop-frontends-summary.md` ### Phase 86–90: Loop frontends(要約) - Phase 86–90 は “dev-only fixtures + shape guard + fail-fast” で段階的に固定済み。 - 具体の fixture / shape / 未検証は `docs/development/current/main/phase86-90-loop-frontends-summary.md` を SSOT とする。 ### Scope / BindingId(dev-only の段階移行ライン) - MIR builder 側で lexical scope / shadowing を実在化し、言語仕様の “local はブロック境界で分離” を SSOT に揃えた。 - JoinIR lowering 側は name-based から BindingId-based へ段階移行中: - `ScopeManager.lookup_with_binding()` / `ConditionEnv.binding_id_map` を導入し、shadowing を壊さずに解決できる足場を作った。 - promoted carriers(DigitPos/Trim)については `BindingId(original) → BindingId(promoted) → ValueId(join)` の鎖を dev-only で整備中。 - Phase 86 で `carrier_init_builder` / `error_tags` を SSOT 化し、段階移行ラインの基盤(ValueId 生成とエラー語彙)が確立した。 - これにより、BindingId dual-path の拡張・統合時に「生成」と「表示」の責務が混ざらない構造が固定された。 - Phase 81 で Pattern2(DigitPos/Trim)の ExitLine 契約(ConditionOnly を exit PHI から除外、LoopState のみを reconnect)を E2E で固定した。 - 参照: - `docs/development/current/main/phase73-scope-manager-design.md` - `docs/development/current/main/phase78-bindingid-promoted-carriers.md` - `docs/development/current/main/phase80-bindingid-p3p4-plan.md` - `docs/development/current/main/phase81-pattern2-exitline-contract.md` - `docs/development/current/main/phase78-85-boxification-feedback.md` ### JsonParser / Selfhost depth‑2 ライン - `selfhost_build.sh --json` で Program JSON v0 emit は安定。 `.hako` 側から env 経由で JSON を読む最小ループ(`program_read_min.hako`)は動作確認済み。 - JsonParserBox / BundleResolver のループ 21 本のうち: - 18 本は Pattern1–4 で JoinIR 対応済み(Phase 162–165)。 - `_trim` を含む一部の複合ループは、ValueId 境界や Box 登録など残課題あり。 - BoolExprLowerer / condition_to_joinir で OR/AND/NOT 付き条件式の lowering は実装完了(Phase 168–169)。 - 残課題(JsonParser/selfhost depth‑2): - JoinIR→MIR ValueId boundary の完全一般化(条件用 ValueId を含める) - JsonParserBox の using / Box 登録(Rust VM 側での認識) - Program JSON v0 を JsonParserBox 経由でフル解析する line の仕上げ ### Ring0 / Runtime / CoreServices ライン - Ring0Context + Ring0Registry で OS API 抽象化レイヤ完成: - MemApi / IoApi / TimeApi / LogApi / FsApi / ThreadApi - RuntimeProfile(Default / NoFs) で条件付き必須を制御。 - CoreServices(ring1‑core)として次を実装済み: - StringService / IntegerService / BoolService - ArrayService / MapService / ConsoleService - PluginHost 統合 + UnifiedBoxRegistry からの自動初期化 - FileBox / FileHandleBox ライン: - Ring0FsFileIo 経由で read / write / append / metadata 完全対応 - Default プロファイルでは必須、NoFs プロファイルでは disabled。 - Logging ライン: - ConsoleService(user‑facing) - Ring0.log(internal/dev) - println!(test 専用) の 3 層が `logging_policy.md` で整理済み。JoinIR/Loop trace も同ドキュメントに集約。 - VM backend の Box 解決(UnifiedBoxRegistry / BoxFactoryRegistry)の経路図: - `docs/development/current/main/phase131-2-box-resolution-map.md` - LLVM(Python llvmlite)lowering の棚卸し(Phase 131-3..10): - `docs/development/current/main/phase131-3-llvm-lowering-inventory.md` - 状態: Case B(Pattern1/loop_min_while)は EMIT/LINK/RUN まで復旧済み。Phase 132 で `return i` の VM/LLVM parity を固定。 - Case C は別途 “Case C docs” を SSOT にして追跡する(状況は更新されるので、この箇所では断定しない) - Case C の調査と実装計画: - `docs/development/current/main/phase131-11-case-c-summary.md` - `docs/development/current/main/case-c-infinite-loop-analysis.md` --- ## 2025‑09‑08:旧スナップショット(参考) - LLVM 側 P0 完了(BitOps/Array/Echo/Map 緑)。VInvoke(by‑name/by‑id vector) は戻り値マッピングの暫定課題を確認中(Decisions 参照)。 - selfhosting-dev の作業を main に順次取り込み。VM/MIR 基盤は main で先に整える方針。 直近タスク(当時) 1) continue/break の lowering(Builder 修正のみで表現) - ループ文脈スタック {head, exit} を導入。 - continue に遭遇 → head(または latch)へ br を emit し終端。 - break に遭遇 → exit へ br を emit し終端。 - post‑terminated 後に emit しない制御を徹底。 2) ループ CFG の厳密化 - 単一 exit ブロックの徹底。 - Phi はヘッダでキャリー変数を合流(SSA/支配関係が崩れない形)。 3) 検証とスモーク - Verifier 緑(dominance/SSA)。 - VM のループ代表(単純/ネスト/早期継続・脱出)。 - LLVM/Cranelift EXE に綺麗に降りる(br/phi ベースで問題なし)。 代表コマンド(例) - ビルド: `cargo build --release` - LLVM smoke: `LLVM_SYS_180_PREFIX=$(llvm-config-18 --prefix) NYASH_LLVM_BITOPS_SMOKE=1 ./tools/llvm_smoke.sh release` - VInvoke 調査: `NYASH_LLVM_VINVOKE_TRACE=1 NYASH_LLVM_VINVOKE_SMOKE=1 ./tools/llvm_smoke.sh release`