Refactor global variable access in VM and optimizer

Replaces `Rc<RefCell<Vec<Value>>>` with a new `GlobalStore` struct for
accessing global variables. This provides a more structured way to
manage global values and allows for future optimizations like sharing
immutable RTL portions across environments. The `GlobalStore` also
includes an `rtl_len` field to distinguish between RTL and user global
slots, enabling debug-time checks for writes to immutable RTL slots.
This commit is contained in:
2026-03-27 23:40:42 +01:00
parent 893d9936ed
commit 0e8cd0832f
6 changed files with 89 additions and 44 deletions
+7 -9
View File
@@ -3,6 +3,7 @@ use crate::ast::nodes::{
IdentifierBinding, LambdaBinding, Node, NodeKind, UpvalueIdx, VirtualId,
};
use crate::ast::types::{Purity, Value};
use crate::ast::vm::GlobalStore;
use std::cell::RefCell;
use std::rc::Rc;
@@ -15,7 +16,7 @@ use super::utils::{collect_pattern_addrs, PathTracker, UsageInfo};
pub struct Optimizer {
pub enabled: bool,
max_passes: usize,
pub globals: Option<Rc<RefCell<Vec<Value>>>>,
pub globals: Option<GlobalStore>,
pub root_purity: Option<Rc<RefCell<Vec<Purity>>>>,
pub lambda_registry: Option<Rc<RefCell<GlobalAnalyzedRegistry>>>,
}
@@ -31,7 +32,7 @@ impl Optimizer {
}
}
pub fn with_globals(mut self, globals: Rc<RefCell<Vec<Value>>>) -> Self {
pub fn with_globals(mut self, globals: GlobalStore) -> Self {
self.globals = Some(globals);
self
}
@@ -127,14 +128,11 @@ impl Optimizer {
// 3. Fallback for Globals: check the actual VM environment
if let Address::Global(idx) = addr
&& let Some(globals_rc) = &self.globals
&& let Some(globals_store) = &self.globals
&& let Some(val) = globals_store.get(idx.0 as usize)
&& inliner.is_inlinable_value(&val, addr)
{
let globals = globals_rc.borrow();
if let Some(val) = globals.get(idx.0 as usize)
&& inliner.is_inlinable_value(val, addr)
{
return Rc::new(folder.make_constant_node(val.clone(), node));
}
return Rc::new(folder.make_constant_node(val, node));
}
}
+4 -4
View File
@@ -2,15 +2,15 @@ use crate::ast::nodes::{
Address, AnalyzedNode, IdentifierBinding, Node, NodeKind, NodeMetrics,
};
use crate::ast::types::{Purity, RecordLayout, StaticType, Value};
use std::cell::RefCell;
use crate::ast::vm::GlobalStore;
use std::rc::Rc;
pub struct Folder<'a> {
pub globals: &'a Option<Rc<RefCell<Vec<Value>>>>,
pub globals: &'a Option<GlobalStore>,
}
impl<'a> Folder<'a> {
pub fn new(globals: &'a Option<Rc<RefCell<Vec<Value>>>>) -> Self {
pub fn new(globals: &'a Option<GlobalStore>) -> Self {
Self { globals }
}
@@ -94,7 +94,7 @@ impl<'a> Folder<'a> {
NodeKind::Identifier {
binding: IdentifierBinding::Reference(Address::Global(idx)),
..
} => self.globals.as_ref()?.borrow().get(idx.0 as usize)?.clone(),
} => self.globals.as_ref()?.get(idx.0 as usize)?,
NodeKind::Constant(val) => val.clone(),
_ => return None,
};
+3 -2
View File
@@ -2,6 +2,7 @@ use crate::ast::nodes::{
Address, AnalyzedNode, IdentifierBinding, NodeKind, VirtualId,
};
use crate::ast::types::{Purity, Value};
use crate::ast::vm::GlobalStore;
use std::cell::RefCell;
use std::collections::HashSet;
@@ -11,13 +12,13 @@ use super::substitution_map::SubstitutionMap;
use super::utils::UsageInfo;
pub struct Inliner<'a> {
pub globals: &'a Option<Rc<RefCell<Vec<Value>>>>,
pub globals: &'a Option<GlobalStore>,
pub root_purity: &'a Option<Rc<RefCell<Vec<Purity>>>>,
}
impl<'a> Inliner<'a> {
pub fn new(
globals: &'a Option<Rc<RefCell<Vec<Value>>>>,
globals: &'a Option<GlobalStore>,
root_purity: &'a Option<Rc<RefCell<Vec<Purity>>>>,
) -> Self {
Self {