- 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>
122 lines
4.6 KiB
Plaintext
122 lines
4.6 KiB
Plaintext
Nyashプログラミング言語のclone_box()設計について深い相談をお願いします。
|
||
|
||
【緊急問題の発生】
|
||
Phase 9.75でArc<Mutex> → RwLock変換後、ArrayBoxの状態保持が機能しなくなりました:
|
||
|
||
```nyash
|
||
// 期待される動作
|
||
arr = new ArrayBox()
|
||
arr.push("hello") // 状態変更
|
||
arr.length() // 1 であるべき
|
||
|
||
// 実際の動作
|
||
arr.length() // 0 (状態が失われる)
|
||
```
|
||
|
||
【根本原因の特定】
|
||
インタープリターの変数アクセス時にclone_box()で毎回新インスタンス作成:
|
||
|
||
```rust
|
||
// src/interpreter/expressions.rs:108
|
||
ASTNode::Variable { name, .. } => {
|
||
let shared_var = self.resolve_variable(name)?;
|
||
Ok((*shared_var).clone_box()) // ← 🚨 ここで新インスタンス作成!
|
||
}
|
||
|
||
// src/boxes/array/mod.rs:282
|
||
impl NyashBox for ArrayBox {
|
||
fn clone_box(&self) -> Box<dyn NyashBox> {
|
||
Box::new(self.clone()) // ← 🚨 完全コピー!状態消失!
|
||
}
|
||
}
|
||
|
||
// Clone実装でも完全新インスタンス作成
|
||
impl Clone for ArrayBox {
|
||
fn clone(&self) -> Self {
|
||
let items = self.items.read().unwrap();
|
||
let cloned_items: Vec<Box<dyn NyashBox>> = items.iter()
|
||
.map(|item| item.clone_box())
|
||
.collect();
|
||
ArrayBox::new_with_elements(cloned_items) // ← 新インスタンス!
|
||
}
|
||
}
|
||
```
|
||
|
||
【Nyashの設計制約】
|
||
1. **Everything is Box哲学**: 全てがBox、統一インターフェース必須
|
||
2. **3つの実行バックエンド**: インタープリター・VM・WASM
|
||
3. **Rust実装**: メモリ安全性・スレッドセーフティ重視
|
||
4. **RwLock統一アーキテクチャ**: Arc<Mutex>二重ロック問題を解決済み
|
||
|
||
【影響を受けるBox型】
|
||
- **ステートフル**: ArrayBox, MapBox, SocketBox, P2PBox, FileBox, StreamBox
|
||
- **ステートレス**: StringBox, IntegerBox, BoolBox(問題なし)
|
||
|
||
【実行バックエンド別影響】
|
||
- **インタープリター**: 🔴 確実に影響(expressions.rs:108)
|
||
- **VM**: 🟡 可能性大(vm.rs:764の配列アクセス)
|
||
- **WASM**: 🟢 独自メモリ管理で軽微
|
||
|
||
【設計選択肢の検討】
|
||
|
||
**Option A: clone_box()を参照共有に変更**
|
||
```rust
|
||
// 案1: Arc<RwLock>でラップして参照共有
|
||
fn clone_box(&self) -> Box<dyn NyashBox> {
|
||
// 何らかの参照共有メカニズム
|
||
}
|
||
```
|
||
|
||
**Option B: 新しい参照Box導入**
|
||
```rust
|
||
// 案2: ReferenceBoxやSharedBoxを新設
|
||
trait NyashBox {
|
||
fn clone_box(&self) -> Box<dyn NyashBox>; // 値コピー用
|
||
fn share_box(&self) -> Box<dyn NyashBox>; // 参照共有用
|
||
}
|
||
```
|
||
|
||
**Option C: インタープリター側修正**
|
||
```rust
|
||
// 案3: Arc<dyn NyashBox>を直接使用
|
||
// clone_box()を呼ばずに参照を直接返す
|
||
```
|
||
|
||
**Option D: 型レベル区別**
|
||
```rust
|
||
// 案4: ValueBoxとReferenceBoxを型レベルで区別
|
||
enum BoxType {
|
||
Value(Box<dyn NyashBox>), // 値型(StringBox等)
|
||
Reference(Arc<RwLock<dyn NyashBox>>), // 参照型(ArrayBox等)
|
||
}
|
||
```
|
||
|
||
【技術的制約】
|
||
1. **3バックエンド対応**: 全実行バックエンドで一貫動作必須
|
||
2. **スレッドセーフティ**: RwLock統一アーキテクチャ維持
|
||
3. **メモリ効率**: 不要なコピー・ロックを避ける
|
||
4. **型安全性**: Rustの借用チェッカーと協調
|
||
5. **Everything is Box**: 統一インターフェース維持
|
||
|
||
【パフォーマンス要件】
|
||
- WASM: 13.5倍高速化を維持
|
||
- VM: 20.4倍高速化を維持
|
||
- インタープリター: デバッグ用途、性能より安定性
|
||
|
||
【質問】
|
||
1. **設計哲学**: clone_box()は値コピーと参照共有のどちらであるべきか?
|
||
2. **実装戦略**: 上記Option A-Dのどれが最適か?他の案は?
|
||
3. **型システム**: 値型と参照型を型レベルで区別すべきか?
|
||
4. **互換性**: 既存のBox型実装への影響を最小化する方法は?
|
||
5. **マルチバックエンド**: 3つの実行バックエンドで一貫性を保つ設計は?
|
||
6. **段階的移行**: 15個のステートフルBox修正の優先順位は?
|
||
|
||
プログラミング言語実装・Rust設計パターンの専門的視点から、最も堅実で拡張性の高い解決策を提案してください。
|
||
|
||
【開発制約】
|
||
- 開発者: Rust中級レベル
|
||
- 優先順位: 安定性 > 性能 > 実装の簡潔さ
|
||
- 保守性: 将来的なBox型追加に対応できる設計
|
||
- テスト: 既存のテストケースが動作し続ける必要あり
|
||
|
||
以上の制約下で、Nyashの「Everything is Box」哲学を保ちつつ、状態保持問題を根本解決する設計を分析してください。 |