110 lines
3.7 KiB
Markdown
110 lines
3.7 KiB
Markdown
|
|
# Key Insights: VM as a Stepping Stone
|
|||
|
|
|
|||
|
|
## 核心的な発見
|
|||
|
|
|
|||
|
|
### 1. 偶然から生まれた方法論
|
|||
|
|
|
|||
|
|
#### 当初の計画(2024年8月)
|
|||
|
|
```
|
|||
|
|
MIR → VM (インタープリタ実行用)
|
|||
|
|
MIR → LLVM (ネイティブ実行用)
|
|||
|
|
```
|
|||
|
|
並列に実装する予定だった。
|
|||
|
|
|
|||
|
|
#### 実際の経緯
|
|||
|
|
```
|
|||
|
|
MIR → VM → LLVM
|
|||
|
|
```
|
|||
|
|
実装の都合でVM経由にしたところ、予想外の利点が判明。
|
|||
|
|
|
|||
|
|
### 2. VM層の5つの役割
|
|||
|
|
|
|||
|
|
#### 2.1 Living Specification(生きた仕様書)
|
|||
|
|
```rust
|
|||
|
|
// VMで確立されたセマンティクス
|
|||
|
|
match instr {
|
|||
|
|
CallPlugin { type_id: 11, method_id: 3, args: [1, 42] }
|
|||
|
|
=> MapBox.set(1, 42) の動作が確定
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
#### 2.2 Validation Layer(検証層)
|
|||
|
|
- MIR生成が正しいか → VMで実行して確認
|
|||
|
|
- プラグインFFIが正しいか → VMで動作確認
|
|||
|
|
- 型システムが健全か → VMで実行時チェック
|
|||
|
|
|
|||
|
|
#### 2.3 Debug Reference(デバッグ基準)
|
|||
|
|
```
|
|||
|
|
問題: LLVM実行で "Result: 0" (期待値: "Result: 42")
|
|||
|
|
診断: VM実行 → "Result: 42" → LLVMの実装バグと特定
|
|||
|
|
時間: 30分で解決(argc-1の問題)
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
#### 2.4 Pattern Establisher(パターン確立)
|
|||
|
|
```rust
|
|||
|
|
// VM実装で確立したパターン
|
|||
|
|
let tlv_args = encode_tlv_header(argc) + encode_args(args);
|
|||
|
|
call_plugin(type_id, method_id, tlv_args);
|
|||
|
|
|
|||
|
|
// LLVM実装でそのまま再利用
|
|||
|
|
builder.call(nyash_plugin_invoke3_tagged_i64, [type_id, method_id, argc, ...]);
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
#### 2.5 Incremental Complexity(段階的複雑性)
|
|||
|
|
1. 単純な整数演算 → VM実装 → LLVM移植
|
|||
|
|
2. プラグイン呼び出し → VM実装 → LLVM移植
|
|||
|
|
3. 可変長引数 → VM実装 → LLVM移植
|
|||
|
|
|
|||
|
|
### 3. 定量的効果
|
|||
|
|
|
|||
|
|
#### 開発速度
|
|||
|
|
- MIR設計: 1ヶ月(2024年8月)
|
|||
|
|
- VM実装: 2ヶ月(2024年9-10月)
|
|||
|
|
- LLVM実装: 3ヶ月(2024年11月-2025年1月)
|
|||
|
|
- **合計: 6ヶ月でネイティブコンパイラ完成**
|
|||
|
|
|
|||
|
|
#### コード再利用
|
|||
|
|
```
|
|||
|
|
src/runtime/plugin_loader_v2.rs - VM/LLVM共通
|
|||
|
|
src/runtime/plugin_ffi_common.rs - VM/LLVM共通
|
|||
|
|
crates/nyrt/ - 完全共有
|
|||
|
|
→ 約80%のランタイムコードを共有
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
#### デバッグ効率
|
|||
|
|
- VInvokeバグ: 30分で解決(VM比較)
|
|||
|
|
- 推定: 従来手法なら2-3時間
|
|||
|
|
|
|||
|
|
### 4. 一般化可能な条件
|
|||
|
|
|
|||
|
|
#### この手法が有効な言語の特徴
|
|||
|
|
1. **統一的な実行モデル**: Everything is Box のような統一概念
|
|||
|
|
2. **プラグインシステム**: FFI/ABIが重要な役割
|
|||
|
|
3. **段階的な機能追加**: 基本機能から複雑な機能へ
|
|||
|
|
|
|||
|
|
#### 適用が難しい場合
|
|||
|
|
1. VMとネイティブで根本的に異なる実行モデル
|
|||
|
|
2. 極度に最適化されたネイティブコードが必要
|
|||
|
|
3. VM実装のオーバーヘッドが許容できない
|
|||
|
|
|
|||
|
|
### 5. 理論的含意
|
|||
|
|
|
|||
|
|
#### ソフトウェア工学的視点
|
|||
|
|
- **Iterative Refinement**: VM→LLVMは自然な洗練プロセス
|
|||
|
|
- **Separation of Concerns**: 正しさ(VM)と性能(LLVM)の分離
|
|||
|
|
- **Fail Fast**: 問題をVM段階で早期発見
|
|||
|
|
|
|||
|
|
#### プログラミング言語理論的視点
|
|||
|
|
- **Semantic Preservation**: VMセマンティクスの保存性
|
|||
|
|
- **Bisimulation**: VM実行とLLVM実行の等価性証明が容易
|
|||
|
|
- **Gradual Verification**: 段階的な正しさの確認
|
|||
|
|
|
|||
|
|
### 6. 今後の研究課題
|
|||
|
|
|
|||
|
|
1. **自動化**: VM実装からLLVM実装への自動変換
|
|||
|
|
2. **形式的証明**: VM-LLVM等価性の形式的証明
|
|||
|
|
3. **最適化**: VM実行情報を使ったLLVM最適化
|
|||
|
|
|
|||
|
|
## まとめ
|
|||
|
|
|
|||
|
|
「VM as a Stepping Stone」パターンは、偶然の発見から生まれた実用的な言語実装手法である。特に、プラグインシステムを持つ言語や、統一的な実行モデルを持つ言語において、開発効率とコード品質の両面で大きな利点をもたらす。
|