fix(joinir): Phase 241-EX - Remove hardcoded 'sum' check from Pattern3

Remove legacy hardcoded 'sum' carrier validation that was blocking
array_filter patterns with different accumulator names (e.g., 'out').

Before: Pattern3 required carrier named 'sum' to exist
After: Pattern3 uses carrier_info generically (any carrier name works)

Test results:
- phase49_joinir_array_filter_smoke: PASS 
- phase49_joinir_array_filter_fallback: PASS 
- phase49_joinir_array_filter_ab_comparison: PASS 
- Full suite: 909/909 PASS, 0 FAIL

Also: Archive old roadmap documentation (67k lines moved to docs/archive/)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
nyash-codex
2025-12-11 00:48:42 +09:00
parent a7dbc15878
commit 811dfebf98
387 changed files with 106 additions and 5551 deletions

View File

@ -0,0 +1,61 @@
# Phase 10: JIT実装とセルフホスティング
## 🎯 Phase 10の全体像
Phase 10は、Nyashの実行性能を大幅に向上させるJIT実装と、言語の成熟度を示すセルフホスティングを実現します。
## 📊 実装優先順位
### 1⃣ **メイン実装: Cranelift JIT**
→ [phase_10_cranelift_jit_backend.md](phase_10_cranelift_jit_backend.md)
- VMとのハイブリッド実行ホットパス検出→JIT化
- 実装期間: 2-3ヶ月
- 目標: ホットパスで2倍以上の高速化
### 🌟 **革新的機能: GC切り替え可能ランタイム**
→ [phase_10_4_gc_switchable_runtime.md](phase_10_4_gc_switchable_runtime.md)
- 世界初実行時にGCモード切り替え可能
- 開発時はGCオンで快適、本番はGCオフで高速
- 実装期間: 2-3ヶ月Cranelift JIT後
- 技術的にCodex GPT-5が実現可能性を確認済み
### 2⃣ **並行プロジェクト: セルフホスティング**
→ [phase_10_5_core_std_nyash_impl.md](phase_10_5_core_std_nyash_impl.md)
- String/Array/MapをNyash自身で実装
- Rust依存の段階的削減
- 実装期間: 1-2ヶ月
### 3⃣ **実戦テスト: アプリケーション移植**
→ [phase_10_app_migration.md](phase_10_app_migration.md)
- Tinyproxy: ゼロコピー判定機能の検証
- Chip-8エミュレータ: fini伝播とweak参照の実戦テスト
- kiloエディタ: メモリ効率の「うっかり全体コピー」検出
### 🚫 **延期プロジェクト**
→ [Phase 11: LLVM AOT Backend](../phase-11/) - 将来の研究開発として分離
## 🛤️ 実装ロードマップ
```
Phase 9.79b (現在)
Phase 10.0: Cranelift JIT基盤構築
├→ Phase 10.1-10.3: JIT実装・最適化
├→ Phase 10.4: GC切り替え可能ランタイム ← NEW!
└→ Phase 10.5: セルフホスティング(並行)
Phase 10.9: アプリケーション移植で実戦検証
Phase 11: LLVM AOT研究将来
```
## 📈 期待される成果
1. **実行性能**: インタープリタ比100倍、VM比2-3倍の高速化
2. **言語成熟度**: 基本コンテナのセルフホスティング達成
3. **実用性検証**: 実アプリケーションの移植による実戦テスト
## 🔗 関連ドキュメント
- [00_MASTER_ROADMAP.md](../00_MASTER_ROADMAP.md) - 全体計画
- [Phase 9.79b](../phase-9/) - 統一Box設計前提
- [MIR仕様](../../../../reference/mir/) - 中間表現

View File

@ -0,0 +1,94 @@
# Phase 10.10 Python→Nyash→MIR→VM/Native ラインの実用化整備Box-First 継続)
目的: Nyash→MIR→VM/Native の実行ラインを日常運用レベルに引き上げ、GC/デバッグ/HostCallの柱を整備する。
## ゴールDoD
- エンドツーエンド実行ラインParser→AST→MIR→VM→JITがビルトインBoxで安定RO/一部WO
- GC切替Null/CountingをCLI/Boxから操作可能、root領域APIが一箇所化
- デバッグ/可視化の旗振りDebugConfig/BoxでJIT/VM/イベント/DOTを一本化
- HostCall: 読み取り系はparam受けでJIT直実行allow。書き込み系はポリシー/whitelistでopt-in可能
- 最小ベンチと回帰(サンプル)でラインの劣化を検知
## 事前整備(現状)
- HostCall基盤: Registry/Policy/Events/Boundary10.9-β/δ完了)
- JITイベント: `NYASH_JIT_EVENTS=1` 時に `threshold=1` 自動適用でLower確実実行
- 戻り境界: CallBoundaryBox で JitValue→VMValue を一元化(ハンドル復元含む)
## ワークストリーム
1) GC Switchable Runtimephase_10_4_gc_switchable_runtime.md
- 目標: NullGc/CountingGc の切替、root領域/バリアAPIの一本化
- タスク:
- NyashRuntimeBuilder: GC選択をCLI/Box反映NYASH_GC=none|counting など)
- ScopeTracker/enter_root_region()/pin_roots() の公開インターフェース確認
- CountingGcの統計出力roots/reads/writes/safepoints
- 書き込み系HostCallにバリアサイトのフックMap/Array set/push
- 受入: GC切替コマンドで統計差分が取れるHostCall書き込みでバリアサイトが加算される
2) Unified Debug Systemphase_10_8_unified_debug_system.md
- 目標: デバッグ/観測フラグを DebugConfig/Box に統合CLI/env/Boxの単一路
- タスク:
- DebugConfigRust側: dump/events/stats/dot/phi_min 等を集約
- DebugConfigBox: Boxから get/set/apply/toJson/fromJson
- Runner: CLI→DebugConfig→env/Box の一本化env直読み排除
- イベント出力先: stdout/file 切替の設定NYASH_JIT_EVENTS_PATH のBox反映
- 受入: Boxから apply 後、JIT/VM/DOTの挙動が即時反映JSONLが指定先に出力
3) E2Eラインの実用化builtin→pluginの足場
- 目標: ビルトインBoxで日常運用レベル、プラグインBoxはTLV HostCallの足場を準備
- タスク:
- Lowerカバレッジの整理BoxCall/RO/WO・param/非paramの分岐ダンプ
- 署名管理: レジストリのオーバーロード運用方針canonical idと派生idの整理
- 返り型推論: MIR Builderのreturn_type推定を確認main/補助関数とも)
- Plugin PoC: TLV/handle経由のread-onlyメソッド1つをHostCall経由で通すallowログまで
- 受入: 代表サンプルmath/map/array/stringでallow/fallbackが意図通り、plugin PoCでallowイベントが出る
4) ドキュメントと例の整理
- 目標: 例の最小集合化param/非param/RO/WO/HH/Hの代表、手順の簡潔化
- タスク:
- examples/: 重複の削減、README実行コマンド付き
- phase_10_9/10_10 のガイドをCURRENT_TASKと相互参照
- 受入: 主要ケースが examples/README からそのまま実行可
5) ベンチと回帰(最小)
- 目標: ラインの性能/退行の早期検知
- タスク:
- ny_bench.hako のケース整理(関数呼出/Map set-get/branch
- compare: VM vs JITウォームアップ付き
- 受入: ベンチ出力に JIT/VM の比較が出る(改善/退行が見える)
## リスクと対策
- param/非param 分岐の混乱: イベントに reason を必ず出すdocsにベストプラクティス受け手をparam化
- mutatingの誤許可: JitPolicyBox の whitelist/プリセットのみで許可、既定はread_only
- 署名の散逸: canonical id例: nyash.map.get_hと派生_hhの方針を明示
## 受け入れ基準(サマリ)
- DebugConfig/Box/CLIの一貫挙動apply後の即時反映
- GC切替とバリアサイト観測が可能
- HostCallRO/一部WOが param でallow、非paramでfallbackイベントで確認可
- 代表サンプルが examples/README の手順で成功
## すぐ試せるコマンド(抜粋)
```bash
# math.min関数スタイル
NYASH_JIT_EXEC=1 NYASH_JIT_THRESHOLD=1 NYASH_JIT_NATIVE_F64=1 NYASH_JIT_EVENTS=1 \
./target/release/nyash --backend vm examples/jit_math_function_style_min_float.hako
# Map.get HH直実行
NYASH_JIT_EXEC=1 NYASH_JIT_THRESHOLD=1 NYASH_JIT_HOSTCALL=1 NYASH_JIT_EVENTS=1 \
./target/release/nyash --backend vm examples/jit_map_get_param_hh.hako
# Mutating opt-inArray.push
NYASH_JIT_EXEC=1 NYASH_JIT_THRESHOLD=1 NYASH_JIT_HOSTCALL=1 NYASH_JIT_EVENTS=1 \
./target/release/nyash --backend vm examples/jit_policy_optin_mutating.hako
## 例とスモーク(開発者向けクイック)
- 例一覧: `examples/README.md`HH直実行・mutating opt-in・GCデモ
- スモーク: `bash tools/smoke_phase_10_10.sh`
- JITイベント最小スキーマ: `docs/reference/jit/jit_events_json_v0_1.md`
### Quick Note運用の勘所
- phase分離: compile→`phase:"lower"`opt-in, runtime→`phase:"execute"`既定ON可
- しきい値: 観測ONかつ未指定なら `NYASH_JIT_THRESHOLD=1`Runner/DebugConfigが補助
- HostCall: 実例では `NYASH_JIT_HOSTCALL=1` を明示HH直実行/ANYヘルパ
- ANYヘルパ: `nyash.any.length_h / is_empty_h` でROは十分カバー追加不要
```

View File

@ -0,0 +1,19 @@
# Phase 10.4 — GC Switchable Runtime (Scaffold)
Status: scaffolded (hooks only)
Goals
- Decouple execution engines from a concrete GC.
- Provide minimal `GcHooks` with `safepoint()` and `barrier(kind)` used by MIR `Safepoint`/`Barrier*`.
- Make runtime supply a pluggable GC via `NyashRuntimeBuilder::with_gc_hooks`.
Whats done (in this repo)
- Added `src/runtime/gc.rs` with `GcHooks` trait, `BarrierKind`, and `NullGc` (no-op).
- `NyashRuntime` now holds `gc: Arc<dyn GcHooks>`; defaults to `NullGc`.
- VM dispatch calls hooks on `Safepoint` and `Barrier(Read|Write|unified)`.
Next
- Thread-local root set API design (`enter_scope/leave_scope`, root pinning) for precise collectors.
- Card marking/write barrier integration for object field writes (`RefSet` sites).
- Preemption policy at safepoints (cooperative scheduling integration).

View File

@ -0,0 +1,27 @@
Phase 10.4d — Barrier Strict Mode (CI/Local)
Goal
- Catch missing Write-Barrier quickly in development and CI.
How-To (Local)
1) Build with default features:
cargo build --release -j32
2) Run with CountingGc + Strict Barrier + Trace:
(in code) build runtime via NyashRuntimeBuilder::with_counting_gc()
(env)
set NYASH_GC_BARRIER_STRICT=1
set NYASH_GC_TRACE=1
nyash <program.hako>
Expected
- Barrier sites log to stderr.
- On any mutating site without barrier increment, process panics with site name.
CI Suggestion
- Add a job that runs selected examples/tests with CountingGc enabled and
NYASH_GC_BARRIER_STRICT=1. Fail build on panic.
Notes
- Strict mode requires CountingGc; otherwise the helper panics to avoid false negatives.
- Use NYASH_GC_TRACE=2 for detailed roots breakdown at end-of-run when investigating.

