Implement targeted SocketBox Clone fix for shared mutable state
Co-authored-by: moe-charm <217100418+moe-charm@users.noreply.github.com>
This commit is contained in:
@ -56,18 +56,14 @@ pub struct SocketBox {
|
|||||||
|
|
||||||
impl Clone for SocketBox {
|
impl Clone for SocketBox {
|
||||||
fn clone(&self) -> Self {
|
fn clone(&self) -> Self {
|
||||||
// Read the current state values atomically
|
// 🔧 FIX: Share state containers for "Everything is Box" reference sharing
|
||||||
let current_is_server = *self.is_server.lock().unwrap();
|
// This ensures that clones of the same SocketBox share mutable state
|
||||||
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 {
|
Self {
|
||||||
base: BoxBase::new(), // New unique ID for clone
|
base: BoxBase::new(), // New unique ID for clone (for debugging/identity)
|
||||||
listener: Arc::clone(&self.listener), // Share the same listener
|
listener: Arc::clone(&self.listener), // Share the same listener
|
||||||
stream: Arc::clone(&self.stream), // Share the same stream
|
stream: Arc::clone(&self.stream), // Share the same stream
|
||||||
is_server: Arc::new(Mutex::new(current_is_server)), // New Arc with current value
|
is_server: Arc::clone(&self.is_server), // 🔧 Share the same state container
|
||||||
is_connected: Arc::new(Mutex::new(current_is_connected)), // New Arc with current value
|
is_connected: Arc::clone(&self.is_connected), // 🔧 Share the same state container
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -51,7 +51,8 @@ impl NyashInterpreter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ASTNode::FieldAccess { object, field, .. } => {
|
ASTNode::FieldAccess { object, field, .. } => {
|
||||||
self.execute_field_access(object, field)
|
let shared_result = self.execute_field_access(object, field)?;
|
||||||
|
Ok((*shared_result).clone_box()) // Convert Arc to Box for external interface
|
||||||
}
|
}
|
||||||
|
|
||||||
ASTNode::New { class, arguments, type_arguments, .. } => {
|
ASTNode::New { class, arguments, type_arguments, .. } => {
|
||||||
@ -672,7 +673,7 @@ impl NyashInterpreter {
|
|||||||
|
|
||||||
/// フィールドアクセスを実行 - Field access processing with weak reference support
|
/// フィールドアクセスを実行 - Field access processing with weak reference support
|
||||||
pub(super) fn execute_field_access(&mut self, object: &ASTNode, field: &str)
|
pub(super) fn execute_field_access(&mut self, object: &ASTNode, field: &str)
|
||||||
-> Result<Box<dyn NyashBox>, RuntimeError> {
|
-> Result<SharedNyashBox, RuntimeError> {
|
||||||
|
|
||||||
// 🔥 Static Boxアクセスチェック
|
// 🔥 Static Boxアクセスチェック
|
||||||
if let ASTNode::Variable { name, .. } = object {
|
if let ASTNode::Variable { name, .. } = object {
|
||||||
@ -734,8 +735,8 @@ impl NyashInterpreter {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Normal field access - convert Arc back to Box for compatibility
|
// Return the shared Arc reference directly
|
||||||
Ok((*field_value).clone_box())
|
Ok(field_value)
|
||||||
} else {
|
} else {
|
||||||
Err(RuntimeError::TypeError {
|
Err(RuntimeError::TypeError {
|
||||||
message: format!("Cannot access field '{}' on non-instance type. Type: {}", field, obj_value.type_name()),
|
message: format!("Cannot access field '{}' on non-instance type. Type: {}", field, obj_value.type_name()),
|
||||||
|
|||||||
20
test_basic_sharing.nyash
Normal file
20
test_basic_sharing.nyash
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
// Test basic field access sharing
|
||||||
|
static box Main {
|
||||||
|
init { mybox }
|
||||||
|
|
||||||
|
main() {
|
||||||
|
me.mybox = new IntegerBox(100)
|
||||||
|
|
||||||
|
print("=== Test 1: Basic field access ===")
|
||||||
|
local temp1
|
||||||
|
temp1 = me.mybox
|
||||||
|
print("temp1 ID: " + temp1.toString())
|
||||||
|
|
||||||
|
local temp2
|
||||||
|
temp2 = me.mybox
|
||||||
|
print("temp2 ID: " + temp2.toString())
|
||||||
|
|
||||||
|
// The IDs should be the same if sharing works
|
||||||
|
return temp1
|
||||||
|
}
|
||||||
|
}
|
||||||
21
test_box_id_sharing.nyash
Normal file
21
test_box_id_sharing.nyash
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
// Test for Arc sharing - checking if same Box ID is returned
|
||||||
|
static box Main {
|
||||||
|
init { server }
|
||||||
|
|
||||||
|
main() {
|
||||||
|
me.server = new SocketBox()
|
||||||
|
|
||||||
|
print("=== First access ===")
|
||||||
|
local temp1
|
||||||
|
temp1 = me.server
|
||||||
|
print("Box ID: " + temp1.toString())
|
||||||
|
|
||||||
|
print("=== Second access ===")
|
||||||
|
local temp2
|
||||||
|
temp2 = me.server
|
||||||
|
print("Box ID: " + temp2.toString())
|
||||||
|
|
||||||
|
// If Arc sharing works, both should have same ID
|
||||||
|
return temp1
|
||||||
|
}
|
||||||
|
}
|
||||||
24
test_simple_arc_fix.nyash
Normal file
24
test_simple_arc_fix.nyash
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
// Simple test case to verify Arc sharing fix
|
||||||
|
static box Main {
|
||||||
|
init { counter }
|
||||||
|
|
||||||
|
main() {
|
||||||
|
me.counter = new IntegerBox(42)
|
||||||
|
|
||||||
|
print("=== Initial value ===")
|
||||||
|
print("counter: " + me.counter.to_string())
|
||||||
|
|
||||||
|
// Test if getting the same field returns the same object
|
||||||
|
local temp1
|
||||||
|
temp1 = me.counter
|
||||||
|
|
||||||
|
local temp2
|
||||||
|
temp2 = me.counter
|
||||||
|
|
||||||
|
print("=== Testing shared reference ===")
|
||||||
|
print("temp1: " + temp1.to_string())
|
||||||
|
print("temp2: " + temp2.to_string())
|
||||||
|
|
||||||
|
return me.counter
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user