docs: restore docs/private/roadmap from 7b4908f9 (Phase 20.31)
This commit is contained in:
504
docs/private/roadmap/phases/phase-15/README.md
Normal file
504
docs/private/roadmap/phases/phase-15/README.md
Normal file
@ -0,0 +1,504 @@
|
||||
# Phase 15: Nyashセルフホスティング - 世界一美しい箱の完成
|
||||
|
||||
## 📋 概要
|
||||
|
||||
NyashでNyashコンパイラを書く、完全なセルフホスティングの実現フェーズ。
|
||||
MIR 13命令の美しさを最大限に活かし、外部コンパイラ依存から完全に解放される。
|
||||
**究極の目標:80,000行→20,000行(75%削減)→ さらなる最適化へ**
|
||||
|
||||
## 🔄 2025‑09‑26 Update(方針の明確化)
|
||||
- 実行系の優先順位: LLVM は Python/llvmlite ハーネスを主経路に固定(llvm_sys 依存は前提にしない)。Rust VM/JIT は保守最小・比較用。
|
||||
- パーサ: TokenCursor 統一を env ゲート下で進行。Step‑2/3(式+主要文の薄ラッパ)完了、代表スモーク/パリティは緑。
|
||||
- PHI: if/else の incoming は「実際の遷移元(exit ブロック)」を使用する規約で統一。dev 検証を追加(pred 重複/自己参照/CFG 包含)。
|
||||
- ループPHI: `phi_core` に統合(IncompletePhi/スナップショット/exit PHI の責務集約)。`loop_builder.rs` は委譲化で軽量化。
|
||||
- 次の主タスク: Nyash 製 JSON ライブラリ(JSON v0 DOM: parse/stringify)。完了後に Ny Executor(最小命令)へ直行。
|
||||
- 既定挙動は不変。新経路はすべて env トグルで opt‑in。
|
||||
|
||||
## 🔄 2025‑10‑02 Update(PyVM 撤退・LLVM本流)
|
||||
- 実行系の既定は Rust VM(MIR)と LLVM(llvmlite ハーネス)。
|
||||
- PyVM は撤退(既定OFF)。互換確認が必要な場合のみ `--features pyvm-bridge` を明示してビルドし、`NYASH_VM_USE_PY=1` で起動する。
|
||||
- パリティ検証は LLVM ハーネス基準に一本化。PyVM はローカル限定の互換用途に留める。
|
||||
|
||||
推奨トグル
|
||||
- `NYASH_LLVM_USE_HARNESS=1`(LLVM Python ハーネス)
|
||||
- `NYASH_PARSER_TOKEN_CURSOR=1`(TokenCursor 経路)
|
||||
- `NYASH_JSON_PROVIDER=ny`(Ny JSON ライブラリ)
|
||||
- `NYASH_SELFHOST_EXEC=1`(Ny Executor 最小経路)
|
||||
|
||||
## 🎯 フェーズの目的
|
||||
|
||||
1. **完全なセルフホスティング**: NyashコンパイラをNyashで実装
|
||||
2. **外部依存の排除**: gcc/clang/MSVC不要の世界
|
||||
3. **Everything is Box哲学の完成**: コンパイラもBox
|
||||
4. **エコシステムの自立**: Nyashだけで完結する開発環境
|
||||
5. **劇的なコード圧縮**: 75%削減で保守性・可読性の革命
|
||||
|
||||
## 🚀 実装戦略(2025年9月更新・改定)
|
||||
|
||||
### Self‑Hosting 優先(Phase‑15 基礎固め)
|
||||
- 目的: Nyash製パーサ/言語機能/Bridge整合/パリティを完成させ、自己ホスト c0→c1→c1' を達成する。
|
||||
- 運用:
|
||||
- Runner から `NYASH_USE_NY_COMPILER=1` を推奨(子プロセス実行→JSON v0→Bridge→MIR 実行)。
|
||||
- EXE化は任意の実験導線として維持(配布は Phase‑15 の外)。
|
||||
- PyVM は参照実行器として意味論検証に用い、パリティ監視を継続。
|
||||
|
||||
### [Historical] Phase 15.2: LLVM(llvmlite)安定化 + PyVM導入
|
||||
(注)2025‑10‑02 の撤退により PyVM は互換モードのみ。現行は LLVM/Rust VM を主経路に統一。
|
||||
- JIT/Cranelift は一時停止(古い/非対応)。Rust/inkwell は参照のみ。
|
||||
- 既定のコンパイル経路は **Python/llvmlite**(harness)のみ
|
||||
- MIR(JSON) → LLVM IR → .o → NyRTリンク → EXE
|
||||
- Resolver-only / Sealed SSA / 文字列ハンドル不変 を強化
|
||||
- 新規: **PyVM(Python MIR VM)** を導入し、2本目の実行経路を確保(現在は撤退済み・互換モードのみ)
|
||||
- 最小命令: const/binop/compare/phi/branch/jump/ret + 最小 boxcall(Console/File/Path/String)
|
||||
- ランナー統合: `NYASH_VM_USE_PY=1` で MIR(JSON) を PyVM に渡して実行
|
||||
- 代表スモーク(esc_dirname_smoke / dep_tree_min_string)で llvmlite とパリティ確認
|
||||
|
||||
【Current Status — 2025‑09‑14】
|
||||
- A6 受入達成: esc_dirname_smoke の PyVM↔llvmlite パリティ一致(ゲートOFF)、LLVM verifier green → .o → リンク → 実行OK。
|
||||
- dep_tree_min_string: PyVM↔llvmlite パリティ一致、llvmlite 経路で `.ll verify → .o → EXE` 完走。
|
||||
- 一時救済ゲート `NYASH_LLVM_ESC_JSON_FIX` は受入には未使用(OFF)。
|
||||
|
||||
#### PHI 取り扱い方針(Phase‑15 中)
|
||||
- 現行: JSON v0 Bridge 側で If/Loop の PHI を生成(安定・緑)。
|
||||
- 方針: Phase‑15 ではこのまま完成させる(変更しない)。
|
||||
- 理由: LoopForm(MIR18)導入時に、逆Loweringで PHI を自動生成する案(推薦)に寄せるため。
|
||||
- PHI は「合流点での別名付け」であり、Boxの操作ではない。
|
||||
- 抽象レイヤの純度維持(Everything is Box)。
|
||||
- 実装責務の一極化(行数削減/保守性向上)。
|
||||
|
||||
#### IfForm(構造化 if)— Builder 内部モデル(追加)
|
||||
- 目的: if/merge を構造化フォームで生成し、PHI‑off/PHI‑on の両経路で安定合流を得る。
|
||||
|
||||
### 🚀 **Phase 15.4: MIR Call革新(2025-09-23 NEW)**
|
||||
**シャドウイングバグからの設計革命 - ChatGPT5 Pro協働成果**
|
||||
|
||||
#### 📋 **革新の背景**
|
||||
- **発端**: PyVM無限ループ問題(ConsoleStd.print内でのprint()再帰呼び出し)
|
||||
- **発見**: 根本原因は実行時文字列解決によるスコープ曖昧性
|
||||
- **昇華**: ChatGPT5 Pro提案により表面修正→根本的アーキテクチャ改良へ
|
||||
|
||||
#### 🎯 **技術革新内容**
|
||||
```rust
|
||||
// ❌ 従来(問題構造)
|
||||
Call { func: ValueId /* "print"文字列 */, args }
|
||||
|
||||
// ✅ 革新後(型付き解決)
|
||||
enum Callee {
|
||||
Global(String), // nyash.builtin.print
|
||||
Method { box_name, method, receiver },
|
||||
Value(ValueId), // 関数値(最小限)
|
||||
Extern(String), // C ABI
|
||||
}
|
||||
Call { callee: Callee, args }
|
||||
```
|
||||
|
||||
#### 📈 **Phase 15目標への直接寄与**
|
||||
|
||||
1. **80k→20k行削減目標**
|
||||
- Phase 1のみ: ~1,500行削減(目標の7.5%)
|
||||
- 全Phase完了: ~4,500行削減(目標の22.5%)
|
||||
- 実行時解決ロジック・エラー処理・デバッグコードの大幅簡略化
|
||||
|
||||
2. **セルフホスティング安定化**
|
||||
- using system連携: built-in namespace統合
|
||||
- PyVM最適化: 型付き呼び出しによる高速化
|
||||
- LLVM最適化: 静的解決による最適化機会拡大
|
||||
|
||||
3. **Everything is Box哲学強化**
|
||||
- コンパイル時型安全性の確立
|
||||
- Box間の呼び出し関係の明確化
|
||||
- デバッグ・保守性の劇的向上
|
||||
|
||||
#### 🛡️ **実装戦略(3段階・破壊的変更なし)**
|
||||
- **Phase 1**: 最小変更(2-3日)→即実装可能
|
||||
- **Phase 2**: HIR導入(1-2週間)→コンパイル時解決確立
|
||||
- **Phase 3**: 言語仕様統合(1ヶ月)→完全修飾名システム
|
||||
|
||||
#### 📊 **成功指標**
|
||||
- [ ] シャドウイング無限再帰の完全排除
|
||||
- [ ] 全既存テストの破壊なし(グリーン維持)
|
||||
- [ ] MIRダンプの可読性向上
|
||||
- [ ] パフォーマンス向上(実行時オーバーヘッド削減)
|
||||
- [ ] using systemとの完全統合
|
||||
- 規約(PHI 合流):
|
||||
- merge 内に copy は置かない。then/else の pred へ edge_copy のみを挿入(self‑copy は No‑Op)。
|
||||
- 分岐直前に pre_if_snapshot を取得し、then/else は snapshot ベースで独立構築。merge で snapshot を基底に戻す。
|
||||
- 差分検出で“変更された変数のみ”をマージ対象にする。
|
||||
- LoopForm との合成: ループ body 内に IfForm をネスト。continue は latch、break は after へ分岐(IfForm の merge preds から除外)。
|
||||
- 検証: スナップショットテストで CFG/edge_copy/終端/分岐先を固定。
|
||||
|
||||
### Phase 15.3: NyashコンパイラMVP(次フェーズ着手)
|
||||
- PyVM 安定後、Nyash製パーサ/レクサ(サブセット)と MIR ビルダを段階導入
|
||||
- フラグでRustフォールバックと併存(例: `NYASH_USE_NY_COMPILER=1`)
|
||||
- JIT不要、PyVM/llvmlite のパリティで正しさを担保
|
||||
|
||||
【Kickoff 目標(MVP)】
|
||||
- ステージ1: Ny→JSON v0 パイプ(整数/文字列/加減乗除/括弧/return)。CLI: `--ny-parser-pipe` と互換のJSONを生成。
|
||||
- ステージ2: 文/式サブセット拡張(local/if/loop/call/method/new/me/substring/length/lastIndexOf)。
|
||||
- ステージ3: Ny AST→MIR JSON 降下(直接 llvmlite/PyVM へ渡す)。
|
||||
|
||||
#### Phase 15.3 — Detailed Plan(Ny compiler MVP)
|
||||
- Directory layout(selfhost compiler — migrated)
|
||||
- `lang/src/compiler/entry/compiler.hako`(CompilerBox entry; Ny→JSON v0 emit)
|
||||
- `lang/src/compiler/parser/{lexer.nyash,parser.nyash,ast.nyash}`(Stage‑2 へ段階拡張)
|
||||
- `lang/src/compiler/emitter/json_v0.nyash`(将来: emit 分離。MVPは inline でも可)
|
||||
- `lang/src/compiler/mir/{builder.nyash,optimizer.nyash}`(将来)
|
||||
- `lang/src/compiler/tests/{stage1,stage2}`(サンプルと期待JSON)
|
||||
|
||||
- Runner integration(安全ゲート)
|
||||
- フラグ: `NYASH_USE_NY_COMPILER=1`(既定OFF)
|
||||
- 子プロセス: `--backend vm` で selfhost compiler を起動し、stdout から JSON v0 1行を収集
|
||||
- 環境: `NYASH_JSON_ONLY=1` を子に渡して余計な出力を抑制。失敗時は静かにフォールバック
|
||||
|
||||
- Stage‑1(小さく積む)
|
||||
1) return / 整数 / 文字列 / 四則 / 括弧(左結合)
|
||||
2) 文分離(最小ASI): 改行=文区切り、継続子(+ - * / . ,)やグルーピング中は継続
|
||||
3) 代表スモーク: `return 1+2*3` → JSON v0 → Bridge → MIR 実行 = 7
|
||||
|
||||
- Stage‑2(本命へ)
|
||||
- local / if / loop / call / method / new / var / 比較 / 論理(短絡)
|
||||
- PHI: Bridge 側の合流(If/Loop)に依存(Phase‑15中は現行維持)
|
||||
- 代表スモーク: nested if / loop 累積 / 短絡 and/or と if/loop の交錯
|
||||
|
||||
- Acceptance(15.3)
|
||||
- Stage‑1: 代表サンプルで JSON v0 emit → Bridge → VM/llvmlite で一致(差分なし)
|
||||
- Bootstrap: `tools/bootstrap_selfhost_smoke.sh` で c0→c1→c1' が PASS(フォールバックは許容)
|
||||
- Docs: 文分離ポリシー(改行+最小ASI)を公開(link: reference/language/statements.md)
|
||||
|
||||
- Smokes / Tools(更新)
|
||||
- `tools/selfhost_compiler_smoke.sh`(入口)
|
||||
- `tools/build_compiler_exe.sh`(Selfhost Parser のEXE化)
|
||||
- `tools/ny_stage2_bridge_smoke.sh`(算術/比較/短絡/ネストif)
|
||||
- `tools/ny_parser_stage2_phi_smoke.sh`(If/Loop の PHI 合流)
|
||||
- `tools/parity.sh --lhs vm --rhs llvmlite <test.nyash>`(常時)
|
||||
|
||||
Imports/Namespace plan(15.3‑late)
|
||||
- See: imports-namespace-plan.md — keep `nyash.toml` resolution in runner; accept `using` in Ny compiler as no‑op (no resolution) gated by `NYASH_USING=1` (compat: `NYASH_ENABLE_USING=1`).
|
||||
|
||||
- Operational switches
|
||||
- `NYASH_USE_NY_COMPILER=1`(selfhost compiler 経路ON)
|
||||
- `NYASH_JSON_ONLY=1`(子プロセスの余計な出力抑止)
|
||||
- `NYASH_PLUGIN_POLICY=off`(必要に応じて子のみ最小化; compat: `NYASH_DISABLE_PLUGINS=1`)
|
||||
- 文分離: 最小ASIルール(深さ0・直前が継続子でない改行のみ終端)
|
||||
|
||||
- Risks / Rollback
|
||||
- 子プロセス出力がJSONでない→フォールバックで安全運用
|
||||
- 代表ケースで parity 不一致→selfhost 経路のみ切替OFF
|
||||
- 影響範囲: CLI/Runner 層の限定的変更(ゲートOFFなら既存経路と同値)
|
||||
|
||||
【受入(MVP)】
|
||||
- `tools/ny_roundtrip_smoke.sh` 緑(Case A/B)。
|
||||
- `apps/tests/esc_dirname_smoke.nyash` / `selfhost/tools/dep_tree_min_string.hako` を Ny パーサ経路で実行し、PyVM/llvmlite とパリティ一致(stdout/exit)。
|
||||
|
||||
#### 予告: LoopForm(MIR18)での PHI 自動化(Phase‑15 後)
|
||||
- LoopForm を強化し、`loop.begin(loop_carried_values) / loop.iter / loop.branch / loop.end` の構造的情報から逆Loweringで PHI を合成。
|
||||
- If/短絡についても同様に、構造ブロックから合流点を決めて PHI を自動化。
|
||||
- スケジュール: Phase‑15 後(MIR18/LoopForm)で検討・実装。Phase‑15 では変更しない。
|
||||
|
||||
### Phase 15.4: VM層のNyash化(PyVMからの置換)
|
||||
- PyVM を足場に、VMコアを Nyash 実装へ段階移植(命令サブセットから)
|
||||
- 動的ディスパッチで13命令処理を目標に拡張
|
||||
|
||||
詳細:[セルフホスティング戦略 2025年9月版](implementation/self-hosting-strategy-2025-09.md)
|
||||
|
||||
---
|
||||
|
||||
## ♻ 再計画(Macro駆動リファクタ)
|
||||
|
||||
強化されたマクロ基盤(AST JSON v0 / PyVMサンドボックス / strict / timeout / golden)を前提に、Phase‑15 のセルフホスティング工程を **「前段AST正規化 → 正式MIR生成」** の二段型にリフレームする。
|
||||
|
||||
### ポイント(運用)
|
||||
- すべてのフロント側変換(構文糖衣・derive相当・軽微なリライト・静的検証)は **MacroBoxSpec**(Nyash/PyVM)で実行(1パス固定点)。
|
||||
- Rust側は **最小のコア**(パース/AST JSON生成、MIRビルド、バックエンド)に収束。
|
||||
- 決定性担保: strict=1(既定)、capabilitiesは全OFF(io/net/env=false)の純粋展開。
|
||||
- 観測: `--dump-expanded-ast-json` と golden 比較で安定性を担保。
|
||||
|
||||
### 実行順序(改定)
|
||||
1) Parse → AST
|
||||
2) Macro expand(1パス固定点: Built‑in(Rust)→User (Nyash/PyVM))
|
||||
3) Using/解決 → MIR → Backend(VM/LLVM/AOT)
|
||||
|
||||
### 直近タスクリスト(Phase‑15用)
|
||||
1. Macro 前段の正式導入(完了/PoC→実運用)
|
||||
- `NYASH_MACRO_PATHS=...` でユーザーマクロ登録(ランナールート既定)
|
||||
- strict=1/timeout=2000ms(既定)
|
||||
- `--dump-expanded-ast-json` を golden として活用
|
||||
2. Self‑host フロントの簡素化
|
||||
- Nyash 製パーサは **最小構文**のみサポート(Stage‑2サブセット)
|
||||
- 糖衣や軽いリライトは **MacroBox** に寄せる
|
||||
3. Golden セットの拡充
|
||||
- `apps/tests/*` → `tools/test/golden/*` で展開後JSONの一致
|
||||
- timeout/strict/失敗cap の負例テストを追加
|
||||
4. nyash.toml 設計の雛形(capabilities)
|
||||
- `[macros] paths=[…]` + `[macro_caps."path"] io/net/env=false` をドキュメント化
|
||||
|
||||
### 受け入れ基準(Phase‑15)
|
||||
- `--dump-expanded-ast-json` の golden が緑(MacroON/OFF差分は無い/または期待通り)
|
||||
- PyVM ランナー経由で `MacroBoxSpec.expand(json)` を呼べる(strict/timeout遵守)
|
||||
- MIR/LLVM/VM の後段は、Macro展開済み入力で恒常緑
|
||||
|
||||
関連: [planning/macro_driven_replan.md](planning/macro_driven_replan.md)
|
||||
|
||||
---
|
||||
|
||||
補足: JSON v0 の扱い(互換)
|
||||
- Phase‑15: Bridge で PHI を生成(現行継続)。
|
||||
- MIR18(LoopForm)以降: PHI 自動化後、JSON 側の PHI は非必須(将来は除外方向)。
|
||||
- 型メタ(“+”の文字列混在/文字列比較)は継続。
|
||||
|
||||
## 📊 主要成果物
|
||||
|
||||
### コンパイラコンポーネント
|
||||
- [ ] CompilerBox実装(統合コンパイラ)
|
||||
- [ ] Nyashパーサー(800行目標)
|
||||
- [ ] MIR Lowerer(2,500行目標)
|
||||
- [ ] CraneliftBox(JITエンジンラッパー)
|
||||
- [ ] LinkerBox(lld内蔵リンカー統合)
|
||||
- [ ] nyashrtランタイム(静的/動的ライブラリ)
|
||||
- [ ] ToolchainBox(環境診断・SDK検出)
|
||||
|
||||
### 自動生成基盤
|
||||
- [ ] boxes.yaml(Box型定義)
|
||||
- [ ] externs.yaml(C ABI境界)
|
||||
- [ ] semantics.yaml(MIR14定義)
|
||||
- [ ] build.rs(自動生成システム)
|
||||
|
||||
### ブートストラップ
|
||||
- [ ] c0→c1コンパイル成功
|
||||
- [ ] c1→c1'自己コンパイル
|
||||
- [ ] パリティテスト合格
|
||||
|
||||
## 🔧 技術的アプローチ
|
||||
|
||||
### MIR 14命令の革命
|
||||
1. Const - 定数
|
||||
2. BinOp - 二項演算
|
||||
3. UnaryOp - 単項演算(復活!)
|
||||
4. Compare - 比較
|
||||
5. Jump - 無条件ジャンプ
|
||||
6. Branch - 条件分岐
|
||||
7. Return - 戻り値
|
||||
8. Phi - SSA合流
|
||||
9. Call - 関数呼び出し
|
||||
10. BoxCall - Box操作(配列/フィールド/メソッド統一!)
|
||||
11. ExternCall - 外部呼び出し
|
||||
12. TypeOp - 型操作
|
||||
13. Safepoint - GC安全点
|
||||
14. Barrier - メモリバリア
|
||||
この究極のシンプルさにより、直接x86変換も現実的に!
|
||||
|
||||
### バックエンドの選択肢
|
||||
#### 1. Cranelift + lld内蔵(保留)
|
||||
- **軽量**: 3-5MB程度(LLVMの1/10以下)
|
||||
- **JIT特化**: メモリ上での動的コンパイル
|
||||
- **Rust統合**: 静的リンクで配布容易
|
||||
- **lld内蔵**: Windows(lld-link)/Linux(ld.lld)で完全自立
|
||||
- **C ABIファサード**: `ny_mir_to_obj()`で美しい境界
|
||||
|
||||
#### 2. 直接x86エミッタ(将来の革新的アプローチ)
|
||||
- **dynasm-rs/iced-x86**: Rust内で直接アセンブリ生成
|
||||
- **テンプレート・スティッチャ方式**: 2-3KBの超小型バイナリ可能
|
||||
- **完全な制御**: 依存ゼロの究極形
|
||||
|
||||
### コード削減の秘密
|
||||
- **Arc<Mutex>自動化**: 明示的ロック管理不要(-30%)
|
||||
- **型システム簡略化**: 動的型付けの恩恵(-20%)
|
||||
- **エラー処理統一**: Result<T,E>地獄からの解放(-15%)
|
||||
- **動的ディスパッチ**: match文の大幅削減(-10%)
|
||||
- **合計**: 80,000行→20,000行(75%削減)
|
||||
|
||||
### 実装例
|
||||
```nyash
|
||||
// 80,000行のRust実装が20,000行のNyashに!
|
||||
box NyashCompiler {
|
||||
parser: ParserBox
|
||||
lowerer: LowererBox
|
||||
backend: BackendBox
|
||||
|
||||
birth() {
|
||||
me.parser = new ParserBox()
|
||||
me.lowerer = new LowererBox()
|
||||
me.backend = new BackendBox()
|
||||
}
|
||||
|
||||
compile(source) {
|
||||
local ast = me.parser.parse(source)
|
||||
local mir = me.lowerer.lower(ast)
|
||||
return me.backend.generate(mir)
|
||||
}
|
||||
}
|
||||
|
||||
// MIR実行器も動的ディスパッチで簡潔に
|
||||
box MirExecutor {
|
||||
values: MapBox
|
||||
|
||||
birth() {
|
||||
me.values = new MapBox()
|
||||
}
|
||||
|
||||
execute(inst) { return me[inst.type](inst) }
|
||||
Const(inst) { me.values[inst.result] = inst.value }
|
||||
BinOp(inst) { /* 実装 */ }
|
||||
}
|
||||
|
||||
// lld内蔵リンカー(ChatGPT5協議)
|
||||
box LinkerBox {
|
||||
platform: PlatformBox
|
||||
lld_path: StringBox
|
||||
libraries: ArrayBox
|
||||
|
||||
birth(platform) {
|
||||
me.platform = platform
|
||||
me.lld_path = platform.findLldPath()
|
||||
me.libraries = new ArrayBox()
|
||||
}
|
||||
|
||||
link(objects, output) {
|
||||
local cmd = me.build_command(objects, output)
|
||||
return me.platform.execute(cmd)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### テンプレート・スティッチャ方式(革新的アプローチ)
|
||||
```nyash
|
||||
// 各MIR命令を共通スタブとして実装
|
||||
box TemplateStitcher {
|
||||
init { stubs }
|
||||
|
||||
constructor() {
|
||||
me.stubs = new MapBox()
|
||||
// 各命令の共通実装をスタブとして登録
|
||||
me.stubs.set("Const", 0x1000) // スタブアドレス
|
||||
me.stubs.set("BinOp", 0x1100)
|
||||
me.stubs.set("BoxCall", 0x1200)
|
||||
// ... 13命令分のスタブ
|
||||
}
|
||||
|
||||
generate(mir) {
|
||||
local jumps = new ArrayBox()
|
||||
|
||||
// プログラムはスタブ間のジャンプ列に!
|
||||
for inst in mir.instructions {
|
||||
jumps.push("jmp " + me.stubs.get(inst.type))
|
||||
}
|
||||
|
||||
return jumps // 超小型バイナリ!
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 🔗 EXEファイル生成・リンク戦略
|
||||
|
||||
### 統合ツールチェーン(現状)
|
||||
```bash
|
||||
nyash build main.ny --backend=llvm --emit exe -o program.exe # llvmlite/harness 経路
|
||||
NYASH_VM_USE_PY=1 nyash run main.ny --backend=vm # PyVM(MIR JSON を実行)
|
||||
```
|
||||
|
||||
### 実装戦略
|
||||
|
||||
#### LLVM バックエンド(優先・llvmlite)
|
||||
1. **MIR→LLVM IR**: MIR13をLLVM IRに変換(✅ 実装済み)
|
||||
2. **LLVM IR→Object**: ネイティブオブジェクトファイル生成(✅ 実装済み)
|
||||
3. **Python/llvmlite実装**: Resolver patternでSSA安全性確保(✅ 実証済み)
|
||||
4. **Object→EXE**: リンカー統合でEXE作成(🚀 実装中)
|
||||
5. **独立コンパイラ**: `nyash-llvm-compiler` crateとして分離(📝 計画中)
|
||||
|
||||
詳細は[**LLVM EXE生成戦略**](implementation/llvm-exe-strategy.md)を参照。
|
||||
|
||||
#### Cranelift バックエンド(保留)
|
||||
1. **MIR→Cranelift**: MIR13をCranelift IRに変換
|
||||
2. **Cranelift→Object**: ネイティブオブジェクトファイル生成(.o/.obj)
|
||||
3. **lld内蔵リンク**: lld-link(Win)/ld.lld(Linux)でEXE作成
|
||||
4. **nyashrtランタイム**: 静的/動的リンク選択可能
|
||||
|
||||
### C ABI境界設計
|
||||
```c
|
||||
// 最小限の美しいインターフェース
|
||||
ny_mir_to_obj(mir_bin, target_triple) -> obj_bytes
|
||||
ny_mir_jit_entry(mir_bin) -> exit_code
|
||||
ny_free_buf(buffer)
|
||||
```
|
||||
|
||||
詳細は[**自己ホスティングlld戦略**](implementation/lld-strategy.md)を参照。
|
||||
|
||||
## 🔗 関連ドキュメント
|
||||
|
||||
### 📂 実装関連(implementationフォルダ)
|
||||
- [🚀 LLVM EXE生成戦略](implementation/llvm-exe-strategy.md)(NEW)
|
||||
- [🚀 自己ホスティングlld戦略](implementation/lld-strategy.md)(Cranelift版)
|
||||
- [🧱 箱積み上げ準備メモ](implementation/box-stacking.md)
|
||||
- [🏗️ アーキテクチャ詳細](implementation/architecture.md)
|
||||
|
||||
### 📅 計画関連(planningフォルダ)
|
||||
- [📋 推奨実装順序](planning/sequence.md)
|
||||
- [🔧 準備作業まとめ](planning/preparation.md)
|
||||
|
||||
### 🔧 実行チェックリスト
|
||||
- [ROADMAP.md](ROADMAP.md) - 進捗管理用チェックリスト
|
||||
|
||||
### ✅ クイックスモーク(現状)
|
||||
- PyVM↔llvmlite パリティ: `tools/parity.sh --lhs pyvm --rhs llvmlite apps/tests/esc_dirname_smoke.nyash`
|
||||
- dep_tree(ハーネスON): `NYASH_LLVM_FEATURE=llvm ./tools/build_llvm.sh selfhost/tools/dep_tree_min_string.hako -o app_dep && ./app_dep`
|
||||
- Selfhost Parser EXE: `tools/build_compiler_exe.sh && (cd dist/nyash_compiler && ./nyash_compiler tmp/sample.nyash > sample.json)`
|
||||
- JSON v0 bridge spec: `docs/reference/ir/json_v0.md`
|
||||
- Stage‑2 smokes: `tools/ny_stage2_bridge_smoke.sh`, `tools/ny_parser_stage2_phi_smoke.sh`, `tools/ny_me_dummy_smoke.sh`
|
||||
|
||||
WSL Quickstart
|
||||
- See: `docs/guides/exe-first-wsl.md`(依存の導入→Parser EXE バンドル→スモークの順)
|
||||
|
||||
### 📚 関連フェーズ
|
||||
- [Phase 10: Cranelift JIT](../phase-10/)
|
||||
- [Phase 12.5: 最適化戦略](../phase-12.5/)
|
||||
- [Phase 12.7: ANCP圧縮](../phase-12.7/)
|
||||
- [Phase 15.1: AOT計画](phase-15.1/)
|
||||
|
||||
## 📅 実施時期(修正版)
|
||||
|
||||
- **現在進行中**(2025年9月)
|
||||
- Python/llvmlite(既定)/Craneliftは停止
|
||||
- PyVM(Python MIR VM)導入・代表スモークで llvmlite とパリティ確認
|
||||
- **Phase 15.2**: llvmlite安定化 + PyVM最小完成(2025年9-10月)
|
||||
- **Phase 15.3**: NyashコンパイラMVP(2025年11-12月)
|
||||
- **Phase 15.4**: VM層Nyash化(2026年1-3月)
|
||||
- **Phase 15.5**: ABI移行(LLVM完成後、必要に応じて)
|
||||
|
||||
## 💡 期待される成果
|
||||
|
||||
1. **技術的証明**: 実用言語としての成熟度
|
||||
2. **開発効率**: Nyashだけで開発完結
|
||||
3. **教育価値**: 15,000行で読破可能なコンパイラ
|
||||
4. **コミュニティ**: 参入障壁の大幅低下
|
||||
5. **保守性革命**: 75%削減で誰でも改造可能
|
||||
|
||||
## 🌟 夢の実現
|
||||
|
||||
> 「コンパイラもBox、リンカーもBox、すべてがBox」
|
||||
> 「71,000行→15,000行、これが革命」
|
||||
|
||||
外部ツールチェーンに依存しない、真の自立したプログラミング言語へ。
|
||||
|
||||
### 数値で見る革命
|
||||
- **現在**: 80,000行(Rust実装)
|
||||
- **第一目標**: 20,000行(Nyashセルフホスティング、**75%削減**)
|
||||
- **究極の夢**: さらなる最適化でより小さく!
|
||||
- **MIR命令数**: たった13個で全機能実現
|
||||
- **理解容易性**: 週末で読破可能なコンパイラ
|
||||
- **バイナリサイズ**: テンプレート方式なら2-3KBも可能
|
||||
- **教育的価値**: 世界一美しく、世界一小さい実用コンパイラ
|
||||
|
||||
### 🌟 Everything is Boxの究極形
|
||||
- コンパイラもBox
|
||||
- リンカーもBox
|
||||
- アセンブラもBox
|
||||
- プラグインもBox(.so/.o/.a全方向対応)
|
||||
- すべてがBox!
|
||||
|
||||
**世界一美しい箱は、自分自身さえも美しく包み込む**
|
||||
|
||||
### 🚀 次のマイルストーン
|
||||
- ✅ LLVM dominance違反解決(Resolver pattern)
|
||||
- 🚀 Python/llvmliteでEXE生成パイプライン完成
|
||||
- 📝 nyash-llvm-compiler分離設計
|
||||
- 📝 NyashパーサーMVP実装開始
|
||||
108
docs/private/roadmap/phases/phase-15/ROADMAP.md
Normal file
108
docs/private/roadmap/phases/phase-15/ROADMAP.md
Normal file
@ -0,0 +1,108 @@
|
||||
# Phase 15 — Box Stacking Roadmap (Living)
|
||||
|
||||
This roadmap is a living checklist to advance Phase 15 with small, safe boxes. Update continuously as we progress.
|
||||
|
||||
## Now (ready/green)
|
||||
|
||||
- [x] v0 Ny parser (Ny→JSON IR v0) with wrappers (Unix/Windows)
|
||||
- [x] Runner JSON v0 bridge (`--ny-parser-pipe`) → MIR → MIR-Interp
|
||||
- [x] E2E + roundtrip practical recipes (Windows/Unix)
|
||||
- [x] Docs path unify (phase-15 under roadmap tree)
|
||||
- [x] Direct bridge (design + skeleton; feature-gated)
|
||||
- [x] AOT P2 stubs (CraneliftAotBox/LinkerBox) + RUN smoke wiring
|
||||
- [x] JIT‑only baseline stabilized (core smokes green; plugins optional)
|
||||
- [x] Roundtrip (Case A/B) aligned; Case A re‑enabled via parser pipe
|
||||
- [x] using/namespace (gated) + nyash.link minimal resolver
|
||||
- [x] NyModules + ny_plugins regression suite (Windows path normalization/namespace derivation)
|
||||
- [x] Standard Ny scripts scaffolds added (string/array/map P0) + examples + jit_smoke
|
||||
- [x] Selfhost Parser accepts positional input file arg(EXE運用の前提)
|
||||
- [x] **Phase 15.5-A: プラグインチェッカー拡張完成**(ChatGPT5 Pro⭐⭐⭐⭐⭐最高評価)
|
||||
- ✅ 4つの安全性機能完全実装(ユニバーサルスロット衝突・StringBox問題・E_METHOD・TLV検証)
|
||||
- ✅ 100%検出精度実証(手動発見問題を完全自動検出)
|
||||
- ✅ 実用検証済み(実際のnyash.tomlで8問題自動検出・修正指示)
|
||||
- [x] **Phase 15.5-B-1: slot_registry統一化完成**(StringBox問題根本修正)
|
||||
- ✅ core box静的定義30行削除完了(3-tier→2-tier基盤確立)
|
||||
- ✅ former core boxes(StringBox/IntegerBox/ArrayBox/MapBox)のplugin slots移行
|
||||
- ✅ WebChatGPT環境との完全一致(同じnyash.toml設定で同じ動作)
|
||||
|
||||
## Next (small boxes)
|
||||
|
||||
1) Ny JSON ライブラリ(最小 DOM / JSON v0 対応)
|
||||
- Nyash 製の parse/stringify(object/array/string/number/bool/null)。
|
||||
- Env: `NYASH_JSON_PROVIDER=ny`(既定OFF)。
|
||||
- Smokes: roundtrip/エラー位置検証(quick 任意; CI非ブロック)。
|
||||
2) Ny Executor(最小命令セット)
|
||||
- ops: const/binop/compare/branch/jump/ret/phi(Box 呼び出しは後段)。
|
||||
- Env: `NYASH_SELFHOST_EXEC=1`(既定OFF)。
|
||||
- Parity: PyVM/LLVM harness と stdout/exit の一致。
|
||||
3) 呼び出し最小(Console/String/Array/Map P0)
|
||||
- call/externcall/boxcall の最小を接続。未知 extern は STRICT で拒否。
|
||||
4) Selfhost Parser の EXE 化(任意・後回し可)
|
||||
- `tools/build_compiler_exe.sh` により JSON v0 emit の単体配布(開発者向け)。
|
||||
5) PHI 自動化は Phase‑15 後(LoopForm = MIR18)
|
||||
- Phase‑15: 現行の Bridge‑PHI を維持(規約は「incoming pred=実際の遷移元」)。
|
||||
- MIR18: LoopForm 強化+逆Loweringでの自動化に委譲(設計のみ先行)。
|
||||
6) Plugins CI split(継続)
|
||||
- Plugins は任意ジョブ(strict off)を維持。Core は軽量 quick を常時。
|
||||
|
||||
## Later (incremental)
|
||||
|
||||
- v1 Ny parser (let/if/call) behind `NYASH_JSON_IR_VERSION=1`
|
||||
- JSON v1 bridge → MirBuilder (back-compat v0)
|
||||
- 12.7 sugars normalized patterns in bridge (?. / ?? / range)
|
||||
- E2E CI-lite matrix (no LLVM) for v0/v1/bridge roundtrip
|
||||
- Ny script plugin examples under `apps/plugins-scripts/`
|
||||
- Expand std Ny impl (String P1: trim/split/startsWith/endsWith; Array P1: map/each/filter; Map P1: values/entries/forEach)
|
||||
- using/nyash.link E2E samples under `apps/` (small project template)
|
||||
- Tighten Plugins job: migrate samples to Core‑13; re‑enable strict diagnostics
|
||||
|
||||
## Operational switches
|
||||
|
||||
- Parser path: `--parser {rust|ny}` or `NYASH_USE_NY_PARSER=1`
|
||||
- JSON dump: `NYASH_DUMP_JSON_IR=1`
|
||||
- (予告)LoopForm: MIR18 で仕様化予定
|
||||
- Selfhost compiler: `NYASH_USE_NY_COMPILER=1`, child quiet: `NYASH_JSON_ONLY=1`
|
||||
- JSON provider: `NYASH_JSON_PROVIDER=ny`(Ny JSON; 既定OFF)
|
||||
- Ny executor: `NYASH_SELFHOST_EXEC=1`(既定OFF)
|
||||
- EXE-first bundle: `tools/build_compiler_exe.sh` → `dist/nyash_compiler/`
|
||||
- Load Ny plugins: `NYASH_LOAD_NY_PLUGINS=1` / `--load-ny-plugins`
|
||||
- AOT smoke: `CLIF_SMOKE_RUN=1`
|
||||
|
||||
## Recipes / Smokes
|
||||
|
||||
- JSON v0 bridge: `tools/ny_parser_bridge_smoke.sh` / `tools/ny_parser_bridge_smoke.ps1`
|
||||
- E2E roundtrip: `tools/ny_roundtrip_smoke.sh` / `tools/ny_roundtrip_smoke.ps1`
|
||||
- EXE-first smoke: `tools/build_compiler_exe.sh && (cd dist/nyash_compiler && ./nyash_compiler tmp/sample.nyash > sample.json)`
|
||||
|
||||
## Implementation Dependencies
|
||||
|
||||
- Phase 15.2 (LLVM EXE) → Phase 15.3 (Nyash Compiler) → Phase 15.4 (VM in Nyash)
|
||||
- Python llvmlite serves as rapid prototyping path while Rust/inkwell continues
|
||||
- Plugin all-direction build enables static executable generation
|
||||
- Total expected Nyash code: ~20,000 lines (75% reduction from 80k Rust)
|
||||
|
||||
## Stop criteria (Phase 15)
|
||||
|
||||
- v0 E2E green (parser pipe + direct bridge) including Ny compiler MVP switch
|
||||
- v1 minimal samples pass via JSON bridge
|
||||
- AOT P2: emit→link→run stable for constant/arith
|
||||
- Phase‑15 STOP には PHI 切替を含めない(PHI は LoopForm/MIR18 で扱う)
|
||||
- 15.3: Stage‑1 代表サンプル緑 + Bootstrap smoke(フォールバック許容)+ 文分離ポリシー公開
|
||||
- Docs/recipes usable on Windows/Unix
|
||||
|
||||
## Notes
|
||||
|
||||
- JSON is a temporary, safe boundary. We will keep it for observability even after the in-proc bridge is default.
|
||||
- Favor smallest viable steps; do not couple large refactors with new features.
|
||||
|
||||
## Ny Plugins → Namespace (Plan)
|
||||
|
||||
- Phase A (minimal): Add a shared `NyModules` registry (env.modules.{set,get}).
|
||||
- Map file path → namespace (project‑relative, separators → `.`, trim extension).
|
||||
- R5 hook: if a Ny plugin returns an exports map/static box, register it under the derived namespace.
|
||||
- Guard: reject reserved prefixes (e.g., `nyashstd.*`, `system.*`).
|
||||
- Phase B (scope): Optionally run `[ny_plugins]` in a shared Interpreter to share static definitions.
|
||||
- Flag: `NYASH_NY_PLUGINS_SHARED=0` to keep isolated execution.
|
||||
- Logs: `[ny_plugins] <ns>: REGISTERED | FAIL(reason)`.
|
||||
- Phase C (language bridge): Resolve `using foo.bar` via `NyModules`, then fallback to file/package resolver (nyash.link).
|
||||
- Keep IDE‑friendly fully qualified access; integrate with future `nyash_modules/`.
|
||||
292
docs/private/roadmap/phases/phase-15/SELF_HOSTING_VISION.txt
Normal file
292
docs/private/roadmap/phases/phase-15/SELF_HOSTING_VISION.txt
Normal file
@ -0,0 +1,292 @@
|
||||
================================================================================
|
||||
Phase 15: Nyashセルフホスティング計画 - 80k→20k行への革命的圧縮
|
||||
================================================================================
|
||||
|
||||
【ビジョン】
|
||||
NyashでNyashコンパイラを書き、Nyashプログラムをコンパイル・実行する
|
||||
完全なセルフホスティング環境の実現 + 劇的なコード圧縮(75%削減)
|
||||
MIR 13命令の美しさを最大限に活かした究極の実装
|
||||
|
||||
【数値目標】
|
||||
現在: 80,000行(Rust実装)
|
||||
第一目標: 20,000行(Nyash実装)
|
||||
削減率: 75%
|
||||
究極の夢: さらなる最適化で更に小さく!
|
||||
|
||||
【革命的要素】
|
||||
MIR命令数: たった13個で全機能実現
|
||||
バックエンド選択: Cranelift/直接x86/テンプレート方式
|
||||
バイナリサイズ: 2-3KBの超小型も可能
|
||||
|
||||
================================================================================
|
||||
1. なぜセルフホスティングか + コード圧縮の価値
|
||||
================================================================================
|
||||
|
||||
■ 言語の成熟度の証明
|
||||
├─ 自分自身をコンパイルできる = 実用的な言語
|
||||
├─ ドッグフーディング = 実際に使って改善
|
||||
├─ エコシステムの完成 = 外部依存からの解放
|
||||
└─ 75%コード削減 = 保守性・理解容易性の劇的向上
|
||||
|
||||
■ Everything is Box哲学の究極形
|
||||
├─ コンパイラもBox
|
||||
├─ JITエンジンもBox
|
||||
├─ リンカーもBox
|
||||
└─ すべてがNyashで完結
|
||||
|
||||
■ コード削減の主要因
|
||||
├─ Arc<Mutex>パターンの自動化(-30%)
|
||||
├─ 型システムの簡略化(-20%)
|
||||
├─ エラーハンドリングの統一(-15%)
|
||||
└─ パターンマッチングの動的ディスパッチ化(-10%)
|
||||
|
||||
================================================================================
|
||||
2. 技術的実現可能性
|
||||
================================================================================
|
||||
|
||||
■ Cranelift埋め込みの利点
|
||||
├─ 軽量: 3-5MB程度の追加(LLVMは50-100MB)
|
||||
├─ Rustライブラリ: 静的リンクで配布容易
|
||||
├─ JIT特化: メモリ上でのコンパイル・実行に最適
|
||||
└─ 依存が少ない: ビルド時間短縮
|
||||
|
||||
■ 既存の準備状況
|
||||
├─ ✅ MIR 13命令に削減完了(究極のシンプルさ)
|
||||
├─ ✅ Cranelift統合準備済み(Cargo.toml)
|
||||
├─ ✅ 直接x86エミッタ選択肢(dynasm-rs/iced-x86)
|
||||
├─ ✅ プラグインシステム(拡張可能)
|
||||
└─ ✅ Phase 12で統一実行パス確立
|
||||
|
||||
================================================================================
|
||||
3. 段階的実装計画 - ChatGPT5戦略による最速ルート
|
||||
================================================================================
|
||||
|
||||
■ Phase 15.0: バックエンド選択戦略(新規追加)
|
||||
├─ 選択肢1: Cranelift(現在の主力、安定)
|
||||
├─ 選択肢2: 直接x86エミッタ(dynasm-rs使用、高速)
|
||||
├─ 選択肢3: テンプレート・スティッチャ(2-3KB超小型)
|
||||
└─ 段階的移行: Cranelift→x86→テンプレート
|
||||
|
||||
■ Phase 15.1: YAML自動生成基盤(1-2週間)【最優先】
|
||||
├─ boxes.yaml: Box型定義(type_id, method_id対応表)
|
||||
├─ externs.yaml: 外部関数定義(C ABI境界)
|
||||
├─ semantics.yaml: MIR13セマンティクス定義(13命令!)
|
||||
└─ build.rs: 自動生成システム(重複コード即削除)
|
||||
|
||||
効果: Array/Instance/Console等で即座に1-2万行削減
|
||||
|
||||
■ Phase 15.1: 外部リンカー統合(1週間)
|
||||
box LinkerBox {
|
||||
link(objects, output) {
|
||||
if Platform.isWindows() {
|
||||
return exec("lld-link", objects + ["nyrt.lib", "/out:" + output])
|
||||
} else {
|
||||
return exec("ld.lld", ["-o", output, objects, "nyrt.a"])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
■ Phase 15.2: Nyashパーサー最小実装(2-3週間)
|
||||
├─ 再帰下降パーサー(800行目標)
|
||||
├─ MIR15 JSON出力(既存VMで即実行可能)
|
||||
├─ エラー処理の簡略化(Result祭り解消)
|
||||
└─ ny-echo/ny-calcで動作確認
|
||||
|
||||
■ Phase 15.3: MIR実行器のNyash化(2-3週間)
|
||||
box MirExecutor {
|
||||
// 動的ディスパッチで15命令を処理
|
||||
execute(inst) { return me[inst.type](inst) }
|
||||
|
||||
Const(inst) { me.values[inst.result] = inst.value }
|
||||
BinOp(inst) { /* 実装 */ }
|
||||
// ... 15命令分のメソッド
|
||||
}
|
||||
|
||||
■ Phase 15.4: Boxes高レベル実装移植(1ヶ月)
|
||||
├─ String/Array/Map等の表層メソッドをNyashへ
|
||||
├─ NyRT側は最小プリミティブのみ維持
|
||||
├─ プラグインBox統合
|
||||
└─ 目標: 3,000行以下
|
||||
|
||||
■ Phase 15.5: インタープリターコア移植(1ヶ月)
|
||||
├─ 評価ループのNyash化(3,000行目標)
|
||||
├─ Arc<Mutex>自動管理の恩恵
|
||||
├─ GCフックはNyRT委譲
|
||||
└─ 自己コンパイル可能ラインへ
|
||||
|
||||
■ Phase 15.6: ブートストラップ(2週間)
|
||||
├─ c0(Rust版)→ c1(Nyash版)コンパイル
|
||||
├─ c1 → c1' 自己コンパイル
|
||||
├─ パリティテスト(trace_hash一致)
|
||||
└─ 完全セルフホスティング達成
|
||||
|
||||
================================================================================
|
||||
4. EXEファイル生成・リンク戦略(ChatGPT5提案)
|
||||
================================================================================
|
||||
|
||||
■ 段階的アプローチ(現実的順序)
|
||||
├─ Phase 1: 外部リンカー利用(lld/gcc)【最速】
|
||||
├─ Phase 2: lld内蔵(配布容易性)
|
||||
└─ Phase 3: ミニリンカー自作(究極の自立)
|
||||
|
||||
■ C ABI境界設計(ny_プレフィクス統一)
|
||||
├─ 呼出規約: Windows(fastcall) / Linux(sysv_amd64)
|
||||
├─ 型マッピング: ny_handle=uint64_t, 数値=int64_t/double
|
||||
├─ シンボル: ny_v1_console_log, ny_init, ny_fini
|
||||
└─ 必須: 16Bスタックアライン、32B Shadow Space(Win64)
|
||||
|
||||
■ リンク形態の選択
|
||||
├─ 静的リンク: nyrt.lib/.a同梱(配布楽・サイズ大)
|
||||
├─ 動的リンク: nyrt.dll/.so依存(サイズ小・管理難)
|
||||
└─ バンドル方式: スタブEXEにMIR埋め込み(初期案)
|
||||
|
||||
■ 最小リンカー実装(将来ロマン)
|
||||
box MiniLinkerBox {
|
||||
// PE/ELFサブセット実装
|
||||
link(objects) {
|
||||
local exe = new ExecutableBuilder()
|
||||
exe.addSections(objects)
|
||||
exe.resolveSymbols()
|
||||
exe.applyRelocations()
|
||||
return exe.build()
|
||||
}
|
||||
}
|
||||
|
||||
================================================================================
|
||||
5. 実装上の課題と解決策
|
||||
================================================================================
|
||||
|
||||
■ 課題1: パフォーマンス
|
||||
├─ 問題: Nyashで書いたコンパイラは遅い?
|
||||
└─ 解決: ホットパスをCraneliftでJIT最適化
|
||||
|
||||
■ 課題2: メモリ使用量
|
||||
├─ 問題: Everything is Boxのオーバーヘッド
|
||||
└─ 解決: コンパイラ特有の最適化Box設計
|
||||
|
||||
■ 課題3: デバッグの難しさ
|
||||
├─ 問題: セルフホスティングのデバッグは複雑
|
||||
└─ 解決: 段階的移行・既存コンパイラとの比較検証
|
||||
|
||||
■ 課題4: ABI互換性
|
||||
├─ 問題: プラットフォーム毎の呼出規約差異
|
||||
└─ 解決: 統一FFI層(type_id, method_id)で抽象化
|
||||
|
||||
================================================================================
|
||||
6. 期待される成果
|
||||
================================================================================
|
||||
|
||||
■ 技術的成果
|
||||
├─ 完全なセルフホスティング言語
|
||||
├─ 外部コンパイラ依存からの解放
|
||||
├─ Nyashエコシステムの完成
|
||||
├─ 言語の実用性の証明
|
||||
└─ 【革命】71,000行→15,000行(75%削減)
|
||||
|
||||
■ 教育的価値
|
||||
├─ コンパイラ実装の教材として
|
||||
├─ Nyashで学ぶコンパイラ理論
|
||||
├─ シンプルで理解しやすい実装
|
||||
└─ 15,000行で読破可能なコンパイラ
|
||||
|
||||
■ コミュニティへの影響
|
||||
├─ 開発者の参入障壁低下
|
||||
├─ Nyashだけで開発環境構築
|
||||
├─ 真の「Everything is Box」体験
|
||||
└─ コントリビューション容易化
|
||||
|
||||
■ コード削減の具体例(80k→20k)
|
||||
├─ Boxes実装: 13,000行 → 3,000行(77%削減)
|
||||
├─ Interpreter: 15,000行 → 4,000行(73%削減)
|
||||
├─ MIR: 12,000行 → 2,000行(83%削減、13命令化の効果)
|
||||
├─ Parser: 5,000行 → 1,500行(70%削減)
|
||||
├─ Backend: 15,000行 → 4,000行(73%削減)
|
||||
└─ その他: 20,000行 → 5,500行(72%削減)
|
||||
|
||||
================================================================================
|
||||
7. 成功指標
|
||||
================================================================================
|
||||
|
||||
□ NyashコンパイラがNyash自身をコンパイル可能
|
||||
□ コード行数: 20,000行以内(75%削減達成)
|
||||
□ MIR 13命令での完全実装
|
||||
□ 性能: Rustコンパイラの50%以上
|
||||
□ バイナリサイズ:
|
||||
- Cranelift版: 10MB以下
|
||||
- 直接x86版: 5MB以下
|
||||
- テンプレート版: 1MB以下(夢の2-3KBも視野)
|
||||
□ コンパイル時間: 中規模プロジェクトで10秒以内
|
||||
□ 100%のテストケース互換性
|
||||
□ trace_hash/heap_hashパリティ(VM/JIT/AOT)
|
||||
|
||||
================================================================================
|
||||
8. ロードマップ依存関係
|
||||
================================================================================
|
||||
|
||||
必須完了フェーズ:
|
||||
├─ Phase 10: Cranelift JIT統合
|
||||
├─ Phase 11.8: MIR Core-13最適化
|
||||
├─ Phase 12: プラグインシステム統一
|
||||
├─ Phase 12.5: 最適化戦略確立
|
||||
└─ Phase 14: 実アプリでの実証
|
||||
|
||||
推定開始時期: 2026年前半
|
||||
推定完了時期: 2026年後半
|
||||
|
||||
================================================================================
|
||||
9. 実装優先順位(ChatGPT5推奨)
|
||||
================================================================================
|
||||
|
||||
■ 今すぐ着手(2日以内)
|
||||
├─ boxes.yaml/externs.yaml/semantics.yaml スキーマ設計
|
||||
├─ build.rs自動生成(Array/Instance/Console)
|
||||
└─ 生成物でのパリティテスト
|
||||
|
||||
■ 今週中
|
||||
├─ 外部リンカー呼び出し実装
|
||||
├─ ny_プレフィクスABI仕様書作成
|
||||
└─ echo/calcのリンク動作確認
|
||||
|
||||
■ 今月中
|
||||
├─ Nyashパーサー骨格(MIR15 JSON出力)
|
||||
├─ MirExecutorのNyash実装開始
|
||||
└─ 1万行削減の実証
|
||||
|
||||
■ 3ヶ月以内
|
||||
├─ c0→c1ブートストラップ
|
||||
├─ 主要Box型のNyash移植
|
||||
└─ 3万行削減達成
|
||||
|
||||
================================================================================
|
||||
10. 夢の先にあるもの
|
||||
================================================================================
|
||||
|
||||
セルフホスティング達成後の可能性:
|
||||
|
||||
■ Nyash専用最適化
|
||||
├─ Box境界での特殊最適化
|
||||
├─ Everything is Box前提の新しい最適化手法
|
||||
└─ Nyashらしい高速化
|
||||
|
||||
■ 新しいバックエンド
|
||||
├─ WebAssembly直接出力
|
||||
├─ GPU計算対応
|
||||
└─ 組み込みターゲット
|
||||
|
||||
■ 言語の進化
|
||||
├─ Nyashで実験的機能を実装
|
||||
├─ コミュニティ駆動の言語拡張
|
||||
└─ 真のオープンソース言語
|
||||
|
||||
■ 究極の姿
|
||||
├─ 15,000行で完全なコンパイラ
|
||||
├─ 誰でも読めて改造できる
|
||||
├─ 教育用言語の決定版
|
||||
└─ Everything is Boxの証明
|
||||
|
||||
================================================================================
|
||||
|
||||
「コンパイラもBox、リンカーもBox、すべてがBox」
|
||||
「71,000行→15,000行、これが革命」
|
||||
|
||||
これがNyashの究極の姿。
|
||||
@ -0,0 +1,212 @@
|
||||
# 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/hako_kernel` 完全移行
|
||||
- **42%削減実現**: 11箇所の`with_legacy_vm_args`系統的削除完了
|
||||
- **Plugin-First統一**: 旧VM依存システム完全根絶
|
||||
- **ビルド成功**: libhako_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側の定数になる
|
||||
|
||||
### ランタイム側の構造
|
||||
- **プラグインローダ/統合レジストリ/GC/Host 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"として)**
|
||||
- **GC(write 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/`(ユーザー実装&プラグイン側)**に分割
|
||||
- **CoreBox(Builtin)関連の残存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)
|
||||
- **VM(Rust)とLLVMの出力一致**(代表20パターン)
|
||||
- **プラグインを"全静的リンク"**&**NyRTなしで実行**
|
||||
|
||||
### 回帰テスト(Full)
|
||||
- 例外/早期return/ネストif/loop(PHI合流)など、**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を撤去**し、**NyKernel(GC/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.3(builtin削除)の発展形
|
||||
- **80k→20k削減**: 大幅なアーキテクチャ簡素化による寄与
|
||||
- **Everything is Plugin完全実現**: VM/LLVM統一設計の完成
|
||||
@ -0,0 +1,117 @@
|
||||
# ABI移行タイミング詳細検討
|
||||
|
||||
## 🎯 現状分析
|
||||
|
||||
### 現在のTypeBox実装
|
||||
- **TLVベース統一** - `invoke_id`ですべてのメソッド呼び出し処理
|
||||
- **7つのプラグイン** - String/Integer/Array/Map/Console/File/Egui
|
||||
- **問題なく動作** - 機能的には十分、パフォーマンスも実用レベル
|
||||
|
||||
### LLVM層の進捗
|
||||
- ChatGPT5がLLVM実装改善中
|
||||
- PHI/ターミネーター問題を解決中
|
||||
- BuilderCursor導入で構造化
|
||||
- EXE生成までもう少し
|
||||
|
||||
## 🔄 移行オプション検討
|
||||
|
||||
### Option 1: 今すぐ移行開始
|
||||
**メリット**:
|
||||
- プラグイン数が少ない(7個)今がチャンス
|
||||
- 早期のパフォーマンス改善
|
||||
- 技術的負債を早めに解消
|
||||
- Phase 16に向けた準備
|
||||
|
||||
**デメリット**:
|
||||
- LLVM作業と並行→リソース分散
|
||||
- 優先度の問題(LLVM > ABI?)
|
||||
- 現行で問題ないのに変更リスク
|
||||
|
||||
### Option 2: LLVM完成後に移行(推奨)✅
|
||||
**メリット**:
|
||||
- **集中できる** - まずLLVM完成に全力
|
||||
- **最適化考慮** - LLVM/JITの特性を踏まえた設計
|
||||
- **一度の変更** - まとめて最適な形に
|
||||
- **実証データ** - LLVM性能を見てから判断
|
||||
|
||||
**デメリット**:
|
||||
- 移行が遅れる(でも急ぐ必要ない)
|
||||
- TLVオーバーヘッド継続(でも実用上問題なし)
|
||||
|
||||
### Option 3: 段階的準備
|
||||
**今できること**:
|
||||
1. struct_size活用コードの準備
|
||||
2. ドキュメント整理(完了✅)
|
||||
3. 拡張計画の詳細化
|
||||
4. テストコード準備
|
||||
|
||||
**LLVM後にやること**:
|
||||
1. create/destroy追加
|
||||
2. プラグイン順次対応
|
||||
3. パフォーマンス測定
|
||||
4. 最適化
|
||||
|
||||
## 📊 判断基準
|
||||
|
||||
### なぜLLVM完成後が最適か
|
||||
|
||||
1. **優先度の明確化**
|
||||
- 現在の最重要課題:セルフホスティング
|
||||
- LLVM完成 → EXE生成 → セルフホスト実現
|
||||
- ABIは「改善」であって「必須」ではない
|
||||
|
||||
2. **設計の最適化**
|
||||
- LLVMの最適化特性を理解してから
|
||||
- インライン化可能性の考慮
|
||||
- JIT/AOTでの扱いの違い
|
||||
|
||||
3. **リスク管理**
|
||||
- 動いているものを変えるリスク
|
||||
- LLVM作業への影響を避ける
|
||||
- 一度に大きく変える方が安全
|
||||
|
||||
4. **実装効率**
|
||||
- ChatGPT5がLLVM集中できる
|
||||
- 混乱を避ける
|
||||
- 明確なマイルストーン
|
||||
|
||||
## 🚀 推奨ロードマップ
|
||||
|
||||
### Phase 15(現在)
|
||||
1. **LLVM完成に集中**
|
||||
2. EXE生成実現
|
||||
3. セルフホスト基盤確立
|
||||
4. ABI拡張の詳細設計(並行)
|
||||
|
||||
### Phase 15.5(LLVM完成直後)
|
||||
1. **ABI拡張実装**
|
||||
- create/destroy追加
|
||||
- struct_size活用
|
||||
- 互換性維持
|
||||
2. **プラグイン移行**
|
||||
- 性能重要なものから
|
||||
- 段階的に対応
|
||||
3. **パフォーマンス検証**
|
||||
|
||||
### Phase 16(次フェーズ)
|
||||
1. **ABI安定化宣言**
|
||||
2. 外部開発者向けドキュメント
|
||||
3. 他言語バインディング
|
||||
|
||||
## 🎯 結論
|
||||
|
||||
**LLVM完成後の移行が最適**
|
||||
|
||||
理由:
|
||||
1. 現在のTLVベースで機能的問題なし
|
||||
2. LLVM完成が最優先(セルフホストへの道)
|
||||
3. 最適化知見を活かした設計可能
|
||||
4. リスク最小化・効率最大化
|
||||
|
||||
**ただし準備は今から**:
|
||||
- ドキュメント整理(完了✅)
|
||||
- 設計詳細化
|
||||
- テスト準備
|
||||
- 移行計画策定
|
||||
|
||||
これにより、LLVM完成後にスムーズに移行開始できる。
|
||||
@ -0,0 +1,469 @@
|
||||
# Phase 15: セルフホスティング技術詳細
|
||||
|
||||
## 1. アーキテクチャ設計
|
||||
|
||||
### 1.1 全体構成
|
||||
|
||||
```
|
||||
NyashCompiler (Nyashで実装)
|
||||
├── Frontend
|
||||
│ ├── Lexer (トークナイザー)
|
||||
│ ├── Parser (構文解析)
|
||||
│ └── AST Builder
|
||||
├── Middle-end
|
||||
│ ├── Type Checker
|
||||
│ ├── Name Resolver
|
||||
│ ├── MIR Lowerer (→13命令)
|
||||
│ └── Optimizer
|
||||
└── Backend(複数選択可能)
|
||||
├── CraneliftBox (JITラッパー)
|
||||
├── X86EmitterBox (直接エミッタ)
|
||||
├── TemplateStitcherBox (超小型)
|
||||
└── Runtime Linker
|
||||
```
|
||||
|
||||
### 1.2 CompilerBox設計
|
||||
|
||||
```nyash
|
||||
box CompilerBox {
|
||||
init {
|
||||
lexer, // トークン解析器
|
||||
parser, // 構文解析器
|
||||
lowerer, // MIR生成器
|
||||
optimizer, // 最適化器
|
||||
backend // コード生成器
|
||||
}
|
||||
|
||||
// ソースコードからASTを生成
|
||||
parse(source) {
|
||||
local tokens = me.lexer.tokenize(source)
|
||||
local ast = me.parser.parse(tokens)
|
||||
return ast
|
||||
}
|
||||
|
||||
// ASTからMIRを生成
|
||||
lower(ast) {
|
||||
local mir = me.lowerer.lower(ast)
|
||||
return me.optimizer.optimize(mir)
|
||||
}
|
||||
|
||||
// MIRから実行可能コードを生成
|
||||
codegen(mir) {
|
||||
return me.backend.generate(mir)
|
||||
}
|
||||
|
||||
// 完全なコンパイルパイプライン
|
||||
compile(source) {
|
||||
local ast = me.parse(source)
|
||||
local mir = me.lower(ast)
|
||||
return me.codegen(mir)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 2. パーサー実装(Nyash版)
|
||||
|
||||
### 2.1 Lexer実装例
|
||||
|
||||
```nyash
|
||||
box Lexer {
|
||||
init { keywords, operators }
|
||||
|
||||
constructor() {
|
||||
me.keywords = new MapBox()
|
||||
me.keywords.set("box", TokenType.BOX)
|
||||
me.keywords.set("if", TokenType.IF)
|
||||
me.keywords.set("loop", TokenType.LOOP)
|
||||
// ... 他のキーワード
|
||||
|
||||
me.operators = new MapBox()
|
||||
me.operators.set("+", TokenType.PLUS)
|
||||
me.operators.set("-", TokenType.MINUS)
|
||||
// ... 他の演算子
|
||||
}
|
||||
|
||||
tokenize(source) {
|
||||
local tokens = new ArrayBox()
|
||||
local position = 0
|
||||
|
||||
loop(position < source.length()) {
|
||||
local char = source.charAt(position)
|
||||
|
||||
if me.isWhitespace(char) {
|
||||
position = position + 1
|
||||
continue
|
||||
}
|
||||
|
||||
if me.isDigit(char) {
|
||||
local token = me.readNumber(source, position)
|
||||
tokens.push(token)
|
||||
position = token.end
|
||||
continue
|
||||
}
|
||||
|
||||
if me.isLetter(char) {
|
||||
local token = me.readIdentifier(source, position)
|
||||
tokens.push(token)
|
||||
position = token.end
|
||||
continue
|
||||
}
|
||||
|
||||
// ... 他のトークン種別
|
||||
}
|
||||
|
||||
return tokens
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 2.2 Parser実装例
|
||||
|
||||
```nyash
|
||||
box Parser {
|
||||
init { tokens, current }
|
||||
|
||||
parse(tokens) {
|
||||
me.tokens = tokens
|
||||
me.current = 0
|
||||
return me.parseProgram()
|
||||
}
|
||||
|
||||
parseProgram() {
|
||||
local statements = new ArrayBox()
|
||||
|
||||
loop(not me.isAtEnd()) {
|
||||
local stmt = me.parseStatement()
|
||||
statements.push(stmt)
|
||||
}
|
||||
|
||||
return new ASTNode("Program", statements)
|
||||
}
|
||||
|
||||
parseStatement() {
|
||||
if me.match(TokenType.BOX) {
|
||||
return me.parseBoxDeclaration()
|
||||
}
|
||||
|
||||
if me.match(TokenType.IF) {
|
||||
return me.parseIfStatement()
|
||||
}
|
||||
|
||||
// ... 他の文種別
|
||||
|
||||
return me.parseExpression()
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 3. MIR生成器実装
|
||||
|
||||
### 3.1 Lowerer実装例
|
||||
|
||||
```nyash
|
||||
box MIRLowerer {
|
||||
init {
|
||||
current_block,
|
||||
value_counter,
|
||||
block_counter,
|
||||
locals
|
||||
}
|
||||
|
||||
lower(ast) {
|
||||
me.value_counter = 0
|
||||
me.block_counter = 0
|
||||
me.locals = new MapBox()
|
||||
|
||||
local mir = new MIRModule()
|
||||
me.lowerNode(ast, mir)
|
||||
return mir
|
||||
}
|
||||
|
||||
lowerExpression(node, mir) {
|
||||
if node.type == "BinaryOp" {
|
||||
local left = me.lowerExpression(node.left, mir)
|
||||
local right = me.lowerExpression(node.right, mir)
|
||||
local result = me.newValue()
|
||||
|
||||
mir.addInstruction(new BinOp(
|
||||
node.operator,
|
||||
left,
|
||||
right,
|
||||
result
|
||||
))
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
if node.type == "Literal" {
|
||||
local result = me.newValue()
|
||||
mir.addInstruction(new Const(node.value, result))
|
||||
return result
|
||||
}
|
||||
|
||||
// ... 他の式種別
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 4. バックエンド実装
|
||||
|
||||
### 4.1 CraneliftBox実装
|
||||
|
||||
```nyash
|
||||
box CraneliftBox {
|
||||
init { jit_module, func_ctx }
|
||||
|
||||
constructor() {
|
||||
// CraneliftをFFI経由で初期化
|
||||
me.jit_module = ExternCall("cranelift_new_module")
|
||||
me.func_ctx = ExternCall("cranelift_new_context")
|
||||
}
|
||||
|
||||
compile(mir) {
|
||||
local compiled_funcs = new MapBox()
|
||||
|
||||
// 各関数をコンパイル
|
||||
for func in mir.functions {
|
||||
local code = me.compileFunction(func)
|
||||
compiled_funcs.set(func.name, code)
|
||||
}
|
||||
|
||||
return compiled_funcs
|
||||
}
|
||||
|
||||
compileFunction(mir_func) {
|
||||
// MIR → Cranelift IR変換
|
||||
ExternCall("cranelift_begin_function", me.func_ctx)
|
||||
|
||||
for inst in mir_func.instructions {
|
||||
me.emitInstruction(inst)
|
||||
}
|
||||
|
||||
// JITコンパイル
|
||||
return ExternCall("cranelift_finalize_function", me.func_ctx)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 4.2 X86EmitterBox実装(直接x86生成)
|
||||
|
||||
```nyash
|
||||
box X86EmitterBox {
|
||||
init { code_buffer, label_map }
|
||||
|
||||
constructor() {
|
||||
me.code_buffer = new ArrayBox()
|
||||
me.label_map = new MapBox()
|
||||
}
|
||||
|
||||
compile(mir) {
|
||||
// MIR 13命令を直接x86-64に変換!
|
||||
for func in mir.functions {
|
||||
me.emitFunction(func)
|
||||
}
|
||||
|
||||
return me.code_buffer
|
||||
}
|
||||
|
||||
emitInstruction(inst) {
|
||||
// MIR命令をx86テンプレートに変換
|
||||
if inst.type == "Const" {
|
||||
// mov rax, imm64
|
||||
me.emit_mov_imm(inst.dst, inst.value)
|
||||
}
|
||||
|
||||
if inst.type == "BinOp" {
|
||||
if inst.op == "Add" {
|
||||
// add rax, rbx
|
||||
me.emit_add(inst.dst, inst.left, inst.right)
|
||||
}
|
||||
}
|
||||
|
||||
if inst.type == "BoxCall" {
|
||||
// mov rdi, receiver
|
||||
// mov rax, [rdi] ; vtable
|
||||
// call [rax+slot*8] ; method call
|
||||
me.emit_boxcall(inst.recv, inst.slot)
|
||||
}
|
||||
|
||||
// ... 残り10命令のテンプレート
|
||||
}
|
||||
|
||||
emit_mov_imm(reg, value) {
|
||||
// REX.W + mov r64, imm64
|
||||
me.code_buffer.push(0x48) // REX.W
|
||||
me.code_buffer.push(0xB8 + reg) // mov opcode
|
||||
|
||||
// 64ビット即値をリトルエンディアンで
|
||||
for i in range(0, 8) {
|
||||
me.code_buffer.push((value >> (i * 8)) & 0xFF)
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 4.3 テンプレート・スティッチャ実装(超小型バイナリ)
|
||||
|
||||
```nyash
|
||||
box TemplateStitcherBox {
|
||||
init { stub_addresses, jump_table }
|
||||
|
||||
constructor() {
|
||||
// 各MIR命令の共通スタブアドレス
|
||||
me.stub_addresses = new MapBox()
|
||||
me.stub_addresses.set("Const", 0x1000)
|
||||
me.stub_addresses.set("UnaryOp", 0x1100)
|
||||
me.stub_addresses.set("BinOp", 0x1200)
|
||||
me.stub_addresses.set("Compare", 0x1300)
|
||||
me.stub_addresses.set("TypeOp", 0x1400)
|
||||
me.stub_addresses.set("Load", 0x1500)
|
||||
me.stub_addresses.set("Store", 0x1600)
|
||||
me.stub_addresses.set("Branch", 0x1700)
|
||||
me.stub_addresses.set("Jump", 0x1800)
|
||||
me.stub_addresses.set("Return", 0x1900)
|
||||
me.stub_addresses.set("Phi", 0x1A00)
|
||||
me.stub_addresses.set("BoxCall", 0x1B00)
|
||||
me.stub_addresses.set("ExternCall", 0x1C00)
|
||||
}
|
||||
|
||||
compile(mir) {
|
||||
me.jump_table = new ArrayBox()
|
||||
|
||||
// プログラムはスタブへのジャンプ列として表現
|
||||
for inst in mir.instructions {
|
||||
local stub_addr = me.stub_addresses.get(inst.type)
|
||||
|
||||
// jmp rel32
|
||||
me.jump_table.push(0xE9) // jmp opcode
|
||||
me.jump_table.push_rel32(stub_addr)
|
||||
|
||||
// 命令固有のパラメータをデータセクションに配置
|
||||
me.encodeParameters(inst)
|
||||
}
|
||||
|
||||
return me.jump_table
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 5. ブートストラップ手順
|
||||
|
||||
### 5.1 段階的移行
|
||||
|
||||
1. **Stage 0**: Rustコンパイラで初期Nyashコンパイラをビルド
|
||||
2. **Stage 1**: Stage 0コンパイラでNyashコンパイラ(Nyash版)をコンパイル
|
||||
3. **Stage 2**: Stage 1コンパイラで自分自身をコンパイル
|
||||
4. **検証**: Stage 1とStage 2の出力が同一であることを確認
|
||||
|
||||
### 5.2 検証スクリプト
|
||||
|
||||
```nyash
|
||||
box BootstrapVerifier {
|
||||
verify() {
|
||||
// Stage 0でStage 1をビルド
|
||||
local stage0 = new CompilerBox() // Rust版
|
||||
local stage1_code = stage0.compile(readFile("compiler.nyash"))
|
||||
|
||||
// Stage 1でStage 2をビルド
|
||||
local stage1 = stage1_code.instantiate()
|
||||
local stage2_code = stage1.compile(readFile("compiler.nyash"))
|
||||
|
||||
// バイナリ比較
|
||||
if stage1_code.equals(stage2_code) {
|
||||
print("🎉 Bootstrap successful!")
|
||||
return true
|
||||
} else {
|
||||
print("❌ Bootstrap failed - outputs differ")
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 6. 性能最適化
|
||||
|
||||
### 6.1 ホットパス最適化
|
||||
|
||||
```nyash
|
||||
box OptimizingCompiler from CompilerBox {
|
||||
init { profiler }
|
||||
|
||||
constructor() {
|
||||
from CompilerBox.constructor()
|
||||
me.profiler = new ProfilerBox()
|
||||
}
|
||||
|
||||
compile(source) {
|
||||
// プロファイル収集モード
|
||||
if me.profiler.isEnabled() {
|
||||
me.profiler.start()
|
||||
}
|
||||
|
||||
local result = from CompilerBox.compile(source)
|
||||
|
||||
// ホット関数をJIT再コンパイル
|
||||
if me.profiler.hasHotFunctions() {
|
||||
for func in me.profiler.getHotFunctions() {
|
||||
me.recompileWithOptimization(func)
|
||||
}
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 7. エラー処理とデバッグ
|
||||
|
||||
### 7.1 エラーレポート
|
||||
|
||||
```nyash
|
||||
box CompilerError {
|
||||
init { message, location, suggestions }
|
||||
|
||||
format() {
|
||||
local output = "Error at " + me.location + ": " + me.message
|
||||
|
||||
if me.suggestions.length() > 0 {
|
||||
output = output + "\nSuggestions:"
|
||||
for suggestion in me.suggestions {
|
||||
output = output + "\n - " + suggestion
|
||||
}
|
||||
}
|
||||
|
||||
return output
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 8. テストフレームワーク
|
||||
|
||||
```nyash
|
||||
box CompilerTest {
|
||||
testParser() {
|
||||
local parser = new Parser()
|
||||
local ast = parser.parse("box Test { }")
|
||||
|
||||
assert(ast.type == "Program")
|
||||
assert(ast.children.length() == 1)
|
||||
assert(ast.children[0].type == "BoxDeclaration")
|
||||
}
|
||||
|
||||
testMIRGeneration() {
|
||||
local compiler = new CompilerBox()
|
||||
local mir = compiler.lower(compiler.parse("1 + 2"))
|
||||
|
||||
assert(mir.instructions.length() == 3) // 2 Const + 1 BinOp
|
||||
}
|
||||
|
||||
testEndToEnd() {
|
||||
local compiler = new CompilerBox()
|
||||
local code = compiler.compile("print('Hello')")
|
||||
local output = code.run()
|
||||
|
||||
assert(output == "Hello")
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
このようにして、NyashでNyashコンパイラを実装することで、真のセルフホスティングを実現します。
|
||||
@ -0,0 +1,139 @@
|
||||
# Phase 15 自己ホスティング準備メモ - 箱積み上げ戦略
|
||||
|
||||
Date: 2025-09-03
|
||||
Author: Claude + にゃ
|
||||
|
||||
## 基本理念:箱を下にして積み重ねる
|
||||
|
||||
- フォールバック不要、Rust依存なし(EXEライブラリのみ)
|
||||
- 一度置いた箱は動かさない
|
||||
- 下の箱が安定なら、上も安定
|
||||
- 複雑さは敵、シンプルさは友
|
||||
|
||||
## 基礎Box群の階層構造
|
||||
|
||||
### 第1層(最下層):これがないと何も始まらない
|
||||
- **MemoryBox**: メモリ管理
|
||||
- **StringBox**: 文字列処理
|
||||
- **ArrayBox**: 配列操作
|
||||
- **MapBox**: 連想配列
|
||||
- **ErrorBox**: エラー処理
|
||||
|
||||
### 第2層:言語処理の基礎
|
||||
- **TokenBox**: 字句解析
|
||||
- **ASTBox**: 構文木
|
||||
- **SymbolBox**: シンボルテーブル
|
||||
- **ScopeBox**: スコープ管理
|
||||
|
||||
### 第3層:コンパイラコア
|
||||
- **ParserBox**: パーサー
|
||||
- **MIRBox**: 中間表現(13命令)
|
||||
- **OptimizerBox**: 最適化
|
||||
- **GeneratorBox**: コード生成
|
||||
|
||||
### 第4層:実行系
|
||||
- **InterpreterBox**: インタープリター
|
||||
- **VMBox**: 仮想マシン
|
||||
- **JITBox**: JITコンパイラ(Cranelift)
|
||||
- **LinkerBox**: リンカー(lld)
|
||||
|
||||
## 準備期間の研究項目
|
||||
|
||||
### 1. 依存関係マップ作成
|
||||
- 何が何に依存?
|
||||
- 最小限の依存で最大の効果
|
||||
- 循環依存の排除
|
||||
|
||||
### 2. インターフェース設計
|
||||
- 全Boxの共通プロトコル
|
||||
- 入力/出力の標準化
|
||||
- エラー処理の統一
|
||||
|
||||
### 3. ビルド順序の科学
|
||||
- Day 1: 基礎Box群
|
||||
- Day 2: 言語処理層
|
||||
- Day 3: コンパイラ層
|
||||
- 完成まで一直線
|
||||
|
||||
### 4. 最小ブートストラップセット
|
||||
- 自分自身をコンパイルできる最小構成
|
||||
- 必須機能の特定
|
||||
- 段階的な機能追加
|
||||
|
||||
## 箱の品質保証原則
|
||||
|
||||
1. **単体で完結** - 他に依存しすぎない
|
||||
2. **明確な責務** - 1つの箱は1つの仕事
|
||||
3. **テスト可能** - 単独で動作確認
|
||||
4. **不変インターフェース** - 一度決めたら変更なし
|
||||
|
||||
## 実装戦略
|
||||
|
||||
1. Rust実装の機能分解(Box単位)
|
||||
2. 各Boxの仕様書作成
|
||||
3. テストケースの移植計画
|
||||
4. Box間プロトコル設計
|
||||
5. 最小実装から始める
|
||||
6. 増分的に機能追加
|
||||
|
||||
## 成功の鍵
|
||||
|
||||
- 準備こそすべて
|
||||
- 急いで実装より、じっくり設計
|
||||
- 箱を積み重ねれば必ず頂上に到達
|
||||
- フォールバックなし、後戻りなし、前進あるのみ
|
||||
|
||||
## 革新的アイデア
|
||||
|
||||
### 1. BoxDNA設計書
|
||||
- 各Boxの入力/出力/依存を明文化
|
||||
- 遺伝子のように継承・組み合わせ
|
||||
|
||||
### 2. 増分コンパイル対応
|
||||
- 変更部分だけ再コンパイル
|
||||
- 開発効率の向上
|
||||
|
||||
### 3. 可視化ツール
|
||||
- 進捗の見える化
|
||||
- 依存関係の図示
|
||||
|
||||
## 数値目標
|
||||
|
||||
- **80,000行 → 20,000行**(75%削減)
|
||||
- **MIR13命令**で全機能実現
|
||||
- **ビルド時間**:1分以内
|
||||
- **テストカバレッジ**:90%以上
|
||||
|
||||
## コンテキスト圧縮対策
|
||||
|
||||
### 1. ANCP活用(Phase 12.7)
|
||||
- 90%圧縮でAIコンテキスト節約
|
||||
- [ANCP仕様書](../../../phase-12.7/ancp-specs/ANCP-Token-Specification-v1.md)
|
||||
|
||||
### 2. モジュール分割開発
|
||||
- 各Boxを独立して開発
|
||||
- 統合は最後に実施
|
||||
|
||||
### 3. AI協調開発
|
||||
- Claude:実装担当
|
||||
- ChatGPT5:リファクタリング
|
||||
- Gemini:レビュー
|
||||
- Codex:デバッグ支援
|
||||
|
||||
## 関連ドキュメント
|
||||
|
||||
- [自己ホスティングlld戦略](./lld-strategy.md)
|
||||
- [Phase 15 README](../README.md)
|
||||
- [Phase 12.7 ANCP](../../../phase-12.7/)
|
||||
- [MIR13命令セット](../../../../../reference/mir/INSTRUCTION_SET.md)
|
||||
|
||||
## 次のアクション
|
||||
|
||||
1. このメモをベースに詳細設計
|
||||
2. Box依存関係グラフの作成
|
||||
3. 最小実装セットの確定
|
||||
4. 各Boxの仕様書ドラフト
|
||||
|
||||
---
|
||||
|
||||
「箱を積み上げて、世界一美しいコンパイラを作るにゃ!」
|
||||
@ -0,0 +1,196 @@
|
||||
# Phase 15 自己ホスティング実装戦略 - MIR→Cranelift→lld
|
||||
|
||||
Author: ChatGPT5 + Claude協議
|
||||
Date: 2025-09-03
|
||||
Version: 1.0
|
||||
|
||||
## 📋 概要
|
||||
|
||||
Nyash完全自己ホスティングを実現するための具体的実装戦略。
|
||||
**「MIR→Craneliftで.o/.objを作る→lldでEXEを組む」**をNyashツールチェーンに内蔵する。
|
||||
|
||||
## 🎯 最終形(自己ホスト時の一発ボタン)
|
||||
|
||||
```bash
|
||||
nyash build main.ny \
|
||||
--backend=cranelift \
|
||||
--target=x86_64-pc-windows-msvc # or x86_64-unknown-linux-gnu
|
||||
```
|
||||
|
||||
内部処理フロー:
|
||||
1. **frontend**: AST→MIR13
|
||||
2. **codegen**: MIR→Cranelift→`.obj/.o`
|
||||
3. **link**: `lld-link`(Win) / `ld.lld`(Linux)でEXE生成
|
||||
4. 依存ランタイム`nyashrt`を自動リンク(静的/動的選択)
|
||||
|
||||
## 🏗️ 実装の芯(最小で美しいやつ)
|
||||
|
||||
### 1. コード生成ライブラリ(C ABIファサード)
|
||||
|
||||
```c
|
||||
// 最小限の美しいインターフェース
|
||||
ny_mir_to_obj(mir_bin, target_triple) -> obj_bytes
|
||||
ny_mir_jit_entry(mir_bin) -> exit_code // 開発用
|
||||
ny_free_buf(buffer) // メモリ解放
|
||||
|
||||
// エラーハンドリング
|
||||
// 例外は戻り値+NyErr(unwind禁止)
|
||||
```
|
||||
|
||||
実装のポイント:
|
||||
- 返却メモリは`ny_free_buf`で解放
|
||||
- 例外は戻り値+NyErrで統一(unwind禁止)
|
||||
- C ABIで安定した境界を作る
|
||||
|
||||
### 2. リンカー・ラッパ(プラットフォーム別)
|
||||
|
||||
#### Windows
|
||||
- 既定: `lld-link`
|
||||
- 主要フラグ:
|
||||
```bash
|
||||
lld-link <objs...> nyashrt.lib /SUBSYSTEM:CONSOLE \
|
||||
/OUT:a.exe /ENTRY:nyash_entry \
|
||||
/LIBPATH:<sdk/lib> /MACHINE:X64
|
||||
```
|
||||
- MSVC互換が要る配布向けに`/fallback:link.exe`オプションも用意可
|
||||
|
||||
#### Linux
|
||||
- 既定: `ld.lld`(開発で`mold`併用可)
|
||||
```bash
|
||||
ld.lld -o a.out main.o -L. -lnyashrt -lc -lm -pthread \
|
||||
--gc-sections --icf=all
|
||||
```
|
||||
|
||||
#### macOS(将来)
|
||||
- 日常は`ld64.lld`、配布はXcodeの`ld64` + コード署名(要Entitlements)
|
||||
|
||||
### 3. 同梱/検出戦略
|
||||
|
||||
**優先順**: 埋め込み`lld` → システム`lld` → 代替(mold/link.exe/ld64)
|
||||
|
||||
```bash
|
||||
nyash toolchain doctor # 検出&パス設定
|
||||
--linker=lld|mold|link.exe|ld64 # 明示上書き
|
||||
```
|
||||
|
||||
### 4. ランタイム同梱
|
||||
|
||||
- `nyashrt`を**static(.a/.lib)**と**shared(.so/.dll)**両用意
|
||||
- 既定は**static**(配布が楽)、`--shared-rt`で動的リンクに切替
|
||||
- Windowsは**PDB生成**、Linuxは`-g`/`-Wl,--build-id`でデバッグ容易に
|
||||
|
||||
## 🔧 エラー整合(ビルド失敗をわかりやすく)
|
||||
|
||||
| エラー種別 | 戻り値 | 説明・対処 |
|
||||
|----------|-------|-----------|
|
||||
| `ny_mir_to_obj`失敗 | `NYCG_ERR_*` | ターゲット不一致/CLIF生成失敗など |
|
||||
| リンク失敗 | リンカ標準出力 | ファイル名/未解決シンボルを整形表示 |
|
||||
|
||||
診断オプション:
|
||||
```bash
|
||||
--emit=clif,asm,obj,link-cmd # 診断をファイル出力(再現しやすい)
|
||||
```
|
||||
|
||||
## 💾 キャッシュ&クロスコンパイル
|
||||
|
||||
### オブジェクトキャッシュ
|
||||
`hash(MIR, target, codegen_ver)` → `.obj/.o`を再利用
|
||||
|
||||
### クロスコンパイル
|
||||
```bash
|
||||
--target=<triple> # .obj/.oとリンク器/SDKを切替
|
||||
```
|
||||
- Win用: `x86_64-pc-windows-msvc`(`lld-link` + MSVCライブラリ)
|
||||
- Linux: `x86_64-unknown-linux-gnu`(`ld.lld` + glibc)
|
||||
|
||||
**Zig toolchain**を併用するとクロス用のCRT/SDKが楽(内部はlld)
|
||||
|
||||
## 🎨 使いやすいCLI例
|
||||
|
||||
```bash
|
||||
nyash build main.ny --backend=cranelift --release
|
||||
nyash build main.ny --emit=obj,asm,clif # 解析用
|
||||
nyash run main.ny --backend=cranelift # JITで即実行
|
||||
nyash toolchain doctor # lld/SDK検出
|
||||
```
|
||||
|
||||
## ⚡ 地味に効く最適化スイッチ
|
||||
|
||||
### リンカ最適化
|
||||
- `ld.lld`: `--gc-sections --icf=all`(不要コード除去&同一関数折りたたみ)
|
||||
|
||||
### Cranelift最適化
|
||||
- `opt_level=speed`
|
||||
- TypedArrayの**bounds-check併合**をLowerで実装
|
||||
|
||||
### 実行時最適化
|
||||
- 起動時CPUIDで**関数ポインタ切替**(AVX2/512の専用小関数)
|
||||
|
||||
## ✅ 最初の"動くまで"チェックリスト
|
||||
|
||||
- [ ] `ny_mir_to_obj`(C ABI)で`.o/.obj`を返せる
|
||||
- [ ] `nyash link <obj> --target=<triple>`が`lld`でEXEを作れる
|
||||
- [ ] Windows/Linuxそれぞれ"Hello, Box!"実行成功
|
||||
- [ ] `--emit=clif,asm`でダンプが落ちる
|
||||
- [ ] 失敗時のエラーメッセージが**ファイル名+未解決シンボル**まで出る
|
||||
- [ ] `nyash toolchain doctor`でlld/SDK検出
|
||||
|
||||
## 📐 実装設計詳細
|
||||
|
||||
### LinkerBox設計
|
||||
```nyash
|
||||
box LinkerBox {
|
||||
init { platform, linker_path, libraries, flags }
|
||||
|
||||
link(objects, output_path) {
|
||||
local cmd = me.build_link_command(objects, output_path)
|
||||
local result = me.execute_linker(cmd)
|
||||
|
||||
if result.exit_code != 0 {
|
||||
me.format_link_error(result.stderr)
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
detect_linker() {
|
||||
// 優先順: 内蔵lld → システムlld → 代替
|
||||
if me.has_embedded_lld() {
|
||||
return me.extract_embedded_lld()
|
||||
}
|
||||
return me.find_system_linker()
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### CraneliftBox統合
|
||||
```nyash
|
||||
box CraneliftBox {
|
||||
init { target_triple, opt_level }
|
||||
|
||||
compile(mir) {
|
||||
// MIR13 → Cranelift IR → Object
|
||||
local module = me.create_module()
|
||||
|
||||
for inst in mir.instructions {
|
||||
me.lower_instruction(module, inst)
|
||||
}
|
||||
|
||||
return module.compile()
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 🌟 まとめ
|
||||
|
||||
- **Yes**: CraneliftでEXEにするには**内部でlldを叩く機能を埋め込む**のが正攻法
|
||||
- 仕組みは**MIR→Cranelift .o/.obj → lld**
|
||||
- C ABIファサード経由でcodegenを呼び、リンカは**内蔵ドライバ**で統一
|
||||
- これで**自己ホスト→即EXE生成**の"気持ちいい体験"が完成!
|
||||
|
||||
## 🔗 関連ドキュメント
|
||||
|
||||
- [Phase 15メインドキュメント](README.md)
|
||||
- [C ABI境界設計](../phase-12/c-abi-spec.md)
|
||||
- [MIR 13命令セット](../../reference/mir/INSTRUCTION_SET.md)
|
||||
- [Cranelift統合](../phase-10/)
|
||||
@ -0,0 +1,213 @@
|
||||
# LLVM Native EXE Generation Strategy
|
||||
|
||||
## 📋 概要
|
||||
|
||||
LLVM バックエンドを使用した完全なネイティブ実行ファイル生成パイプラインの実装戦略。
|
||||
Rustのビルド時間を削減するため、LLVM コンパイラ部分を独立した crate として分離する。
|
||||
|
||||
## 🎯 目標
|
||||
|
||||
### 短期目標(Phase 15.5)
|
||||
1. **LLVM オブジェクト生成の安定化**(ChatGPT5実装中)
|
||||
2. **リンカー統合**によるEXE生成
|
||||
3. **基本的なビルド・実行パイプライン**の確立
|
||||
|
||||
### 中期目標(Phase 15.6)
|
||||
1. **`nyash-llvm-compiler` crate の分離**
|
||||
2. **ビルド時間の大幅短縮**(5分→2分)
|
||||
3. **CI/CD での並列ビルド**対応
|
||||
|
||||
## 🏗️ アーキテクチャ
|
||||
|
||||
### 現在の構成(モノリシック)
|
||||
```
|
||||
nyash-rust/
|
||||
├── Cargo.toml (features = ["llvm"]) # 重い!
|
||||
├── src/
|
||||
│ ├── backend/
|
||||
│ │ └── llvm/ # LLVM実装
|
||||
│ └── main.rs
|
||||
```
|
||||
|
||||
### 目標構成(分離型)
|
||||
```
|
||||
nyash-rust/ # メインクレート(軽量)
|
||||
├── Cargo.toml # LLVM機能なし
|
||||
├── src/
|
||||
|
||||
nyash-llvm-compiler/ # 独立コンパイラ
|
||||
├── Cargo.toml # LLVM依存のみ
|
||||
├── src/
|
||||
│ ├── main.rs # CLI エントリポイント
|
||||
│ ├── mir_reader.rs # MIR入力処理
|
||||
│ ├── codegen/ # LLVM コード生成
|
||||
│ └── linker.rs # リンカー統合
|
||||
```
|
||||
|
||||
## 🔧 実装計画
|
||||
|
||||
### Phase 1: 現在のLLVMバックエンド完成
|
||||
```rust
|
||||
// src/backend/llvm/compiler.rs
|
||||
impl LLVMCompiler {
|
||||
pub fn compile_to_executable(
|
||||
&self,
|
||||
mir: &MirModule,
|
||||
output: &Path,
|
||||
link_options: &LinkOptions,
|
||||
) -> Result<(), Error> {
|
||||
// 1. MIR → LLVM IR
|
||||
let llvm_module = self.compile_module(mir)?;
|
||||
|
||||
// 2. LLVM IR → Object file
|
||||
let obj_path = self.emit_object(llvm_module)?;
|
||||
|
||||
// 3. Link with runtime
|
||||
self.link_executable(obj_path, output, link_options)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Phase 2: インターフェース定義
|
||||
```rust
|
||||
// MIR交換フォーマット(JSON or MessagePack)
|
||||
#[derive(Serialize, Deserialize)]
|
||||
pub struct MirPackage {
|
||||
pub version: u32,
|
||||
pub module: MirModule,
|
||||
pub metadata: CompileMetadata,
|
||||
}
|
||||
|
||||
// コンパイラAPI
|
||||
pub trait MirCompiler {
|
||||
fn compile(&self, package: MirPackage, options: CompileOptions) -> Result<Output>;
|
||||
}
|
||||
```
|
||||
|
||||
### Phase 3: 独立crateの作成
|
||||
```toml
|
||||
# nyash-llvm-compiler/Cargo.toml
|
||||
[package]
|
||||
name = "nyash-llvm-compiler"
|
||||
version = "0.1.0"
|
||||
|
||||
[dependencies]
|
||||
inkwell = { version = "0.5", features = ["llvm18-0"] }
|
||||
serde = { version = "1.0", features = ["derive"] }
|
||||
serde_json = "1.0"
|
||||
clap = { version = "4.0", features = ["derive"] }
|
||||
|
||||
# Nyash共通定義(MIR構造体など)
|
||||
nyash-mir = { path = "../nyash-mir" }
|
||||
```
|
||||
|
||||
### Phase 4: CLI実装
|
||||
```rust
|
||||
// nyash-llvm-compiler/src/main.rs
|
||||
#[derive(Parser)]
|
||||
struct Args {
|
||||
/// Input MIR file (JSON format)
|
||||
input: PathBuf,
|
||||
|
||||
/// Output executable path
|
||||
#[arg(short, long)]
|
||||
output: PathBuf,
|
||||
|
||||
/// Target triple
|
||||
#[arg(long, default_value = "native")]
|
||||
target: String,
|
||||
|
||||
/// Link with nyrt runtime
|
||||
#[arg(long)]
|
||||
nyrt_path: Option<PathBuf>,
|
||||
|
||||
/// Static linking
|
||||
#[arg(long)]
|
||||
static_link: bool,
|
||||
}
|
||||
|
||||
fn main() -> Result<()> {
|
||||
let args = Args::parse();
|
||||
|
||||
// 1. Read MIR
|
||||
let mir_package = read_mir_package(&args.input)?;
|
||||
|
||||
// 2. Compile to object
|
||||
let compiler = LLVMCompiler::new(&args.target)?;
|
||||
let obj_file = compiler.compile_to_object(&mir_package)?;
|
||||
|
||||
// 3. Link
|
||||
let linker = Linker::new()?;
|
||||
linker.link_executable(
|
||||
&obj_file,
|
||||
&args.output,
|
||||
LinkOptions {
|
||||
runtime: args.nyrt_path,
|
||||
static_link: args.static_link,
|
||||
},
|
||||
)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
```
|
||||
|
||||
## 🚀 使用方法
|
||||
|
||||
### 統合実行(将来)
|
||||
```bash
|
||||
# ワンステップビルド
|
||||
nyash build --backend llvm --emit exe program.nyash -o program.exe
|
||||
|
||||
# デバッグ用分離実行
|
||||
nyash --dump-mir program.nyash > program.mir.json
|
||||
nyash-llvm-compiler program.mir.json -o program.exe
|
||||
```
|
||||
|
||||
### パイプライン実行
|
||||
```bash
|
||||
# Unix pipe
|
||||
nyash --dump-mir program.nyash | nyash-llvm-compiler - -o program.exe
|
||||
|
||||
# Windows
|
||||
nyash --dump-mir program.nyash > temp.mir
|
||||
nyash-llvm-compiler temp.mir -o program.exe
|
||||
```
|
||||
|
||||
## 📊 期待される効果
|
||||
|
||||
### ビルド時間の改善
|
||||
```
|
||||
現在:
|
||||
cargo build --release --features llvm # 5-7分
|
||||
|
||||
分離後:
|
||||
cargo build --release # 1-2分(メイン)
|
||||
cd nyash-llvm-compiler && cargo build # 2-3分(LLVM部分)
|
||||
|
||||
並列ビルド可能 → トータル3分程度
|
||||
```
|
||||
|
||||
### CI/CD の改善
|
||||
- メインビルドとLLVMビルドを並列実行
|
||||
- LLVM部分の変更がない場合はキャッシュ利用
|
||||
- プラットフォーム別ビルドの高速化
|
||||
|
||||
## 🔗 関連ファイル
|
||||
- [lld-strategy.md](lld-strategy.md) - Cranelift版のリンカー戦略
|
||||
- [../README.md](../README.md) - Phase 15全体計画
|
||||
- [CURRENT_TASK.md](/mnt/c/git/nyash-project/nyash_self_main/CURRENT_TASK.md) - 現在の実装状況
|
||||
|
||||
## 📅 マイルストーン
|
||||
|
||||
- [ ] ChatGPT5によるLLVMバックエンド完成
|
||||
- [ ] オブジェクトファイル生成の安定化
|
||||
- [ ] build_llvm.shからの移行
|
||||
- [ ] MIR交換フォーマットの確定
|
||||
- [ ] nyash-llvm-compiler crate作成
|
||||
- [ ] CI統合とドキュメント整備
|
||||
|
||||
---
|
||||
|
||||
> 「重いビルドは開発の敵。必要な部分だけを切り出して、高速な開発サイクルを実現するにゃ!」
|
||||
@ -0,0 +1,100 @@
|
||||
# MIR Builder EXE Design (Phase 15 — EXE‑First)
|
||||
|
||||
Purpose: define a standalone MIR Builder executable that takes Nyash JSON IR (v0/v1) and produces native outputs (object/executable), independent of the Rust Runner/VM. This aligns Phase‑15 with an EXE‑first delivery pipeline.
|
||||
|
||||
Goals
|
||||
- Accept JSON IR from stdin or file and validate semantics (minimal passes).
|
||||
- Emit: object (.o/.obj), LLVM IR (.ll), or final executable by linking with NyRT.
|
||||
- Operate without the Rust VM path; suitable for CLI and scripted pipelines.
|
||||
- Keep the boundary simple and observable (stdout diagnostics, exit codes).
|
||||
|
||||
CLI Interface (proposed)
|
||||
- Basic form
|
||||
- `ny_mir_builder [--in <file>|--stdin] [--emit {obj|exe|ll|json}] -o <out> [options]`
|
||||
- Defaults: `--stdin`, `--emit obj`, `-o target/aot_objects/a.o`
|
||||
- Options
|
||||
- `--in <file>`: Input JSON IR file (v0/v1). If omitted, read stdin.
|
||||
- `--emit {obj|exe|ll|json}`: Output kind. `json` emits validated/normalized IR for roundtrip.
|
||||
- `-o <path>`: Output path (object/exe/IR). Default under `target/aot_objects`.
|
||||
- `--target <triple>`: Target triple override (default: host).
|
||||
- `--nyrt <path>`: NyRT static runtime directory (for `--emit exe`).
|
||||
- `--plugin-config <path>`: `nyash.toml` path resolution for boxes/plugins.
|
||||
- `--quiet`: Minimize logs; only errors to stderr.
|
||||
- `--validate-only`: Parse+validate IR; no codegen.
|
||||
- `--verify-llvm`: Run LLVM verifier on generated IR (when `--emit {obj|exe}`).
|
||||
|
||||
Exit Codes
|
||||
- `0` on success; >0 on error. Validation errors produce human‑readable messages on stderr.
|
||||
|
||||
Input IR
|
||||
- JSON v0 (current Bridge spec). Unknown fields are ignored; `meta.usings` is accepted.
|
||||
- Future JSON v1 (additive) must remain backward compatible; builder performs normalization.
|
||||
|
||||
Outputs
|
||||
- `--emit obj`: Native object file. Uses LLVM harness internally.
|
||||
- `--emit ll`: Dumps LLVM IR for diagnostics.
|
||||
- `--emit exe`: Produces a self‑contained executable by linking the object with NyRT.
|
||||
- `--emit json`: Emits normalized MIR JSON (post‑validation) for roundtrip tests.
|
||||
|
||||
Packaging Forms
|
||||
- CLI executable: `ny_mir_builder` (primary).
|
||||
- Optional shared lib: `libny_mir_builder` exposing a minimal C ABI for embedding.
|
||||
|
||||
C ABI Sketch (optional library form)
|
||||
```c
|
||||
// Input: JSON IR bytes. Output: newly allocated buffer with object bytes.
|
||||
// Caller frees via ny_free_buf.
|
||||
int ny_mir_to_obj(const uint8_t* json, size_t len,
|
||||
const char* target_triple,
|
||||
uint8_t** out_buf, size_t* out_len);
|
||||
|
||||
// Convenience linker: object → exe (returns 0=ok).
|
||||
int ny_obj_to_exe(const uint8_t* obj, size_t len,
|
||||
const char* nyrt_dir, const char* out_path);
|
||||
|
||||
void ny_free_buf(void* p);
|
||||
```
|
||||
|
||||
Internal Architecture
|
||||
- Frontend
|
||||
- JSON IR parser → AST/CFG structures compatible with existing MIR builder expectations.
|
||||
- Validation passes: control‑flow well‑formedness, PHI consistency (incoming edges), type sanity for BoxCall/ExternCall minimal set.
|
||||
- Codegen
|
||||
- LLVM harness path (current primary). Environment fallback via `LLVM_SYS_180/181_PREFIX`.
|
||||
- Option flag `NYASH_LLVM_FEATURE=llvm|llvm-inkwell-legacy` maintained for transitional builds.
|
||||
- Linking (`--emit exe`)
|
||||
- Use `cc` with `-L <nyrt>/target/release -lnyrt` (static preferred) + platform libs `-lpthread -ldl -lm` (Unix) or Win equivalents.
|
||||
- Search `nyash.toml` near the output exe and current CWD (same heuristic as NyRT runtime) to initialize plugins at runtime.
|
||||
|
||||
Integration Points
|
||||
- Parser EXE → MIR Builder EXE
|
||||
- `./nyash_compiler <in.nyash> | ny_mir_builder --stdin --emit obj -o a.o`
|
||||
- Compose with link step for quick end‑to‑end: `... --emit exe -o a.out`
|
||||
- Runner (future option)
|
||||
- `NYASH_USE_NY_COMPILER_EXE=1`: Runner spawns parser EXE; optionally chain into MIR Builder EXE for AOT.
|
||||
- Fallback to in‑proc Bridge when EXE pipeline fails.
|
||||
|
||||
Logging & Observability
|
||||
- Default: single‑line summaries on success, detailed errors on failure.
|
||||
- `--quiet` to suppress non‑essential logs; `--verify-llvm` to force verification.
|
||||
- Print `OK obj:<path>` / `OK exe:<path>` on success (stable for scripts).
|
||||
|
||||
Security & Sandboxing
|
||||
- No arbitrary file writes beyond `-o` and temp dirs.
|
||||
- Deny network; fail fast on malformed JSON.
|
||||
|
||||
Platform Notes
|
||||
- Windows: `.obj` + link with MSVC or lld‑link; prefer bundling `nyrt` artifacts.
|
||||
- macOS/Linux: `.o` + `cc` link; RPATH/loader path considerations documented.
|
||||
|
||||
Incremental Plan
|
||||
1) CLI skeleton: stdin/file → validate → `--emit json/ll` (dry path) + golden tests。
|
||||
2) Hook LLVM harness: `--emit obj` for const/arith/branch/ret subset。
|
||||
3) Linker integration: `--emit exe` with NyRT static lib; add platform matrices。
|
||||
4) Parity suite: run produced EXE against known cases (strings/collections minimal)。
|
||||
5) Packaging: `tools/build_mir_builder_exe.sh` + smoke `tools/mir_builder_exe_smoke.sh`。
|
||||
|
||||
Reference Artifacts
|
||||
- `tools/build_llvm.sh`: current harness flow used as a baseline for emission and link steps。
|
||||
- `crates/nyrt`: runtime interface and plugin host initialization heuristics。
|
||||
|
||||
@ -0,0 +1,132 @@
|
||||
# Phase 15 セルフホスティング戦略 2025年9月版
|
||||
|
||||
## 🎯 セルフホスティングの段階的実現戦略
|
||||
|
||||
### 現在地
|
||||
- ✅ v0 Nyパーサー(Ny→JSON IR)完成
|
||||
- ✅ MIR生成基盤あり(Rust実装)
|
||||
- 🚧 LLVM層改善中(ChatGPT5協力)
|
||||
- 📅 NyコンパイラMVP計画中
|
||||
|
||||
### 君の提案の妥当性検証
|
||||
|
||||
## 📊 セルフホスティングの段階
|
||||
|
||||
### Stage 1: LLVM層の独立(最優先)✅
|
||||
```
|
||||
現在: Rustモノリス → MIR → LLVM → オブジェクト
|
||||
提案: Rustモノリス → MIR(JSON) → [LLVM EXE] → ネイティブEXE
|
||||
```
|
||||
|
||||
**実装詳細**:
|
||||
1. `nyash-llvm-compiler` crateを分離
|
||||
2. 入力:MIR(JSON/バイナリ)
|
||||
3. 出力:ネイティブ実行ファイル
|
||||
4. nyrtランタイムとのリンク
|
||||
|
||||
**メリット**:
|
||||
- ビルド時間短縮(Rust側は軽量化)
|
||||
- 独立したツールとして配布可能
|
||||
- パイプライン明確化
|
||||
|
||||
### Stage 2: Nyashコンパイラ実装(現在計画中)✅
|
||||
```
|
||||
現在: Rustパーサー → MIR
|
||||
提案: Nyashコンパイラ → AST/JSON → MIR生成層
|
||||
```
|
||||
|
||||
**実装詳細**:
|
||||
1. Nyashで再帰下降パーサー実装
|
||||
2. AST構造をJSONで出力
|
||||
3. 既存のMIR生成層に接続
|
||||
4. `NYASH_USE_NY_COMPILER=1`で切替
|
||||
|
||||
**これでセルフホスティング達成!**
|
||||
- Nyashで書いたコンパイラがNyashをコンパイル
|
||||
- Rustコンパイラは不要に
|
||||
|
||||
### Stage 3: VM層のNyash実装(革新的)⚡
|
||||
```
|
||||
現在: Rust VM → MIR解釈
|
||||
提案: Nyash VM → MIR解釈 → (必要時LLVM呼び出し)
|
||||
```
|
||||
|
||||
**実装詳細**:
|
||||
```nyash
|
||||
box NyashVMBox {
|
||||
mir_module: MIRModuleBox
|
||||
pc_stack: ArrayBox
|
||||
value_stack: ArrayBox
|
||||
frame_stack: ArrayBox
|
||||
|
||||
execute(mir_json) {
|
||||
me.mir_module = MIRModuleBox.parse(mir_json)
|
||||
me.runFunction("main")
|
||||
}
|
||||
|
||||
runFunction(name) {
|
||||
local func = me.mir_module.getFunction(name)
|
||||
local frame = new FrameBox(func)
|
||||
me.frame_stack.push(frame)
|
||||
|
||||
loop(frame.pc < func.instructions.length()) {
|
||||
local inst = func.instructions[frame.pc]
|
||||
me.executeInstruction(inst, frame)
|
||||
frame.pc = frame.pc + 1
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**メリット**:
|
||||
- **コンパイル不要**で即実行
|
||||
- VMロジックを動的に変更可能
|
||||
- デバッグ・実験が容易
|
||||
|
||||
## 🚀 実現順序の提案
|
||||
|
||||
### Phase 15.2: LLVM独立化
|
||||
1. LLVM層をcrateに分離
|
||||
2. MIR JSONインターフェース確立
|
||||
3. スタンドアロンEXE生成
|
||||
|
||||
### Phase 15.3: Nyashコンパイラ
|
||||
1. パーサー実装(Nyashで)
|
||||
2. AST→MIRブリッジ
|
||||
3. ブートストラップテスト
|
||||
|
||||
### Phase 15.4: VM層Nyash化
|
||||
1. MIR解釈エンジン(基本13命令)
|
||||
2. BoxCall/ExternCallブリッジ
|
||||
3. パフォーマンス最適化(JIT連携)
|
||||
|
||||
## 💡 ABI移行タイミング
|
||||
|
||||
**LLVM独立化完了後が最適**理由:
|
||||
1. インターフェース確定後に最適化
|
||||
2. 独立EXEならABI変更の影響限定的
|
||||
3. パフォーマンス測定してから判断
|
||||
|
||||
## 📋 検証結果
|
||||
|
||||
**君の提案は正しい!**
|
||||
|
||||
1. **LLVM EXE独立** → MIR JSONで疎結合
|
||||
2. **Nyashコンパイラ** → AST/JSONでMIR生成
|
||||
3. **セルフホスト完了** → Rustコンパイラ不要
|
||||
4. **VM層Nyash化** → 究極の柔軟性
|
||||
|
||||
この順序なら:
|
||||
- 段階的に実現可能
|
||||
- 各段階で動作確認
|
||||
- リスク最小化
|
||||
- 最終的に完全セルフホスト
|
||||
|
||||
## 🎯 次のアクション
|
||||
|
||||
1. **LLVM crateの設計開始**
|
||||
2. **MIR JSONスキーマ確定**
|
||||
3. **Nyパーサー拡張計画**
|
||||
4. **VMプロトタイプ設計**
|
||||
|
||||
これが現実的で革新的なロードマップにゃ!
|
||||
@ -0,0 +1,38 @@
|
||||
# Phase 15.3 — Imports/Namespace/nyash.toml Plan
|
||||
|
||||
Status: 15.3 planning; focus remains on Stage‑1/2 compiler MVP. This document scopes when and how to bring `nyash.toml`/include/import/namespace into the selfhost path without destabilizing parity.
|
||||
|
||||
Goals
|
||||
- Keep runner‑level `nyash.toml` parsing/resolution as the source of truth during 15.3.
|
||||
- Accept `using/import` syntax in the Ny compiler as a no‑op (record only) until resolution is delegated.
|
||||
- Avoid VM changes; resolution happens before codegen.
|
||||
|
||||
Scope & Sequence (Phase 15.3)
|
||||
1) Stage‑1/2 compiler stability (primary)
|
||||
- Ny→JSON v0 → Bridge → PyVM/llvmlite parity maintained
|
||||
- PHI merge remains on Bridge (If/Loop)
|
||||
2) Imports/Namespace minimal acceptance (15.3‑late)
|
||||
- Parse `using ns` / `using "path" [as alias]` as statements in the Ny compiler
|
||||
- Do not resolve; emit no JSON entries (or emit metadata) — runner continues to strip/handle
|
||||
- Gate via `NYASH_USING=1`(compat: `NYASH_ENABLE_USING=1`)
|
||||
3) Runner remains in charge
|
||||
- Keep existing Rust runner’s `using` stripping + modules registry population
|
||||
- `nyash.toml` parsing stays in Rust (Phase 15)
|
||||
|
||||
Out of scope (Phase 15)
|
||||
- Porting `nyash.toml` parsing to Ny
|
||||
- Cross‑module codegen/linking in Ny compiler
|
||||
- Advanced include resolution / package graph
|
||||
|
||||
Acceptance (15.3)
|
||||
- Ny compiler can lex/parse `using` forms without breaking Stage‑1/2 programs
|
||||
- Runner path (Rust) continues to resolve `using` and `nyash.toml` as before (parity unchanged)
|
||||
|
||||
Looking ahead (MIR18 / Phase 16)
|
||||
- Evaluate moving `nyash.toml` parsing to Ny as a library box (ConfigBox)
|
||||
- Unify include/import/namespace into a single resolver pass in Ny with a small JSON side channel back to the runner
|
||||
- Keep VM unchanged; all resolution before MIR build
|
||||
|
||||
Switches
|
||||
- `NYASH_USING=1` — enable `using` acceptance in Ny compiler (no resolution; compat: `NYASH_ENABLE_USING=1`)
|
||||
- `NYASH_SKIP_TOML_ENV=1` — skip applying [env] in nyash.toml (existing)
|
||||
@ -0,0 +1,484 @@
|
||||
# MIR Call命令統一 完全移行戦略
|
||||
|
||||
## Executive Summary
|
||||
|
||||
ChatGPT5 Pro A++設計によるMIR Call系命令の完全統一化プロジェクト。6種類の異なるCall命令を1つのMirCallに統一し、4つの実行器すべてで統一処理を実現。Phase 15セルフホスティングの重要な柱として、**5,200行(26%)のコード削減**を達成する。
|
||||
|
||||
## 現在の状況分析
|
||||
|
||||
### ✅ 完了済み項目(Phase 1-2)
|
||||
- **MIR統一定義**: `src/mir/definitions/call_unified.rs`(297行)完成
|
||||
- **Callee enum拡張**: Constructor/Closureバリアント追加済み
|
||||
- **統一メソッド実装**: `emit_unified_call()`と便利メソッド3種実装済み
|
||||
- **環境変数制御**: `NYASH_MIR_UNIFIED_CALL=1`で切り替え可能
|
||||
- **Math関数で実使用**: builder_calls.rs:340-347で統一Call使用中
|
||||
|
||||
### 🔍 現在の実装状況
|
||||
|
||||
#### 1. Call系命令の処理箇所(4つの実行器)
|
||||
|
||||
| 実行器 | ファイル | 行数 | 実装状況 |
|
||||
|-------|----------|------|----------|
|
||||
| **MIR生成** | `src/mir/builder/*.rs` | 3,656行 | ✅ 統一Call部分実装済み |
|
||||
| **VM Interpreter** | `src/backend/mir_interpreter.rs` | 712行 | ✅ Callee型対応済み |
|
||||
| **Python LLVM** | `src/llvm_py/instructions/` | 804行 | ❌ 6種類別々実装 |
|
||||
| **mini-vm (Nyash)** | `apps/selfhost/vm/` | 2,200行 | 🔄 新規実装(最初から統一対応) |
|
||||
|
||||
#### 2. 6種類のCall系命令の分布
|
||||
|
||||
```rust
|
||||
// 現在の6種類
|
||||
MirInstruction::Call { .. } // 汎用関数呼び出し
|
||||
MirInstruction::BoxCall { .. } // Boxメソッド呼び出し
|
||||
MirInstruction::PluginInvoke { .. } // プラグイン呼び出し
|
||||
MirInstruction::ExternCall { .. } // C ABI外部呼び出し
|
||||
MirInstruction::NewBox { .. } // Box コンストラクタ
|
||||
MirInstruction::NewClosure { .. } // クロージャ生成
|
||||
|
||||
// 統一後の1種類
|
||||
MirInstruction::MirCall(MirCall) // すべて統一
|
||||
```
|
||||
|
||||
## 移行戦略詳細
|
||||
|
||||
### Phase 3: MIR Builder完全統一(1週間)
|
||||
|
||||
#### 3.1 高頻度使用箇所の統一(2日)
|
||||
|
||||
**対象箇所**:
|
||||
- `build_indirect_call_expression`(exprs_call.rs:6) - 旧Call生成箇所
|
||||
- `emit_box_or_plugin_call`(utils.rs:75) - BoxCall/PluginInvoke生成
|
||||
- print等の基本関数(builder_calls.rs) - 現在callee: None
|
||||
|
||||
**実装内容**:
|
||||
```rust
|
||||
// Before: 旧Call生成
|
||||
self.emit_instruction(MirInstruction::Call {
|
||||
dst: Some(dst),
|
||||
func: func_val,
|
||||
callee: None, // ← 旧式
|
||||
args,
|
||||
effects: EffectMask::IO,
|
||||
});
|
||||
|
||||
// After: 統一Call生成
|
||||
self.emit_unified_call(
|
||||
Some(dst),
|
||||
CallTarget::Value(func_val),
|
||||
args
|
||||
)?;
|
||||
```
|
||||
|
||||
**期待成果**:
|
||||
- MIR生成器の統一率: 45% → 80%
|
||||
- コード削減: 400行
|
||||
|
||||
#### 3.2 残存emit_*_call系メソッド統一(2日)
|
||||
|
||||
**統一対象**:
|
||||
- `emit_box_or_plugin_call` → `emit_method_call`
|
||||
- `emit_external_call` → `emit_extern_call`
|
||||
- `emit_new_box` → `emit_constructor_call`
|
||||
|
||||
**実装戦略**:
|
||||
1. 各メソッドを統一Call使用に書き換え
|
||||
2. 既存呼び出し箇所を段階的に移行
|
||||
3. `NYASH_MIR_UNIFIED_CALL=1`で切り替えテスト
|
||||
|
||||
#### 3.3 環境変数制御からデフォルト化(3日)
|
||||
|
||||
**段階的デフォルト化**:
|
||||
1. テストスイート全体で統一Call有効化
|
||||
2. スモークテスト + CI通過確認
|
||||
3. 環境変数をデフォルトONに変更
|
||||
4. 旧実装コードの削除
|
||||
|
||||
### Phase 4: Python LLVM統一(1.5週間)
|
||||
|
||||
#### 4.1 統一MirCall処理の実装(4日)
|
||||
|
||||
**新ファイル作成**:
|
||||
```python
|
||||
# src/llvm_py/instructions/mir_call.py
|
||||
def lower_mir_call(builder, module, mir_call, dst_vid, vmap, resolver):
|
||||
"""統一MirCall処理 - 6種類の命令を1箇所で処理"""
|
||||
match mir_call.callee:
|
||||
case Global(name):
|
||||
# 旧call.pyロジック流用
|
||||
case Method(box_name, method, receiver):
|
||||
# 旧boxcall.pyロジック流用
|
||||
case Extern(name):
|
||||
# 旧externcall.pyロジック流用
|
||||
case Constructor(box_type):
|
||||
# 旧newbox.pyロジック流用
|
||||
case Closure(params, captures):
|
||||
# 新規実装
|
||||
case Value(vid):
|
||||
# 動的呼び出し実装
|
||||
```
|
||||
|
||||
#### 4.2 instruction_lower.py統合(2日)
|
||||
|
||||
**dispatch統一**:
|
||||
```python
|
||||
# Before: 6つの分岐
|
||||
elif op == "call":
|
||||
lower_call(...)
|
||||
elif op == "boxcall":
|
||||
lower_boxcall(...)
|
||||
elif op == "externcall":
|
||||
lower_externcall(...)
|
||||
# ... 他3種類
|
||||
|
||||
# After: 1つの統一分岐
|
||||
elif op == "mir_call":
|
||||
lower_mir_call(owner, builder, inst["mir_call"], inst.get("dst"), func)
|
||||
```
|
||||
|
||||
#### 4.3 既存ファイル削除とリファクタ(4日)
|
||||
|
||||
**削除対象**:
|
||||
- `instructions/call.py` (172行)
|
||||
- `instructions/boxcall.py` (425行)
|
||||
- `instructions/externcall.py` (207行)
|
||||
- **合計**: 804行削除
|
||||
|
||||
**期待成果**:
|
||||
- Python LLVM実装: 804行 → 300行(63%削減)
|
||||
- 処理統一による最適化機会増加
|
||||
|
||||
### Phase 5: VM Interpreter最適化(1週間)
|
||||
|
||||
#### 5.1 統一execute_mir_call実装(3日)
|
||||
|
||||
現在のVMはCallee型対応済みだが、さらなる統一と最適化を実施:
|
||||
|
||||
```rust
|
||||
// 統一実行器
|
||||
fn execute_mir_call(&mut self, mir_call: &MirCall) -> Result<VMValue, VMError> {
|
||||
match &mir_call.callee {
|
||||
Callee::Global(name) => self.execute_global_function(name, &mir_call.args),
|
||||
Callee::Method { receiver: Some(recv), method, .. } => {
|
||||
let recv_val = self.reg_load(*recv)?;
|
||||
self.execute_method_call(&recv_val, method, &mir_call.args)
|
||||
},
|
||||
Callee::Constructor { box_type } => {
|
||||
self.execute_constructor_call(box_type, &mir_call.args)
|
||||
},
|
||||
Callee::Extern(name) => self.execute_extern_call(name, &mir_call.args),
|
||||
// ... 他のパターン
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### 5.2 既存分岐削除(2日)
|
||||
|
||||
**削除対象**:
|
||||
- `execute_callee_call`と`execute_legacy_call`の分岐
|
||||
- 6種類のCall命令別処理ロジック
|
||||
|
||||
#### 5.3 エラーハンドリング改善(2日)
|
||||
|
||||
統一された呼び出し処理により、エラー処理も統一化。
|
||||
|
||||
### Phase 6: mini-vm統一対応(5日)
|
||||
|
||||
mini-vmは新規実装のため、最初から統一MirCall対応で実装:
|
||||
|
||||
```nyash
|
||||
// apps/selfhost/vm/call_executor.nyash
|
||||
static box CallExecutor {
|
||||
execute(mir_call: MirCallBox) {
|
||||
local callee_type = mir_call.getCalleeType()
|
||||
match callee_type {
|
||||
"Global" => me.executeGlobal(mir_call)
|
||||
"Method" => me.executeMethod(mir_call)
|
||||
"Constructor" => me.executeConstructor(mir_call)
|
||||
"Extern" => me.executeExtern(mir_call)
|
||||
_ => panic("Unknown callee type: " + callee_type)
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## コード削減見込み
|
||||
|
||||
### 削減内訳
|
||||
|
||||
| フェーズ | 対象領域 | 現在行数 | 削減行数 | 削減率 |
|
||||
|---------|----------|----------|----------|--------|
|
||||
| **Phase 3** | MIR Builder | 3,656行 | 800行 | 22% |
|
||||
| **Phase 4** | Python LLVM | 804行 | 504行 | 63% |
|
||||
| **Phase 5** | VM Interpreter | 712行 | 200行 | 28% |
|
||||
| **Phase 6** | mini-vm | 2,200行 | 400行* | 18% |
|
||||
| **共通** | 統一定義活用 | - | +200行 | - |
|
||||
|
||||
**総計**: **5,372行 → 4,472行** = **900行削減(17%減)**
|
||||
|
||||
\* mini-vmは最初から統一実装のため、削減ではなく最適実装
|
||||
|
||||
### Phase 15目標への寄与
|
||||
|
||||
- **Phase 15目標**: 80k行 → 20k行(75%削減)
|
||||
- **MirCall統一寄与**: 900行削減 = **全体の4.5%**
|
||||
- **複合効果**: 統一による他システムへの波及効果で追加2-3%
|
||||
|
||||
## スケジュール
|
||||
|
||||
### ✅ 完了済み(2025-09-24)
|
||||
- ✅ Phase 3.1: build_indirect_call_expression統一移行(完了)
|
||||
- ✅ Phase 3.2: print等基本関数のCallee型適用(完了)
|
||||
|
||||
### 🔧 進行中(今週)
|
||||
- 🔄 Phase 3.3: emit_box_or_plugin_call統一化(1-2日)
|
||||
|
||||
### 📅 実装優先順位(戦略的判断済み)
|
||||
|
||||
#### **第1優先: Python LLVM(来週)** - 最大削減効果
|
||||
- **Phase 4.1**: Python LLVM dispatch統一(2-3日)
|
||||
- `src/llvm_py/llvm_builder.py`の6種類分岐→1つに統一
|
||||
- 環境変数で段階移行
|
||||
- **Phase 4.2**: Python LLVM統一処理実装(3-4日)
|
||||
- 804行→300行(**63%削減**)
|
||||
- 統一dispatch_unified_call()実装
|
||||
|
||||
#### **第2優先: PyVM/VM(再来週)** - 実行器中核
|
||||
- **Phase 5**: VM Interpreter統一execute実装(4-5日)
|
||||
- `src/backend/mir_interpreter.rs`(Rust VM)
|
||||
- `pyvm/vm.py`(Python VM)
|
||||
- 712行→512行(28%削減)
|
||||
|
||||
#### **第3優先: mini-vm(その後)** - 新規実装
|
||||
- **Phase 6**: mini-vm統一Call実装(5日)
|
||||
- 最初から統一実装なので削減ではなく最適実装
|
||||
- セルフホスティング検証
|
||||
|
||||
### 長期(完成後)
|
||||
- 📅 Phase 7: 旧命令完全削除(3日)
|
||||
- 📅 Phase 8: 最適化とクリーンアップ(1週間)
|
||||
|
||||
## リスク管理
|
||||
|
||||
### 🚨 主要リスク
|
||||
|
||||
1. **パフォーマンス影響**
|
||||
- **対策**: ベンチマーク測定、最適化パス追加
|
||||
- **閾値**: 5%以上の性能低下で要改善
|
||||
|
||||
2. **既存コードの破壊的変更**
|
||||
- **対策**: 段階的移行、環境変数による切り替え
|
||||
- **ロールバック**: 旧実装を環境変数で復活可能
|
||||
|
||||
3. **テストの複雑性**
|
||||
- **対策**: 統一後に統合テスト追加
|
||||
- **CI継続**: 各フェーズでCI通過を確認
|
||||
|
||||
### 🎯 成功指標
|
||||
|
||||
#### Phase別チェックポイント
|
||||
|
||||
| Phase | 成功指標 |
|
||||
|-------|----------|
|
||||
| **Phase 3** | MIR生成器でemit_unified_call使用率80%以上 |
|
||||
| **Phase 4** | Python LLVM実装の命令数6→1への削減完了 |
|
||||
| **Phase 5** | VM実行器のCall統一処理性能5%以内 |
|
||||
| **Phase 6** | mini-vm統一実装完了、セルフホスティング可能 |
|
||||
|
||||
#### パフォーマンス目標
|
||||
|
||||
- **コンパイル時間**: 現状維持(±5%以内)
|
||||
- **実行時間**: 現状維持または向上(統一最適化効果)
|
||||
- **メモリ使用量**: 10%以上削減(重複コード除去効果)
|
||||
|
||||
## 実装サンプルコード
|
||||
|
||||
### 1. MIR Builder統一
|
||||
|
||||
```rust
|
||||
// src/mir/builder/builder_calls.rs
|
||||
impl MirBuilder {
|
||||
/// 段階的移行メソッド - 旧emit_box_or_plugin_callを置き換え
|
||||
pub fn emit_method_call_unified(
|
||||
&mut self,
|
||||
dst: Option<ValueId>,
|
||||
receiver: ValueId,
|
||||
method: String,
|
||||
args: Vec<ValueId>,
|
||||
) -> Result<Option<ValueId>, String> {
|
||||
// 環境変数チェック
|
||||
if std::env::var("NYASH_MIR_UNIFIED_CALL").unwrap_or("0") == "1" {
|
||||
// 統一Call使用
|
||||
self.emit_unified_call(
|
||||
dst,
|
||||
CallTarget::Method {
|
||||
receiver,
|
||||
method,
|
||||
box_name: "InferredBox".to_string(), // 型推論で解決
|
||||
},
|
||||
args
|
||||
)
|
||||
} else {
|
||||
// 従来のBoxCall使用
|
||||
self.emit_box_or_plugin_call(dst, receiver, &method, None, args, EffectMask::IO)
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 2. Python LLVM統一
|
||||
|
||||
```python
|
||||
# src/llvm_py/instructions/mir_call.py
|
||||
def lower_mir_call(owner, builder, mir_call_dict, dst_vid, func):
|
||||
"""統一MirCall処理 - ChatGPT5 Pro A++設計の実装"""
|
||||
callee = mir_call_dict["callee"]
|
||||
args = mir_call_dict["args"]
|
||||
|
||||
match callee["type"]:
|
||||
case "Global":
|
||||
# 旧call.pyロジックを統合
|
||||
return _lower_global_call(
|
||||
builder, owner.module, callee["name"],
|
||||
args, dst_vid, owner.vmap, owner.resolver
|
||||
)
|
||||
case "Method":
|
||||
# 旧boxcall.pyロジックを統合
|
||||
return _lower_method_call(
|
||||
builder, owner.module, callee["receiver"],
|
||||
callee["method"], args, dst_vid, owner.vmap
|
||||
)
|
||||
case "Constructor":
|
||||
# NewBox相当の実装
|
||||
return _lower_constructor_call(
|
||||
builder, owner.module, callee["box_type"],
|
||||
args, dst_vid, owner.vmap
|
||||
)
|
||||
case _:
|
||||
raise NotImplementedError(f"Callee type {callee['type']} not supported")
|
||||
```
|
||||
|
||||
### 3. VM Interpreter最適化
|
||||
|
||||
```rust
|
||||
// src/backend/mir_interpreter.rs
|
||||
impl MirInterpreter {
|
||||
fn execute_mir_call_unified(&mut self, mir_call: &MirCall) -> Result<VMValue, VMError> {
|
||||
// エフェクト検証
|
||||
if mir_call.flags.no_return {
|
||||
// no_return系の処理(panic, exit等)
|
||||
return self.execute_no_return_call(&mir_call.callee, &mir_call.args);
|
||||
}
|
||||
|
||||
// 型安全な呼び出し
|
||||
let result = match &mir_call.callee {
|
||||
Callee::Global(name) => {
|
||||
self.execute_builtin_function(name, &mir_call.args)?
|
||||
}
|
||||
Callee::Method { receiver: Some(recv), method, box_name } => {
|
||||
let recv_val = self.reg_load(*recv)?;
|
||||
self.execute_typed_method(&recv_val, box_name, method, &mir_call.args)?
|
||||
}
|
||||
Callee::Constructor { box_type } => {
|
||||
self.execute_box_constructor(box_type, &mir_call.args)?
|
||||
}
|
||||
Callee::Extern(name) => {
|
||||
self.execute_c_abi_call(name, &mir_call.args)?
|
||||
}
|
||||
_ => return Err(VMError::InvalidInstruction("Unsupported callee type".into())),
|
||||
};
|
||||
|
||||
// 結果格納
|
||||
if let Some(dst) = mir_call.dst {
|
||||
self.regs.insert(dst, result.clone());
|
||||
}
|
||||
|
||||
Ok(result)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 新しいTodoリスト案
|
||||
|
||||
基づいて実装するべきタスク(優先順位付き):
|
||||
|
||||
### 🔥 Urgent(1週間以内)
|
||||
|
||||
1. **build_indirect_call_expression統一移行**
|
||||
- `exprs_call.rs:6`を`emit_unified_call`使用に変更
|
||||
- テスト: 関数呼び出し動作確認
|
||||
|
||||
2. **print等基本関数のCallee型適用**
|
||||
- `builder_calls.rs`でcallee: None箇所を修正
|
||||
- Global("print")等の明示的Callee指定
|
||||
|
||||
3. **emit_box_or_plugin_call統一化**
|
||||
- `utils.rs:75`の処理を`emit_method_call`に集約
|
||||
- BoxCall/PluginInvokeの生成統一
|
||||
|
||||
### ⚡ High(2-3週間以内)
|
||||
|
||||
4. **Python LLVM dispatch統一**
|
||||
- `instruction_lower.py`で6分岐→1分岐に統合
|
||||
- `mir_call.py`新規作成
|
||||
|
||||
5. **Python LLVM統一処理実装**
|
||||
- call/boxcall/externcallロジックをmix
|
||||
- 804行→300行の大幅削減
|
||||
|
||||
6. **VM Interpreter統一execute実装**
|
||||
- `execute_callee_call`と`execute_legacy_call`統合
|
||||
- エラーハンドリング改善
|
||||
|
||||
### 📅 Medium(1ヶ月以内)
|
||||
|
||||
7. **mini-vm統一Call実装**
|
||||
- `apps/selfhost/vm/call_executor.nyash`作成
|
||||
- Nyashでの統一処理実装
|
||||
|
||||
8. **環境変数デフォルト化**
|
||||
- `NYASH_MIR_UNIFIED_CALL=1`をデフォルトに
|
||||
- CI/テスト全体での統一Call使用
|
||||
|
||||
9. **旧実装コード削除**
|
||||
- Python LLVM旧ファイル3種削除
|
||||
- MIR Builder旧メソッド削除
|
||||
|
||||
### 🧹 Low(継続的)
|
||||
|
||||
10. **パフォーマンス測定とベンチマーク**
|
||||
- 統一Call前後の性能比較
|
||||
- 最適化機会の特定
|
||||
|
||||
11. **統合テスト追加**
|
||||
- 4実行器での統一動作テスト
|
||||
- エラーケース検証
|
||||
|
||||
12. **ドキュメント更新**
|
||||
- MIR仕様書の統一Call反映
|
||||
- 開発者ガイド更新
|
||||
|
||||
## 期待される成果
|
||||
|
||||
### 📊 定量的成果
|
||||
|
||||
- **コード削減**: 900行(17%)
|
||||
- **命令種類**: 6種類 → 1種類(83%削減)
|
||||
- **メンテナンス負荷**: 4箇所 × 6種類 = 24パターン → 4箇所 × 1種類 = 4パターン(83%削減)
|
||||
|
||||
### 🚀 定性的成果
|
||||
|
||||
- **開発体験向上**: 新Call実装時の工数大幅削減
|
||||
- **バグ削減**: 統一処理によるエッジケース減少
|
||||
- **最適化機会**: 統一されたCall処理による最適化効果
|
||||
- **AI協働開発**: ChatGPT5 Pro設計の実証完了
|
||||
|
||||
### 🎯 Phase 15への戦略的寄与
|
||||
|
||||
MirCall統一は単なるコード削減を超えて:
|
||||
|
||||
1. **セルフホスティング加速**: mini-vmの統一実装による開発効率化
|
||||
2. **AI設計実証**: ChatGPT5 Pro A++設計の実用性証明
|
||||
3. **拡張性確保**: 新しいCall種類の追加が極めて容易に
|
||||
4. **保守性向上**: 4実行器×1統一処理による保守負荷激減
|
||||
|
||||
この包括的移行により、Phase 15の80k→20k行革命において重要な役割を果たし、Nyashセルフホスティングの技術的基盤を確立する。
|
||||
@ -0,0 +1,288 @@
|
||||
# MIR Callee型実装ロードマップ - Phase 15.4
|
||||
|
||||
## 概要
|
||||
|
||||
ChatGPT5 Pro設計案に基づく、MIR Call命令の根本的改良実装計画。3段階の段階的実装により、破壊的変更を回避しながら設計革新を実現。
|
||||
|
||||
## 実装優先度マトリックス
|
||||
|
||||
| 段階 | 実装コスト | 効果 | リスク | 期間 | 優先度 |
|
||||
|------|----------|------|--------|------|--------|
|
||||
| Phase 1: 最小変更 | ⭐ | ⭐⭐⭐ | ⭐ | 2-3日 | 🟢 **最高** |
|
||||
| Phase 2: HIR導入 | ⭐⭐⭐ | ⭐⭐⭐⭐ | ⭐⭐ | 1-2週間 | 🟡 **高** |
|
||||
| Phase 3: 言語仕様 | ⭐⭐⭐⭐ | ⭐⭐⭐⭐⭐ | ⭐ | 1ヶ月 | 🟠 **中** |
|
||||
|
||||
## Phase 1: 最小変更実装(即実装可能)
|
||||
|
||||
### 🎯 **目標**: 破壊的変更なしでCallee型基盤確立
|
||||
|
||||
### 📋 **実装チェックリスト**
|
||||
|
||||
#### Step 1.1: MIR型定義追加
|
||||
- [ ] `src/mir/mod.rs`: Callee列挙型定義
|
||||
- [ ] `src/mir/mod.rs`: Call構造体にcalleeフィールド追加
|
||||
- [ ] 互換性テスト: 既存MIRテストの全面パス確認
|
||||
|
||||
#### Step 1.2: ビルダー修正
|
||||
- [ ] `src/mir/builder/builder_calls.rs`: resolve_call_target()実装
|
||||
- [ ] `src/mir/builder/builder_calls.rs`: build_function_call()修正
|
||||
- [ ] ビルトイン関数リスト作成: is_builtin_function()
|
||||
- [ ] 警告システム追加: emit_warning()
|
||||
|
||||
#### Step 1.3: 実行器対応
|
||||
- [ ] `src/backend/vm/`: Callee対応実行器
|
||||
- [ ] `src/backend/llvm/`: LLVM Callee変換
|
||||
- [ ] `src/backend/pyvm/`: PyVM Callee処理
|
||||
- [ ] フォールバック処理: 旧func使用時の警告
|
||||
|
||||
#### Step 1.4: テスト・検証
|
||||
- [ ] 基本テスト: `print("hello")`→Callee::Global変換
|
||||
- [ ] ボックステスト: `obj.method()`→Callee::Method変換
|
||||
- [ ] 互換性テスト: 全既存テストのパス確認
|
||||
- [ ] MIRダンプ確認: Callee情報の正確な出力
|
||||
|
||||
### 📂 **具体的ファイル変更**
|
||||
|
||||
#### `src/mir/mod.rs`
|
||||
```rust
|
||||
// 追加: Callee型定義
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
pub enum Callee {
|
||||
Global(String),
|
||||
Method {
|
||||
box_name: String,
|
||||
method: String,
|
||||
receiver: Option<ValueId>,
|
||||
},
|
||||
Value(ValueId),
|
||||
Extern(String),
|
||||
}
|
||||
|
||||
// 修正: Call構造体
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
pub struct Call {
|
||||
pub dst: Option<ValueId>,
|
||||
pub func: ValueId, // 既存(廃止予定)
|
||||
pub callee: Option<Callee>, // 新規(優先)
|
||||
pub args: Vec<ValueId>,
|
||||
pub effects: EffectMask,
|
||||
}
|
||||
```
|
||||
|
||||
#### `src/mir/builder/builder_calls.rs`
|
||||
```rust
|
||||
impl MirBuilder {
|
||||
// 新規: 呼び出し先解決
|
||||
fn resolve_call_target(&self, name: &str) -> Result<Callee, String> {
|
||||
// 1. ビルトイン関数チェック
|
||||
if self.is_builtin_function(name) {
|
||||
return Ok(Callee::Global(name.to_string()));
|
||||
}
|
||||
|
||||
// 2. 現在のボックスメソッドチェック
|
||||
if let Some(box_name) = &self.current_static_box {
|
||||
if self.has_method(box_name, name) {
|
||||
self.emit_warning(Warning::PotentialSelfRecursion {
|
||||
method: name.to_string()
|
||||
});
|
||||
return Ok(Callee::Method {
|
||||
box_name: box_name.clone(),
|
||||
method: name.to_string(),
|
||||
receiver: None,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// 3. ローカル変数として関数値
|
||||
if self.variable_map.contains_key(name) {
|
||||
let value_id = self.variable_map[name];
|
||||
return Ok(Callee::Value(value_id));
|
||||
}
|
||||
|
||||
// 4. 解決失敗
|
||||
Err(format!("Unresolved function: {}", name))
|
||||
}
|
||||
|
||||
// 新規: ビルトイン関数判定
|
||||
fn is_builtin_function(&self, name: &str) -> bool {
|
||||
matches!(name, "print" | "error" | "panic" | "exit" | "now")
|
||||
}
|
||||
|
||||
// 修正: 関数呼び出しビルド
|
||||
pub fn build_function_call(
|
||||
&mut self,
|
||||
name: String,
|
||||
args: Vec<ASTNode>
|
||||
) -> Result<ValueId, String> {
|
||||
let callee = self.resolve_call_target(&name)?;
|
||||
|
||||
let mut arg_values = Vec::new();
|
||||
for arg in args {
|
||||
arg_values.push(self.build_expression(arg)?);
|
||||
}
|
||||
|
||||
let dst = self.value_gen.next();
|
||||
|
||||
// 新型使用
|
||||
self.emit_instruction(MirInstruction::Call {
|
||||
dst: Some(dst),
|
||||
func: self.value_gen.next(), // ダミー(互換性)
|
||||
callee: Some(callee),
|
||||
args: arg_values,
|
||||
effects: EffectMask::READ,
|
||||
})?;
|
||||
|
||||
Ok(dst)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### `src/backend/vm/mod.rs`
|
||||
```rust
|
||||
// Callee対応実行器
|
||||
fn execute_call(
|
||||
vm: &mut VM,
|
||||
dst: Option<ValueId>,
|
||||
func: ValueId,
|
||||
callee: Option<&Callee>,
|
||||
args: &[ValueId],
|
||||
) -> Result<(), VMError> {
|
||||
if let Some(callee) = callee {
|
||||
match callee {
|
||||
Callee::Global(name) => {
|
||||
execute_global_function(vm, name, args, dst)
|
||||
},
|
||||
Callee::Method { box_name, method, receiver } => {
|
||||
execute_method_call(vm, box_name, method, receiver, args, dst)
|
||||
},
|
||||
Callee::Value(func_val) => {
|
||||
execute_dynamic_call(vm, *func_val, args, dst)
|
||||
},
|
||||
Callee::Extern(name) => {
|
||||
execute_extern_call(vm, name, args, dst)
|
||||
},
|
||||
}
|
||||
} else {
|
||||
// フォールバック: 旧実装(警告付き)
|
||||
eprintln!("Warning: Using deprecated string-based function call");
|
||||
execute_string_based_call(vm, func, args, dst)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 🧪 **テスト戦略**
|
||||
|
||||
#### 基本機能テスト
|
||||
```nyash
|
||||
// Test 1: グローバル関数
|
||||
print("Hello World") // → Callee::Global("print")
|
||||
|
||||
// Test 2: ボックスメソッド
|
||||
static box Test {
|
||||
method() {
|
||||
print("from method") // → 警告 + Callee::Method
|
||||
}
|
||||
}
|
||||
|
||||
// Test 3: 関数値
|
||||
local f = print
|
||||
f("dynamic") // → Callee::Value
|
||||
```
|
||||
|
||||
#### MIRダンプ検証
|
||||
```
|
||||
# 期待される出力
|
||||
call global "print" ["Hello World"]
|
||||
call method Test::method() ["from method"] # 警告付き
|
||||
call value %42 ["dynamic"]
|
||||
```
|
||||
|
||||
## Phase 2: HIR導入(中期)
|
||||
|
||||
### 🎯 **目標**: コンパイル時名前解決の確立
|
||||
|
||||
### 📋 **実装計画**
|
||||
- AST→HIR変換層追加
|
||||
- Symbol Table構築
|
||||
- BindingId→FunctionId/MethodIdマッピング
|
||||
- MIRビルダの文字列依存完全排除
|
||||
|
||||
### 🗓️ **実装期間**: 1-2週間
|
||||
|
||||
## Phase 3: 言語仕様統合(長期)
|
||||
|
||||
### 🎯 **目標**: 明示的スコープと完全修飾名
|
||||
|
||||
### 📋 **実装計画**
|
||||
- パーサー拡張: `::print`, `global::print`
|
||||
- 完全修飾名システム
|
||||
- import/moduleシステム
|
||||
- 静的解析・リンタ統合
|
||||
|
||||
### 🗓️ **実装期間**: 1ヶ月
|
||||
|
||||
## Phase 15統合戦略
|
||||
|
||||
### セルフホスティング安定化への直接寄与
|
||||
|
||||
1. **using system連携**
|
||||
- `using nyashstd`→Callee::Global統合
|
||||
- built-in namespace解決の最適化
|
||||
|
||||
2. **PyVM最適化**
|
||||
- 型付き呼び出しによる実行高速化
|
||||
- 動的解決オーバーヘッド削減
|
||||
|
||||
3. **LLVM最適化**
|
||||
- 静的解決による最適化機会拡大
|
||||
- インライン化・特殊化の実現
|
||||
|
||||
### 80k→20k行目標への寄与
|
||||
|
||||
#### 削減予想(Phase 1のみ)
|
||||
- 実行時解決ロジック削減: ~800行
|
||||
- エラー処理の簡略化: ~400行
|
||||
- デバッグコードの削減: ~300行
|
||||
- **Phase 1合計**: ~1500行(目標の7.5%)
|
||||
|
||||
#### 削減予想(全Phase完了時)
|
||||
- 名前解決の一元化: ~2000行
|
||||
- 実行時解決完全排除: ~1500行
|
||||
- デバッグ・エラー処理: ~1000行
|
||||
- **全Phase合計**: ~4500行(目標の22.5%)
|
||||
|
||||
## リスク管理
|
||||
|
||||
### 実装リスク
|
||||
- **互換性破損**: Option<Callee>による段階移行で回避
|
||||
- **パフォーマンス劣化**: ベンチマークによる継続監視
|
||||
- **複雑性増大**: 明確な段階分離とドキュメント化
|
||||
|
||||
### 検証方法
|
||||
- 各段階でのスモークテスト実施
|
||||
- 既存テストスイートの全面グリーン維持
|
||||
- パフォーマンスベンチマークの継続実行
|
||||
|
||||
## 成功指標
|
||||
|
||||
### Phase 1成功基準
|
||||
- [ ] 全既存テストパス(グリーン維持)
|
||||
- [ ] シャドウイング無限再帰の完全排除
|
||||
- [ ] MIRダンプにCallee情報正確表示
|
||||
- [ ] 警告システムの適切な動作
|
||||
- [ ] パフォーマンス劣化なし(±5%以内)
|
||||
|
||||
### 最終成功基準
|
||||
- [ ] 実行時文字列解決の完全排除
|
||||
- [ ] コンパイル時エラー検出の実現
|
||||
- [ ] デバッグ体験の劇的改善
|
||||
- [ ] 80k→20k行目標への明確な寄与
|
||||
- [ ] Phase 15セルフホスティング安定化
|
||||
|
||||
---
|
||||
|
||||
**実装開始**: 2025-09-23
|
||||
**Phase 1完了予定**: 2025-09-26
|
||||
**最終完了予定**: 2025-10-23
|
||||
|
||||
*この計画はChatGPT5 Proとの協働により策定され、段階的実装により確実な成功を目指します。*
|
||||
88
docs/private/roadmap/phases/phase-15/phase-15.1/README.md
Normal file
88
docs/private/roadmap/phases/phase-15/phase-15.1/README.md
Normal file
@ -0,0 +1,88 @@
|
||||
# Phase 15.1 — Self-Hosting AOT-Plan to MIR13 (Nyash-first)
|
||||
|
||||
Scope: Extend Phase 15 (Self-Hosting Ny → MIR → VM/JIT) with a small, safe subphase that keeps VM/JIT primary, and prepares a future AOT pipeline by introducing:
|
||||
|
||||
- Nyash scripts that perform AOT preflight analysis across `using` trees
|
||||
- A stable AOT-Plan JSON schema (functions, externs, exports, type hints, link units)
|
||||
- A compiler-side importer that lowers AOT-Plan → MIR13 skeletons (no object code yet)
|
||||
|
||||
Avoid: deep AOT emission/linking, cross-platform toolchain work, or scope creep beyond planning and MIR13 import.
|
||||
|
||||
## Phase 15 Goals (context)
|
||||
|
||||
- VM-first correctness; JIT as compiler-only, not required for AOT deliverables
|
||||
- Minimal policy: read-only JIT-direct default, deny mut hostcalls unless whitelisted
|
||||
- Observability: compile/runtime JSONL events; counters for lower-time fallbacks
|
||||
- Short-circuit lowering and core collection ops kept consistent
|
||||
|
||||
## Phase 15.1 Objectives
|
||||
|
||||
- AOT-Plan via Nyash scripts (self-hosted analysis):
|
||||
- Parse sources with `using` resolution; build function inventory and extern references
|
||||
- Compute minimal “link unit” groups (per file or per module) pragmatically
|
||||
- Produce `aot_plan.v1.json`
|
||||
|
||||
- MIR13 importer:
|
||||
- Read AOT-Plan → create MIR13 functions with signatures and extern stubs
|
||||
- Leave bodies empty or minimal where applicable; execution stays VM/JIT
|
||||
|
||||
- Smokes:
|
||||
- `plan: using` on 2–3 small Nyash projects; output deterministic JSON
|
||||
- Import the plan and run via VM to confirm pipeline integrity (no AOT emit)
|
||||
|
||||
## Deliverables
|
||||
|
||||
- `tools/aot_plan/` Nyash scripts and helpers
|
||||
- `docs/design/aot-plan-v1.md` (lightweight schema)
|
||||
- Compiler entry to import AOT-Plan → MIR13 (feature-gated)
|
||||
- 3 smokes + 1 golden JSON sample
|
||||
|
||||
## Out of Scope (Phase 15.1)
|
||||
|
||||
- Object emission, linkers, archive/rpath, platform toolchains
|
||||
- Non-trivial inliner/optimizer passes dedicated to AOT
|
||||
|
||||
## Milestones
|
||||
|
||||
1) AOT-Plan schema v1
|
||||
- Minimal fields: functions, externs, exports, units, types(optional)
|
||||
- Golden JSON example committed
|
||||
|
||||
2) Nyash analyzer (self-hosted)
|
||||
- Walk `using` graph; collect symbols and extern refs
|
||||
- Output `aot_plan.v1.json`
|
||||
|
||||
3) Importer to MIR13
|
||||
- Map functions → MIR13 signatures and extern call placeholders
|
||||
- Feature-gate import; maintain VM/JIT run with consistency
|
||||
|
||||
4) Smokes + Observability
|
||||
- 3 projects → stable plan JSON; importer round-trip builds MIR
|
||||
- Emit `jit::events` low-volume markers: `aot_plan.import`, `aot_plan.analyze`
|
||||
|
||||
## Risk & Guardrails
|
||||
|
||||
- Risk: scope creep to AOT emit → Guard: no obj/link in 15.1
|
||||
- Risk: importer expands semantics
|
||||
→ Guard: stub bodies only; effects mask conservative; VM reference behavior unchanged
|
||||
- Risk: plan schema churn → Guard: v1 frozen; add `extensions` map for future keys
|
||||
|
||||
---
|
||||
|
||||
## Consultation Notes (Gemini / Claude)
|
||||
|
||||
Prompts used:
|
||||
- Gemini: "Phase 15 self-hosting goals (VM-first/JIT-compiler-only). Propose a 2-week 15.1 scope to add Nyash-driven AOT preflight that outputs a stable AOT plan JSON, plus a MIR13 importer—no object emission. Include milestones, acceptance criteria, and guardrails to prevent scope creep. Keep implementation incremental and observable."
|
||||
- Claude: "Given an existing Ny parser and using-resolution, design a minimal AOT planning pipeline as Ny scripts that produces a plan.json (functions/externs/exports/units). Define the MIR13 importer requirements and tests ensuring VM/JIT behavior remains canonical. Provide risks, do-not-do list, and minimal telemetry."
|
||||
|
||||
Key takeaways aligned into this document:
|
||||
- Keep 15.1 as a planning/import phase with strong do-not-do
|
||||
- Make plan JSON stable and small; let importer be skeletal
|
||||
- Add clear smokes and counters; avoid new runtime semantics
|
||||
|
||||
## Acceptance Criteria
|
||||
|
||||
- `tools/aot_plan` can analyze a small project with `using` and emit deterministic JSON
|
||||
- Importer can read that JSON and construct MIR13 module(s) without panics
|
||||
- VM runs those modules and matches expected string/number results for trivial bodies
|
||||
- Events present when enabled; counters reflect plan/import activity; no AOT emit performed
|
||||
@ -0,0 +1,332 @@
|
||||
# Phase 15.5: Core Box Unification - 3層→2層革命
|
||||
|
||||
## 📅 実施期間
|
||||
2025年9月24日〜10月15日(3週間)
|
||||
|
||||
## ✅ **実装完了状況**(2025-09-24更新)
|
||||
|
||||
### 🏆 **Phase 15.5-A: プラグインチェッカー拡張完成**
|
||||
**ChatGPT5 Pro最高評価(⭐⭐⭐⭐⭐)機能を完全実装**
|
||||
|
||||
#### 実装詳細
|
||||
- **場所**: `tools/plugin-tester/src/main.rs`
|
||||
- **新コマンド**: `safety-check`サブコマンド追加
|
||||
- **実装規模**: ~300行の高品質Rust実装
|
||||
- **CLIオプション**: `--library`, `--box-type`でフィルタ対応
|
||||
|
||||
#### 4つの安全性機能
|
||||
1. **ユニバーサルスロット衝突検出**:0-3番スロット(toString/type/equals/clone)保護
|
||||
2. **StringBox問題専用検出**:get=1,set=2問題の完全自動検出
|
||||
3. **E_METHOD検出機能**:未実装メソッドの自動発見
|
||||
4. **TLV応答検証機能**:型安全なTLV形式検証
|
||||
|
||||
#### 実証結果
|
||||
- ✅ **100%検出精度**: 手動発見した問題を完全自動検出
|
||||
- ✅ **実際のnyash.toml検証**: 8個の問題を自動検出・修正指示
|
||||
- ✅ **事故防止**: 同様問題の再発完全防止
|
||||
|
||||
### 🎯 **Phase 15.5-B-1: slot_registry統一化完成**
|
||||
**StringBox問題の根本修正実現**
|
||||
|
||||
#### 実装詳細
|
||||
- **場所**: `src/mir/slot_registry.rs`
|
||||
- **削除内容**: core box静的定義30行削除
|
||||
- **統一化**: former core boxesのplugin slots移行
|
||||
|
||||
#### 修正前後の比較
|
||||
```rust
|
||||
// 修正前(問題の源泉)
|
||||
m.insert("StringBox", vec![("substring", 4), ("concat", 5)]);
|
||||
m.insert("ArrayBox", vec![("push", 4), ("pop", 5), /* ... */]);
|
||||
// ↑ core box特別処理がplugin-based解決と衝突
|
||||
|
||||
// 修正後(Phase 15.5統一化)
|
||||
// Former core boxes (StringBox, IntegerBox, ArrayBox, MapBox) now use plugin slots
|
||||
// All slots come from nyash.toml configuration
|
||||
```
|
||||
|
||||
#### 効果
|
||||
- ✅ **WebChatGPT環境との完全一致**: 同じnyash.toml設定で同じ動作
|
||||
- ✅ **3-tier→2-tier基盤完成**: core box特別処理削除
|
||||
- ✅ **統一テスト実装**: Phase 15.5対応テストケース追加
|
||||
|
||||
### 🏆 **Phase 15.5-B-2: MIRビルダー統一化完成**
|
||||
**former core boxesの特別扱い完全撤廃**
|
||||
|
||||
#### 実装詳細(2025-09-24完成)
|
||||
- **場所1**: `src/mir/builder/utils.rs`(22行削除)
|
||||
- StringBox/ArrayBox/MapBox特別型推論完全削除
|
||||
- plugin_method_sigs統一解決のみ使用
|
||||
- **場所2**: `src/mir/builder.rs`(18行→3行統一)
|
||||
- IntegerBox/FloatBox/BoolBox/StringBox特別扱い削除
|
||||
- 全てMirType::Box(class)で統一処理
|
||||
- **場所3**: `src/mir/builder/builder_calls.rs`(parse_type_name_to_mir)
|
||||
- *Box型の特別マッピング削除
|
||||
- core primitiveとBox型の明確分離
|
||||
|
||||
#### 技術的革新
|
||||
```rust
|
||||
// 修正前(特別扱い乱立)
|
||||
match class.as_str() {
|
||||
"IntegerBox" => MirType::Integer,
|
||||
"StringBox" => MirType::String,
|
||||
// 18行の特別処理...
|
||||
}
|
||||
|
||||
// 修正後(完全統一)
|
||||
self.value_types.insert(dst, MirType::Box(class.clone()));
|
||||
```
|
||||
|
||||
#### 実装成果
|
||||
- ✅ **コード削減**: 約40行の特別処理削除(3箇所合計)
|
||||
- ✅ **型システム統一**: 全Box型が同じパスで処理
|
||||
- ✅ **ビルド検証**: 全テスト通過確認済み
|
||||
- ✅ **動作検証**: StringBox/IntegerBox動作確認済み
|
||||
|
||||
---
|
||||
|
||||
## 🎯 目標
|
||||
コアBox(nyrt内蔵)を削除し、プラグインBox・ユーザーBoxの2層構造に統一
|
||||
|
||||
### 削減見込み
|
||||
- **コード削減**: 約600行削除(nyrt実装)
|
||||
- **特別扱い削除**: MIRビルダー/バックエンドから約100行
|
||||
- **全体寄与**: Phase 15目標(80k→20k)の約1%
|
||||
|
||||
## 📊 構造変更の全体像
|
||||
|
||||
### 現状(3層構造)
|
||||
```
|
||||
1. コアBox(nyrt内蔵)← 完全削除
|
||||
- StringBox, IntegerBox, BoolBox
|
||||
- ArrayBox, MapBox
|
||||
- 特別な最適化パス・予約型保護
|
||||
|
||||
2. プラグインBox(.so/.dll)
|
||||
- FileBox, NetBox, ConsoleBox等
|
||||
- FFI TypeBox v2インターフェース
|
||||
|
||||
3. ユーザー定義Box(Nyashコード)
|
||||
- アプリケーション固有Box
|
||||
```
|
||||
|
||||
### 最終形(2層構造)
|
||||
```
|
||||
1. プラグインBox(.so/.dll)← デフォルト動作
|
||||
- StringBox, IntegerBox(元コア)
|
||||
- FileBox, NetBox等(既存プラグイン)
|
||||
- 統一されたFFI TypeBox v2インターフェース
|
||||
|
||||
2. ユーザー定義Box(Nyashコード)
|
||||
- アプリケーション固有Box
|
||||
- 将来:StringBox等もNyashコード実装
|
||||
```
|
||||
|
||||
## 🚀 実装計画
|
||||
|
||||
### Phase A: 予約型保護解除(1週目)
|
||||
|
||||
#### 1. 予約型保護の条件付き解除
|
||||
```rust
|
||||
// src/box_factory/mod.rs: is_reserved_type()修正
|
||||
fn is_reserved_type(name: &str) -> bool {
|
||||
// 環境変数でプラグイン優先モード時は保護解除
|
||||
if std::env::var("NYASH_USE_PLUGIN_BUILTINS").is_ok() {
|
||||
if let Ok(types) = std::env::var("NYASH_PLUGIN_OVERRIDE_TYPES") {
|
||||
if types.split(',').any(|t| t.trim() == name) {
|
||||
return false; // 予約型として扱わない
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
matches!(name, "StringBox" | "IntegerBox" | ...)
|
||||
}
|
||||
```
|
||||
|
||||
#### 2. プラグイン版テスト
|
||||
```bash
|
||||
# Step 1: 単体テスト
|
||||
NYASH_USE_PLUGIN_CORE_BOXES=1 ./target/release/nyash test_integer.nyash
|
||||
NYASH_USE_PLUGIN_CORE_BOXES=1 ./target/release/nyash test_string.nyash
|
||||
|
||||
# Step 2: スモークテスト
|
||||
NYASH_USE_PLUGIN_CORE_BOXES=1 ./tools/jit_smoke.sh
|
||||
|
||||
# Step 3: 包括テスト
|
||||
NYASH_USE_PLUGIN_CORE_BOXES=1 cargo test
|
||||
```
|
||||
|
||||
#### 3. パフォーマンス測定
|
||||
```bash
|
||||
# ベンチマーク
|
||||
./target/release/nyash --benchmark core_vs_plugin.nyash
|
||||
```
|
||||
|
||||
### Phase B: MIRビルダー統一(2週目)
|
||||
|
||||
#### 削除対象ファイル・行
|
||||
1. **src/mir/builder/utils.rs** (行134-156)
|
||||
- StringBox/IntegerBox等の特別な型推論削除
|
||||
- すべてのBoxを統一的に扱う
|
||||
|
||||
2. **src/mir/builder.rs** (行407-424)
|
||||
- build_new_expression の特別扱い削除
|
||||
|
||||
3. **src/mir/builder/builder_calls.rs**
|
||||
- parse_type_name_to_mir の修正
|
||||
|
||||
#### 実装変更
|
||||
```rust
|
||||
// Before(特別扱いあり)
|
||||
match class.as_str() {
|
||||
"StringBox" => MirType::String,
|
||||
"IntegerBox" => MirType::Integer,
|
||||
// ...
|
||||
}
|
||||
|
||||
// After(統一)
|
||||
MirType::Box(class.to_string())
|
||||
```
|
||||
|
||||
### Phase C: 完全統一(3週目)
|
||||
|
||||
#### 1. 予約型保護の完全削除
|
||||
```rust
|
||||
// src/box_factory/mod.rs: 予約型保護を完全削除
|
||||
// この関数を削除またはコメントアウト
|
||||
// fn is_reserved_type(name: &str) -> bool { ... }
|
||||
|
||||
// 登録処理から予約型チェックを削除
|
||||
// if is_reserved_type(type_name) && !factory.is_builtin_factory() {
|
||||
// continue; // この部分を削除
|
||||
// }
|
||||
```
|
||||
|
||||
#### 2. nyrt実装削除
|
||||
1. **crates/nyrt/src/lib.rs**
|
||||
- StringBox関連: 約150行
|
||||
- IntegerBox関連: 約50行
|
||||
- ArrayBox関連: 約50行
|
||||
- MapBox関連: 約50行
|
||||
|
||||
2. **crates/nyrt/src/plugin/**
|
||||
- array.rs: 143行(完全削除)
|
||||
- string.rs: 173行(完全削除)
|
||||
|
||||
3. **src/backend/llvm/compiler/codegen/instructions/newbox.rs**
|
||||
- コアBox最適化パス削除
|
||||
|
||||
#### 3. デフォルト動作の確立
|
||||
```bash
|
||||
# 環境変数なしでプラグインBox使用
|
||||
./target/release/nyash test.nyash # StringBox = プラグイン版
|
||||
```
|
||||
|
||||
### Phase D: Nyashコード実装(将来)
|
||||
|
||||
```nyash
|
||||
// apps/lib/core_boxes/string_box.nyash
|
||||
box StringBox {
|
||||
data: InternalString // 内部表現
|
||||
|
||||
birth(init_val) {
|
||||
me.data = init_val or ""
|
||||
}
|
||||
|
||||
length() {
|
||||
return me.data.len()
|
||||
}
|
||||
|
||||
concat(other) {
|
||||
return me.data + other
|
||||
}
|
||||
|
||||
substring(start, end) {
|
||||
return me.data.slice(start, end)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
```nyash
|
||||
// apps/lib/core_boxes/integer_box.nyash
|
||||
box IntegerBox {
|
||||
value: i64
|
||||
|
||||
birth(init_val) {
|
||||
me.value = init_val or 0
|
||||
}
|
||||
|
||||
get() {
|
||||
return me.value
|
||||
}
|
||||
|
||||
set(new_val) {
|
||||
me.value = new_val
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 📋 チェックリスト
|
||||
|
||||
### 準備段階
|
||||
- [ ] プラグイン版の存在確認
|
||||
- [x] nyash-string-plugin
|
||||
- [x] nyash-integer-plugin
|
||||
- [x] nyash-array-plugin
|
||||
- [x] nyash-map-plugin
|
||||
- [ ] nyash-bool-plugin(作成必要?)
|
||||
|
||||
### Phase A
|
||||
- [ ] 環境変数NYASH_USE_PLUGIN_CORE_BOXES実装
|
||||
- [ ] フォールバック機構実装
|
||||
- [ ] プラグイン版動作テスト
|
||||
- [ ] パフォーマンス測定
|
||||
|
||||
### Phase B
|
||||
- [ ] MIRビルダー特別扱い削除
|
||||
- [ ] 型推論ロジック統一
|
||||
- [ ] テスト通過確認
|
||||
|
||||
### Phase C
|
||||
- [ ] nyrt StringBox実装削除
|
||||
- [ ] nyrt IntegerBox実装削除
|
||||
- [ ] nyrt ArrayBox実装削除
|
||||
- [ ] nyrt MapBox実装削除
|
||||
- [ ] LLVM最適化パス削除
|
||||
|
||||
### Phase D(将来)
|
||||
- [ ] Nyashコード版StringBox実装
|
||||
- [ ] Nyashコード版IntegerBox実装
|
||||
- [ ] Nyashコード版ArrayBox実装
|
||||
- [ ] Nyashコード版MapBox実装
|
||||
|
||||
## 🎯 成功基準
|
||||
|
||||
1. **機能的完全性**: すべてのテストがプラグイン版で通過
|
||||
2. **パフォーマンス**: FFIオーバーヘッドが30%以内
|
||||
3. **コード削減**: 700行以上の削減達成
|
||||
4. **アーキテクチャ**: 3層→2層の簡潔化達成
|
||||
|
||||
## ⚠️ リスクと対策
|
||||
|
||||
| リスク | 影響 | 対策 |
|
||||
|-------|------|------|
|
||||
| FFIオーバーヘッド | 10-30%性能低下 | 静的リンク最適化 |
|
||||
| プラグイン依存関係 | 配布複雑化 | 単一EXE生成(.a静的リンク) |
|
||||
| デバッグ困難 | FFI境界問題 | 詳細ログ・トレース追加 |
|
||||
|
||||
## 📝 関連ドキュメント
|
||||
- [MIR Call統一計画](mir-call-unification-master-plan.md)
|
||||
- [Phase 15 全体計画](README.md)
|
||||
- [セルフホスティング計画](self-hosting-plan.txt)
|
||||
|
||||
## 💡 技術的洞察
|
||||
|
||||
ChatGPTの「コアBox削除」提案は、以下の理由で革命的:
|
||||
|
||||
1. **全チェック地獄の解消**: 3層構造による複雑な型チェック削除
|
||||
2. **統一ABI**: すべてのBoxが同じインターフェース
|
||||
3. **静的リンク活用**: .so→.a変換で性能維持
|
||||
4. **セルフホスティング加速**: Nyashコード化への道筋
|
||||
|
||||
この統一により、Phase 15の80k→20k行削減目標に向けた重要な一歩となる。
|
||||
@ -0,0 +1,38 @@
|
||||
# Phase‑15 Macro‑Driven Replan
|
||||
|
||||
Status: Adopted (2025‑09). This plan reframes Phase‑15 self‑hosting to leverage the new macro system (AST JSON v0 / PyVM sandbox / strict / timeout / golden).
|
||||
|
||||
## Goals
|
||||
- Consolidate all front‑end, sugar, and light rewrites into user macros (Nyash/PyVM)
|
||||
- Keep Rust core minimal: parse/AST emit/MIR build/backend only
|
||||
- Deterministic expansion with strict failure and timeouts; golden testing as acceptance
|
||||
|
||||
## Execution Pipeline
|
||||
1) Parse (Rust) → AST
|
||||
2) Macro Expansion (fixed‑point, 1 pass): Built‑in (Rust) → User Macros (Nyash/PyVM)
|
||||
3) Using/resolve → MIR → Backend (VM/LLVM/WASM/AOT)
|
||||
|
||||
## Guardrails
|
||||
- strict=1 (default): child error/timeout aborts the build
|
||||
- timeout: `NYASH_NY_COMPILER_TIMEOUT_MS=2000` (default)
|
||||
- capabilities: all OFF (io/net/env=false) for Phase‑15
|
||||
- observability: `--dump-expanded-ast-json` + JSONL trace (`NYASH_MACRO_TRACE_JSONL`)
|
||||
|
||||
## Work Items
|
||||
1) Enable PyVM runner route for macros (done)
|
||||
- ランナールートが既定。内部子ルートは非推奨(`NYASH_MACRO_BOX_CHILD_RUNNER=0` でのみ強制)
|
||||
2) Identity + upper_string templates (done)
|
||||
- Examples under `apps/macros/examples/`
|
||||
3) Golden tests
|
||||
- identity/upper cases (done)
|
||||
- add 1–2 more (array/map literal touch) [next]
|
||||
4) Selfhost compiler refactor (front)
|
||||
- Limit Ny parser to Stage‑2 subset; sugar via macros
|
||||
- Keep resolver in runner (Phase‑15 policy)
|
||||
5) nyash.toml sketch for macro registration and caps
|
||||
- `[macros]` + `[macro_caps."path"]` io/net/env=false (docs only in Phase‑15)
|
||||
|
||||
## Acceptance
|
||||
- Expanded AST JSON matches goldens for sample programs
|
||||
- Macro runner path green under strict=1, timeout=2000ms
|
||||
- MIR/LLVM/VM paths stable with expanded inputs
|
||||
126
docs/private/roadmap/phases/phase-15/planning/preparation.md
Normal file
126
docs/private/roadmap/phases/phase-15/planning/preparation.md
Normal file
@ -0,0 +1,126 @@
|
||||
# Phase 15 セルフホスティング準備まとめ
|
||||
作成日: 2025-09-03
|
||||
作成者: Claude (Gemini・Codex協議結果統合)
|
||||
|
||||
## 専門家の技術評価まとめ
|
||||
|
||||
### Gemini先生の分析
|
||||
- **実現可能性**: MIR 13命令で十分実現可能、BoxCallの設計が鍵
|
||||
- **推奨バックエンド**: Cranelift + lld(開発速度・安全性・成熟度)
|
||||
- **コード削減**: 75%削減は現実的(Arc<Mutex>→GC、動的ディスパッチ)
|
||||
- **段階的アプローチ**: まず動くものを作り、後から最適化
|
||||
|
||||
### Codex先生の具体設計
|
||||
- **BoxCall実装**: 隠れクラス(Shape)+ vtable + セレクタインターン
|
||||
- **JIT最適化**: IC/PIC、Shapeガード、devirtualization
|
||||
- **ブートストラップ**: c0→c1→c1'の具体手順、決定論的ビルド
|
||||
- **並列化**: GCでロック削減、フェーズ境界でバリア同期
|
||||
|
||||
## 今すぐ着手可能な準備作業
|
||||
|
||||
### 1. BoxCall設計の詳細化(最優先)
|
||||
```nyash
|
||||
// BoxCall命令のメタデータ設計
|
||||
BoxCall {
|
||||
dst: ValueId,
|
||||
receiver: ValueId,
|
||||
selector: Sel(u32), // インターン化されたメソッド名
|
||||
args: Vec<ValueId>,
|
||||
flags: {
|
||||
op_kind: OpKind, // Get/Set/Invoke/Convert
|
||||
target_type: Option<TypeId>,
|
||||
site_id: u32, // IC/PIC管理用
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 2. 最小言語サブセット定義
|
||||
**必須機能**:
|
||||
- 基本型(Integer, String, Bool, Array, Map)
|
||||
- Box定義(box, birth, field, method)
|
||||
- 制御構造(if, loop, return)
|
||||
- 関数定義(static/instance method)
|
||||
- エラー処理(Result型)
|
||||
|
||||
**初期は省略**:
|
||||
- ジェネリクス
|
||||
- trait/interface
|
||||
- マクロ
|
||||
- 非同期(async/await)
|
||||
|
||||
### 3. セレクタインターン実装
|
||||
```rust
|
||||
// src/runtime/selector_intern.rs
|
||||
pub struct SelectorInterner {
|
||||
string_to_id: HashMap<String, Sel>,
|
||||
id_to_string: Vec<String>,
|
||||
}
|
||||
```
|
||||
|
||||
### 4. TypeDesc/VTable構造定義
|
||||
```rust
|
||||
// crates/nyrt/src/types.rs
|
||||
pub struct TypeDesc {
|
||||
id: TypeId,
|
||||
vtable: *const VTable,
|
||||
shape_epoch: u32,
|
||||
}
|
||||
|
||||
pub struct VTable {
|
||||
get: fn(recv: *mut BoxHdr, sel: Sel) -> Value,
|
||||
set: fn(recv: *mut BoxHdr, sel: Sel, val: Value),
|
||||
invoke: fn(recv: *mut BoxHdr, sel: Sel, args: &[Value]) -> Value,
|
||||
// ... 他のメソッド
|
||||
}
|
||||
```
|
||||
|
||||
### 5. MIR最適化パス準備
|
||||
- BoxCallのdevirtualization検出
|
||||
- Shapeガード生成
|
||||
- IC/PICサイト管理
|
||||
|
||||
## 実装ロードマップ
|
||||
|
||||
### Phase 1: 基盤整備(1-2ヶ月)
|
||||
1. BoxCall命令の完全定義
|
||||
2. セレクタインターンシステム
|
||||
3. TypeDesc/VTable基盤
|
||||
4. 最小サブセット言語仕様
|
||||
|
||||
### Phase 2: プロトタイプ(2-3ヶ月)
|
||||
1. 素朴なBoxCall実装(文字列ディスパッチ)
|
||||
2. Cranelift統合
|
||||
3. 最小コンパイラ(c0.5)実装
|
||||
|
||||
### Phase 3: 最適化(2-3ヶ月)
|
||||
1. Shape/vtableハイブリッド
|
||||
2. IC/PIC実装
|
||||
3. devirtualization
|
||||
|
||||
### Phase 4: セルフホスティング(2-3ヶ月)
|
||||
1. c1実装(Nyashで20,000行)
|
||||
2. ブートストラップ検証
|
||||
3. 性能チューニング
|
||||
|
||||
## 技術的リスクと対策
|
||||
|
||||
### リスク
|
||||
1. BoxCallの性能オーバーヘッド
|
||||
2. ブートストラップの決定論性
|
||||
3. デバッグの困難さ
|
||||
|
||||
### 対策
|
||||
1. 早期にIC/PIC実装で緩和
|
||||
2. SOURCE_DATE_EPOCH等で環境統一
|
||||
3. MIRダンプ比較ツール整備
|
||||
|
||||
## 成功の指標
|
||||
- c1がc1'を正しくコンパイル(バイナリ一致)
|
||||
- 80,000行→20,000行達成
|
||||
- VM比2倍以上の性能(Cranelift JIT)
|
||||
|
||||
## 次のアクション
|
||||
1. BoxCall詳細設計ドキュメント作成
|
||||
2. セレクタインターン実装開始
|
||||
3. 最小サブセット言語仕様確定
|
||||
4. MIRへのBoxCallメタデータ追加
|
||||
165
docs/private/roadmap/phases/phase-15/planning/sequence.md
Normal file
165
docs/private/roadmap/phases/phase-15/planning/sequence.md
Normal file
@ -0,0 +1,165 @@
|
||||
# Phase 15 推奨進行順(llvmlite+PyVM 優先・自己ホスティング最小)
|
||||
|
||||
更新日: 2025-09-05
|
||||
|
||||
## 方針(原則)
|
||||
|
||||
- JIT/Cranelift は停止。LLVM(llvmlite)と PyVM の2経路で前進。
|
||||
- 最小自己ホスト体験を早期に成立 → ドキュメント/スモーク/CIを先に固める。
|
||||
- using(名前空間)はゲート付きで段階導入。NyModulesとny_pluginsの基盤を強化。
|
||||
- tmux + codex-async を使い、常時2本並走で小粒に積み上げる。
|
||||
|
||||
## 推奨シーケンス(概要→実施要点→完了基準)
|
||||
|
||||
### 1) 基盤整備(NyModules / ny_plugins / Windows正規化)
|
||||
|
||||
**要点:**
|
||||
- NyModules 共有レジストリ導入: env.modules.set/get(または ModulesBox)
|
||||
- ny_plugins のパス→名前空間導出: ルート相対、"/"→".", 拡張子 .nyash 省略、[^a-zA-Z0-9_.]→"_"
|
||||
- Windowsパス: "\\"→"/" 正規化後に上記規則を適用
|
||||
- 予約衝突: nyashstd.* の登録を明示拒否しログ出力
|
||||
|
||||
**スモーク/CI:**
|
||||
- tools/modules_smoke.sh, tools/modules_winpath_smoke.sh
|
||||
|
||||
**完了基準:**
|
||||
- env.modules.get("acme.logger") などが取得可能、LIST_ONLY/Fail-continue維持、予約拒否ログが出る。
|
||||
|
||||
### 2) 最小VM(PyVM)
|
||||
|
||||
**要点:**
|
||||
- MIR(JSON) を Python VM(PyVM)で実行。最小命令 + 最小 boxcall(Console/File/Path/String)
|
||||
- ランナー統合(`NYASH_VM_USE_PY=1`)→ 代表スモークが llvmlite と一致
|
||||
|
||||
**スモーク/CI:**
|
||||
- tools/compare_harness_on_off.sh(ハーネス)、compare_vm_vs_harness.sh(PyVM vs llvmlite)
|
||||
|
||||
**完了基準:**
|
||||
- esc_dirname_smoke / dep_tree_min_string が PyVM と llvmlite で一致。
|
||||
|
||||
【Status 2025‑09‑14】完了(A6 受入)。
|
||||
|
||||
### 3) using(ゲート付き)設計・実装(15.2/15.3)
|
||||
|
||||
**要点:**
|
||||
- パーサフック: 'using <ns>' を受理(--enable-using / NYASH_USING=1; compat: NYASH_ENABLE_USING=1)
|
||||
- リゾルバskeleton: resolve(ns) → NyModules を優先。外部/パッケージは TODO として設計のみ。
|
||||
- 実行時フック: 未解決時に提案を含む診断。セッションキャッシュを導入(ny_plugins再読込で無効化)。
|
||||
- using alias: 'using a.b as x' を設計→段階導入。
|
||||
|
||||
**スモーク/CI:**
|
||||
- jit_smoke に using ケースとキャッシュケースを追加。
|
||||
|
||||
**完了基準:**
|
||||
- フラグONで using 経路が動作し、未解決時の診断・キャッシュ挙動がテストで担保。
|
||||
|
||||
【Next】Ny パーサMVPと並走で段階導入(フラグ: `--enable-using` / `NYASH_USING=1`;compat: `NYASH_ENABLE_USING=1`)。
|
||||
|
||||
### 3.5) Nyash パーサMVP(サブセット)
|
||||
|
||||
**要点:**
|
||||
- ステージ1: Ny→JSON v0 パイプ(最小表現)。
|
||||
- ステージ2: 文/式のサブセット拡張。
|
||||
- ステージ3: Ny AST→MIR JSON 直接降下(llvmlite/PyVMへ)。
|
||||
|
||||
**スモーク/CI:**
|
||||
- `tools/ny_roundtrip_smoke.sh` / `tools/ny_parser_bridge_smoke.sh`
|
||||
- `tools/parity.sh --lhs pyvm --rhs llvmlite <smoke.nyash>`(Nyパーサ経路ON)
|
||||
|
||||
**完了基準:**
|
||||
- esc_dirname_smoke / dep_tree_min_string が Ny パーサ経路でも PyVM/llvmlite と一致(stdout/exit)。
|
||||
|
||||
### 4) nyash.link ミニマルリゾルバ(15.4)
|
||||
|
||||
**要点:**
|
||||
- ファイル/相対解決 → 名前空間への写像、検索パス(nyash.toml と環境)、Windows正規化
|
||||
- 未解決時は候補提示、NyModules へのフォールバック
|
||||
- using alias + 診断を仕上げる
|
||||
|
||||
**スモーク/CI:**
|
||||
- end-to-end 例(apps/)とJITスモークの拡充
|
||||
|
||||
**完了基準:**
|
||||
- 小規模プロジェクトで using + nyash.link の基本導線がJITでE2E通る。
|
||||
|
||||
### 5) パフォーマンス守り(MIRマイクロ最適化 + 回帰ゲート)
|
||||
|
||||
**要点:**
|
||||
- const-fold(リテラル・単純四則)、DCE(unreachable return/blocks)をスコープ限定で有効化
|
||||
- 回帰時は NYASH_CLI_VERBOSE=1 で診断を落とす
|
||||
|
||||
**スモーク/CI:**
|
||||
- jit_smoke に閾値付きケースを追加、CI optional stage で監視
|
||||
|
||||
**完了基準:**
|
||||
- 主要ケースで回帰検出が機能し、JITパリティが維持される。
|
||||
|
||||
### 6) Boxes 高レベル移植(15.5 開始)
|
||||
|
||||
**要点:**
|
||||
- StringBox → ArrayBox の順で表層メソッドをNyashへ移植(NyRTは最小プリミティブ維持)
|
||||
- MapBox は次段で検討。ABI/churnを避けるため段階導入
|
||||
|
||||
**スモーク/CI:**
|
||||
- 文字列/配列操作のJITスモークを追加
|
||||
|
||||
**完了基準:**
|
||||
- 代表的な文字列/配列APIがNyash実装で安定動作し、CI常時緑。
|
||||
|
||||
### 7) インタープリターコアの段階移植(15.5/15.6)
|
||||
|
||||
**要点:**
|
||||
- MIR実行ループを段階的にNyash化(動的ディスパッチで13命令処理)
|
||||
- ブートストラップ: c0(Rust) → c1(Nyash) → c1'(自己再コンパイル)
|
||||
|
||||
**検証:**
|
||||
- パリティテスト(trace_hash 等)とスモークを追加
|
||||
|
||||
**完了基準:**
|
||||
- 自己再コンパイルループが成立し、差分トレースが安定。
|
||||
|
||||
### 8) YAML 自動生成(15.1 を後段にスライドして導入)
|
||||
|
||||
**要点:**
|
||||
- boxes.yaml / externs.yaml / semantics.yaml を定義し、build.rs でコード自動生成
|
||||
- まず externs/boxes の一部から段階導入 → 重複削減を早期に回収
|
||||
|
||||
**完了基準:**
|
||||
- 重複コードが実測で大幅削減(1〜2万行級)、CI・ドキュメントに反映。
|
||||
|
||||
### 9) クローズアウト(各小節の都度)
|
||||
|
||||
- README.ja.md / AGENTS.md / docs のHOWTO・旗一覧・スモーク手順を常に最新化
|
||||
- ツール類索引: tools/jit_smoke.sh, selfhost_vm_smoke.sh, modules_smoke.sh, modules_winpath_smoke.sh
|
||||
- CIトグル整備: LLVM系は無効化、JIT(--features cranelift-jit)を標準経路に
|
||||
|
||||
## クイックコマンド(JITオンリー)
|
||||
|
||||
```bash
|
||||
# ビルド
|
||||
cargo build --release --features cranelift-jit
|
||||
|
||||
# 実行
|
||||
./target/release/nyash --backend vm apps/selfhost-minimal/main.nyash
|
||||
|
||||
# スモーク
|
||||
./tools/jit_smoke.sh
|
||||
./tools/selfhost_vm_smoke.sh
|
||||
./tools/modules_smoke.sh ; ./tools/modules_winpath_smoke.sh
|
||||
```
|
||||
|
||||
## フラグ(抜粋)
|
||||
|
||||
- `--load-ny-plugins` / `NYASH_LOAD_NY_PLUGINS=1`
|
||||
- `--enable-using` / `NYASH_USING=1`(compat: `NYASH_ENABLE_USING=1`)
|
||||
- `NYASH_CLI_VERBOSE=1`(診断強化)
|
||||
|
||||
## 運用(Codex async / tmux)
|
||||
|
||||
- 2並走・重複回避: `CODEX_MAX_CONCURRENT=2 CODEX_DEDUP=1 CODEX_ASYNC_DETACH=1`
|
||||
- 監視: `pgrep -af 'codex .* exec'` / `tail -f ~/.codex-async-work/logs/codex-*.log`
|
||||
- Windowsパス/名前空間: "\\"→"/" 正規化 → ルール適用(/→., .nyash除去, sanitize)
|
||||
|
||||
## 備考
|
||||
|
||||
本シーケンスは `docs/private/roadmap/phases/phase-15/self-hosting-plan.txt` を尊重しつつ、JIT最小体験を優先させるため順序を最適化(LLVM/lld と YAML自動生成は後段へスライド)。進捗に応じて適宜見直し、CI/スモークで常時検証する。
|
||||
@ -0,0 +1,138 @@
|
||||
# Python LLVM優先実装の戦略的根拠
|
||||
|
||||
作成日: 2025-09-24
|
||||
|
||||
## 🎯 なぜPython LLVMを優先するか
|
||||
|
||||
### 1. 最大のコード削減効果
|
||||
|
||||
| 実行器 | 現在行数 | 削減後 | 削減率 | 優先度 |
|
||||
|--------|----------|--------|--------|--------|
|
||||
| **Python LLVM** | 804行 | 300行 | **63%** | **1位** |
|
||||
| PyVM/VM | 712行 | 512行 | 28% | 2位 |
|
||||
| mini-vm | 新規 | - | - | 3位 |
|
||||
|
||||
### 2. 実装の独立性
|
||||
|
||||
**Python LLVMの利点**:
|
||||
- **独立したPythonスクリプト** - Rustビルドと無関係
|
||||
- **即座にテスト可能** - `python llvm_builder.py`で実行
|
||||
- **ロールバック容易** - 環境変数で旧実装に切り替え可能
|
||||
|
||||
```python
|
||||
# 環境変数による段階移行
|
||||
if os.environ.get('NYASH_MIR_UNIFIED_CALL') == '1':
|
||||
return dispatch_unified_call(inst) # 新実装
|
||||
else:
|
||||
return dispatch_legacy(inst) # 旧実装
|
||||
```
|
||||
|
||||
### 3. 技術的シンプルさ
|
||||
|
||||
**現在の問題(6種類の処理)**:
|
||||
```python
|
||||
# src/llvm_py/llvm_builder.py の現状
|
||||
if inst['op'] == 'Call':
|
||||
handle_call(...)
|
||||
elif inst['op'] == 'BoxCall':
|
||||
handle_box_call(...)
|
||||
elif inst['op'] == 'PluginInvoke':
|
||||
handle_plugin_invoke(...)
|
||||
elif inst['op'] == 'ExternCall':
|
||||
handle_extern_call(...)
|
||||
elif inst['op'] == 'NewBox':
|
||||
handle_new_box(...)
|
||||
elif inst['op'] == 'NewClosure':
|
||||
handle_new_closure(...)
|
||||
```
|
||||
|
||||
**統一後(1つの処理)**:
|
||||
```python
|
||||
# 統一後のシンプルな実装
|
||||
if inst['op'] == 'MirCall':
|
||||
callee = inst['callee']
|
||||
if callee['type'] == 'Global':
|
||||
emit_global_call(callee['name'], inst['args'])
|
||||
elif callee['type'] == 'Method':
|
||||
emit_method_call(callee['receiver'], callee['method'], inst['args'])
|
||||
elif callee['type'] == 'Constructor':
|
||||
emit_constructor(callee['box_type'], inst['args'])
|
||||
# ... 統一された処理
|
||||
```
|
||||
|
||||
## 📊 PyVM/VMを後にする理由
|
||||
|
||||
### 1. 依存関係の観点
|
||||
- **MIR構造の統一完了後が望ましい**
|
||||
- Python LLVM実装での知見を活用可能
|
||||
- 相互検証(LLVM vs VM)が可能に
|
||||
|
||||
### 2. リスク管理
|
||||
- VMは実行器の中核なので慎重に
|
||||
- Python LLVMで先に検証してから適用
|
||||
|
||||
### 3. 削減効果は中程度
|
||||
- 28%削減は重要だが、63%には及ばない
|
||||
- 優先順位として2位が妥当
|
||||
|
||||
## 📅 推奨実装スケジュール
|
||||
|
||||
```mermaid
|
||||
gantt
|
||||
title MIR Call統一実装スケジュール
|
||||
dateFormat YYYY-MM-DD
|
||||
section Phase 3(MIR Builder)
|
||||
Phase 3.1-3.2 完了 :done, 2025-09-23, 1d
|
||||
Phase 3.3 BoxCall統一 :active, 2025-09-24, 2d
|
||||
|
||||
section Phase 4(Python LLVM)
|
||||
Phase 4.1 dispatch統一 :2025-09-26, 3d
|
||||
Phase 4.2 処理実装 :2025-09-29, 4d
|
||||
|
||||
section Phase 5(VM/PyVM)
|
||||
Phase 5 VM統一 :2025-10-03, 5d
|
||||
|
||||
section Phase 6(mini-vm)
|
||||
Phase 6 新規実装 :2025-10-08, 5d
|
||||
```
|
||||
|
||||
## 🎯 期待される成果
|
||||
|
||||
### 短期的成果(2週間)
|
||||
1. **コード削減**: 1,904行削減(26%)
|
||||
2. **保守性向上**: 6種類→1種類の処理パターン
|
||||
3. **理解容易性**: 統一されたCall semantics
|
||||
|
||||
### 長期的成果(1ヶ月)
|
||||
1. **Phase 15への貢献**: 全体目標の7%達成
|
||||
2. **セルフホスティング基盤**: mini-vm統一実装
|
||||
3. **将来の拡張性**: 新Call種別追加が容易に
|
||||
|
||||
## 🚀 アクションプラン
|
||||
|
||||
### 今週(Phase 3完了)
|
||||
- [ ] emit_box_or_plugin_call統一化
|
||||
- [ ] テストケース準備
|
||||
- [ ] Python LLVM実装調査
|
||||
|
||||
### 来週(Phase 4: Python LLVM)
|
||||
- [ ] llvm_builder.py リファクタリング開始
|
||||
- [ ] dispatch_unified_call実装
|
||||
- [ ] 環境変数による段階移行
|
||||
- [ ] ベンチマーク測定
|
||||
|
||||
### 再来週(Phase 5: VM/PyVM)
|
||||
- [ ] mir_interpreter.rs統一
|
||||
- [ ] pyvm/vm.py統一
|
||||
- [ ] 相互検証テスト
|
||||
- [ ] パフォーマンス最適化
|
||||
|
||||
## まとめ
|
||||
|
||||
**Python LLVM優先の判断は正しい**:
|
||||
1. **最大効果** - 63%削減は圧倒的
|
||||
2. **低リスク** - 独立実装で影響範囲限定
|
||||
3. **高速検証** - Pythonで即座にテスト可能
|
||||
4. **知見獲得** - 後続実装への学習効果
|
||||
|
||||
この戦略により、**2週間で主要実行器の統一完了**が現実的に達成可能。
|
||||
Reference in New Issue
Block a user