feat: MIR Call命令統一Phase 3.1-3.2完了!統一Call実装進行中
✨ Phase 3.1-3.2実装完了 - build_indirect_call_expressionでCallTarget::Value使用 - print関数をcall_global print()として統一 - build_function_callでemit_unified_call使用 - ExternCall(env.console.log)→Callee::Global(print)完全移行 🏗️ MIR統一基盤構築 - src/mir/definitions/call_unified.rs: 統一定義(297行) - emit_unified_call()と便利メソッド3種実装 - NYASH_MIR_UNIFIED_CALL=1で段階移行制御 - VM実行器でCallee対応実装済み 📊 進捗状況(26%削減見込み) - Phase 1-2: ✅ 基盤構築完了 - Phase 3.1-3.2: ✅ 基本関数統一完了 - Phase 3.3: 🔄 BoxCall統一中 - Phase 4: 📅 Python LLVM(最優先・63%削減) - Phase 5: 📅 PyVM/VM統一 📚 ドキュメント更新 - CLAUDE.md: テストスクリプト参考集追加 - CURRENT_TASK.md: Phase 3進捗更新 - python-llvm-priority-rationale.md: 優先順位戦略文書化 - mir-call-unification-master-plan.md: スケジュール最新化 🎯 6種類→1種類: Call/BoxCall/PluginInvoke/ExternCall/NewBox/NewClosure → MirCall統一へ 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
299
docs/development/architecture/mir-callee-revolution.md
Normal file
299
docs/development/architecture/mir-callee-revolution.md
Normal file
@ -0,0 +1,299 @@
|
||||
# MIR Callee型革新 - 関数呼び出しアーキテクチャの根本改良
|
||||
|
||||
## 概要
|
||||
|
||||
シャドウイングバグから発見された根本的問題を解決するため、ChatGPT5 Pro提案に基づくMIR Call命令の完全リアーキテクチャを実施。実行時文字列解決からコンパイル時型付き解決への移行により、パフォーマンス・安全性・保守性を根本改善。
|
||||
|
||||
## 問題の本質
|
||||
|
||||
### 現在のMIR Call命令の構造的欠陥
|
||||
|
||||
```rust
|
||||
// ❌ 現在の問題構造
|
||||
Call {
|
||||
dst: Option<ValueId>,
|
||||
func: ValueId, // ← Const(String("print"))のみ!スコープ情報なし
|
||||
args: Vec<ValueId>,
|
||||
}
|
||||
```
|
||||
|
||||
**根本的問題**:
|
||||
1. **実行時文字列解決**: 全ての関数呼び出しが実行時に文字列で解決
|
||||
2. **スコープ情報欠落**: どこから呼び出すかの情報がMIRに残らない
|
||||
3. **シャドウイング脆弱性**: 同名メソッドが意図せず自己再帰を引き起こす
|
||||
4. **最適化阻害**: コンパイル時に呼び出し先が確定できない
|
||||
5. **デバッグ困難**: MIRダンプに"誰を呼ぶか"が不明瞭
|
||||
|
||||
## 解決策: Callee型の導入
|
||||
|
||||
### 新しいMIR Call命令
|
||||
|
||||
```rust
|
||||
// ✅ 革新後の構造
|
||||
pub enum Callee {
|
||||
/// グローバル関数(nyash.builtin.print等)
|
||||
Global(String),
|
||||
|
||||
/// ボックスメソッド(obj.method())
|
||||
Method {
|
||||
box_name: String,
|
||||
method: String,
|
||||
receiver: Option<ValueId>
|
||||
},
|
||||
|
||||
/// 関数値(動的呼び出し、最小限)
|
||||
Value(ValueId),
|
||||
|
||||
/// 外部関数(C ABI)
|
||||
Extern(String),
|
||||
}
|
||||
|
||||
pub struct Call {
|
||||
pub dst: Option<ValueId>,
|
||||
pub callee: Callee, // ← 型付き呼び出し先!
|
||||
pub args: Vec<ValueId>,
|
||||
}
|
||||
```
|
||||
|
||||
## 実装戦略(3段階)
|
||||
|
||||
### Phase 1: 最小変更(即実装可能)
|
||||
|
||||
**目標**: 破壊的変更なしで基本構造導入
|
||||
|
||||
```rust
|
||||
// 段階移行用構造
|
||||
pub struct Call {
|
||||
pub dst: Option<ValueId>,
|
||||
pub func: ValueId, // 既存(廃止予定)
|
||||
pub callee: Option<Callee>, // 新型(優先)
|
||||
pub args: Vec<ValueId>,
|
||||
}
|
||||
```
|
||||
|
||||
**変更箇所**:
|
||||
- `src/mir/mod.rs`: Callee型定義追加
|
||||
- `src/mir/builder/builder_calls.rs`: build_function_call()修正
|
||||
- `src/backend/*/`: Callee対応実行器追加
|
||||
|
||||
**優先度**:
|
||||
1. グローバル関数(print, error等)のCallee::Global化
|
||||
2. ボックスメソッドのCallee::Method化
|
||||
3. 動的呼び出しのCallee::Value明示化
|
||||
|
||||
### Phase 2: 中期構造化(HIR導入)
|
||||
|
||||
**目標**: コンパイル時名前解決の確立
|
||||
|
||||
```rust
|
||||
// バインダによる名前解決
|
||||
pub struct ResolvedName {
|
||||
pub binding: BindingId,
|
||||
pub kind: BindingKind,
|
||||
}
|
||||
|
||||
pub enum BindingKind {
|
||||
Local(ValueId),
|
||||
Global(FunctionId),
|
||||
Method { box_id: BoxId, method_id: MethodId },
|
||||
Extern(HostFunctionId),
|
||||
}
|
||||
```
|
||||
|
||||
**実装内容**:
|
||||
- AST→HIR変換でSymbol Table構築
|
||||
- 各識別子にBindingId付与
|
||||
- MIRビルダが文字列を一切参照しない構造
|
||||
|
||||
### Phase 3: 長期完成(言語仕様統合)
|
||||
|
||||
**目標**: 完全修飾名と明示的スコープシステム
|
||||
|
||||
```nyash
|
||||
// 明示的スコープ演算子
|
||||
::print("global") // グローバルスコープ
|
||||
global::print("explicit") // グローバル修飾
|
||||
ConsoleStd::print("static") // 静的メソッド
|
||||
|
||||
// 完全修飾名
|
||||
nyash.builtin.print("full") // 完全修飾名
|
||||
std.console.log("module") // モジュールシステム
|
||||
```
|
||||
|
||||
## 技術仕様詳細
|
||||
|
||||
### Callee型の詳細定義
|
||||
|
||||
```rust
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
pub enum Callee {
|
||||
/// グローバル関数
|
||||
/// 例: "print", "error", "panic", "exit"
|
||||
Global(String),
|
||||
|
||||
/// ボックスメソッド呼び出し
|
||||
/// 例: StringBox.upper(), obj.method()
|
||||
Method {
|
||||
box_name: String, // "StringBox", "ConsoleStd"
|
||||
method: String, // "upper", "print"
|
||||
receiver: Option<ValueId> // レシーバオブジェクト(Someの場合)
|
||||
},
|
||||
|
||||
/// 関数値による動的呼び出し
|
||||
/// 例: let f = print; f("hello")
|
||||
Value(ValueId),
|
||||
|
||||
/// 外部関数(C ABI)
|
||||
/// 例: "nyash.console.log"
|
||||
Extern(String),
|
||||
}
|
||||
```
|
||||
|
||||
### MIRビルダの変更
|
||||
|
||||
```rust
|
||||
impl MirBuilder {
|
||||
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),
|
||||
callee, // ← 新型使用
|
||||
args: arg_values,
|
||||
})?;
|
||||
|
||||
Ok(dst)
|
||||
}
|
||||
|
||||
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 // static method
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// 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))
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 段階的移行戦略
|
||||
|
||||
### 1. 互換性保持
|
||||
|
||||
```rust
|
||||
// 実行器での段階的処理
|
||||
fn execute_call(call: &Call) -> Result<Value, Error> {
|
||||
if let Some(callee) = &call.callee {
|
||||
// 新型優先
|
||||
match callee {
|
||||
Callee::Global(name) => execute_global_function(name, &call.args),
|
||||
Callee::Method { box_name, method, receiver } => {
|
||||
execute_method_call(box_name, method, receiver, &call.args)
|
||||
},
|
||||
Callee::Value(func_val) => execute_dynamic_call(func_val, &call.args),
|
||||
Callee::Extern(name) => execute_extern_call(name, &call.args),
|
||||
}
|
||||
} else {
|
||||
// 旧型フォールバック(廃止予定)
|
||||
execute_string_based_call(&call.func, &call.args)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 2. 段階的警告システム
|
||||
|
||||
```rust
|
||||
// コンパイル時警告
|
||||
#[derive(Debug)]
|
||||
pub enum Warning {
|
||||
PotentialSelfRecursion { method: String },
|
||||
DeprecatedStringCall { function: String },
|
||||
AmbiguousScope { name: String, candidates: Vec<String> },
|
||||
}
|
||||
```
|
||||
|
||||
## 予期される効果
|
||||
|
||||
### パフォーマンス向上
|
||||
- **コンパイル時解決**: 実行時オーバーヘッド削減
|
||||
- **最適化機会**: インライン化・特殊化が可能
|
||||
- **キャッシュ効率**: 仮想呼び出し削減
|
||||
|
||||
### 安全性向上
|
||||
- **シャドウイング排除**: 意図しない再帰の完全防止
|
||||
- **静的検証**: コンパイル時エラー検出
|
||||
- **型安全性**: 呼び出し先の型情報保持
|
||||
|
||||
### 保守性向上
|
||||
- **明確な意図**: MIRダンプで呼び出し先が一目瞭然
|
||||
- **デバッグ支援**: スタックトレースの改善
|
||||
- **リファクタリング支援**: 影響範囲の正確な特定
|
||||
|
||||
## Phase 15との統合
|
||||
|
||||
### セルフホスティング安定化への寄与
|
||||
|
||||
1. **using system連携**: built-in namespaceとCallee::Globalの統合
|
||||
2. **PyVM最適化**: 型付き呼び出しによる実行高速化
|
||||
3. **LLVM最適化**: 静的解決による最適化機会拡大
|
||||
4. **コード削減**: 実行時解決ロジックの簡略化
|
||||
|
||||
### 80k→20k行目標への寄与
|
||||
|
||||
- 実行時解決ロジック削減: ~2000行
|
||||
- 名前解決の一元化: ~1500行
|
||||
- デバッグ・エラー処理の簡略化: ~1000行
|
||||
- **合計予想削減**: ~4500行(目標の22.5%)
|
||||
|
||||
## リスク管理
|
||||
|
||||
### 互換性リスク
|
||||
- **対策**: Option<Callee>による段階移行
|
||||
- **検証**: 既存テストの全面グリーン維持
|
||||
|
||||
### 実装複雑性
|
||||
- **対策**: 3段階の明確な分離
|
||||
- **検証**: 各段階でのスモークテスト実施
|
||||
|
||||
### パフォーマンスリスク
|
||||
- **対策**: ベンチマークによる検証
|
||||
- **フォールバック**: 旧実装の維持(警告付き)
|
||||
|
||||
## 結論
|
||||
|
||||
ChatGPT5 Proの洞察により、単純なバグ修正から根本的アーキテクチャ改良への昇華を実現。この変更により、Nyashの関数呼び出しシステムが現代的な言語実装に匹敵する堅牢性と性能を獲得し、Phase 15セルフホスティング目標の重要な基盤となる。
|
||||
|
||||
---
|
||||
|
||||
*この設計は2025-09-23にChatGPT5 Proとの協働により策定されました。*
|
||||
@ -27,4 +27,4 @@ MIR/VM call unification (Phase 12)
|
||||
- If the callee is a String, VM performs a named-function dispatch (existing path).
|
||||
- If the callee is a `FunctionBox` (BoxRef), VM runs it via the interpreter helper with captures/`me` injected and proper return propagation.
|
||||
- Lambda immediate calls are still directly lowered inline for P1 compatibility.
|
||||
- Lambda→FunctionBox: Lambda expressions now lower to a `FunctionNew` MIR instruction that constructs a `FunctionBox` value (minimal: captures currently omitted). This enables MIR-only pipelines to construct and call function values.
|
||||
- Lambda→FunctionBox: Lambda expressions now lower to a `NewClosure` MIR instruction that constructs a `FunctionBox` value (minimal: captures currently omitted). This enables MIR-only pipelines to construct and call function values.
|
||||
|
||||
@ -48,6 +48,58 @@ MIR 13命令の美しさを最大限に活かし、外部コンパイラ依存
|
||||
|
||||
#### 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‑off 既定):
|
||||
- merge 内に copy は置かない。then/else の pred へ edge_copy のみを挿入(self‑copy は No‑Op)。
|
||||
- 分岐直前に pre_if_snapshot を取得し、then/else は snapshot ベースで独立構築。merge で snapshot を基底に戻す。
|
||||
|
||||
@ -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との協働により策定され、段階的実装により確実な成功を目指します。*
|
||||
@ -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