View File

@ -0,0 +1,57 @@
# Phase 10.5: Core Standard (String/Array/Map) in Nyash — Rust依存の段階的削減
目的
- 現状Rust実装に依存している基本コンテナString/Array/Mapを、Nyashで実装したstdへ段階的に置換し、セルフホストへ近づける。
- rt/sys層Box ABI・所有・weak・最小アロケータ、`ny_host_*`)を活用して堅牢性と性能の両立を図る。
前提
- Phase 10.2: Host API層C-ABI `ny_host_*` / WASM `nyir_host`
- Phase 10.3: 層の切り分けcorelang/rt/sys/std
- Phase 10.4: Box ABIfat ptrとEffect→LLVM属性の方向性
範囲MVP
- String
- 構造: { ptr: *u8, len: usize, cap: usize }
- API: new, from_raw, into_raw, clone, len, is_empty, push_str, substr(view), to_utf8(view)
- メモリ: `ny_host_alloc/realloc/free` 経由、UTF-8不変validation optional
- Array<T>
- 構造: { ptr: *T, len: usize, cap: usize }
- API: new, push, pop, get(i), set(i,v), len, reserve
- メモリ: `ny_host_*` 経由、要素のfiniハンドリングBox所有規則順守
- Map<K,V>
- 構造: ハッシュテーブル(オープンアドレス or チェイン; v0は単純で可
- API: new, get, set, remove, len, keys(view), values(view)
- メモリ: `ny_host_*` 経由、キー/値の所有/weak規則順守
設計ポリシー
- 所有とfini: 再代入・スコープ終端でfiniが適切に発火することEverything is Box準拠
- 互換: 現行言語表面の挙動に合わせる(差異は仕様に明記)
- 効果: mut操作の順序保持、view系はpure読み取り
- WASM/LLVM: ABI/ExternCallと矛盾しないStringの(ptr,len)は共通)
タスクCopilot TODO
1) stdレイアウトの骨子作成ファイル/モジュール構成)
2) String v0実装 + 単体テストpush_str/len/substr
3) Array v0実装 + 単体テストpush/get/set/len
4) Map v0簡易hash+ 単体テストset/get/remove/len
5) 再代入/スコープ終端でのfini挙動の統合テスト
6) ベンチ: 既存Rust実装対比の大まかな目安悪化しない/許容範囲)
7) フェールセーフ: OOM/境界エラーの明確化panic/Resultは設計に従う
8) ドキュメント: stdのMVP API一覧と互換要件
受け入れ基準
- 代表サンプルがRust実装なしでString/Array/Mapを利用し動作
- 再代入・スコープ終端時にfiniが期待通り発火ログで可視化
- WASM/LLVMの文字列(ptr,len)取り扱いと整合print等のExternCallで可視化
リスク・軽減
- パフォーマンス劣化: ベンチで目視確認、ホットパス最適化は後続で実施
- メモリ安全: 所有/weak/効果規則をVerifierで補助後続でLSP/静的解析を強化)
- 実装負債: MVP範囲を明確にし、機能追加はIssue分割
参考
- ABIドラフト: docs/予定/native-plan/box_ffi_abi.md
- NyIR: docs/nyir/spec.md
- Host API: Phase 10.2 仕様
最終更新: 2025-08-14

View File

@ -0,0 +1,20 @@
# Phase 10.6 — Thread-Safe Revolution (Design Prep)
Status: preparation
Principles
- Opt-in concurrency: default runtime remains single-threaded for simplicity.
- All extension points intended for cross-thread use must be `Send + Sync`.
Whats prepared
- `GcHooks: Send + Sync` to allow multi-threaded collectors later.
- `NyashRuntime` holds `Arc<dyn GcHooks>` for safe sharing across threads.
Planned tasks
- Audit `NyashBox` implementations for `Send + Sync` (introduce marker traits or wrappers).
- Introduce scheduler abstraction for futures/actors (no global state).
- Introduce interior mutability strategy `RwLock` on shared mutable state, with minimal contention.
Notes
- Until the audit, VM enforces single-threaded access; sharing across threads is unsupported by default.

View File

