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:
61
docs/archive/roadmap/phases/phase-10/README.md
Normal file
61
docs/archive/roadmap/phases/phase-10/README.md
Normal 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/) - 中間表現
|
||||
94
docs/archive/roadmap/phases/phase-10/phase_10_10/README.md
Normal file
94
docs/archive/roadmap/phases/phase-10/phase_10_10/README.md
Normal 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/Boundary(10.9-β/δ完了)
|
||||
- JITイベント: `NYASH_JIT_EVENTS=1` 時に `threshold=1` 自動適用でLower確実実行
|
||||
- 戻り境界: CallBoundaryBox で JitValue→VMValue を一元化(ハンドル復元含む)
|
||||
|
||||
## ワークストリーム
|
||||
1) GC Switchable Runtime(phase_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 System(phase_10_8_unified_debug_system.md)
|
||||
- 目標: デバッグ/観測フラグを DebugConfig/Box に統合(CLI/env/Boxの単一路)
|
||||
- タスク:
|
||||
- DebugConfig(Rust側): 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切替とバリアサイト観測が可能
|
||||
- HostCall(RO/一部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-in(Array.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は十分カバー(追加不要)
|
||||
```
|
||||
@ -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`.
|
||||
|
||||
What’s 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).
|
||||
|
||||
@ -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.
|
||||
|
||||
@ -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 ABI(fat 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
|
||||
@ -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`.
|
||||
|
||||
What’s 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.
|
||||
|
||||
@ -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
|
||||
|
||||
未確認/注意:
|
||||
- プラグインBox(PluginBoxV2)の内部FFIハンドルはVM/EXE側で共有参照のみ(実体はFFI側)。クロススレッド呼出しは未サポート運用(明記要)。
|
||||
- 一部のBoxで外部資源(ファイル/ネット)を扱う場合、スレッド越境のI/O同期設計は別途(Phase 10.6d+)。
|
||||
|
||||
## 次の一手(提案)
|
||||
- マーカーTraits(例: `ThreadSafeBox`)の導入は保留(破壊的)。現時点は監査+ドキュメントで運用。
|
||||
- 並列スケジューラ(M:N)の実装は `feature` フラグで段階導入。
|
||||
@ -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).
|
||||
|
||||
@ -0,0 +1,25 @@
|
||||
Phase 10.6b — Scheduler Prep (Single-Thread Queue)
|
||||
|
||||
What’s 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.
|
||||
@ -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.
|
||||
|
||||
@ -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.
|
||||
|
||||
135
docs/archive/roadmap/phases/phase-10/phase_10_7_master_plan.txt
Normal file
135
docs/archive/roadmap/phases/phase-10/phase_10_7_master_plan.txt
Normal 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 (1–2 days)
|
||||
- 10.7c: Host-handle registry PoC (1–2 days)
|
||||
- 10.7d/e: Hostcall coverage + CFG DOT (2–3 days)
|
||||
- 10.7f: JitConfigBox + integration (1 day)
|
||||
- 10.7g/h: QA + type widening for f64/bool (2–4 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.
|
||||
@ -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
|
||||
@ -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
|
||||
|
||||
@ -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 - 統一されたデバッグ体験へ*
|
||||
@ -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の明示的デリゲーションの象徴*
|
||||
@ -0,0 +1,155 @@
|
||||
# Phase 10.9 – Builtin-Box JIT Support(Box-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 出力
|
||||
|
||||
## 🔢 対象API(v0)
|
||||
- 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_ok(whitelist/オフ時はfallback/policy_denied_mutating)
|
||||
- 受け手≠param: fallback/receiver_not_param(可視化を保証)
|
||||
|
||||
---
|
||||
|
||||
最短ルート: 箱(Policy/Events/Registry/Boundary)を先に置き、読み取り系でJITを安全に通す→観測を増やす→署名とポリシーの一本化で切替点を固定→必要最小限のネイティブ型(f64/b1)を段階導入。
|
||||
220
docs/archive/roadmap/phases/phase-10/phase_10_app_migration.md
Normal file
220
docs/archive/roadmap/phases/phase-10/phase_10_app_migration.md
Normal 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は「実用的なプログラミング言語」として確立されます!** 🎉
|
||||
@ -0,0 +1,267 @@
|
||||
# Phase 10: Cranelift JIT Backend(MIR→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)
|
||||
- 呼出しABI(Nyash 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→JIT/JIT→VM)
|
||||
- 引数/戻り値の受け渡し(整数/浮動/void)
|
||||
- 例外/TypeErrorはVMへバイアウト(trap→VM)
|
||||
- 受入: 再帰/多段呼び出しが安定動作
|
||||
|
||||
### 10_d: コレクション基礎 – Array/Map ホット操作(外部呼び出し)
|
||||
- 目的: 実用的ホットパス(length/get/set/push/pop)をJIT側から呼べるように。
|
||||
- 具体:
|
||||
- ホスト関数テーブル(外部シンボル)で既存Rust実装を呼ぶ
|
||||
- 境界チェック/エラーはRust側に委譲、JITは薄い橋渡し
|
||||
- 受入: Array操作がVM経由より高速(目安1.5–2.0×)
|
||||
|
||||
Status(2025-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 2–4件)→ヒット直呼び、ミス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_a~10_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 10(JIT)安定化後に着手
|
||||
- 実装期間: 2-3週間(JIT基盤の再利用により短期実現可能)
|
||||
- 初期ターゲット: Linux x86_64、その後Windows/macOS対応
|
||||
@ -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ビルダー拡張
|
||||
- 言語仕様の完全性
|
||||
@ -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.
|
||||
|
||||
Reference in New Issue
Block a user