Files
hakorune/docs/development/proposals/architecture-redesign-proposal.md
Moe Charm cc2a820af7 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>
2025-08-21 00:41:26 +09:00

241 lines
6.1 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 🌟 Nyash アーキテクチャ再設計提案
*by Codex exec (2025-08-21)*
## 🎯 核心的洞察
**「実装詳細共有」から「モデル共有・実行時共有」への転換**
現在の問題の本質は、InterpreterとVMが「実装詳細」を共有しようとしていること。正しいアプローチは「モデル宣言」と「ランタイム実行環境」を共有し、実行戦略だけを分離すること。
## 🏗️ 新アーキテクチャ層構造
```
┌─────────────┐
│ AST/Model │ ← 純粋なデータモデル(依存なし)
└──────┬──────┘
┌──────▼──────┐
│ Runtime │ ← 型システム・クラス管理・インスタンス生成
└──────┬──────┘
┌──────┴──────┬──────────┬────────────┐
│ Interpreter │ VM │ Plugins │
└─────────────┴──────────┴────────────┘
```
### 各層の責務
**AST/Model層**
- 言語の純データモデル
- BoxDeclaration、ASTNode、型シグネチャ
- 実行時情報を含まない
**Runtime層**
- BoxClass/BoxFactoryによる型システム
- インスタンス生成とライフサイクル管理
- メソッドディスパッチと呼び出し規約
**Backend層**
- Interpreter: AST直接実行
- VM: MIR/Bytecode実行
- 両者ともRuntimeを通じてBoxを操作
## 🔧 具体的な設計
### 1. BoxDeclarationの移動
```rust
// core::model::box_declaration.rs
pub struct BoxDeclaration {
pub name: String,
pub type_params: Vec<TypeParam>,
pub fields: Vec<FieldDecl>,
pub methods: Vec<MethodDecl>,
pub static_methods: Vec<StaticDecl>,
pub attrs: AttrSet,
pub source_span: Option<Span>,
}
pub struct FieldDecl {
pub name: String,
pub ty: TypeRef,
pub attrs: AttrSet,
}
pub struct MethodDecl {
pub name: String,
pub sig: FnSig,
pub body: FnBodyRef, // AST or MIR reference
}
```
### 2. NyashRuntimeの導入
```rust
// runtime::mod.rs
pub struct NyashRuntime {
box_registry: BoxRegistry,
type_space: TypeSpace,
fn_space: FnSpace,
}
pub struct ExecutionSession {
runtime: Arc<NyashRuntime>,
root_box: SharedBox,
frames: Vec<Frame>,
env: Environment,
}
// SharedBox = Arc<dyn NyashBox>
pub type SharedBox = Arc<dyn NyashBox>;
```
### 3. BoxClass/Factoryシステム
```rust
// runtime::box_class.rs
pub trait BoxClass: Send + Sync {
fn name(&self) -> &str;
fn instantiate(
&self,
args: &[SharedBox],
sess: &mut ExecutionSession
) -> Result<SharedBox>;
fn lookup_method(&self, name: &str) -> Option<MethodHandle>;
fn lifecycle(&self) -> Option<&dyn BoxLifecycle>;
}
pub trait BoxFactory: Send + Sync {
fn can_build(&self, decl: &BoxDeclaration) -> bool;
fn build_class(
&self,
decl: &BoxDeclaration,
rt: &NyashRuntime
) -> Result<Arc<dyn BoxClass>>;
}
pub trait BoxLifecycle {
fn on_birth(&self, ctx: &mut InstanceCtx) -> Result<()>;
fn on_fini(&self, ctx: &mut InstanceCtx);
}
```
### 4. 統一されたBox管理
```rust
// runtime::registry.rs
pub struct BoxRegistry {
classes: RwLock<HashMap<String, Arc<dyn BoxClass>>>,
factories: RwLock<Vec<Arc<dyn BoxFactory>>>,
}
impl BoxRegistry {
pub fn register_class(&self, class: Arc<dyn BoxClass>) {
// 登録処理
}
pub fn get_class(&self, name: &str) -> Option<Arc<dyn BoxClass>> {
// クラス取得
}
pub fn create_instance(
&self,
class_name: &str,
args: &[SharedBox],
sess: &mut ExecutionSession
) -> Result<SharedBox> {
let class = self.get_class(class_name)?;
class.instantiate(args, sess)
}
}
```
## 📋 実装手順(最小破壊的移行)
### Step 1: BoxDeclarationの移動
```rust
// 1. core::model モジュールを作成
// 2. BoxDeclarationを移動
// 3. インタープリターで一時的に別名を使用
use core::model::BoxDeclaration as InterpreterBoxDecl;
```
### Step 2: NyashRuntimeの骨組み作成
```rust
// 最初は空の実装から始める
pub struct NyashRuntime {
// 段階的に追加
}
pub struct NyashRuntimeBuilder {
// SharedStateからの移行を支援
}
```
### Step 3: BoxFactoryのdyn化
```rust
// 現在の trait BoxFactory を使用
// すべて Arc<dyn BoxFactory> として扱う
```
### Step 4: グローバル登録の排除
```rust
// 削除: register_user_defined_factory(...)
// 追加: NyashRuntimeBuilder::with_factory(...)
```
### Step 5: SharedStateの段階的分解
```rust
// 一時的なシム
pub struct SharedStateShim {
runtime: Arc<NyashRuntime>,
session: ExecutionSession,
}
// 互換性のためのFrom実装
impl From<SharedState> for SharedStateShim {
// 移行ロジック
}
```
### Step 6-8: 統一と最適化
- Interpreter/VMのコンストラクタ統一
- birth/finiライフサイクルの一元化
- 最終的なSharedState削除
## 🎯 得られる利点
1. **依存関係の明確化**
- VM→Interpreter依存が完全に解消
- 両者はRuntimeのみに依存
2. **テスタビリティ向上**
- グローバル状態なし
- 並行テスト可能
3. **保守性向上**
- 責務が明確に分離
- 新しいBackend追加が容易
4. **Everything is Box哲学の貫徹**
- 統一的なBox管理
- birth/finiライフサイクルの一元化
## ⚠️ 実装上の注意点
1. **trait objectは必ず`Arc<dyn Trait>`**
- `Arc<Trait>`は使わない
- dynキーワードを忘れない
2. **段階的移行**
- 各ステップでテストが通ることを確認
- 互換性レイヤーを活用
3. **ロックの最小化**
- Runtimeは基本的に不変
- 必要最小限のRwLock使用
---
この設計により、Nyashはよりシンプルでエレガントなアーキテクチャとなり、InterpreterとVMの統合が自然に実現されます。