about summary refs log tree commit diff
path: root/tvix/eval/src/vm.rs
diff options
context:
space:
mode:
authorVincent Ambo <mail@tazj.in>2023-01-20T13·18+0300
committerclbot <clbot@tvl.fyi>2023-01-20T22·48+0000
commit7442558b33b3f1ebcf356924b0345cb73d0524ab (patch)
treef66d9c9bbaac9ba9c48d4307794a178b5ee13d49 /tvix/eval/src/vm.rs
parent6d03e310603869b7ad67bd00f8eb858e362bd763 (diff)
refactor(tvix/eval): keep globals alive through VM struct r/5715
This forces users to pass the fully constructed set of globals to the
VM, making it harder to accidentally "lose" the set while weak
references to it still exist.

This doesn't modify any functionality, but is laying the foundation
for simplifying some of the builtins behaviour that has grown more
complex again.

Change-Id: I5120f97861c65dc46d90b8a4e2c92ad32cc53e03
Reviewed-on: https://cl.tvl.fyi/c/depot/+/7877
Autosubmit: tazjin <tazjin@tvl.su>
Tested-by: BuildkiteCI
Reviewed-by: flokli <flokli@flokli.de>
Diffstat (limited to 'tvix/eval/src/vm.rs')
-rw-r--r--tvix/eval/src/vm.rs16
1 files changed, 15 insertions, 1 deletions
diff --git a/tvix/eval/src/vm.rs b/tvix/eval/src/vm.rs
index b42b47c2dc01..06ead175eeb1 100644
--- a/tvix/eval/src/vm.rs
+++ b/tvix/eval/src/vm.rs
@@ -6,6 +6,7 @@ use std::{cmp::Ordering, collections::BTreeMap, ops::DerefMut, path::PathBuf, rc
 
 use crate::{
     chunk::Chunk,
+    compiler::GlobalsMap,
     errors::{Error, ErrorKind, EvalResult},
     io::EvalIO,
     nix_search_path::NixSearchPath,
@@ -124,6 +125,16 @@ pub struct VM<'o> {
 
     /// Runtime observer which can print traces of runtime operations.
     observer: &'o mut dyn RuntimeObserver,
+
+    /// Strong reference to the globals, guaranteeing that they are
+    /// kept alive for the duration of evaluation.
+    ///
+    /// This is important because recursive builtins (specifically
+    /// `import`) hold a weak reference to the builtins, while the
+    /// original strong reference is held by the compiler which does
+    /// not exist anymore at runtime.
+    #[allow(dead_code)]
+    globals: Rc<GlobalsMap>,
 }
 
 /// The result of a VM's runtime evaluation.
@@ -207,6 +218,7 @@ impl<'o> VM<'o> {
         nix_search_path: NixSearchPath,
         io_handle: Box<dyn EvalIO>,
         observer: &'o mut dyn RuntimeObserver,
+        globals: Rc<GlobalsMap>,
     ) -> Self {
         // Backtrace-on-stack-overflow is some seriously weird voodoo and
         // very unsafe.  This double-guard prevents it from accidentally
@@ -221,6 +233,7 @@ impl<'o> VM<'o> {
             nix_search_path,
             io_handle,
             observer,
+            globals,
             frames: vec![],
             stack: vec![],
             with_stack: vec![],
@@ -1180,9 +1193,10 @@ pub fn run_lambda(
     nix_search_path: NixSearchPath,
     io_handle: Box<dyn EvalIO>,
     observer: &mut dyn RuntimeObserver,
+    globals: Rc<GlobalsMap>,
     lambda: Rc<Lambda>,
 ) -> EvalResult<RuntimeResult> {
-    let mut vm = VM::new(nix_search_path, io_handle, observer);
+    let mut vm = VM::new(nix_search_path, io_handle, observer, globals);
 
     // Retain the top-level span of the expression in this lambda, as
     // synthetic "calls" in deep_force will otherwise not have a span