@ -0,0 +1,46 @@
# Phase 10.6a — Thread-Safety Audit (Checklist)
目的: NyashBox/ランタイムのスレッド安全性を棚卸しし、将来の並列化10.6b/c以降に備える。
## 方針
- 既定は単一スレッド実行VM/Interpreter。並列化は opt-in。
- 共有状態は `Arc<...>``RwLock/Mutex` により内的可変を確保。
- クロススレッド境界に出る型は `Send + Sync` を満たす(必要に応じてラッパで担保)。
## チェックリスト
- Box実装src/boxes/*
- [ ] 共有内部状態を持つ型は `Arc<RwLock<_>>` のようにラップされているか
- [ ] `to_string_box()` が重い処理やグローバル可変に依存しないか
- [ ] FFI/プラグイン橋渡し時に非同期イベント/コールバックを保持しないか(保持する場合は送受戦略を文書化)
- ランタイムsrc/runtime/*
- [ ] `NyashRuntime` のメンバは `Send + Sync` 要件を満たす(`Arc<...>`
- [ ] `GcHooks` 実装は `Send + Sync`CountingGc/NullGc はOK
- [ ] Scheduler 実装は `Send + Sync`SingleThreadSchedulerはOK
- VM/Interpreter
- [ ] MIR `Safepoint``runtime.scheduler.poll()` を呼ぶ(協調スケジューラの結合点)
- [ ] Grep: `rg -n "Safepoint" src` で配置確認
## Grep支援
```bash
rg -n "Arc<|Mutex<|RwLock<|Send|Sync" src/boxes src/runtime
```
## 既知の注意点
- Python/外部DLLとの橋渡しはGIL/PATH管理で単一スレッド優先AOT時はPATH/PYTHONHOME調整済
- BufferBox は共有化のために `Arc<RwLock<Vec<u8>>>` を採用済み。
## クイック監査(第一次)
- ArrayBox: `Arc<RwLock<Vec<Box<dyn NyashBox>>>>` → OK共有内的可変
- MapBox: `Arc<RwLock<HashMap<String, Box<dyn NyashBox>>>>` → OK
- BufferBox: `Arc<RwLock<Vec<u8>>>` → OK
- NyashRuntime: `box_registry: Arc<Mutex<_>>`, `box_declarations: Arc<RwLock<_>>`, `gc: Arc<dyn GcHooks>`, `scheduler: Option<Arc<dyn Scheduler>>` → OK
- Scheduler: `SingleThreadScheduler` 内部に `Arc<Mutex<VecDeque<...>>>` → OK
- GC Hooks: `NullGc/CountingGc``Send+Sync` 実装方針 → OK
未確認/注意:
- プラグインBoxPluginBoxV2の内部FFIハンドルはVM/EXE側で共有参照のみ実体はFFI側。クロススレッド呼出しは未サポート運用明記要
- 一部のBoxで外部資源ファイル/ネットを扱う場合、スレッド越境のI/O同期設計は別途Phase 10.6d+)。
## 次の一手(提案)
- マーカーTraits例: `ThreadSafeBox`)の導入は保留(破壊的)。現時点は監査+ドキュメントで運用。
- 並列スケジューラM:Nの実装は `feature` フラグで段階導入。

View File

@ -0,0 +1,64 @@
Phase 10.6a — Thread-Safety Audit (TXT)
Scope
- Audit Send/Sync policy for core runtime + Box families.
- Classify: Allowed (Send+Sync), Not-Send (single-threaded), Needs-Wrapper (guarded by RwLock/mpsc/etc.).
- Output concrete action items for hardening.
Legend
- ALLOW: Safe to share/send across threads as-is.
- NO-SEND: Must remain thread-confined; do not share.
- WRAP: Provide wrapper/adapter to safely share (interior mutability / channels / handles).
Runtime Components
- NyashRuntime: WRAP — shared via Arc; subcomponents must be audited (registry/decls RwLock OK).
- GcHooks: ALLOW — trait requires Send+Sync; CountingGc is Send+Sync by design.
- TypeMeta/CacheVersions: WRAP — global tables; protect via atomic/versioning (already present) + RwLock where needed.
- Scheduler (planned): WRAP — explicit abstraction (cooperative); no global mutable state.
VM Values / Execution
- VMValue: ALLOW (data) / WRAP (BoxRef) — primitives OK; BoxRef must only be shared via immutable Box API.
- ScopeTracker: NO-SEND — per-VM; not shared. Access confined to single thread.
- JIT Manager: WRAP — read-mostly maps; guard with RwLock if shared, or keep per-VM.
Builtin Boxes (initial pass)
- IntegerBox/BoolBox/StringBox: ALLOW (immutable data semantics).
- FloatBox (math): ALLOW (stateless ops; string-ification only).
- ArrayBox/MapBox: WRAP — interior mutability required (RwLock); Write-Barrier remains required.
- Buffer/IO/Net/Time/Audio/etc.: WRAP — external handles; use Arc + internal locks; expose async/channel for ops.
- FutureBox: WRAP — already uses RwLock pattern; verify methods are non-blocking and Send+Sync where applicable.
- ChannelBox: WRAP — backed by mpsc/crossbeam; ensure senders/receivers are Send.
Plugin Boxes
- PluginBoxV2: WRAP — FFI handle; calls marshalled via TLV; all access through thread-safe host layer.
Interpreter/Runner Layers
- Parser/Tokenizer/AST: ALLOW (not shared at runtime).
- Runner (VM backend): NO-SEND — execution confined to the owning thread.
Policies and Enforcement
1) Marker traits (for docs only):
- ThreadSafeBox (Doc): Box types that are Send+Sync-safe as value semantics.
- HandleBox (Doc): wraps external/native handles; must be behind RwLock/Mutex and non-blocking APIs.
2) Constructor guidance:
- For WRAP boxes, store state under RwLock/Mutex; prefer RwLock (read-mostly).
- Avoid blocking in methods; prefer async/task dispatch via scheduler abstraction.
3) Sharing rules:
- VMValue::BoxRef must not be mutated without Write-Barrier when GC is active.
- Cross-thread sharing limited to BoxRef with immutable APIs or actor-like message passing.
4) Testing:
- Add feature-gated thread-smoke tests (spawn two threads, share ALLOW boxes, ensure no UB).
- Add Mutex/RwLock poisoning handling policies (map to Nyash exceptions if needed).
Immediate Action Items
- [A1] Document per-Box classification in code headers (short note + rationale).
- [A2] Ensure ArrayBox/MapBox internals use RwLock and respect Write-Barrier (already partially in place; verify set/push paths).
- [A3] PluginBoxV2 calls remain serialized through host; confirm Send on host dispatch closures.
- [A4] Introduce lightweight scheduler trait (single-threaded impl first); route blocking ops via scheduler.
- [A5] Add CI job to run with NYASH_GC_BARRIER_STRICT=1 and CountingGc for barrier regression.
Future (10_6b/10_6c tie-ins)
- Scheduler + cooperative safepoint policy across threads.
- Per-thread root regions; ensure root pin/unpin remains thread-local.
- Card marking/write barrier strategy for shared objects modified across threads (design doc first).

View File

@ -0,0 +1,25 @@
Phase 10.6b — Scheduler Prep (Single-Thread Queue)
Whats added
- `src/runtime/scheduler.rs` with `Scheduler` trait and `SingleThreadScheduler`.
- Queue + delayed tasks (spawn/spawn_after) and `poll()` to run work.
- VM calls `scheduler.poll()` at MIR `Safepoint` to integrate cooperative scheduling.
- Poll budget via env `NYASH_SCHED_POLL_BUDGET` (default: 1)
- Trace via `NYASH_SCHED_TRACE=1` (diagnostic)
How to use (dev)
- Build runtime with default SingleThreadScheduler (already default via builder), or inject custom via:
`NyashRuntimeBuilder::new().with_single_thread_scheduler().build()`
- Schedule tasks from boxes/host code via `runtime.scheduler.spawn(...)`.
- At safepoints, queued tasks run (1 per safepoint) and due delayed tasks are enqueued.
How to validate quickly
- Run any Nyash program that contains loops or function entries (safepoints exist by default).
- Optionally enable the demo hook: set `NYASH_SCHED_DEMO=1` and run the VM backend
to observe scheduler tasks firing at safepoints.
- Control throughput by `NYASH_SCHED_POLL_BUDGET` (e.g., 3 runs up to 3 tasks/safepoint).
- GC trace pairs well: set `NYASH_GC_COUNTING=1 NYASH_GC_TRACE=1` to see safepoints.
Next (10.6c+)
- Expose scheduling APIs to script level (Box API).
- Optional multi-thread scheduler implementation behind feature flag.

View File

@ -0,0 +1,37 @@
Phase 10.6c — Parallel GC Design (Notes)
Objectives
- Keep GC hooks and MIR sites stable while enabling parallel/stop-the-world options.
- Introduce per-thread root regions, card marking, and coordinated safepoints.
Design Sketch
1) Per-thread roots
- Root API remains the same but live under thread-local trackers.
- VM/engines expose `enter_root_region/pin/leave_root_region` that operate on TLS.
- Global snapshot for diagnostics merges per-thread views (debug only).
2) Safepoint coordination
- Central GC controller requests a safepoint; worker threads acknowledge at next MIR `Safepoint`.
- Timeout/poll policy configurable; in single-threaded mode this is no-op.
3) Card marking / write barriers
- Extend `BarrierKind::Write` to accept optional object metadata (future API): object id/card index.
- For now, keep symbolic barrier only; when parallel GC is enabled, maintain a global dirty set.
4) Scheduler interplay
- GC controller can schedule minor/major cycles using the Scheduler abstraction.
- In single-threaded mode, cycles are chunked via `poll()` to avoid long pauses.
API Diffs (future)
- `GcHooks::barrier(kind)` → `barrier(kind, obj: Option<ObjectId>)` (compat shim keeps old signature).
- `GcHooks::safepoint()` may return a hint (`Proceed`, `Yield`) for engines to cooperate.
Migration Plan
- Keep current single-threaded path as default.
- Add feature flag `gc-parallel` that swaps in an implementation honoring the extended API.
- Incrementally add: dirty set, per-thread roots, coordinated safepoint prototype.
Testing Strategy
- Deterministic unit tests using SingleThreadScheduler.
- Stress tests with STRICT barrier and TRACE=2 to validate barrier coverage and root progression.

View File

@ -0,0 +1,85 @@
Phase 10.7 — JIT Branch Wiring + Minimal ABI Extensions
Overview
- Purpose: Enable real control-flow in the JIT path by wiring MIR Branch/Jump/Return to Cranelift blocks, and extend the minimal ABI to support multi-arg i64 and basic bool/f64.
- Outcome: If/loop constructs execute natively in JIT for straight-line + branched code paths, with safe VM fallback preserved. HostCall PoC remains opt-in.
Goals (Must)
- Wire MIR basic blocks to Cranelift blocks; emit `brif` and `jump` for Branch/Jump.
- Keep Compare result usable as a branch condition (b1); where necessary, convert i64 to b1 via `icmp_imm != 0`.
- Preserve Return behavior (already in place) and allow branching to return in both sides (no PHI required for first pass).
- Minimal ABI: multi-argument i64 stable, bool constants lowered to 0/1, f64 constants passed through (no arithmetic yet required).
- Safety: On JIT panic or unsupported instruction at runtime, VM fallback with logs.
Stretch (Nice-to-have)
- PHI at merge points via block parameters for simple patterns (two-predecessor if-else returning a value).
- Bench: Add a small control-flow benchmark to CLI/`examples`.
Non-Goals (10.7)
- Full PHI generalization across arbitrary CFG.
- Type-specialized calling conventions beyond i64/f64/bool minimal path.
- Deoptimization or on-stack replacement.
Deliverables
- Code: CraneliftBuilder block management + branch/jump emission.
- Lowering updates: Branch/Jump hook uses real block IDs; Compare emits b1-friendly shape.
- Env flags: Reuse `NYASH_JIT_EXEC/THRESHOLD/STATS/DUMP`; guard hostcalls by `NYASH_JIT_HOSTCALL`.
- Docs: Update execution-backends.md with “JIT control-flow coverage (10.7)”.
- Examples: `examples/jit_branch_demo.hako` (if/loop minimal).
Design Sketch
1) Block Mapping
- Build `bb_map: MirBB -> Cranelift Block` in `begin_function` based on MIR function blocks.
- Switch to entry block, `seal_block(entry)`.
2) Conditions
- Compare emits Cranelift `icmp` returning b1; avoid converting to i64 unless explicitly needed.
- If the condition arrives as i64 (const/param), lower `icmp_imm != 0` to get b1 for `brif`.
3) Branch / Jump
- `emit_branch(cond, then_bb, else_bb)` → `brif(cond_b1, then_block, []); jump(else_block, []); seal both`.
- `emit_jump(target_bb)` → `jump(target_block, [])`.
4) Return
- Keep current return emission; when branches end in return, no PHI needed.
5) PHI (limited)
- For a simple diamond where both arms jump to a single merge, add one block param at merge.
- Pass the value via `jump(merge, [val])`; read via `block-arg(merge, 0)`; return it.
6) ABI
- Keep signature `(i64 x argc) -> i64?` baseline.
- Support f64/bool consts materialization; booleans as 0/1 integers for now unless used as branch cond (then b1).
Implementation Plan (Tasks)
- T1: Extend IRBuilder API (only behind `cranelift-jit`): create_block(), br_if(), jump(), seal_block(), block_param(), append_block_params_for_function_params().
- T2: CraneliftBuilder: implement block map allocation in begin_function; store in builder state.
- T3: LowerCore:
- Track current MIR bb while iterating.
- For Branch/Jump, call builder with mapped blocks and condition value hint.
- Compare: emit b1 icmp; when Compare is used as value elsewhere, allow i64 extend as needed.
- T4: Minimal PHI support for a single merge (optional; guarded by env `NYASH_JIT_PHI_MIN=1`).
- T5: Add `examples/jit_branch_demo.hako` with: `if (a < b) { return 1 } else { return 2 }` and a small loop with early `return`.
- T6: Docs update: execution-backends.md “JIT coverage 10.7” + env flags.
- T7: Bench (optional): integrate into `--benchmark` with JIT warmup when `NYASH_JIT_EXEC=1`.
Validation
- Build matrix: with/without `cranelift-jit` feature.
- Smoke tests: run `jit_branch_demo.hako` with `NYASH_JIT_EXEC=1 NYASH_JIT_THRESHOLD=1`.
- Fallback verification: force a path with unsupported op to confirm VM fallback.
- GC/scheduler: ensure safepoint path still works (unchanged).
Risk & Mitigation
- Mismatch of block sealing/order → start with straight-line + simple diamond; add asserts; prefer FunctionBuilder patterns.
- Condition type confusion (i64 vs b1) → centralize cond normalization helper.
- PHI complexity → keep optional, limited to single value diamond.
Rollout
- Phase gate by envs: `NYASH_JIT_EXEC` for enable, `NYASH_JIT_PHI_MIN` for PHI.
- Keep `NYASH_JIT_HOSTCALL` opt-in.
Success Criteria
- If/else returning constants runs fully via JIT (Cranelift) without VM fallback.
- Simple counting loop with early exit returns correct result via JIT.
- All tests pass with and without feature flag; VM fallback works on traps.

View File

@ -0,0 +1,135 @@
Phase 10.7 — JIT CFG/PHI/ABI Hardening (Master Plan)
Intent
- Deliver a practical, observable JIT path for control flow and minimal data flow while keeping VM as the safe fallback.
- Decompose into small, shippable sub-phases with flags and examples, minimizing blast radius.
Related docs
- 10.7a details: phase_10_7a_jit_phi_cfg_and_abi_min.txt
- Current work log: docs/development/current/CURRENT_TASK.md
- Cranelift JIT backend notes: phase_10_cranelift_jit_backend.md
Flags and CLI (common across 10.7)
- Env: NYASH_JIT_EXEC, NYASH_JIT_STATS, NYASH_JIT_STATS_JSON, NYASH_JIT_DUMP, NYASH_JIT_THRESHOLD, NYASH_JIT_PHI_MIN, NYASH_JIT_HOSTCALL
- CLI: --jit-exec --jit-stats --jit-stats-json --jit-dump --jit-threshold N --jit-phi-min --jit-hostcall
Examples to validate
- examples/jit_branch_demo.hako
- examples/jit_loop_early_return.hako
- examples/jit_phi_demo.hako
- examples/jit_array_param_call.hako, jit_map_param_call.hako (when hostcall is enabled)
Sub-phases (10.7a → 10.7h)
10.7a — Minimal branch/PHI/ABI (Done or in-flight)
- Branch wiring with b1 and i64!=0 normalization
- Minimal PHI: single-value diamond via block param
- Independent ABI (JitValue) with integer-first calling
- Panic-safe dispatch (catch_unwind) and VM fallback
- Minimal hostcall bridge (Array/Map) behind NYASH_JIT_HOSTCALL
- Observability: unified JIT summary/JSON, lower summary (argc/phi_min), CFG edge dump (phi_min)
Acceptance: see 10.7a doc
10.7b — PHI generalization and block-parameterization
- Support multiple PHIs in a merge block; pass N values via block params
- LowerCore: gather PHI inputs per successor, produce explicit arg lists; handle straight merges and simple loops
- IRBuilder API formalization:
- ensure_block_params_i64(index, count)
- br_if_with_args(then_idx, else_idx, then_n, else_n)
- jump_with_args(target_idx, n)
- CraneliftBuilder: append N I64 params per block, materialize current block params onto stack when requested
- Validation: multi-PHI diamonds, if-else chains, early returns; keep loops as simple as possible in 10.7b
10.7c — Independent host-handle registry (JIT↔Host decoupling)
- Introduce JitHandleRegistry: u64 ↔ Arc<dyn NyashBox>
- JIT hostcalls accept/return only handles and PODs; VMValue↔JitValue boundary converts BoxRef <-> Handle via registry
- Rooting policy: enter/pin roots for handles crossing the boundary; leave on return
- Flags: NYASH_JIT_HOSTCALL=1 (still gated); add NYASH_JIT_HANDLE_DEBUG for dumps
- Deliverables: array/map operations via handles, no direct VMValue access on JIT side
10.7d — Side-effect boundary and hostcall coverage expansion
- Keep side-effecting ops (print/IO) on VM for now; document deopt path
- Expand safe hostcalls (read-only or confined):
- String.len / slice basics (POD returns)
- Map.size; Map.get with integer and string keys (key boxing handled at boundary)
- Record effect categories on lowered calls for future optimizer (metadata only)
10.7e — CFG diagnostics and visualization
- Add DOT export for CLIF CFG with block params and PHI bindings
- Env: NYASH_JIT_DOT=path.dot (produces per-function graph)
- Optional: ASCII CFG summary for CI logs
- Cross-check with VM-side MIR printer for block and PHI consistency
10.7f — JitConfigBox (configuration as a Box)
- Encapsulate all JIT toggles into a runtime-managed box (JitConfigBox)
- Harmonize env/CLI with programmatic overrides for tests
- Feed config into JIT engine and lowerers (no direct env reads inside hot paths)
- Serialization: dump/load config JSON for reproducible runs
10.7g — Stability, tests, and benchmarks
- Golden tests: ensure JIT/VM outputs match on curated programs
- Fallback ratio regression guard: alert when fallback_rate spikes beyond threshold
- JSON schema stability for stats; include version field
- Microbenchmarks: branch-heavy, phi-heavy, and hostcall-heavy cases; gated perf checks
10.7h — Type widening for native ABI
- Add native F64 and Bool parameter/return paths in CLIF
- Condition handling: keep b1 where possible; map Bool to b1 cleanly
- Conversions: explicit i64<->f64 ops in lowerer where needed (no silent truncation)
- Update adapter and closure trampoline to select proper function signatures (arity×type shapes)
Out of scope for 10.7 (shift to 10.8/10.9)
- Global register allocation strategies or codegen-level optimizations
- Deoptimization machinery beyond simple VM fallback
- Advanced exception propagation across JIT/VM boundary
Risks and mitigation
- PHI N-arity correctness: introduce targeted unit tests over synthetic MIR
- Handle registry leaks: counting diagnostics, strict mode; tie roots to scope regions
- CLIF block-param misuse: deterministic block order + seal discipline + assertions in builder
Verification checklist (roll-up)
- cargo check (± --features cranelift-jit)
- Run examples with JIT flags; diff with pure VM runs
- Inspect: unified JIT summary/JSON, lower logs, CFG dumps/DOT
- Leak/roots checks when NYASH_GC_TRACE=1/2/3 and strict barrier mode is on
Suggested timeline (tentative)
- 10.7a: Minimal branch/PHI/ABI (done / in-flight)
- 10.7b: PHI generalization + builder API formalization (12 days)
- 10.7c: Host-handle registry PoC (12 days)
- 10.7d/e: Hostcall coverage + CFG DOT (23 days)
- 10.7f: JitConfigBox + integration (1 day)
- 10.7g/h: QA + type widening for f64/bool (24 days)
10.7z — Follow-ups and Open Items (post-10.7)
- b1 PHI tagging robustness
- Problem: Provenance can be obscured by Load/Store and multi-step copies; (b1) tag may be missed in dumps.
- Action:
- Add a lightweight boolean-lattice analysis over MIR to classify boolean-producing values independent of path shape.
- Extend dump to include phi_summary JSON or structured rows when NYASH_JIT_STATS_JSON is on.
- Placement: 10.7g (stability/tests) — does not block 10.7 close.
- VM f64 arithmetic/compare parity
- Problem: VM backend currently errors on f64 BinOp/Compare; JIT (Cranelift) supports f64 when enabled.
- Action: Implement f64 ops in VM or add consistent auto-promotion; add golden tests.
- Placement: 10.8 (VM parity/perf) — out-of-scope for 10.7.
- Native b1 ABI in function signatures
- Problem: Toolchain capability for b1 return/params is currently disabled.
- Action: Keep centralized switch; add CI probe to flip automatically when supported; wire return path fully.
- Placement: 10.7h or later (gated by toolchain).
- Stats/diagnostics polish
- Action: Version the unified JIT JSON schema; expose phi(b1) slot counts in JSON; enrich JitStatsBox with summary/topN (partially done).
- Placement: 10.7g.
- Build warnings (unexpected cfg: llvm)
- Problem: Warning noise from unused/unknown cfg.
- Action: Declare feature flags in Cargo.toml or gate code behind existing features; optionally silence for non-supported builds.
- Placement: 10.7g (cleanup) — non-blocking.
- Documentation sync
- Action: Add a "JIT quick flags" section with common env/CLI combos; ensure CURRENT_TASK and examples remain aligned.
- Placement: 10.7e (docs) — non-blocking.

View File

@ -0,0 +1,92 @@
Phase 10.7a — JIT Branch/PHI/Independent ABI: Minimal Path Hardening (Plan)
Purpose
- Solidify the first functional slice of the JIT control-flow path:
- Branch wiring (b1 and i64!=0 normalization)
- Minimal PHI via block parameters (single-value diamond)
- Independent ABI (JitValue) and safe dispatch + fallback
- Observable, toggleable, and easy to verify via flags + examples
Scope (10.7a only)
1) Minimal PHI handoff
- LowerCore: detect single-PHI merge; pass i64 value via block param
- CraneliftBuilder: ensure block param (I64), push/pop on branch/jump with args
- Flag gate: NYASH_JIT_PHI_MIN=1
2) Branch wiring and condition normalization
- Keep compare result on stack as b1 when possible
- If top-of-stack is I64, normalize by icmp_imm != 0
- Implement br_if/jump to pre-created blocks (deterministic order)
3) Independent ABI (minimum viable)
- JitValue(I64/F64/Bool/Handle) in/out; normalize non-i64 args to i64 for now
- TLS split: legacy VM args (for hostcalls) and JIT args
- Engine.execute_handle uses catch_unwind; panic → VM fallback with stats
4) Minimal hostcall bridge (safe; off by default)
- Symbols: nyash.array.{len,get,set,push}, nyash.map.{size}
- Gate: NYASH_JIT_HOSTCALL=1
- Only integer indices/values (PoC); other types map to handles later
5) Observability and ergonomics
- Flags: NYASH_JIT_EXEC, NYASH_JIT_STATS, NYASH_JIT_STATS_JSON, NYASH_JIT_DUMP, NYASH_JIT_THRESHOLD, NYASH_JIT_PHI_MIN, NYASH_JIT_HOSTCALL
- CLI: --jit-exec --jit-stats --jit-stats-json --jit-dump --jit-threshold N --jit-phi-min --jit-hostcall
- Unified JIT summary on VM exit (sites/compiled/hits/exec_ok/trap/fallback_rate)
- Lower log includes argc/phi_min + CFG light dump (phi edges) when NYASH_JIT_DUMP=1
Non-Goals (later 10.7b+)
- Full PHI generalization (multiple values, loops, complex CFG forms)
- Non-i64 native path (true F64/Bool return/params in CLIF)
- Side-effect instruction lowering (print, IO) — keep in VM path
- Host handle registry for real object bridging (u64↔Arc<dyn NyashBox>)
Deliverables
- Working minimal PHI + branch JIT execution on curated examples:
- examples/jit_branch_demo.hako
- examples/jit_loop_early_return.hako
- examples/jit_phi_demo.hako (single-PHI diamond)
- Fallback correctness: traps/panic → VM path; results match VM
- Configurable via CLI flags; metrics visible via JIT summary/JSON
Acceptance Criteria
- With: --backend vm --jit-exec --jit-stats --jit-threshold 1
- For branch/phi examples, JIT executes without panic
- VM fallback occurs only for unsupported ops (logged)
- JIT summary shows exec_ok > 0 and reasonable fallback_rate
- With: --jit-phi-min
- CFG dump lists phi_min edges and blocks count
- Results match the same program without JIT enabled
Risk & Mitigation
- Mismatch between VMValue and JitValue adapters
- Mitigation: normalize non-i64 to i64 defensively; expand tests on adapters
- Cranelift block parameter misuse
- Mitigation: deterministic block order and explicit ensure_block_param_i64()
- Panic in hostcall stubs (unexpected Box types)
- Mitigation: gated by NYASH_JIT_HOSTCALL=1; default off; fallback to VM on panic
Verification Checklist
- cargo check (w/ and w/o --features cranelift-jit)
- Run examples with JIT flags; compare outputs with pure VM
- Inspect logs: lower summary + CFG dump + unified summary/JSON
Timeline (10.7a)
Day 1:
- Finalize ABI normalization and branch wiring; add unified stats (done)
- Wire CLI flags and JSON stats (done)
Day 2:
- Harden minimal PHI path and CFG dump (done)
- Curate examples and sanity-run on flags
Day 3:
- Stabilize logging format, trim rough edges, doc polish
→ Then roll into 10.7b (multi-PHI, multi-arg block params, real handle registry)
Follow-ups (10.7b/10.7c seeds)
- Host handle registry (u64↔Arc) and type-safe bridging
- True F64/Bool native ABI, multi-arg params/returns
- CFG visualization improvements (dot export) and JitConfigBox
Refs
- docs/development/current/CURRENT_TASK.md (10_7 items)
- src/jit/{lower,engine,manager,abi,rt}/
- examples: jit_* demos

View File

@ -0,0 +1,45 @@
# Phase 10.7h — Native ABI Types (F64/Bool)
Goal
- Extend the minimal i64-only JIT ABI to support f64 and bool as native parameter/return types in CLIF.
Principles
- Keep JIT independent from VM internals (use JitValue + adapters at boundary)
- Avoid silent truncation; perform explicit conversions in the lowerer
- Maintain safety-first fallback to VM for unsupported ops
Plan
1) JitValue widening
- JitValue already has I64/F64/Bool/Handle — keep this as the ABI surface
- Adapter: refine to/from VMValue mappings (no lossy coercion by default)
2) CLIF signature selection
- Augment CraneliftBuilder to build signatures based on (arity × type shape)
- Start with small shapes: (I64|F64|Bool)* → I64|F64|Bool
- Closure trampoline: transmute to matching extern "C" fn type; dispatch by shape id
3) Condition handling
- Bool: prefer b1 in IR; allow i64!=0 normalization when comparing integers
- Comparisons yield b1; lower branch consumes b1 directly
4) Conversions in lowerer (explicit only)
- add_const_f64, add_convert_{i64_to_f64, f64_to_i64}
- prohibit implicit int<->float coercion in arithmetic; gate conversions via explicit MIR ops or intrinsics
5) Observability and flags
- NYASH_JIT_NATIVE_F64=1 / NYASH_JIT_NATIVE_BOOL=1 to enable paths
- Dump: show chosen signature shape and conversions when NYASH_JIT_DUMP=1
6) Rollout
- Phase A: const/binop/ret for f64; comparisons yield b1
- Phase B: mixed-type ops via explicit converts
- Phase C: HostCall bridging for f64/bool PODs (read-only first)
Risks / Mitigation
- Signature explosion: start with a few common shapes; fallback to i64 path
- Platform ABI mismatches: rely on Cranelift default call conv; e2e-perf and correctness first
Acceptance
- Examples with pure f64 pipelines run under JIT with matching results vs VM
- No silent lossy conversions; conversions visible in MIR/Lower logs

View File

@ -0,0 +1,172 @@
# Phase 10.8: 統一デバッグシステム - DeepInspectorBoxとグローバルデバッグ整理
作成日: 2025-08-27
発見者: ニャー
参照元: docs/ideas/other/2025-08-25-unified-box-design-deep-analysis.md
## 🚨 現在の問題
### 1. デバッグ環境変数の乱立
現在20個以上の環境変数が散在
- `NYASH_VM_STATS=1`
- `NYASH_VM_DEBUG_BOXCALL=1`
- `NYASH_DEBUG_PLUGIN=1`
- `NYASH_NET_LOG=1`
- `NYASH_JIT_THRESHOLD=1`
- ... など多数
### 2. 統一されていないデバッグ体験
- VM、プラグイン、JIT、ネットワークなど各コンポーネントが独自のデバッグフラグ
- 複数の環境変数を組み合わせる必要がある
- 何をONにすればいいか分かりにくい
## 🌟 提案: 統一デバッグシステム
### 1. 環境変数の整理統合
```bash
# Before (現在)
NYASH_VM_STATS=1 NYASH_VM_DEBUG_BOXCALL=1 NYASH_NET_LOG=1 ./nyash
# After (提案)
NYASH_DEBUG=vm,boxcall,net ./nyash
```
### 2. デバッグレベル制御
```bash
# シンプルなレベル制御
NYASH_DEBUG_LEVEL=0 # OFF
NYASH_DEBUG_LEVEL=1 # 基本情報のみ
NYASH_DEBUG_LEVEL=2 # 詳細情報
NYASH_DEBUG_LEVEL=3 # すべて
# カテゴリ別レベル
NYASH_DEBUG=vm:2,net:1,jit:3
```
### 3. プリセット(よく使う組み合わせ)
```bash
# プリセット
NYASH_DEBUG_PRESET=basic # 基本的なデバッグ情報
NYASH_DEBUG_PRESET=perf # パフォーマンス分析用
NYASH_DEBUG_PRESET=network # ネットワーク問題調査用
NYASH_DEBUG_PRESET=memory # メモリリーク調査用
NYASH_DEBUG_PRESET=all # すべて有効
```
## 🔍 DeepInspectorBox - Everything is Debugの実現
### グローバルシングルトンデバッガー
```nyash
// グローバルに1つだけ存在する統一デバッガー
static box DeepInspectorBox {
public { enabled }
private {
boxCreations, methodCalls, fieldAccess,
memorySnapshots, referenceGraph, performanceMetrics
}
// === 簡単な有効化 ===
enable(categories) {
// "vm,net,memory" のようなカテゴリ文字列を解析
me.parseAndEnableCategories(categories)
}
// === プリセット対応 ===
usePreset(presetName) {
match presetName {
"basic" => me.enable("vm,error")
"perf" => me.enable("vm,boxcall,stats")
"network" => me.enable("net,plugin,tlv")
"memory" => me.enable("alloc,gc,leak")
"all" => me.enable("*")
}
}
// === 統合ログ出力 ===
log(category, level, message) {
if me.shouldLog(category, level) {
local formatted = me.formatLog(category, level, message)
me.output(formatted)
}
}
}
```
### MIRレベルでの統一実装
```rust
// MIR生成時にデバッグフックを埋め込み
impl MirBuilder {
fn build_new_box(&mut self, type_id: TypeId) -> ValueId {
let result = self.push(NewBox { type_id });
// デバッグモード時のみ
if self.debug_enabled {
self.push(DebugHook {
event: DebugEvent::BoxCreated,
type_id,
value: result,
});
}
result
}
}
```
## 📊 実装計画
### Phase 10.8a: 環境変数統合3日
- [ ] 統一パーサー実装(`NYASH_DEBUG`解析)
- [ ] レベル制御システム
- [ ] プリセット定義
- [ ] 既存環境変数との互換性層
### Phase 10.8b: DeepInspectorBox基礎1週間
- [ ] グローバルシングルトン実装
- [ ] カテゴリ管理システム
- [ ] 基本的なログ収集
- [ ] 出力フォーマッター
### Phase 10.8c: MIR統合1週間
- [ ] DebugHook命令追加
- [ ] MirBuilderへのフック埋め込み
- [ ] VMでのDebugHook実行
- [ ] JITでのデバッグ情報保持
### Phase 10.8d: 高度な機能2週間
- [ ] メモリリーク検出
- [ ] 参照グラフ構築
- [ ] P2P非同期フロー追跡
- [ ] パフォーマンスプロファイリング
## 🎯 期待される効果
### 1. 使いやすさ向上
- 1つの環境変数で制御
- 分かりやすいプリセット
- 統一されたログフォーマット
### 2. デバッグ効率向上
- 必要な情報だけを表示
- カテゴリ別フィルタリング
- レベル別詳細度制御
### 3. 保守性向上
- 新しいデバッグ機能の追加が容易
- 統一されたインターフェース
- MIRレベルでの一元管理
## ✅ 成功基準
1. **環境変数の数**: 20個以上 → 3個以下
2. **デバッグ有効化**: 複雑なコマンド → `NYASH_DEBUG=basic`
3. **統一体験**: すべてのコンポーネントで同じデバッグインターフェース
---
*Everything is Box, Everything is Debug - 統一されたデバッグ体験へ*

View File

@ -0,0 +1,85 @@
# Phase 10.7: fromキーワード一貫性修正
作成日: 2025-08-27
発見者: ニャー
## 🚨 現在の問題
### 言語仕様と実装の不一致
- **言語仕様**: `from Parent.method()` 2025-08-11完全明示デリゲーション革命で決定
- **実装の一部**: まだ`super`という用語が残っている可能性
### 影響範囲
主にRustの`use super::*`(モジュールインポート)なので言語仕様への影響は限定的だが、以下の確認が必要:
1. エラーメッセージ内の文言
2. ドキュメントやコメント内の記述
3. 内部変数名・関数名での使用
## 🔧 修正内容
### 1. エラーメッセージの確認
```rust
// 例: エラーメッセージで"super"を使っていないか確認
"Cannot find super class" "Cannot find parent box for delegation"
```
### 2. ドキュメント・コメントの統一
```rust
// Before
// Call super method
// After
// Call parent method via from delegation
```
### 3. 内部実装での用語統一(必要に応じて)
```rust
// 変数名や内部メソッド名での統一
super_call() from_call()
SuperMethodCall FromMethodCall
```
## 📊 優先度評価
- **重要度**: 中(言語仕様の一貫性)
- **緊急度**: 低(機能的には問題ない)
- **実装難度**: 低(主に文言修正)
## 🎯 実装計画
### Phase 10.7a: 調査フェーズ1日
- [ ] エラーメッセージ内の"super"使用箇所を特定
- [ ] ドキュメント内の不整合を洗い出し
- [ ] テストケース内の文言確認
### Phase 10.7b: 修正フェーズ1日
- [ ] エラーメッセージの文言修正
- [ ] ドキュメント更新
- [ ] 必要に応じて内部変数名の統一
### Phase 10.7c: 検証フェーズ(半日)
- [ ] 修正後の動作確認
- [ ] エラーメッセージの表示確認
- [ ] ドキュメントの整合性チェック
## 📝 Nyashの哲学との整合性
### fromキーワードの意義
- **明示性**: どの親のどのメソッドかを完全に明示
- **統一性**: 宣言(`box Child from Parent`)と呼び出し(`from Parent.method()`)で同じキーワード
- **初学者フレンドリー**: 「〜から」という直感的な表現
### superを使わない理由
- 多重デリゲーション時に曖昧
- 他言語の概念を引きずらない
- Nyash独自の哲学を貫く
## ✅ 期待される効果
1. **一貫性**: 言語仕様と実装の完全な一致
2. **学習性**: 初学者が混乱しない統一された用語
3. **独自性**: Nyashらしい設計思想の徹底
---
*「from」こそがNyashの明示的デリゲーションの象徴*

View File

@ -0,0 +1,155 @@
# Phase 10.9 Builtin-Box JIT SupportBox-First Plan
目的: Nyashスクリプト → VM基準→ JIT段階導入
まずは「読み取り系」をJITで安全に通し、箱で問題点を包んで順に拡張する。
## 🎯 ゴールDoD
- 機能: String/Array/Map の読み取りAPIが JIT 経路で VM と一致
- length/isEmpty/charCodeAt, Array.get, Map.size/has
- 境界: 署名不一致・未対応は VM フォールバック理由はイベントJSONに記録
- 箱: Policy/Events/Registry を 1 箇所参照(切替点の一本化)
- 観測: JSONL イベントが最小1件以上出力オプトイン
## 🧱 先に積む箱(最小)
- JitConfigBox設定
- exec/stats/dump/phi_min/hostcall/native_f64/native_bool/threshold を `apply()` でenv反映
- `toJson()/fromJson()/summary()` で可視化
- JitPolicyBoxポリシー
- read_only/hostcall_whitelist。書込系は既定で拒否jit-direct等の安全弁
- JitEventsBox観測
- compile/execute/fallback/trap を 1行JSON標準出力 or ファイル)で記録
- HostcallRegistryBoxレジストリ
- 許可HostCallと args/ret 署名(唯一の切替点)。不一致は `sig_mismatch`
- FrameSlotsBoxスロット
- ptr→slot の割付と型注釈v0は i64 のみ)
- CallBoundaryBox境界
- JIT↔VM の薄い呼出し点(型変換の一本化)。将来多関数へ拡張
最小原則: 箱を先に置くno-op/ログでもOK→ 切替点を1箇所に固定 → その箱の内部を順に強化。
## 🛣️ 実行経路の設計(概要)
1) Runner: CLI/env→`JitConfig`→TLSへ反映env直読を排除
2) LowerCore: `jit::config::current()` を参照し、BoxCall/Load/Store/Branch/PHIを最小下ろし
3) HostCall: Handle経由で read-only を通すmutating は Policy で拒否)
4) Fallback: 未対応/署名不一致/ポリシー違反は VM 実行へ委譲
5) Events: `JitEventsBox` 経由で allow/fallback/trap を JSONL 出力
## 🔢 対象APIv0
- ArrayBox: `length`, `get`, `isEmpty`, `push/set`mutatingは拒否
- MapBox: `size`, `has`, `get`, `set`mutatingは拒否
- StringBox: `length`, `isEmpty`, `charCodeAt`
- Math薄接続: `sin/cos/abs/min/max`(署名一致のみ allow を記録、実体はVMへ
## 🗺️ マイルストーン
### 10.9-α(足場)
- JitPolicyBox v0: read-only/whitelist を箱へ移動
- JitEventsBox v0: compile/execute の JSONL イベント(オプトイン)
- ドキュメント: 再起動チェック/箱の役割を追記
### 10.9-β(読み取りカバレッジ)
- HostcallRegistryBox v0: String/Array/Map 読み取り API の登録・署名検査
- LowerCore: BoxCall read-only 経路を Registry/Policy 参照に切替
- E2E: `length/isEmpty/charCodeAt/get/size/has` の一致jit-direct + VM
### 10.9-γ(生成の足場)
- CallBoundaryBox v0: JIT→VMで `new` 等を委譲(薄い箱)
- `new StringBox/IntegerBox/ArrayBox` の最小経路(方針次第で jit-direct は拒否)
### 10.9-δ(書き込みの導線のみ)
- JitPolicyBox: 書込許可スイッチ既定OFF
- LowerCore: 書込命令は Policy 参照で拒否/委譲/許可1箇所で判断
## ✅ すぐ使えるチェック
- ビルド
- `cargo build --release --features cranelift-jit`
- 主要フラグ
- `NYASH_JIT_EXEC=1` `NYASH_JIT_THRESHOLD=1`
- `NYASH_JIT_EVENTS=1`標準出力へJSON
- 任意: `NYASH_JIT_EVENTS_PATH=target/nyash/jit-events.jsonl`
- 代表サンプルVM経由でJITパス通過
- 成功: `./target/release/nyash --backend vm examples/jit_hostcall_len_string.hako`
- 失敗: `NYASH_JIT_EVENTS=1 ./target/release/nyash --backend vm examples/jit_hostcall_array_append.hako`
- 境界: `NYASH_JIT_EVENTS=1 ./target/release/nyash --backend vm examples/jit_hostcall_math_sin_mismatch.hako`
- 署名一致(allow観測): `NYASH_JIT_EVENTS=1 ./target/release/nyash --backend vm examples/jit_hostcall_math_sin_allow_float.hako`
- 関数スタイル(math.*): `NYASH_JIT_NATIVE_F64=1 NYASH_JIT_EVENTS=1 ./target/release/nyash --backend vm examples/jit_math_function_style_sin_float.hako`
- `cos/abs/min/max` も同様のサンプルあり
- 詰まったら
- `--features cranelift-jit` が付いているか
- イベントJSONに `fallback/trap` の理由が出ているか
- `cargo clean -p nyash-rust` → 再ビルド
## 🧪 検証と観測
- 統合JIT統計テキスト/JSON: sites/compiled/hits/exec_ok/trap/fallback_rate/handles
- `JitStatsBox.perFunction()` で関数単位の統計JSON配列
- CFG/PHIダンプ: `NYASH_JIT_DUMP=1``NYASH_JIT_DOT=path.dot`(最小)
- b1正規化カウンタ: `b1_norm_count`(分岐条件/PHI
- HostCallイベント: `argc`/`arg_types`/`reason`でデバッグ容易化mutatingは `policy_denied_mutating`
### 🔎 HostCallイベントの基準10.9-β)
- 受け手が関数パラメータparamの場合は JIT直実行allow/sig_okを基本にイベント出力
- Map.get(Handle, I64): `id: nyash.map.get_h`, `arg_types: ["Handle","I64"]`
- Map.get(Handle, Handle): `id: nyash.map.get_hh`, `arg_types: ["Handle","Handle"]`
- length/isEmpty/charCodeAt/size 等も `*_h`Handle受けでallow
- 受け手がparamでない場合は VMへフォールバックfallback/receiver_not_paramをイベントで記録読み取り系の可視化を保証
- 例: `id: nyash.any.length_h`, `decision: fallback`, `reason: receiver_not_param`
- 数値緩和: `NYASH_JIT_HOSTCALL_RELAX_NUMERIC=1` または `NYASH_JIT_NATIVE_F64=1``I64→F64` コアーションを許容sig_okに影響
### 🧪 代表サンプルE2E
```bash
# math.*(関数スタイル): 署名一致でallow、戻りFloat表示
NYASH_JIT_EXEC=1 NYASH_JIT_THRESHOLD=1 NYASH_JIT_NATIVE_F64=1 NYASH_JIT_EVENTS=1 \
./target/release/nyash --backend vm examples/jit_math_function_style_min_float.hako
# Map.getパラメータ受けHandleキー → HH直実行
NYASH_JIT_EXEC=1 NYASH_JIT_THRESHOLD=1 NYASH_JIT_HOSTCALL=1 NYASH_JIT_EVENTS=1 \
./target/release/nyash --backend vm examples/jit_map_get_param_hh.hako
# Map.get非パラメータ受け → fallback記録
NYASH_JIT_EXEC=1 NYASH_JIT_THRESHOLD=1 NYASH_JIT_HOSTCALL=1 NYASH_JIT_EVENTS=1 \
./target/release/nyash --backend vm examples/jit_hostcall_map_get_handle.hako
```
### ⚙️ Quick flagsイベント観測を確実に
- `NYASH_JIT_EVENTS=1` のとき Runner が `NYASH_JIT_THRESHOLD=1` を自動適用(未指定の場合)
- 1回目からLowerが走り、allow/fallbackのイベントが必ず出る
- 明示的に `NYASH_JIT_THRESHOLD` を指定した場合はそちらを優先
## ⚠️ リスクとその箱での緩和
- 署名不一致args/ret
- HostcallRegistryBox で一元検査。不一致は `sig_mismatch` でイベント記録→VMへ
- mutatingの混入
- JitPolicyBox.read_only で抑止。Registryの Mutating 分類と併用
- 型崩れ/ABIの揺れ
- `JitValue`I64/F64/Bool/Handleへ統一、変換は境界1箇所
- 観測不足
- JitEventsBox の粒度を最小から用意(必要に応じ拡張)
## 🔧 実装ノート(現状)
- Config: Rust側 `jit::config::JitConfig` に集約。Nyash側は JitConfigBox で操作
- LowerCore: BoxCallの read-only は Registry/Policyに委譲。math.* は署名一致なら allow を記録実行はVM
- Handle: `rt::handles` による u64→Arc<Box>。JIT↔ホストをVM型非参照で独立
- 数値緩和: `NYASH_JIT_HOSTCALL_RELAX_NUMERIC=1` で i64→f64 コアーションを許容(既定は `native_f64=1` 時に有効)。`JitConfigBox.set_flag("relax_numeric", true)` でも切替可能
## 📌 次の拡張10.9の後)
- f64ネイティブ最小経路`NYASH_JIT_NATIVE_F64=1`)の拡充
- Boolネイティブb1署名サポートツールチェーンcapに連動
- HostCallブリッジの拡大Map.getの多型キー、String操作の追加
- CallBoundaryBox経由の `new`/副作用命令の段階的JIT化
## ✳️ 10.9-δ 書き込みの導線(運用)
- 既定ポリシー: read_only`NYASH_JIT_READ_ONLY=1`)で mutating はフォールバック(`reason: policy_denied_mutating`)。
- JitPolicyBox でopt-in:
```nyash
P = new JitPolicyBox()
P.set("read_only", true)
P.addWhitelist("nyash.array.push_h") // 個別に許可
// またはプリセット:
P.enablePreset("mutating_minimal") // Array.push_h を許可
```
- イベント方針:
- 受け手=param: allow/sig_okwhitelist/オフ時はfallback/policy_denied_mutating
- 受け手≠param: fallback/receiver_not_param可視化を保証
---
最短ルート: 箱Policy/Events/Registry/Boundaryを先に置き、読み取り系でJITを安全に通す→観測を増やす→署名とポリシーの一本化で切替点を固定→必要最小限のネイティブ型f64/b1を段階導入。

View File

@ -0,0 +1,220 @@
# Phase 10: Classic C Applications Migration to Nyash
## 🎯 概要
3つの著名なCアプリケーションをNyashに移植し、新実装された高度なメモリ管理機能を実戦テストする。
## 📦 移植対象アプリケーション(優先順位順)
### 1. 🌐 **Tinyproxy** - ゼロコピー判定機能の実証
**元実装**: https://github.com/tinyproxy/tinyproxy
**サイズ**: ~5000行C、軽量HTTPプロキシサーバー
**Nyash移植目標**: `apps/tinyproxy_nyash/`
#### 🔍 **ゼロコピー判定テストケース**
```nyash
// HTTPリクエスト転送でのメモリ効率検証
static box ProxyServer {
init { upstream_buffer, downstream_buffer }
relay_data(client_data) {
// ⭐ ゼロコピー判定:バッファーが共有されているかチェック
if (me.upstream_buffer.is_shared_with(client_data)) {
console.log("✅ Zero-copy achieved!")
} else {
console.log("❌ Unnecessary copy detected")
}
// 大量データ転送での最適化確認
return me.upstream_buffer.share_reference(client_data)
}
}
```
#### 📋 **実装要件**
- HTTPプロキシの基本機能GET/POST転送
- `SocketBox`でのクライアント・サーバー接続
- `BufferBox`での効率的なデータ転送
- **ゼロコピー判定API**の実装・テスト
---
### 2. 🎮 **Chip-8エミュレーター** - fini伝播とweak生存チェック
**元実装**: https://github.com/mattmikolay/chip-8 (参考)
**サイズ**: ~1000行C、8ビットゲーム機エミュレーター
**Nyash移植目標**: `apps/chip8_nyash/`
#### 🔍 **メモリ管理テストケース**
```nyash
// CPU・メモリ・グラフィックスの相互参照関係でのfini伝播テスト
static box Chip8CPU {
init { memory, graphics, sound }
fini() {
// ⭐ fini伝播依存オブジェクトの自動クリーンアップ
console.log("🔄 CPU cleanup triggered")
me.memory.cleanup() // メモリバンクの解放
me.graphics.cleanup() // VRAM解放
}
}
static box Chip8Memory {
init { ram, weak_cpu_ref } // CPUへの弱参照
read_byte(address) {
// ⭐ weak生存チェックCPUがまだ生きているか確認
if (me.weak_cpu_ref.is_alive()) {
return me.ram.get(address)
} else {
console.log("⚠️ CPU destroyed, memory access blocked")
return null
}
}
}
```
#### 📋 **実装要件**
- Chip-8命令セット実装35命令
- 64x32ピクセルグラフィックス`WebCanvasBox`使用)
- サウンド出力(`SoundBox`使用)
- **fini伝播システム**と**weak参照**の実戦テスト
---
### 3. ✏️ **kilo テキストエディター** - 「うっかり全体コピー」検出
**元実装**: https://github.com/antirez/kilo
**サイズ**: ~1000行C、軽量ターミナルエディター
**Nyash移植目標**: `apps/kilo_nyash/`
#### 🔍 **メモリ効率テストケース**
```nyash
// 大きなテキストファイル編集での不必要なコピー検出
static box TextBuffer {
init { lines, undo_stack }
insert_char(row, col, char) {
local old_lines_size = me.lines.memory_footprint()
// 文字挿入操作
me.lines.get(row).insert_at(col, char)
local new_lines_size = me.lines.memory_footprint()
local size_diff = new_lines_size - old_lines_size
// ⭐ 「うっかり全体コピー」検出
if (size_diff > 1000) { // 1文字挿入で1KB以上増加
console.log("🚨 INEFFICIENT COPY DETECTED!")
console.log("Expected: 1 byte, Actual: " + size_diff + " bytes")
me.log_memory_leak_warning()
}
}
// 大規模な検索・置換での効率性チェック
search_and_replace(pattern, replacement) {
local initial_memory = me.lines.memory_footprint()
// 検索・置換実行
me.lines.replace_all(pattern, replacement)
local final_memory = me.lines.memory_footprint()
// メモリ使用量が2倍を超えた場合は問題
if (final_memory > initial_memory * 2) {
console.log("⚠️ Memory usage doubled during replace operation")
}
}
}
```
#### 📋 **実装要件**
- ターミナル操作(`ConsoleBox`での入出力)
- ファイル読み書き(`FileBox`使用)
- 基本的な編集機能(カーソル移動、挿入、削除)
- **メモリ効率監視**と**コピー検出システム**
---
## 🛠️ **技術的実装指針**
### 共通アーキテクチャ
```nyash
// 各アプリケーション共通の構造
static box AppName {
init { core_components }
main() {
me.initialize_components()
me.run_main_loop()
me.cleanup_resources()
}
// メモリ効率レポート(全アプリ共通)
memory_report() {
return new MapBox()
.set("zero_copy_count", me.zero_copy_operations)
.set("unnecessary_copies", me.detected_copies)
.set("memory_leaks", me.fini_failures)
.set("weak_ref_cleanups", me.weak_cleanup_count)
}
}
```
### 新API要件
1. **ゼロコピー判定API**
- `BufferBox.is_shared_with(other)` → BoolBox
- `BufferBox.share_reference(data)` → 参照共有
2. **fini伝播システム**
- 自動的な依存オブジェクトクリーンアップ
- クリーンアップチェーンの可視化
3. **weak参照システム**
- `WeakBox.is_alive()` → BoolBox
- 循環参照の自動検出・回避
4. **メモリ効率監視**
- `Box.memory_footprint()` → IntegerBox
- コピー発生の検出・警告
---
## 🎯 **期待される成果**
### パフォーマンス目標
- **Tinyproxy**: HTTP転送でのゼロコピー率 90%以上
- **Chip-8**: 60FPSエミュレーション + fini伝播の完全動作
- **kilo**: 1MB+ファイル編集でのメモリ効率 95%以上
### 学習効果
- **Copilot**: 大規模Nyashアプリケーション開発経験
- **開発者**: 新メモリ管理機能の実用性確認
- **コミュニティ**: Nyashでの実用アプリケーション事例
---
## 📅 **実装計画**
### Phase 10.1: Tinyproxy実装 (1週間)
- HTTPプロキシ基本機能
- ゼロコピー判定API実装・テスト
### Phase 10.2: Chip-8実装 (1週間)
- エミュレーター基本機能
- fini伝播・weak参照の実戦テスト
### Phase 10.3: kilo実装 (1週間)
- テキストエディター基本機能
- メモリ効率監視システム
### Phase 10.4: 統合テスト・最適化 (1週間)
- 3アプリケーション同時実行テスト
- パフォーマンス分析・改善
---
## 🚀 **この移植プロジェクトの意義**
1. **実用性の実証**: Nyashで実際のアプリケーションが作れることを証明
2. **新機能の検証**: ゼロコピー・fini・weakの実戦テスト
3. **開発体験の向上**: Copilotとの協調開発での生産性検証
4. **エコシステム拡充**: Nyashアプリケーションの具体例提供
**この移植が成功すれば、Nyashは「実用的なプログラミング言語」として確立されます** 🎉

View File

@ -0,0 +1,267 @@
# Phase 10: Cranelift JIT BackendMIR→VM→Cranelift
Status: Planned (Primary path for native speed)
Last Updated: 2025-08-25
## 🎯 ゴール
- 実行系の主経路を「MIR→VM」を維持しつつ、ホットパスをCraneliftでJIT化して高速化する。
- LLVM AOTは後段Phase 11以降の研究対象へ繰り延べ。
## 🔗 位置づけ
- これまでの案MIR→LLVM AOTを改め、現実的な開発速度と安定性を優先してCranelift JITを先行。
- VMとのハイブリッド実行OSR/ホットカウントに基づくJITを採用。
## 📐 アーキテクチャ
```
AST → MIR → Optimizer → VM Dispatcher
└─(Hot)→ Cranelift JIT (fn単位)
```
- VMが命令カウント・プロファイルを集計し、しきい値超過関数をJITコンパイル。
- JIT済み関数は関数テーブルから直接呼び出し、VMはフォールバック先として維持。
## 📋 スコープ
1) 基盤
- JITマネージャ関数プロファイル・コンパイルキャッシュ
- Craneliftコード生成MIR→CLIF Lower
- 呼出しABINyash VMスタック/レジスタとのブリッジ)
2) 命令カバレッジ(段階導入)
- Phase A: Const/Copy/BinOp/Compare/Jump/Branch/Return純関数相当
- Phase B: Call/BoxCall/ArrayGet/ArraySetホットパス対応
- Phase C: TypeOp/Ref*/Weak*/Barrier必要最小
3) ランタイム連携
- Boxの所有・参照モデルを維持共有/クローンの意味論を破らない)
- 例外・TypeErrorはVMの例外パスへエスケープ
## ✅ 受け入れ基準Milestone
- M1: 算術/比較/分岐/returnの関数がJIT化され、VMより高速に実行
- M2: Array/Mapの代表操作get/set/push/sizeがJITで安定動作
- M3: BoxCallホットパス特にArray/Mapで有意な高速化2×目標
- M4: 回帰防止のベンチと`--vm-stats`連携JITカウント/時間)
## 🪜 実装ステップ
1. JITマネージャ/関数プロファイルの導入VM統計と統合
2. MIR→CLIF Lower骨子基本型/算術/比較/制御)
3. 呼出しABIブリッジ引数/戻り値/BoxRefの表現
4. JIT関数テーブル + VMディスパッチ切替
5. Array/Map/BoxCallのホットパス最適化
6. TypeOp/Ref/Weak/Barrierの必要最小を実装
7. ベンチ/スナップショット整備・回帰検出
## ⚠️ 依存・前提
- MIR26整合TypeOp/WeakRef/Barrierの統合前提
- P2PBox再設計Phase 9.xを先に安定化しておくVM/プラグインE2E維持
## 📚 参考
- Cranelift: Peepmatic/CLIF、simple_jitの最小例
- JIT/VMハイブリッド: LuaJIT/HotSpotのOSR設計
---
備考: LLVM AOTはPhase 11以降の研究路線に移行設計ドキュメントは維持
## 🔬 Sub-Phases (10_a .. 10_h)
各サブフェーズは「小さく立ち上げ→検証→次へ」。既存のVM/Thunk/PICを活用し、JITは同じ経路に自然合流させる。
### 10_a: JITブートストラップ基盤プロファイラ
- 目的: Cranelift JITの骨組みとホット関数検出の導線を用意。
- 具体:
- `JitManager`(関数プロファイル、しきい値、キャッシュ)
- CLIF環境初期化`Module`, `Context`, `ISA`
- VM統合: 関数入口でホット度チェック→JITコンパイル/呼び出し
- 診断: `NYASH_JIT_STATS=1`JIT件数/時間/キャッシュヒット)
- 受入: ダミー関数をJIT登録してVMから呼出可能、ログが出る
### 10_b: Lower(Core-1) Const/Move/BinOp/Cmp/Branch/Ret
- 目的: ループや条件分岐を含む純粋関数をJIT実行可能に。
- 具体:
- MIR値/型→CLIF型i64/f64/i1/void
- Const/Copy/算術/比較/ジャンプ/分岐/return のLower
- フレームレイアウトVMValue最小表現
- 受入: 算術/比較/分岐のみの関数がJITでVMより速い小ベンチ
### 10_c: ABI/呼出し 関数呼び出しとフォールバック
- 目的: JIT化関数から他関数を呼ぶ/VMへ戻る道を用意。
- 具体:
- 同一モジュール関数呼び出しJIT→JITJIT→VM
- 引数/戻り値の受け渡し(整数/浮動/void
- 例外/TypeErrorはVMへバイアウトtrap→VM
- 受入: 再帰/多段呼び出しが安定動作
### 10_d: コレクション基礎 Array/Map ホット操作(外部呼び出し)
- 目的: 実用的ホットパスlength/get/set/push/popをJIT側から呼べるように。
- 具体:
- ホスト関数テーブル外部シンボルで既存Rust実装を呼ぶ
- 境界チェック/エラーはRust側に委譲、JITは薄い橋渡し
- 受入: Array操作がVM経由より高速目安1.52.0×
Status2025-08-27
- Param経路でのE2Eを実装`NYASH_JIT_HOSTCALL=1`ゲート)
- 実装済みシンボルPoC, C-ABI in Rust:
- `nyash.array.{len,push,get,set}` / `nyash.map.size`
- 使い方(例):
```bash
cargo build --features cranelift-jit --release
NYASH_JIT_THRESHOLD=1 NYASH_JIT_HOSTCALL=1 NYASH_JIT_EXEC=1 \
./target/release/nyash --backend vm examples/jit_array_param_call.hako
NYASH_JIT_THRESHOLD=1 NYASH_JIT_HOSTCALL=1 NYASH_JIT_EXEC=1 \
./target/release/nyash --backend vm examples/jit_map_param_call.hako
```
Notes
- 関数パラメータに渡した配列/MapのみHostCall経由でアクセスthread-local引数参照
- ローカルnew値は10_eへ移管ハンドル表PoC: u64→Arc<Box>
### 10_e: BoxCall高速化 Thunk/PICの直結
- 目的: Phase 9.79bの `TypeMeta{slot->thunk}` と Poly-PIC をJITにインライン。
- 具体:
- `slot -> thunk -> target` 解決をJITで再現ユニバーサル0..3含む)
- `(type_id, version)` チェックPoly-PIC 24件→ヒット直呼び、ミスVM
- バージョンミスマッチで安全にフォールバック
- 受入: BoxCallホットサイトで2×以上の高速化正しい無効化挙動
### 10_f: TypeOp/Ref/Weak/Barrier最小
- 目的: 実アプリで必要な最小限のタイプ/参照操作を埋める。
- 具体:
- `as_bool()` 等の基本型変換
- 参照/弱参照/バリアの最小パス重い経路はVMへ
- 受入: 代表的コードパスでJIT有効のままE2E成功
### 10_g: 診断/ベンチ/回帰
- 目的: 可視化と安定化。
- 具体:
- `--vm-stats` にJIT統計統合compile/ms, sites, cache率
- ベンチ更新JIT有/無比較)とスナップショット
- 受入: CIで回帰検知可能ドキュメント更新
### 10_h: 硬化・パフォーマンス調整
- 目的: ホットスポットの最適化とノイズ除去。
- 具体:
- ガード配置最適化(分岐予測/ICヒット優先
- 不要コピー削減、ホスト呼出回数の削減
- 受入: 代表ベンチで安定して目標達成2×以上
## 📦 成果物(各サブフェーズ)
- 10_a: `jit/manager.rs` スケルトン、VM連携、統計ログ
- 10_b: `jit/lower/core.rs`Const/BinOp/Cmp/Branch/Ret単体テスト
- 10_c: `jit/abi.rs`call/ret/fallback再帰テスト
- 10_d: `jit/extern/collections.rs`Array/Mapブリッジマイクロベンチ
- 10_e: `jit/inline_cache.rs`PIC/VT連携無効化テスト
- 10_f: `jit/lower/typeop_ref.rs`(最小)
- 10_g: ベンチ/統計/README更新
- 10_h: 最適化コミットと測定レポート
## 🧩 既存資産との連携(重要)
- Thunk: Phase 9.79b.3の `TypeMeta{thunks}` をJIT直呼びターゲットとして使用
- Poly-PIC: VMの構造をJITに投影同じキー `(label, version)` を使用)
- Versioning: `cache_versions` のイベントに同期してIC無効化
## 🎯 マイルストーン再定義
- M1: 10_a + 10_b 合格Core関数のJIT実行
- M2: 10_c + 10_d 合格(関数呼出/Arrayホット操作
- M3: 10_e 合格BoxCallホットパス2×
- M4: 10_g + 10_h 合格(ベンチ/統計/硬化)
## ⚠️ リスクと緩和
- ABI複雑化: まず整数/浮動/voidに限定し、BoxRefはホスト関数へブリッジ
- 最適化過剰: 常にVMフォールバックを保持、ガード失敗で安全に戻す
- デバッグ困難: CLIFダンプ/CFG表示/`NYASH_JIT_STATS`で観測
## 🐛 発見した問題点2025-08-27 ベンチマーク実行時)
### 1. インタープリター性能問題
- **問題**: 10万回のループで2分以上かかりタイムアウト
- **原因**: `unwrap_instance`のデバッグログが大量出力毎回の演算でInstanceBoxチェック
- **目標**: 10万回ループを数秒で完了
- **対策**:
- デバッグログの条件付き出力化
- 基本演算の高速化IntegerBoxの直接操作最適化
### 2. VMの変数管理エラー
- **問題**: `Invalid value: Value %47 not set` - simple_add_loop内の変数zが正しく管理されていない
- **原因**: MIR生成時の変数スコープ管理の不具合
- **対策**: MirBuilderの変数トラッキング改善
### 3. Box APIの成熟度
- **問題**: TimeBoxにelapsed()/reset()メソッドがインタープリターから呼べない
- **原因**: Boxメソッドの登録システム未完成
- **対策**:
- Boxメソッドの統一的登録システム実装
- インタープリターとVMのメソッド解決統一
### 4. ベンチマーク基盤
- **問題**: Nyashスクリプトでの正確な時間計測が困難
- **根本原因**: TimeBoxのelapsed()/reset()メソッドがインタープリターから呼べないBox API問題と同じ
- **対策**: Box APIの成熟度問題問題3が解決すれば自動的に解決
### 改善優先度
1. **高**: インタープリター性能問題(基本機能の使い物にならない)
2. **中**: VM変数管理JIT最適化の前提
3. **中**: Box APIの成熟度ベンチマーク基盤も同時解決
## 🚀 Phase 10.9: Cranelift AOT Backend追加計画
Status: Future (JIT実装の上乗せで実現可能)
### 概要
JIT実装10_a10_hで構築したMIR→CLIF変換基盤をそのまま活用し、事前コンパイルAOTによるスタンドアロン実行ファイル生成を実現する。
### 利点
- **コード再利用**: JITと同じLowerCore実装を使用追加実装最小
- **非同期完全サポート**: WASMの制限なし、ネイティブ非同期可能
- **最高性能**: ネイティブコード直接実行(起動時コンパイル不要)
- **デバッグ容易**: gdb/lldb等のネイティブデバッガ使用可能
### 実装ステップ案
```
10.9a: ObjectModule統合
├── cranelift-objectモジュール導入
├── CLIF→オブジェクトファイル生成
└── 既存のLowerCore再利用
10.9b: ランタイムライブラリ
├── Nyash標準Box群の静的リンク版作成
├── プラグインの静的埋め込み対応
└── 最小ランタイムGC hooks等分離
10.9c: リンカー統合
├── cc/ldによる実行ファイル生成
├── プラットフォーム別設定
└── デバッグシンボル生成
10.9d: クロスコンパイル
├── 複数ターゲットx86_64/aarch64/wasm32
├── ターゲット別最適化
└── CI/CDでのマルチプラットフォームビルド
```
### 使用イメージ
```bash
# ネイティブ実行ファイル生成
./target/release/nyash --compile-native program.hako -o program
./program # スタンドアロン実行!
# クロスコンパイル
./target/release/nyash --compile-native --target x86_64-pc-windows-msvc program.hako -o program.exe
./target/release/nyash --compile-native --target aarch64-apple-darwin program.hako -o program.mac
```
### 技術的詳細
- **共通基盤**: `LowerCore`のemit処理はJIT/AOT両対応
- **差分実装**: JITは`JITModule`、AOTは`ObjectModule`を使用
- **リンク方式**: 静的リンク優先(配布容易性重視)
- **サイズ最適化**: LTO/strip対応で実行ファイルサイズ削減
### WASM AOTとの比較
| 特性 | Cranelift AOT | WASM AOT |
|------|--------------|----------|
| 非同期 | ✅ 完全対応 | ❌ 制限あり |
| 実行速度 | 最速 | 速い |
| ファイルサイズ | 大MB級 | 小KB級 |
| ポータビリティ | プラットフォーム別 | 高い |
| デバッグ | ネイティブツール | 限定的 |
### 想定スケジュール
- Phase 10JIT安定化後に着手
- 実装期間: 2-3週間JIT基盤の再利用により短期実現可能
- 初期ターゲット: Linux x86_64、その後Windows/macOS対応

View File

@ -0,0 +1,72 @@
# Phase 10: Function Declaration MIR サポート課題
作成日: 2025-08-27
発見者: Claude & ChatGPT5 & ニャー
## 🚨 現在の問題
### 症状
```bash
❌ MIR compilation error: Unsupported AST node type: FunctionDeclaration
```
### 影響範囲
- 通常の`function`定義がMIRでコンパイルできない
- JITテストで関数を使った配列操作ができない
- Static Boxメソッドは動作するが、通常関数が使えない
### 具体例
```nyash
// ❌ 動作しない - FunctionDeclarationがMIR未対応
function len_of(arr) {
return arr.length()
}
// ✅ 動作する - Static Boxメソッド
static box Utils {
len_of(arr) {
return arr.length()
}
}
// ✅ 動作する - 直接呼び出し
local arr = new ArrayBox()
local len = arr.length()
```
## 🔧 解決案
### Option 1: MIRビルダーにFunctionDeclaration対応追加
```rust
// mir/builder.rs に追加
AstNode::FunctionDeclaration { name, params, body, .. } => {
// 関数をMirFunctionとして登録
let mir_func = self.build_function(name, params, body)?;
self.functions.insert(name.clone(), mir_func);
}
```
### Option 2: ASTレベルでStatic Boxに変換
- FunctionDeclarationを内部的にStatic Boxメソッドに変換
- 互換性を保ちつつ既存の仕組みを活用
### Option 3: 当面の回避策を公式化
- ドキュメントで「VMモードではStatic Boxメソッドを推奨」と明記
- 将来のサポートとして計画に含める
## 📊 優先度評価
- **重要度**: 中(基本的な言語機能だが回避策あり)
- **緊急度**: 低Static Boxで代替可能
- **実装難度**: 中MIRビルダーの拡張が必要
## 🎯 推奨アクション
1. **短期**: Static Boxメソッドを使った回避策をドキュメント化
2. **中期**: Phase 10.1でFunctionDeclaration対応を実装
3. **長期**: 関数定義の最適化(インライン化等)も検討
## 📝 関連イシュー
- JIT配列操作テスト
- MIRビルダー拡張
- 言語仕様の完全性

View File

@ -0,0 +1,35 @@
Phase 10 — GC/Thread Roadmap Order (txt)
Recommended order:
10_4a → 10_4b → 10_6a → 10_4c → 10_4d → 10_6b → 10_6c
10_4a: GC hook scaffolding
- Add GcHooks { safepoint(), barrier(kind) } and BarrierKind.
- NyashRuntime holds Arc<dyn GcHooks>; builder supports with_gc_hooks.
- VM calls hooks at MIR Safepoint/Barrier*.
10_4b: Roots + minimal barriers
- ScopeTracker root API: enter_root_region/leave_root_region/pin_root.
- Write-Barrier at RefSet/ArraySet/BoxCall(Array/Map: set/push).
- Tracing flags: NYASH_GC_TRACE=1 for barrier/safepoint and roots.
10_6a: Thread-safety audit (prep)
- Audit Builtin/User/Plugin boxes for Send/Sync policy.
- Strategy for shared state (RwLock) and non-thread-safe wrappers.
10_4c: GC PoC (STW, single-thread)
- Implement simple collector behind GcHooks (e.g., mark-sweep or RC hybrid).
- Manage roots via ScopeTracker; traverse VMValue graph/object_fields.
10_4d: Barrier hardening + regression
- Ensure coverage for all mutating write sites (Array/Map/Ref/Plugin paths).
- Strict checks flag for development; add stress/regression tests.
10_6b: Thread runtime scaffolding
- Scheduler abstraction (cooperative preemption), Future/Channel compliance.
- Confirm GcHooks is Send+Sync and shareable.
10_6c: Parallel GC design notes
- Per-thread root regions, card marking/write barriers, safepoint coordination.
- Document design and API diffs for later implementation.