From f775c0fe01a1e4b849a540f4f33d1e8c402cb83b Mon Sep 17 00:00:00 2001 From: nyash-codex Date: Thu, 18 Dec 2025 17:48:18 +0900 Subject: [PATCH] docs: Phase 131 P2 DirectValue exit reconnection complete MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Update completion status for Phase 131 P2: - CURRENT_TASK.md: Note WSL restart resolved EXDEV issue - 10-Now.md: Add Phase 131 P2 completion entry - phase-131/README.md: Document P1.5 and P2 deliverables Phase 131 Status: DONE ✅ - loop(true) break-once executes correctly - Exit values propagate through DirectValue mode - VM + LLVM EXE parity verified 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 --- CURRENT_TASK.md | 56 +++++++++++++ docs/development/current/main/10-Now.md | 15 ++-- .../current/main/phases/phase-131/README.md | 81 ++++++++++++------- 3 files changed, 116 insertions(+), 36 deletions(-) diff --git a/CURRENT_TASK.md b/CURRENT_TASK.md index c8404d23..e6b1bc57 100644 --- a/CURRENT_TASK.md +++ b/CURRENT_TASK.md @@ -5,3 +5,59 @@ Scope: Repo root の旧リンク互換。現行の入口は `docs/development/cu - Now: `docs/development/current/main/10-Now.md` - Backlog: `docs/development/current/main/30-Backlog.md` + +--- + +## Handoff (was blocking; now unblocked) + +### 状況 + +- JoinIR/Phase 131 系(Normalized shadow + DirectValue exit)が進行中だが、**LLVM EXE smoke が Rust のビルド段階でブロック**していた。 +- エラー: `Invalid cross-device link (os error 18)`(`cargo build` が `.rmeta/.rlib` を書き出すときに落ちる) +- 2025-12-18: `wsl --shutdown` による WSL 再起動後、`cargo build`/LLVM build/該当 smokes が復活(下のコマンドは PASS)。 + +### 症状(再現コマンド) + +- `cargo build -p nyash-rust` +- `cargo build --release -p nyash-rust --features llvm` +- LLVM EXE smokes(内部で release build するので同様に失敗) + - `bash tools/smokes/v2/profiles/integration/apps/phase131_loop_true_break_once_llvm_exe.sh` + - `bash tools/smokes/v2/profiles/integration/apps/phase97_next_non_ws_llvm_exe.sh` + +### 影響しない(通るもの) + +- `cargo test --lib` は PASS +- VM smokes は PASS(例) + - `bash tools/smokes/v2/profiles/integration/apps/phase131_loop_true_break_once_vm.sh` + - `bash tools/smokes/v2/profiles/integration/apps/phase130_if_only_post_if_add_vm.sh` + +### 根本原因メモ(環境) + +- WSL2 上で、`O_TMPFILE` で作った一時ファイルを `/proc/self/fd/` 経由で `link` すると **EXDEV が返る**挙動を確認。 + - Rustc/cargo が内部で類似の「tmpfile → persist(link/rename)」を使っている可能性が高い。 +- さらに、この環境では `~/.rustup/tmp` と `~/.cargo` が書き込み不可に見える(immutable/perm issue の疑い)。 +- DNS も一時的に死んでおり、`rustup toolchain install` 等の回避策が取れない状態だった(`Temporary failure in name resolution`)。 + +### 対処(ユーザー側での復旧手順) + +1. WSL を完全再起動: + - Windows 側で `wsl --shutdown` → その後 WSL を起動し直す +2. 再起動後にビルドが復活しているか確認: + - `cargo build -p nyash-rust` + - `cargo build --release -p nyash-rust --features llvm` +3. 復活したら、VM+LLVM EXE の最終確認(integration): + - `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` + - `bash tools/smokes/v2/profiles/integration/apps/phase97_next_non_ws_llvm_exe.sh` + +### 補足(再発時のワークアラウンド) + +- `tools/build_llvm.sh` は EXDEV を避けるため、`TMPDIR` を `target/...` 配下へ寄せる(同一 FS 内での artifact finalize を狙う)。 + +### 注意(作業ツリー) + +- 現在 `git status` は clean ではない(Phase 131 関連の変更が多数 + 未tracked docs/ファイルあり)。 + - 未tracked: `docs/development/current/main/phases/phase-131/p1.5-implementation-guide.md` + - 未tracked: `docs/development/current/main/phases/phase-131/p1.5-option-b-analysis.md` + - 未tracked: `docs/development/current/main/phases/phase-131/p1.5-root-cause-summary.md` + - 未tracked: `src/mir/control_tree/normalized_shadow/exit_reconnector.rs` diff --git a/docs/development/current/main/10-Now.md b/docs/development/current/main/10-Now.md index 75a698ef..3a788088 100644 --- a/docs/development/current/main/10-Now.md +++ b/docs/development/current/main/10-Now.md @@ -35,13 +35,18 @@ - Unit tests: 1155/1155 PASS - 入口: `docs/development/current/main/phases/phase-129/README.md` -## Next: Phase 131(loop(true) break-once Normalized support) +## 2025-12-18:Phase 131 P2 完了 ✅ -**Phase 131 P0: loop(true) break-once Normalized support(dev-only)** -- 目的: Loop capability を Normalized shadow に追加し、最小ループ(`loop(true) { * ; break }`)を通す +**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` -- 受け入れ: Phase 131 VM + LLVM EXE smokes + Phase 130/129 回帰が green -- Status: IN PROGRESS ## 2025-12-18:Phase 127 完了 ✅ diff --git a/docs/development/current/main/phases/phase-131/README.md b/docs/development/current/main/phases/phase-131/README.md index 31236d19..53d8ec61 100644 --- a/docs/development/current/main/phases/phase-131/README.md +++ b/docs/development/current/main/phases/phase-131/README.md @@ -1,6 +1,6 @@ -# Phase 131: loop(true) break-once Normalized Support (P0) +# Phase 131: loop(true) break-once Normalized Support -Status: IN PROGRESS +Status: DONE Scope: loop(true) break-once Normalized(StepTree → Normalized shadow pipeline) Related: - Entry: `docs/development/current/main/10-Now.md` @@ -104,7 +104,12 @@ Both backends must produce identical results: - VM: Rust VM backend (`--backend vm`) - LLVM: LLVM EXE backend via llvm_exe_runner.sh -Expected output for fixture: `1` (single line, numeric) +Expected contract for fixture: exit code `1` (return value) + +## Environment Note (WSL) + +- If `cargo build` fails with `Invalid cross-device link (os error 18)` on WSL, a full WSL restart (`wsl --shutdown`) has been sufficient to recover in practice. +- `tools/build_llvm.sh` also forces `TMPDIR` under `target/` to reduce EXDEV risk during artifact finalization. ## Work Items (P0) @@ -116,7 +121,7 @@ Expected output for fixture: `1` (single line, numeric) ### Step 1: Fixtures + Smokes - New fixture: `apps/tests/phase131_loop_true_break_once_min.hako` - - Expected output: `1` + - Expected exit code: `1` - Form: x=0; loop(true) { x=1; break }; return x - VM smoke: `tools/smokes/v2/profiles/integration/apps/phase131_loop_true_break_once_vm.sh` - LLVM EXE smoke: `tools/smokes/v2/profiles/integration/apps/phase131_loop_true_break_once_llvm_exe.sh` @@ -183,51 +188,65 @@ match &step_tree.root { ## Current Status -Phase 131 P0 - Structure Implementation (2025-12-18) +Phase 131 P2 - Variable Propagation (2025-12-18) -### ✅ Completed +### ✅ P0 Completed (Structure) - **Fixtures**: `apps/tests/phase131_loop_true_break_once_min.hako` created - **Builder**: `src/mir/control_tree/normalized_shadow/loop_true_break_once.rs` (407 lines) - **Integration**: Wired into `builder.rs` orchestrator via `lower_with_loop_support()` - **Smoke Tests**: VM and LLVM EXE smoke scripts created -- **Unit Tests**: All 1155 tests passing - **Structure**: Shadow JoinModule generation working correctly -### ⚠️ Execution Path Not Yet Wired +### ✅ P1 Completed (Execution Path) -**Current Behavior**: Normalized shadow generates correct JoinModules but only for observation/verification (dev-only). Execution still routes through Pattern2/canonicalizer which rejects loop(true) break-once. +- **Routing**: `try_cf_loop_joinir` now checks Normalized shadow before Pattern2 (`routing.rs`) +- **Dev Gating**: Routes to Normalized when `NYASH_JOINIR_DEV=1` +- **Merge Pipeline**: Uses existing `JoinIRConversionPipeline` (JoinModule → MirModule → merge) +- **Execution**: Loop executes successfully without freeze (verified in trace output) +- **Void Return**: Emits void constant when loop has no explicit return value -**Error Seen**: +**Evidence of Success**: ``` -[ERROR] Loop lowering failed: JoinIR does not support this pattern +[joinir/meta] MirFunc 'main', 'loop_step', 'loop_body', 'k_exit' converted +[cf_loop/joinir] Phase 189: Merge complete: 4 functions merged +[trace:debug] build_block: Statement 4/4 ... (loop completed, execution continues) +RC: 0 (program completes without freeze) ``` -**Root Cause**: The `try_cf_loop_joinir` routing in `cf_loop` attempts existing patterns before Normalized shadow can intercept. +### ✅ P1.5 Completed (DirectValue Exit Reconnection) -**Why This Is OK for P0**: Phase 131 P0 scope is "structure implementation" - proving the Normalized lowering logic works. Execution wiring is follow-up work. +**DirectValue mode**: Normalized shadow path does not build exit PHIs. Final env values are reconnected directly to host `variable_map`. -### Verification +**Example**: +```hako +x = 0 +loop(true) { x = 1; break } +return x // Returns 1 ✅ +``` -The shadow builder generates correct structure (verified in dev mode): -- main(env) → loop_step(env) → loop_body(env) → k_exit(env) -- PHI-free: all state via env parameters -- Continuation-passing style: TailCall for all transitions -- Structural verification passing +**Root Cause** (fixed): PHI-based exit merge assumptions did not match continuation-based Normalized control flow. -### Next Steps (Follow-Up Phase) +**Fix**: +- Introduce `ExitReconnectMode::DirectValue` and skip exit PHI generation in that mode. +- Carry `remapped_exit_values` through the merge result and update host `variable_map` directly. -To make this executable: -1. Modify `try_cf_loop_joinir` to check Normalized shadow before Pattern2 routing -2. Add dev-mode gating: route loop(true) break-once to Normalized when `NYASH_JOINIR_DEV=1` -3. Implement JoinModule → MIR merge for Normalized loop patterns -4. Enable and verify VM/LLVM smoke tests +### ✅ P2 Completed (k_exit contract alignment) + +**Problem**: continuation entry-jumps / exit edges were inconsistent, so the updated env visible at `k_exit` could be lost. + +**Fix**: normalize tail-call/exit edges so updated env reaches the exit reconnection point. ### Deliverables -Phase 131 P0 provides: -- ✅ Complete loop(true) break-once Normalized lowering logic -- ✅ PHI-free implementation (env + continuations) -- ✅ Box-First modular design -- ✅ Foundation for execution (structure verified) -- 📋 Clear path to execution wiring (documented above) +Phase 131 P2 provides: +- ✅ Execution path fully wired (dev-only, `NYASH_JOINIR_DEV=1`) +- ✅ Loop completes without freeze and returns the updated value +- ✅ DirectValue mode skips exit PHIs (PHI-free) +- ✅ Existing patterns unaffected (既定挙動不変) + +### Design Notes (historical) + +- `docs/development/current/main/phases/phase-131/p1.5-root-cause-summary.md` +- `docs/development/current/main/phases/phase-131/p1.5-option-b-analysis.md` +- `docs/development/current/main/phases/phase-131/p1.5-implementation-guide.md`