Phase 25.1b: VM undefined-value diagnostics and builder SSA helpers

This commit is contained in:
nyash-codex
2025-11-17 03:19:03 +09:00
parent 4b078e6df9
commit 82b6c4e834
12 changed files with 231 additions and 41 deletions

View File

@ -26,8 +26,8 @@ Status: planning構造整理フェーズ・挙動は変えない
2. **hostbridge.extern_invoke を「互換レイヤ」に押し込める**
- 方針: 「`env.*` で表現できるものは ExternCall を正義とし、`hostbridge.extern_invoke` は互換用ラッパに限定する」。
- Hako 側: `hostbridge.extern_invoke("env.*", ..)` は内部で `env.*` を呼ぶだけにする(新規コードは直接 `env.*` を使う)。
- Rust 側: `"hostbridge.extern_invoke"` の実装は、`extern_provider_dispatch("env.*", ..)` に委譲する薄いブリッジに整理する。
- Hako 側: `hostbridge.extern_invoke("env.*", ..)` は内部で `env.*` を呼ぶだけにする(新規コードは直接 `env.*` を使う)。
- Rust 側: `"hostbridge.extern_invoke"` の実装は、`extern_provider_dispatch("env.*", ..)` に委譲する薄いブリッジに整理する。
3. **BoxIntrospect をコア型システムに昇格させる**
- `env.box_introspect.kind` の実装を plugin loader v2 直下ではなく、コア runtime例: `runtime/box_introspect.rs`)に寄せる。
@ -35,14 +35,53 @@ Status: planning構造整理フェーズ・挙動は変えない
- `BoxTypeInspectorBox``env.box_introspect.kind(value)` を唯一の情報源として扱い、repr ベースの fallback は「plugins も env.* も使えないデバッグ環境のみ」で使うことをコメントで明示する。
4. **Numeric viewi64 unwrapの SSOT 化**
- Hako 側: `string_helpers` / `BoxHelpers` / `MirSchemaBox` / `JsonEmitBox` / `LoopOptsBox` に散っている i64 unwrap ロジックを、小さなユーティリティ(仮: `box_numeric_view.hako`)に寄せる。
- Rust 側: `NyashBox` から i64 を取り出す `as_i64` 的な関数を 1 箇所に置き、extern / BoxIntrospect 経路からはそれを使う。
- Hako 側: `string_helpers` / `BoxHelpers` / `MirSchemaBox` / `JsonEmitBox` / `LoopOptsBox` に散っている i64 unwrap ロジックを、小さなユーティリティ(仮: `box_numeric_view.hako`)に寄せる。
- Rust 側: `NyashBox` から i64 を取り出す `as_i64` 的な関数を 1 箇所に置き、extern / BoxIntrospect 経路からはそれを使う。
5. **StageB Main を箱に分割して SSA/デバッグを軽くする**
- 現状の `compiler_stageb.hako: Main.main` は:
- CLI 引数パース (`--source` / `--bundle-*` / `--require-mod`)
- bundle/require 解決 (`BundleResolver`)
- body 抽出 (`body_src` の抽出ロジック)
- ParserBox 呼び出し (`parse_program2` → emit JSON)
- defs スキャン (`FuncScannerBox.scan_all_boxes`)
が 1 関数に詰め込まれており、MIR 上でも巨大な `Main.main` になっている。
- 25.1c ではこれを「箱理論」に沿って分割する:
- `StageBArgsBox`CLI 引数と bundle/require の扱いだけを担当)
- `StageBBodyExtractorBox``body_src` 抽出ロジックだけを担当)
- `StageBDriverBox`ParserBox/FuncScannerBox を呼んで Program(JSON v0) を emit
- Rust 側 MirBuilder には、この箱ごとの小さな関数をそのまま MIR に落とさせることで、`Main.main` の SSA/Loop の複雑さを減らし、今回のような ValueId 追跡をしやすくする。
- 併せて、現状 selfhost CLI サンプルで観測されている `Main.main` 内の `ParserBox.length()` 呼び出しに対する recv 未定義エラー(`Invalid value: use of undefined value ValueId(17)`を、StageB Main 分割LocalSSA/LoopBuilder 整理の一環として根本修正するMethodCall の recv にも SSA/verify を適用する)。
6. **LoopBuilder / pin スロットの型付け・箱化**
- いまの LoopBuilder は `__pin$*$@recv` のような文字列ベースの「内部変数名」を `variable_map` に直接突っ込んで、SSA/phi/pin を管理している。
- 25.1c では、Loop 状態を「箱」として切り出して型付けする:
- 例: `LoopStateBox`Rust 側構造体)に
- `recv_slots`Method receiver 用)
- `index_slots`(ループカウンタ用)
- `limit_slots`limit/上限 expr 用)
を明示的に持たせる。
- `LoopBuilder::emit_phi_at_block_start` / `update_variable` は、この LoopStateBox を通じてのみ pin/phi を操作し、「recv に Null/未定義が混ざらない」ことを構造レベルで保証する。
7. **ビルダー観測用の専用レイヤ(デバッグ箱)**
- すでに `NYASH_BUILDER_TRACE_RECV` / `NYASH_BUILDER_DEBUG` などで ad-hoc に eprintln を入れているが、出力箇所が複数ファイルに散っていて再利用しにくい。
- 25.1c ではこれを `builder.observe` 的なモジュール(箱)に集約する:
- 例: `observe::recv::log(fn, bb, name, src, dst)``observe::phi::log(fn, bb, dst, inputs)` など。
- ポリシー:
- すべて dev トグルNYASH_BUILDER_TRACE_*)越しに呼ぶ。
- 本番挙動は変えず、「どこをどうトレースできるか」を構造として明示する。
8. **StageB 向けの極小 MIR 再現ハーネス**
- `docs/private/roadmap/phases/phase-20.33/DEBUG.md` にあるような StageB 向けメモを踏まえ、StageB/MirBuilder 用の「極小 Hako → MIR テスト」を 1 つ用意する。
- 例:
- 100〜200 行程度の `.hako``lang/src/compiler/tests/stageb_min_sample.hako` のようなファイルに固定。
- Rust 側で MirBuilder に直接その AST を食わせて MIR を生成し、`NYASH_VM_VERIFY_MIR=1` で「Undefined value」が出ないことを確認するユニットスモークを足す構造バグ検知用
- これにより、StageB/LoopBuilder に関する修正が `.hako` 本番コード全体に依存せず、小さな再現ケースで検証できるようにする。
## 進め方メモ
- 先にドキュメントを書くenv extern / BoxIntrospect / numeric view の仕様を `docs/specs` 配下に整理)→ そのあとで Bridge / VM / Hako を小さく揃える。
- 既存フェーズとの関係:
- Phase 25.1b: selfhost builder / multicarrier / BoxTypeInspector 実装フェーズ(機能側)。
- Phase 25.1c: そのうち「env.* / hostbridge.* / BoxIntrospect の構造と責務」を整理するメタフェーズ(構造側)。
- Phase 25.1c: そのうち「env.* / hostbridge.* / BoxIntrospect」に加えて、StageB Main / LoopBuilder / builder 観測レイヤの構造と責務整理するメタフェーズ(構造側)。
- 挙動を変えないことFailFast / default path は現状維持)を前提に、小さな差分で進める。