feat(plugin): Fix plugin BoxRef return and Box argument support
- Fixed deadlock in FileBox plugin copyFrom implementation (single lock) - Added TLV Handle (tag=8) parsing in calls.rs for returned BoxRefs - Improved plugin loader with config path consistency and detailed logging - Fixed loader routing for proper Handle type_id/fini_method_id resolution - Added detailed logging for TLV encoding/decoding in plugin_loader_v2 Test docs/examples/plugin_boxref_return.nyash now works correctly: - cloneSelf() returns FileBox Handle properly - copyFrom(Box) accepts plugin Box arguments - Both FileBox instances close and fini correctly 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@ -0,0 +1,143 @@
|
||||
# Phase 8.3: WASM Box Operations - オブジェクト操作のWASM実装
|
||||
|
||||
## Summary
|
||||
Phase 8.2 PoC1で基本演算のMIR→WASM変換が完成。次はNyashの核心である「Everything is Box」哲学をWASMで実現する。メモリ管理とBox操作(RefNew/RefGet/RefSet)を実装し、オブジェクト指向プログラミングをWASMで動作させる。
|
||||
|
||||
## Current State
|
||||
- ✅ Phase 8.1: WASM基盤完成(メモリ管理・ランタイム・WAT生成)
|
||||
- ✅ Phase 8.2 PoC1: 基本演算完成(算術・比較・制御フロー・print)
|
||||
- ✅ Phase 8.2 PoC2: CLI統合完成(`--compile-wasm`オプション + Safepoint対応)
|
||||
- ✅ Phase 8.2 PoC3: ブラウザ実行確認(Nyash→WASM→Browser完全パイプライン)
|
||||
- ✅ Phase 8.2 Docs: 実行バックエンド完全ドキュメント作成(execution-backends.md)
|
||||
- 🚧 Phase 8.3: Box操作実装(本Issue)
|
||||
|
||||
## Technical Requirements
|
||||
|
||||
### 1. メモリレイアウト拡張
|
||||
```wat
|
||||
;; Box layout in WASM linear memory:
|
||||
;; [type_id:i32][ref_count:i32][field_count:i32][field0:i32][field1:i32]...
|
||||
;;
|
||||
;; Example: StringBox
|
||||
;; [0x1001][1][2][ptr_to_string][string_length]
|
||||
```
|
||||
|
||||
### 2. メモリアロケータ改良
|
||||
現在のbump allocatorを拡張:
|
||||
- `malloc(size) -> ptr` - メモリ確保
|
||||
- `free(ptr)` - メモリ解放(Phase 8.3では未実装、将来対応)
|
||||
- アライメント考慮(4バイト境界)
|
||||
|
||||
### 3. MIR→WASM変換実装
|
||||
```rust
|
||||
// Phase 6で実装済みのMIR命令
|
||||
MirInstruction::RefNew { dst, box_val } // 新規Box作成
|
||||
MirInstruction::RefGet { dst, reference, field } // フィールド読み取り
|
||||
MirInstruction::RefSet { reference, field, value } // フィールド書き込み
|
||||
MirInstruction::NewBox { dst, box_type, args } // Box生成
|
||||
```
|
||||
|
||||
## Implementation Tasks
|
||||
|
||||
### Task 1: メモリ管理強化 🔧
|
||||
- [ ] Box用メモリレイアウト定義(src/backend/wasm/memory.rs)
|
||||
- [ ] malloc関数のWASM実装(アライメント対応)
|
||||
- [ ] Box型ID管理システム(StringBox=0x1001等)
|
||||
|
||||
### Task 2: RefNew実装 📦
|
||||
- [ ] `MirInstruction::RefNew` → WASM変換
|
||||
- [ ] メモリ確保 + 初期化コード生成
|
||||
- [ ] 参照カウント初期値設定(将来のGC対応準備)
|
||||
- [ ] **実装例参考**:
|
||||
```rust
|
||||
// src/backend/wasm/codegen.rs の MirInstruction::RefNew 処理
|
||||
MirInstruction::RefNew { dst, box_val } => {
|
||||
// 1. メモリサイズ計算 (header + fields)
|
||||
// 2. malloc呼び出し
|
||||
// 3. type_id設定
|
||||
// 4. ref_count=1設定
|
||||
// 5. dst変数に格納
|
||||
}
|
||||
```
|
||||
|
||||
### Task 3: RefGet/RefSet実装 🔍
|
||||
- [ ] フィールドオフセット計算
|
||||
- [ ] `MirInstruction::RefGet` → `i32.load` 変換
|
||||
- [ ] `MirInstruction::RefSet` → `i32.store` 変換
|
||||
- [ ] 型安全性チェック(デバッグビルドのみ)
|
||||
|
||||
### Task 4: NewBox実装 🎁
|
||||
- [ ] Box型名→型ID解決
|
||||
- [ ] コンストラクタ呼び出しシーケンス生成
|
||||
- [ ] 初期化引数の処理
|
||||
|
||||
### Task 5: テスト実装 ✅
|
||||
- [ ] `test_wasm_poc2_box_operations.rs` 作成
|
||||
- [ ] 基本的なBox操作テスト
|
||||
```nyash
|
||||
// テスト対象のNyashコード相当
|
||||
box DataBox { init { value } }
|
||||
local obj = new DataBox()
|
||||
obj.value = 42
|
||||
print(obj.value) // 42が出力される
|
||||
```
|
||||
- [ ] **Copilot実装支援用:詳細テストケース**
|
||||
- [ ] RefNew単体テスト(Box作成のみ)
|
||||
- [ ] RefSet単体テスト(フィールド書き込み)
|
||||
- [ ] RefGet単体テスト(フィールド読み取り)
|
||||
- [ ] 複合操作テスト(作成→書き込み→読み取り)
|
||||
- [ ] エラーハンドリングテスト(不正アクセス等)
|
||||
- [ ] メモリレイアウト検証テスト(アライメント確認)
|
||||
|
||||
## Success Criteria
|
||||
- [ ] RefNew/RefGet/RefSetがWASMで正常動作
|
||||
- [ ] 簡単なオブジェクト操作がend-to-endで実行可能
|
||||
- [ ] メモリレイアウトが明確にドキュメント化
|
||||
- [ ] 既存のPoC1テストが引き続きPASS
|
||||
- [ ] **Copilot品質保証**:
|
||||
- [ ] 全テストケースがCI環境でPASS
|
||||
- [ ] `cargo check` でビルドエラーなし
|
||||
- [ ] `--compile-wasm` オプションで正常なWAT出力
|
||||
- [ ] ブラウザでの実行確認(`wasm_demo/` 環境)
|
||||
- [ ] 既存Phase 8.2テストとの互換性維持
|
||||
|
||||
## Technical Notes
|
||||
|
||||
### 現在の実装基盤(2025-08-14時点)
|
||||
- ✅ **WASM CLI**: `./target/release/nyash --compile-wasm program.nyash` で動作
|
||||
- ✅ **ブラウザテスト**: `wasm_demo/` ディレクトリに実行環境完備
|
||||
- ✅ **Safepoint対応**: `src/backend/wasm/codegen.rs:line XX` で実装済み
|
||||
- ✅ **実行ドキュメント**: `docs/execution-backends.md` で使用方法詳細化
|
||||
|
||||
### AST→MIR制約への対応
|
||||
現在AST→MIRは基本構文のみ対応(ユーザー定義Box未対応)。本Phaseでは:
|
||||
- MIR直接構築によるテストを優先
|
||||
- AST→MIR拡張は並行して別タスクで実施
|
||||
|
||||
### Copilot実装ガイダンス
|
||||
Phase 8.3実装時の推奨アプローチ:
|
||||
1. **段階的実装**: RefNew → RefGet → RefSet の順序で個別実装
|
||||
2. **テスト駆動**: 各MIR命令に対応する単体テストを先に作成
|
||||
3. **既存パターン活用**: `src/backend/wasm/codegen.rs` の既存実装を参考
|
||||
4. **メモリ安全性**: アライメント・境界チェックを必ず実装
|
||||
5. **デバッグ支援**: WAT出力にコメント追加で可読性向上
|
||||
|
||||
### 将来の拡張準備
|
||||
- 参照カウントフィールドを含むが、Phase 8.3では使用しない
|
||||
- GC実装は将来のPhaseで対応
|
||||
- 文字列等の可変長データは次Phase以降
|
||||
|
||||
## Dependencies
|
||||
- wasmtime 18.0.4
|
||||
- wabt 0.10.0
|
||||
- 既存のMIR Phase 6実装
|
||||
|
||||
## Estimate
|
||||
- 実装期間: 2-3日
|
||||
- 複雑度: 中(メモリ管理が主な課題)
|
||||
- リスク: WASMメモリ管理の複雑性
|
||||
|
||||
---
|
||||
Created: 2025-08-13
|
||||
Target: Phase 8.3 PoC2
|
||||
Priority: High
|
||||
224
docs/development/roadmap/phases/phase-8/phase8_mir_to_wasm.md
Normal file
224
docs/development/roadmap/phases/phase-8/phase8_mir_to_wasm.md
Normal file
@ -0,0 +1,224 @@
|
||||
# Phase 8: MIR→WASM codegen (browser/wasmtime; sandboxed; Rust runtime free)
|
||||
|
||||
## Summary
|
||||
- MIR から素の WebAssembly を生成し、ブラウザ/wasmtime(WASI)でサンドボックス実行する。
|
||||
- Rust は「コンパイラ本体」のみ。実行は純WASM+ホストimport(env.print 等)。
|
||||
- Phase 6/7で実装済みのMIR命令(RefNew/RefGet/RefSet, FutureNew/Await等)をWASM命令に変換
|
||||
|
||||
## Technical Architecture
|
||||
### WASM Module Structure
|
||||
```wat
|
||||
(module
|
||||
(memory (export "memory") 1) ; 64KB initial
|
||||
(import "env" "print" (func $print (param i32)))
|
||||
|
||||
;; Heap management
|
||||
(global $heap_ptr (mut i32) (i32.const 1024))
|
||||
|
||||
;; Main entry point
|
||||
(func (export "main") (result i32)
|
||||
;; Generated from MIR main function
|
||||
)
|
||||
)
|
||||
```
|
||||
|
||||
### Memory Layout
|
||||
- `0x000-0x3FF`: Reserved/globals
|
||||
- `0x400-0x7FF`: Stack space
|
||||
- `0x800+`: Heap (bump allocator)
|
||||
- Box layout: `[type_id:i32][field_count:i32][field0:i32][field1:i32]...`
|
||||
|
||||
## Scope
|
||||
- **ABI/Imports/Exports(最小)**
|
||||
- exports: `main() -> i32`, `memory`
|
||||
- imports: `env.print(i32)`(デバッグ用に整数のみ。将来文字列ABIを定義)
|
||||
- **メモリ/ヒープ**
|
||||
- 線形メモリに簡易ヒープ(bump allocator → フリーリスト)
|
||||
- Box の固定レイアウト(フィールド→オフセット表; 型名→レイアウトは暫定固定)
|
||||
- **命令カバレッジ(段階導入)**
|
||||
- **PoC1**: 算術/比較/分岐/loop/return/print
|
||||
- **PoC2**: RefNew/RefSet/RefGet(Phase 6 と整合)で `print(o.x)`
|
||||
- **PoC3**: Weak/Barrier の下地(WeakLoad は当面 Some 相当、Barrier は no-op)
|
||||
- **PoC4**: Future/Await の基本実装(スレッドなしの即座完了)
|
||||
- **CLI 統合**
|
||||
- `nyash --backend wasm program.nyash` で生成・実行(wasmtime 呼び出し)
|
||||
- `--output program.wasm` でWASMファイル出力のみ
|
||||
|
||||
## Implementation Plan
|
||||
|
||||
### Phase 8.1: 基盤構築 (Foundation)
|
||||
- [ ] **Task 1.1**: WASMバックエンドモジュール作成
|
||||
- `src/backend/wasm/mod.rs` - エントリポイント
|
||||
- `src/backend/wasm/codegen.rs` - MIR→WASM変換器
|
||||
- `src/backend/wasm/memory.rs` - メモリ管理
|
||||
- `src/backend/wasm/runtime.rs` - ランタイムヘルパー
|
||||
|
||||
- [ ] **Task 1.2**: WASM出力基盤
|
||||
- WAT形式での出力(人間可読、デバッグ用)
|
||||
- `wabt` crateでWAT→WASMバイナリ変換
|
||||
-基本的なmodule structure生成
|
||||
|
||||
### Phase 8.2: PoC1 - 基本演算 (Basic Operations)
|
||||
- [ ] **Task 2.1**: MIR基本命令の変換実装
|
||||
- `MirInstruction::Const` → WASM `i32.const`
|
||||
- `MirInstruction::BinOp` → WASM算術命令 (`i32.add`, `i32.mul` etc.)
|
||||
- `MirInstruction::Compare` → WASM比較命令 (`i32.eq`, `i32.lt` etc.)
|
||||
|
||||
- [ ] **Task 2.2**: 制御フロー実装
|
||||
- `MirInstruction::Branch` → WASM `br_if`
|
||||
- `MirInstruction::Jump` → WASM `br`
|
||||
- `MirInstruction::Return` → WASM `return`
|
||||
|
||||
- [ ] **Task 2.3**: Print機能実装
|
||||
- `MirInstruction::Print` → `call $print`
|
||||
- env.print import の定義
|
||||
|
||||
**PoC1目標**: `42 + 8` のような基本計算がWASMで動作
|
||||
|
||||
### Phase 8.3: PoC2 - オブジェクト操作 (Object Operations)
|
||||
- [ ] **Task 3.1**: メモリ管理実装
|
||||
- Bump allocator (`$heap_ptr` global)
|
||||
- `malloc(size) -> ptr` WASM function
|
||||
- Box layout定義 (`[type_id][field_count][fields...]`)
|
||||
|
||||
- [ ] **Task 3.2**: 参照操作実装
|
||||
- `MirInstruction::RefNew` → `call $malloc` + 初期化
|
||||
- `MirInstruction::RefGet` → memory load (`i32.load offset=...`)
|
||||
- `MirInstruction::RefSet` → memory store (`i32.store offset=...`)
|
||||
|
||||
**PoC2目標**: `o = new Obj(); o.x = 1; print(o.x)` 相当がWASMで動作
|
||||
|
||||
### Phase 8.4: PoC3 - 拡張機能下地 (Extension Foundation)
|
||||
- [ ] **Task 4.1**: Weak参照ダミー実装
|
||||
- `MirInstruction::WeakNew` → 通常の参照として処理
|
||||
- `MirInstruction::WeakLoad` → 常にSome相当で成功
|
||||
|
||||
- [ ] **Task 4.2**: Barrier命令ダミー実装
|
||||
- `MirInstruction::BarrierRead/Write` → no-op
|
||||
|
||||
- [ ] **Task 4.3**: Future基本実装
|
||||
- `MirInstruction::FutureNew` → 即座に完了状態のFuture
|
||||
- `MirInstruction::Await` → 値をそのまま返す
|
||||
|
||||
### Phase 8.5: CLI統合 (CLI Integration)
|
||||
- [ ] **Task 5.1**: CLI実装
|
||||
- `--backend wasm` オプション追加
|
||||
- `--output file.wasm` オプション追加
|
||||
- wasmtimeとの連携(`wasmtime run`)
|
||||
|
||||
- [ ] **Task 5.2**: エラーハンドリング
|
||||
- 未対応MIR命令の明確なエラーメッセージ
|
||||
- WASM生成失敗時の診断情報
|
||||
|
||||
## Acceptance Criteria
|
||||
|
||||
### PoC1 (Basic Operations)
|
||||
- ✅ **WASM Generation**: 基本MIR命令がvalid WASMに変換される
|
||||
- ✅ **Wasmtime Execution**: `wasmtime run output.wasm` で正常実行
|
||||
- ✅ **Arithmetic**: `print(42 + 8)` → stdout: `50`
|
||||
- ✅ **Control Flow**: if文、loop文が正しく動作
|
||||
|
||||
### PoC2 (Object Operations)
|
||||
- ✅ **Memory Allocation**: RefNew でヒープメモリが正しく割り当てられる
|
||||
- ✅ **Field Access**: `o = new DataBox(); o.value = 1; print(o.value)` → stdout: `1`
|
||||
- ✅ **Memory Layout**: Box構造がメモリ上で正しいレイアウトになる
|
||||
|
||||
### PoC3 (Extension Foundation)
|
||||
- ✅ **Weak Reference**: WeakNew/WeakLoad命令がno-opとして動作
|
||||
- ✅ **Memory Barriers**: BarrierRead/Write命令が含まれても実行できる
|
||||
- ✅ **Future Operations**: FutureNew/Await が即座完了として動作
|
||||
|
||||
### CLI Integration
|
||||
- ✅ **Command Line**: `nyash --backend wasm test.nyash` で実行可能
|
||||
- ✅ **File Output**: `nyash --backend wasm --output test.wasm test.nyash` でファイル出力
|
||||
- ✅ **Error Messages**: 未対応機能の明確なエラーメッセージ
|
||||
|
||||
## Test Strategy
|
||||
|
||||
### Unit Tests (Rust)
|
||||
```rust
|
||||
// tests/wasm_codegen_tests.rs
|
||||
#[test]
|
||||
fn test_basic_arithmetic_codegen() {
|
||||
let mir = /* 42 + 8 のMIR */;
|
||||
let wasm_bytes = WasmBackend::new().compile_module(mir).unwrap();
|
||||
let result = wasmtime_execute(&wasm_bytes);
|
||||
assert_eq!(result.stdout, "50\n");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_ref_operations_codegen() {
|
||||
let mir = /* object field access のMIR */;
|
||||
let wasm_bytes = WasmBackend::new().compile_module(mir).unwrap();
|
||||
let result = wasmtime_execute(&wasm_bytes);
|
||||
assert_eq!(result.stdout, "1\n");
|
||||
}
|
||||
```
|
||||
|
||||
### Integration Tests
|
||||
- `tests/wasm_poc1_arithmetic.nyash` → MIR → WASM → wasmtime実行
|
||||
- `tests/wasm_poc2_objects.nyash` → RefNew/RefGet/RefSet使用 → WASM実行
|
||||
- `tests/wasm_poc3_features.nyash` → Weak/Future命令含む → WASM実行
|
||||
|
||||
### Browser Testing
|
||||
```html
|
||||
<!-- tests/browser_test.html -->
|
||||
<script type="module">
|
||||
const importObject = {
|
||||
env: {
|
||||
print: (value) => console.log(value)
|
||||
}
|
||||
};
|
||||
const wasmModule = await WebAssembly.instantiateStreaming(
|
||||
fetch('./test.wasm'), importObject
|
||||
);
|
||||
const result = wasmModule.instance.exports.main();
|
||||
console.log('Result:', result);
|
||||
</script>
|
||||
```
|
||||
|
||||
## Technical Dependencies
|
||||
|
||||
### Required Crates
|
||||
- `wabt` - WAT ↔ WASM conversion
|
||||
- `wasmtime` - Runtime execution (dev dependency)
|
||||
- `wat` - WAT text format parsing (optional)
|
||||
|
||||
### WASM Tools
|
||||
- `wasmtime` CLI - Local execution & testing
|
||||
- `wasm-objdump` - Binary inspection (optional)
|
||||
- `wasm-validate` - Validation (optional)
|
||||
|
||||
## Development Notes
|
||||
|
||||
### Memory Management Strategy
|
||||
1. **Phase 8.3**: Simple bump allocator (no free)
|
||||
2. **Future**: Free list allocator
|
||||
3. **Future**: Generational GC integration
|
||||
|
||||
### Type System Mapping
|
||||
| Nyash Type | MIR Type | WASM Type | Memory Layout |
|
||||
|-----------|----------|-----------|---------------|
|
||||
| IntegerBox | Integer | i32 | 4 bytes |
|
||||
| BoolBox | Bool | i32 | 4 bytes (0/1) |
|
||||
| DataBox | Box("DataBox") | i32 | ptr to [type_id, field_count, fields...] |
|
||||
|
||||
### Debugging Support
|
||||
- WAT output for human inspection
|
||||
- Source map generation (future)
|
||||
- WASM stack trace integration (future)
|
||||
|
||||
## Out of Scope (Phase 8)
|
||||
- 本格的なGC(mark-sweep、generational等)
|
||||
- Weak参照の実際の無効化メカニズム
|
||||
- Pin/Unpin、fini()のカスケード処理
|
||||
- JIT/AOTコンパイル最適化
|
||||
- 複雑な文字列ABI(UTF-8、length prefixed等)
|
||||
- WASI I/O インターフェース(file、network等)
|
||||
|
||||
## References & Dependencies
|
||||
- **Phase 6**: RefNew/RefGet/RefSet MIR命令 (実装済み)
|
||||
- **Phase 7**: FutureNew/Await MIR命令 (実装済み)
|
||||
- docs/予定/native-plan/README.md(Phase 8詳細)
|
||||
- docs/説明書/wasm/* (WASM関連ドキュメント)
|
||||
- [WebAssembly Specification](https://webassembly.github.io/spec/)
|
||||
@ -0,0 +1,335 @@
|
||||
# Phase 8.4: AST→MIR Lowering完全実装
|
||||
|
||||
## 🎯 Issue概要
|
||||
|
||||
**現在の最重要課題**: Phase 8.3のBox操作WASMが実際にテストできない
|
||||
|
||||
**根本原因**: AST→MIR Loweringが不完全で、基本的なオブジェクト指向機能が使用不可
|
||||
|
||||
**影響範囲**:
|
||||
- ユーザー定義Boxが定義・使用できない
|
||||
- Phase 8.3のRefNew/RefGet/RefSet WASMが実際にテストできない
|
||||
- Everything is Box哲学の基盤部分が欠如
|
||||
|
||||
## 🚨 現在の具体的問題
|
||||
|
||||
### 1. ユーザー定義Box定義不可
|
||||
```nyash
|
||||
box DataBox {
|
||||
init { value }
|
||||
}
|
||||
```
|
||||
**エラー**: `BoxDeclaration support is currently limited to static box Main`
|
||||
|
||||
### 2. オブジェクト生成不可
|
||||
```nyash
|
||||
local obj = new DataBox(42)
|
||||
```
|
||||
**エラー**: `Unsupported AST node type: New`
|
||||
|
||||
### 3. フィールドアクセス不可
|
||||
```nyash
|
||||
obj.value
|
||||
me.field = 10
|
||||
```
|
||||
**エラー**: `Unsupported AST node type: Me`
|
||||
|
||||
### 4. デリゲーション構文不完全
|
||||
```nyash
|
||||
from Parent.method()
|
||||
override method() { ... }
|
||||
```
|
||||
**エラー**: 未対応
|
||||
|
||||
## 📋 実装が必要な機能
|
||||
|
||||
### Priority 1: 基本オブジェクト操作
|
||||
- [ ] **BoxDeclaration**: ユーザー定義Box定義
|
||||
- [ ] **New expression**: `new DataBox(args)` オブジェクト生成
|
||||
- [ ] **Field access**: `obj.field` フィールド読み取り
|
||||
- [ ] **Field assignment**: `obj.field = value` フィールド書き込み
|
||||
- [ ] **Me expression**: `me.field` 自己参照
|
||||
|
||||
### Priority 2: デリゲーション・継承
|
||||
- [ ] **From expression**: `from Parent.method()` デリゲーション呼び出し
|
||||
- [ ] **Override declaration**: `override method() { ... }` メソッドオーバーライド
|
||||
- [ ] **Method calls**: `obj.method(args)` メソッド呼び出し
|
||||
|
||||
### Priority 3: 高度な機能
|
||||
- [ ] **Constructor calls**: `pack()`, `init()` コンストラクタ
|
||||
- [ ] **Static methods**: `Class.method()` 静的メソッド呼び出し
|
||||
|
||||
## 🔧 実装場所・方法
|
||||
|
||||
### メインファイル: `src/mir/builder.rs`
|
||||
|
||||
#### 1. `build_expression()` メソッド拡張 (行103-)
|
||||
**現在の対応**: Literal, BinaryOp, UnaryOp, AwaitExpression のみ
|
||||
|
||||
**追加が必要**:
|
||||
```rust
|
||||
// Line 215付近の _ => Err(...) の前に追加
|
||||
ASTNode::New { class, arguments, .. } => {
|
||||
self.build_new_expression(class, arguments)
|
||||
},
|
||||
|
||||
ASTNode::Me { span } => {
|
||||
// 現在のインスタンスへの参照を返す
|
||||
self.build_me_expression()
|
||||
},
|
||||
|
||||
ASTNode::FieldAccess { object, field, .. } => {
|
||||
self.build_field_access(*object, field)
|
||||
},
|
||||
|
||||
ASTNode::MethodCall { object, method, arguments, .. } => {
|
||||
self.build_method_call(*object, method, arguments)
|
||||
},
|
||||
|
||||
ASTNode::From { parent, method, arguments, .. } => {
|
||||
self.build_from_expression(parent, method, arguments)
|
||||
},
|
||||
```
|
||||
|
||||
#### 2. `build_statement()` メソッド拡張
|
||||
**BoxDeclaration制限解除**:
|
||||
```rust
|
||||
// Line 190付近の条件を拡張
|
||||
ASTNode::BoxDeclaration { name, methods, is_static, fields, .. } => {
|
||||
if *is_static && name == "Main" {
|
||||
// 既存のstatic box Main処理
|
||||
} else {
|
||||
// 新規:ユーザー定義Box処理
|
||||
self.build_box_declaration(name.clone(), methods.clone(), fields.clone())
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### 3. 新規メソッド実装が必要
|
||||
|
||||
```rust
|
||||
impl MirBuilder {
|
||||
fn build_new_expression(&mut self, class: String, arguments: Vec<ASTNode>) -> Result<ValueId, String> {
|
||||
// RefNew MIR命令生成
|
||||
// Phase 8.3のWASM Box操作と連携
|
||||
}
|
||||
|
||||
fn build_field_access(&mut self, object: ASTNode, field: String) -> Result<ValueId, String> {
|
||||
// RefGet MIR命令生成
|
||||
}
|
||||
|
||||
fn build_field_assignment(&mut self, object: ASTNode, field: String, value: ASTNode) -> Result<ValueId, String> {
|
||||
// RefSet MIR命令生成
|
||||
}
|
||||
|
||||
fn build_me_expression(&mut self) -> Result<ValueId, String> {
|
||||
// 現在のインスタンスへの参照
|
||||
}
|
||||
|
||||
fn build_box_declaration(&mut self, name: String, methods: Vec<ASTNode>, fields: Vec<String>) -> Result<(), String> {
|
||||
// ユーザー定義Box登録
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 🧪 テストケース(Copilot実装必須)
|
||||
|
||||
### Test 1: 基本Box定義・生成
|
||||
**ファイル**: `test_user_defined_box.nyash`
|
||||
```nyash
|
||||
box DataBox {
|
||||
init { value }
|
||||
|
||||
pack(v) {
|
||||
me.value = v
|
||||
}
|
||||
}
|
||||
|
||||
static box Main {
|
||||
main() {
|
||||
local obj = new DataBox(42)
|
||||
return obj.value
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**期待MIR出力例**:
|
||||
```mir
|
||||
define void @main() {
|
||||
bb0:
|
||||
0: safepoint
|
||||
1: %0 = const 42
|
||||
2: %1 = ref_new "DataBox", %0
|
||||
3: %2 = ref_get %1, "value"
|
||||
4: ret %2
|
||||
}
|
||||
```
|
||||
|
||||
**実行期待結果**: `42`
|
||||
|
||||
### Test 2: フィールドアクセス・代入
|
||||
**ファイル**: `test_field_operations.nyash`
|
||||
```nyash
|
||||
box Counter {
|
||||
init { count }
|
||||
|
||||
pack() {
|
||||
me.count = 0
|
||||
}
|
||||
|
||||
increment() {
|
||||
me.count = me.count + 1
|
||||
return me.count
|
||||
}
|
||||
}
|
||||
|
||||
static box Main {
|
||||
main() {
|
||||
local c = new Counter()
|
||||
return c.increment()
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**期待結果**: `1`
|
||||
|
||||
### Test 3: デリゲーション基本
|
||||
**ファイル**: `test_delegation_basic.nyash`
|
||||
```nyash
|
||||
box Parent {
|
||||
init { name }
|
||||
|
||||
pack(n) {
|
||||
me.name = n
|
||||
}
|
||||
|
||||
greet() {
|
||||
return "Hello " + me.name
|
||||
}
|
||||
}
|
||||
|
||||
box Child from Parent {
|
||||
init { age }
|
||||
|
||||
pack(n, a) {
|
||||
from Parent.pack(n)
|
||||
me.age = a
|
||||
}
|
||||
|
||||
override greet() {
|
||||
local base = from Parent.greet()
|
||||
return base + " (age " + me.age + ")"
|
||||
}
|
||||
}
|
||||
|
||||
static box Main {
|
||||
main() {
|
||||
local c = new Child("Alice", 25)
|
||||
return c.greet()
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**期待結果**: `"Hello Alice (age 25)"`
|
||||
|
||||
### Test 4: WASM Box操作統合テスト
|
||||
**ファイル**: `test_wasm_box_integration.nyash`
|
||||
```nyash
|
||||
box SimpleData {
|
||||
init { x, y }
|
||||
|
||||
pack(a, b) {
|
||||
me.x = a
|
||||
me.y = b
|
||||
}
|
||||
|
||||
sum() {
|
||||
return me.x + me.y
|
||||
}
|
||||
}
|
||||
|
||||
static box Main {
|
||||
main() {
|
||||
local data = new SimpleData(10, 20)
|
||||
return data.sum()
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**テスト方法**:
|
||||
```bash
|
||||
# MIR生成テスト
|
||||
./target/release/nyash --dump-mir test_wasm_box_integration.nyash
|
||||
|
||||
# WASM生成テスト
|
||||
./target/release/nyash --compile-wasm test_wasm_box_integration.nyash
|
||||
|
||||
# WASM実行テスト(wasmtime)
|
||||
./target/release/nyash --compile-wasm test_wasm_box_integration.nyash > test.wat
|
||||
sed -n '4,$p' test.wat > clean_test.wat
|
||||
$HOME/.wasmtime/bin/wasmtime run clean_test.wat --invoke main
|
||||
```
|
||||
|
||||
**期待結果**: 全プロセスでエラーなし、最終結果 `30`
|
||||
|
||||
## ✅ 成功基準
|
||||
|
||||
### 必須基準
|
||||
- [ ] 上記4つのテストケースがすべて成功
|
||||
- [ ] `cargo build --release` でエラーなし
|
||||
- [ ] 既存のstatic box Main機能が破損していない
|
||||
- [ ] Phase 8.3のWASM Box操作が実際に動作確認
|
||||
|
||||
### 理想基準
|
||||
- [ ] MIR→WASM→wasmtime実行の完全パイプライン動作
|
||||
- [ ] ベンチマーク性能が劣化していない
|
||||
- [ ] 複雑なデリゲーション・継承チェーンが動作
|
||||
|
||||
## 🤖 Copilot向け実装ガイド
|
||||
|
||||
### 実装順序推奨
|
||||
1. **Phase 1**: `build_new_expression()` - オブジェクト生成
|
||||
2. **Phase 2**: `build_field_access()` - フィールド読み取り
|
||||
3. **Phase 3**: Field assignment - フィールド書き込み
|
||||
4. **Phase 4**: `build_me_expression()` - 自己参照
|
||||
5. **Phase 5**: `build_box_declaration()` - Box定義
|
||||
6. **Phase 6**: デリゲーション構文
|
||||
|
||||
### 既存コードとの統合注意点
|
||||
- **MIR命令**: 既存のRefNew/RefGet/RefSet MIR命令を活用
|
||||
- **型システム**: 既存のValueId/BasicBlockId体系を維持
|
||||
- **エラーハンドリング**: 既存のResult<ValueId, String>パターンを踏襲
|
||||
|
||||
### デバッグ支援
|
||||
```bash
|
||||
# MIR生成確認
|
||||
./target/release/nyash --dump-mir --mir-verbose test_file.nyash
|
||||
|
||||
# パーサー確認
|
||||
./target/release/nyash --debug-fuel unlimited test_file.nyash
|
||||
```
|
||||
|
||||
## 📊 期待される効果
|
||||
|
||||
### 技術的効果
|
||||
- Phase 8.3のBox操作WASMが実際に使用可能
|
||||
- Everything is Box哲学の実用レベル実現
|
||||
- 真のオブジェクト指向プログラミング対応
|
||||
|
||||
### 開発効率向上
|
||||
- Nyashプログラムの実用性大幅向上
|
||||
- 実際のアプリケーション開発が可能
|
||||
- ベンチマーク・テストの精度向上
|
||||
|
||||
## 🔗 関連リンク
|
||||
|
||||
- **Phase 8.3実装**: RefNew/RefGet/RefSet WASM対応
|
||||
- **MIR設計**: `docs/説明書/reference/mir-reference.md`
|
||||
- **AST定義**: `src/ast.rs`
|
||||
- **既存MIR実装**: `src/mir/instruction.rs`
|
||||
|
||||
---
|
||||
|
||||
**優先度**: Critical
|
||||
**担当**: Copilot + Claude協調実装
|
||||
**最終目標**: test_wasm_box_integration.nyash が完全動作
|
||||
@ -0,0 +1,338 @@
|
||||
# Phase 8.5: MIR 25命令完全仕様実装(ChatGPT5 + AI大会議決定版)
|
||||
|
||||
## 🎯 Issue概要
|
||||
|
||||
**最終決定**: AI大会議(Gemini+Codex)+ ChatGPT5先生によるMIR 25命令完全仕様の実装
|
||||
|
||||
**仕様確定**: ChatGPT5先生が「化け物に伸びる余白」と「実装の現実」のちょうど真ん中として設計した、**Nyashのコア価値(所有森+weak+Bus+効果注釈)を無理なくIR化**する完璧な25命令セット
|
||||
|
||||
## 📋 確定版: MIR 25命令完全仕様
|
||||
|
||||
### **Tier-0: 普遍コア(8命令)**
|
||||
```mir
|
||||
Const // 定数値生成(pure)
|
||||
BinOp // 二項演算(pure)
|
||||
Compare // 比較演算(pure)
|
||||
Branch // 条件分岐(control)
|
||||
Jump // 無条件ジャンプ(control)
|
||||
Phi // SSA phi関数(pure)
|
||||
Call // 外部関数呼び出し(context依存)
|
||||
Return // 関数戻り(control)
|
||||
```
|
||||
|
||||
**効果**: 将来のJIT/AOT/WASMすべてで必須の基盤
|
||||
|
||||
### **Tier-1: Nyashセマンティクス(12命令)**
|
||||
```mir
|
||||
NewBox // 強所有のBox生成(所有森のノード)
|
||||
BoxFieldLoad // Boxのフィールド読み(pure)
|
||||
BoxFieldStore // Boxのフィールド書き(mut)
|
||||
BoxCall // Boxのメソッド呼び出し(context依存)
|
||||
Safepoint // 分割finiや割込み許可ポイント(io)
|
||||
RefGet // 参照(強/弱を問わず)を値として取得(pure)
|
||||
RefSet // 参照の差し替え(所有規則検証付き)(mut)
|
||||
WeakNew // weak ハンドル生成(非所有リンク作成)(pure)
|
||||
WeakLoad // weak から生存チェック付きで強参照取得(失効時null)(pure)
|
||||
WeakCheck // weak の生存確認(bool)(pure)
|
||||
Send // Bus送信(io)
|
||||
Recv // Bus受信(io)
|
||||
```
|
||||
|
||||
**革命的価値**: **所有森+weak+Bus** が言語一次市民として表現可能
|
||||
|
||||
### **Tier-2: 実装補助・最適化友好(5命令)**
|
||||
```mir
|
||||
TailCall // 末尾呼び出し(スタック節約)(control)
|
||||
Adopt // 所有移管: this が子を強所有に取り込む(mut)
|
||||
Release // 強所有を解除(weak化 or null化)(mut)
|
||||
MemCopy // 小さなメモリ移動(構造体/配列最適化フック)(mut)
|
||||
AtomicFence // 並行時の順序保証(Actor/Port境界で使用)(io)
|
||||
```
|
||||
|
||||
**位置づけ**: 言語仕様の裏方。無くても表現可能だが、**性能・安全検査・移植性**が安定
|
||||
|
||||
## 🔧 効果(Effect)システム
|
||||
|
||||
### 効果分類と最適化ルール
|
||||
```rust
|
||||
pub enum Effect {
|
||||
Pure, // 再順序化OK、CSE/LICM可能
|
||||
Mut, // 同一Box/同一Fieldで依存保持
|
||||
Io, // 再順序化禁止、副作用あり
|
||||
Control, // 制御フロー変更
|
||||
}
|
||||
```
|
||||
|
||||
### 命令別効果定義
|
||||
- **pure**: Const, BinOp, Compare, Phi, RefGet, WeakNew, WeakLoad, WeakCheck
|
||||
- **mut**: BoxFieldStore, RefSet, Adopt, Release, MemCopy
|
||||
- **io**: Send, Recv, Safepoint, AtomicFence
|
||||
- **control**: Branch, Jump, Return, TailCall
|
||||
- **context依存**: Call, BoxCall(呼び先効果に従属)
|
||||
|
||||
## 🔍 検証(Verifier)要件
|
||||
|
||||
### 所有森検証ルール
|
||||
```rust
|
||||
// 1. 強参照のin-degree制約
|
||||
fn verify_ownership_forest(mir: &MirModule) -> Result<(), VerifyError> {
|
||||
for instruction in mir.instructions() {
|
||||
match instruction {
|
||||
NewBox { dst, .. } => verify_strong_indegree_one(dst)?,
|
||||
Adopt { parent, child, .. } => verify_ownership_transfer(parent, child)?,
|
||||
Release { ref_val, .. } => verify_release_safety(ref_val)?,
|
||||
RefSet { target, new_ref, .. } => verify_refset_safety(target, new_ref)?,
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 2. 強循環禁止検証
|
||||
fn verify_no_strong_cycles(mir: &MirModule) -> Result<(), VerifyError> {
|
||||
// 強エッジのみ辿ってDAG(森)であることを確認
|
||||
}
|
||||
|
||||
// 3. weak参照の決定的挙動
|
||||
fn verify_weak_determinism(mir: &MirModule) -> Result<(), VerifyError> {
|
||||
// WeakLoad/WeakCheckの失効時はnull/falseを返す(例外禁止)
|
||||
}
|
||||
```
|
||||
|
||||
### 安全性検証項目
|
||||
- [ ] **所有森**: `strong in-degree ≤ 1`(NewBox/Adopt/Release/RefSetで常時検査)
|
||||
- [ ] **強循環禁止**: 強エッジのみ辿ってDAG(森)であること
|
||||
- [ ] **weak/強相互**: 双方向とも強 → エラー(片側はWeakNew経由で弱化)
|
||||
- [ ] **RefSetの安全**: 強→強の差し替え時は旧所有元からのReleaseが伴うこと
|
||||
- [ ] **WeakLoad/WeakCheck**: 失効時はnull/falseを返す(例外禁止、決定的挙動)
|
||||
- [ ] **TailCall**: 末尾位置のみ可(Return直前)
|
||||
- [ ] **Send/Recv**: at-least-once契約を満たすか、契約を明示
|
||||
|
||||
## 🚀 実装範囲・優先度
|
||||
|
||||
### Phase 8.5A: コア命令実装(最優先)
|
||||
- [ ] **Tier-0完全実装**: 8命令の基盤確立
|
||||
- [ ] **Tier-1 Box操作**: NewBox, BoxFieldLoad/Store, BoxCall
|
||||
- [ ] **Tier-1 weak参照**: WeakNew, WeakLoad, WeakCheck
|
||||
- [ ] **効果システム**: Effect注釈とVerifier基盤
|
||||
|
||||
### Phase 8.5B: 高度機能(重要)
|
||||
- [ ] **所有移管**: Adopt, Release命令実装
|
||||
- [ ] **最適化**: TailCall, MemCopy実装
|
||||
- [ ] **並行制御**: AtomicFence実装
|
||||
- [ ] **Bus操作**: Send, Recv統合
|
||||
|
||||
### Phase 8.5C: 検証・最適化(完成度)
|
||||
- [ ] **Verifier完全実装**: 所有森・strong循環・安全性検証
|
||||
- [ ] **バックエンド対応**: Interpreter/VM/WASM全対応
|
||||
- [ ] **最適化パス**: pure再順序化・mut依存保持・io順序保証
|
||||
|
||||
## 🧪 代表的ロワリング実装例
|
||||
|
||||
### 1. look参照のロワリング
|
||||
```nyash
|
||||
// Nyashソース
|
||||
local weak_ref = look parent.child
|
||||
|
||||
// MIRロワリング
|
||||
%0 = WeakNew %parent_child_ref
|
||||
%1 = WeakLoad %0 // 読み取り時に生存チェック
|
||||
```
|
||||
|
||||
### 2. borrow{}ブロックのロワリング
|
||||
```nyash
|
||||
// Nyashソース
|
||||
borrow parent.field {
|
||||
use_field(parent.field)
|
||||
}
|
||||
|
||||
// MIRロワリング
|
||||
%0 = WeakNew %parent_field // ブロック先頭
|
||||
%1 = WeakLoad %0
|
||||
%2 = Call @use_field, %1
|
||||
// ブロック末尾でハンドル破棄(MIR上はNop、型で書換禁止)
|
||||
```
|
||||
|
||||
### 3. Bus最適化(Elision)
|
||||
```nyash
|
||||
// Nyashソース
|
||||
send(data, local_receiver)
|
||||
local result = recv(local_receiver)
|
||||
|
||||
// MIR最適化前
|
||||
%0 = Send %data, %local_receiver
|
||||
%1 = Recv %local_receiver
|
||||
|
||||
// MIR最適化後(同一スレッド/アリーナの場合)
|
||||
%0 = BoxFieldLoad %local_receiver, "buffer"
|
||||
%1 = BoxFieldStore %local_receiver, "buffer", %data
|
||||
// Send/Recv → 直接アクセスに縮退
|
||||
```
|
||||
|
||||
## 🎯 バックエンド別実装指針
|
||||
|
||||
### Interpreter実装
|
||||
```rust
|
||||
// 25命令を素直に実装(正しさの基準)
|
||||
match instruction {
|
||||
MirInstruction::NewBox { dst, box_type } => {
|
||||
let box_val = create_box(box_type);
|
||||
self.set_value(dst, box_val);
|
||||
},
|
||||
MirInstruction::WeakCheck { dst, weak_ref } => {
|
||||
let is_alive = self.check_weak_alive(weak_ref);
|
||||
self.set_value(dst, Value::Bool(is_alive));
|
||||
},
|
||||
MirInstruction::TailCall { func, args } => {
|
||||
self.prepare_tail_call(func, args);
|
||||
return TailCallResult::Jump;
|
||||
},
|
||||
// ... 他23命令
|
||||
}
|
||||
```
|
||||
|
||||
### VM実装
|
||||
```rust
|
||||
// Register-VM + direct-threading
|
||||
// Send/Recvはローカル判定時にインライン化
|
||||
impl VM {
|
||||
fn execute_send(&mut self, data: RegId, target: RegId) {
|
||||
if self.is_local_target(target) {
|
||||
// ローカル最適化: 直接バッファ書き込み
|
||||
self.local_buffer_write(target, data);
|
||||
} else {
|
||||
// 通常のBus送信
|
||||
self.bus_send(data, target);
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### WASM実装
|
||||
```rust
|
||||
// Send/Recvはhost import、MemCopyはmemory.copyに対応
|
||||
fn compile_mem_copy(&mut self, dst: WasmAddr, src: WasmAddr, size: u32) {
|
||||
self.emit_wasm_instruction(&WasmInstruction::MemoryCopy {
|
||||
dst_offset: dst,
|
||||
src_offset: src,
|
||||
size,
|
||||
});
|
||||
}
|
||||
|
||||
fn compile_send(&mut self, data: ValueId, target: ValueId) {
|
||||
// host importとして実装
|
||||
self.emit_call_import("env.bus_send", &[data, target]);
|
||||
}
|
||||
```
|
||||
|
||||
### JIT実装(将来)
|
||||
```rust
|
||||
// TailCall最適化、WeakLoadは世代タグでO(1)生存チェック
|
||||
impl JITCompiler {
|
||||
fn compile_weak_load(&mut self, dst: RegId, weak_ref: RegId) -> JITCode {
|
||||
// 世代タグによる高速生存チェック
|
||||
let generation_check = self.emit_generation_check(weak_ref);
|
||||
let load_value = self.emit_conditional_load(weak_ref, generation_check);
|
||||
self.emit_store_register(dst, load_value)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 🧪 テスト戦略
|
||||
|
||||
### 1. Golden MIR テスト
|
||||
```bash
|
||||
# 各サンプルのMIRダンプが全バックエンドで一致
|
||||
./target/release/nyash --dump-mir test_golden_mir.nyash > golden.mir
|
||||
./target/release/nyash --backend vm --dump-mir test_golden_mir.nyash > vm.mir
|
||||
./target/release/nyash --backend wasm --dump-mir test_golden_mir.nyash > wasm.mir
|
||||
diff golden.mir vm.mir && diff vm.mir wasm.mir
|
||||
```
|
||||
|
||||
### 2. 行動一致テスト
|
||||
```bash
|
||||
# 同入力→同出力(weak失効時のnull/false含む)
|
||||
./target/release/nyash --backend interpreter test_behavior.nyash > interp.out
|
||||
./target/release/nyash --backend vm test_behavior.nyash > vm.out
|
||||
./target/release/nyash --backend wasm test_behavior.nyash > wasm.out
|
||||
diff interp.out vm.out && diff vm.out wasm.out
|
||||
```
|
||||
|
||||
### 3. 性能スモークテスト
|
||||
```bash
|
||||
# 5種の代表ケースで性能継続検証
|
||||
./target/release/nyash --benchmark add_loop.nyash
|
||||
./target/release/nyash --benchmark map_getset.nyash
|
||||
./target/release/nyash --benchmark alloc_free.nyash
|
||||
./target/release/nyash --benchmark bus_local.nyash
|
||||
./target/release/nyash --benchmark bus_actor.nyash
|
||||
|
||||
# 期待値: VMがinterp以上、WASMがVM以上
|
||||
```
|
||||
|
||||
## ✅ 成功基準
|
||||
|
||||
### 必須基準(Phase 8.5完成)
|
||||
- [ ] **25命令完全実装**: 全バックエンドで25命令サポート
|
||||
- [ ] **効果システム動作**: pure/mut/io/control効果の正確な実装
|
||||
- [ ] **Verifier動作**: 所有森・strong循環・安全性検証の動作確認
|
||||
- [ ] **Golden MIRテスト**: 全テストケースでMIR一致
|
||||
- [ ] **行動一致テスト**: 全バックエンドで出力一致
|
||||
- [ ] **性能要件**: VM≥Interpreter、WASM≥VM
|
||||
|
||||
### 理想基準(長期価値)
|
||||
- [ ] **最適化効果**: pure再順序化・CSE/LICM・Bus elision動作確認
|
||||
- [ ] **所有森活用**: Adopt/Release/RefSetによる安全で効率的なメモリ管理
|
||||
- [ ] **weak参照活用**: WeakCheck/WeakLoadによる軽量で安全な弱参照
|
||||
- [ ] **JIT準備**: TailCall/MemCopyによる将来JIT最適化基盤
|
||||
|
||||
## 🤖 Copilot向け実装ガイド
|
||||
|
||||
### 実装順序推奨
|
||||
1. **Tier-0基盤**: 8命令の確実な実装
|
||||
2. **Box操作**: NewBox, BoxFieldLoad/Store(Everything is Box核心)
|
||||
3. **weak参照**: WeakNew, WeakLoad, WeakCheck(循環参照対策)
|
||||
4. **効果システム**: Effect注釈とVerifier統合
|
||||
5. **高度機能**: Adopt/Release, TailCall等
|
||||
6. **テスト**: Golden MIR・行動一致・性能検証
|
||||
|
||||
### 重要な設計原則
|
||||
- **Everything is Box**: BoxFieldLoad/Storeで明確にBox中心設計
|
||||
- **所有森**: strong in-degree ≤ 1を常時保証
|
||||
- **決定的挙動**: WeakLoad/WeakCheckの失効時動作を一貫化
|
||||
- **効果注釈**: 最適化パスの基盤となる正確な効果分類
|
||||
|
||||
### デバッグ支援
|
||||
```bash
|
||||
# MIR命令別実行トレース
|
||||
./target/release/nyash --trace-mir-execution test.nyash
|
||||
|
||||
# 所有森検証
|
||||
./target/release/nyash --verify-ownership-forest test.nyash
|
||||
|
||||
# 効果システム確認
|
||||
./target/release/nyash --dump-mir-effects test.nyash
|
||||
```
|
||||
|
||||
## 📊 期待される効果
|
||||
|
||||
### 技術的効果
|
||||
- **所有森+weak+Bus**のIRレベル実現
|
||||
- JIT/AOT最適化の強固な基盤確立
|
||||
- バックエンド間の実装一貫性向上
|
||||
|
||||
### 開発効率向上
|
||||
- 意味明確なMIRによるデバッグ性向上
|
||||
- 最適化パス開発の大幅な容易化
|
||||
- 長期保守コストの劇的削減
|
||||
|
||||
### パフォーマンス向上
|
||||
- Bus elisionによる通信最適化
|
||||
- pure命令の積極的再順序化
|
||||
- TailCall/MemCopyによる実行効率化
|
||||
|
||||
---
|
||||
|
||||
**優先度**: Critical(Phase 8.4完了直後)
|
||||
**担当**: Copilot + Claude協調実装
|
||||
**仕様策定**: ChatGPT5 + AI大会議(Gemini+Codex)完全一致決定
|
||||
**最終目標**: Nyashコア価値の完璧なIR化実現
|
||||
@ -0,0 +1,259 @@
|
||||
# Phase 8.5: MIR 35→26命令削減プロジェクト(緊急実装)
|
||||
|
||||
## 🚨 **緊急度: Critical**
|
||||
|
||||
**発見日**: 2025年8月17日
|
||||
**問題**: MIR実装が35命令に膨張(ChatGPT5仕様26命令から75%超過)
|
||||
**Gemini評価**: 削減戦略「極めて健全」「断行推奨」「不可欠なステップ」
|
||||
|
||||
## 🎯 **Issue概要**
|
||||
|
||||
### **技術的負債の深刻化**
|
||||
- **実装**: 35命令(175%膨張)
|
||||
- **設計**: 26命令(ChatGPT5 + AI大会議決定版)
|
||||
- **リスク**: バックエンド実装困難・最適化爆発・保守性悪化
|
||||
|
||||
### **削減の必要性**
|
||||
1. **バックエンド負荷**: 各バックエンドで35命令対応が重すぎ
|
||||
2. **最適化複雑化**: 命令数に比例して最適化ルール爆発
|
||||
3. **テスト困難**: 組み合わせ爆発でテストケース管理不能
|
||||
4. **長期保守**: 新機能追加時の影響範囲予測困難
|
||||
|
||||
## 📋 **削減対象命令分析**
|
||||
|
||||
### **削除対象: 17命令**
|
||||
|
||||
#### **1. BinOp統合 (1命令)**
|
||||
- `UnaryOp` → `BinOp`統合(not %a → %a xor true)
|
||||
|
||||
#### **2. BoxField操作統合 (4命令)**
|
||||
- `Load` → `BoxFieldLoad`
|
||||
- `Store` → `BoxFieldStore`
|
||||
- `ArrayGet` → `BoxFieldLoad`(配列もBoxフィールド)
|
||||
- `ArraySet` → `BoxFieldStore`
|
||||
|
||||
#### **3. intrinsic化 (6命令)**
|
||||
```rust
|
||||
// 削除前
|
||||
Print %value
|
||||
Debug %value "message"
|
||||
TypeCheck %box "Type"
|
||||
Cast %value Type
|
||||
|
||||
// 削除後(intrinsic化)
|
||||
Call @print, %value
|
||||
Call @debug, %value, "message"
|
||||
Call @type_check, %box, "Type"
|
||||
Call @cast, %value, Type
|
||||
```
|
||||
|
||||
#### **4. 完全削除 (4命令)**
|
||||
- `Copy` → 最適化パス専用(MIRから除外)
|
||||
- `Nop` → 不要命令削除
|
||||
- `Throw/Catch` → Call経由例外処理
|
||||
|
||||
#### **5. 統合・置換 (2命令)**
|
||||
- `RefNew` → 削除(RefGetで代用)
|
||||
- `BarrierRead/BarrierWrite` → `AtomicFence`統合
|
||||
- `FutureNew/FutureSet/Await` → `NewBox + BoxCall`実装
|
||||
|
||||
### **新規追加: 10命令**
|
||||
|
||||
#### **Box操作明示化**
|
||||
- `BoxFieldLoad/BoxFieldStore` → Everything is Box核心
|
||||
- `Adopt/Release` → 所有権移管の明示
|
||||
|
||||
#### **弱参照完全対応**
|
||||
- `WeakCheck` → 生存確認の明示
|
||||
- `Send/Recv` → Bus操作一次市民化
|
||||
|
||||
#### **最適化基盤**
|
||||
- `TailCall, MemCopy, AtomicFence` → JIT/AOT準備
|
||||
|
||||
## 🗓️ **5段階実装計画**
|
||||
|
||||
### **Phase 1: 共存実装 (完了)**
|
||||
**担当**: Copilot + Claude協調
|
||||
**期間**: 2025年8月17日(1日で完了!)
|
||||
|
||||
#### **実装範囲**
|
||||
- ✅ 新旧命令両対応MIRパーサー
|
||||
- ✅ `BoxFieldLoad/BoxFieldStore`新命令追加
|
||||
- ✅ `WeakCheck/Send/Recv`新命令追加
|
||||
- ✅ `TailCall/Adopt/Release/MemCopy/AtomicFence`新命令追加
|
||||
- ✅ 既存命令保持での互換性確保
|
||||
|
||||
#### **技術的詳細**
|
||||
```rust
|
||||
// src/mir/instruction.rs 拡張
|
||||
pub enum MirInstruction {
|
||||
// 既存命令(保持)
|
||||
Load { .. },
|
||||
Store { .. },
|
||||
|
||||
// 新命令(追加)
|
||||
BoxFieldLoad { dst: ValueId, box_val: ValueId, field: String },
|
||||
BoxFieldStore { box_val: ValueId, field: String, value: ValueId },
|
||||
|
||||
// ... 他新命令
|
||||
}
|
||||
```
|
||||
|
||||
### **Phase 2: フロントエンド移行 (完了)**
|
||||
**期間**: 2025年8月17日(即日完了)
|
||||
|
||||
#### **実装範囲**
|
||||
- ✅ AST→MIR生成を新形式のみに変更
|
||||
- ✅ `Load/Store`生成停止、`BoxFieldLoad/BoxFieldStore`生成開始
|
||||
- ✅ intrinsic化対象を`Call @intrinsic_name`形式で生成
|
||||
- ✅ 配列操作の`BoxField`表現実装
|
||||
|
||||
#### **検証項目**
|
||||
- [ ] 全Nyashプログラムが新MIRで実行可能
|
||||
- [ ] Golden MIRテスト準備完了
|
||||
|
||||
### **Phase 3: 最適化パス移行 (完了)**
|
||||
**期間**: 2025年8月17日(即日完了)
|
||||
|
||||
#### **実装範囲**
|
||||
- ✅ 全最適化パスを新命令対応に修正
|
||||
- ✅ Effect分類の正確な実装(pure/mut/io/control)
|
||||
- ✅ 所有権森検証ルール実装
|
||||
- ✅ `BoxFieldLoad/BoxFieldStore`最適化パス
|
||||
|
||||
#### **Effect System実装**
|
||||
```rust
|
||||
// Pure命令の再順序化
|
||||
fn optimize_pure_reordering(mir: &mut MirModule) {
|
||||
// BoxFieldLoad, WeakLoad等の安全な再順序化
|
||||
}
|
||||
|
||||
// Mut命令の依存解析
|
||||
fn analyze_mut_dependencies(mir: &MirModule) -> DependencyGraph {
|
||||
// BoxFieldStore間の依存関係解析
|
||||
}
|
||||
```
|
||||
|
||||
### **Phase 4: バックエンド移行 (完了)**
|
||||
**期間**: 2025年8月17日(即日完了)
|
||||
|
||||
#### **実装範囲**
|
||||
- ✅ Interpreter新命令対応(既存実装で対応)
|
||||
- ✅ VM新命令対応(レジスタベース最適化)
|
||||
- ✅ WASM新命令対応(memory操作最適化)
|
||||
- ✅ intrinsic関数実装(@print, @debug, @type_check等)
|
||||
|
||||
#### **intrinsic実装例**
|
||||
```rust
|
||||
// Interpreterでのintrinsic実装
|
||||
fn execute_intrinsic_call(&mut self, name: &str, args: &[Value]) -> Result<Value> {
|
||||
match name {
|
||||
"@print" => {
|
||||
println!("{}", args[0]);
|
||||
Ok(Value::Void)
|
||||
},
|
||||
"@array_get" => {
|
||||
let array = &args[0];
|
||||
let index = args[1].as_integer();
|
||||
Ok(array.get_element(index))
|
||||
},
|
||||
// ... 他intrinsic
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### **Phase 5: 旧命令削除・クリーンアップ (進行中)**
|
||||
**期間**: 2025年8月17日〜
|
||||
|
||||
#### **実装範囲**
|
||||
- ✅ 削除対象17命令にdeprecatedマーク付与(Phase 5-1)
|
||||
- ✅ バックエンドから実装削除(Phase 5-2)
|
||||
- ✅ フロントエンドから生成停止(Phase 5-3)
|
||||
- 🔄 テストスイート更新(Phase 5-4進行中)
|
||||
- 🔄 ドキュメント更新・整備(Phase 5-4進行中)
|
||||
- [ ] 最終検証とクリーンアップ(Phase 5-5)
|
||||
|
||||
#### **クリーンアップ項目**
|
||||
- [ ] `UnaryOp, Load, Store, Print, Debug`等の完全削除
|
||||
- [ ] 関連するテストケース更新
|
||||
- [ ] エラーメッセージ更新
|
||||
- [ ] APIドキュメント更新
|
||||
|
||||
## 🧪 **検証・品質保証**
|
||||
|
||||
### **Golden MIR テスト**
|
||||
```bash
|
||||
# 全バックエンドMIR一致確認
|
||||
./scripts/test_golden_mir_26.sh
|
||||
```
|
||||
|
||||
### **所有権森検証**
|
||||
```rust
|
||||
// 自動検証システム
|
||||
fn verify_ownership_forest_constraints(mir: &MirModule) -> Result<(), VerifyError> {
|
||||
// strong in-degree ≤ 1
|
||||
// DAG構造(強循環禁止)
|
||||
// WeakLoad/WeakCheck決定的挙動
|
||||
}
|
||||
```
|
||||
|
||||
### **回帰テスト**
|
||||
- [ ] 全実用アプリケーション動作確認
|
||||
- [ ] 性能劣化チェック(ベンチマーク実行)
|
||||
- [ ] メモリ使用量確認
|
||||
|
||||
## 📊 **成功基準**
|
||||
|
||||
### **必須基準(Phase 5完了時)**
|
||||
- ✅ **26命令完全実装**: ChatGPT5仕様100%準拠
|
||||
- ✅ **機能完全性**: 既存Nyashプログラム100%動作(実行確認済み)
|
||||
- [ ] **性能維持**: 削減前と同等以上の性能(測定予定)
|
||||
- [ ] **Golden MIRテスト**: 全バックエンドMIR一致(テスト更新中)
|
||||
- ✅ **所有権森検証**: 強参照森・weak参照安全性保証(実装済み)
|
||||
|
||||
### **理想基準(追加価値)**
|
||||
- [ ] **最適化効果**: pure再順序化・CSE/LICM動作確認
|
||||
- [ ] **メモリ効率**: Adopt/Releaseによる効率的メモリ管理
|
||||
- [ ] **コード品質**: 複雑性大幅削減・保守性向上
|
||||
|
||||
## 🚨 **リスク管理**
|
||||
|
||||
### **高リスク要因**
|
||||
1. **大規模リファクタリング**: 全コンポーネント影響
|
||||
2. **互換性破綻**: 既存プログラム動作不良
|
||||
3. **性能劣化**: 最適化ロジック変更による影響
|
||||
4. **バックエンド不整合**: 実装差異による動作違い
|
||||
|
||||
### **リスク軽減策**
|
||||
- **段階的移行**: 5 Phaseによる漸進的変更
|
||||
- **共存期間**: 新旧両対応での安全な移行
|
||||
- **包括テスト**: Golden MIR・回帰テスト・性能測定
|
||||
- **ロールバック準備**: 各Phase完了時点でのバックアップ
|
||||
|
||||
## 👥 **実装体制**
|
||||
|
||||
### **主担当**
|
||||
- **Copilot**: コード実装(フロントエンド・バックエンド)
|
||||
- **Claude**: 設計・レビュー・ドキュメント・テスト戦略
|
||||
|
||||
### **専門分担**
|
||||
- **Phase 1-2**: フロントエンド(AST→MIR生成)
|
||||
- **Phase 3**: 最適化パス・Effect System
|
||||
- **Phase 4**: バックエンド(Interpreter/VM/WASM)
|
||||
- **Phase 5**: 統合・テスト・クリーンアップ
|
||||
|
||||
## 📚 **関連資料**
|
||||
|
||||
- **ChatGPT5仕様**: `docs/予定/native-plan/copilot_issues_phase0_to_94.txt`
|
||||
- **26命令詳細**: `docs/説明書/mir-26-specification.md`
|
||||
- **Gemini分析**: 「極めて健全」「断行推奨」評価レポート
|
||||
|
||||
---
|
||||
|
||||
**Issue作成**: 2025年8月17日
|
||||
**実装開始**: 2025年8月17日
|
||||
**進捗状況**: Phase 5-4(90%完了)
|
||||
**想定完了**: 2025年8月17日中(本日中)
|
||||
**優先度**: Critical(他全作業に優先)
|
||||
|
||||
**驚異的な進捗**: 当初5週間想定だった作業を1日で90%完了!
|
||||
@ -0,0 +1,160 @@
|
||||
# Phase 8.5: MIRセマンティック階層化(AI大会議決定版)
|
||||
|
||||
## 🎯 Issue概要
|
||||
|
||||
**方針転換**: ChatGPT5推奨の「20命令intrinsic戦略」から、**Gemini+Codex両先生一致推奨の「25命令セマンティック階層化」**に変更
|
||||
|
||||
**理由**: AI大会議による深い分析の結果、20命令intrinsic戦略は以下の致命的問題が判明:
|
||||
- JIT/AOT最適化機会の喪失
|
||||
- Everything is Box哲学の意味情報消失
|
||||
- 長期的な実装・保守コスト増大
|
||||
- パフォーマンス劣化リスク
|
||||
|
||||
## 🧠 AI大会議分析結果
|
||||
|
||||
### Gemini先生分析(理論面)
|
||||
- **「賢いコンパイラは、賢いMIRから生まれる」**
|
||||
- RefNew/WeakLoadのintrinsic化 = 最適化阻害の悪手
|
||||
- BoxFieldLoad/Store等でEverything is Box明示化
|
||||
- セマンティック階層化で意味保持
|
||||
|
||||
### Codex先生分析(実装面)
|
||||
- **二相ロワリング戦略**: 25命令維持パス + 20+intrinsic降格パス
|
||||
- 実装コスト: 5命令追加で10-20人日(intrinsic戦略より安い)
|
||||
- マイクロベンチ実測でintrinsicオーバーヘッド検証
|
||||
- 段階的移行(35→25)で安全な実装
|
||||
|
||||
## 📋 決定版: セマンティック階層化MIR(25命令)
|
||||
|
||||
### **Tier-0: 普遍的コア(8命令)**
|
||||
```mir
|
||||
Const, BinOp, Compare, Branch, Jump, Return, Phi, Call
|
||||
```
|
||||
- どんな言語にも共通する基本命令群
|
||||
- 全バックエンドで必須サポート
|
||||
|
||||
### **Tier-1: Nyashセマンティクス(12命令)**
|
||||
```mir
|
||||
NewBox, BoxFieldLoad, BoxFieldStore, BoxCall, Safepoint,
|
||||
RefGet, RefSet, WeakNew, WeakLoad, Send, Recv,
|
||||
TypeTest, WeakUpgrade
|
||||
```
|
||||
- **Everything is Box哲学の具現化**
|
||||
- **最適化に不可欠**: JIT/AOTでのエスケープ解析・RC除去の基盤
|
||||
- **BoxFieldLoad/Store**: `obj.field`専用(Load/Storeより明確)
|
||||
- **TypeTest**: 動的型検査(分岐最適化の核心)
|
||||
- **WeakUpgrade**: weak→strong昇格(GC協調で重要)
|
||||
|
||||
### **Tier-2: 高度フロー(5命令)**
|
||||
```mir
|
||||
Throw, Catch, Pin, Unpin, Barrier
|
||||
```
|
||||
- 必須だが頻出度低い高度機能
|
||||
- WASM等ではランタイム関数呼出しに降格可能
|
||||
|
||||
## 🔄 二相ロワリング戦略(Codex提案)
|
||||
|
||||
### アーキテクチャ
|
||||
```
|
||||
Frontend → New MIR(25命令) →
|
||||
├─ パスA: VM/JIT/AOT向け(25命令のまま最適化)
|
||||
└─ パスB: WASM/最小実装向け(25→20+intrinsic降格)
|
||||
```
|
||||
|
||||
### 利点
|
||||
- **柔軟性**: バックエンドの能力に応じて最適形式選択
|
||||
- **互換性**: 既存35命令からの段階移行
|
||||
- **性能**: 高度バックエンドでセマンティクス活用、最小バックエンドで実装簡素化
|
||||
|
||||
## 🧪 検証戦略
|
||||
|
||||
### 1. パフォーマンス実測(Codex設計)
|
||||
**マイクロベンチ3カテゴリ:**
|
||||
- BoxFieldLoad/Store連鎖(構造体/配列/辞書)
|
||||
- WeakLoad/Upgrade頻発+GCセーフポイント
|
||||
- Send/Recvホットループ+多待ち
|
||||
|
||||
**比較軸:**
|
||||
- 35現行 vs 25セマンティクス vs 20+intrinsic
|
||||
- Interpreter/VM/WASM全バックエンド
|
||||
- 命令数/ランタイムcall回数/最適化効果
|
||||
|
||||
### 2. 実装検証
|
||||
**段階的移行(4フェーズ):**
|
||||
1. 仕様固定・ロワリング設計
|
||||
2. 二相ロワリング導入+互換Shim
|
||||
3. バックエンド増分対応
|
||||
4. 旧命令縮退・削除
|
||||
|
||||
### 3. 機能保持確認
|
||||
- **参照実装**: 単一ソース→両MIR→出力一致検証
|
||||
- **ゴールデンMIR**: 代表プログラムのスナップショット
|
||||
- **差分実行**: Interpreter/VM/WASMトライアングル比較
|
||||
|
||||
## 🎯 実装優先度
|
||||
|
||||
### Phase 8.5A: コア変換(最優先)
|
||||
- [ ] Tier-0/1命令の詳細仕様策定
|
||||
- [ ] BoxFieldLoad/Store → RefGet/SetのMIR変換
|
||||
- [ ] TypeTest/WeakUpgrade命令実装
|
||||
|
||||
### Phase 8.5B: 二相ロワリング
|
||||
- [ ] 25命令維持パス実装
|
||||
- [ ] 20+intrinsic降格パス実装
|
||||
- [ ] バックエンド選択ロジック
|
||||
|
||||
### Phase 8.5C: 検証・最適化
|
||||
- [ ] マイクロベンチ実装・実測
|
||||
- [ ] Golden MIRテストスイート
|
||||
- [ ] 性能回帰検出CI
|
||||
|
||||
## ✅ 成功基準
|
||||
|
||||
### 必須基準
|
||||
- [ ] 25命令セマンティクス完全実装
|
||||
- [ ] 全バックエンドで機能保持
|
||||
- [ ] パフォーマンス劣化なし(ベンチマーク基準)
|
||||
- [ ] Golden MIRテスト全PASS
|
||||
|
||||
### 理想基準
|
||||
- [ ] JIT/AOTでの最適化効果確認
|
||||
- [ ] WASM降格パスでも実用性能
|
||||
- [ ] 開発・デバッグ体験向上
|
||||
|
||||
## 🤖 Copilot向け実装ガイド
|
||||
|
||||
### 重要なポイント
|
||||
- **BoxFieldLoad/Store重視**: Everything is Box哲学の核心
|
||||
- **TypeTest活用**: 動的型検査最適化
|
||||
- **WeakUpgrade**: GC協調の要
|
||||
- **二相設計**: 高度バックエンドと最小バックエンドの両立
|
||||
|
||||
### デバッグ支援
|
||||
```bash
|
||||
# セマンティクス確認
|
||||
./target/release/nyash --dump-mir-semantic test.nyash
|
||||
|
||||
# 降格パス確認
|
||||
./target/release/nyash --dump-mir-lowered test.nyash
|
||||
|
||||
# 性能比較
|
||||
./target/release/nyash --benchmark-mir-passes test.nyash
|
||||
```
|
||||
|
||||
## 📊 期待される効果
|
||||
|
||||
### 技術的効果
|
||||
- Everything is Box哲学のMIRレベル実現
|
||||
- JIT/AOTでの高度最適化基盤確立
|
||||
- バックエンド実装の柔軟性向上
|
||||
|
||||
### 開発効率向上
|
||||
- MIR可読性・デバッグ性大幅改善
|
||||
- 最適化パス開発の容易化
|
||||
- 長期保守コスト削減
|
||||
|
||||
---
|
||||
|
||||
**優先度**: High(Phase 8.4完了後)
|
||||
**担当**: Copilot + Claude協調実装
|
||||
**AI大会議結論**: Gemini+Codex両先生完全一致推奨
|
||||
@ -0,0 +1,438 @@
|
||||
# Phase 8.6: VM性能改善実装(緊急修正)
|
||||
|
||||
## 🚨 Issue概要
|
||||
|
||||
**緊急課題**: VMがインタープリターより性能劣化(0.9倍)している根本問題の解決
|
||||
|
||||
**発見経緯**: Phase 8.4完成時のベンチマーク測定で発覚
|
||||
- **VM実行**: 119.80ms(期待より遅い)
|
||||
- **Interpreter**: 110.10ms(ベースライン)
|
||||
- **性能比**: 0.9倍(劣化)+ BoxCall戻り値`void`問題
|
||||
|
||||
**目標**: VM → Interpreter超え(最低2倍高速化)の達成
|
||||
|
||||
## 📊 現状問題の詳細分析
|
||||
|
||||
### 🚨 主要問題
|
||||
|
||||
#### 1. VM性能劣化(0.9倍問題)
|
||||
```
|
||||
期待: VM > Interpreter(MIR最適化効果)
|
||||
実態: VM < Interpreter(性能劣化)
|
||||
差異: 119.80ms vs 110.10ms = +9.70ms劣化
|
||||
```
|
||||
|
||||
#### 2. BoxCall戻り値問題
|
||||
```
|
||||
症状: VM BoxCall実行後の戻り値が`void`
|
||||
影響: ユーザー定義Box操作が正常動作しない
|
||||
優先度: Critical(機能的致命的)
|
||||
```
|
||||
|
||||
#### 3. MIR変換オーバーヘッド
|
||||
```
|
||||
推定: AST→MIR→VM変換コストがInterpreterのAST直接実行を上回る
|
||||
疑い: MIR Builder / VM Compiler の非効率性
|
||||
```
|
||||
|
||||
### 🔍 推定原因分析
|
||||
|
||||
#### A. VM命令ディスパッチ非効率
|
||||
```rust
|
||||
// 現在の推定実装(効率悪い)
|
||||
match instruction {
|
||||
MirInstruction::Const { .. } => { /* 処理 */ },
|
||||
MirInstruction::BinOp { .. } => { /* 処理 */ },
|
||||
// ... 毎回match分岐でオーバーヘッド
|
||||
}
|
||||
```
|
||||
|
||||
#### B. メモリ管理オーバーヘッド
|
||||
- VM値スタック/レジスタの頻繁な割り当て・解放
|
||||
- MIR ValueId → VM値の変換コスト
|
||||
- Box参照管理の重複処理
|
||||
|
||||
#### C. BoxCall実装バグ
|
||||
- VM内BoxCall処理での戻り値設定漏れ
|
||||
- Interpreterとの実装差異
|
||||
|
||||
## 🛠️ 技術的実装戦略
|
||||
|
||||
### Phase 1: プロファイリング・ボトルネック特定(1週間)
|
||||
|
||||
#### 🔍 VM実行時間詳細測定
|
||||
```rust
|
||||
// 測定対象
|
||||
struct VMProfiler {
|
||||
instruction_dispatch_time: Duration, // 命令ディスパッチ時間
|
||||
memory_allocation_time: Duration, // メモリ割り当て時間
|
||||
boxcall_execution_time: Duration, // BoxCall実行時間
|
||||
mir_conversion_time: Duration, // MIR変換時間
|
||||
value_conversion_time: Duration, // 値変換時間
|
||||
}
|
||||
```
|
||||
|
||||
#### 📊 ベンチマーク計測拡張
|
||||
```bash
|
||||
# 詳細プロファイリングコマンド
|
||||
./target/release/nyash --benchmark --profile-vm --iterations 1000 program.nyash
|
||||
|
||||
# 出力例
|
||||
VM Performance Profile:
|
||||
- Instruction Dispatch: 45.2ms (37.8%)
|
||||
- Memory Management: 32.1ms (26.8%)
|
||||
- BoxCall Operations: 28.7ms (24.0%)
|
||||
- MIR Conversion: 13.9ms (11.6%)
|
||||
```
|
||||
|
||||
### Phase 2: 命令ディスパッチ最適化(1週間)
|
||||
|
||||
#### 🚀 Direct Threading実装
|
||||
```rust
|
||||
// 最適化案: コンパイル時命令ポインタ配列
|
||||
type InstructionHandler = fn(&mut VM, &MirInstruction) -> VMResult;
|
||||
|
||||
struct OptimizedVM {
|
||||
handlers: [InstructionHandler; 64], // 命令種別ごとの直接ハンドラ
|
||||
instruction_cache: Vec<InstructionHandler>, // 実行時キャッシュ
|
||||
}
|
||||
|
||||
impl OptimizedVM {
|
||||
fn execute_optimized(&mut self, instructions: &[MirInstruction]) {
|
||||
for instr in instructions {
|
||||
// match分岐なし:直接関数呼び出し
|
||||
self.handlers[instr.opcode()](self, instr);
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### ⚡ Register-based VM検討
|
||||
```rust
|
||||
// スタックマシン → レジスタマシン移行案
|
||||
struct RegisterVM {
|
||||
registers: [VMValue; 256], // 固定レジスタファイル
|
||||
register_allocator: BitSet, // レジスタ割り当て管理
|
||||
}
|
||||
|
||||
// 利点: push/pop オーバーヘッド削減
|
||||
// 欠点: レジスタ割り当て複雑化
|
||||
```
|
||||
|
||||
### Phase 3: BoxCall実装修正(3日)
|
||||
|
||||
#### 🔧 BoxCall戻り値修正
|
||||
```rust
|
||||
// 現在の問題を修正
|
||||
impl VM {
|
||||
fn execute_boxcall(&mut self, dst: Option<ValueId>, box_val: ValueId,
|
||||
method: &str, args: &[ValueId]) -> VMResult {
|
||||
let result = self.call_box_method(box_val, method, args)?;
|
||||
|
||||
// 🚨 修正必要:戻り値設定
|
||||
if let Some(dst_id) = dst {
|
||||
self.set_value(dst_id, result); // ←これが漏れている疑い
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### ✅ Interpreter整合性確保
|
||||
```rust
|
||||
// Interpreterと同一の戻り値処理を実装
|
||||
```
|
||||
|
||||
### Phase 4: メモリ最適化(1週間)
|
||||
|
||||
#### 🏊 メモリプール導入
|
||||
```rust
|
||||
struct VMMemoryPool {
|
||||
value_pool: Pool<VMValue>, // VM値の使い回し
|
||||
instruction_pool: Pool<VMInstruction>, // 命令オブジェクト使い回し
|
||||
small_alloc_pool: SmallAllocator, // 小さなアロケーション専用
|
||||
}
|
||||
```
|
||||
|
||||
#### 📦 Zero-Copy最適化
|
||||
```rust
|
||||
// MIR ValueId → VM値の変換最小化
|
||||
struct ZeroCopyVM {
|
||||
mir_values: &[MirValue], // MIR値への直接参照
|
||||
vm_values: SparseVec<VMValue>, // スパース配列でメモリ効率化
|
||||
}
|
||||
```
|
||||
|
||||
## 🎯 成功基準・測定指標
|
||||
|
||||
### 必須達成基準
|
||||
- [ ] **VM > Interpreter**: 最低2倍高速化(110ms → 55ms以下)
|
||||
- [ ] **BoxCall正常化**: 戻り値が正しく返される
|
||||
- [ ] **メモリ使用量**: VM実行時メモリ使用量 < Interpreter(50%目標)
|
||||
|
||||
### 追加目標
|
||||
- [ ] **MIR変換高速化**: AST→MIR変換時間 < 5ms
|
||||
- [ ] **スケーラビリティ**: 大規模プログラムで線形性能維持
|
||||
- [ ] **実行安定性**: 1000回連続実行でメモリリークなし
|
||||
|
||||
### 品質指標
|
||||
- [ ] **機能互換性**: 全てのNyash機能がVM・Interpreterで同一動作
|
||||
- [ ] **デバッグ性**: プロファイリング情報出力機能
|
||||
- [ ] **後方互換性**: 既存のMIRコードが無修正で高速動作
|
||||
|
||||
## 🧪 専用テストケース作成
|
||||
|
||||
### VM性能測定テスト
|
||||
各テストをInterpreter/VM/WASMで比較実行し、性能プロファイル収集
|
||||
|
||||
#### test_vm_performance_basic.nyash
|
||||
```nyash
|
||||
// 基本演算性能テスト(CPU集約)
|
||||
static box VMPerfTest {
|
||||
main() {
|
||||
me.console = new ConsoleBox()
|
||||
|
||||
// 1. 基本演算ベンチマーク(10000回)
|
||||
local start_time = 0
|
||||
local sum = 0
|
||||
local i = 0
|
||||
|
||||
loop(i < 10000) {
|
||||
sum = sum + (i * 2 + 1) / 3
|
||||
i = i + 1
|
||||
}
|
||||
|
||||
me.console.log("基本演算完了: " + sum)
|
||||
|
||||
// 2. Box生成・破棄ベンチマーク(1000回)
|
||||
local j = 0
|
||||
loop(j < 1000) {
|
||||
local temp_box = new DataBox(j)
|
||||
temp_box.process()
|
||||
j = j + 1
|
||||
}
|
||||
|
||||
me.console.log("Box操作完了")
|
||||
}
|
||||
}
|
||||
|
||||
box DataBox {
|
||||
init { value }
|
||||
|
||||
pack(initial_value) {
|
||||
me.value = initial_value
|
||||
}
|
||||
|
||||
process() {
|
||||
me.value = me.value * 2 + 1
|
||||
return me.value
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### test_vm_boxcall_return.nyash
|
||||
```nyash
|
||||
// BoxCall戻り値問題専用テスト
|
||||
static box BoxCallTest {
|
||||
main() {
|
||||
me.console = new ConsoleBox()
|
||||
|
||||
// 1. 基本BoxCall戻り値テスト
|
||||
local calculator = new Calculator()
|
||||
local result1 = calculator.add(10, 20)
|
||||
me.console.log("加算結果: " + result1) // 期待値: 30
|
||||
|
||||
// 2. チェーンBoxCall戻り値テスト
|
||||
local result2 = calculator.multiply(result1, 2)
|
||||
me.console.log("乗算結果: " + result2) // 期待値: 60
|
||||
|
||||
// 3. 複雑BoxCall戻り値テスト
|
||||
local complex = new ComplexBox()
|
||||
local result3 = complex.nested_calculation(5)
|
||||
me.console.log("複雑計算結果: " + result3) // 期待値: 要計算
|
||||
|
||||
// 🚨 VMで void が返される場合はここで判明
|
||||
if result1 == null {
|
||||
me.console.log("🚨 ERROR: BoxCall returned void in VM!")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
box Calculator {
|
||||
add(a, b) {
|
||||
return a + b
|
||||
}
|
||||
|
||||
multiply(a, b) {
|
||||
return a * b
|
||||
}
|
||||
}
|
||||
|
||||
box ComplexBox {
|
||||
nested_calculation(input) {
|
||||
local calc = new Calculator()
|
||||
local step1 = calc.add(input, 10)
|
||||
local step2 = calc.multiply(step1, 3)
|
||||
return calc.add(step2, 7)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### test_vm_memory_usage.nyash
|
||||
```nyash
|
||||
// メモリ使用量測定テスト
|
||||
static box MemoryTest {
|
||||
main() {
|
||||
me.console = new ConsoleBox()
|
||||
me.debug = new DebugBox()
|
||||
|
||||
// メモリ測定開始
|
||||
me.debug.startMemoryTracking()
|
||||
|
||||
// 1. 大量Box生成テスト(メモリプール効果測定)
|
||||
local boxes = new ArrayBox()
|
||||
local i = 0
|
||||
loop(i < 5000) {
|
||||
local data = new LargeDataBox(i)
|
||||
boxes.push(data)
|
||||
i = i + 1
|
||||
}
|
||||
|
||||
me.console.log("大量Box生成完了: " + boxes.size())
|
||||
|
||||
// 2. 参照操作テスト(参照管理オーバーヘッド測定)
|
||||
local j = 0
|
||||
loop(j < 1000) {
|
||||
local item = boxes.get(j % boxes.size())
|
||||
item.update_data()
|
||||
j = j + 1
|
||||
}
|
||||
|
||||
// メモリ使用量レポート
|
||||
me.console.log(me.debug.memoryReport())
|
||||
me.debug.stopMemoryTracking()
|
||||
}
|
||||
}
|
||||
|
||||
box LargeDataBox {
|
||||
init { id, data1, data2, data3, data4, data5 }
|
||||
|
||||
pack(identifier) {
|
||||
me.id = identifier
|
||||
me.data1 = "Large data string " + identifier
|
||||
me.data2 = identifier * 1000
|
||||
me.data3 = new ArrayBox()
|
||||
me.data4 = identifier + 0.5
|
||||
me.data5 = identifier % 2 == 0
|
||||
}
|
||||
|
||||
update_data() {
|
||||
me.data2 = me.data2 + 1
|
||||
me.data3.push(me.data2)
|
||||
return me.data2
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### test_vm_instruction_dispatch.nyash
|
||||
```nyash
|
||||
// 命令ディスパッチ性能特化テスト
|
||||
static box DispatchTest {
|
||||
main() {
|
||||
me.console = new ConsoleBox()
|
||||
|
||||
// 1. 大量の異なる命令種別実行(ディスパッチオーバーヘッド測定)
|
||||
local result = 0
|
||||
local i = 0
|
||||
|
||||
loop(i < 50000) {
|
||||
// 様々な命令を組み合わせ
|
||||
local a = i % 10 // Const, BinOp
|
||||
local b = (i + 1) % 10 // Const, BinOp
|
||||
local c = a + b // BinOp
|
||||
local d = c * 2 // BinOp
|
||||
local e = d > 15 // Compare
|
||||
|
||||
if e { // Branch
|
||||
result = result + d // BinOp
|
||||
} else {
|
||||
result = result - d // BinOp
|
||||
}
|
||||
|
||||
// BoxCall挿入
|
||||
local box_result = me.simple_calc(a, b) // BoxCall
|
||||
result = result + box_result
|
||||
|
||||
i = i + 1
|
||||
}
|
||||
|
||||
me.console.log("ディスパッチテスト完了: " + result)
|
||||
}
|
||||
|
||||
simple_calc(x, y) {
|
||||
return (x + y) * 2
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 🔧 実装支援スクリプト
|
||||
|
||||
### ベンチマーク実行スクリプト
|
||||
```bash
|
||||
#!/bin/bash
|
||||
# benchmark_vm_performance.sh
|
||||
|
||||
echo "🚀 Phase 8.6 VM性能改善テスト実行"
|
||||
|
||||
# 各テストを3バックエンドで実行
|
||||
TESTS=(
|
||||
"test_vm_performance_basic"
|
||||
"test_vm_boxcall_return"
|
||||
"test_vm_memory_usage"
|
||||
"test_vm_instruction_dispatch"
|
||||
)
|
||||
|
||||
for test in "${TESTS[@]}"; do
|
||||
echo "📊 $test.nyash テスト実行中..."
|
||||
|
||||
echo " - Interpreter実行..."
|
||||
time ./target/release/nyash --backend interpreter "tests/vm_performance/$test.nyash"
|
||||
|
||||
echo " - VM実行..."
|
||||
time ./target/release/nyash --backend vm "tests/vm_performance/$test.nyash"
|
||||
|
||||
echo " - WASM実行..."
|
||||
time ./target/release/nyash --backend wasm "tests/vm_performance/$test.nyash"
|
||||
|
||||
echo ""
|
||||
done
|
||||
|
||||
echo "✅ 全テスト完了"
|
||||
```
|
||||
|
||||
## 🏆 期待される成果
|
||||
|
||||
### 短期成果(2週間)
|
||||
- [ ] **VM性能2倍達成**: 119.80ms → 55ms以下
|
||||
- [ ] **BoxCall問題解決**: 戻り値正常動作
|
||||
- [ ] **プロファイリング環境**: 詳細性能測定機能
|
||||
|
||||
### 中期成果(1ヶ月)
|
||||
- [ ] **最適化基盤確立**: Phase 9 JIT準備完了
|
||||
- [ ] **メモリ効率向上**: 実行時メモリ使用量50%削減
|
||||
- [ ] **開発効率向上**: デバッグ・プロファイリング環境
|
||||
|
||||
### 長期インパクト
|
||||
- [ ] **JIT開発加速**: 最適化されたVM → JIT移行が容易
|
||||
- [ ] **実用性向上**: VM実行で実用的なアプリケーション開発可能
|
||||
- [ ] **競争力確立**: 他言語VM実装との性能競争力
|
||||
|
||||
---
|
||||
|
||||
**作成**: 2025-08-14
|
||||
**優先度**: 🚨 Critical(次期最優先)
|
||||
**期間**: 2週間
|
||||
**担当**: Copilot + Claude協調
|
||||
|
||||
この問題解決により、Nyash言語のVM実行性能が飛躍的に向上し、Phase 9 JIT実装への道筋が確立されます 🚀
|
||||
@ -0,0 +1,300 @@
|
||||
# Phase 8.7: Real-world Memory Management Testing + VM BoxCall修正(統合版)
|
||||
|
||||
## 🎯 Issue概要
|
||||
|
||||
**主目的**: 実用アプリケーション開発によるNyashメモリ管理システムの実証テスト
|
||||
|
||||
**統合目的**: VM BoxCall戻り値問題の修正を実用アプリ実装と同時に実施
|
||||
|
||||
**戦略的背景**:
|
||||
- Phase 8.4完了でAST→MIR Lowering完成
|
||||
- Phase 8.5完了でMIR 25命令階層化完成
|
||||
- **発見された課題**: VM BoxCall実行後の戻り値が`void`になる問題
|
||||
- **合理的統合**: kilo実装とBoxCall修正を同時実施で効率最大化
|
||||
|
||||
**統合効果**:
|
||||
```
|
||||
kilo実装 = ユーザー定義Box + メソッド呼び出し重用
|
||||
↓
|
||||
BoxCall正常動作 = kilo正常動作の前提条件
|
||||
↓
|
||||
統合実装 = 一石二鳥の効率性
|
||||
```
|
||||
|
||||
## 🎯 Phase 8.7A: kilo(テキストエディタ)
|
||||
|
||||
### 技術的特徴
|
||||
- **サイズ**: <1k LOC(超小型)
|
||||
- **メモリパターン**: Editor -> (Rows -> Syntax) 木構造+相互参照
|
||||
- **fini戦略**: Editor削除でRows自動解放、逆参照をweak化
|
||||
- **BoxCall実証**: ユーザー定義Boxメソッド呼び出しでVM戻り値正常化確認
|
||||
- **統合検証**: メモリ管理 + VM BoxCall動作の同時実証
|
||||
|
||||
### 実装仕様
|
||||
|
||||
#### 基本構造
|
||||
```nyash
|
||||
box Editor {
|
||||
init { rows, current_row, screen_rows, filename }
|
||||
|
||||
pack() {
|
||||
me.rows = new ArrayBox()
|
||||
me.current_row = 0
|
||||
me.screen_rows = 24
|
||||
me.filename = ""
|
||||
}
|
||||
|
||||
fini() {
|
||||
// ArrayBox自動解放でRows全解放
|
||||
// weak参照は自動null化される
|
||||
}
|
||||
}
|
||||
|
||||
box Row {
|
||||
init { text, size, editor } // editor: weak参照
|
||||
|
||||
pack(text_content, parent_editor) {
|
||||
me.text = text_content
|
||||
me.size = text_content.length()
|
||||
me.editor = weak parent_editor // 循環参照回避
|
||||
}
|
||||
|
||||
render() {
|
||||
if me.editor == null {
|
||||
return "ERROR: Editor already freed"
|
||||
}
|
||||
return me.text
|
||||
}
|
||||
}
|
||||
|
||||
box EditorState {
|
||||
init { cursor_x, cursor_y, editor } // editor: weak参照
|
||||
|
||||
pack(editor_ref) {
|
||||
me.cursor_x = 0
|
||||
me.cursor_y = 0
|
||||
me.editor = weak editor_ref
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### メイン処理
|
||||
```nyash
|
||||
static box Main {
|
||||
main() {
|
||||
local editor = new Editor()
|
||||
|
||||
// ファイル読み込み
|
||||
editor.loadFile("test.txt")
|
||||
|
||||
// 編集操作
|
||||
editor.insertLine(0, "Hello Nyash Editor!")
|
||||
editor.insertLine(1, "This tests memory management")
|
||||
|
||||
// 状態作成
|
||||
local state = new EditorState(editor)
|
||||
|
||||
// editor削除 → Rows自動解放、state.editorは自動null化
|
||||
editor.fini()
|
||||
|
||||
// weak参照確認
|
||||
if state.editor == null {
|
||||
print("✅ Editor properly freed, weak ref nullified")
|
||||
return 1
|
||||
} else {
|
||||
print("❌ Memory leak detected!")
|
||||
return 0
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 🧪 検証テストケース
|
||||
|
||||
#### Test 1: 基本メモリ管理
|
||||
```nyash
|
||||
// test_kilo_basic_memory.nyash
|
||||
box Editor {
|
||||
init { rows }
|
||||
pack() { me.rows = new ArrayBox() }
|
||||
fini() { print("Editor freed") }
|
||||
}
|
||||
|
||||
box Row {
|
||||
init { editor }
|
||||
pack(ed) { me.editor = weak ed }
|
||||
}
|
||||
|
||||
static box Main {
|
||||
main() {
|
||||
local editor = new Editor()
|
||||
local row = new Row(editor)
|
||||
|
||||
// editor削除
|
||||
editor.fini()
|
||||
|
||||
// weak参照確認
|
||||
return row.editor == null ? 1 : 0
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### Test 2: 複雑な相互参照
|
||||
```nyash
|
||||
// test_kilo_circular_refs.nyash
|
||||
box Editor {
|
||||
init { rows, state }
|
||||
pack() {
|
||||
me.rows = new ArrayBox()
|
||||
me.state = new EditorState(me) // 循環参照テスト
|
||||
}
|
||||
}
|
||||
|
||||
box EditorState {
|
||||
init { editor }
|
||||
pack(ed) { me.editor = weak ed }
|
||||
}
|
||||
|
||||
static box Main {
|
||||
main() {
|
||||
local editor = new Editor()
|
||||
editor.pack()
|
||||
|
||||
// 循環参照があっても正常解放されるか
|
||||
editor.fini()
|
||||
|
||||
return 1 // メモリリークなしで完了すればOK
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### Test 3: 大量オブジェクト管理
|
||||
```nyash
|
||||
// test_kilo_mass_objects.nyash
|
||||
static box Main {
|
||||
main() {
|
||||
local editor = new Editor()
|
||||
|
||||
// 大量行作成
|
||||
loop(i < 1000) {
|
||||
editor.addRow("Line " + i)
|
||||
}
|
||||
|
||||
print("Created 1000 rows")
|
||||
|
||||
// 一括削除
|
||||
editor.fini()
|
||||
|
||||
print("Editor freed with all rows")
|
||||
return 1
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### ✅ 成功基準(統合版)
|
||||
|
||||
#### 必須基準(メモリ管理)
|
||||
- [ ] 全テストケースでメモリリークなし
|
||||
- [ ] weak参照の自動null化動作確認
|
||||
- [ ] fini()伝播の正確性確認
|
||||
- [ ] 循環参照でも正常解放確認
|
||||
|
||||
#### 必須基準(VM BoxCall修正)
|
||||
- [ ] VM BoxCall実行後の戻り値が正常に返される
|
||||
- [ ] ユーザー定義Boxメソッド呼び出しがVMで正常動作
|
||||
- [ ] Interpreter/VM/WASMで同一BoxCall動作
|
||||
- [ ] kilo実装でBoxCallが期待通り動作
|
||||
|
||||
#### 理想基準
|
||||
- [ ] 1000+オブジェクトでも高速動作
|
||||
- [ ] WASM実行でもメモリ管理正常
|
||||
- [ ] ベンチマーク性能劣化なし
|
||||
- [ ] VM BoxCall性能がInterpreterと同等以上
|
||||
|
||||
## 🚀 Phase 9.5: tiny-web-server(将来実装)
|
||||
|
||||
### 技術的特徴
|
||||
- **複雑度**: 中〜高
|
||||
- **メモリパターン**: Server -> Clients -> Requests(並行処理)
|
||||
- **I/O管理**: ソケット・ファイルハンドルの確実解放
|
||||
|
||||
### 基本設計
|
||||
```nyash
|
||||
box Server {
|
||||
init { clients, port }
|
||||
fini() {
|
||||
// 全クライアント接続を確実切断
|
||||
me.clients.forEach(client => client.fini())
|
||||
}
|
||||
}
|
||||
|
||||
box Client {
|
||||
init { socket, server } // server: weak参照
|
||||
fini() {
|
||||
me.socket.close() // 確実なソケット解放
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 🤖 Copilot向け実装ガイド
|
||||
|
||||
### 実装順序(統合版)
|
||||
1. **Phase 1**: VM BoxCall戻り値修正 + Editor/Row基本構造実装
|
||||
2. **Phase 2**: weak参照・fini()システム統合 + BoxCall動作確認
|
||||
3. **Phase 3**: テストケース実装・検証(メモリ管理 + BoxCall統合テスト)
|
||||
4. **Phase 4**: パフォーマンス最適化・3バックエンド互換性確認
|
||||
|
||||
### 重要注意点
|
||||
- **weak参照構文**: `me.editor = weak editor_ref`
|
||||
- **fini()自動呼び出し**: ガベージコレクション時
|
||||
- **メモリリーク検出**: デバッグ出力で確認
|
||||
- **WASM互換性**: ブラウザ環境でも動作
|
||||
|
||||
### デバッグ支援(統合版)
|
||||
```bash
|
||||
# メモリ使用量監視
|
||||
./target/release/nyash --debug-memory test_kilo_basic.nyash
|
||||
|
||||
# weak参照追跡
|
||||
./target/release/nyash --trace-weak test_kilo_circular.nyash
|
||||
|
||||
# fini呼び出し追跡
|
||||
./target/release/nyash --trace-fini test_kilo_mass.nyash
|
||||
|
||||
# BoxCall戻り値デバッグ(新規)
|
||||
./target/release/nyash --debug-boxcall test_kilo_basic.nyash
|
||||
|
||||
# VM/Interpreter/WASM BoxCall比較(新規)
|
||||
./target/release/nyash --compare-boxcall test_kilo_basic.nyash
|
||||
|
||||
# 統合デバッグ(メモリ + BoxCall)
|
||||
./target/release/nyash --debug-all test_kilo_basic.nyash
|
||||
```
|
||||
|
||||
## 📊 期待される効果(統合版)
|
||||
|
||||
### 技術的効果
|
||||
- **メモリ管理実証**: Nyashメモリ管理システムの実用性実証
|
||||
- **VM実行基盤確立**: BoxCall正常動作によるVM実用性確保
|
||||
- **Everything is Box実証**: Box哲学の実用レベル確認
|
||||
- **fini/weak参照実証**: システムの堅牢性確認
|
||||
- **3バックエンド統一**: Interpreter/VM/WASMでの一貫動作
|
||||
|
||||
### 開発体験向上
|
||||
- **実用アプリ開発実現**: kiloエディタによる実証
|
||||
- **メモリ安全パターン**: プログラミングパターン確立
|
||||
- **デバッグ環境整備**: 包括的デバッグ支援機能
|
||||
- **移行容易性**: 他言語からの移行促進
|
||||
- **Phase 9準備完了**: JIT実装への安全な基盤確立
|
||||
|
||||
---
|
||||
|
||||
**優先度**: 🚨 Critical(Phase 8.5完了直後の最優先)
|
||||
**期間**: 2週間(Phase 8.6統合により3日短縮)
|
||||
**担当**: Copilot + Claude協調実装
|
||||
**統合目標**:
|
||||
- ✅ メモリ安全な実用アプリケーション完成(kilo)
|
||||
- ✅ VM BoxCall戻り値問題完全解決
|
||||
- ✅ Phase 9 JIT実装への安全な基盤確立
|
||||
|
||||
**戦略的価値**: 効率性最大化(統合実装)+ 品質保証(実証テスト)+ Phase 9準備完了
|
||||
@ -0,0 +1,226 @@
|
||||
# Phase 8.8: pack透明化システム実装
|
||||
|
||||
**Priority**: Critical
|
||||
**Estimated Effort**: 2-3日
|
||||
**Assignee**: Copilot (Claude監修)
|
||||
**Status**: Ready for Implementation
|
||||
|
||||
## 🎯 概要
|
||||
|
||||
**pack構文のユーザー完全透明化システム**を実装する。ユーザーは`pack`を一切意識せず、`from BuiltinBox()`で自動的に内部のpack機能が呼ばれるシステム。
|
||||
|
||||
### 🚨 背景問題
|
||||
- **Copilotがpack機能を誤解**:一般コンストラクタとして実装
|
||||
- **ドキュメント矛盾**:packの定義が混乱していた ✅ 修正済み
|
||||
- **ユーザー体験悪化**:packを意識する必要があった
|
||||
|
||||
## 📋 実装要件
|
||||
|
||||
### 1. **ビルトインBox判定システム**
|
||||
```rust
|
||||
// 実装必要な関数
|
||||
fn is_builtin_box(box_name: &str) -> bool {
|
||||
// StringBox, P2PBox, MathBox, ConsoleBox等を判定
|
||||
}
|
||||
|
||||
// 登録リスト (最低限)
|
||||
const BUILTIN_BOXES: &[&str] = &[
|
||||
"StringBox", "IntegerBox", "BoolBox", "NullBox",
|
||||
"P2PBox", "MathBox", "ConsoleBox", "DebugBox",
|
||||
"TimeBox", "RandomBox", "SoundBox", "MapBox"
|
||||
];
|
||||
```
|
||||
|
||||
### 2. **pack透明化解決システム**
|
||||
```rust
|
||||
// from BuiltinBox() の自動解決
|
||||
fn resolve_builtin_delegation(builtin: &str, args: Vec<_>) -> Result<(), String> {
|
||||
if is_builtin_box(builtin) {
|
||||
// 内部的に BuiltinBox.pack() を呼ぶ
|
||||
call_builtin_pack(builtin, args)
|
||||
} else {
|
||||
// ユーザー定義Box: birth > init > Box名 の順
|
||||
resolve_user_constructor(builtin, args)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 3. **エラーメッセージ改善**
|
||||
- ユーザーには「birth()がありません」表示
|
||||
- pack関連エラーは内部ログのみ
|
||||
- 混乱を避ける明確なメッセージ
|
||||
|
||||
## 🧪 テスト要件
|
||||
|
||||
### **必須テストケース** (全て PASS 必須)
|
||||
|
||||
#### **A. ユーザー定義Box基本動作**
|
||||
```nyash
|
||||
# test_user_box_basic.nyash
|
||||
box Life {
|
||||
init { name, energy }
|
||||
|
||||
birth(lifeName) {
|
||||
me.name = lifeName
|
||||
me.energy = 100
|
||||
}
|
||||
}
|
||||
|
||||
local alice = new Life("Alice")
|
||||
assert(alice.name == "Alice")
|
||||
assert(alice.energy == 100)
|
||||
```
|
||||
|
||||
#### **B. ビルトインBox継承**
|
||||
```nyash
|
||||
# test_builtin_inheritance.nyash
|
||||
box EnhancedP2P from P2PBox {
|
||||
init { features }
|
||||
|
||||
pack(nodeId, transport) {
|
||||
from P2PBox.pack(nodeId, transport) # 明示的pack
|
||||
me.features = new ArrayBox()
|
||||
}
|
||||
}
|
||||
|
||||
local node = new EnhancedP2P("node1", "tcp")
|
||||
assert(node.features != null)
|
||||
```
|
||||
|
||||
#### **C. 透明化システム動作**
|
||||
```nyash
|
||||
# test_transparency.nyash
|
||||
box SimpleString from StringBox {
|
||||
init { prefix }
|
||||
|
||||
birth(content, prefixStr) {
|
||||
from StringBox(content) # ← 透明化!内部的にpack呼び出し
|
||||
me.prefix = prefixStr
|
||||
}
|
||||
|
||||
override toString() {
|
||||
return me.prefix + from StringBox.toString()
|
||||
}
|
||||
}
|
||||
|
||||
local str = new SimpleString("Hello", ">>> ")
|
||||
assert(str.toString() == ">>> Hello")
|
||||
```
|
||||
|
||||
#### **D. 混在テスト**
|
||||
```nyash
|
||||
# test_mixed_inheritance.nyash
|
||||
box AdvancedCalc from MathBox {
|
||||
init { history }
|
||||
|
||||
birth() {
|
||||
from MathBox() # 透明化
|
||||
me.history = new ArrayBox()
|
||||
}
|
||||
}
|
||||
|
||||
box Calculator {
|
||||
init { result }
|
||||
|
||||
birth() {
|
||||
me.result = 0
|
||||
}
|
||||
}
|
||||
|
||||
local calc1 = new AdvancedCalc() # ビルトイン継承
|
||||
local calc2 = new Calculator() # ユーザー定義
|
||||
assert(calc1.history != null)
|
||||
assert(calc2.result == 0)
|
||||
```
|
||||
|
||||
#### **E. エラーケーステスト**
|
||||
```nyash
|
||||
# test_error_cases.nyash
|
||||
|
||||
# 1. 存在しないmethodを呼び出し
|
||||
box BadBox from StringBox {
|
||||
birth(content) {
|
||||
from StringBox.nonexistent() # エラー:適切なメッセージ
|
||||
}
|
||||
}
|
||||
|
||||
# 2. 引数不一致
|
||||
box ArgMismatch from P2PBox {
|
||||
birth() {
|
||||
from P2PBox("too", "many", "args") # エラー:引数不一致
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### **パフォーマンステスト**
|
||||
```nyash
|
||||
# test_performance.nyash
|
||||
local startTime = getCurrentTime()
|
||||
|
||||
loop(i < 1000) {
|
||||
local str = new SimpleString("test" + i, "prefix")
|
||||
local result = str.toString()
|
||||
}
|
||||
|
||||
local endTime = getCurrentTime()
|
||||
local elapsed = endTime - startTime
|
||||
assert(elapsed < 1000) # 1秒以内で完了
|
||||
```
|
||||
|
||||
## ✅ チェックリスト
|
||||
|
||||
### **実装前チェック**
|
||||
- [ ] 既存のbirth()実装が正常動作している
|
||||
- [ ] ドキュメント修正が完了している
|
||||
- [ ] テストファイルが準備されている
|
||||
|
||||
### **実装中チェック**
|
||||
- [ ] `is_builtin_box()` 関数実装完了
|
||||
- [ ] pack透明化解決システム実装完了
|
||||
- [ ] エラーメッセージ改善完了
|
||||
- [ ] 全テストケース PASS
|
||||
|
||||
### **実装後チェック**
|
||||
- [ ] 既存テストファイルが継続動作
|
||||
- [ ] パフォーマンス劣化なし(<5%)
|
||||
- [ ] birth()優先順位システム正常動作
|
||||
- [ ] エラーメッセージがユーザーフレンドリー
|
||||
|
||||
### **統合テスト**
|
||||
- [ ] `test_birth_simple.nyash` 継続動作 ✅
|
||||
- [ ] Chip-8エミュレーター修正版動作
|
||||
- [ ] 全ビルトインBox継承パターン動作
|
||||
- [ ] デリゲーションチェーン正常動作
|
||||
|
||||
## 📂 実装場所
|
||||
|
||||
### **主要ファイル**
|
||||
- `src/interpreter/expressions.rs` - from解決ロジック
|
||||
- `src/interpreter/objects.rs` - コンストラクタ優先順位
|
||||
- `src/interpreter/core.rs` - ビルトインBox判定
|
||||
- `src/box_trait.rs` - BUILTIN_BOXES定数
|
||||
|
||||
### **テストファイル**
|
||||
- `test_pack_transparency.nyash` - 統合テスト
|
||||
- `test_builtin_inheritance.nyash` - ビルトイン継承
|
||||
- `test_user_box_birth.nyash` - ユーザー定義Box
|
||||
- `test_error_cases.nyash` - エラーケース
|
||||
|
||||
## 🎉 完了条件
|
||||
|
||||
1. **全テストケース PASS** ✅
|
||||
2. **既存機能の継続動作** ✅
|
||||
3. **パフォーマンス維持** ✅
|
||||
4. **エラーメッセージ改善** ✅
|
||||
5. **ドキュメント整合性** ✅
|
||||
|
||||
## 🚨 注意事項
|
||||
|
||||
- **既存のbirth()実装は変更しない**
|
||||
- **pack機能自体は残す**(ビルトイン継承で必要)
|
||||
- **ユーザーAPIからpackを完全隠蔽**
|
||||
- **パフォーマンス劣化は避ける**
|
||||
|
||||
---
|
||||
|
||||
**実装時は必ずテストファースト開発で進める!** 🧪
|
||||
@ -0,0 +1,120 @@
|
||||
# Phase 8.9: birth()統一システム + weak参照修正 (Copilot手抜き対策版)
|
||||
|
||||
## 🚨 **緊急度**: Critical - 言語設計の根幹修正
|
||||
|
||||
## 📋 **背景・コンテキスト**
|
||||
Gemini専門家分析により「birth()統一・内部実装自由案」が言語設計として最適と確定。
|
||||
現在のpack透明化システムは**Nyash明示性哲学と根本的に矛盾**するため、完全廃止が必要。
|
||||
|
||||
**Gemini結論**: 「多くの点で優れており、Nyashの言語設計として非常に妥当で洗練されたもの」
|
||||
|
||||
## 🎯 **最終目標(手抜き検証ポイント)**
|
||||
|
||||
### ✅ **必須完了条件**
|
||||
1. `from StringBox(content)` → **コンパイルエラー化** (透明化完全廃止)
|
||||
2. `from StringBox.birth(content)` → **正常動作** (明示構文必須)
|
||||
3. weak参照 fini後 → **自動null化** (循環参照解放修正)
|
||||
4. **全テストケース PASS** (手抜き検出用)
|
||||
|
||||
### 🧪 **必須テストケース (手抜き防止)**
|
||||
```nyash
|
||||
# TEST 1: 透明化エラー化
|
||||
from StringBox(content) # ❌ コンパイルエラー必須
|
||||
|
||||
# TEST 2: 明示構文動作
|
||||
from StringBox.birth(content) # ✅ 正常動作必須
|
||||
|
||||
# TEST 3: weak参照修正
|
||||
cpu.fini()
|
||||
cpu = null
|
||||
assert(memory.cpu_ref == null) # ✅ null判定必須
|
||||
```
|
||||
|
||||
## 🔧 **技術実装要件**
|
||||
|
||||
### **1. パーサー修正 (透明化削除)**
|
||||
**場所**: `src/parser/expressions.rs:519-522`
|
||||
```rust
|
||||
// ❌ 削除対象: DOTなし構文サポート
|
||||
// DOTがない場合: from Parent() 形式 - 透明化システム
|
||||
parent.clone()
|
||||
|
||||
// ✅ 追加: エラー化
|
||||
return Err(ParseError::TransparencySystemRemoved {
|
||||
suggestion: format!("Use 'from {}.birth()' instead", parent),
|
||||
line: self.current_token().line,
|
||||
});
|
||||
```
|
||||
|
||||
### **2. インタープリター修正 (透明化削除)**
|
||||
**場所**: `src/interpreter/expressions.rs:1091-1095`
|
||||
```rust
|
||||
// ❌ 削除対象
|
||||
if is_builtin && method == parent {
|
||||
return self.execute_builtin_constructor_call(parent, current_instance_val.clone_box(), arguments);
|
||||
}
|
||||
|
||||
// ✅ 完全削除 + エラー化
|
||||
```
|
||||
|
||||
### **3. weak参照修正 (fini連動)**
|
||||
**場所**: `src/interpreter/objects.rs` weak関連
|
||||
**問題**: fini後もweak参照が有効判定される
|
||||
**修正**: fini実行時にweak参照を自動null化
|
||||
|
||||
## 📁 **削除対象ファイル・関数 (手抜き検証用)**
|
||||
|
||||
### **完全削除必須**
|
||||
- `execute_builtin_constructor_call()` 関数全体
|
||||
- `BUILTIN_BOXES`定数の透明化用途
|
||||
- `is_builtin_box()`の透明化判定用途
|
||||
|
||||
### **修正必須**
|
||||
- パーサーの`from Parent()`構文サポート → エラー化
|
||||
- weak参照のライフサイクル管理
|
||||
|
||||
## 🧪 **段階的実装・検証戦略**
|
||||
|
||||
### **Phase 1: 透明化削除**
|
||||
1. パーサー修正 → エラーメッセージ確認
|
||||
2. インタープリター修正 → 関数削除確認
|
||||
3. ビルド成功確認
|
||||
|
||||
### **Phase 2: 明示構文確認**
|
||||
1. `from StringBox.birth(content)` テスト
|
||||
2. 既存birth()機能継続確認
|
||||
3. エラーケーステスト
|
||||
|
||||
### **Phase 3: weak修正**
|
||||
1. fini→weak null化実装
|
||||
2. 循環参照解放確認
|
||||
3. メモリリーク防止確認
|
||||
|
||||
## 🚨 **手抜き検出メトリクス**
|
||||
|
||||
### **絶対に手抜きできない証拠**
|
||||
1. **コンパイルエラー**: `from StringBox(content)` で必ずエラー
|
||||
2. **テスト全PASS**: 5個のテストケース全て成功
|
||||
3. **weak null判定**: fini後の自動null化動作
|
||||
4. **メモリ安全性**: 循環参照完全解放
|
||||
|
||||
### **手抜き検出用デバッグログ**
|
||||
```rust
|
||||
println!("🔥 DEBUG: Transparency system removed - error should occur");
|
||||
println!("✅ DEBUG: Explicit birth() call successful");
|
||||
println!("🔗 DEBUG: Weak reference nullified after fini");
|
||||
```
|
||||
|
||||
## 🎯 **成功の定義 (妥協なし)**
|
||||
|
||||
**100%完了の条件**:
|
||||
1. 透明化システム完全根絶 ✅
|
||||
2. 明示的birth()構文強制 ✅
|
||||
3. weak参照ライフサイクル修正 ✅
|
||||
4. 全テストケース完全PASS ✅
|
||||
5. Nyash明示性哲学完全復活 ✅
|
||||
|
||||
---
|
||||
**注意**: この修正はNyash言語の設計哲学を正常化する根本的変更です。
|
||||
**手抜き不可**: 部分実装は言語の整合性を破壊します。
|
||||
**検証必須**: 全テストケースの完全成功が絶対条件です。
|
||||
Reference in New Issue
Block a user