2025-11-15 05:42:32 +09:00
# Current Task — Phase 21.8 / 25 / 25.1 / 25.2( Numeric Core & Stage0/Stage1 Bootstrap)
2025-11-15 00:02:13 +09:00
Update (2025-11-14 — Phase 25.1 kickoff: Stage0/Stage1 bootstrap design)
- Status: Phase 25.1 で「Rust 製 hakorune= Stage0 ブートストラップ」「Hakorune コードで構成された selfhost バイナリ= Stage1」という二段構え方針を導入。
- Decisions:
- Stage0( Rust bootstrap binary) : プロセス起動・FFI・VM/LLVM コアのみを担当し、ランタイムロジックや数値コアは持たない。
- Stage1( Hakorune selfhost binary) : Stage‑ B / MirBuilder / AotPrep / numeric core などの自己ホストコアを .hako で実装し、AOT して EXE 化する本命バイナリとする。
2025-11-15 05:42:32 +09:00
- バイナリ配置案: `target/release/hakorune-bootstrap` ( Stage0) , `target/selfhost/hakorune` ( Stage1) を想定。
2025-11-15 00:02:13 +09:00
- Docs:
- `docs/development/roadmap/phases/phase-25.1/README.md` に Stage0/Stage1 の責務と禁止事項、将来の自己ホストサイクル案を記載。
- `docs/development/roadmap/phases/phase-25/README.md` の Related docs に Phase 25.1 / numeric ABI / System Hakorune subset / ENV_VARS をリンク(構造的な入口を統一)。
2025-11-15 05:42:32 +09:00
Update (2025-11-15 — Phase 25.1: Stage1 build wiring initial implementation)
- Status: Stage0/Stage1 の「バイナリ分離」をビルド導線レベルで実現( Rust bin と selfhost bin を別パスに配置)。
- Implemented:
- Stage0( Rust CLI) :
- `cargo build --release` → `target/release/nyash` を Stage0 ブートストラップとして扱う(名称は将来 `hakorune-bootstrap` へ移行予定)。
- `Makefile` に `stage0-release` ターゲットを追加( Rust 側のみをビルドする専用ターゲット)。
- Stage1( Hakorune selfhost binary — Ny Executor プロトタイプ):
- `tools/selfhost/build_stage1.sh` を追加。
- 入力: `apps/selfhost-runtime/runner.hako` ( Ny Executor entry) 。
- 経路: `tools/hakorune_emit_mir.sh` → `tools/ny_mir_builder.sh --emit exe` → native EXE。
- 出力: `target/selfhost/hakorune` ( Phase 25.1 時点では「MIR v0 Executor」専用 EXE) 。
- `Makefile` に `stage1-selfhost` ターゲットを追加し、`make stage0-release` → `tools/selfhost/build_stage1.sh` のシーケンスを固定。
- Docs:
- `docs/development/roadmap/phases/phase-25.1/README.md` :
- Status を design+partial implementation に更新。
- Stage0/Stage1 の「現在の実体( nyash / build_stage1.sh) 」と「将来の名称( hakorune-bootstrap / hakorune) 」を明示。
- Makefile ターゲットと build_stage1.sh の役割を記載。
- `tools/selfhost/README.md` :
- Stage1 selfhost binary セクションを追加し、`tools/selfhost/build_stage1.sh` の使い方とパイプラインを説明。
- `Cargo.toml` :
- `[[bin]] 付近にコメントで「Stage0=nyash( Rust CLI) , Stage1=hakorune( tools/selfhost/build_stage1.sh 経由)」の方針を追記。
Update (2025-11-15 — Phase 25.1: Stage1 runtime independence & selfhost cycle plan)
- Clarified model:
- Stage1 `hakorune` は、実行時には Stage0 CLI( `nyash` )から独立した selfhost EXE として振る舞う。
- VM/LLVM/ny-llvmc などのバックエンド機能には、Ny 側から `env.mirbuilder.emit` / `env.codegen.emit_object` / `env.codegen.link_object` 等の extern を通じてアクセスする。
- つまり「Stage1 の backend」として `nyash` コマンドを前提にせず、Ring0 のサービスは C-ABI/extern レイヤで見る構造にする。
- 一方で現時点では、Stage1 自身のビルド( Stage0→Stage1) には `NYASH_BIN` (nyash) を利用している:
- `tools/hakorune_emit_mir.sh` / `tools/selfhost_exe_stageb.sh` が Stage‑ B / MirBuilder を実行する際に Stage0 をブートストラップとして使用。
- これにより「実行時は独立・ビルド時は Stage0 依存」という段階的自己ホスト状態になっている。
- Plan (selfhost cycle):
- 次フェーズ以降で「Stage1→Stage1'」の自己ホストサイクルを確認する:
- Stage1 が自分自身のソース( launcher/runner/CLI を含む) を取り込み、AOT して Stage1' バイナリを生成できること。
- Stage1 / Stage1' 間で CLI インターフェースと代表的な挙動が一致することをスモーク/ゴールデンで検証する(差分が収束することを確認)。
- Fix status:
- ✅ Rust provider (`env.mirbuilder.emit` → `program_json_to_mir_json_with_imports` ) で発生していた `[mirbuilder/parse/error] undefined variable: args` を修正。
- `lower_program` のメイン関数に仮引数 `args` を追加し、Stage‑ B が出力する `Main.main(args)` を正しく降ろせるようにした。
- ✅ `tools/selfhost_exe_stageb.sh` / `tools/selfhost/build_stage1.sh` から selfhost builder (hako.mir.builder) を既定OFF に切り替え、provider ルートのみで `.hako → MIR(JSON) → EXE` を再び通せるようにした。
- `NYASH_LLVM_SKIP_BUILD=1 tools/selfhost/build_stage1.sh --out /tmp/hakorune-dev` が成功し、Stage1 dev バイナリを生成できることを確認済み。
- selfhost builder (`HAKO_SELFHOST_BUILDER_FIRST=1` ) の再有効化は後続タスクとして扱う。
- 最終的には「Stage0 はブートストラップ専用・Stage1 単独で Stage1 を維持できる」状態を目標とする。
Update (2025-11-15 — Phase 25.1: Stage1 CLI first commands wired)
- Stage1 CLI( launcher.hako) :
- `lang/src/runner/launcher.hako` に `HakoCli` dispatcher を実装し、`Main.main(args)` を Stage1 エントリとして固定。
- コマンド実装( Phase 25.1 実装範囲):
- `hakorune emit program-json [-o <out>] [--quiet] <source.hako>` :
- `FileBox` で `<source.hako>` を読み取り、`BuildBox.emit_program_json_v0(src, null)` で Program(JSON v0) を生成。
- `"version":0` / `"kind":"Program"` を含むことを確認し、stdout または `-o/--out` で指定されたファイルに Program(JSON v0) を出力(失敗時は exit 92) 。
- `hakorune emit mir-json [--from-program-json <program.json>] [-o <out>] [--quiet] [<source.hako>]` :
- `--from-program-json` 指定時は Program(JSON v0) から、`.hako` 指定時は `.hako → Program(JSON v0) → MIR(JSON)` のパイプラインで `MirBuilderBox.emit_from_program_json_v0` を実行。
- 成功時は MIR(JSON) を stdout またはファイルに出力(失敗時は exit 92) 。
- `hakorune build exe [-o <out>] [--quiet] <source.hako>` :
- `.hako → Program(JSON v0) → MIR(JSON)` まで同様に進めた後、`env.codegen.emit_object` / `env.codegen.link_object` を通じて EXE を生成。
- C-API ルート(`NYASH_LLVM_USE_CAPI=1` , `HAKO_V1_EXTERN_PROVIDER_C_ABI=1` など) が有効な環境で、EXE パスを表示(`--quiet` 指定時は非表示)。
- 未実装のコマンド:
- `run` / `check` はプレースホルダのまま(`[hakorune] <cmd>: not implemented yet` を表示し、90– 93 の固定コードで終了)。
- Tools/docs:
- `tools/selfhost/build_stage1.sh` :
- デフォルト entry を `apps/selfhost-runtime/runner.hako` から `lang/src/runner/launcher.hako` に変更( Stage1 CLI ベースの dev bin を生成)。
- `tools/selfhost/README.md` :
- Stage1 entry の説明を launcher.hako に合わせて更新。
- `docs/development/runtime/cli-hakorune-stage1.md` :
- `emit program-json` / `emit mir-json` のセクションに「Phase 25.1 実装範囲」を反映(サポートされるフラグと I/O 挙動を具体化)。
Update (2025-11-15 — Phase 25.1a: Stage1 build pipeline hotfix progress)
- Context:
2025-11-15 22:32:13 +09:00
- Stage1 CLI( launcher.hako) と selfhost AOT パイプライン( build_stage1.sh) は設計上つながっているが、現状 selfhost builder (MirBuilderBox on VM) は Stage1 CLI の Program(JSON) をフルで扱えず 171 bytes の stub MIR を返してしまうため、provider-first を既定としている。
2025-11-15 05:42:32 +09:00
- CLI 側の `.hako → Program(JSON v0) → MIR(JSON) → EXE` ロジックは Ny コードとして実装済みで、Rust 側の Program→MIR( env.mirbuilder.emit) も修復済み。
- Current symptoms (after first fixes):
- `tools/hakorune_emit_mir.sh lang/src/runner/launcher.hako /tmp/launcher_mir.json` :
- Stage‑ B: `[emit:trace] Stage-B: SUCCESS - Generated Program(JSON)` まで成功( Program(JSON v0) 自体は安定して取得可能)。
2025-11-15 22:32:13 +09:00
- selfhost builder 経路( try_selfhost_builder) は、当初の `Parse error: Unexpected token FN` → LoopForm/`init` 予約語衝突 → `self._is_on/1` 未解決 → `NewClosure` 未実装、という段階的なエラーが出ていたが、
- `lang/src/mir/builder/func_lowering.hako` の `local fn` をリネーム、
- `lang/src/shared/mir/loop_form_box.hako` / `lang/src/mir/builder/internal/lower_loop_count_param_box.hako` の `init` →`start_value` リネーム、
- `BuilderConfigBox._is_on` 呼び出しを `me._is_on` に統一し、
- `MirBuilderBox` / `MirBuilderMinBox` の `norm_if = fn(...)` を helper メソッド(`_norm_if_apply` / `_norm_json_if_needed` )に置き換えて lambda/closure を排除、
によって Stage‑ 3 パース/VM 実行の両方で builder Runner が launcher.hako を通せるようになった(`[OK] MIR JSON written (selfhost-first)` まで到達)。
2025-11-15 05:42:32 +09:00
- selfhost builder 経路( try_selfhost_builder) :
2025-11-15 22:32:13 +09:00
- 現状 launcher.hako に対しては selfhost-first で Program→MIR が成功しているが、一般の lambda/closure (`fn(...) { ... }` ) は VM 側で未サポートのままなので、selfhost builder のコードからは意図的に排除している( lambda の完全な意味論実装は後続フェーズに送る)。
2025-11-15 05:42:32 +09:00
- provider 経路( try_provider_emit → env.mirbuilder.emit) :
2025-11-15 22:32:13 +09:00
- Rust 側の Program→MIR ルート修正後は `[mirbuilder/parse/error] undefined variable: args` が発生しなくなり、`launcher.hako` から MIR(JSON) を安定して生成できる状態( delegate:provider 経路が暫定のメインパス) 。selfhost builder 実行が `self._is_on/1` で落ちても、最終的な MIR(JSON) は provider 経由で出力されている。
2025-11-15 05:42:32 +09:00
- legacy CLI 経路(--program-json-to-mir) :
- Program(JSON) を一時ファイルに書いて `nyash --program-json-to-mir` を叩くフォールバックは、Phase 25.1a では退避路扱いのまま(通常は provider 経路が先に成功する)。
- Plan (Phase 25.1a, updated):
- Stage1 CLI ソース( launcher.hako) を Stage‑ 3 VM で素直に通るように整える( using 解決と文法を selfhost 既存パターンに合わせる)タスクは継続。
2025-11-15 22:32:13 +09:00
- `tools/hakorune_emit_mir.sh` の Program→MIR 部分については、provider 経路が安定していることを確認しつつ、selfhost builder 経路( MirBuilderBox.emit_from_program_json_v0) が Stage1 CLI に対して stub MIR を返してしまう根本課題を Phase 25.1b で解く(現時点では `HAKO_SELFHOST_BUILDER_FIRST=0` を維持)。
- デバッグ導線(マージ後 Hako を `/tmp/hako_builder_merged.hako` に保存 etc.)は既に整備済みで、次のフェーズで原因特定と修正を行う。
- `.hako → MIR(JSON) → EXE` スモークは provider-first( `HAKO_SELFHOST_BUILDER_FIRST=0` ) でグリーン。selfhost-first( `=1` )は Stage1 CLI の Program(JSON) を完全には扱えないため stub MIR になり、EXE が空挙動になる。MirBuilderBox 側の対応後( Phase 25.1b 以降)に再度 selfhost-first へ戻す予定。***
- Phase 25.1b の具体タスク( selfhost builder 拡張):
- `Program.defs` を MirBuilder 側で反映し、`HakoCli` 内の各メソッドを MIR 関数として生成する。
- `func_lowering` / `call_resolve` 相当の処理を Hako 側でも実装し、`Call("cmd_emit_*")` を `Global` resolve できるようにする。
- Loop / branch / boxcall など Stage1 CLI で出現する全ステートメントを lowering するため、`lang/src/mir/builder/internal/*` の helper を統合。
- JSON 出力を jsonfrag ベースで構築し、functions 配列に複数関数を格納可能にする。
- 上記の完了後、selfhost-first を既定に戻し Stage1 CLI EXE の JSON stdout 契約( Rust/llvmlite と同等)を仕上げる。
- ループについては LoopForm 正規化を前提とし、LoopForm の制約を満たさない形( キャリア3変数以上・順序再配置不能など) は selfhost builder では扱わず、タグ付き Fail‑ Fast で検知する( PHI ノード生成は既存 LoopForm/LowerLoop helper に一元化)。
- docs: `docs/development/roadmap/phases/phase-25.1b/README.md` を design deep‑ dive 版に更新し、FuncLoweringBox / MirBuilderBox の現状把握と拡張方針( Fail‑ Fast ポリシー・LoopForm/PHI ポリシー・Step0〜6 の実装順序など) を整理済み。Step0( Fail‑ Fast/観測導線)は 2025-11-15 実装済み( defs_only/no_match タグ+ `_lower_func_body` トレース) 、Step1 は `HAKO_MIR_BUILDER_REQUIRE_MAIN=1` トグルによる main 必須チェックを inject_funcs に入れるところまで完了。Step2 の最初の差分として、`FuncBodyBasicLowerBox` を追加して Local/If/Return パターンを既存の minimal lowers で箱化し、`_lower_func_body` から段階的に呼び出せるようにした( Loop を含む場合は `[builder/funcs:unsupported:loop]` をトレース)。***
Update (2025-11-16 — Stage‑ B using resolver alias 化 & 環境導線)
- Stage‑ B entry (`compiler_stageb.hako` ) の `using "hako.compiler.entry.bundle_resolver"` / `using "lang/src/compiler/entry/using_resolver_box.hako"` を module alias (`hako.compiler.entry.bundle_resolver` , `lang.compiler.entry.using_resolver` ) に置き換え、Stage‑ 3 パーサが string literal using を弾いていた問題を解消。
- `tools/hakorune_emit_mir.sh` では `nyash.toml` `[modules]` を Python で読み取り `name=path` を `HAKO_STAGEB_MODULES_LIST` ( `|||` 区切り)として export 済み。Stage‑ B 側では `Stage1UsingResolverBox` がこの env を `MapBox` 化し、`using lang.mir.builder.MirBuilderBox` などの module alias を元の .hako に展開してから parse する。
- 同じく `tools/hakorune_emit_mir.sh` 内の `HAKO_MIRBUILDER_IMPORTS` 生成ロジックを拡張し、`using ns.path.Type as Alias` だけでなく `using ns.path.Type` 形式からも末尾セグメント(例: `MirBuilderBox` )を alias として抽出するようにした。これにより Stage‑ B 経由で生成された Program(JSON v0) を `env.mirbuilder.emit` が処理するときに、`MirBuilderBox` や `BuildBox` といった static box 名が `undefined variable` にならず、imports 経由で Const(String) に解決されるようになった。
- Rust 側 JSON v0 ブリッジ(`src/runner/json_v0_bridge/lowering/expr.rs` )には `hostbridge` 名の変数を well-known グローバルとして扱う最小の分岐を追加し、`hostbridge.extern_invoke(...)` を含む Program(JSON v0) でも `undefined variable: hostbridge` エラーが出ないようにした(値は `Const(String(\"hostbridge\"))` を発行する placeholder とし、実際の extern dispatch は VM/ランタイム側で担保)。
- Stage1 CLI (`lang/src/runner/launcher.hako` ) の emit/build コマンドを整理し、FileBox 操作を `_read_file` / `_write_file` helper に集約。Option 解析の重複を解消しつつ Stage‑ 3 friendly な `local` 宣言へ寄せた結果、`tools/hakorune_emit_mir.sh lang/src/runner/launcher.hako /tmp/launcher_cli_mir.json` が provider delegate で安定して成功する状態を quick smoke (`phase251/stage1_launcher_program_to_mir_canary_vm` ) でカバー。
- 検証:
- `HAKO_SELFHOST_TRACE=1 ./tools/hakorune_emit_mir.sh basic_test.hako /tmp/test_mir_stageb.json` が `[emit:trace] Stage-B: SUCCESS - Generated Program(JSON)` の後に `delegate:provider` で MIR を出力し、`[OK] MIR JSON written (delegate:provider)` で終了(`direct-emit` フォールバックに落ちない)。
- `HAKO_SELFHOST_TRACE=1 ./tools/hakorune_emit_mir.sh lang/src/runner/launcher.hako /tmp/launcher_mir.json` でも `env.mirbuilder.emit` が `undefined variable: MirBuilderBox` / `hostbridge` を出さずに 0 exit し、MIR(JSON) を生成できることを確認。
- Next:
- Stage1 CLI (`lang/src/runner/launcher.hako` ) 側の `using` も module alias に揃え、Stage‑ B から box 定義が Program(JSON) に落ちるようにする。
- selfhost builder Runner (`try_selfhost_builder` ) は引き続き opt-in。Stage‑ B 改修により Program(JSON) 生成が安定したので、次のターンは builder prelude の VM 実行エラー(`self._is_on` 等)を潰し selfhost-first を既定ONに戻せるかを調査する。
Update (2025-11-15 — Phase 25.1a extension: ny-llvmc / llvmlite I/O semantics)
- Decision:
- Stage1 EXE( ny-llvmc 経由で生成されたバイナリ)が提供する `emit program-json` / `emit mir-json` の I/O 挙動は、llvmlite ハーネス(`NYASH_LLVM_USE_HARNESS=1` 経路)の挙動に揃える。
- 具体的には:
- stdout: JSON をそのまま吐く(`Result: 0` のようなハーネス用メッセージは既定OFF/ verbose専用に寄せる) 、エラー時は JSON ではなく明示的なエラーメッセージ+ 非0 exit code。
- exit code: Rust CLI / llvmlite ハーネスと同じく、0=成功、非0=失敗( Stage1 CLI 側の 90– 93 番台コードと整合)。
- Scope (Phase 25.1a 内でやる範囲):
- `tools/ny_mir_builder.sh` / ny-llvmc ハーネスで、Stage1 EXE( `target/selfhost/hakorune` 等)が `emit program-json` / `emit mir-json` を呼び出す場合に、llvmlite ハーネスと同じ I/O 契約( stdout に JSON、exit code で成否を表現)になるように調整する。
- `docs/development/runtime/cli-hakorune-stage1.md` に「Stage1 EXE の emit I/O 挙動は llvmlite ハーネスを参照する」ことを明記し、さらなる profile 切替( dev/ci/lite 等)は Phase 25.2 以降のタスクとして扱う。
- Helper: `tools/selfhost/run_stage1_cli.sh` を追加し、Stage1 CLI 実行時に `NYASH_NYRT_SILENT_RESULT=1` / `NYASH_DISABLE_PLUGINS=1` / `NYASH_FILEBOX_MODE=core-ro` を既定ONにして呼び出せるようにした。これにより JSON stdout が ny-llvmc / llvmlite ハーネスと同一契約になり、`tools/selfhost_exe_stageb.sh --run` も Result 行を出さずに exit code だけで評価できる。
- 現在の状況( 2025-11-16 調査):
- Stage-B では `HakoCli` 本体や `cmd_emit_*` が Program(JSON v0) に落ちるようになったが、VM 側 selfhost builder は Stage1 CLI をほぼ no-op に潰してしまい、171 bytes の stub MIR しか出力していない。
- provider 経由 (`env.mirbuilder.emit` ) は `.hako → Program(JSON) → MIR(JSON)` を安定して通すため、Phase 25.1a では `HAKO_SELFHOST_BUILDER_FIRST=0` を維持してこのルートを採用する。
- Stage1 EXE (`target/selfhost/hakorune` ) の CLI コマンドは現在 `Result: 0` しか出力しない( MIR が stub のため) 。selfhost builder の機能拡張後に JSON stdout を Rust/llvmlite と揃えるタスクを再開する。
2025-11-15 05:42:32 +09:00
Update (2025-11-14 — Phase 25 closure & Phase 25.2 deferral)
- Phase 25:
- Ring0/Ring1 設計と numeric_core (MatI64.mul_naive) の BoxCall→Call 降ろし用 AotPrep パスの MVP 実装までを達成。
- `NYASH_AOT_NUMERIC_CORE=1` で MatI64.mul_naive を `Call("NyNumericMatI64.mul_naive", args=[receiver, ...])` に書き換える処理は、代表的な MIR パターン( 13 PHI / 1 PHI 両方)で動作確認済み。
- STRICT モードは「AotPrep.run_json 後の MIR(JSON) に対してのみ BoxCall(mul_naive) 残存をチェックする」運用に整理し、pre-AotPrep の MirBuilder には干渉しない形に修正済み。
- Phase 25.2 への移管:
- `matmul_core` microbench( `tools/perf/microbench.sh --case matmul_core --backend llvm --exe` )の EXE/LLVM 統合と性能チューニングは Phase 25.2 に移す。
- 本フェーズでは「numeric_core の構造と導線」を優先し、heavy な microbench 最適化は Stage1 構築後の Phase 25.2 で扱う。
2025-11-15 00:02:13 +09:00
---
Update (2025-11-14 — Phase 25 MVP SUCCESS! numeric_core transformation working!)
- Status: ✅ **Phase 25 MVP BoxCall→Call transformation完全動作! **
- Breakthrough:
- `numeric_core.hako` の重大バグを2つ発見・修正し、MatI64.mul_naive の BoxCall→Call 変換に成功
- 変換例: `BoxCall(MatI64, "mul_naive")` → `Call("NyNumericMatI64.mul_naive", args=[receiver, ...args])`
- Fixed bugs:
1. **Missing nyash.toml mapping** (Critical): `selfhost.llvm.ir.aot_prep.passes.numeric_core` module path was missing from nyash.toml:224
- Without this, the `using` statement couldn't resolve and the pass never loaded
2. **JSON parsing bug** (Critical): `build_type_table()` and `build_copy_map()` were treating entire JSON as one instruction
- Root cause: Used `text.indexOf("{", pos)` which found the root `{` of entire JSON document
- Fix: Changed to op-marker-first pattern: find `"op":"..."` → `lastIndexOf("{")` → `_seek_object_end()`
- Result: Now correctly processes individual instruction objects within the instructions array
- Debug output confirms success:
```
[aot/numeric_core] MatI64.new() result at r2
[aot/numeric_core] MatI64.new() result at r3
[aot/numeric_core] type table size: 3
[aot/numeric_core] transformed BoxCall(MatI64, mul_naive) → Call(NyNumericMatI64.mul_naive)
[aot/numeric_core] transformed 1 BoxCall(s) → Call
```
- Files modified:
- `/home/tomoaki/git/hakorune-selfhost/nyash.toml` (added module mapping)
- `/home/tomoaki/git/hakorune-selfhost/lang/src/llvm_ir/boxes/aot_prep/passes/numeric_core.hako` (fixed JSON parsing)
- Next steps:
- Test with actual matmul benchmark using `NYASH_AOT_NUMERIC_CORE=1`
- Verify VM and LLVM execution paths both work
- Measure performance improvement (expected: 10-100x for large matrices)
- How to verify:
```bash
# Standalone test (already confirmed working)
bash /tmp/run_numeric_core_test.sh 2>& 1 | grep -E "\[aot/numeric_core"
# Full benchmark test
NYASH_AOT_NUMERIC_CORE=1 NYASH_SKIP_TOML_ENV=1 NYASH_DISABLE_PLUGINS=1 \
tools/perf/microbench.sh --case matmul_core --backend llvm --exe --runs 1 --n 64
```
2025-11-14 15:18:14 +09:00
2025-11-14 20:19:00 +09:00
Update (2025-11-14 — Phase 21.8 wrap-up: builder/importsまでで一旦クローズ)
- Status:
- Phase 21.8 は「Stage‑ B / Bridge / MirBuilder への IntArrayCore/MatI64 導線( imports) 」まで完了とし、EXE/LLVM ベンチ統合は Phase 25 に移管する。
- Done in 21.8:
- BridgeEnv に `imports: HashMap<String,String>` フィールドを追加し、using 由来の alias 情報を JSON→MIR 変換に渡せるようにした。
- `MapVars::resolve` を拡張し、`env.imports` を参照して `MatI64` / `IntArrayCore` などの静的 box 名を「有効な変数」として解決できるようにした。
- `parse_json_v0_to_module_with_imports` / `program_json_to_mir_json_with_imports` を導入し、Program(JSON v0)→MIR(JSON) 経路が imports マップを受け取れるようにした。
- `collect_using_and_strip` の戻り値を `(cleaned, prelude_paths, imports)` に拡張し、using から alias 一覧を収集できるようにした(既存呼び出しは `_imports` として無視し、挙動不変)。
- `HAKO_MIRBUILDER_IMPORTS` 経由で imports を Rust 側 MirBuilder へ渡す読み取り側の配線を追加( env.mirbuilder.emit ルート)。
- Deferred to Phase 25:
- `matmul_core` microbench の EXE/LLVM 統合( MatI64/IntArrayCore を LLVM ラインで実行可能にする設計と実装)。
- Numeric core AOT ライン( Ring1 numeric runtime を .hako 実装+汎用 `ExternCall` /numeric ABI 経由で LLVM に乗せる設計)。
- これらの後続タスクは `docs/development/roadmap/phases/phase-25/README.md` に移し、Ring0/Ring1 再編フェーズ( Phase 25) の一部として扱う。
2025-11-15 05:42:32 +09:00
Helper (2025-11-14 — numeric_core 開発用ラッパ追加)
- 新しい開発用スクリプト:
- `tools/dev_numeric_core_prep.sh <input.hako> <out.json>`
- 常に `HAKO_APPLY_AOT_PREP=1` と `NYASH_AOT_NUMERIC_CORE=1` を立てて `tools/hakorune_emit_mir.sh` を呼び出す。
- `NYASH_SKIP_TOML_ENV=1 NYASH_DISABLE_PLUGINS=1 HAKO_SELFHOST_TRACE=1 NYASH_JSON_ONLY=1` を既定ONにして、環境変数漏れで numeric_core が動かない問題を避ける。
- Claude Code / Codex への推奨:
- numeric_core / AotPrep 関連のテスト・デバッグは、直接 env を組むのではなく **このラッパを使う** こと。
- 例: `tools/dev_numeric_core_prep.sh tmp/matmul_core_test.hako tmp/matmul_core_test_mir.json`
- こうして生成した MIR(JSON) に対して `NYASH_AOT_NUMERIC_CORE_STRICT=1` + `NYASH_LLVM_DUMP_MIR_IN=...` を使えば、LLVM/EXE ラインでも同じ MIR を共有できる。
2025-11-14 15:18:14 +09:00
Update (2025-11-14 — 21.8 kickoff: MatI64/IntArrayCore builder integration)
- Context:
- 21.5: AotPrep/CollectionsHot v1 + microbench整備まで完了( linidx/maplin ≒ C=100%) 。arraymap/matmul は次フェーズ送り。
- 21.6: NyRT IntArrayCore + Hako IntArrayCore/MatI64/matmul_core スケルトン実装まで完了( builder 経路未対応)。
- Current goal:
- Hakorune selfhost chain( Stage‑ B → MirBuilder → ny‑ llvmc(crate))に IntArrayCore/MatI64 を統合し、`matmul_core` ベンチを EXE ラインで実行できるようにする。
- 実装は Claude Code 担当、このホストは仕様・構造・診断の整理に専念。
Planned tasks (for Claude Code)
1) Fix MatI64 visibility in Stage‑ B / MirBuilder
- Reproduce provider error: `[mirbuilder/parse/error] undefined variable: MatI64` from `env.mirbuilder.emit` when compiling a small test using `using nyash.core.numeric.matrix_i64 as MatI64` .
- Wire `nyash.core.numeric.matrix_i64` / `nyash.core.numeric.intarray` modules into the resolver/prelude so that Stage‑ B/MirBuilder can see MatI64 and IntArrayCore like other core boxes.
2) Make `tools/hakorune_emit_mir.sh` emit MIR(JSON) for `matmul_core`
- With `HAKO_APPLY_AOT_PREP=1 NYASH_AOT_COLLECTIONS_HOT=1 NYASH_LLVM_FAST=1 NYASH_MIR_LOOP_HOIST=1 NYASH_JSON_ONLY=1` , emit MIR(JSON) for the `matmul_core` case in microbench and ensure no undefined‑ variable errors.
3) Finish `matmul_core` bench EXE path
- Confirm `tools/perf/microbench.sh --case matmul_core --backend llvm --exe --runs 1 --n 64` builds EXE and runs, logging ratio vs the matching C implementation.
4) Keep defaults stable
- No behaviour changes for existing code/benches; IntArrayCore/MatI64 integration is additive and behind explicit use.
2025-11-10 19:42:42 +09:00
2025-11-14 13:36:20 +09:00
Update (2025-11-14 — CollectionsHot rewrite expansion, waiting for Claude Code)
- Status: pending (waiting on Claude Code to land rewrite coverage improvements)
- Scope: AotPrep CollectionsHot — expand Array/Map get/set/has rewrite to externcall by strengthening receiver type resolution.
- Done (this host):
- Stage‑ 3 local hint added in builder (Undefined variable: local → guide to set NYASH_PARSER_STAGE3=1 / HAKO_PARSER_STAGE3=1).
- 2‑ arg lastIndexOf removed across .hako (prefix + 1‑ arg pattern) — AotPrep no longer trips PyVM.
- CollectionsHot: fixpoint type_table, on‑ the‑ fly phi peek, backward scan, CH trace logs, push rewrite working.
- Bench (arraymap, 10s budget): externcall>0 is observed; boxcall remains in loop; ratio still high.
- Waiting (Claude Code tasks):
1) Implement tmap_backprop (receiver type from call‑ site signals), iterate to small fixpoint (max 2 rounds).
2) Integrate resolve_recv_type_backward into decision order (after phi peek), widen key/index heuristics.
3) Emit gated logs: "[aot/collections_hot] backprop recv=< vid > => arr|map via method=< mname > " (NYASH_AOT_CH_TRACE=1).
4) Update README with decision order and NYASH_AOT_CH_BACKPROP toggle (default=1).
- Acceptance:
- PREP.json contains nyash.array.get_h/set_h and/or nyash.map.get_h(hh)/set_h(hh); boxcall count decreases; jsonfrag=0.
- Bench diag shows externcall>1 (push + at least one of get/set); build/exe succeeds.
- How to verify quickly:
- ORIG: HAKO_APPLY_AOT_PREP=0 NYASH_JSON_ONLY=1 tools/hakorune_emit_mir.sh /tmp/arraymap_min.hako tmp/arraymap_orig.json
- PREP: HAKO_APPLY_AOT_PREP=1 NYASH_AOT_COLLECTIONS_HOT=1 NYASH_LLVM_FAST=1 NYASH_MIR_LOOP_HOIST=1 NYASH_JSON_ONLY=1 tools/hakorune_emit_mir.sh /tmp/arraymap_min.hako tmp/arraymap_prep.json
- Bench: NYASH_SKIP_TOML_ENV=1 NYASH_DISABLE_PLUGINS=1 tools/perf/microbench.sh --case arraymap --exe --budget-ms 10000
- Optional logs: NYASH_AOT_CH_TRACE=1 HAKO_SELFHOST_TRACE=1 …/hakorune_emit_mir.sh
2025-11-13 16:40:58 +09:00
Update (2025-11-12 — Optimization pre-work and bench harness)
- Implemented (opt‑ in, defaults OFF)
- Ret block purity verifier: NYASH_VERIFY_RET_PURITY=1 → Return直前の副作用命令をFail‑ Fast( Const/Copy/Phi/Nopのみ許可) 。構造純化の安全弁として維持。
- strlen FAST 強化: newbox(StringBox,const) だけでなく const ハンドルからの length() も即値畳み込み( NYASH_LLVM_FAST=1時) 。
- Kernel hint: nyrt_string_length に #[inline(always)] を付与( AOT呼び出しのオーバーヘッド抑制) 。
- FAST_INT ゲート: NYASH_LLVM_FAST_INT=1 で BinOp/Compare が同一ブロックSSA( vmap) を優先利用し、resolver/PHIの局所化コストを回避( 文字列連結は除外) 。
- length キャッシュ( llvmlite 最低限): NYASH_LLVM_FAST=1 時、文字列リテラル由来ハンドルに対する length()/len の i64 即値を resolver.length_cache に格納し、ループ内で再利用。
- Added
- Bench harness 拡張( tools/perf/microbench.sh) : branch/call/stringchain/arraymap/chip8/kilo を追加。各ケースは C 参照付きで ratio を自動算出。
- Bench doc: benchmarks/README.md に一覧・実行例を追加。
- Preliminary results( LLVM/EXE, ノイズ抑制: NYASH_SKIP_TOML_ENV=1 NYASH_DISABLE_PLUGINS=1)
- 良好: call / stringchain / kilo → ratio < 100 %( Nyash側が軽い )
- 要改善: branch / arraymap / chip8 → ratio ≈ 200%( Cの約1/2速度)
Compiler health( E0308対応)
- PHI 挿入のコールサイトを監査し、`insert_phi_at_head(&mut MirFunction, ...)` へ統一(`current_function.as_mut()` 経由で渡す)。`cargo check` は通過済み。
- `tools/ny_mir_builder.sh --emit exe` 実行時にワークスペース再ビルドが走る環境では、必要に応じて `NYASH_LLVM_SKIP_BUILD=1` を指定し、既存の `ny-llvmc` / `nyash_kernel` ビルド成果物を用いる運用を併記。
- Next actions( AOT集中; 既定OFFのまま段階適用)
1) ループ不変の簡易ホイスティング( strlen/比較/分母mod など)
2) FAST_INT の適用範囲精緻化( 不要cast/extendの抑制、CFG保存のまま)
3) array/map のホットパス検討( AOT経路のみ・診断OFF)
4) 再ベンチ( branch/arraymap/chip8 を再測)、目標: ratio ≤ 125%( Cの8割)
5) 既定OFFで挙動不変・Ret純化ガード緑維持・小差分リバーシブルを堅持
Toggles( 再掲)
- NYASH_LLVM_FAST=1 … strlen FAST + literal length キャッシュ
- NYASH_LLVM_FAST_INT=1 … i64 ホットパス( 同一BB SSA 優先)
- NYASH_VERIFY_RET_PURITY=1 … Ret 純化ガード(開発ガード)
- NYASH_LLVM_SKIP_BUILD=1 … ny_mir_builder.sh の再ビルド抑止(既存バイナリ再利用)
- NYASH_MIR_DEV_IDEMP=1 … MIR normalize/dev 用の再実行安定化( idempotence) メタ。既定OFF( 診断専用)
- HAKO_MIR_NORMALIZE_PRINT=1 … AotPrep(.hako) 側で print→externcall(env.console.log) を正規化( CFG不変・既定OFF)
- HAKO_MIR_NORMALIZE_REF=1 … AotPrep(.hako) 側で ref_get/ref_set→boxcall(getField/setField) を正規化( CFG不変・既定OFF)
- HAKO_SILENT_TAGS=0|1 … v2ランナーのタグ静音トグル( 1=静音: 既定、0=生ログ)
Wrap‑ up (this session)
- Rust/Hako ownership clarified( docs/development/normalization/ownership.md) 。Hako=意味論正規化、Rust=構造/安全。
- Runtime autoload for using.dylib( guarded) を Runner 初期化に集約。箱名は nyash_box.toml から推論して登録。
- Builder/VM safety: 受信ローカライズを強化( LocalSSA/pin/after‑ PHIs/tail) 。未定義受信は同一BBの直近 NewBox< Box > で構造回復( dev 安全弁)に限定。
- PluginInvoke→BoxCall の過剰な書換えを停止(意味論は Hako 側の methodize に集約)。
- カナリア:
- phase217_methodize_canary.sh → PASS( rc=5) 。
- phase217_methodize_json_canary.sh → v1 + mir_call present( Method が優先、Global は経過容認)。
- phase217_methodize_json_strict.sh を追加( selfhost‑ only 仕上げ用ゲート、現状は Stage‑ B child パース修正が必要)。
## Phase 21.5 — Optimization Checklist( 進行管理)
- [x] パス分割( AotPrep: StrlenFold / LoopHoist / ConstDedup / CollectionsHot / BinopCSE)
- [x] CollectionsHot: Array/Map の boxcall→externcall( 既定OFF・トグル)
- [x] Map key モード導入(`NYASH_AOT_MAP_KEY_MODE={h|i64|hh|auto}` )
- [x] LoopHoist v1: compare/mod/div 右辺 const の前出し(参照 const を先頭へ)
- [x] BinopCSE v1: `+/*` の同一式を再利用、`copy` で伝播
- [x] VERIFY ガード常時ON( `NYASH_VERIFY_RET_PURITY=1` )で測定
- [x] ベンチ新規(`linidx` /`maplin` )追加・実測を README に反映
- [x] LoopHoist v2: `+/*` 右項 const の連鎖前出し、fix‑ point( ≤3周) の安全適用( 定数 binop 折畳み+ hoist 実装)
- [x] BinopCSE v2: 線形 `i*n` の共通化強化( copy 連鎖の正規化・左右交換可の正規化)
- [x] CollectionsHot v2: Array/Map index/key の式キー共有(同一ブロック短窓で get/set の a0 を統一)
- [x] Map auto 精緻化: `_is_const_or_linear` の再帰判定強化( copy 追跡+ div/rem の定数片を線形扱い)
- [x] Rust normalize.rs の借用修正( E0499/E0502解消) + dev idempotence メタ追加( 既定OFF)
- [x] 正規化の .hako 化( 新箱でモジュール化) : NormalizePrint / NormalizeRef を AotPrep から opt-in で呼び出し
- [ ] Idempotence: 置換済みマーク( devメタ) で再実行の結果不変を担保
- [ ] ベンチ更新: `arraymap` /`matmul` /`sieve` /`linidx` /`maplin` EXE 比率 ≤ 125%( arraymap/matmul優先)
### 21.5 引き継ぎメモ(ベンチ&観測)
- 新規トグル/修正
- `NYASH_LLVM_DUMP_MIR_IN=/tmp/xxx.json` ( AOT 入力MIRダンプ)
- dump_mir.sh: provider/selfhost-first + min fallback で実MIRダンプを安定化
- microbench: `PERF_USE_PROVIDER=1` で jsonfrag 強制を解除( 実MIRでの突合せ用)
- ベンチ現状( EXE, C=100%)
- arraymap: 150– 300%(分散あり) / matmul: 300% / sieve: 200% / linidx: 100% / maplin: 200%
- 次のアクション
1) arraymap/matmul の実MIR( provider or `NYASH_LLVM_DUMP_MIR_IN` )で index SSA 共有の崩れを特定
2) CollectionsHot v2.1: 同一ブロック短窓 get→set で a0 の一致を強制(式キー統一の取りこぼし追加)
3) BinopCSE 小窓 fix‑ point 拡張(隣接ブロックまでの `i*n+k` 共有; 制御不変・既定OFF)
4) 再ベンチ( arraymap/matmul/maplin) → `benchmarks/README.md` に 日付/トグル/ratio ≤ 125% を追記
5) provider emit の失敗パターンを継続調査( emit ラッパの fallback/guard を追加調整)
Decisions
- 既定挙動は変更しない( dev では methodize トグルON、CI/ユーザ既定は従来維持)。
- Rust 層は正規化を持たず、構造のみ( SSA/PHI/LocalSSA/安全弁) 。Hako が mir_call(Method) のSSOT。
Rust normalize.rs sunset plan( 記録)
- 目的: normalize.rs の責務を .hako 側へ移し、Rust 側は既定OFF→撤去へ。
- 段階:
- 1) dev カナリア期間は `HAKO_MIR_NORMALIZE_*` ( PRINT/REF/ARRAY) を opt-in で運用( 既定OFF) 。
- 2) AotPrep 経由の normalize が十分に安定後、dev/quick で既定ONへ昇格( CI は段階移行)。
- 3) Rust 側 normalize は env で明示 ON のみ許可(互換ガードを残す)。
- 4) 既定ON 状態で 2 週安定を確認後、Rust normalize のビルド配線を外し、最終撤去。
- 付随: 新規/更新トグルは env 一覧へ追記し、昇格時にデフォルト化→古いトグルは段階的に非推奨化とする。
Follow‑ ups (carried to backlog)
- Stage‑ B child の "Unexpected token FN" 修正( selfhost‑ first/strict ゲート用)。
- Provider 出力の callee を Method へ寄せ、Global 経過容認を段階縮小。
- core_bridge の methodize ブリッジは bring‑ up 用。Hako 既定化後に撤去。
# Next Active Task — Phase 21.16( Pre‑ Optimization / 最適化前フェーズへ戻す)
Intent
- 正規化の骨格が揃った段階で、最適化前の安定化に戻す(意味論は不変、構造/観測の強化)。
Scope( 当面の作業)
1) Optimizer 前段の安定化(構造のみ)
- normalize_legacy/ref_field_access は構造変換の範囲に留める(意味論を変えない)。
- NYASH_MIR_DISABLE_OPT/HAKO_MIR_DISABLE_OPT で最適化全休のゲートを尊重(既存)。
2) Baseline/観測
- quick/integration の rc/出力をゴールデン更新( mir_call 既定はまだOFF) 。
- crate_exec タイムボックスを EXE テストへ段階横展開。
- プラグイン parity の軽量観測( autoload ガード有効時)。
3) テスト整備
- 受信未定義の負テスト追加( Builder で防止) 。dev 安全弁を将来的にOFFにできる状態を作る。
- v1 + unified の canary は dev のみ strict を維持( CI は現状どおり)。
Exit criteria( 21.16)
- Optimizer OFF でも quick/integration/plugins が安定緑。
- 受信ローカライズの穴が負テストで検知可能( dev 安全弁に依存しない)。
- v1/unified は dev プロファイルで常時確認可能(既存トグルで担保)。
Handoff Summary (ready for restart)
- Delegate v1 fixed (provider‑ first): tools/hakorune_emit_mir.sh now prefers env.mirbuilder.emit to emit MIR(JSON v1). Legacy CLI converter kept as fallback with NYASH_JSON_SCHEMA_V1=1/NYASH_MIR_UNIFIED_CALL=1.
- Selfhost‑ first stabilized for mini cases: HAKO_SELFHOST_TRY_MIN=1 in dev profile; min runner (BuilderRunnerMinBox.run) is used when builder fails.
- Methodize canaries:
- phase217_methodize_canary.sh → compile‑ run rc=5 PASS( semantics)
- phase217_methodize_json_canary.sh → schema_version present + mir_call present( Method preferred; Global tolerated for now)
- Dev one‑ gun toggles (enable_mirbuilder_dev_env.sh): HAKO_STAGEB_FUNC_SCAN=1, HAKO_MIR_BUILDER_FUNCS=1, HAKO_MIR_BUILDER_CALL_RESOLVE=1, NYASH_JSON_SCHEMA_V1=1, NYASH_MIR_UNIFIED_CALL=1, HAKO_SELFHOST_TRY_MIN=1.
2025-11-15 00:02:13 +09:00
---
Update (2025-11-15 — Phase 25 / 25.1 handoff: numeric_core & Stage0/Stage1 bootstrap)
- Context:
- Phase 21.8 の imports 導線まで完了し、`matmul_core` EXE/LLVM 統合と numeric runtime AOT は Phase 25 に移管済み。
- Phase 25 では Ring0/Ring1 分離と Numeric ABI( IntArrayCore/MatI64) 設計を docs に固定済み。
- このホストでは numeric_core パスと Stage0/Stage1 設計の「土台」までを整備し、実際の BoxCall→Call 降ろしと自己ホストバイナリ構築は次ホスト( Claude Code) に委譲する。
- Done (this host):
- Docs/設計:
- Phase 25 README を Numeric ABI + BoxCall→Call 方針に合わせて更新( numeric は Hako 関数 Call、ExternCall は rt_mem_* 等のみ)。
- `docs/development/runtime/NUMERIC_ABI.md` に IntArrayCore/MatI64 の関数契約を整理(実体は Hako 関数、必要になれば FFI にも載せられる)。
- `docs/development/runtime/system-hakorune-subset.md` に runtime/numeric core 用言語サブセットを定義。
- `lang/src/runtime/numeric/README.md` に IntArrayCore/MatI64 の Box API と numeric core の分離構造を記述。
- `docs/development/runtime/ENV_VARS.md` に `NYASH_AOT_NUMERIC_CORE` / `NYASH_AOT_NUMERIC_CORE_TRACE` を追記。
- Phase 25.1 用 README 追加( Stage0=Rust bootstrap / Stage1=Hakorune selfhost バイナリの構想と配置案)。
- Numeric runtime:
- `lang/src/runtime/numeric/mat_i64_box.hako` で `MatI64.mul_naive` を `NyNumericMatI64.mul_naive` へ分離( Box=API/所有権、NyNumericMatI64=ループ本体)。
- AotPrep numeric_core パス( MVP土台) :
- `lang/src/llvm_ir/boxes/aot_prep/passes/numeric_core.hako` を追加。
- MatI64 由来の const/new/copy/phi から `tmap` を構築(`rN -> MatI64` )。
- `BoxCall(MatI64, "mul_naive", ...)` を検出し、`Call("NyNumericMatI64.mul_naive", [recv, args...])` に書き換えるロジックを実装(現状は AotPrep 統合が失敗しているため未実運用)。
- TRACE ON 時に type table / 変換件数 / skip 理由をログ出力。
- `lang/src/llvm_ir/aot_prep.hako` に numeric_core パスを統合(`NYASH_AOT_NUMERIC_CORE=1` で `AotPrepPass_NumericCore.run` を実行)。
- `lang/src/llvm_ir/hako_module.toml` に `aot_prep.passes.numeric_core = "boxes/aot_prep/passes/numeric_core.hako"` を追加。
- `tools/hakorune_emit_mir.sh` :
- AotPrep(run_json) 呼び出しに `NYASH_AOT_NUMERIC_CORE` / `TRACE` をパススルー。
- `_prep_stdout` から `[aot/numeric_core]` 行を拾って stderr に透過( TRACE ON 時)。
- VM step budget:
- Rust VM( `src/backend/mir_interpreter/exec.rs` )において、`HAKO_VM_MAX_STEPS` / `NYASH_VM_MAX_STEPS` = 0 を「上限なし」と解釈するように変更。
- AotPrep(run_json) 実行時に `HAKO_VM_MAX_STEPS=0` / `NYASH_VM_MAX_STEPS=0` をデフォルト指定(無限ループに注意しつつ、現状の長大 JSON でも落ちにくくする目的)。
- 現状の問題( Claude Code への引き継ぎポイント):
- `AotPrepBox.run_json` 統合経路が、selfhost VM 実行中に `vm step budget exceeded (max_steps=1000000)` で失敗しており、AotPrep 全体が rc=1 → `tools/hakorune_emit_mir.sh` が元の MIR(JSON) にフォールバックしている。
- このため numeric_core の BoxCall→Call 変換は最終 MIR には反映されていない( PREP 後の JSON にも `boxcall` が残る)。
- Rust VM 側は 0=unbounded 対応済みだが、selfhost VM 経路のどこかが依然として 1_000_000 ステップ上限で走っている可能性が高い。
- numeric_core の JSON パースで `_seek_object_end` の使い方に問題がある兆候:
- `build_type_table` / `build_copy_map` で JSON 全体に対して `{` をスキャンして `_seek_object_end` を呼んでいるため、ルート `{` から呼ばれた場合に JSON 全体末尾まで飛ぶ。
- 結果として「1 命令オブジェクト」ではなく「functions ブロック全体」を inst として扱ってしまい、`dst=0` と `"MatI64"` が同じ巨大文字列内に混在 → 型判定や BoxCall 検出が誤動作する。
- CollectionsHot は `find_block_span` + 命令配列スライスを使っているため問題が顕在化していないが、numeric_core 側では命令単位スキャンの前処理が足りていない。
- TODO( 次ホスト向け指示) :
1) `AotPrepNumericCoreBox` を単体で安定化する:
- `AotPrepNumericCoreBox.run` を直接呼ぶテストで、MatI64.new/mul_naive/at を含む MIR(JSON) に対して BoxCall→Call 変換が正しく行われることを確認。
- `_seek_object_end` を「命令オブジェクトの `{` 」に対してのみ呼ぶ形にリファクタ(`"\"op\":\"...\""` の位置から `lastIndexOf("{")` でオブジェクト先頭を求めるなど)。
2) AotPrep(run_json) 経路の VM 実装と Step budget を特定し、`HAKO_VM_MAX_STEPS=0` / `NYASH_VM_MAX_STEPS=0` が実際に効いているかを確認。
3) 統合テスト:
- `NYASH_AOT_NUMERIC_CORE=1 NYASH_AOT_NUMERIC_CORE_TRACE=1 HAKO_APPLY_AOT_PREP=1` で `tools/hakorune_emit_mir.sh tmp/matmul_core_bench.hako ...` を実行し、PREP 後 MIR に `call("NyNumericMatI64.mul_naive", ...)` が含まれ、対応する `boxcall` が消えていること。
- VM/LLVM 両ラインで `matmul_core` の戻り値が従来と一致していること(小さい n=4,8 程度でOK) 。
4) Numeric core 関連のエラー表示強化:
- `NYASH_AOT_NUMERIC_CORE_TRACE=1` 時に、type table が空/変換 0 件/ skip 理由(型不一致など)を必ずログ出しすることで、「静かにフォールバックする」状態を避ける。
2025-11-13 16:40:58 +09:00
Next Steps (post‑ restart)
1) Selfhost‑ first child parse fix( Stage‑ B) : resolve the known “Unexpected token FN” in compiler_stageb chain; target [builder/selfhost‑ first:ok] without min fallback.
2) Provider output callee finishing: prefer Method callee so JSON canary asserts Method strictly (now Global allowed temporarily).
3) Consolidate remaining legacy converter usage to provider where possible; keep defaults unchanged.
4) Docs: 21.7 checklist updated; core_bridge methodize remains diagnostic‑ only (OFF) with a removal plan once Hako methodize is default.
# New Active Task — Phase 21.6( Dual‑ Emit Parity & C‑ line Readiness)
Intent
- Provider( Rust) と Selfhost( Hako) で同一の MIR(JSON) を出力できることを確認し、生成時間を計測・比較する。AOT( ny‑ llvmc/crate) も O0 既定で安定させる。
What’ s done (this session)
- Perf ツール追加:
- MIR emit bench: `tools/perf/bench_hakorune_emit_mir.sh`
- AOT bench: `tools/perf/bench_ny_mir_builder.sh`
- 構造比較: `tools/perf/compare_mir_json.sh`
- Dual emit + 比較 + ベンチ: `tools/perf/dual_emit_compare.sh`
- Docs 整備:
- `docs/guides/perf/benchmarks.md` (手順/トグル)
- README/README.ja にパフォーマンス導線を追記
- `docs/ENV_VARS.md` にベンチ関連のトグルを追加
- 小最適化(意味論不変):
- Builder の不要 clone / finalize 二重呼び出し削減
- VM console 出力の to_string の枝刈り( String/StringBox/Null 先出し)
- VM 受信未定義の負テストを 3 本追加( Array/Map/String) 。fail‑ fast を監視
Known issue / Action
- Provider 経路( tools/hakorune_emit_mir.sh の provider‑ first) が一部環境で `Program→MIR delegate failed` になることがある。
- 原因: Stage‑ B 実行の stdout にログが混在し JSON 抽出が空になるケース。
- 対策(次実装): ラッパを tmp 経由の CLI 変換(`--program-json-to-mir` ) へフォールバックさせる安全化。selfhost‑ first も明示トグルで維持。
Plan (next after restart)
1) tools/hakorune_emit_mir.sh を安全化( Stage‑ B→tmp→CLI 変換フォールバック) 。stderr/JSON 分離を強化
2) 代表 4 ケース( json_pp / json_query_min / json_lint / json_query) で dual‑ emit を 5 回実行し、21.6 表に p50/Parity を記入
3) Parity 不一致はカテゴリ化( callee 種別/順序/PHI/メタ) して修正元を特定( provider か selfhost)
4) AOT( ny‑ llvmc) O0 の 3 回ベンチを取得、必要なら O1 スポットも取得
Tracking
- 記録台帳: `docs/development/roadmap/phases/phase-21.6/README.md` の表へ随時追記(チェックボックス方式)
2025-11-11 22:35:45 +09:00
Phase 21.6 wrap-up
- Parser(Stage‑ B) ループJSONの保守フォールバックで壊れ形のみ復元( 正常形は素通り)
- 代表E2E( return/binop/loop/call) PASS( call は関数化: "Main.add" → Global 関数呼び出し)
- VM/LLVM にユーザー関数呼び出しを追加実装( VMのGlobal dispatch、LLVMのarity補正/事前定義)
- docs 追加: phase-21.6-solidification、canaries 整備
Next — Phase 21.7 (Normalization & Unification)
- 目的: Global("Box.method") ベースの関数化正規化から、段階的に Method 化(静的シングルトン受信)へ統一
- 既定は変更しない。dev トグルで methodize→canary 緑→既定化の順
- 命名とarityの正規化は最適化前に完了させる
2025-11-10 19:42:42 +09:00
- Added always-on quick runner: `tools/smokes/v2/run_quick.sh` ( fast, SKIP-safe)
- Includes Stage‑ B Program(JSON) shape and loop_scan (!= with else Break/Continue) canaries.
- Hardened MirBuilder internals: replaced JSON hand scans with `JsonFragBox` in core paths (Return/If/Loop/Method utils).
- Added opt‑ in registry canaries( structure/tag observation only; remain optional) .
- Added MirBuilderMin (bring‑ up minimal builder): `hako.mir.builder.min`
- Purpose: tiny using set to avoid heavy prelude in this host; emits `[mirbuilder/min:*]` tags.
- New canaries (PASS): builder_min_method_arraymap_{get,push,set,len}_canary_vm.sh
2025-11-11 02:07:12 +09:00
- Added direct-lower canary (PASS): registry_optin_method_arraymap_direct_canary_vm.sh
2025-11-10 19:42:42 +09:00
- Phase2034 canaries: migrated several rc‑ based checks to content checks
- If family: varint/varvar/nested/then-follow → now print MIR and assert '"op":"compare"'+'"op":"branch"'
- Return family: var_local/bool/float/string/binop_varint/logical → now print MIR and assert minimal tokens
- Removed nested command substitution in `mirbuilder_canary_vm.sh` ; switched to content assertion
2025-11-11 21:24:51 +09:00
- Registry(get) Full path: exercised fast path (JsonFrag‑ only) via `HAKO_MIR_BUILDER_REGISTRY_ONLY=return.method.arraymap` and pinned canary to registry tag only
Update (today)
- Selfhost builder child defaults: when `HAKO_MIR_BUILDER_LOOP_FORCE_JSONFRAG=1` , auto-enable normalizer+purify for child (`HAKO_MIR_BUILDER_JSONFRAG_NORMALIZE=1` , `HAKO_MIR_BUILDER_JSONFRAG_PURIFY=1` ) — dev-only, defaults unchanged.
- Normalizer tag passthrough: `HAKO_MIR_BUILDER_NORMALIZE_TAG` is now forwarded to selfhost child; remains quiet by default.
- strlen FAST path (crate harness): Python lowering now calls neutral kernel symbol `nyrt_string_length(i8*, i64)` when `NYASH_LLVM_FAST=1` .
- NyRT kernel: added `nyrt_string_length` and legacy alias `nyash.string.length_si` implementations (byte length, mode reserved).
- Canary: added `tools/smokes/v2/profiles/quick/core/phase2034/emit_boxcall_length_canary_vm.sh` to assert `--emit-mir-json` contains `boxcall length` .
- Stage‑ B parser loop JSON: added conservative fallback in `ParserControlBox.parse_loop` to recover empty body and `rhs:Int(0)` regressions; new canary `tools/dev/stageb_loop_json_canary.sh` PASS( dev補助・既定挙動不変) 。
2025-11-10 19:42:42 +09:00
2025-11-11 02:07:12 +09:00
Additional updates (dev-only, behavior unchanged by default)
- VM counters wired: `inst_count` ( non‑ phi) , `compare_count` ( Compare) , `branch_count` ( Branch)
- Print with `NYASH_VM_STATS=1` as `[vm/stats] inst=… compare=… branch=…`
- Microbench harness: fixed ratio print noise( heredoc→one‑ liner) 。
- EXE canaries: crate backend bring‑ up hardened
- Added `enable_exe_dev_env` helper and applied to representative EXE tests
- Enabled `NYASH_LLVM_VERIFY=1` /`NYASH_LLVM_VERIFY_IR=1` for deterministic cases
- Promoted `return42` canary to FAIL on mismatch (was SKIP)
2025-11-11 22:35:45 +09:00
Action items( 21.7)
1) docs: phase-21.7-normalization/README.md, CHECKLIST.md( 追加済み)
2) MirBuilder( dev) : HAKO_MIR_BUILDER_METHODIZE=1 で Global("Box.method") → Method(receiver=singleton)
3) VM: Method 経路の静的シングルトンを ensure_static_box_instance で安定化(既存機能の活用)
4) LLVM: mir_call(Method) を既存 unified lowering で実施、必要なら receiver の型/引数整合を補助
5) canary: methodize OFF/ON 両方で rc=5 を維持、method callee を観測( dev)
6) 既定化と撤去計画: 緑維持後、methodize を既定ON → Global 互換は当面維持
2025-11-10 19:42:42 +09:00
2025-11-11 21:24:51 +09:00
Phase 21.6 tasks (bug‑ first, default OFF aids)
1) Parser(Stage‑ B) loop JSON canaryを緑に維持( tools/dev/stageb_loop_json_canary.sh)
2) Delegate MirBuilder 経路で最小ループの MIR(JSON) → EXE(rc=10)( tools/dev/phase216_chain_canary.sh)
3) VM/EXE パリティを1件追加( 最小ループ) し、差分が出たらFail‑ Fastで停止
4) 代表ケース( return/binop/method/loop) を少数固定し、自己ホスト導線は hakorune スクリプトのみで回す
5) 最適化( 21.5) は全停止。全カナリアが緑になってから再開( docs/phase‑ 21.6参照)
2025-11-10 19:42:42 +09:00
Constraints / Guardrails
- quick remains green; new toggles default OFF( `NYASH_LLVM_FAST` / `NYASH_VM_FAST` )。
- Changes small, reversible; acceptance = EXE parity + speedup in benches.
2025-11-11 22:35:45 +09:00
Phase references
- 21.6: docs/development/roadmap/phases/phase-21.6-solidification/{README.md,CHECKLIST.md}
- 21.7: docs/development/roadmap/phases/phase-21.7-normalization/{README.md,CHECKLIST.md}
2025-11-10 19:42:42 +09:00
2025-11-11 02:07:12 +09:00
---
Stage‑ B → MirBuilder → ny‑ llvmc( crate EXE) — Pre‑ Optimization Goal
2025-11-11 21:24:51 +09:00
Status (2025‑ 11‑ 11)
- Loop JsonFrag → crate EXE canary: PASS( rc=10)
- Root fix: PHI プレースホルダの一元化(前宣言→再利用→配線)
- 前宣言: tagging.setup_phi_placeholders で ensure_phi + predeclared_ret_phis に保存
- 再利用: resolver/compare/ret/values が builder の global vmap を参照して同一SSAを読む
- 配線: wiring.finalize_phis が前宣言PHIのみを配線、重複/空PHIを抑止
- 代表スクリプト: tools/smokes/v2/profiles/quick/core/phase2100/stageb_loop_jsonfrag_crate_exe_canary_vm.sh( rc=10)
- 並行確認
- emit boxcall( v0) : 維持( PASS)
- strlen FAST( crate) : 維持( PASS, rc=5)
Phase 21.5 — Optimization folder
- New docs: docs/development/roadmap/phases/phase-21.5-optimization/ (README.md, CHECKLIST.md)
- New perf wrappers: tools/perf/phase215/{bench_loop.sh, bench_strlen.sh, bench_box.sh, run_all.sh}
- Usage example: RUNS=5 TIMEOUT=120 tools/perf/phase215/run_all.sh
Rollback 手順(最小)
- 万一差戻しが必要な場合:
1) instruction_lower の phi で一時的に ensure_phi を復活(今回撤去したローカル生成を戻す)
2) tagging の predeclared_ret_phis 保存を OFF( 行削除)
3) utils/values の global vmap 参照を削除( resolve_i64_strict を元に)
4) 影響範囲は src/llvm_py/* のみ( ny-llvmc ラッパーは無変更)
Notes( ライン確認)
- ny-llvm 本線( crate) は、ny-llvmc → tools/llvmlite_harness.py → src/llvm_py/llvm_builder.py という導線。
- 今回の PHI 一元化は src/llvm_py 配下のため、crate( ny-llvmc) 経路に直接効く( ハーネスは内部) 。
- tools/ny_mir_builder.sh は既定で BACKEND=crate を選択し、ny-llvmc を呼ぶ( llvmlite 直選択は明示時のみ)。
2025-11-11 02:07:12 +09:00
- Goal (pre‑ 21.5 optimization): build EXE via crate backend (ny‑ llvmc) from Stage‑ B Program(JSON) → MirBuilder MIR(JSON) before focusing on perf. Make EXE self‑ hosting reliable on this host.
- Why now
- VM self‑ host is green. EXE canaries (return/compare/binop/phi/externcall) are green.
- Loop/strlen general cases fail in crate EXE due to builder output mixing `newbox/MapBox` (loop) and missing FAST path (strlen). Fix these first to unlock fair “execute‑ only” microbench.
- Plan (small, reversible, default‑ OFF)
1) Loop JSONFrag purification (no MapBox/newbox)
- Ensure `HAKO_MIR_BUILDER_LOOP_JSONFRAG=1` route emits pure control‑ flow MIR only (const/compare/branch/phi/ret).
- Acceptance: MIR(JSON) for minimal loop contains no `newbox|MapBox` ; crate EXE build PASS; add canary to assert absence and EXE RC parity.
2) strlen FAST path (opt‑ in)
- ny‑ llvmc lowering (FAST=1): `externcall nyrt_string_length(i8*, i64)` (returns i64; no boxing).
- Add `nyrt_string_length` to `crates/nyash_kernel` (minimal impl; byte/char mode param reserved).
- Acceptance: FAST=1 で crate EXE RC=5( "nyash".length) ; FAST=0 挙動不変。
3) Selfhost EXE wrapper (dev helper)
- Script (plan): `tools/selfhost_exe_stageb.sh`
- Stage‑ B Program(JSON) emit → MirBuilder to MIR(JSON) via `tools/hakorune_emit_mir.sh`
- Build EXE via `tools/ny_mir_builder.sh --emit exe` (force `NYASH_LLVM_BACKEND=crate` )
- Optional: run + RC parity check vs VM
4) Canaries / Runner
- Loop JSONFrag no‑ MapBox check (FAIL 基準)
- strlen FAST EXE RC check( FAST=1 のみタグ観測/ 既定OFFで静音)
- EXE parity: minimal Stage‑ B sample VM↔EXE RC 一致
5) Acceptance & Docs
- quick 代表( EXE混在) は `--timeout 120` 推奨で緑維持(既定は変更しない)
- CURRENT_TASK/README に切替手順とフラグ記載(ロールバック容易)
- Toggles / Scripts
- `HAKO_MIR_BUILDER_LOOP_JSONFRAG=1` ( Loop を JSONFrag 直組立に固定)
- `HAKO_MIR_BUILDER_JSONFRAG_NORMALIZE=1` (任意)
- `NYASH_LLVM_BACKEND=crate` / `NYASH_NY_LLVM_COMPILER=target/release/ny-llvmc` / `NYASH_EMIT_EXE_NYRT=target/release`
- Helper: `tools/hakorune_emit_mir.sh` ( Stage‑ B→MIR) 、`tools/ny_mir_builder.sh --emit exe` ( crate で obj/exe)
- Done (recent)
2025-11-13 16:40:58 +09:00
- EXE canaries hardened( enable_exe_dev_env 適用・検証ON・代表は FAIL 基準へ昇格)
- VM runtime counters( `NYASH_VM_STATS=1` )
- microbench `--exe` 実装( ビルド1回→EXEをRUNS回実行) 。現状、loop/strlen の一般形は crate 未対応で EXE 失敗 → 上記 1)/2) で解消予定。
2025‑ 11‑ 12 Updates( PHI grouping fix, ret‑ after guards, provider hooks)
- LLVM Python backend( llvmlite harness/crate 経由)
- Return 合成 PHI を常にブロック先頭に配置( PHI グルーピング違反の根治)。
- lowering 入口( boxcall/mir_call/safepoint) で terminator 後の誤挿入を防止( 継続BBへ移動) 。
- builder 側でブロック命令列は最初の terminator( ret/branch/jump) で打ち切る。
- JsonFrag 正規化・純化( dev)
- purify=1 で newbox/boxcall/externcall/mir_call を除去、ret 以降を打ち切り。
- provider-first フック( dev)
- HAKO_MIR_NORMALIZE_PROVIDER=1 で provider 出力 MIR にも正規化を適用可能。
- HAKO_MIR_BUILDER_LOOP_FORCE_JSONFRAG=1 を provider-first にも適用(最小ループ MIR を直返し)。
Verified
- selfhost-first + JsonFrag 正規化+ purify: llvmlite=OK / ny‑ llvmc=OK( EXE生成)
- provider-first + FORCE_JSONFRAG: ny‑ llvmc=OK( EXE生成)
Open
- provider-first の通常出力に対する純化強化( ret ブロックの副作用禁止を徹底)。
- strlen(FAST) の適用強化( resolver マーク補強 → IR に nyrt_string_length を反映)。
- Rust→.hako Normalize 移行計画( Self‑ Host First / Freeze準拠)
- 方針
- 正規化/置換系は Rust 側から .hako( AotPrep/MirBuilder 直下の新規箱)へ段階移行する。
- Rust 層は最小シーム+安全ガード(互換維持・借用修正・診断)に限定。既定挙動は不変。
- 現状
- 実装済み( opt‑ in、既定OFF) : NormalizePrintBox( print→externcall) 、NormalizeRefBox( ref_get/ref_set→boxcall) 。
- Rust 側 normalize.rs は借用修正のみ。dev 用 idempotence トグル( NYASH_MIR_DEV_IDEMP=1) を追加( 既定OFF) 。
- これから(段階)
1) .hako 正規化のカナリア整備( 出力形状トークン検証+ VM/EXE RC パリティ)。
2) Rust 側の同等パスは「既定OFF」を明文化し、.hako 側が有効な場合は二重適用を避ける運用に統一(最終的に Rust 側の normalize はOFF運用) 。
3) 代表ケースが緑になった段階で、.hako 側をデフォルト化( dev/bench ラッパでON) 。
4) 安定期間後、Rust 側の当該パスを撤去(環境変数は deprecate → 警告 → 削除の順)。
- 環境変数の扱い(増えたトグルの将来)
- いまは opt‑ in( 既定OFF) 。デフォルト化タイミングで .hako 側トグルはON に寄せ、Rust 側の旧トグルは非推奨化。
- 最終的に Rust 側トグルは削除(ドキュメントも更新)。.hako 側は必要最小のみ残す。
2025-11-11 02:07:12 +09:00
- Next (actionable)
- Implement loop JSONFrag purification (no MapBox/newbox) and add canary
- Add strlen FAST lowering + `nyrt_string_length` (kernel) + EXE canary
- Wire `tools/selfhost_exe_stageb.sh` and record one EXE parity check
- Then resume 21.5 optimization and run microbench with `--exe` ( execute‑ only timing)
MirBuilder/JsonFrag note
- JsonFrag path is for structure observation only (minimal MIR). Semantics remain prioritized by the default path. Keep it default OFF and tag‑ gated. Builder toggles are centralized in `hako.mir.builder.internal.builder_config` to reduce scattered `env.get` calls in lowers.
2025-11-10 19:42:42 +09:00
Toggles (dev)
- `NYASH_VM_FAST=1` ( VM micro fast paths: new StringBox, String.length/size)
- `NYASH_LLVM_FAST=1` ( ny-llvmc AOT lowering fast path; default OFF)
- `HAKO_MIR_BUILDER_SKIP_LOOPS=1` ( skip loop lowers in MirBuilderBox; default OFF)
- `HAKO_MIR_BUILDER_REGISTRY_ONLY=<name>` ( restrict registry for diagnostics; default unset)
Next (short)
- Extend MirBuilderMin to accept minimal compare/binop (structure only) and add 1– 2 min canaries.
- Keep full MirBuilder path unchanged (opt‑ in, still SKIP on this host); gradually replace Box‑ heavy bits with JsonFrag‑ only output.
Next after restart — Focused checklist
- Min Builder( if/compare: Var cases)
- [x] lower_if_compare_varint_box.hako: then/else Return(Int) を境界限定で抽出( then→else手前、else→ブロック内)
- [x] lower_if_compare_varvar_box.hako: 同上の境界検出を追加
- [x] canary PASS 化: `builder_min_if_compare_varint_canary_vm.sh` / `builder_min_if_compare_varvar_canary_vm.sh`
- [x] try_lower 順序の最終確認( var 系 → intint)
- [x] fold 系の取り込み( Min) : varint/binints を追加しタグ観測(`[mirbuilder/min:if.compare.fold.*]` )
- MirBuilder( フル経路の軽量化・段階)
- [x] compare/fold( IntInt/VarInt/VarVar) を境界限定へ置換( inline/Lower 双方)
- [x] registry: Min 経路での canary PASS 化(`[min|registry]` 許容)
2025-11-10 19:50:30 +09:00
- [x] 重い using の原因箇所から Box 依存を JsonFrag のテキスト組立へ置換(点で進める)
- **調査完了**: method系lower( array/map) は既にJsonFrag置換済み( 文字列結合でMIR JSON生成)
- **残存Box使用**: 3箇所のみ( loop系lowerでLoopFormBox.build2()へのopts渡し用 `new MapBox()` )
- **Test結果**: phase2034 全29テスト PASS、phase2160 registry 全7テスト PASS
2025-11-10 19:42:42 +09:00
- [x] registry:return.method.arraymap( get) を Full(JsonFrag) へ固定し、canary を registry 単独 PASS に更新
- [x] registry:return.method.arraymap( set/push/len) も順次 Full に移植( Min 許容を段階撤去)
2025-11-10 19:50:30 +09:00
- [x] loop lowers は必要時のみ `HAKO_MIR_BUILDER_SKIP_LOOPS=1` を使用( 既定OFF)
- **現状**: loop系lowerは最小MapBox使用のみ、スキップ不要
2025-11-10 19:42:42 +09:00
- Runtime( ファイルプロバイダ)
- [x] FileBox を ring‑ 1 常備( core‑ ro) として登録( panic 経路の撤廃; plugin‑ only は従来通り)
- [x] ENV 追補の確認: MODE/ALLOW_FALLBACK/JSON_ONLY の説明を ENV_VARS.md に整合
Env tips( bring‑ up)
- Auto + このホスト: `NYASH_JSON_ONLY=1` か `NYASH_FILEBOX_ALLOW_FALLBACK=1` で JSON パイプを静音&安定化
- registry 診断: `HAKO_MIR_BUILDER_REGISTRY_ONLY=return.method.arraymap` で 1 件に絞る
Progress — 22.1 MirBuilder 緑化( Bring‑ up 導線)
- Return 系の JSON 文字列出力へ統一( Int/Float/String/VarInt/VarVar)
- If 系( varint/varvar/intint/fold) の then/else 抽出を配列境界限定化
- Min Builder 強化( fold 取り込み+タグ出力)
- テスト整理:
- include を using へ全面置換
- dev トグルを test_runner に集約(`enable_mirbuilder_dev_env` )
- registry canary は当面 `[min|registry]` 許容でパス計画→段階で registry 単独に収束
- phase2034: rc 依存 canary を内容トークン検証へ移行(完了)
- 対応済: if(compare eq/le/ge/ne/varint/varvar/nested/then-follow), return(var_local/bool/float/string/binop_varint/logical)
- 備考: core_exec 系は rc 検証維持(意味検証のため)
Next (pre‑ Optimization — MirBuilder build line復活まで)
1) phase2034 の ENV 直書きを `enable_mirbuilder_dev_env` に置換(集約)
2) registry 直経路の軽量化( JsonFrag 置換)を 1 箇所ずつ移植( array/map 周辺から)
3) MirBuilder‑ first 導線( tools/hakorune_emit_mir.sh) をトグルで有効化( 既定OFF)
4) FAIL_FAST=1/ny‑ compiler=既定 の条件で緑維持を確認し、dev トグルを段階撤去
5) tests/NOTES_DEV_TOGGLES.md を追加( dev トグルの意味・使い所・撤去方針)
2025-11-10 23:17:46 +09:00
Loop 化の小ステップ(構造→置換)
- [x] 最小シーム化: Loop lowers( simple / sum_bc / count_param) の MapBox 生成・set を `loop_opts_adapter` に退避(置換点の集約)
- [x] トグル検証: `HAKO_MIR_BUILDER_SKIP_LOOPS=1` の canary を追加( ON=回避、OFF=通常)
- [x] JsonFrag 置換( opt-in) : `loop_opts_adapter.build2(opts)` で JsonFrag ベースの最小 MIR(JSON) を出力(タグ `[mirbuilder/internal/loop:jsonfrag]` )
- [x] 残り 2 件へ水平展開( simple/sum_bc/count_param の3種を対応済・挙動不変/ 既定OFF)
Next( Loop/JsonFrag polish)
- [ ] JsonFragの精度引上げ( phi整列・ret値の正規化・const宣言の整理) — 既定OFFのまま小刻み導入( 参照: docs/checklists/mirbuilder_jsonfrag_defaultization.md)
- progress: Normalizer シーム導入済み( pass-through→最小実装) 。phiを先頭集約、ret値の明示、constの重複排除/先頭寄せを追加( devトグル下) 。
- progress: const 正規化は i64 に加え f64/String を軽量カバー( signature ベースの dedupe) 。
- progress: f64 値の出力正規化(小数表記の冗長ゼロを削除、整数は .0 付与)を実装、カナリアで確認。
- progress: f64 指数・-0.0 に対応。共通ユーティリティへ切り出し( JsonNumberCanonicalBox) 。
- [ ] canary helper の共通化( MIR抽出/トークン検証/一貫したSKIPタグ) — 共通lib: tools/smokes/v2/lib/mir_canary.sh
- progress: loop トグル canary に導入( phase2034/mirbuilder_internal_loop_skip_toggle_canary_vm.sh) 。順次水平展開。
- progress: loop_*_jsonfrag 系3件へ適用( simple/sum_bc/count_param) 。
- progress: Normalizer検証カナリアを追加( 重複なし) :
- 冪等: tools/smokes/v2/profiles/quick/core/phase2034/mirbuilder_jsonfrag_normalizer_idempotent_canary_vm.sh
- cross-block no-dedupe: tools/smokes/v2/profiles/quick/core/phase2034/mirbuilder_jsonfrag_normalizer_const_crossblock_no_dedupe_canary_vm.sh
- rcパリティ: if/loop/binop( 3件)
- f64 exponent/negzero: tools/smokes/v2/profiles/quick/core/phase2034/mirbuilder_jsonfrag_normalizer_const_f64_exponent_negzero_canary_vm.sh
- f64 bigexp: tools/smokes/v2/profiles/quick/core/phase2034/mirbuilder_jsonfrag_normalizer_const_f64_bigexp_canary_vm.sh
- phi many incomings: tools/smokes/v2/profiles/quick/core/phase2034/mirbuilder_jsonfrag_normalizer_phi_many_incomings_order_canary_vm.sh
- phi multistage merge: tools/smokes/v2/profiles/quick/core/phase2034/mirbuilder_jsonfrag_normalizer_phi_multistage_merge_order_canary_vm.sh
- [ ] タグ静音トグル(既定静音)
- progress: `HAKO_MIR_BUILDER_NORMALIZE_TAG=1` の時のみタグ出力(既定は静音)。
- [ ] 正規化ロジックの共通化
- progress: `lang/src/shared/json/utils/json_number_canonical_box.hako` を新設し、f64正規化/トークン読取を共通化。
- [ ] dev一括トグル
- progress: `enable_mirbuilder_dev_env` に Normalizer 注入導線を追加(`SMOKES_DEV_NORMALIZE=1` /コメントで profile 切替例)。
- [ ] quick の timeout 推奨を明記
- progress: `tools/smokes/v2/run.sh` の Examples に `--timeout 120` の案内を追加。
Phase 21.5( Optimization readiness)
- 状態: Normalizer を本線( MirBuilderBox/Min) に既定OFFで配線、quick 代表セット( Normalizer ON) でパリティ確認済み。
- 推奨: quick 全体を Normalizer ON で回す場合は `--timeout 120` を使用( EXE/AOT系の安定化) 。
- 次アクション: rcパリティの面を拡大→default 候補フラグ( 既定OFF) で段階導入→緑維持で default 化判断。
- [ ] 既定化の条件整理( 代表canary緑・タグ観測・既定経路とのdiff=なし・戻し手順) をチェックリスト化( docs/checklists/mirbuilder_jsonfrag_defaultization.md)
- progress: チェックリストと Rollback 手順を docs に明記済み。
追加カナリア( Normalizer)
- 直接検証: tools/smokes/v2/profiles/quick/core/phase2034/mirbuilder_jsonfrag_normalizer_direct_canary_vm.sh
- 複数ブロック/phi順序: tools/smokes/v2/profiles/quick/core/phase2034/mirbuilder_jsonfrag_normalizer_multiblock_phi_order_canary_vm.sh
- JsonFrag+Normalize(tag): tools/smokes/v2/profiles/quick/core/phase2034/mirbuilder_internal_loop_simple_jsonfrag_normalize_canary_vm.sh
- JsonFrag+Normalize(tag・OFF確認): tools/smokes/v2/profiles/quick/core/phase2034/mirbuilder_internal_loop_simple_jsonfrag_nonormalize_no_tag_canary_vm.sh
- 冪等性: tools/smokes/v2/profiles/quick/core/phase2034/mirbuilder_jsonfrag_normalizer_idempotent_canary_vm.sh
- cross-block no-dedupe: tools/smokes/v2/profiles/quick/core/phase2034/mirbuilder_jsonfrag_normalizer_const_crossblock_no_dedupe_canary_vm.sh
- f64 canonicalize: tools/smokes/v2/profiles/quick/core/phase2034/mirbuilder_jsonfrag_normalizer_const_f64_canonicalize_canary_vm.sh
- phi nested merge: tools/smokes/v2/profiles/quick/core/phase2034/mirbuilder_jsonfrag_normalizer_phi_nested_merge_order_canary_vm.sh
- rcパリティ: if/loop/binop( 3件)
2025-11-09 23:40:36 +09:00
# Current Task — Phase 21.10( LLVM line – crate backend print EXE)
Status (22.3 wrap)
- 22.3 締め: 最小Cランタイム( 設計) /Cシンボル整合( nyash.console.*→nyash_console_*)を反映。
- Hako-first MIR emit は wrapper 経由で安定( Stage‑ B 出力の RC 混入を抑止、Hako→失敗時は Rust CLI にフォールバック)。
- 緑条件は quick 代表セット + phase2231 canary( rc=42) で確認済み。
Next (this phase) — 22.x continuation
1) TLV配線( 既定OFF) + parityカナリア
- 既存の `nyash-tlv` ( optional / feature `tlv-shim` )を `src/runtime/plugin_ffi_common.rs` に薄く配線。
- 制御: feature + `HAKO_TLV_SHIM=1` (トレース `HAKO_TLV_SHIM_TRACE{,_DETAIL}` )。
- 受け入れ: ON/OFF で実行/rc 同一( parity) + トレース観測が可能。
2) SSOTメッセージ・相対推定の整形 + 代表カナリアの常時化
- 曖昧時のメッセージ統一(件数+先頭N、legacy委譲の明記) 。
- cwd vs using_paths 優先の明文化・軽量canaryを quick 常時化。
3) ビルダーの JsonFragBox / PatternUtilBox 採用(差分小さい箇所から)
- 手書きスキャンの置換を段階導入。If/Compare VarInt / Return BinOp VarVar 周辺を優先。
4) C‑ core 一点通し( Map.set) + parity維持( 既定OFF)
- feature+ENV で no‑ op 経路を通し、ON/OFF parity をカナリアで検証。
2025-11-06 15:41:52 +09:00
目的(このフェーズで到達するゴール)
2025-11-07 21:04:01 +09:00
- Hako Parser( MVP) で AST JSON v0 を出力し、Analyzer の一次入力に採用( text は fallback 維持)。
- 代表ルール( HC001/002/003/010/011/020) を AST 入力で正確化。
- JSON(LSP) 出力を用意し、エディタ統合の下地を整備。
2025-11-03 23:21:48 +09:00
This document is intentionally concise (≤ 500 lines). Detailed history and per‑ phase plans are kept under docs/private/roadmap/. See links below.
2025-11-07 21:04:01 +09:00
Focus (now) - 🎯 Parser/Analyzer の骨格と I/F を先に
- tools/hako_parser/* に Tokenizer/Parser/AST emit/CLI を実装( MVP)
- Analyzer は AST JSON を優先入力に切替( Text fallback は保持)
- 代表ルールの AST 化と LSP 出力、簡易テスト基盤を確立
2025-11-05 18:57:03 +09:00
2025-11-06 22:34:18 +09:00
Update (today)
2025-11-07 21:04:01 +09:00
- docs/private/roadmap/phases/phase-21.4/PLAN.md を追加(優先順の実行計画)
- tools/hako_parser/* の MVP スケルトン確認( CLI/Emitter/Parser/Tokenizer)
- tools/hako_check/tests/README.md と run_tests.sh を追加(テスト雛形)
2025-11-08 00:46:34 +09:00
- Runner: plugin_guard 導入( vm/vm_fallback から共通化)
- String API: size() を length() のエイリアスとして VM で受理
- Analyzer CLI: --format/--debug/--source-file を順不同で処理
- Analyzer IR: AST 空時の methods をテキスト走査でフォールバック
2025-11-09 15:11:18 +09:00
- HC021/HC031: 実装完了。PHI 調査は一旦収束( AST path は既定OFF、`--force-ast` でオン)。
- CLI: `--rules` /`--skip-rules` を追加し、ルール単体/組合せ検証を高速化。`--no-ast` 既定化。
- Runtime: `NYASH_SCRIPT_ARGS_HEX_JSON` を導入( HEX経由で改行・特殊文字を安全搬送) 。
- File I/O: FileBox provider 設計( SSOT + 薄いラッパ + 選択ポリシー) を文書化( docs/development/runtime/FILEBOX_PROVIDER.md) 。
2025-11-08 23:45:29 +09:00
- ENV: `NYASH_FILEBOX_MODE=auto|core-ro|plugin-only` を追加( ENV_VARS.md) 。Analyzer/CI は core‑ ro 相当で運用。
2025-11-09 15:11:18 +09:00
Quick update — Green Conditions & Toggles( quick)
- Green baseline( quick)
- Builder: Hako registry/internal = ON( 既定) 。必要時のみ `=0` でOFF。
- hv1 inline PRIMARY = ON( 直列も緑) 。必要時のみ `HAKO_PHASE2100_ENABLE_HV1=0` 。
- S3 reps: 任意(`NYASH_LLVM_S3=1` かつ LLVM18 環境時) 。未満は自動SKIP。
- EXE‑ first: 任意(`SMOKES_ENABLE_SELFHOST=1` ) 。重いのでデフォルトOFF。
- TLV smoke: 常時( nyash-tlv のみを -p でビルド/テスト)。本体未配線でも安全。
Toggles quicklist
- Builder: `HAKO_MIR_BUILDER_INTERNAL=0/1` (既定=1) , `HAKO_MIR_BUILDER_REGISTRY=0/1` (既定=1)
- hv1: `HAKO_PHASE2100_ENABLE_HV1=0/1` (既定=1)
- S3: `NYASH_LLVM_S3=0/1` (既定=auto; LLVM18検出でON)
- EXE‑ first: `SMOKES_ENABLE_SELFHOST=1` ( 既定OFF)
- TLV: `--features tlv-shim` + `HAKO_TLV_SHIM=1` ( 既定OFF/配線は無害な identity)
- Using SSOT: `HAKO_USING_SSOT=1` ( MVP は現行解決ロジックを経由しつつタグ出力)
2025-11-09 23:40:36 +09:00
- ENV consolidation( 既定不変)
- NY compiler: 主 `NYASH_USE_NY_COMPILER` 、alias `NYASH_DISABLE_NY_COMPILER` /`HAKO_DISABLE_NY_COMPILER` (受理+警告、一度だけ)
- LLVM opt: 主 `NYASH_LLVM_OPT_LEVEL` 、alias `HAKO_LLVM_OPT_LEVEL` (受理+警告、一度だけ)
- Gate‑ C: 主 `NYASH_GATE_C_CORE` 、alias `HAKO_GATE_C_CORE` (受理+警告、一度だけ)
2025-11-09 15:11:18 +09:00
22.1 progress (today)
- TLV配線( 最小導線・既定OFF)
- 追加: ルート `Cargo.toml` に `nyash-tlv` ( optional) と feature `tlv-shim`
- 追加: `src/runtime/plugin_ffi_common.rs` に `maybe_tlv_roundtrip()` を実装し、`encode_args()` の末尾で呼び出し( ENV `HAKO_TLV_SHIM=1` かつ feature 有効時のみ動作)
- スモーク: `tools/tlv_roundtrip_smoke.sh` を SKIP→常時 PASS に変更(`-p nyash-tlv` 固定)
- Resolver/Using SSOT( 薄い導線・トグル)
- 追加: `HAKO_USING_SSOT=1` 時に SSOT ブリッジを呼び出し( modules のみを ctx として渡す)。未解決時は既存ロジックにフォールバック
- ctx: `{ modules, using_paths, cwd }` ( MVPは modules のみ有効)
- トレース: `NYASH_RESOLVE_TRACE=1` で `[using/ssot]` タグを出力
- スモーク: `tools/smokes/v2/profiles/quick/core/phase2211/using_ssot_parity_canary_vm.sh` を追加( ON/OFF で出力同一を検証)
22.1 next (follow‑ up tasks)
- SSOT ctx 拡張(段階導入・既定不変)
- [ ] Bridge→Hako 箱で `using_paths` /`cwd` を活用した相対推定のMVP( IOはRunner側で制御) 。
- [ ] Runner 側の ctx 渡しを拡張し、パス推定に必要な情報(呼出元ディレクトリ、プロファイル)を追加。
- 受け入れ: パリティcanary( modules命名あり) 維持 + 代表ケースで `using_paths` 提示時に解決成功( 既定OFF/トグルONのみ) 。
- TLV shim 観測タグ( 既定OFF・安全)
- [x] `HAKO_TLV_SHIM_TRACE=1` で shim 経由のコールに `[tlv/shim:<Box>.<method>]` を出力(既定は `MapBox.set` のみ)。
- [x] `HAKO_TLV_SHIM_FILTER=MapBox.set` などで対象コールを限定(カンマ区切り可)。
- 受け入れ: canary で `MapBox.set` の単発コール時にタグが現れる( feature有効+ ENV時) 、既定OFFではログ増加なし。
22.1 exit (criteria)
- SSOT( relative 推定の仕上げ)
- Unique: `phase2211/ssot_relative_unique_canary_vm.sh` が常時 PASS( cwd 優先、短時間で終了)。
- Ambiguous+strict: `phase2211/ssot_relative_ambiguous_strict_canary_vm.sh` が PASS( strict=1 時は legacy 委譲)。
- Recursion guard: `HAKO_USING_SSOT_HAKO=1` を含む実行でも無限再帰は発生しない(子プロセスへ SSOT を強制OFF+ INVOKING=1) 。
- TLV/Extern( 観測統合)
- `HAKO_CALL_TRACE=1` で plugin/extern 双方に `[call:<target>.<method>]` が観測可能。
- `HAKO_CALL_TRACE_FILTER` で method 名/`<target>.<method>` の双方が機能(例: `MapBox.set,env.console.log` )。
- 既定挙動は不変( 新機能はすべてトグルOFFで無影響) 。
22.2 progress (today) — Core Thinning I
- Docs/plan: docs/private/roadmap/phases/phase-22.2/PLAN.md( T0/T1/T2・ABI契約・受け入れ規準)
- C-core crate( 設計) : crates/nyash_c_core( feature c-core=OFF 既定)
- 導線( 既定OFF) : cwrap/c-core タグ& ENV。対象は MapBox.set / ArrayBox.push / ArrayBox.get / ArrayBox.size(len/length)。
- Parity canaries( ON/OFF 完全一致):
- phase2220/c_core_map_set_parity_canary_vm.sh → PASS
- phase2220/c_core_array_push_parity_canary_vm.sh → PASS
- phase2220/c_core_array_len_length_parity_canary_vm.sh → PASS
- Exit( 22.2) : 既定OFFで挙動不変/ ON/OFF parityが緑/ 失敗時フォールバック( Rust経路)
Next — Phase 22.3 (Kernel Minimal C Runtime)
- Docs skeleton added: docs/private/roadmap/phases/phase-22.3/PLAN.md
- No behavior change; future toggle: NYASH_KERNEL_C_MIN (reserved).
- Crate present: `crates/nyash_kernel_min_c` (staticlib) with `nyash_console_log` and a few handle stubs.
- Canary: `tools/smokes/v2/profiles/quick/core/phase2230/kernel_min_c_build_canary.sh` → PASS( ビルドのみ、未リンク)
- Note: LLVM extern lowering maps `nyash.console.*` → `nyash_console_*` for C linkage (dots→underscores).
LLVM line (21.10 prework)
- Added backend selector to tools/ny_mir_builder.sh via `NYASH_LLVM_BACKEND=llvmlite|crate|native` (default llvmlite).
- Added crate path canaries:
- obj (dummy): phase2100/s3_backend_selector_crate_obj_canary_vm.sh → PASS
- exe (dummy): phase2100/s3_backend_selector_crate_exe_canary_vm.sh → PASS
- exe (print): phase2100/s3_backend_selector_crate_exe_print_canary_vm.sh → SKIP( llvmlite未導入環境では自動SKIP/ 名称整合は済)
- Extern lowering updated: `nyash.console.*` is emitted as `nyash_console_*` to match C symbols (`nyash-kernel-min-c` ).
2025-11-10 19:42:42 +09:00
Next — Phase 21.5 (Optimization Prep)
- Docs: Added plan at `docs/private/roadmap/phases/phase-21.5/PLAN.md` ( C≒80% を目標)
- C baselines: `benchmarks/c/bench_box_create_destroy_small.c` , `benchmarks/c/bench_method_call_only_small.c`
- Perf harness:
- `tools/perf/bench_compare_c_vs_hako.sh <key>` → `[bench] name=.. c_ms=.. ny_ms=.. ratio=..` を出力( median) 。
- `tools/perf/run_all_21_5.sh` で2本まとめ実行( warmup=2, repeat=7) 。
- 既定不変: スクリプトは任意実行。ビルド未済み時はヒント表示で SKIP。
Baseline records (new)
- Recorder: `tools/perf/record_baselines.sh <bench|all> [warmup] [repeat]`
- 出力先: `benchmarks/baselines/<bench>.latest.json` と追記 `benchmarks/baselines/<bench>.ndjson`
- 含まれる値: `c_ms` , `py_ms` , `ny_vm_ms` ( AOTは現状0固定) 。ホスト名/時刻/試行回数も保存。
- 使い方: `cargo build --release && bash tools/perf/record_baselines.sh all`
- 今後: これらの C/Python/NY VM 値をターゲットとして最適化を進める(比率の改善を目標管理)。
Note (21.6 / Stage‑ B include)
- VM の include は未対応。Stage‑ B → MirBuilder を VM 直で実行する経路は既定OFF( 検証は opt‑ in) 。
- Program(JSON) → MIR(JSON) は Rust CLI 変換( Gate‑ C) を既定とし、wrapper は失敗時に委譲して安定化する。
Hakorune‑ primary( 検証手順・短縮)
- 目的: verify_mir_rc の primary を hakovm 側に切替えて最小セットを検証する。
- 手順(推奨は単発・軽量):
- env: `HAKO_VERIFY_PRIMARY=hakovm` を付与して対象スクリプトを実行
- 代表: phase2160 の registry opt‑ in canary を個別に実行( Fail‑ Fast が必要な箇所は canary 内で `NYASH_FAIL_FAST=0` を注入済)
- 既定は Gate‑ C 維持。切替は opt‑ in のテスト/開発用途に限定。
phase2160/run_all( self‑ host canaries)
- 今は“任意実行”。quick 常時には含めない(軽さ優先/ホスト依存は SKIP 保護)。
Perf options
- `PERF_SUBTRACT_STARTUP=1` で VM/AOT の起動コスト( ret0) を差し引き( ネットのループ時間近似) 。
- `PERF_AOT=1` で bench_compare に AOT 行を追加( MIR emit/link が失敗する環境では自動スキップ)。
2025-11-08 23:45:29 +09:00
Roadmap links (21.5→21.7)
- 21.5 — Unicode & Provider Polish( 現行計画) : docs/private/roadmap/phases/phase-21.5/PLAN.md
- 21.6 — Hako MIR Builder MVP & Registry( opt‑ in) : docs/private/roadmap/phases/phase-21.6/PLAN.md
- 21.7 — VM mir_call state & Primary Flip( guarded) : docs/private/roadmap/phases/phase-21.7/PLAN.md
- 21.8 — Hako Check: Refactor & QuickFix( MVP) : docs/private/roadmap/phases/phase-21.8/PLAN.md
2025-11-06 22:34:18 +09:00
2025-11-08 02:59:54 +09:00
Footing update (A→B→C, today) — 仕様と入口をまず固定
- A. 仕様/インターフェース( hako_check 診断 I/F と出力規約)
- 診断スキーマ(型付き)を明文化: `{rule, message, line, severity?, quickFix?}` 。
- 互換性: ルールが文字列を `out.push("[HCxxx] ...")` で返す場合も受理( CLI 側で string→diag 変換)。
- 抑制ルール: HC012 > HC011( Box 全体が dead の場合、個別メソッドの unreachable は抑制)。
- 既定の閾値: HC012=warning、HC011=info( CLI 側で override 可能に)。
- Quiet/JSON: `NYASH_JSON_ONLY=1` ( JSON/LSP 生成時は冗長ログ抑止) 、plugin_guard 出力は stderr のみ。
- B. AST 拡張(解析に必要な最小メタ)
- `parser_core.hako` : `boxes[].span_line` (定義開始行)、`methods[].arity` (引数個数)、`is_static` を bool で統一。
- `tokenizer.hako` : 行・桁の位置情報を維持(ブロックコメント除去後も一貫)。
- C. Analyzer 適用(初期化の堅牢化と AST 優先)
- `analysis_consumer.hako` : `_ensure_array(ir, key)` を導入し、`methods/calls/boxes` へ `push` 前に必ず確保。
- AST 取り込みを優先(`boxes/uses/includes` と `*_arr` の二系統に両対応)、欠落時のみ簡易テキスト走査にフォールバック。
- CLI: ルール出力をそのまま透過( typed diag を優先、string は変換) 、HC012>HC011 の抑制を集約段で適用。
Acceptance( Footing A→B→C)
- A: `tools/hako_check/run_tests.sh` が `--format json-lsp` で純 JSON を返し、HC012/HC011 混在入力で抑制が働く。
- B: `parser_core.hako` の AST に `span_line` /`arity` が入り、ダンプで確認可能( 最小ケース2件) 。
- C: `analysis_consumer.hako` が未初期化 IR に対しても `push` で落ちず、AST 経路で HC011/HC012 が緑。
2025-11-08 15:49:25 +09:00
Status (HC rules)
2025-11-08 17:04:21 +09:00
- 10/11 pass, 1 skipped: HC011/012/013/014/015/016/018/021/022/031 = PASS、HC017 = SKIP( UTF‑ 8 byte-level 支援待ち)
2025-11-08 15:49:25 +09:00
- CLI: `--rules` /`--skip-rules` で単体/組合せ検証を高速化、JSON_ONLY で純出力。
2025-11-08 23:45:29 +09:00
Phase 21.7 — VM mir_call state & Primary Flip( green)
- T0( 最小・安定化)
- length state( per‑ receiver可) : size/len/push, Map.set(new-key) 実装済み( Hakorune VM + Rust hv1_inline 両ルート)。
- フラグ: HAKO_VM_MIRCALL_SIZESTATE=1( 既定OFF) , HAKO_VM_MIRCALL_SIZESTATE_PER_RECV=1( 任意) 。
- T1( 検証導線)
- Primary 切替( verify_mir_rc) 配線済み( 既定=hakovm) 。
- Canary 拡充( phase2170/*) : push× N、alias、per‑ recv差分、flow跨ぎ。Map dup-key 非増分・value_state set→get も緑化。
- 実行: bash tools/smokes/v2/profiles/quick/core/phase2170/run_all.sh → 全PASS。
2025-11-09 00:57:10 +09:00
Phase 21.8 — Hako Check: Refactor & QuickFix( MVP)
- T0 QuickFix( --fix-dry-run, text-scope)
- HC002 include→using( 安全置換) / HC003 using 非引用→引用化/ HC016 未使用 alias 行削除/ HC014 空スタブ提案。
- 統一diff( ---/+++/@@) で標準出力。既定OFF( dry-run時のみ) 。
- T1 AST Rename( 同一ファイル)
- --rename-box < Old > < New > / --rename-method < Box > < Old > < New > を追加。
- 定義は AST span 行で安全置換、呼出は `<Box>.<Method>(` を置換。--fix-dry-run で diff 出力。
- T2 Plan 出力
- --fix-plan で refactor_plan.json と sed 雛形( apply_script) を出力( 手動レビュー想定) 。
- 既定挙動は不変。適用は別フェーズ( write-capable provider) で検討。
2025-11-09 15:11:18 +09:00
Phase 21.9 — De‑ Rust( Non‑ Plugin) Checklist
- [x] Docs: Roadmap – docs/development/strategies/de-rust-roadmap.md( 原則/ゲート/リバータブル)
- [x] Docs: Gap Analysis – docs/development/strategies/de-rust-gap-analysis.md( Phase1/2の具体)
- [x] Script: Phase‑ 0 archive helper – tools/de_rust/archive_rust_llvm_backend.sh( RESTORE.md 自動生成)
- [x] Phase‑ 0: Rust LLVM backend を archive/ へ移動(既定ビルド影響なし・リバータブル)
- [ ] hv1_inline opt‑ out トグル( HAKO_VERIFY_DISABLE_INLINE=1) 追加( 任意)
- [ ] TLV C shim( FFI) 雛形+ 往復テスト( 最小)
- [ ] MIR Interpreter の診断化( Primary=Hakovm を確認、envで明示切替)
- [ ] Resolver/Using SSOT ドキュメントを運用ガイド化( Runner/Analyzer 一致)
- [x] LLVM harness: object 出力( tmp/nyash_llvm_run.o) 確認
- [ ] LLVM link: NyRT 静的ライブラリ( crates/nyash_kernel) ビルド → EXE リンクの確認
CI Integration( end of phase)
- [ ] Add optional CI job: selfhost EXE-first smoke
- Steps: install LLVM18; prebuild nyash(llvm)/ny-llvmc/nyash_kernel; run `tools/exe_first_smoke.sh` and `tools/exe_first_runner_smoke.sh` .
- Policy: non-blocking initially( `continue-on-error` or separate optional workflow) ; promote later when stable.
- [ ] Fix legacy CI workflow bug( old workflow failing)
- Audit existing `.github/workflows/*` for broken steps/env; update to use `hakorune` binary and new env toggles.
- Ensure LLVM/S3 gates respect environment (skip when LLVM18 absent).
2025-11-07 21:04:01 +09:00
Remaining (21.4)
2025-11-08 15:49:25 +09:00
1) Hako Parser MVP 実装( tokenizer/parser_core/ast_emit/cli) 【微修整】
2) Analyzer AST 入力の安定化(必要時のみ AST を使用)
2025-11-07 21:04:01 +09:00
3) 代表ルール AST 化( HC001/002/003/010/011/020)
2025-11-08 15:49:25 +09:00
4) `--format json-lsp` 追加ケース( OK/NG/edge)
2025-11-07 21:04:01 +09:00
5) テスト駆動( tests/< rule > /)を 3 ルール分用意
6) 限定 `--fix` ( HC002/003/500)
7) DOT エッジ ON( calls→edges, cluster by box)
2025-11-08 15:49:25 +09:00
8) FileBox provider 実装( リング0/1/選択ポリシー) と最小スモーク追加( core‑ ro/auto/plugin-only) 【COMPLETE】
2025-11-08 23:45:29 +09:00
Remaining (21.4 → 21.5 handoff, concise)
- A. Parser/Analyzer まわり
- [ ] Hako Parser MVP 微修整( tokenizer/parser_core/ast_emit/cli)
- [ ] Analyzer AST 入力安定化(必要時のみ AST、_needs_ast/_needs_ir 調整)
- [ ] 代表ルール AST 化( HC001/002/003/010/011/020)
- [ ] json-lsp 追加ケース( OK/NG/edge)
- [ ] テスト駆動( tests/< rule > / を3ルール分)
- [ ] 限定 --fix( HC002/HC003/HC500)
- B. DOT 改善
- [ ] calls→edges 検証と代表追加ケース( cluster は既存を維持)
- C. Ring1/Plugins polish( 未了のみ)
- [ ] Using/modules SSOT 確認( modules優先→相対推定→not found=警告/verbose詳細)
- [x] Capability introspection( FileBox provider caps(read/write) を Shim から参照→未サポート操作は Fail‑ Fast)
- 実装: `src/runtime/provider_lock.rs:get_filebox_caps()` を追加、`src/boxes/file/mod.rs` で caps.write を参照し明示エラー
- [ ] Provider modes スモークの継続( auto/core‑ ro/plugin‑ only + failure injection)
Phase 21.6 — Hako MIR Builder MVP & Registry( COMPLETE)
- [x] Registry 経路( opt‑ in) を MirBuilderBox に実装( 既定OFF)
- [x] registry 専用 canary 一式を PASS( Return/Int, If/Compare[Int/Int|Var/Int|Var/Var], Return(Binary Int/Int), Return(Logical OR/AND Var/Var))
- [x] PatternUtilBox の find_local_* を“次の Local まで”で安全化
- [x] MirBuilderBox チェーン fallback を厳格化( Binary/IntInt, Return/Int)
- Return(BinOp Var/Int) は registry が先に一致( rc=42)
- Logical AND(Var/Var) は JSON v0 bool=0/1 に合わせて一致( rc=0)
受け入れ( 21.6)
- [x] phase2111 の registry canary 全緑
- [x] 既定OFF・互換維持( トグルON時のみ影響)
Phase 21.7 — VM mir_call state & Primary Flip( kickoff)
- 目的: VM に最小 state( Array/Map length) を導入し、primary 切替( core|hakovm) で Core と同値検証( 既定OFF) 。
- スコープ( T0→T1)
- T0: state map( 受信者ID合成・length管理) 、size/len 実値、push で length++、get/set は安定タグ維持
- T1: HAKO_VERIFY_PRIMARY=core|hakovm 配線と canary( push→size 増分、primary=hakovm でも rc一致)
- トグル/既定
- HAKO_VM_MIRCALL_STUB=1( 既定ON: 非対象は0返し+タグ)
- HAKO_VERIFY_PRIMARY=core( 既定)
2025-11-08 17:04:21 +09:00
- Checklist — Ring1/Plugins polish( このフェーズで完了)
- [x] Env 統一(二重解消): `NYASH_FILEBOX_MODE` /`NYASH_DISABLE_PLUGINS` に一本化し、
2025-11-08 15:49:25 +09:00
旧 `NYASH_USE_PLUGIN_BUILTINS` / `NYASH_PLUGIN_OVERRIDE_TYPES` は非推奨(互換ブリッジは維持)
2025-11-08 17:04:21 +09:00
- [x] 初期化順のSSOT: `register_builtin_filebox` ( feature) → dynamic登録( toml) → provider選択→ FILEBOX_PROVIDER 設定( vm/vm_fallback 共通)
- [x] Provider 登録口の一本化: static/dynamic/builtin を同じ ProviderFactory 登録APIに集約( select は registry のみ)
- [x] FileBox 公開の一本化: `basic/file_box.rs` を再エクスポート/委譲化し、公開は BoxShim( 委譲) に揃える( 重複実装撤去)
2025-11-08 15:49:25 +09:00
- [ ] Using/modules のSSOT確認: modules優先→相対ファイル推定→not found( 警告; verboseで詳細) を維持
2025-11-08 17:04:21 +09:00
- [x] JSON_ONLY 監査: json-lsp時は stdout 純JSON・ログは stderr の規約を plugin_guard/loader を含む全経路で確認
- [x] AST/IR ゲート最終化: `_needs_ast` /`_needs_ir` の方針を docs と実装で一致させる( ASTは最小; 既定 no-ast)
2025-11-08 15:49:25 +09:00
- [ ] Capability introspection: FILEBOX_PROVIDER の `caps(read/write)` を BoxShim から取得・Fail‑ Fastの可否を明示
2025-11-08 17:04:21 +09:00
- [x] スモーク追加: core‑ ro(open/read/close)/auto(フォールバック)/plugin-only(厳格)/analyzer(json-lsp純出力) の代表ケース
- [x] Docs 同期: FILEBOX_PROVIDER.md / ENV_VARS.md / hako_check README を最終状態に更新
- [x] フォールバック保証: プラグインのロード失敗だけでなく「create_box 失敗時」にも ring1/core‑ ro へ自動フォールバック( auto モード) 。plugin‑ only では Fail‑ Fast。
- [x] 失敗時スモーク: ArrayBox の plugin が存在するが creation に失敗するケースを再現し、ring1/core‑ ro で生成できることを確認。
Follow‑ ups( Analyzer polish)
- [x] HC012 JSON 安定化( using alias 依存排除、itoa ローカル化)
- [x] HC017 一時 disable( UTF‑ 8バイト操作対応後に復活)
- [x] using の不要宣言削除( Str aliasの掃除: 使用ファイル以外から撤去)
- [x] ルール実行エラーの可視化( stderr ログを明確に: rule名・ファイル名・行)
- [x] テスト運用のENVまとめを README に明示( Disable Plugins / FactoryPolicy / Disable NyCompiler / JSON_ONLY)
Phase 21.4 — Completion
- FileBox SSOT( provider_lock / provider_registry / CoreRo / BoxShim / feature builtin-filebox) : COMPLETE
- Analyzer 安定化( HC012 修復、HC017 skip、ENV明文化、json-lsp純出力) : COMPLETE
Phase 22 — Proposed Focus
- Unicode Support( HC017 復活): ByteArrayBox / UTF‑ 8 encode/decode helpers / 文字プロパティ
- Plugin 完全化: dynamic plugin( .so) での create_box 安定化、bid/registry の暫定停止解除
- ENV Migration 完了: 旧ENV 警告の全面展開→削除
- Error Logging 強化: error() extern 経由の統一ロギング、ルール/テキスト系への横展開
2025-11-08 15:49:25 +09:00
Completed — FileBox Provider Wiring( C: Feature と静的/動的の選択を1本化)
- 目的: File I/O を SSOT 抽象( FileIo) + 薄いラッパ( FileBoxShim) + provider_registry で一本化し、静的/動的/コアRO の選択を ENV で制御する。
- 完了内容:
- provider_lock: `FILEBOX_PROVIDER` を追加し、グローバルに選択結果を保持
- vm 起動時に `read_filebox_mode_from_env` → `select_file_provider` で provider を決定・登録
- CoreRoFileIo を read‑ only で実装( thread‑ safe)
- FileBox を provider 経由の委譲へ寄せ、basic/file_box.rs は deprecate 化
- Cargo.toml に `builtin-filebox` feature を追加
- Docs/ENV を同期( FILEBOX_PROVIDER.md / ENV_VARS.md)
- 既知の非関連課題(別タスク扱い):
- hako_check/cli.hako の parse error( line表示の不整合) 。FileBox配線とは無関係。HC012 JSON安定化の一環で対応予定。
Next (handoff to Claude Code)
- HC012 JSON 安定化( cli.hako)
- json‑ lsp時は stdout を純JSON、ログは stderr の規約徹底( fmt判定ガードの再確認)
- parse error の発生箇所を修正(構文境界/コメント/Stage‑ 3トグル周り)
- `NYASH_JSON_ONLY=1 ./tools/hako_check.sh --format json-lsp tools/hako_check/tests/HC012_dead_static_box` が純JSONを返すこと
- Analyzer run_tests 全緑の維持(--rules/--skip-rules で個別検証可能)
8) FileBox provider 実装( リング0/1/選択ポリシー) と最小スモーク追加( core‑ ro/auto/plugin-only)
2025-11-06 22:34:18 +09:00
2025-11-08 00:46:34 +09:00
Roadmap (A→B→C) — 必ずこの順序で進める
- A. HC011 をまず緑にする( AST 非依存の安全経路) 【COMPLETE】
- 実装: `--no-ast` 追加、IR に `source` 格納、methods/calls のテキスト走査フォールバック、整形 JSON-LSP
- 受け入れ: `tools/hako_check/run_tests.sh` → [TEST/OK] HC011_dead_methods 緑( 期待JSON一致)
- 影響範囲: tools/hako_check/{cli,analysis_consumer,rules/rule_dead_methods}.hako( 既定は AST、`--no-ast` で切替)
- B. plugin_guard の仕上げと一貫化
- 目的: すべての runner モードで不足プラグイン報告を共通APIに統一( strict/quiet のポリシー遵守)
- 受け入れ条件: vm/vm_fallback 以外に残る ad-hoc 出力が 0、メッセージは stderr のみ( quiet 時)
- C. AST/Tokenizer の精緻化( AST 経路へ戻す)
- 目的: parser_core/tokenizer を強化して `boxes[].methods[]` を安定抽出、HC011 を AST 入力で PASS
- 受け入れ条件: `HAKO_CHECK_NO_AST=0` (既定)で run_tests.sh が緑、methods/calls 数が IR デバッグに出力される
2025-11-07 19:32:44 +09:00
Open Issues (Map semantics)
- Map.get の戻り値セマンティクス未確定
- 現状: kernel 側の get_h の値/存在判定の定義が曖昧。reps は has を優先して固定( rc=1) 。
- 決めたいこと: get_h の戻り(値 or sentinel) / キー不存在時の扱い( 0/-1/None 相当) / rc への反映規約。
- 提案: reps を2段階で導入( has→get) 。get は「存在しない場合は 0( 未使用値) 」を一旦の規約とし、将来 Option 風のタグに拡張可能にする。
- ランタイムシンボルの最小集合の確認
- nyash.map.{birth_h,set_h,size_h,has_h,get_h} が kernel に存在することを常時確認( link 失敗時は Fail‑ Fast) 。
- 決定性とハッシュ
- いまは size 決定性を優先( hash はオプション) 。TargetMachine へ移行後に `NYASH_HASH_STRICT=1` を既定 ON に切替予定。
2025-11-07 21:04:01 +09:00
Near‑ term TODO( 21.4 準備)
- tokenizer: 文字列/数値/識別子/記号/位置情報
- parser_core: using/box/static method/assign/簡易block
- ast_emit: boxes/uses/methods/calls(min) を JSON 化
- cli: ファイル→AST JSON
- Analyzer: AST→IR 変換の経路を優先
- 代表ルールの AST 実装と LSP 出力の雛形
2025-11-06 22:34:18 +09:00
Next (21.2 — TBD)
- 21.1 の安定化を維持しつつ、C‑ API の純API移行( ny‑ llvmc 経由を段階縮小)計画を作成
- reps の決定性( 3× ) を phase2100 aggregator にも追加検討
2025-11-07 19:32:44 +09:00
- Hako‑ first 方針( Rust変更最小化)
- Rust は Kernel/ABI( シンボル/リンク)に集中。解釈/解決は Hako 側の Adapter/Policy に段階移行。
- dev は Adapter 登録や by‑ name fallback を許容( トグル) 、prod は Adapter 必須( Fail‑ Fast) 。
Next Steps (immediate)
2025-11-08 15:49:25 +09:00
1) A( 仕上げ) : HC012 line 精度( span_line) / README 追随 / CLI I/F最終確認
2) B( Parser強化) : tokenizer 文字列エスケープ/位置情報、parser_core 複数行・alias 抽出
3) C( 可視化) : DOT 改善( box cluster / 孤立ノード)と quick スモーク追加
2025-11-08 02:59:54 +09:00
Context Compression Notes
- A( 診断I/F+ 抑制) は実装済み。文字列診断→型付き変換あり。
- B( AST: span_line/is_static=bool) は実装済み。methods.arity は既に出力。
- C は ensure_array と calls arity 推定を反映。残は AST優先の徹底と HC012 line 精度。
2025-11-08 15:49:25 +09:00
- HC021/HC031 は完了。PHI は AST パス限定で再発可能性があるため、当面 `--no-ast` 既定(`--force-ast` で明示オン)。
- ルール検証は `--rules` /`--skip-rules` で二分探索可能。
2025-11-08 02:59:54 +09:00
TODO (short-term, non-HC0)
- AST-first intake: minimize text fallback; ensure analyzer never uses FileBox in tests.
- DOT edges: keep unique edges; add box clusters (optional, post-21.4).
- Quiet JSON: enforce NYASH_JSON_ONLY=1 in wrappers; stderr-only plugin hints.
- HC015 prep: rely on inferred call arity for arity mismatch rule later.
2025-11-08 00:46:34 +09:00
Rules Backlog( 候補・優先提案)
- HC012: Dead Static Box — 定義のみで参照/呼出ゼロの static box を検出
- HC013: Duplicate Method — 同一 box 内の重複メソッド名/arity を検出
- HC014: Missing Entrypoint — Main.main/0 不在を警告(プロファイル可)
- HC015: Arity Mismatch (MVP) — 明確な `Name.method()` 呼び出しの引数個数不一致を検出( 0/1の最小版)
- HC016: Unused Using/Alias — `using ... as Alias` の未使用を検出
- HC017: Non‑ ASCII Quotes — “ ” ‘ ’ 等の fancy quotes を検出し ASCII へ置換提案
- HC018: Top‑ level local in prelude — 先頭 `local` を検出( merge 前提のクリーンアップ漏れ)
- HC021: Analyzer IO Safety — CLI 経路での FileBox 使用を警告(`--source-file` 利用を提案)
- HC022: Stage‑ 3 Gate — while/for を含む .hako を Nyash VM へ流す危険の検出( gate フラグ提示)
- HC031: Brace Heuristics — `{` /`}` の粗い不整合検出(早期警告)
5) `--format json-lsp` の最小実装(既存配線に診断配列を流し込む)
2025-11-05 18:57:03 +09:00
2025-11-06 15:41:52 +09:00
Previous Achievement
- ✅ Phase 20.44 COMPLETE( provider emit/codegen reps 緑)
- ✅ Phase 20.45‑ 46: PRIMARY 切替のための品質・整流( env_bool・MethodAliasPolicy・MirBuilder prefer reps の整備)
- ✅ Phase 20.48 COMPLETE( Deterministic Bootstrap & Parity: run_all 緑 / repeat 3回一致)
- ✅ Phase 20.49 COMPLETE( SSOT & hv1 inline 最小: phase2049/run_all 緑、S3 reps ゲート整備)
2025-11-04 16:33:04 +09:00
2025-11-04 20:51:15 +09:00
Next Steps (ordered)
2025-11-06 15:41:52 +09:00
1) repeat reps: TypeOp を追加(済)
2) PRIMARY reps: Array/Map 三受信者の独立性(追加済)
2025-11-06 16:59:34 +09:00
3) S3 reps を1本追加( 3ブロック系、LLVM18 検出で自動実行)
2025-11-06 15:41:52 +09:00
4) README( 20.48)へ Quick Verify の項目拡張( typeop_check/cast と multi‑ recv を追記済)
Close Ready( 20.48)
- 条件:
- s1s2s3_repeat_*( const/compare/logical/typeop) が3回一致
- PRIMARY reps( If/Logical/Loop/Array/Map/TypeOp) が PASS( no‑ fallback)
2025-11-06 16:59:34 +09:00
- run_all( phase2048) が緑( S3 は LLVM18 環境で自動、NYASH_LLVM_S3=0 で明示無効)
2025-11-04 20:51:15 +09:00
2025-11-04 16:33:04 +09:00
Hotfix Plan — Using/Prelude Unification (Self‑ Host)
- Problem: .hako を NyashParser に通す経路でパース落ち( Invalid expression) 。
- Decision: プレリュードは“テキスト統合( merge_prelude_text) ”に一本化。AST マージは撤退。
- Resolver 入口は共通( alias/modules/packages/builtin) 。
- 以降はメインの言語に応じて実行器へ渡す( Hako→Hakorune VM / MIR→Core) 。
- NyashParser は Nyash コードのみ。Hako は Nyash VM 経路に入れない( Fail‑ Fast) 。
Action Items (20.38)
- P1 C‑ ABI ブリッジ( 既定OFF)
- Hako provider→Rust extern_provider へ最小接続( emit/codegen) 。
- ハーネスのタグ用シム( test_runner) を撤去できる状態にする。
- P2 v1 Dispatcher IR 完了+φテーブル堅牢化
- V1SchemaBox.get_function_ir を構造IRで返却( blocks/phi_table) 。
- ループは IR 反復に完全切替、φ は entry 適用(命令ループから除去)。
- 複数φ/複数incoming/空白改行混在を canary で固定。
- P3 Verify 既定整流(完了)
- v1→Hakorune を既定ON、Core は診断 fallback。末尾数値抽出で rc を一意化。
- include ポリシー quick=ERROR を維持(ドキュメントと一致)。
- P4 Resolver/alias 仕上げ
- lang/src/vm/** の alias を監査し、直参照を払拭。normalize/trace ログは最小に整流。
- P5 Docs 反映
- phase‑ 20.38 のトグル/受け入れ条件/撤去予定のシムを反映。φ entry SSOT は IR 完了後に更新。
- extern タグ用シムの現状と撤去条件( hv1 inline 安定後に除去)を明記。
2025-11-06 22:34:18 +09:00
Acceptance( phase 21.2)
- HAKO_CAPI_PURE=1 で reps( ternary=44 / map=1) が PASS、各3回一致( obj/rc) 。
- 21.1 reps( C‑ API fallback) と既存 llvmlite 経路は緑維持。
New (21.1 wiring)
- Rust provider 切替の実装( src/host_providers/llvm_codegen.rs)
- `NYASH_LLVM_USE_CAPI=1` + `HAKO_V1_EXTERN_PROVIDER_C_ABI=1` で C‑ API 経路を有効化。
- `libhako_llvmc_ffi.so` を dlopen し、`hako_llvmc_compile_json` を呼び出して `.o` を生成。
- plugins feature 未有効時は明示エラー( Fail‑ Fast) 。
2025-11-06 15:41:52 +09:00
---
# Next Task — Phase 20.49( Resolver SSOT & Compiler Bring‑ up)
目的(このフェーズで到達するゴール)
- using/プレリュード統合の SSOT を dev/prod で確定( include は prod で非対応)
- dev では toml なしの最短導線(相対パス using / preinclude) で“すぐ動く”を保証
- コンパイラ自走に必要な hv1 inline の最小カバレッジを reps で固定
Focus( 20.49)
- Resolver/Runner: using 解決と prelude 統合の一本化( dev/prod トグルを明文化)
- Reps: using/alias/nested prelude の代表追加( dev/prod 両系)
- hv1 inline: 命令/extern の最小セットを reps から埋める(不足は段階実装)
- S3( 任意) : ternary / map set→size 等のE2E代表を `NYASH_LLVM_S3=1` で実行
Acceptance( 20.49)
- dev: toml無し一発経路でコンパイラ一式の v1 生成が成功( S1/S2 繰り返し一致)
- prod: alias/modules 経路のみで run_all が緑( include=ERROR)
- hv1 inline: 代表で本体必要最小命令/extern が緑
2025-11-04 16:33:04 +09:00
2025-11-05 18:57:03 +09:00
Changes (recent)
2025-11-06 15:41:52 +09:00
- Core executor: v1 優先実行( schema_version 検出時)。
- hv1 mir_call handler: per‑ recv size state 実装+ trace。
- test_runner: HAKO_VERIFY_V1_FORCE_HAKOVM=1 を追加( hv1 ラッパーで v1 実行)。
- hv1 inline reps: 代表を整備( per‑ recv second は暫定 rc=1) 。
Changes (this pass)
- 20.44 を ✅ COMPLETE にマーク
- 20.47/20.48 のフェーズ文書を追加(自己ホストの工程と受け入れを明文化)
- 拡張子統一(.hako/.nyash 等価): 仕様の明文化 + 実装反映
- Fail‑ Fast( Hako in Nyash VM) 既定OFF( HAKO_FAIL_FAST_ON_HAKO_IN_NYASH_VM=1 のみON)
- using はテキスト・プレリュード統合を既定に( AST統合は任意)
- using 解決は .hako 優先→.nyash 次点。using.paths に lang/src を追加
- ドキュメント更新: docs/guides/source-extensions.md を等価性ポリシーに刷新
- runner: env_bool 横展開( common_util/strip.rs, modes/pyvm.rs, modes/common.rs, hv1_inline.rs)
- vm: MirCallV1HandlerBox trace の受信者IDログ修正
- quick/core phase2036: v1_minivm_size_stub_off_canary_vm を修正
- using をパス指定から alias( `using selfhost.vm.entry as MiniVmEntryBox` )へ切替
- `NYASH_PREINCLUDE=1` を注入してプレリュードをテキスト統合( prod プロファイルの path using 限制を回避)
- 結果: rc=0 で PASS( スタブ時の size=0 が Mini‑ VM の rc に反映)
- quick/core phase2047: Using alias 代表を追加
- tools/smokes/v2/profiles/quick/core/phase2047/using_alias_selfhost_vm_entry_canary_vm.sh( PASS)
- alias 解決の実行確認( cross‑ box static call → rc=0)
- tools/smokes/v2/profiles/quick/core/phase2047/using_alias_string_helpers_canary_vm.sh( PASS)
- shared/helpers の alias 解決を実行確認(静的呼び出し)
- Self‑ Hosting S1/S2( builder 直行)
- gen: tools/selfhost/gen_v1_from_builder.sh( emit_return_int2(42) → v1 JSON 出力)
- canary: tools/smokes/v2/profiles/quick/core/phase2047/selfhost_s1_s2_from_builder_canary_vm.sh( PASS)
- provider 雛形: tools/selfhost/gen_v1_from_provider.sh( C‑ ABI 連携は段階導入)
- Provider v1 強制(最終化)
- src/host_providers/mir_builder.rs: emit前後で v1 を強制( NYASH_JSON_SCHEMA_V1=1 一時設定 + 読み戻し時の v1 ラップ)
- hv1 inline 実装の強化
- Array と Map の per‑ receiver サイズ状態を分離(独立マップ: arr/map)
- MapBox: set→size を rc で検証可能( first=1/second=0 reps と整合)
- Docs 更新
- phase‑ 20.48 の README に “Quick Verify” セクションを追加( run_all と S3 トグルの手順)
- canary 追加: tools/smokes/v2/profiles/quick/core/phase2047/provider_v1_shape_canary_vm.sh( PASS)
- SSOT の徹底( strip.rs 連携)
- src/runner/modes/common_util/resolve/strip.rs: is_path 判定と dev-file 候補判定を SSOT に寄せ( path_util)
- S1/S2 拡張 reps( builder)
- gen: tools/selfhost/gen_v1_from_builder_compare_{cfg,ret}.sh
- canary: tools/smokes/v2/profiles/quick/core/phase2047/selfhost_s1_s2_from_builder_compare_{cfg,ret}_canary_vm.sh( PASS/環境で整合)
- S3 reps( llvmlite, NyRTリンク, 実行)
- phase2047/s3_link_run_llvmlite_compare_{cfg,ret}_canary_vm.sh( rc=1)
- phase2047/s3_link_run_llvmlite_const42_canary_vm.sh( rc=42)
- phase2047/s3_link_run_llvmlite_branch_ret_44_canary_vm.sh( rc=44)
- 生成器: tools/selfhost/gen_v1_from_builder_branch_ret_44.sh
- PRIMARY no‑ fallback reps( hv1 inline)
- phase2047/primary_no_fallback_v1_const_rc_canary_vm.sh( rc=42)
- phase2047/primary_no_fallback_v1_compare_branch_rc_canary_vm.sh( rc=1)
- phase2047/primary_no_fallback_v1_jump_rc_canary_vm.sh( rc=7)
- S1/S2 拡張 reps( builder)
- gen: tools/selfhost/gen_v1_from_builder_compare_{cfg,ret}.sh
- canary: tools/smokes/v2/profiles/quick/core/phase2047/selfhost_s1_s2_from_builder_compare_{cfg,ret}_canary_vm.sh( PASS/環境で整合)
- S3 代表( llvmlite, NyRTリンク, 実行)
- phase2047/s3_link_run_llvmlite_compare_cfg_canary_vm.sh( NYASH_LLVM_S3=1 で有効、SKIPガードあり)
- Self‑ Hosting S1/S2 実行例(雛形)を追加
- tools/selfhost/examples/gen_v1_const42.sh( 最小 v1 を出力)
- `tools/selfhost/bootstrap_s1_s2.sh --cmd1 'bash tools/selfhost/examples/gen_v1_const42.sh' --cmd2 'bash tools/selfhost/examples/gen_v1_const42.sh'` → PASS( 正規化ハッシュ一致)
2025-11-04 20:46:43 +09:00
// Loop compares normalization (Step‑ 1)
- Loop lowers( simple/count_param/sum_bc) : Compare 受理を拡張し Lt 形へ正規化。
- i < L / i <= L は既存通り ( <= は L + 1 )。
- L > i / L >= i は左右スワップで受理(>= は L+1) 。
- i != L は init=0, step=1 の単純カウントに限り i < L と同値として受理 。
- Canaries: phase2039 に追加( swapped > / >=, !=) し、Core verify で PASS を確認。
// Step‑ 2/3 generalization (count_param)
- step 一般化: Int 2,3,… と Local Var 由来の step を受理。'-' は負の step に正規化( Add + 負値)。
- 降順対応: i > / i >= limit を cmp=Gt/Ge で build2 へ伝達。
- init/limit 起源の拡大: Local Var( Int) 由来を逆引きで受理。
- Canaries: step=2 / step(Local) / 降順('-') / limit(Local) / init(Local) を追加し PASS。
// Step‑ 4( 部分) break/continue 検出の堅牢化( sum_bc)
- 'i==X' に加え 'X==i' も受理。専用カナリー( swapped equals) PASS。
- If(var != X) else [Break] の最小サブセットを受理( loop_scan_box へ委譲)。専用カナリー PASS。
- If(var != Y) else [Continue] は検出実装あり( inline) が未検証→次段で helper へ移設しつつ canary 追加予定。
2025-11-03 23:21:48 +09:00
What’ s green (20.34)
- Loop/PHI unify (phi_core) in JSON v0 bridge — unified path used (toggle exposed).
- Program(JSON v0) PHI‑ trace canaries — PASS.
- Core exec canaries (builder → emit → Core) — now routed and PASS:
- mirbuilder_internal_core_exec_canary_vm (rc=10)
- mirbuilder_internal_loop_core_exec_canary_vm (rc=3)
- mirbuilder_internal_loop_count_param_core_exec_canary_vm (rc=6)
- mirbuilder_internal_loop_sum_bc_core_exec_canary_vm (rc=8)
Recent changes (summary)
- Added MIR JSON v0 loader (minimal): src/runner/mir_json_v0.rs
- Supports const/compare/branch/jump/phi/ret/copy
- Promoted --mir-json-file to “execute + exit(rc)”
- v1 → try_parse_v1_to_module; v0 → minimal loader; executes via Core interpreter
- rc mapping unified in execute_mir_module_quiet_exit
- verify_mir_rc improvements (tools/smokes/v2/lib/test_runner.sh)
- Core primary: MIR(JSON) uses --mir-json-file, Program(JSON v0) uses --json-file
- Mini‑ VM( hakovm) rc==1 ヒューリスティックを削除し、経路評価を素直化( v1はCore、v0はhakovmに整流)
- Hako JSON reader minor fix
- lang/src/vm/core/json_v0_reader.hako: r# raw を通常文字列に統一( Hako生文字列の互換性向上)
- MIR JSON v1 bridge extended
- parse_const_value now handles f64/float, bool, string, and handle(StringBox) → ConstValue::String
- Direct extern names supported in VM interpreter: env.mirbuilder.emit, env.codegen.emit_object
- New v1 canaries (Core route)
- tools/smokes/v2/profiles/quick/core/phase2035/v1_method_string_indexof_canary_vm.sh
- tools/smokes/v2/profiles/quick/core/phase2035/v1_extern_mirbuilder_emit_canary_vm.sh
- tools/smokes/v2/profiles/quick/core/phase2035/v1_method_string_substring_1arg_canary_vm.sh
- tools/smokes/v2/profiles/quick/core/phase2035/v1_method_string_substring_2args_canary_vm.sh
- tools/smokes/v2/profiles/quick/core/phase2035/v1_array_push_size_canary_vm.sh
- (map) tools/smokes/v2/profiles/quick/core/phase2035/v1_map_set_get_size_canary_vm.sh
- Note: returns size (1) for rc stability; get-path validated structurally
2025-11-04 16:33:04 +09:00
- 20.38 extern bring-up (Hakorune primary)
- Hakorune provider tags: prints `[extern/c-abi:mirbuilder.emit]` / `[extern/c-abi:codegen.emit_object]` when `HAKO_V1_EXTERN_PROVIDER_C_ABI=1` ( 既定OFF)
- Core extern provider: when `HAKO_V1_EXTERN_PROVIDER=1` , `env.mirbuilder.emit` / `env.codegen.emit_object` return empty string (stub) to keep rc=0( verify fallbackの安定化)
- Dispatcher(FLOW): minor cleanup to avoid stray scanning code; ret-path returns value and does not emit trailing prints
- Canaries: phase2038 emit/codegen → PASS( タグ+ rc=0 を固定) 。phi 追加ケース( then→jump combo3) も PASS。
2025-11-03 23:21:48 +09:00
Open (pending)
2025-11-04 20:46:43 +09:00
- SSOT helpers( binop_lower / loop_common) の導入と呼び出し置換( Builder/Bridge) 。
- Continue ‘ !=’ else の builder 経路の MIR 生成整流( rc=8 固定化)。
2025-11-04 16:33:04 +09:00
- P1〜P4 の実装・緑化(上記 Action Items) 。
2025-11-03 23:21:48 +09:00
Active toggles (debug/verify)
2025-11-04 16:33:04 +09:00
- HAKO_VERIFY_PRIMARY=hakovm|core( 既定 hakovm、Coreは診断)
- HAKO_V1_DISPATCHER_FLOW=1( v1 FLOW 実行)
- HAKO_V1_EXTERN_PROVIDER=1( Hako extern provider 有効)
- HAKO_V1_EXTERN_PROVIDER_C_ABI=1( タグ/ブリッジ実験。既定OFF)
- HAKO_V1_PHI_STRICT=1 / HAKO_V1_PHI_TOLERATE_VOID=1( φポリシー)
- NYASH_RESOLVE_TRACE=1 / NYASH_RESOLVE_NORMALIZE=1( resolver dev)
2025-11-03 23:21:48 +09:00
How to run (quick)
- Build: `cargo build --release`
- Program v0 PHI‑ trace (debug):
- `SMOKES_ENABLE_DEBUG=1 bash tools/smokes/v2/profiles/quick/core/phase2034/program_v0_if_phi_trace_vm.sh`
- `SMOKES_ENABLE_DEBUG=1 bash tools/smokes/v2/profiles/quick/core/phase2034/program_v0_loop_phi_trace_vm.sh`
- Core exec canaries( 20.34 緑対象):
- `bash tools/smokes/v2/profiles/quick/core/phase2034/mirbuilder_internal_core_exec_canary_vm.sh`
- `bash tools/smokes/v2/profiles/quick/core/phase2034/mirbuilder_internal_loop_core_exec_canary_vm.sh`
- `bash tools/smokes/v2/profiles/quick/core/phase2034/mirbuilder_internal_loop_count_param_core_exec_canary_vm.sh`
- `bash tools/smokes/v2/profiles/quick/core/phase2034/mirbuilder_internal_loop_sum_bc_core_exec_canary_vm.sh`
Mini‑ VM policy( 20.34)
- 実装は維持( alias/ret/phi 最小系を今後整える)。ただし quick の canary は Core へ寄せて緑化。
- 20.36 で verify primary を hakovm に段階的に切替、Mini‑ VM green を進める。
Next (20.35 — scoped; behavior unchanged)
1) MIR JSON v1 loader expansion( Method/Extern/BoxCall — 最小)
- callee.type=Method → BoxCall 復元( box_name/method/receiver/args)
- callee.type=Extern → ExternCall 復元( env.get/env.codegen.emit_object/env.mirbuilder.emit/console.log など)
- effects 未指定は PURE 既定、WRITE 系は最小でフラグ化(実害ゼロ)
- v1 canary 追加( string indexOf/substring、array push/size、map set/get/size、extern env.get)
2) Using/alias の推移解決の堅牢化(深さ/循環/キャッシュ)
- 実装済み( DFS 深さ上限=10、循環検知、キャッシュ) 。strict では曖昧解決をエラー扱い。
3) ドキュメント: 今回の経路( Core/verify) を roadmap に反映( DONE)
Structure cleanups (20.35 A→B→C)
- A) v1 mir_call 両対応( flat/nested) : 実装済(ローダで互換吸収)。
- B) Extern provider 単一点化: 実装済( handlers/extern_provider.rs) 。calls.rs/externals.rs から委譲。
- C) Const パース共通化: 実装済( src/runner/mir_json/common.rs) 。まず v1 から採用( v0 は次段)。
Next (20.36 — verify primary → hakovm, preinclude removal, C‑ ABI scaffold)
- Verify primary 切替(段階): hakovm → Core fallback
- preinclude 非推奨化( quick から撤去)
- Mini‑ VM の最小状態( len/size/push の簡易 state) を flag ガードで導入( デフォルトOFF) — 導入済
- 受信者別サイズ管理フラグ `HAKO_VM_MIRCALL_SIZESTATE_PER_RECV=1` を導入( canary 追加済)
- HAKO_VM_MIRCALL_SIZESTATE=1 は緑化済( push 2回→size=2) 。次は受信者別管理を flag で導入: HAKO_VM_MIRCALL_SIZESTATE_PER_RECV=1
- C‑ ABI 設計( docs + ヘッダ雛形)
Known open items( tracked to 20.36)
- Mini‑ VM: using/alias の推移解決( selfhost.vm.helpers.* 連鎖)
- Mini‑ VM: ret/phi の最小ケースで rc が確実に数値化されるよう整備(継続確認)
2025-11-04 16:33:04 +09:00
Next (20.37 — v1 Dispatcher & Phi)
1) V1SchemaBox: get_function_ir(JSON→IR) を拡張( blocks/insts/phi_table を一括)
2) NyVmDispatcherV1Box: IR反復へ切替( スキャナ依存の最終撤去) 、今は二重化( IR優先/scan後退互換)
3) Resolver/inline: AST prelude マージで推移usingを一次収束( Claude codeで進行) 、ランナーは既存fallback維持
Next (Hotfix — Using/Prelude Unification)
1) vm.rs: using_ast 経路を `merge_prelude_text` に一本化( ASTマージ撤去)
2) vm.rs: Hako 構文検出で Hakorune VM へ切替( NyashParser をバイパス)
3) strip.rs: `.hako` の AST パース抑止と診断ガイド
4) verify: extern canary を PASS 化(末尾 rc 抽出の安定化)
Docs:
- docs/development/architecture/phi-entry-in-hako.md に φ entry 設計のSSOTを記載( 不変条件/flags/テスト)
Next (20.38 — extern provider & C‑ ABI)
1) HakoruneExternProviderBox を拡張( warn/error/emit の最小タグ/空文字挙動)— 完了
2) HAKO_V1_EXTERN_PROVIDER=1 の canary 追加(構造緑固定)— 完了
3) C‑ ABI 導線のPoC接続( emit/codegen、既定OFF) — 完了( タグ+ rc=0)
4) hv1 inline 安定化(残): -c 経路の using resolver に modules.workspace を強制ロードするか、dispatcher の using を dev 限定で path 化。
5) include 撤去の計画( dev → 本線):
- まず stub カナリーの include は撤去済み( rc=0 のみ確認)。
- hv1 inline カナリーの prelude include は暫定( dev専用) 。-c/alias 安定後に alias へ移行して include を撤去する。
- ランナー側では merge_prelude_text を既定経路とし、include は quick=ERROR のポリシーを維持。
2025-11-03 23:21:48 +09:00
Roadmap links( per‑ phase docs)
- Index: docs/private/roadmap/README.md
- Phase 20.34: docs/private/roadmap/phases/phase-20.34/README.md
- Phase 20.35: docs/private/roadmap/phases/phase-20.35/README.md
- Phase 20.36: docs/private/roadmap/phases/phase-20.36/README.md
Appendix — Toggle quick reference
- NYASH_MIR_UNIFY_LOOPFORM=1|0 … Loop/PHI 統一( 既定ON)
- HAKO_VERIFY_PRIMARY=hakovm|core … verify 実行経路(今は core 優先で緑化)
- NYASH_VM_TRACE_PHI=1 … VM PHI 適用トレース
- HAKO_PHI_VERIFY=1 | NYASH_PHI_VERIFY=1 … ビルダー側の PHI inputs 検証
- HAKO_VM_PHI_STRICT=0( 互換:NYASH_VM_PHI_STRICT=0) … 実行時 PHI 厳格 OFF( 開発時のみ)
2025-11-04 16:33:04 +09:00
Updates (2025-11-04)
- hv1 inline: alias-only route stabilized (no include/preinclude). vm.rs wrapper now uses `using selfhost.vm.hv1.dispatch` and relaxes fail-fast for child.
- Verify harness: include+preinclude fallback for v1 removed in `verify_mir_rc` ; alias-only hv1 is the standard path.
- Concat-safety (hv1 scope): replaced `"" + <int>` coercions with `StringHelpers.int_to_str(...)` in `lang/src/vm/hakorune-vm/dispatcher_v1.hako` and `lang/src/vm/boxes/mir_call_v1_handler.hako` .
2025-11-05 18:57:03 +09:00
# Handoff — 20.43 Kickoff (15h progress)
Focus (next)
- Start Phase 20.43: MIR generation coverage for call/method/newbox/load/store/typeop, with minimal Array/Map bridge (structure-first, no behavior change).
What’ s landed this session (DONE)
- NewBox → Constructor (minimal lower)
- Added: `lang/src/mir/builder/internal/lower_newbox_constructor_box.hako`
- Wired in: `lang/src/mir/builder/MirBuilderBox.hako` (try_lower early) and alias in `nyash.toml` .
- Direct canary (PASS): `tools/smokes/v2/profiles/quick/core/phase2043/lower_newbox_constructor_direct_core_exec_canary_vm.sh` .
- Method(size) → structural MIR (Array)
- Added: `lang/src/mir/builder/internal/lower_method_array_size_box.hako` + alias in `nyash.toml` .
- Direct structural canary (PASS): `tools/smokes/v2/profiles/quick/core/phase2043/lower_method_array_size_direct_struct_canary_vm.sh` .
- Method(push) → structural MIR (Array)
- Added: `lang/src/mir/builder/internal/lower_method_array_push_box.hako` + alias in `nyash.toml` .
- Direct structural canary (PASS): `tools/smokes/v2/profiles/quick/core/phase2043/lower_method_array_push_direct_struct_canary_vm.sh` .
- New → Constructor (direct) and Method(size/push) canaries all green under phase‑ 2043.
- Array get/set
- Added: `lang/src/mir/builder/internal/lower_method_array_get_set_box.hako` + alias.
- Direct structural canary (PASS): `tools/smokes/v2/profiles/quick/core/phase2043/lower_method_array_get_set_direct_struct_canary_vm.sh` .
- Map size/get/set
- Added: `lang/src/mir/builder/internal/lower_method_map_size_box.hako` , `lower_method_map_get_set_box.hako` + aliases.
- Direct structural canaries (PASS): `lower_method_map_size_direct_struct_canary_vm.sh` , `lower_method_map_get_set_direct_struct_canary_vm.sh` .
- Load/Store( 最小)
- Added: `lang/src/mir/builder/internal/lower_load_store_local_box.hako` + alias。
- Direct structural canary (PASS): `lower_load_store_local_direct_struct_canary_vm.sh` 。
- TypeOp Check( 最小)
- Added: `lang/src/mir/builder/internal/lower_typeop_check_box.hako` + alias。
- Direct structural canary (PASS): `lower_typeop_check_direct_struct_canary_vm.sh` 。
- TypeOp Cast( 最小)
- Added: `lang/src/mir/builder/internal/lower_typeop_cast_box.hako` + alias。
- Direct structural canary (PASS): `lower_typeop_cast_direct_struct_canary_vm.sh` 。
- Builder internal route stabilized for simple New → Core via runner_min
- Added: `lang/src/mir/builder/internal/runner_min_box.hako` + alias。
- `verify_program_via_builder_to_core` uses runner_min first, with markers + optional full MirBuilder fallback.
- Harness improvements
- Builder output extraction with markers `[MIR_OUT_BEGIN]/[MIR_OUT_END]` in `tools/smokes/v2/lib/test_runner.sh` .
- Debug tails for stdout/stderr when `HAKO_MIR_BUILDER_DEBUG=1` .
- Enabled using for inline runs: `NYASH_ENABLE_USING=1` / `HAKO_ENABLE_USING=1` .
Open items / blockers
- Builder (internal/delegate) inline route still unstable for JSON capture; `phase2043/program_new_array_delegate_struct_canary_vm.sh` fails (no JSON in stdout).
- Plan: switch builder to write MIR to a temp file (FileBox) and let harness read it; or adopt provider route in 20.44 (`env.mirbuilder.emit` ).
- Remaining lowers for 20.43 not yet added: method(push/get/set/len), load/store (local), typeop(is/as) minimal; builder wiring after direct lowers pass.
Next-up checklist (20.43)
1) MirBuilder wiring: 上記 direct lowers を `MirBuilderBox` から段階採用( Return系フォールバック前) → 一部( Array/Map/LoadStore/TypeOp) 採用済み。
2) New(Map) は Constructor lower で既に生成可能( direct PASS) 。Builder経路へ採用。
3) TypeOp: `Cast` 採用済( 構造lower→canary→配線) 。
4) Builder route 安定化( internal) : lower ラッパー側で MIR を `/tmp` に保存→ハーネスが読む( pipe 揺れを回避)。
5) Delegate route( 20.44 に接続):`env.mirbuilder.emit` を provider 経由に切替(構造は共通)。
6) Delegate route (optional): use provider `env.mirbuilder.emit` (20.44 scope) to make canaries robust.
How to run
- All new phase 20.43 canaries:
- `bash tools/smokes/v2/run.sh --profile quick --filter phase2043`
- Single tests:
- NewBox direct: `tools/smokes/v2/profiles/quick/core/phase2043/lower_newbox_constructor_direct_core_exec_canary_vm.sh`
- Method(size) direct: `tools/smokes/v2/profiles/quick/core/phase2043/lower_method_array_size_direct_struct_canary_vm.sh`
Toggles (dev)
- Inline Hako: `HAKO_FAIL_FAST_ON_HAKO_IN_NYASH_VM=0 NYASH_ENABLE_USING=1 HAKO_ENABLE_USING=1`
- Builder internal: `HAKO_MIR_BUILDER_INTERNAL=1` (and `HAKO_MIR_BUILDER_DEBUG=1` for tails)
Pointers
- New lowers: `lang/src/mir/builder/internal/lower_newbox_constructor_box.hako` , `lang/src/mir/builder/internal/lower_method_array_size_box.hako`
- Wiring: `lang/src/mir/builder/MirBuilderBox.hako` (try_lower order) and `nyash.toml` aliases
- Harness: `tools/smokes/v2/lib/test_runner.sh` (marker extraction / debug tails)
---
2025-11-15 22:32:13 +09:00
Update (2025-11-15 — Stage1 CLI emit調査メモ)
- Stage‐ B emit を拡張( FuncScannerBox/Stage‐ B 本体)して `static box` メソッドを defs に追加。暗黙 `me` もパラメータへ補完。
- Rust 側 JSON v0 ブリッジに `ExprV0::Null` variant を追加し、Stage‐ B が吐く Null リテラルを受理。
- `launcher.hako` の `while` を `loop` 構文へ置換( Stage‐ B パーサ互換)。
- Stage1 CLI の Program(JSON) は attr付き defs まで含むようになったが、selfhost builder ( MirBuilderBox on VM) がまだ HakoCli 全体を lowering できず stub MIR を返している。provider 経由では 62KB 超の MIR(JSON) が得られるので Phase 25.1a ではこちらを利用。