Files
hakorune/docs/development/current/main/phases/phase-285/README.md
tomoaki 661bbe1ab7 feat(phase284): P1 Complete - Return in Loop with Block Remap Fix
## Summary

Completed Phase 284 P1: Enable return statements in Pattern4/5 loops via
JoinInst::Ret infrastructure (100% pre-existing, no new infrastructure needed).

**Critical Bug Fix**: Block ID remap priority
- Fixed: local_block_map must take precedence over skipped_entry_redirects
- Root cause: Function-local block IDs can collide with global remap entries
  (example: loop_step:bb4 vs k_exit:bb4 after merge allocation)
- Impact: Conditional Jump else branches were incorrectly redirected to exit
- Solution: Check local_block_map FIRST, then skipped_entry_redirects

## Implementation

### New Files
- `src/mir/join_ir/lowering/return_collector.rs` - Return detection SSOT (top-level only, P1 scope)
- `apps/tests/phase284_p1_return_in_loop_min.hako` - Test fixture (exit code 7)
- Smoke test scripts (VM/LLVM)

### Modified Files
- `loop_with_continue_minimal.rs`: Return condition check + Jump generation
- `pattern4_with_continue.rs`: K_RETURN registration in continuation_funcs
- `canonical_names.rs`: K_RETURN constant
- `instruction_rewriter.rs`: Fixed Branch remap priority (P1 fix)
- `terminator.rs`: Fixed Jump/Branch remap priority (P1 fix)
- `conversion_pipeline.rs`: Return normalization support

## Testing

 VM: exit=7 PASS
 LLVM: exit=7 PASS
 Baseline: 46 PASS, 1 FAIL (pre-existing emit issue)
 Zero regression

## Design Notes

- JoinInst::Ret infrastructure was 100% complete before P1
- Bridge automatically converts JoinInst::Ret → MIR Return terminator
- Pattern4/5 now properly merge k_return as non-skippable continuation
- Correct semantics: true condition → return, false → continue loop

## Next Phase (P2+)

- Refactor: Block remap SSOT (block_remapper.rs)
- Refactor: Return jump emitter extraction
- Scope: Nested if/loop returns, multiple returns
- Design: Standardize early exit pattern (return/break/continue as Jump with cond)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2025-12-23 14:21:27 +09:00

3.3 KiB
Raw Blame History

Phase 285: Box lifecycle / weakref / finalization / GC SSOT

Status: Planned (design-first)

Goal

Box の生存期間(強参照/弱参照/解放/最終化/GCを SSOT として固定し、移行期間でも意味論が割れない状態にする。

Why now

  • JoinIR/Plan/compose の収束が進むほど、実行時の “値の寿命” の揺れが目立つ。
  • weakref/finalization は「実装が仕様」になりやすく、後から直すコストが最大級。
  • LLVM harness 側は未対応の可能性が高く、差分を “仕様として明文化” しないと再現/調査が難しい。

SSOT References (current code)

  • weakref の値表現: src/value.rsNyashValue::WeakBox
  • finalization: src/finalization.rs
  • Box trait: src/box_trait.rsSharedNyashBox = Arc<dyn NyashBox>
  • Scope tracking: src/scope_tracker.rsBox の登録/スコープ)

Snapshot今わかっていること

  • weakref は Weak<Mutex<dyn NyashBox>> で保持される(NyashValue::WeakBox
  • WeakBoxto_string()upgrade() を試み、WeakRef(null) 表示になりうる(観測可能)
  • src/value.rs に weakref の drop 挙動を固定する unit test がある(test_weak_reference_drop

Responsibility Mapどこが仕様を決めるか

  • SSOT意味: Rust VM 実装(src/value.rs, src/finalization.rs 周辺)
  • SSOT観測: fixture/smokePhase 285 P2 で作る)
  • LLVM harness: まずは “差分を仕様として明文化” が優先(未対応なら SKIP を SSOT 化する)

用語P0で固定する

  • Strong reference: 所有参照(Arc 等で Box を保持)
  • Weak reference: 非所有参照(Weak / upgrade() が失敗しうる)
  • Upgrade: weak → strong の昇格(成功/失敗が意味論)
  • Roots: 解放/GC から保護される参照集合stack/local/global/handle/plugin
  • Finalizer: 解放に伴う最終化処理(もし存在するなら)

Questions to Answer (P0/P1)

  • weakref の “生存判定” は何で観測できるか(toString / is_alive / upgrade API など)
  • finalizer は存在するか / いつ発火するかdrop 時GC 時?明示 API
  • finalizer 内での禁止事項再入、例外、I/O、allocationをどうするか
  • LLVM harness の扱い(現状未対応なら “未対応として SSOT 化”)

Scope (proposed)

P0docs-only

  • 用語の固定strong/weak/roots/finalizer/collection
  • 仕様の固定weakref の upgrade 成否、finalizer の発火条件、禁止事項)
  • “LLVM harness の扱い” を明文化(未対応なら未対応として SSOT に書く)

P1investigation

  • Rust VM の現状実装の棚卸し(どこで roots が形成され、どこで解放/最終化されるか)
  • LLVM harness の現状調査(弱参照/GC が無い場合は差分として記録)

P2smoke

  • weakref の最小 fixture/smoke を作り、挙動を固定する
    • VM: stdout/exit code で固定
    • LLVM: 未対応なら “スキップ理由” を smoke で明示

Non-goals

  • GC アルゴリズム刷新RC→tracing 等の設計変更)
  • LLVM harness に同等機能を “一気に” 実装(差分の記録→段階導入を優先)