docs(phase-29y): self-contained consult packet + entry

This commit is contained in:
2025-12-27 01:03:24 +09:00
parent ba1fc21375
commit 348b19f42d
4 changed files with 122 additions and 181 deletions

View File

@ -13,7 +13,7 @@ Phase 285 の "weak + hidden root + LLVM one-pass検出/設定含む)" は
**2025-12-26: Phase 285 P2.1 完了**
- hidden root を根治し、weak-fail fixture を PASS に復帰(`x = null` 後に `weak_to_strong()``null`
- `KeepAlive(drop_after)` により「スコープ維持 / 上書きdrop」を両立(当日中に命令分離で整理)
- `KeepAlive` / `ReleaseStrong` により「スコープ維持 / 上書きdrop」を語彙として分離(後続の命令分離で整理)
**2025-12-26: Phase 285 P2.2hygiene完了**
- `KeepAlive { values, drop_after }` を廃止し、`KeepAlive` / `ReleaseStrong` に命令分離(意図を MIR 語彙で明確化)
@ -38,7 +38,7 @@ Phase 285 の "weak + hidden root + LLVM one-pass検出/設定含む)" は
**2025-12-26: Phase 284 P2 完了**
- return を含む loopPattern5を VM で smoke 固定
- LLVM harness は理由付き SKIPビルドに LLVM feature なし
- LLVM harness integration でも PASSunreachable return の型不整合を修正
- quick smoke 154/154 PASS 維持
設計相談(将来の正規化):

View File

@ -31,13 +31,13 @@ Related:
- P0docs-onlyで “return の意味” と “Ok(None)/Err” の境界を固定
- P1+ で Rust/LLVM の実装を SSOT に収束pattern側に例外実装を増やさない
- **Phase 285active: Box lifecycle / weakref / finalization / GC SSOT**
- **Phase 285✅ COMPLETE: Box lifecycle / weakref / finalization / GC SSOT**
- 目的: Box の生存期間(強参照/弱参照/解放/最終化)を SSOT として固定し、「実装が仕様」になっている箇所を潰す
- ねらい:
- VM 側の weakref/finalization を仕様化(テストで固定)
- LLVM harness 側の未対応/差分を “仕様として明文化” し、将来の実装計画を切る
- 入口: `docs/development/current/main/phases/phase-285/README.md`
- 状況:
- 状況(完了):
- P0/P1/P2 ✅ 完了weak 成功パターンは smoke 固定)
- P2.1 ✅ 完了: hidden root を根治し、weak-fail smoke を PASS に復帰
- P2.2 ✅ 完了: KeepAlive の二重責務を命令分離で解消(`KeepAlive`/`ReleaseStrong`
@ -64,6 +64,7 @@ Related:
- **Phase 29yplanned, post self-host / docs-first: MIR lifecycle vocab freezeRC/weak/ABI**
- 目的: 参照カウントstrong/weakを “どこで” 実装するかMIR語彙 vs runtime ABIを設計SSOT化し、脱Rust実装の土台にする
- 前提: self-host 後Phase 285weak conformance + hidden root 根治)が落ち着いていること
- 入口phase: `docs/development/current/main/phases/phase-29y/README.md`
- 入口(相談パケット): `docs/development/current/main/investigations/phase-29y-mir-lifecycle-vocab-consult.md`
- **Phase 286✅ complete: JoinIR Line AbsorptionJoinIR→CorePlan/Frag 収束)**

View File

