diff --git a/docs/development/current/main/core_boxes_design.md b/docs/development/current/main/core_boxes_design.md index ad36bcc7..6d044ddb 100644 --- a/docs/development/current/main/core_boxes_design.md +++ b/docs/development/current/main/core_boxes_design.md @@ -363,3 +363,107 @@ pub trait NyashPlugin: Send + Sync { - PluginHost.optional への optional/user プラグイン登録 - 既存 Box 実装と Service trait の接続 +--- + +## 9. Phase 92: UnifiedBoxRegistry 統合計画(2025-12-03) + +### 9.1 CoreServices と CoreBoxId の対応テーブル + +**実装**: `src/runtime/core_services.rs` + +```rust +impl CoreServices { + pub fn required_ids() -> &'static [CoreBoxId] { + &[ + CoreBoxId::String, + CoreBoxId::Integer, + CoreBoxId::Bool, + CoreBoxId::Array, + CoreBoxId::Map, + CoreBoxId::Console, + ] + } +} +``` + +**Phase 87 整合性**: CoreBoxId::is_core_required() と完全一致 + +### 9.2 PluginHost 初期化フック + +**実装**: `src/runtime/plugin_host.rs` + +```rust +impl PluginHost { + pub fn with_core_from_registry( + ring0: Arc, + registry: &UnifiedBoxRegistry, + ) -> Result { + // Phase 93 で実装予定 + todo!("Phase 93: UnifiedBoxRegistry から CoreServices への変換実装") + } +} +``` + +**エラー型**: `CoreInitError` で不足している core service を明示 + +### 9.3 Runtime 初期化接続ポイント + +**実装**: `src/runtime/mod.rs` + +```rust +pub fn initialize_runtime(ring0: Arc) -> Result { + let registry = UnifiedBoxRegistry::new(); + let plugin_host = PluginHost::with_core_from_registry(ring0, ®istry)?; + Ok(plugin_host) +} +``` + +**Phase 93 で実装**: UnifiedBoxRegistry から CoreServices への実際の変換 + +### 9.4 ensure_initialized() 呼び出し場所(Phase 93 実装予定) + +**決定事項**: Phase 93 以降で以下の4箇所で呼び出す + +1. **selfhost ランナー起動時**(`src/runner/selfhost.rs`) + ```rust + pub fn run_selfhost(config: &Config) -> Result<(), Error> { + let plugin_host = initialize_runtime(get_global_ring0())?; + plugin_host.ensure_core_initialized(); + // ... + } + ``` + +2. **hack_check 実行前**(`src/runner/hack_check.rs`) + ```rust + pub fn run_hack_check() -> Result<(), Error> { + let plugin_host = initialize_runtime(get_global_ring0())?; + plugin_host.ensure_core_initialized(); + // ... + } + ``` + +3. **VM バックエンド起動時**(`src/runner/modes/vm.rs`) + ```rust + pub fn run_vm(program: &str) -> Result<(), Error> { + let plugin_host = initialize_runtime(get_global_ring0())?; + plugin_host.ensure_core_initialized(); + // ... + } + ``` + +4. **統合テスト setup**(`tests/integration/setup.rs`) + ```rust + pub fn setup_test_runtime() -> PluginHost { + let plugin_host = initialize_runtime(get_global_ring0()).unwrap(); + plugin_host.ensure_core_initialized(); + plugin_host + } + ``` + +### 9.5 Phase 93 実装計画 + +- UnifiedBoxRegistry から core_required Box の取得 +- Box → Service trait への変換ロジック +- CoreServices の自動構築 +- ensure_initialized() の4箇所への配置 + diff --git a/src/runtime/core_services.rs b/src/runtime/core_services.rs index 5a90af25..ce6ce13c 100644 --- a/src/runtime/core_services.rs +++ b/src/runtime/core_services.rs @@ -4,6 +4,7 @@ //! Phase 87 CoreBoxId の core_required (6個) 全てをカバー。 use std::sync::Arc; +use crate::runtime::CoreBoxId; /// StringBox Service trait pub trait StringService: Send + Sync { @@ -58,6 +59,20 @@ pub struct CoreServices { } impl CoreServices { + /// Phase 87 CoreBoxId の core_required (6個) を返す + /// + /// Phase 87 CoreBoxId::is_core_required() と完全一致する。 + pub fn required_ids() -> &'static [CoreBoxId] { + &[ + CoreBoxId::String, + CoreBoxId::Integer, + CoreBoxId::Bool, + CoreBoxId::Array, + CoreBoxId::Map, + CoreBoxId::Console, + ] + } + /// 全フィールドが初期化されているか検証 /// Phase 92 以降で各 Service の初期化を検証 pub fn ensure_initialized(&self) { @@ -65,3 +80,27 @@ impl CoreServices { // Phase 92 以降で各 Service の初期化を検証 } } + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_required_ids_consistency() { + let required = CoreServices::required_ids(); + assert_eq!(required.len(), 6); + + // Phase 87 CoreBoxId::is_core_required() と一致 + for id in required { + assert!(id.is_core_required()); + } + + // 全ての core_required が含まれているか確認 + assert!(required.contains(&CoreBoxId::String)); + assert!(required.contains(&CoreBoxId::Integer)); + assert!(required.contains(&CoreBoxId::Bool)); + assert!(required.contains(&CoreBoxId::Array)); + assert!(required.contains(&CoreBoxId::Map)); + assert!(required.contains(&CoreBoxId::Console)); + } +} diff --git a/src/runtime/mod.rs b/src/runtime/mod.rs index 0b133ee4..fb61d651 100644 --- a/src/runtime/mod.rs +++ b/src/runtime/mod.rs @@ -42,6 +42,7 @@ pub use box_registry::{get_global_registry, BoxFactoryRegistry, BoxProvider}; pub use core_box_ids::{CoreBoxCategory, CoreBoxId, CoreMethodId}; // Phase 87: 型安全enum pub use plugin_config::PluginConfig; pub use ring0::{get_global_ring0, init_global_ring0, Ring0Context}; // Phase 88: Ring0 公開 API +pub use plugin_host::CoreInitError; // Phase 92: CoreServices 初期化エラー pub use plugin_loader_unified::{ get_global_plugin_host, init_global_plugin_host, MethodHandle, PluginBoxType, PluginHost, PluginLibraryHandle, @@ -57,3 +58,19 @@ pub use unified_registry::{ // pub use plugin_box::PluginBox; // legacy // Use unified plugin loader (formerly v2) // pub use plugin_loader::{PluginLoaderV2 as PluginLoader, get_global_loader_v2 as get_global_loader}; // legacy + +/// Runtime 初期化(Phase 92: 接続ポイント決定) +/// +/// Phase 93 で実装予定の接続ポイント。 +/// Phase 92 では skeleton のみ(todo!() を呼ぶ)。 +#[allow(dead_code)] +pub fn initialize_runtime(ring0: std::sync::Arc) -> Result { + use crate::box_factory::UnifiedBoxRegistry; + + let registry = UnifiedBoxRegistry::new(); + + // Phase 92: 接続ポイント決定(実装は Phase 93) + let plugin_host = plugin_host::PluginHost::with_core_from_registry(ring0, ®istry)?; + + Ok(plugin_host) +} diff --git a/src/runtime/plugin_host.rs b/src/runtime/plugin_host.rs index e6619817..d93e255d 100644 --- a/src/runtime/plugin_host.rs +++ b/src/runtime/plugin_host.rs @@ -6,6 +6,8 @@ use std::sync::Arc; use std::collections::HashMap; use std::any::Any; +use crate::box_factory::UnifiedBoxRegistry; +use crate::runtime::CoreBoxId; /// Plugin の基本情報 #[derive(Debug, Clone)] @@ -37,6 +39,39 @@ impl PluginRegistry { use super::core_services::CoreServices; use super::ring0::Ring0Context; +/// CoreServices 初期化エラー +#[derive(Debug, Clone)] +pub enum CoreInitError { + MissingService { + box_id: CoreBoxId, + message: String, + }, + RegistryEmpty, + InvalidServiceType { + box_id: CoreBoxId, + expected: &'static str, + found: String, + }, +} + +impl std::fmt::Display for CoreInitError { + fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { + match self { + CoreInitError::MissingService { box_id, message } => { + write!(f, "Missing core service {:?}: {}", box_id, message) + } + CoreInitError::RegistryEmpty => { + write!(f, "UnifiedBoxRegistry is empty") + } + CoreInitError::InvalidServiceType { box_id, expected, found } => { + write!(f, "Invalid service type for {:?}: expected {}, found {}", box_id, expected, found) + } + } + } +} + +impl std::error::Error for CoreInitError {} + /// PluginHost: Ring0Context と CoreServices の橋渡し pub struct PluginHost { pub ring0: Arc, @@ -53,6 +88,21 @@ impl PluginHost { unimplemented!("Phase 92 で from_registry() 実装後に削除") } + /// UnifiedBoxRegistry から core_required Box を取得して CoreServices を初期化 + /// + /// Phase 92: skeleton のみ(Phase 93 で実装) + #[allow(dead_code)] + pub fn with_core_from_registry( + ring0: Arc, + _registry: &UnifiedBoxRegistry, + ) -> Result { + // Phase 93 で実装予定 + // TODO: registry から core_required Box を取得 + // TODO: 各 Box を対応する Service trait に変換 + // TODO: CoreServices を構築 + todo!("Phase 93: UnifiedBoxRegistry から CoreServices への変換実装") + } + /// core_required が全て揃っているか検証 pub fn ensure_core_initialized(&self) { self.core.ensure_initialized(); @@ -160,4 +210,27 @@ mod tests { assert_eq!(desc.name, "dummy"); assert_eq!(desc.version, "0.1.0"); } + + #[test] + fn test_core_init_error_display() { + let error = CoreInitError::MissingService { + box_id: CoreBoxId::String, + message: "StringBox not found".to_string(), + }; + let display = format!("{}", error); + assert!(display.contains("String")); + assert!(display.contains("not found")); + } + + #[test] + #[should_panic(expected = "Phase 93")] + fn test_with_core_from_registry_todo() { + // Phase 92: todo!() を返すことを確認 + use crate::runtime::ring0::default_ring0; + let ring0 = Arc::new(default_ring0()); + let registry = UnifiedBoxRegistry::new(); + + let _result = PluginHost::with_core_from_registry(ring0, ®istry); + // Phase 93 で実装後はこのテストを削除 + } }