docs(phase-29y): add ABI/RC-insertion/observability SSOT stubs

This commit is contained in:
2025-12-27 01:11:36 +09:00
parent 47493b95ce
commit 8a5218a9ad
4 changed files with 179 additions and 0 deletions

View File

@ -0,0 +1,77 @@
# Phase 29y: ABI SSOTlifecycle / RC / weak
Status: Draft (docs-first, post self-host)
Scope: “脱RustランタイムNyRT/.hako” を進める前提で、lifecycle/RC/weak の境界を ABI として固定する。
この文書は「実装の現状」を説明するのではなく、**将来の置換NyRT/.hako化に耐える契約**を先に固定する。
## 0. 目的SSOT
- backendVM/LLVM/wasm/othersが “同じ意味” を実装できる最小 ABI を定義する
- “言語意味論” と “実装都合VMのregs等” を切り離し、hidden root を再発しにくくする
## 1. 前提(言語意味論)
ここでの weak は観測可能:
- `weak_to_strong()` が成功/失敗を返す(失敗は `null`
- したがって「SSA last-use = 寿命」を意味論にしてはいけない
## 2. ハンドル/値の表現(最低限)
### 2.1 Box handle
- `BoxHandle` は runtime 管理の参照opaqueとする
- 返値/引数は「0 = null」を許す`null` を表す)
### 2.2 Weak handletoken identity
weak の等価性identityは backend 差が出にくい token を SSOT として固定する:
- `alloc_id + generation` を含む token概念
- ログ表示も token を使う(例: `WeakRef(#1234:g7)`
比較(`==`)の扱い:
- `WeakRef``==` は token 同一性比較Alive/Dead/Freed に依存しない)
## 3. 関数 ABI最小契約
推奨 SSOT:
- **args borrowed / return owned**
契約:
- 引数は borrowedcallee は retain/release しない)
- 戻り値は ownedcaller が release 責務を持つ)
- borrowed を保存/捕獲/フィールド格納/返す等の “escape” を行う場合のみ、compile 側が acquireretainを挿入する
## 4. NyRT lifecycle ABI最小セット案
ここでは “名前” より契約を SSOT とする(既存の実装名が異なる場合は shim で吸収)。
### 4.1 strong
- `retain(h: BoxHandle) -> BoxHandle`
- `h == 0` のときは `0` を返すno-op
- `release(h: BoxHandle) -> void`
- `h == 0` のときは no-op
- 物理解放のタイミングは runtime 実装に委譲(言語意味論では規定しない)
### 4.2 weak
- `weak_new(h: BoxHandle) -> WeakHandle`
- `h == 0` はエラー(または `0` weak を禁止)
- `weak_drop(w: WeakHandle) -> void`
- `weak_to_strong(w: WeakHandle) -> BoxHandle`
- 成功: Alive のときだけ non-null を返す
- 失敗: Dead/Freed は `0`nullを返す
## 5. 非目標このABIで扱わない
- finalizer の自動実行RC/GC が勝手に `fini()` を呼ばない)
- GCアルゴリズムcycle回収等の規定
## 6. 関連(参考リンク)
- ABIの既存ドキュメント参考:
- `docs/reference/abi/nyrt_c_abi_v0.md`
- `docs/reference/abi/NYASH_ABI_MIN_CORE.md`
- 言語意味論 SSOT参照のみ:
- `docs/reference/language/lifecycle.md`

View File