@ -1,216 +1,122 @@
Status: Draft (docs-first, post self-host)
Date: 2025-12-27
Scope: Self-host後に “脱RustランタイムNyRT/.hako” を進めるため、MIR命令語彙と runtime ABIlifecycle/RC/weakの境界をどう固めるべきか相談するパケット
Related:
- docs/reference/language/lifecycle.md
- docs/development/current/main/phases/phase-285/README.md
- docs/development/current/main/design/edgecfg-fragments.md
- docs/development/current/main/investigations/phase-286-plan-normalization-consult.md
Scope: self-host 後に “脱RustランタイムNyRT/.hako” を進める前提で、MIR lifecycle/RC/weak の境界を SSOT 化するための **相談パケットこの1枚で完結**
# Phase 29y (future): MIR lifecycle vocab freeze 相談パケット
# Phase 29yfuture, post self-host / docs-first: MIR lifecycle vocab freeze 相談パケット
## 0. 相談の意図
この文書は「ソースコードや他 docs を参照しなくても回答できる」ことを最優先にしている。
この文書は「今すぐ MIR 命令を増やす」提案を求めない。
self-host後に脱Rustを進める前提で、**MIRのどこまでを語彙として固定し、どこからを runtime ABINyRT/.hakoに委譲するか**を設計SSOT化するための相談パケット。
## 0. 相談の意図(お願い)
強調:
- “脱Rust” はゴールだが、**実装移行NyRT/.hako化は別フェーズ**でやるこの文書はその設計SSOTの下敷き
- Phase 285weak conformance / hidden root 根治)が未解決なら、先に Phase 285 を優先する。
この相談は「いま実装する」ためではなく、self-host 後に脱Rustを進める前提で、**設計SSOT**を固めるためのもの。
## 0.1 現時点で確定した事実Phase 285 からの入力)
欲しいのは “最終形の完成図” ではなく:
- 小刻み1フェーズ=小差分)で壊れにくい段階移行
- hidden root を再発させないための観測点diagnosticsと境界
ソースを見ずに議論できるように、「現実に起きたこと」を短く固定する。
この相談で “やらない” こと:
- 所有モデルを型に埋め込む等の MIR 大改造
- self-host 前に NyRT を .hako 化する実装
- GC/finalizer のアルゴリズム追加(境界を固定するところまで)
- weak は `weak_to_strong()` で生死が観測できるため、**SSA last-use = 言語寿命**は意味論として成立しない。
- hidden root は実装の細部VMのレジスタ/一時値保持など)で起きうるため、**“root面” と観測点(診断/ABI**を設計で固定する必要がある。
- LLVM harness は stdout にログが混入し得るため、smoke は **exit code SSOT**(出力比較に依存しない)へ寄せた方が安定する。
## 1. 前提(この相談で固定したい最小意味論)
## 1. 背景(いま分かったこと)
### 1.1 用語
- weak/strong の意味論は言語SSOT`docs/reference/language/lifecycle.md`)で定義されている
- VM 実装では “hidden root” が起きうる(例: SSA値を保持する `regs` / `mem` 等が strong を保持しうる)
- LLVM/wasm/他言語へ広げるには、Rust VM の内部構造に依存しない **共通の境界ABI/観測点)**が必要
- **strong reference**: 生存を延ばす参照。strong が 0 になると object は “死ぬ”
- **weak reference**: 生存を延ばさない参照。生死の観測に使える
- **weak_to_strong()**: weak から strong へ “昇格” を試みる。成功したら strong を返し、失敗したら `null` を返す
- **explicit drop**: `x = null` のように strong を明示的に落とす操作。
- **binding scope**: `local` で宣言された変数のスコープ(ブロック/関数など)。
- **hidden root**: プログラムからは解放済みに見えるのに、実装のどこかが strong を保持し続けてしまうことweak_to_strong が成功して露見する)。
- **root surfaceroot面**: strong を保持し得る場所の集合(例: VM のレジスタ/一時領域/フィールド表/ハンドル表など)。この集合と観測点を SSOT として固定したい。
## 2. 相談したい焦点
### 1.2 いま分かった “事実”(実装からの入力として固定)
この文書の目的は “決めたいことを増やす” ではなく、論点を減らして設計SSOTの入口を作ること
- weak は `weak_to_strong()` で生死が観測できるため、**SSA last-use = 言語寿命**のような最適化起点の寿命決定は、意味論として破綻しやすい
- hidden root は “root面” のどこかで strong が残留すると発生する。よって **root面の定義**と **観測点**が必要。
- LLVM/harness は stdout にログが混入し得るため、smoke は **exit code SSOT**に寄せた方が安定する。
相談したい論点は **5つだけ**に絞る(追加しない)。
### 1.3 相談に含めたい追加の制約(運用/設計)
### Q1. RC/weak の実体はどこに置くべきかruntime vs MIR vocab
- 診断 ON/OFF で意味論(結果)が変わらない(観測だけが増える)。
- 環境変数を増殖させない(既存の verbose/trace と統合する)。
- 既定挙動は変えない(必要なら docs-first で境界を固定してから別フェーズで実装)。
## 2. 相談したいこと(質問は 5つだけ
ここからが相談の本体。質問は増やさない。
### Q1. RC/weak の “実体” はどこに置くのが一番壊れにくい?
候補(推奨と段階移行の観点で教えてほしい):
- A) **runtimeNyRTに実体を置く**。MIR は寿命を語らず、backend は ABI を呼ぶだけ。
- B) MIR/Frag に **薄い寿命 effectretain/release 等)**を持たせて “見える化” し、backend 差分を減らす。
求める回答:
- 破綻リスクPHI/loop/early-exit/cleanupと移植性LLVM/wasmを踏まえた推奨
- 推奨の理由(短く)
### Q2. retain/release/weak_drop の “発火点” はどこで SSOT 化すべき?
候補:
- A) **MIRは寿命を語らず**、runtime ABI で retain/release/weak を表現するMIR→loweringがABI呼び出しへ
- B) MIRに **薄い寿命effect**Retain/Release等を追加し、後段で最適化するliveness/use-count由来
- A) `CorePlan → Frag → emit` のどこかで **1回だけ**走る “RC insertion pass” に寄せる(分散実装しない)。
- B) lowering 各所に分散(非推奨寄りだが、理由があるなら聞きたい)。
求める回答:
- “移植性LLVM/wasm” と “実装コスト/破綻リスクPHI/early-exit/例外)” の観点で、段階移行のおすすめ。
- PHI/loop/early-exit を踏まえた「壊れにくい置き場所」
- “1箇所” に寄せるなら、どこが一番安全か
### Q2. retain/release/weak_drop の “発火点” をどこで決めるべきか
### Q3. 関数 ABIargs borrowed / return ownedは妥当
候補:
- `Frag` 直前/直後の **1回の pass**CFG確定後で RC event 列を挿入する
- lowering 各所に分散する(非推奨
求める回答:
- PHI/loop/early-exit を踏まえた “壊れにくい置き場所” の推奨
### Q3. 関数 ABIargs borrowed / return ownedは妥当か
前提案:
- 引数: borrowedcallee は retain/release しない)
- 戻り値: ownedcaller が release 責務を持つ
求める回答:
- これで破綻しやすいパターンがあるか(例外/早期return/保存)
- 代替案があるなら “語彙が増えない最小案” を提示してほしい
### Q4. weak handle の表現token/handle/tagと等価性をどう固定すべきか
### Q4. weak handle の表現と等価性identityをどう固定するのが安全
論点:
- weak の同一性を何で表すべきかtoken / handle / generation / pointer 等)
- ログ表示とデバッグの契約(観測点 SSOT
求める回答:
- identity同一性/比較/ログ表示の契約をどう置くのが安全か
- バックエンド差が出にくい表現のおすすめ
- compare/equals を “仕様として”どう扱うべきか(未実装なら未実装として固定すべきか)
### Q5. finalizer/GC はどの層に置くべき?(非目標を明確にする
### Q5. finalizer/GC はどの層に置くべき?(非目標を明確
求める回答:
- まず “未対応を仕様として固定する” べき境界VMのみ/LLVM未対応 等)
- “いま固定すべき境界” と “まだ仕様にしない” 境界
- 例: 「finalizer は VM のみ」「LLVM/wasm は未対応」などの “仕様としての未対応” の置き方
## 2.1 “観測点” をどこに置くべきかQ2の補足
## 3. 相談先に求めるアウトプット形式(短く
目的は「weak_to_strong が成功する理由strong root の残留)」を追えること。
- Q1Q5 に対して各 3〜8行程度
- 段階移行2〜4ステップで、各ステップの受け入れ条件smoke/verify/contract
- 破綻しやすい罠PHI/loop/early-exit/cleanup/diagnostics のどれが危険か)
候補:
- runtime 側で root summary APIregs/mem/obj_fields/handlesの強参照数
- MIR 側で liveness の契約を固定し、VMがそれに従って解放する
## 4. Done 条件(この相談パケットを “締める”)
## 2.1 推奨の設計分離(相談ベースライン)
この文書の完了条件は実装ではなく、次フェーズへ切れること。
相談の叩き台(推奨):
- **参照カウンタの実体(カウンタ値)は runtimeNyRT**に置くMIRは“値”として持たない)
- **retain/release/weak_* の“発火点”はコンパイラ側が決める**が、語彙の増殖を避けるため “1箇所” に寄せる。
- 候補: `CorePlan → Frag → emit_frag()` の流れの **Frag直前/直後に 1 回だけ**走る RC insertion pass。
- backendVM/LLVM/wasmは、その RC event 列を **NyRT ABI 呼び出し**へ落とすだけにする。
- Q1Q5 の回答を受けて、次の実装タスクが **3つ以内**に分割できる(例: ABI固定 / RC挿入pass設計 / 観測点SSOT
- “やらないこと” が崩れていないself-host 前に大改造しない)
狙い:
- MIR/CorePlan は “意味論の語彙BoxRef/WeakRef/weak_to_strong” に留め、RC 実装の詳細を押し込めない。
- RC の発火点は “見える” ようにしつつ、分散実装を防ぐhidden root の再発を減らす)。
- self-host後に NyRT を `.hako runtime` に置換しても、ABIがSSOTなら導線が崩れにくい。
## 5. 回答メモ(相談結果の要約, 2025-12-27
## 2.2 最小 NyRT ABI相談先に提示したい候補
※ この節は「相談の回答」を短く保存するためのメモで、質問Q1Q5自体は増やさない。
### strong参照カウント
- **Q1**: 推奨は「実体は runtimeNyRTSSOT」。ただし hidden root を潰すために RC の “発火イベント列” は可視化したいので、MIRではなく **Frag以降の薄い effect 列(後段挿入)**として扱うA をSSOT、Bは後段effectとして限定採用
- **Q2**: retain/release/weak_drop の発火点は **分散せず 1箇所**。推奨は `emit_frag()` 後〜codegen直前CFG確定後**RC insertion pass**。PHI/loop/early-exit/cleanup を全部見た状態で挿入し、破綻を減らす。
- **Q3**: 関数 ABI は **args borrowed / return owned** が最小語彙で妥当。追加で「borrowed を保存/捕獲/フィールド格納/返すなら acquireretainを伴う」を契約として明文化すると事故が減る。
- **Q4**: weak handle は backend差を避けるため **token identityalloc_id + generation**を推奨。`weak_to_strong` は Alive のみ成功、Dead/Freed は `null`。ログも token を出す。
- **Q5**: finalizer/GC は Phase 29y では “境界の固定” まで。まず **RCとfiniを混ぜない**自動finiを入れないを強く固定し、未対応例: LLVM/wasmも仕様として明記する。
- `nyrt_retain(BoxRef)`
- `nyrt_release(BoxRef)`
注意:
- `release` が strong==0 になったとき “物理解放” は runtime の責務。
- `fini()` は言語SSOT上 “論理終端” であり、GC/RCで勝手に呼ばない`docs/reference/language/lifecycle.md`)。
### weak弱参照
- `nyrt_weak_new(BoxRef) -> WeakRef`
- `nyrt_weak_drop(WeakRef)`
- `nyrt_weak_to_strong(WeakRef) -> BoxRef | null`
SSOT整合:
- `weak_to_strong()` は Alive のみ成功し、Dead/Freed は `null` を返す(`docs/reference/language/lifecycle.md`)。
### optional診断/可観測性)
実装は後でよいが、相談では “観測点” を固定しておきたい。
- `nyrt_debug_roots_summary()`(カテゴリ別の strong root 数など)
- `nyrt_debug_refcounts(BoxRef)`(単体の strong/weak 数など)
制約:
- 診断は意味論を変えないON/OFFで挙動が変わらない
- env sprawl を防ぐため、既存の verbose/trace と統合するPhase 285 の方針と整合)。
## 2.3 関数 ABIowned/borrowed の最小規約)
相談したい焦点(推奨案):
- 引数は **borrowed**(呼び出し中は alive を呼び出し側が保証、callee は retain/release しない)。
- 戻り値は **owned**callee は +1 を返し、caller が release 責務を持つ)。
この規約の狙い:
- 関数境界の retain/release を最小語彙で固定できる。
- VM/LLVM/wasm で ABI を揃えやすい。
## 2.4 “RC insertion pass” の置き場所SSOT候補
目的:
- retain/release/weak_drop を “分散実装” させず、**1箇所**で決める。
候補(相談):
- `Frag` に入る直前CorePlan から “CFGが確定した後”に、RC event 列を挿入する。
- `PHI/loop/early-exit/cleanup` を見た上で挿入できる(誤りが減る)。
- Plan/Frag SSOT の “出口語彙return/break/continue” と整合しやすい。
相談したい点:
- “RC event” を MIR 命令として持つか(`Retain/Release/WeakDrop`)、あるいは `Frag` の effect として表すか。
- 最初は正しさを優先し、冗長操作削除(最適化)は別フェーズに分離するのが安全か。
## 3. 非目標(今回はやらない)
- MIR語彙の大改造型システムへ所有モデルを埋め込む等
- GCアルゴリズム刷新
- self-host前に NyRT を .hako 化する実装
## 4. 期待するアウトプット(相談先に求める形式)
- 最終形ではなく **段階移行1フェーズ=小差分)**のマイルストーン
- 各フェーズの受け入れ条件smoke/verify/contract
- “やると破綻しやすい罠” の列挙PHI/early return/exception/cleanup
## 4.1 マイルストーン案(相談先に求めたい “小刻み” の形)
Milestone Adocs-first:
- NyRT ABI最小セットと関数 ABIowned/borrowedを SSOT 化
- 受け入れ: doc が `lifecycle.md` と矛盾しない、smoke の観測点が明確
Milestone Bconformance-first:
- Phase 285 の weak-failhidden rootを根治し、VM で conformance を固定
- 受け入れ: weak-fail fixture が PASS、quick gate が green
Milestone Ccompiler-side SSOT:
- RC insertion pass の設計SSOTどこで何を挿入するかを確定まだ実装しない
- 受け入れ: PHI/loop/return/cleanup のケース分類がある、破綻ポイントが明文化されている
Milestone Dimplementation:
- RC insertion pass を実装し、VM/LLVM/wasm が同じ ABI を呼ぶ形にする
- 受け入れ: 既存 fixture を使って VM/LLVM parity を維持、診断が意味論を変えない
## 4.2 罠リスト(相談先に “やらない方がいい” として確認したい)
- “SSAの last-use = 言語寿命” を意味論にしてしまうweak_to_strong で観測できて破綻しやすい)。
- by-name で例外処理Box名/関数名の文字列一致で retain/release を変える)。
- 環境変数で挙動を分岐し、既定が揺れるenv sprawl
- RC と `fini()` を混ぜるGC/RC で勝手に `fini()` を呼ぶ等)。
- “万能 structOptionだらけ” で語彙統合し、結局デバッグできなくなる。
## 5. 参考現時点のSSOT
- lifecycle semantics SSOT: `docs/reference/language/lifecycle.md`
- Phase 285 conformance: `docs/development/current/main/phases/phase-285/README.md`
## 6. 相談先に渡すための最小質問テンプレ
「ソースコードを見なくても回答できる」ことを重視する。
1) 推奨の分離は A/B のどれか?
- A: MIRは寿命を語らず、NyRT ABI を呼ぶ
- B: MIR/Frag に薄い寿命effectRetain/Releaseを載せて“見える化”する
2) 関数 ABI は “args borrowed / return owned” が妥当か?
- もし違うなら、最小で安全な代替案は何か?
3) RC insertion pass を置く場所はどこが安全か?
- CorePlan→Frag 直前/直後/emit直前など、PHI/loop/cleanup を踏まえて推奨を教えてほしい
4) weak_to_strong の失敗条件Dead/Freedを実装間で揃えるための “観測点” はどこが良いか?
- runtime に root summary API を置くのが妥当か?
5) 破綻しやすい罠(特に PHI/early return/cleanupを列挙してほしい
## 7. Done 条件Phase 29y を “締める”)
この相談パケットの完了条件は実装ではなく、次フェーズへ切れること。
- docs が `lifecycle.md` と矛盾しない
- 次に実装するタスクが **3つ以内**に分割されている(例: ABI固定 / RC挿入pass設計 / 診断SSOT
まとめ(次フェーズへ切るための 3 タスク案):
1) NyRT ABI + 関数ABI + weak token identity を docs SSOT 化
2) RC insertion pass の置き場所/規則(禁止最適化含む)を docs SSOT 化(実装しない)
3) root surfaceカテゴリ+ 診断APIsummary+ smokeは exit code SSOT を docs SSOT 化

