# Phase 285: Box lifecycle / weakref / finalization / GC conformance Status: In progress (A1 series implemented; LLVM sub-phases ongoing) ## LLVM Sub-Phases Status | Phase | Status | Summary | |-------|--------|---------| | 285LLVM-0.3 | ✅ COMPLETE | Leak report smoke test修正(検証スコープ明確化) (2025-12-25) | | 285LLVM-1.1 | ✅ COMPLETE | ユーザーBox登録・デバッグ出力 (2025-12-24) | | 285LLVM-1.2 | ✅ COMPLETE | WeakRef基本動作(identity保留) (2025-12-24) | | 285LLVM-1.3 | ✅ COMPLETE | InstanceBox Field Access (getField/setField) (2025-12-24) | | **285LLVM-1.4** | ✅ **COMPLETE** | **print Handle Resolution (型タグ伝播)** (2025-12-24) | | **285W-Syntax-0** | ✅ **COMPLETE** | **weak文法SSOT確定 (weak x unary operator)** (2025-12-24) | | **285W-Syntax-0.1** | ✅ **COMPLETE** | **weak(x) 完全拒否 (Parser-level Fail-Fast)** (2025-12-24) | **LLVM Details**: See [phase-285llvm-1.3-verification-report.md](phase-285llvm-1.3-verification-report.md) **Syntax Change**: Phase 285W-Syntax-0 migrates from `weak(x)` function call to `weak x` unary operator **Syntax Enforcement**: Phase 285W-Syntax-0.1 enforces parser-level rejection of `weak(...)` syntax with helpful error message ### Phase 285LLVM-0.3 (2025-12-25): Smoke test 修正 - `NYASH_DISABLE_PLUGINS=1` 削除、plugins 有効化で leak report 動作確認 - stdout 検証を削除(leak report のみを検証対象とする) - 結果: 45/46 PASS(退行なし) - コメント修正: 「print() は機能しない」→「このsmoke testはleak reportingのみ検証」(SSOT整合) --- ## Goal Box の生存期間(強参照/弱参照/解放/最終化/GC)を SSOT として固定し、移行期間でも意味論が割れない状態にする。 Language-level SSOT: - Lifecycle/weak/fini/GC policy: `docs/reference/language/lifecycle.md` - Truthiness + `null`/`void`: `docs/reference/language/types.md` This Phase document is not the language SSOT; it tracks implementation status, backend gaps, and acceptance criteria. ## Implemented (A1 series) See `docs/development/current/main/phases/phase-285/phase-285a1-boxification.md`. - WeakRef E2E (VM/LLVM harness): `weak ` + `weak_to_strong()`, plus strict weak-field contract (no implicit weakification). - Visibility support: `public { weak parent }` plus sugar `public weak parent` (same meaning). - Parser robustness: parameter type annotations (`arg: Type`) are rejected with a clear parse error (no hang). - Helper: `src/parser/common/params.rs` - Smoke: `tools/smokes/v2/profiles/quick/parser/phase285_param_type_annotation_nohang.sh` ## Why now - JoinIR/Plan/compose の収束が進むほど、実行時の “値の寿命” の揺れが目立つ。 - weakref/finalization は「実装が仕様」になりやすく、後から直すコストが最大級。 - LLVM harness 側は未対応の可能性が高く、差分を “仕様として明文化” しないと再現/調査が難しい。 ## SSOT References (current code) - weakref の値表現: `src/value.rs`(`NyashValue::WeakBox`) - finalization: `src/finalization.rs` - Box trait: `src/box_trait.rs`(`SharedNyashBox = Arc`) - Scope tracking: `src/scope_tracker.rs`(Box の登録/スコープ) ## Snapshot(今わかっていること) - weakref は `Weak>` で保持される(`NyashValue::WeakBox`) - `WeakBox` の `to_string()` は `weak_to_strong()` を試み、`WeakRef(null)` 表示になりうる(観測可能) - `src/value.rs` に weakref の drop 挙動を固定する unit test がある(`test_weak_reference_drop`) ## Responsibility Map(どこが仕様を決めるか) - **SSOT(意味)**: `docs/reference/language/*`(言語レベルのSSOT) - **Conformance**: Rust VM / LLVM harness / WASM / JIT など各バックエンド実装 - **観測の固定**: fixture/smoke(Phase 285 P2 で作る) ## 用語(P0で固定する) - **Strong reference**: 所有参照(`Arc` 等で Box を保持) - **Weak reference**: 非所有参照(`Weak` / `weak_to_strong()` が失敗しうる) - **Weak-to-strong**: weak → strong の昇格(成功/失敗が意味論) - **Roots**: 解放/GC から保護される参照集合(stack/local/global/handle/plugin) - **Finalizer**: 解放に伴う最終化処理(もし存在するなら) ## P0 decisions (docs-only) - Weak の観測は `weak_to_strong()` で行い、失敗値は `null`(= runtime `Void` の別名)。 - `cleanup`(Stage‑3 block-postfix)が「出口で必ず走る」決定的 cleanup を保証する(`catch` の有無に関係なく、常に実行)。 - GC は意味論ではなく補助(GC off で cycle はリークしうる)。 - ByRef (`RefGet/RefSet`) は non-owning / non-escaping(寿命・弱参照・GC の道具にしない)。 ## RUNBOOK caveat (implementation reality) The runbook assumes WeakRef infrastructure exists in the VM and lowering. If any of the following are missing, treat weak smokes as **unsupported** and scope to exit-time leak report first: - `weak ` parse/lower (and `weak(...)` is rejected) - VM handler for MIR WeakRef/WeakNew/WeakLoad - language-surface `weak_to_strong()` on WeakRef ## Questions to Answer (P0/P1) - weakref の “生存判定” は何で観測できるか(`toString` / `is_alive` / `weak_to_strong` API など) - finalizer は存在するか / いつ発火するか(drop 時?GC 時?明示 API?) - finalizer 内での禁止事項(再入、例外、I/O、allocation)をどうするか - LLVM harness の扱い(現状未対応なら “未対応として SSOT 化”) ## Scope (proposed) ### P0(docs-only) - 用語の固定(strong/weak/roots/finalizer/collection) - 仕様の固定(weakref の weak_to_strong 成否、finalizer の発火条件、禁止事項) - “LLVM harness の扱い” を明文化(未対応なら未対応として SSOT に書く) ### P1(investigation) - Rust VM の現状実装の棚卸し(どこで roots が形成され、どこで解放/最終化されるか) - LLVM harness の現状調査(弱参照/GC が無い場合は差分として記録) ### P2(smoke) - weakref の最小 fixture/smoke を作り、挙動を固定する - VM: stdout/exit code で固定 - LLVM: 未対応なら “スキップ理由” を smoke で明示 ## Non-goals - GC アルゴリズム刷新(RC→tracing 等の設計変更) - LLVM harness に同等機能を “一気に” 実装(差分の記録→段階導入を優先) ## Acceptance criteria (P2+) - VM と LLVM で、weak が仕様通り動作する(`weak_to_strong()` 成功/失敗が一致、失敗は `null`)。 - 強参照サイクルを意図的に作ったとき、(GC off なら)回収されないことが観測できる。 - 終了時に「強参照が残っている root」をデバッグ出力できる(default-off の診断フラグ)。 - これは意味論ではなく診断であり、ON/OFF でプログラムの意味を変えない。