@ -0,0 +1,50 @@
# Phase 29y: RC insertion SSOT1箇所で決める
Status: Draft (docs-first, post self-host)
Scope: retain/release/weak_drop の発火点を “分散実装しない” ための SSOT を固定する。
## 0. 目的
- RCイベントretain/release/weak_dropを **1箇所**で挿入し、backend差と hidden root を減らす
- 「SSA last-use = 寿命」にならないよう、drop点を **binding scope / explicit drop / 上書き**に限定する
## 1. 置き場所SSOT
推奨: `emit_frag()` で CFG が確定した後、codegen直前に **1回だけ**走る “RC insertion pass”
- ここなら PHI/loop/early-exit/cleanup を全部見た状態で挿入できる
- lowering 各所に retain/release を散らさないSSOTを壊さない
## 2. 入力と出力(概念)
入力:
- “CFG確定後” の IRFrag / block graph
- 変数スコープ境界binding scopeの情報
出力:
- RCイベントが明示された IR例: `rc.retain`, `rc.release`, `rc.weak_drop` の effect 列)
重要:
- RCイベント列は “見える化” であり、RCの実体カウンタ値/Alive判定は runtimeNyRTに委譲する
## 3. drop点の規則最小
禁止(意味論を壊しやすい):
- SSA last-use を根拠に release するweak_to_strong で観測できて破綻し得る)
許可(意味論に沿う):
- explicit drop: `x = null` の直前に “旧値の release”
- 上書き: `x = <new>` の直前に “旧値の release”
- スコープ終端: binding scope の終端で “そのスコープの binding が保持していた current value の release”
## 4. PHI / loop / early-exit の罠(最低限)
- PHI: “入力値” を間違って release すると破綻する。drop対象は binding の current value と一致する必要がある
- loop: back-edge とスコープ終端の相互作用(継続で生存する値/上書きされる値)を分類する
- early-exitreturn/break/continue: exit edge により “どのスコープが閉じるか” が変わるため、cleanupと統合する必要がある
## 5. 実装に切る時の最小タスク3つ以内
1) insertion pass の入口/出口を固定どのIRを入力にし、何を出力するか
2) drop点の規則を最小実装上書き/explicit drop/スコープ終端)
3) verify不変条件を追加PHI/edge数と drop点が矛盾しないこと

View File

@ -0,0 +1,47 @@
# Phase 29y: Observability SSOTroot surface / diagnostics
Status: Draft (docs-first, post self-host)
Scope: hidden root を “再発しにくく” するために、root面と観測点を SSOT として固定する。
## 0. 目的
- weak が観測できる以上、hidden root は “意味論上のバグ” として露見する
- 露見したときに「どこが strong を保持しているか」を追える設計(観測点)を固定する
制約:
- 診断 ON/OFF で意味論を変えない(観測のみ)
- 環境変数を増殖させない(既存 verbose/trace と統合)
- smoke は stdout 比較に寄せず、exit code SSOT を優先
## 1. root surfaceroot面の SSOTカテゴリ
root面は “場所の列挙” ではなく “カテゴリ契約” として固定する。
最低限のカテゴリbackendが0でもよい:
- `locals`: bindinglocal変数が保持する strong
- `temps`: 一時値/評価結果が保持する strongVM regs 等)
- `heap_fields`: オブジェクトの strong-owned fields が保持する strong
- `handles`: host-visible registry/handle table が保持する strong
- `singletons`: runtime の singleton/グローバルが保持する strong存在する場合
## 2. 診断APIsummaryのみで十分
相談パケットの目的は “原因が追える” ことであり、詳細な個体列挙は後回しでよい。
推奨の観測:
- root summary: カテゴリ別の strong root 数
- optional: 特定 handle/token の参照数strong/weak
例(概念):
- `debug_root_summary() -> { locals: N, temps: N, heap_fields: N, handles: N, singletons: N }`
## 3. テスト(観測の固定)
- LLVM/harness は stdout にログが混ざり得るため、スモークは exit code を SSOT とする
- stdout比較が必要な場合は、先に “出力ノイズの抑制” を設計で固定してから(環境変数スパロー禁止)
## 4. 破綻しやすい罠
- 診断トグルが意味論を変えるON/OFFで挙動が変わる
- hidden root を “仕様” として放置し、weak_to_strong の意味が揺れる
- root面が実装の場所列挙になり、backend追加時に追従できなくなる

View File

@ -21,6 +21,11 @@ Phase 29y を “締める” 条件は実装ではなく、次フェーズへ
2. **RC insertion SSOT**: retain/release/weak_drop の発火点を “1箇所” に寄せる設計Frag 前後)を docs に固定
3. **Observability SSOT**: hidden root を追える観測点root面の定義、診断API、smokeは exit code SSOTを docs に固定
DocsPhase 29y 内の SSOT:
- ABI SSOT: `docs/development/current/main/phases/phase-29y/10-ABI-SSOT.md`
- RC insertion SSOT: `docs/development/current/main/phases/phase-29y/20-RC-INSERTION-SSOT.md`
- Observability SSOT: `docs/development/current/main/phases/phase-29y/30-OBSERVABILITY-SSOT.md`
## Current Recommendation (consultation summary)
- **実体**: RC の値と Alive/Dead/Freed 判定は runtimeNyRTに置く