diff --git a/src/boxes/debug_box.rs b/src/boxes/debug_box.rs index caa4e627..9ecfe059 100644 --- a/src/boxes/debug_box.rs +++ b/src/boxes/debug_box.rs @@ -102,12 +102,12 @@ use std::collections::HashMap; use std::sync::RwLock; use chrono::Local; -use crate::box_trait::{BoxCore, BoxBase, next_box_id, NyashBox, StringBox, BoolBox, VoidBox}; +use crate::box_trait::{BoxCore, BoxBase, NyashBox, StringBox, BoolBox, VoidBox}; use crate::interpreter::RuntimeError; use crate::instance::InstanceBox; use std::any::Any; -#[derive(Debug, Clone)] +#[derive(Debug)] pub struct DebugBox { base: BoxBase, tracking_enabled: RwLock, @@ -188,7 +188,7 @@ impl DebugBox { } pub fn dump_all(&self) -> Result, RuntimeError> { - let tracked = self.tracked_boxes.lock().unwrap(); + let tracked = self.tracked_boxes.read().unwrap(); let mut output = String::from("=== Box State Dump ===\n"); output.push_str(&format!("Time: {}\n", Local::now().format("%Y-%m-%d %H:%M:%S"))); output.push_str(&format!("Total tracked boxes: {}\n\n", tracked.len())); @@ -228,7 +228,7 @@ impl DebugBox { } pub fn memory_report(&self) -> Result, RuntimeError> { - let tracked = self.tracked_boxes.lock().unwrap(); + let tracked = self.tracked_boxes.read().unwrap(); let mut report = String::from("=== Memory Report ===\n"); report.push_str(&format!("Tracked boxes: {}\n", tracked.len())); @@ -248,14 +248,14 @@ impl DebugBox { // Advanced features pub fn set_breakpoint(&self, function_name: &str) -> Result, RuntimeError> { - let mut breakpoints = self.breakpoints.lock().unwrap(); + let mut breakpoints = self.breakpoints.write().unwrap(); breakpoints.push(function_name.to_string()); println!("[DEBUG] Breakpoint set at function: {}", function_name); Ok(Box::new(VoidBox::new())) } pub fn trace_call(&self, function_name: &str, args: Vec) -> Result, RuntimeError> { - let mut stack = self.call_stack.lock().unwrap(); + let mut stack = self.call_stack.write().unwrap(); stack.push(CallInfo { function_name: function_name.to_string(), args, @@ -271,7 +271,7 @@ impl DebugBox { } pub fn show_call_stack(&self) -> Result, RuntimeError> { - let stack = self.call_stack.lock().unwrap(); + let stack = self.call_stack.read().unwrap(); let mut output = String::from("=== Call Stack ===\n"); for (i, call) in stack.iter().enumerate() { @@ -287,10 +287,10 @@ impl DebugBox { } pub fn clear(&self) -> Result, RuntimeError> { - let mut tracked = self.tracked_boxes.lock().unwrap(); + let mut tracked = self.tracked_boxes.write().unwrap(); tracked.clear(); - let mut stack = self.call_stack.lock().unwrap(); + let mut stack = self.call_stack.write().unwrap(); stack.clear(); println!("[DEBUG] Cleared all debug information"); @@ -303,11 +303,29 @@ impl DebugBox { } pub fn get_tracked_count(&self) -> Result, RuntimeError> { - let tracked = self.tracked_boxes.lock().unwrap(); + let tracked = self.tracked_boxes.read().unwrap(); Ok(Box::new(crate::box_trait::IntegerBox::new(tracked.len() as i64))) } } +// Manual Clone implementation for DebugBox (RwLock doesn't auto-derive Clone) +impl Clone for DebugBox { + fn clone(&self) -> Self { + let tracked = self.tracked_boxes.read().unwrap(); + let breakpoints = self.breakpoints.read().unwrap(); + let call_stack = self.call_stack.read().unwrap(); + let tracking_enabled = self.tracking_enabled.read().unwrap(); + + DebugBox { + base: BoxBase::new(), // New unique ID for cloned instance + tracking_enabled: RwLock::new(*tracking_enabled), + tracked_boxes: RwLock::new(tracked.clone()), + breakpoints: RwLock::new(breakpoints.clone()), + call_stack: RwLock::new(call_stack.clone()), + } + } +} + // Implement BoxCore trait for DebugBox impl BoxCore for DebugBox { fn box_id(&self) -> u64 { @@ -319,7 +337,7 @@ impl BoxCore for DebugBox { } fn fmt_box(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { - let tracked = self.tracked_boxes.lock().unwrap(); + let tracked = self.tracked_boxes.read().unwrap(); write!(f, "DebugBox[{} tracked]", tracked.len()) } @@ -342,7 +360,7 @@ impl std::fmt::Display for DebugBox { // Implement NyashBox trait for DebugBox impl NyashBox for DebugBox { fn to_string_box(&self) -> StringBox { - let tracked = self.tracked_boxes.lock().unwrap(); + let tracked = self.tracked_boxes.read().unwrap(); StringBox::new(format!("DebugBox[{} tracked]", tracked.len())) } diff --git a/src/boxes/future/mod.rs b/src/boxes/future/mod.rs index 1104efbe..b817269a 100644 --- a/src/boxes/future/mod.rs +++ b/src/boxes/future/mod.rs @@ -17,7 +17,11 @@ pub struct NyashFutureBox { impl Clone for NyashFutureBox { fn clone(&self) -> Self { - let result_val = self.result.read().unwrap().clone(); + let result_guard = self.result.read().unwrap(); + let result_val = match result_guard.as_ref() { + Some(box_value) => Some(box_value.clone_box()), + None => None, + }; let is_ready_val = *self.is_ready.read().unwrap(); Self { diff --git a/src/boxes/http_server_box.rs b/src/boxes/http_server_box.rs index 7edaaada..b1b39c87 100644 --- a/src/boxes/http_server_box.rs +++ b/src/boxes/http_server_box.rs @@ -41,9 +41,8 @@ */ use crate::box_trait::{NyashBox, StringBox, IntegerBox, BoolBox, BoxCore, BoxBase}; -use crate::boxes::{SocketBox, MapBox, ArrayBox}; +use crate::boxes::SocketBox; use crate::boxes::http_message_box::{HTTPRequestBox, HTTPResponseBox}; -use crate::boxes::future::FutureBox; use std::any::Any; use std::sync::RwLock; use std::collections::HashMap; @@ -65,13 +64,27 @@ pub struct HTTPServerBox { impl Clone for HTTPServerBox { fn clone(&self) -> Self { // State-preserving clone implementation following PR #87 pattern - let socket_val = self.socket.read().unwrap().clone(); - let routes_val = self.routes.read().unwrap().clone(); - let middleware_val = self.middleware.read().unwrap().clone(); + let socket_guard = self.socket.read().unwrap(); + let socket_val = socket_guard.as_ref().map(|s| s.clone()); + + let routes_guard = self.routes.read().unwrap(); + let routes_val: HashMap> = routes_guard.iter() + .map(|(k, v)| (k.clone(), v.clone_box())) + .collect(); + + let middleware_guard = self.middleware.read().unwrap(); + let middleware_val: Vec> = middleware_guard.iter() + .map(|item| item.clone_box()) + .collect(); + let running_val = *self.running.read().unwrap(); let static_path_val = self.static_path.read().unwrap().clone(); let timeout_val = *self.timeout_seconds.read().unwrap(); - let connections_val = self.active_connections.read().unwrap().clone(); + + let connections_guard = self.active_connections.read().unwrap(); + let connections_val: Vec> = connections_guard.iter() + .map(|item| item.clone_box()) + .collect(); Self { base: BoxBase::new(), // New unique ID for clone @@ -189,7 +202,12 @@ impl HTTPServerBox { // Handle client in separate thread (simulate nowait) // For RwLock pattern, we need to pass the data needed for the thread let routes_snapshot = match self.routes.read() { - Ok(routes_guard) => routes_guard.clone(), + Ok(routes_guard) => { + let routes_clone: HashMap> = routes_guard.iter() + .map(|(k, v)| (k.clone(), v.clone_box())) + .collect(); + routes_clone + }, Err(_) => continue, // Skip this connection if we can't read routes }; diff --git a/src/boxes/socket_box.rs b/src/boxes/socket_box.rs index 042916c6..792e4052 100644 --- a/src/boxes/socket_box.rs +++ b/src/boxes/socket_box.rs @@ -34,10 +34,10 @@ * ``` */ -use crate::box_trait::{NyashBox, StringBox, IntegerBox, BoolBox, BoxCore, BoxBase}; +use crate::box_trait::{NyashBox, StringBox, BoolBox, BoxCore, BoxBase}; use std::any::Any; -use std::net::{TcpListener, TcpStream, SocketAddr, ToSocketAddrs}; -use std::io::{Read, Write, BufRead, BufReader}; +use std::net::{TcpListener, TcpStream}; +use std::io::{Write, BufRead, BufReader}; use std::sync::RwLock; use std::time::Duration; @@ -98,7 +98,7 @@ impl SocketBox { eprintln!("✅ TCP bind successful"); // listener設定 - match self.listener.lock() { + match self.listener.write() { Ok(mut listener_guard) => { *listener_guard = Some(listener); eprintln!("✅ Listener stored successfully"); @@ -110,12 +110,11 @@ impl SocketBox { } // is_server状態設定 - 徹底デバッグ - match self.is_server.lock() { + match self.is_server.write() { Ok(mut is_server_guard) => { eprintln!("🔥 BEFORE MUTATION:"); eprintln!("🔥 is_server value = {}", *is_server_guard); - eprintln!("🔥 Arc strong_count = {}", std::sync::Arc::strong_count(&self.is_server)); - eprintln!("🔥 Arc weak_count = {}", std::sync::Arc::weak_count(&self.is_server)); + eprintln!("🔥 RwLock pointer = {:p}", &self.is_server); eprintln!("🔥 Guard pointer = {:p}", &*is_server_guard); // 状態変更 @@ -130,7 +129,7 @@ impl SocketBox { eprintln!("✅ is_server guard dropped"); // 再確認テスト - match self.is_server.lock() { + match self.is_server.read() { Ok(check_guard) => { eprintln!("🔥 RECHECK AFTER DROP:"); eprintln!("🔥 is_server value = {}", *check_guard); @@ -161,7 +160,7 @@ impl SocketBox { let _backlog_num = backlog.to_string_box().value.parse::().unwrap_or(128); // Check if listener exists and is properly bound - let listener_guard = match self.listener.lock() { + let listener_guard = match self.listener.read() { Ok(guard) => guard, Err(_) => return Box::new(BoolBox::new(false)), }; @@ -195,8 +194,8 @@ impl SocketBox { // Create new SocketBox for the client connection let client_socket = SocketBox::new(); - *client_socket.stream.lock().unwrap() = Some(stream); - *client_socket.is_connected.lock().unwrap() = true; + *client_socket.stream.write().unwrap() = Some(stream); + *client_socket.is_connected.write().unwrap() = true; Box::new(client_socket) }, @@ -361,16 +360,13 @@ impl SocketBox { pub fn is_server(&self) -> Box { eprintln!("🔥 SOCKETBOX DEBUG: is_server() called"); eprintln!("🔥 Socket ID = {}", self.base.id); - eprintln!("🔥 Arc pointer = {:p}", &self.is_server); - eprintln!("🔥 Arc data pointer = {:p}", self.is_server.as_ref()); + eprintln!("🔥 RwLock pointer = {:p}", &self.is_server); - match self.is_server.lock() { + match self.is_server.read() { Ok(is_server_guard) => { let is_server_value = *is_server_guard; eprintln!("🔥 IS_SERVER READ:"); eprintln!("🔥 is_server value = {}", is_server_value); - eprintln!("🔥 Arc strong_count = {}", std::sync::Arc::strong_count(&self.is_server)); - eprintln!("🔥 Arc weak_count = {}", std::sync::Arc::weak_count(&self.is_server)); eprintln!("🔥 Guard pointer = {:p}", &*is_server_guard); eprintln!("🔥 Returning BoolBox with value = {}", is_server_value); @@ -391,26 +387,26 @@ impl NyashBox for SocketBox { fn to_string_box(&self) -> StringBox { eprintln!("🔥 SOCKETBOX to_string_box() called - Socket ID = {}", self.base.id); - eprintln!("🔥 Arc pointer = {:p}", &self.is_server); + eprintln!("🔥 RwLock pointer = {:p}", &self.is_server); - let is_server = match self.is_server.lock() { + let is_server = match self.is_server.read() { Ok(guard) => { - eprintln!("✅ is_server.lock() successful"); + eprintln!("✅ is_server.read() successful"); *guard }, Err(e) => { - eprintln!("❌ is_server.lock() failed: {}", e); + eprintln!("❌ is_server.read() failed: {}", e); false // デフォルト値 } }; - let is_connected = match self.is_connected.lock() { + let is_connected = match self.is_connected.read() { Ok(guard) => { - eprintln!("✅ is_connected.lock() successful"); + eprintln!("✅ is_connected.read() successful"); *guard }, Err(e) => { - eprintln!("❌ is_connected.lock() failed: {}", e); + eprintln!("❌ is_connected.read() failed: {}", e); false // デフォルト値 } }; @@ -451,18 +447,18 @@ impl BoxCore for SocketBox { fn fmt_box(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { eprintln!("🔥 SOCKETBOX fmt_box() called - Socket ID = {}", self.base.id); - let is_server = match self.is_server.lock() { + let is_server = match self.is_server.read() { Ok(guard) => *guard, Err(e) => { - eprintln!("❌ fmt_box: is_server.lock() failed: {}", e); + eprintln!("❌ fmt_box: is_server.read() failed: {}", e); false } }; - let is_connected = match self.is_connected.lock() { + let is_connected = match self.is_connected.read() { Ok(guard) => *guard, Err(e) => { - eprintln!("❌ fmt_box: is_connected.lock() failed: {}", e); + eprintln!("❌ fmt_box: is_connected.read() failed: {}", e); false } }; diff --git a/src/interpreter/async_methods.rs b/src/interpreter/async_methods.rs index cb264872..10c6e4fc 100644 --- a/src/interpreter/async_methods.rs +++ b/src/interpreter/async_methods.rs @@ -41,7 +41,7 @@ impl NyashInterpreter { message: format!("ready() expects 0 arguments, got {}", arguments.len()), }); } - Ok(future_box.ready()) + Ok(Box::new(BoolBox::new(future_box.ready()))) } "equals" => { if arguments.len() != 1 { diff --git a/src/interpreter/methods/p2p_methods.rs b/src/interpreter/methods/p2p_methods.rs index 1139e326..c06113eb 100644 --- a/src/interpreter/methods/p2p_methods.rs +++ b/src/interpreter/methods/p2p_methods.rs @@ -11,27 +11,22 @@ use crate::boxes::{IntentBox}; use crate::method_box::MethodBox; impl NyashInterpreter { - /// IntentBoxのメソッド実行 (Arc版) + /// IntentBoxのメソッド実行 (RwLock版) pub(in crate::interpreter) fn execute_intent_box_method( &mut self, intent_box: &IntentBox, method: &str, _arguments: &[ASTNode], - ) -> Result, RuntimeError> { - let data = intent_box.lock().map_err(|_| RuntimeError::UndefinedVariable { - name: "Failed to lock IntentBox".to_string(), - })?; - + ) -> Result, RuntimeError> { match method { // メッセージ名取得 "getName" | "name" => { - Ok(Box::new(StringBox::new(data.name.clone()))) + Ok(intent_box.get_name()) } // ペイロード取得(JSON文字列として) "getPayload" | "payload" => { - let payload_str = data.payload.to_string(); - Ok(Box::new(StringBox::new(payload_str))) + Ok(intent_box.get_payload()) } // 型情報取得 diff --git a/src/messaging/message_bus.rs b/src/messaging/message_bus.rs index 0a0c78ae..b736ebaa 100644 --- a/src/messaging/message_bus.rs +++ b/src/messaging/message_bus.rs @@ -52,10 +52,9 @@ impl BusEndpoint { /// メッセージを配送 pub fn deliver(&self, intent: IntentBox, from: &str) { let handlers = self.handlers.lock().unwrap(); - let intent_data = intent.lock().unwrap(); - let intent_name = &intent_data.name; + let intent_name = intent.get_name().to_string_box().value; - if let Some(intent_handlers) = handlers.get(intent_name) { + if let Some(intent_handlers) = handlers.get(&intent_name) { for handler in intent_handlers { handler(intent.clone(), from); }