Introduce Rtl struct and from_rtl constructor
This commit refactors the `Environment` struct to better manage the Rust Runtime Library (RTL) bootstrap state. A new `Rtl` struct is introduced to hold a frozen snapshot of the initial RTL state, including scopes, types, purity, values, and documentation. This snapshot is created once after `rtl::register()` completes. The `Environment::new()` constructor is updated to perform a two-phase bootstrap: first, it registers RTL functions, and then it freezes the scope 0 and captures the RTL state into the new `Rtl` struct. A new constructor, `Environment::from_rtl()`, is added. This allows creating independent execution environments that all share the same underlying RTL state. This is crucial for isolation between different execution contexts, as user definitions and loaded modules will not leak between environments created from the same `Rtl` snapshot. The `Environment::list_bindings` and `Environment::list_rtl_docs` methods are updated to use the `rtl` field for accessing the RTL scope and documentation, reinforcing the concept of a shared, immutable RTL state. A new test, `test_environments_from_shared_rtl_are_independent`, is added to verify that environments created from the same `Rtl` snapshot are indeed independent and do not leak user-defined bindings.
This commit is contained in:
@@ -118,3 +118,22 @@ fn test_date_parsing() {
|
||||
panic!("Expected DateTime, got {:?}", res);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_environments_from_shared_rtl_are_independent() {
|
||||
let rtl = Environment::new().rtl();
|
||||
|
||||
// Two fresh environments from the same frozen RTL snapshot.
|
||||
let env1 = Environment::from_rtl(rtl.clone());
|
||||
let env2 = Environment::from_rtl(rtl.clone());
|
||||
|
||||
// Define a variable in env1 only.
|
||||
env1.run_script("(do (def x 42) 0)").unwrap();
|
||||
|
||||
// x must not be visible in env2.
|
||||
assert!(env2.run_script("x").is_err(), "User binding leaked across environments");
|
||||
|
||||
// RTL functions must work in both environments.
|
||||
assert_eq!(format!("{}", env1.run_script("(+ 1 2)").unwrap()), "3");
|
||||
assert_eq!(format!("{}", env2.run_script("(+ 1 2)").unwrap()), "3");
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user