diff --git a/src/boxes/socket_box.rs b/src/boxes/socket_box.rs index 65f5b25b..12a57acd 100644 --- a/src/boxes/socket_box.rs +++ b/src/boxes/socket_box.rs @@ -56,12 +56,18 @@ pub struct SocketBox { impl Clone for SocketBox { fn clone(&self) -> Self { + // Read the current state values atomically + let current_is_server = *self.is_server.lock().unwrap(); + let current_is_connected = *self.is_connected.lock().unwrap(); + + // For listener and stream, we can't clone them, so we'll share them + // but create new Arc instances with the current state Self { base: BoxBase::new(), // New unique ID for clone - listener: Arc::clone(&self.listener), - stream: Arc::clone(&self.stream), - is_server: Arc::clone(&self.is_server), - is_connected: Arc::clone(&self.is_connected), + listener: Arc::clone(&self.listener), // Share the same listener + stream: Arc::clone(&self.stream), // Share the same stream + is_server: Arc::new(Mutex::new(current_is_server)), // New Arc with current value + is_connected: Arc::new(Mutex::new(current_is_connected)), // New Arc with current value } } } @@ -314,7 +320,8 @@ impl SocketBox { /// サーバーモード確認 pub fn is_server(&self) -> Box { - Box::new(BoolBox::new(*self.is_server.lock().unwrap())) + let is_server_value = *self.is_server.lock().unwrap(); + Box::new(BoolBox::new(is_server_value)) } } diff --git a/src/interpreter/expressions.rs b/src/interpreter/expressions.rs index 310d9aa9..d004299a 100644 --- a/src/interpreter/expressions.rs +++ b/src/interpreter/expressions.rs @@ -455,7 +455,22 @@ impl NyashInterpreter { // SocketBox method calls if let Some(socket_box) = obj_value.as_any().downcast_ref::() { - return self.execute_socket_method(socket_box, method, arguments); + let result = self.execute_socket_method(socket_box, method, arguments)?; + + // 🔧 FIX: Update stored variable for stateful SocketBox methods + // These methods modify the SocketBox internal state, so we need to update + // the stored local variable to ensure subsequent accesses get the updated state + if matches!(method, "bind" | "connect" | "close") { + if let ASTNode::Variable { name, .. } = object { + if let Some(stored_var) = self.local_vars.get_mut(name) { + // Replace the stored instance with the modified one + let updated_instance = socket_box.clone(); + *stored_var = Box::new(updated_instance); + } + } + } + + return Ok(result); } // HTTPServerBox method calls diff --git a/test_arc_sharing.nyash b/test_arc_sharing.nyash new file mode 100644 index 00000000..312c84af --- /dev/null +++ b/test_arc_sharing.nyash @@ -0,0 +1,24 @@ +// Test Arc sharing issue +static box Main { + main() { + print("🔬 Testing Arc sharing...") + + local socket1 + socket1 = new SocketBox() + + local socket2 + socket2 = socket1 // This should clone + + print("Before bind - socket1.isServer(): " + socket1.isServer().toString()) + print("Before bind - socket2.isServer(): " + socket2.isServer().toString()) + + socket1.bind("127.0.0.1", 8080) + + print("After bind - socket1.isServer(): " + socket1.isServer().toString()) + print("After bind - socket2.isServer(): " + socket2.isServer().toString()) + + socket1.close() + + return true + } +} \ No newline at end of file diff --git a/test_socket_simple.nyash b/test_socket_simple.nyash new file mode 100644 index 00000000..9733199c --- /dev/null +++ b/test_socket_simple.nyash @@ -0,0 +1,23 @@ +// Simple test for SocketBox state sharing +static box Main { + main() { + print("🧪 Testing SocketBox state sharing...") + + local socket + socket = new SocketBox() + + print("Initial isServer: " + socket.isServer().toString()) + + local bindOk + bindOk = socket.bind("127.0.0.1", 8080) + print("Bind result: " + bindOk.toString()) + + print("After bind isServer: " + socket.isServer().toString()) + + local closeOk + closeOk = socket.close() + print("Close result: " + closeOk.toString()) + + return true + } +} \ No newline at end of file