- TypeBox ABI雛形: メソッドスロット管理システム追加 - Type Registry: Array/Map/StringBoxの基本メソッド定義 - Host API: C ABI逆呼び出しシステム実装 - Phase 12ドキュメント整理: 設計文書統合・アーカイブ化 - MIR Builder: クリーンアップと分離実装完了 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
5.4 KiB
5.4 KiB
Codex先生のBoxCall拡張分析 (2025-09-01)
質問内容
Nyash ABI実装の具体的アプローチについて技術相談です。
【背景】 前回の議論で、C ABIとNyash ABIの両方をサポートする方向性が見えました。実装方法について新しいアイデアがあります。
【BoxCall拡張による統合案】 MIR命令を増やさず、既存のBoxCallを自然に拡張する案です:
// 現在のBoxCall
MirInstruction::BoxCall {
receiver: Value,
method: String,
args: Vec<Value>,
}
// 提案:最小限の拡張
MirInstruction::BoxCall {
receiver: Value,
method: String,
args: Vec<Value>,
abi_hint: Option<AbiType>, // 追加
}
【実装の流れ】
- MIRビルダー:プラグインBoxならABIヒント付与
- VM実行時:receiver.type_idから適切なABI選択
- プラグインローダー:nyash.tomlでABI指定可能
【この案の利点】
- MIR命令数は15個維持(Everything is Box哲学)
- 既存コード無変更(後方互換)
- プラグインごとに段階的移行可能
- JITでABI別最適化も可能
【質問】
- このBoxCall拡張案は設計として健全でしょうか?
- abi_hintは本当に必要?VM実行時の型判定で十分?
- 将来的な拡張(WASM等)にも対応できる設計か?
- パフォーマンス影響をどう評価すべきか?
実装の観点から、MIR層でのabi_hint追加とVM層でのABI判定について深く分析してください。特に既存実装への影響を最小化する方法を考慮して。
Codex先生の回答
コードベース分析
まず、現在のMIR/VM実装を確認:
// 現在のMirInstruction::BoxCall定義
BoxCall {
dst: Option<ValueId>,
box_val: ValueId,
method: String,
method_id: Option<u16>, // Universal method用
args: Vec<ValueId>,
effects: EffectMask,
}
プラグインローダーはすでにnyash.tomlから型情報を読み込んでおり、VM実行時に利用可能。
核心的な洞察
abi_hintは実は不要かもしれない!
理由:
- VM実行時にreceiver.type_idから型情報を取得可能
- プラグインローダーが既にABI情報を保持している
- MIR層を変更せずに済む(15命令維持)
実装提案
Option A: 最小限実装(MIR無変更)
// VM層での実装
fn execute_boxcall(&mut self, dst: Option<ValueId>, box_val: ValueId, method: &str, args: &[ValueId]) -> Result<ControlFlow, VMError> {
let receiver = self.get_value(box_val)?;
let type_id = receiver.get_type_id();
// プラグインローダーから型情報取得
if let Some(plugin_info) = self.runtime.get_plugin_info(type_id) {
match plugin_info.abi.as_str() {
"c" => self.call_c_abi_plugin(plugin_info, method, args),
"nyash" => self.call_nyash_abi_plugin(plugin_info, method, args),
_ => self.call_c_abi_plugin(plugin_info, method, args), // fallback
}
} else {
// ビルトインBox処理(既存のまま)
self.execute_builtin_method(receiver, method, args)
}
}
Option B: 将来の拡張性を考慮
// MIRに汎用メタデータ追加(ABIに限定しない)
MirInstruction::BoxCall {
receiver: Value,
method: String,
args: Vec<Value>,
metadata: Option<u32>, // 汎用的な最適化ヒント
}
JIT/AOT最適化の観点
// JIT時の特化
match type_info.abi {
Some("c") => {
// 直接call命令生成
builder.emit_direct_call(symbol, args);
}
Some("nyash") => {
// NyashValue pack/unpackを含めてインライン化
let packed = builder.emit_pack_nyash_values(args);
builder.emit_call_with_abi(symbol, packed);
}
_ => {
// 汎用パス(VM呼び出し)
builder.emit_vm_boxcall(receiver, method, args);
}
}
パフォーマンス評価方法
// ベンチマーク設計
fn benchmark_abi_comparison() {
// 1. 高頻度呼び出し(math operations)
measure_time("C ABI", || {
for _ in 0..1_000_000 {
math_add_c_abi(1.0, 2.0);
}
});
measure_time("Nyash ABI", || {
for _ in 0..1_000_000 {
math_add_nyash_abi(pack(1.0), pack(2.0));
}
});
// 2. 複雑な型(string operations)
// 3. プラグイン初期化コスト
}
結論と推奨事項
- abi_hintは不要 - VM実行時の型判定で十分
- MIR層は無変更 - 15命令の美しさ維持
- 将来拡張は型システム経由 - WASMもプラグイン型として追加
- 段階的実装:
- Week 1: nyash.toml拡張 + VM分岐
- Week 2: ベンチマーク + 最適化
- Week 3: JIT特化(必要なら)
実装の具体的ステップ
Step 1: nyash.toml拡張
- LibraryDefinition に abi: Option<String> 追加
- デフォルトは "c"
Step 2: プラグインローダー
- PluginInfo 構造体に abi フィールド追加
- ロード時に保存
Step 3: VM execute_boxcall
- 型判定でABI分岐
- call_c_abi / call_nyash_abi メソッド追加
Step 4: テスト
- 同一機能の C/Nyash 両実装
- 性能比較測定
この最小限アプローチなら、既存コードへの影響を最小化しつつ、将来の拡張性も確保できます。