Refactor: Use Rc/RefCell for shared mutable state

This commit replaces `Arc<Mutex<T>>` with `Rc<RefCell<T>>` for managing
shared mutable state within the AST and VM. This change is primarily an
internal refactoring to leverage Rust's standard library more
effectively for single-threaded scenarios, improving performance by
avoiding the overhead of mutexes.

The following types and their usage have been updated:
- `Environment.global_names` and `Environment.global_values`
- `Binder.globals`
- `bound_nodes::BoundKind::Lambda.body` (now `Rc<Node>`)
- `ast::types::NodeIdentity` (now `Rc<NodeIdentity>`)
- `ast::types::Value::List`, `Value::Record`, `Value::Function`,
  `Value::Object`, `Value::Cell`
- `ast::nodes::Scope` and `ast::nodes::Context`
- `ast::vm::Closure.function_node` and `Closure.upvalues`
- `ast::vm::VM.globals`

This change does not alter the external behavior of the library but
streamlines internal data management.
This commit is contained in:
Michael Schimmel
2026-02-17 13:00:25 +01:00
parent ce166f39e3
commit d55422272b
9 changed files with 112 additions and 148 deletions
+16 -15
View File
@@ -1,8 +1,9 @@
use std::collections::{HashMap, BTreeMap};
use std::sync::Arc;
use std::rc::Rc;
use std::cell::RefCell;
use std::fmt;
use std::sync::Mutex;
use lazy_static::lazy_static;
use std::sync::Mutex; // Still needed for global keyword registry
use std::any::Any;
/// Simple source location
@@ -18,7 +19,7 @@ pub struct NodeIdentity {
pub location: SourceLocation,
}
pub type Identity = Arc<NodeIdentity>;
pub type Identity = Rc<NodeIdentity>;
/// Interned string identifier
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
@@ -50,7 +51,7 @@ impl Keyword {
}
/// Interface for custom objects (Closures, Series, Streams)
pub trait Object: fmt::Debug + Send + Sync {
pub trait Object: fmt::Debug {
fn type_name(&self) -> &'static str;
fn as_any(&self) -> &dyn Any;
}
@@ -62,13 +63,13 @@ pub enum Value {
Bool(bool),
Int(i64),
Float(f64),
Text(Arc<str>),
Text(Rc<str>),
Keyword(Keyword),
List(Arc<Vec<Value>>),
Record(Arc<HashMap<Keyword, Value>>),
Function(Arc<dyn Fn(Vec<Value>) -> Value + Send + Sync>),
Object(Arc<dyn Object>), // For compiled Closures and other opaque types
Cell(Arc<Mutex<Value>>), // Boxed value for captures
List(Rc<Vec<Value>>),
Record(Rc<HashMap<Keyword, Value>>),
Function(Rc<dyn Fn(Vec<Value>) -> Value>),
Object(Rc<dyn Object>), // For compiled Closures and other opaque types
Cell(Rc<RefCell<Value>>), // Boxed value for captures
}
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
@@ -81,7 +82,7 @@ pub enum StaticType {
Text,
Keyword,
List(Box<StaticType>),
Record(Arc<BTreeMap<Keyword, StaticType>>),
Record(Rc<BTreeMap<Keyword, StaticType>>),
Function {
params: Vec<StaticType>,
ret: Box<StaticType>,
@@ -94,7 +95,7 @@ impl Value {
match self {
Value::Void => false,
Value::Bool(b) => *b,
Value::Cell(c) => c.lock().unwrap().is_truthy(),
Value::Cell(c) => c.borrow().is_truthy(),
_ => true,
}
}
@@ -108,10 +109,10 @@ impl Value {
Value::Text(_) => StaticType::Text,
Value::Keyword(_) => StaticType::Keyword,
Value::List(_) => StaticType::List(Box::new(StaticType::Any)),
Value::Record(_) => StaticType::Record(Arc::new(BTreeMap::new())), // Empty for now
Value::Record(_) => StaticType::Record(Rc::new(BTreeMap::new())), // Empty for now
Value::Function { .. } => StaticType::Any, // Dynamic function
Value::Object(o) => StaticType::Object(o.type_name()),
Value::Cell(c) => c.lock().unwrap().static_type(),
Value::Cell(c) => c.borrow().static_type(),
}
}
}
@@ -129,7 +130,7 @@ impl fmt::Display for Value {
Value::Record(r) => write!(f, "<record[{}]>", r.len()),
Value::Function(_) => write!(f, "<native fn>"),
Value::Object(o) => write!(f, "<{}>", o.type_name()),
Value::Cell(c) => write!(f, "{}", c.lock().unwrap()),
Value::Cell(c) => write!(f, "{}", c.borrow()),
}
}
}