docs: Phase 131 P2 DirectValue exit reconnection complete

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 <noreply@anthropic.com>
This commit is contained in:
nyash-codex
2025-12-18 17:48:18 +09:00
parent 02c4c313e5
commit f775c0fe01
3 changed files with 116 additions and 36 deletions

View File

@ -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/<n>` 経由で `link` すると **EXDEV が返る**挙動を確認。
- Rustc/cargo が内部で類似の「tmpfile → persistlink/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`

View File

@ -35,13 +35,18 @@
- Unit tests: 1155/1155 PASS
- 入口: `docs/development/current/main/phases/phase-129/README.md`
## Next: Phase 131loop(true) break-once Normalized support
## 2025-12-18Phase 131 P2 完了 ✅
**Phase 131 P0: loop(true) break-once Normalized supportdev-only**
- 目的: Loop capability を Normalized shadow に追加し、最小ループ(`loop(true) { <assign>* ; break }`)を通す
**Phase 131: loop(true) break-once Normalizeddev-only**
- 目的: Normalized shadow の最小ループを VM/LLVM EXE 両方で動かし、更新値が外に見えることまで固定
- 仕様:
- `loop(true) { x = 1; break }; return x` は exit code `1`
- DirectValue modePHI-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-18Phase 127 完了 ✅

View File

@ -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 NormalizedStepTree → 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`