diff --git a/docs/development/current/main/phases/phase-285/README.md b/docs/development/current/main/phases/phase-285/README.md index ec32fb4c..e5809b38 100644 --- a/docs/development/current/main/phases/phase-285/README.md +++ b/docs/development/current/main/phases/phase-285/README.md @@ -167,38 +167,70 @@ If any of the following are missing, treat weak smokes as **unsupported** and sc - 仕様の固定(weakref の weak_to_strong 成否、finalizer の発火条件、禁止事項) - “LLVM harness の扱い” を明文化(未対応なら未対応として SSOT に書く) -### P1(investigation) +### P1(investigation)✅ COMPLETE (2025-12-26) **目的**: Rust VM の現状実装の棚卸し(どこで roots が形成され、どこで解放/最終化されるか) -**棚卸し対象ファイル**: -| ファイル | 観測ポイント | -|----------|-------------| -| `src/value.rs` | `NyashValue::WeakBox` 生成箇所、`weak_to_strong()` 失敗時の観測方法 | -| `src/finalization.rs` | finalizer 存在確認、登録・呼び出しタイミング・順序 | -| `src/box_trait.rs` | Box の所有モデル(Arc/Weak の境界、roots の形成点)| -| `src/scope_tracker.rs` | Box の登録/スコープ管理 | +#### Rust VM 実装棚卸し -**LLVM harness 調査**: -- `src/llvm_py/` で weakref/finalizer の相当機能を確認 -- 無いなら「無い」を明文化し、smoke を SKIP にする +| 責務 | ファイル | 関連シンボル | 観測ポイント | SSOT との差分 | +|------|----------|-------------|-------------|--------------| +| WeakBox 生成 | `src/value.rs:32` | `NyashValue::WeakBox` | `Weak>` で保持 | ✅ 仕様通り | +| weak_to_strong | `src/value.rs:196-201` | `upgrade_weak()` | `Weak::upgrade()` 失敗時 `Void` | ✅ 仕様通り | +| WeakBox 観測 | `src/value.rs:106-115` | `to_string()` + `upgrade()` | `WeakRef(null)` 表示で死亡観測可能 | ✅ 仕様通り | +| WeakBox 真実値 | `src/value.rs:157-160` | `to_bool()` | `weak_ref.upgrade().is_some()` → 生死判定 | ✅ 仕様通り | +| Finalizer 登録 | `src/finalization.rs:49-52` | `BoxFinalizer::track()` | InstanceBox のスコープ終了時 `fini()` 呼び出し | ⚠️ スコープレベル | +| Finalizer 呼び出し | `src/finalization.rs:61-76` | `finalize_all()` | `instance.fini()` を呼び出す(存在チェック付き) | ✅ 実装済み | +| Scope 追跡 | `src/scope_tracker.rs:14-28` | `ScopeTracker` | `stack: Vec>>` | ✅ 実装済み | +| Scope push/pop | `src/scope_tracker.rs:31-43` | `push_scope()/pop_scope()` | 逆順で `fini()` 呼び出し | ✅ 実装済み | +| Roots 形成 | `src/scope_tracker.rs:85-100` | `enter_root_region()/leave_root_region()` | GC root region 管理(Phase 10.4 prep) | ⚠️ 準備中 | +| MIR WeakNew | `src/backend/mir_interpreter/handlers/weak.rs:23-34` | `handle_weak_new()` | Box → Weak の変換 | ✅ 仕様通り | +| MIR WeakLoad | `src/backend/mir_interpreter/handlers/weak.rs:48-58` | `handle_weak_load()` | Weak → Box \| Void 昇格 | ✅ 仕様通り | + +**重要な観測**: +- `ScopeTracker` は **Rust MM レベル**(Arc/Weak)で管理 +- `BoxFinalizer` は **スコープレベル**(ブロックスコープ)で管理(別モジュール) +- WeakRef は **値表現レベル** (`Weak>`) で実装 +- Finalizer は **InstanceBox 限定**(`downcast_ref::()` で確認後呼び出し) + +#### LLVM harness 状況 + +| 機能 | 実装状況 | ファイル | 備考 | +|------|----------|----------|------| +| WeakNew | ✅ 実装済み | `src/llvm_py/instructions/weak.py:12-61` | `@nyrt_weak_new()` 呼び出し | +| WeakLoad | ✅ 実装済み | `src/llvm_py/instructions/weak.py:63-112` | `@nyrt_weak_to_strong()` 呼び出し | +| Finalizer (`fini()`) | ❌ 未実装 | - | 対応関数なし | +| GC / Cycle Collection | ❌ 未実装 | - | Reference Count のみ | + +**重要な発見**: +- **(A) 仕様通り**: `weak ` + `weak_to_strong()` は **両バックエンド** で動作 +- **(B) 未実装**: Finalizer (`fini()`) は **両バックエンド** で言語意味論としては統一されていない + - VM: `scope_tracker.rs` の `pop_scope()` 時に InstanceBox `.fini()` を呼び出し(実装あり) + - LLVM: 対応する finalizer 呼び出し機構がない(現在 harness は scope 管理を持たない) ### P2(smoke) **目的**: weakref の最小 fixture/smoke を作り、挙動を固定する -**smoke 候補(2-3本)**: -| smoke | 内容 | 期待値 | -|-------|------|--------| -| `phase285_weak_basic_vm.sh` | 既存 weak basic smoke | PASS(既に存在)| -| `phase285_weak_to_strong_fail_vm.sh` | weak_to_strong 失敗観測 | PASS(null 確認)| -| `phase285_leak_report_vm.sh` | exit-time leak report | PASS(既に存在)| +#### P2 smoke 候補(絞り込み済み) + +| smoke | 内容 | 期待値 | 優先度 | +|-------|------|--------|--------| +| `phase285_weak_basic_vm.sh` | 既存 weak basic smoke(`weak x` + `weak_to_strong()` 成功) | PASS(既に存在) | 既存 | +| `phase285_weak_to_strong_fail_vm.sh` | weak_to_strong 失敗観測(Void = null) | PASS(`WeakRef(null)` または `void` 確認) | **新規** | +| `phase285_weak_cycle_report_vm.sh` | 強参照サイクルで leak report | PASS(exit-time leak report で検出) | **新規** | +| `phase285_weak_basic_llvm.sh` | LLVM weak 基本動作確認 | PASS(VM と同一動作) | **新規** | **LLVM 扱い**: -- VM と同一動作: PASS -- 未対応: 理由付き SKIP(`test_skip "reason"`) +- WeakNew/WeakLoad は **両バックエンド実装済み** → smoke は `--backend vm` と `--backend llvm` 両方実行 +- Finalizer は **両バックエンド未実装** → **P2 では scope finalization のテストを行わない** +- 未対応機能: 理由付き SKIP(`test_skip "reason"`) - silent fallback 禁止 +**P2 で扱わない項目**: +- Finalizer (`fini()`) の統一テスト → Phase 286+ で統一化予定 +- GC cycle collection → Reference Count のみで既知の制約 + ## Non-goals - GC アルゴリズム刷新(RC→tracing 等の設計変更)