View File

@ -0,0 +1,34 @@
# Phase 29y (future, post self-host / docs-first): MIR lifecycle vocab freezeRC/weak/ABI
Status: Draft (docs-first)
Scope: self-host 後に “脱RustランタイムNyRT/.hako” を進める前提で、MIR の lifecycle/RC/weak を **どこまで語彙として固定**し、どこからを **runtime ABINyRT**に委譲するかを SSOT 化する。
## Entry
- 相談パケットSSOT: `docs/development/current/main/investigations/phase-29y-mir-lifecycle-vocab-consult.md`
## Non-goals (Phase 29y ではやらない)
- MIR 命令語彙の大改造(所有モデルを型に埋め込む等)
- self-host 前の NyRT の .hako 化(実装は別フェーズ)
- GC/finalizer の新規実装(境界の明文化まで)
## Deliverables (最大 3 つに切る)
Phase 29y を “締める” 条件は実装ではなく、次フェーズへ切れること。
1. **ABI SSOT**: NyRT ABI最小セット+ 関数 ABIargs borrowed / return owned など)を docs に固定
2. **RC insertion SSOT**: retain/release/weak_drop の発火点を “1箇所” に寄せる設計Frag 前後)を docs に固定
3. **Observability SSOT**: hidden root を追える観測点root面の定義、診断API、smokeは exit code SSOTを docs に固定
## Current Recommendation (consultation summary)
- **実体**: RC の値と Alive/Dead/Freed 判定は runtimeNyRTに置く
- **発火点**: retain/release/weak_drop は分散せず、CFG確定後の “1回だけ” の挿入パスで SSOT 化
- **関数ABI**: args borrowed / return ownedborrowed を保存/返す場合のみ retain
- **weak identity**: alloc_id + generation token を SSOT 化(ログも token 表示)
## Related
- lifecycle semantics SSOT: `docs/reference/language/lifecycle.md`
- Phase 285weak conformance / hidden root 根治): `docs/development/current/main/phases/phase-285/README.md`