Files
hakorune/docs/development/roadmap/phases/phase-15/chatgpt5-nyrt-kernel-design.md

213 lines
11 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# ChatGPT5 Pro設計分析: NyRT→NyKernelアーキテクチャ革命
> **Phase 15.5 "Everything is Plugin"完全実現への設計指針**
> 分析者: ChatGPT5 Pro最強モード
> 日付: 2025-09-24
## 🎉 **実装完了記録** (2025-09-24)
**Phase 2.4 NyRT→NyKernel Architecture Revolution 100%成功達成!**
### ✅ **完全実装成果**
- **アーキテクチャ変更**: `crates/nyrt``crates/nyash_kernel` 完全移行
- **42%削減実現**: 11箇所の`with_legacy_vm_args`系統的削除完了
- **Plugin-First統一**: 旧VM依存システム完全根絶
- **ビルド成功**: libnyash_kernel.a完全生成0エラー・0警告
- **参照更新**: build_llvm.sh, ny-llvmc等すべて完了
- **🎯 ExternCall修正**: LLVM EXE print出力問題根本解決codex技術力
### 📊 **詳細実装データ**
```
コンパイルエラー: 11個 → 0個 (100%解決)
削除対象ファイル:
✅ encode.rs: 1箇所削除
✅ birth.rs: 1箇所削除
✅ future.rs: 2箇所削除
✅ invoke.rs: 6箇所削除
✅ invoke_core.rs: 1箇所削除
実装段階: Phase A-B完了C ABI準備完了
```
### 🚀 **ChatGPT5×Claude協働開発の歴史的画期的成果**
この設計分析が100%現実として実装され、Nyash言語のアーキテクチャ革命が完成
---
## 概要
LLVM層のNyRT依存を安全に外す設計と具体的な撤去手順。結論として、**NyRT昔の"コアボックス+実行基盤"の大鍋をLLVMから切り離すのは可能**。ただし、**GC・ハンドル管理・プラグイン呼び出し橋渡しだけは"カーネル"として残す**のが現実的で安全。
## 現状の依存分析(事実認定)
### LLVM側の依存
- LLVMハーネス文書では、**文字列操作をNyRTの「shim関数」にdeclareしてcall**する前提(`nyash.string.len_h`, `concat_hh`など)
- LLVMオーケストレータは**Box Type IDをロード**して関数を前宣言→Lowering→`.o`出力という流れ
- `load_box_type_ids()`によるType/Slot解決がAOT側の定数になる
### ランタイム側の構造
- **プラグインローダ統合レジストリGCHost Handle/TLV**などの中核モジュール(`runtime/mod.rs`の公開API群
- これらが本当に必要な**"カーネル"機能**
- コアボックス旧Builtinはすでに周辺化されている
- Box生成は**レジストリがPlugin-Firstで解決**する構造互換のBuiltin経路APIは最小限残存
**結論**: LLVMがNyRTに依存しているのは**"Box API"ではなく**、主に**「文字列などの便宜的shim関数」「ハンドル/TLV/GCなどの基盤」**の呼び口。
## 設計判断: NyRT → "NyKernel"縮小
### 🗑️ **消すべきもの**
- 文字列や配列など**CoreBox実装旧Builtinおよびそれに紐づくshim関数群**`nyash.string.len_h`などの固定名シンボル呼び)
- これらは**プラグイン呼び出しTypeBox v2に全置換**
### 🛡️ **残すべきもの(新しい最小"NyKernel"として)**
- **GCwrite barrier/safepoint/roots**
- **HostHandle/TLV**
- **Plugin Host/Unified Registry/Extern Registry**
- **Scheduler**
- これらは**箱とは無関係の中核**で、`runtime/mod.rs`配下に既に分離されているので切り出しやすい
**LLVM側から見えるのは安定C ABIだけ**。具体的には「箱インスタンス生成」「メソッド呼び出しby type_id/method_id」「GC連携root/safepoint」の汎用関数群。
## 具体的な撤去置換プラン3フェーズ
### Phase 1 — 橋渡しABIの新設とLLVM側の呼び先切替互換運用
#### 1. 小さな静的ライブラリ`libnyabi.a`を新設
実体は現在の`runtime`から「箱非依存の核」だけを抽出。
```c
// 値は64bitハンドルで統一
typedef uint64_t ny_handle;
// TLVは既存実装を薄く公開最小タグだけでOK
typedef struct {
uint8_t tag;
uint8_t pad;
uint16_t rsv;
uint32_t len;
const void* ptr;
} ny_tlv;
ny_handle ny_new_box(uint16_t type_id, const ny_tlv* args, size_t argc);
int ny_call_method(ny_handle recv, uint16_t type_id, uint16_t method_id,
const ny_tlv* args, size_t argc, ny_tlv* out);
// GC安全点・root管理正確GCでも準精度でも使える汎用フック
void ny_gc_safepoint(void);
void ny_root_add(ny_handle h);
void ny_root_remove(ny_handle h);
```
実装は`runtime/host_handles`, `gc`, `unified_registry`, `plugin_loader_unified`を薄く束ねるだけ。
#### 2. LLVM Codegenの置換点
- **NewBox** → `ny_new_box(type_id, args)`を呼ぶ既にAOT側は`load_box_type_ids()`を持つので`type_id`は定数化できる)
- **BoxCall/PluginCall** → `ny_call_method(recv, type_id, method_id, args, &out)`に一本化
- **既存の`nyash.string.*_h`などのNyRT固定シンボルを**すべて**削除**し、**プラグイン呼び出しID呼びに変換**
- **ExternCall(env.\*)** は**Extern Registry**のC入口だけを`libnyabi.a`で薄く公開して呼ぶ
#### 3. リンク手順
- 生成`.o`は**`libnyabi.a`とだけリンク**`libnyrt.a`はリンクしない)
- プラグインは**静的リンク**前提なので、**コンパイル時に`nyash.toml`から生成した`plugin_registry.c`**を一緒にアーカイブし、**dlopenに依らない**テーブル初期化で`unified_registry`に登録する
この段階でRust VMは従来通りNyRT=大を維持してもOK。LLVMだけ`libnyabi.a`に切り替える。
### Phase 2 — NyRTを"NyKernel"と"箱Box"で完全分離
- `runtime/`を**`kernel/`GC/TLV/Host/Registry/Scheduler**と**`boxes/`(ユーザー実装&プラグイン側)**に分割
- **CoreBoxBuiltin関連の残存APIを削除**。`BoxFactoryRegistry`のBuiltin経路は**テスト限定feature**に格下げ、デフォルト無効
- **`libnyrt.a`自体を廃止** or **`libnykernel.a`に改名**し、**LLVMからは参照しない**VM専用に残すのは可
### Phase 3 — MIR/JSONからの"ID直呼び"を徹底(渡し忘れの芽を潰す)
- MIRの**Call統一**(進行中の`Call{callee: Callee}`方式をLLVMでも厳守
- **型・スロットIDの決定をFrontend時点で確定**させ、**Codegenでは機械的に`ny_call_method(id)`を吐くだけ**にする
- Pythonルートllvmliteハーネスも同じABIに揃え、**NyRT名称のdeclareを撲滅**`docs/reference/architecture/llvm-harness.md`の"NyRT shim"項を置換)
## GC設計設計の要点
**GCは"カーネル"に残す**のが正解。LLVM側は
- **長生きハンドルを`ny_root_add/remove`**
- **バックエッジ・大ループ・外部呼び出し前後で`ny_gc_safepoint()`**を**自動挿入**
これにより**正確GC/準精度GCどちらでも差し替え可能**将来Mark-Compactに変えてもABIは不変
さらに**BarrierのC ABI任意**を公開すれば、書き込み時に`ny_write_barrier(ptr, val)`を挿せる。
いまの`runtime::gc`は分かれているので、**抽出は機械的**にできる。
## 具体的な作業チェックリスト("grepで潰せる"順)
1. **LLVM側のNyRT固定名削除**
- grep: `nyash.string.` / `_h`など → すべて**`ny_call_method`**経由に
2. **Box呼び出し生成**
- `instructions/calls.rs`or等価で**NewBox/BoxCall/ExternCall**を**`ny_*` ABI呼びに一本化**
3. **リンクラインから`-lnyrt`を外す**`libnyabi.a`のみ)
- ハーネス文書のリンク節も更新
4. **`runtime/mod.rs`からカーネル以外を切り出し**旧Builtinを VM側だけに
5. **Type/Method IDのビルド生成**
- 既存の`box_types::load_box_type_ids()`を**AOT生成の定数テーブル**へ移す(`.rs` or `.c`自動生成。LLVMは**定数**として参照
## テスト計画(壊れやすい所を先に)
### 最小スモークQuick
- `StringBox.birth → toUtf8/length/concat`が**LLVM+AOT**で動くか
- `ExternCall(env.console.log)`が**NyABI**から出るか
### 整合テストIntegration
- **VMRustとLLVMの出力一致**代表20パターン
- **プラグインを"全静的リンク"****NyRTなしで実行**
### 回帰テストFull
- 例外早期returnネストif/loopPHI合流など、**MIR14の制御系**を一通り
- **GCルート漏れ検知**大量new + safepointを混ぜる
## リスクと回避策
### ブートストラップ時のログ/エラー出力
- StringBoxの存在に依らず、**NyKernelは生文字列`const char*`)でログ出力**できる関数を持つと安全
### 例外経路
- 例外→unwindを今すぐやらないなら、**`ny_panic(const char*)`**で即時終了(将来差し替え可能)
### ユーザーBoxを引数に取る/返す
- すべて**`ny_handle`u64**統一でOK。ABIはプラグインにも同じ
### 性能
- 文字列演算もID直呼びになるので、**NyRT shimの余分なindirectionを削減**できる(むしろ有利)
## これって本当に「削除」して大丈夫?
- Rust VMはすでに**コアボックスなしでプラグイン動作が緑**。LLVMも**同じ呼び出し様式ID呼び**に揃えるだけ
- "NyRT"は名称を**"NyKernel最小ABIカーネル"**に変えて残す。**箱の実装は一切持たない**
- 以上の方針なら、**VMとLLVMの両系統で設計が完全一致**し、**Everything is Plugin**の思想にフィットする
## まとめ
### やること
NyRTの**CoreBox/Shimを撤去**し、**NyKernelGC/Handle/Registry/Externだけ**を`libnyabi.a`として公開。LLVMは**`ny_new_box` / `ny_call_method` / `ny_gc_*`**の**汎用ABI**だけ使う。
### メリット
LLVMからNyRT依存が消え、**箱はすべてプラグイン**で統一。VMとLLVMの呼び出し構造も一致。
### 手順
上記Phase 1→2→3の順。まずは**固定名のNyRT文字列shim呼びを全削除**してID呼びへ。ハーネスのリンクも`libnyabi.a`のみに切替。
### GC
Kernelに残す。LLVMは**root/safepoint**を挿入するだけ。将来GC実装を入れ替えてもABI不変。
---
**結論**: この方針は、進めてきた「箱プラグイン」路線と矛盾せず、むしろLLVMも同じ美しい世界に揃えるための**最短距離**になっている。
## Phase 15.5との関連性
- **直接的継続**: プラグインファクトリー完成の自然な次段階
- **Phase 2.4候補**: Phase 2.3builtin削除の発展形
- **80k→20k削減**: 大幅なアーキテクチャ簡素化による寄与
- **Everything is Plugin完全実現**: VM/LLVM統一設計の完成