about summary refs log tree commit diff
path: root/tvix/eval/src/builtins/impure.rs
diff options
context:
space:
mode:
Diffstat (limited to 'tvix/eval/src/builtins/impure.rs')
-rw-r--r--tvix/eval/src/builtins/impure.rs111
1 files changed, 11 insertions, 100 deletions
diff --git a/tvix/eval/src/builtins/impure.rs b/tvix/eval/src/builtins/impure.rs
index d371d877977d..e8c032cc77e6 100644
--- a/tvix/eval/src/builtins/impure.rs
+++ b/tvix/eval/src/builtins/impure.rs
@@ -2,20 +2,17 @@ use builtin_macros::builtins;
 use smol_str::SmolStr;
 
 use std::{
-    collections::BTreeMap,
     env,
-    rc::{Rc, Weak},
+    rc::Rc,
     time::{SystemTime, UNIX_EPOCH},
 };
 
 use crate::{
-    compiler::GlobalsMap,
     errors::ErrorKind,
     io::FileType,
-    observer::NoOpObserver,
-    value::{Builtin, BuiltinArgument, NixAttrs, Thunk},
+    value::{NixAttrs, Thunk},
     vm::VM,
-    SourceCode, Value,
+    Value,
 };
 
 #[builtins]
@@ -67,13 +64,13 @@ mod impure_builtins {
 
 /// Return all impure builtins, that is all builtins which may perform I/O
 /// outside of the VM and so cannot be used in all contexts (e.g. WASM).
-pub(super) fn builtins() -> BTreeMap<&'static str, Value> {
-    let mut map: BTreeMap<&'static str, Value> = impure_builtins::builtins()
+pub fn impure_builtins() -> Vec<(&'static str, Value)> {
+    let mut result = impure_builtins::builtins()
         .into_iter()
-        .map(|b| (b.name(), Value::Builtin(b)))
-        .collect();
+        .map(super::builtin_tuple)
+        .collect::<Vec<_>>();
 
-    map.insert(
+    result.push((
         "storeDir",
         Value::Thunk(Thunk::new_suspended_native(Rc::new(Box::new(
             |vm: &mut VM| match vm.io().store_dir() {
@@ -81,7 +78,7 @@ pub(super) fn builtins() -> BTreeMap<&'static str, Value> {
                 Some(dir) => Ok(Value::String(dir.into())),
             },
         )))),
-    );
+    ));
 
     // currentTime pins the time at which evaluation was started
     {
@@ -92,94 +89,8 @@ pub(super) fn builtins() -> BTreeMap<&'static str, Value> {
             Err(err) => -(err.duration().as_secs() as i64),
         };
 
-        map.insert("currentTime", Value::Integer(seconds));
+        result.push(("currentTime", Value::Integer(seconds)));
     }
 
-    map
-}
-
-/// Constructs and inserts the `import` builtin. This builtin is special in that
-/// it needs to capture the [crate::SourceCode] structure to correctly track
-/// source code locations while invoking a compiler.
-// TODO: need to be able to pass through a CompilationObserver, too.
-pub fn builtins_import(globals: &Weak<GlobalsMap>, source: SourceCode) -> Builtin {
-    // This (very cheap, once-per-compiler-startup) clone exists
-    // solely in order to keep the borrow checker happy.  It
-    // resolves the tension between the requirements of
-    // Rc::new_cyclic() and Builtin::new()
-    let globals = globals.clone();
-
-    Builtin::new(
-        "import",
-        &[BuiltinArgument {
-            strict: true,
-            name: "path",
-        }],
-        None,
-        move |mut args: Vec<Value>, vm: &mut VM| {
-            let mut path = super::coerce_value_to_path(&args.pop().unwrap(), vm)?;
-            if path.is_dir() {
-                path.push("default.nix");
-            }
-
-            let current_span = vm.current_light_span();
-
-            if let Some(cached) = vm.import_cache.get(&path) {
-                return Ok(cached.clone());
-            }
-
-            let contents = vm.io().read_to_string(path.clone())?;
-
-            let parsed = rnix::ast::Root::parse(&contents);
-            let errors = parsed.errors();
-
-            let file = source.add_file(path.to_string_lossy().to_string(), contents);
-
-            if !errors.is_empty() {
-                return Err(ErrorKind::ImportParseError {
-                    path,
-                    file,
-                    errors: errors.to_vec(),
-                });
-            }
-
-            let result = crate::compiler::compile(
-                &parsed.tree().expr().unwrap(),
-                Some(path.clone()),
-                file,
-                // The VM must ensure that a strong reference to the
-                // globals outlives any self-references (which are
-                // weak) embedded within the globals.  If the
-                // expect() below panics, it means that did not
-                // happen.
-                globals
-                    .upgrade()
-                    .expect("globals dropped while still in use"),
-                &mut NoOpObserver::default(),
-            )
-            .map_err(|err| ErrorKind::ImportCompilerError {
-                path: path.clone(),
-                errors: vec![err],
-            })?;
-
-            if !result.errors.is_empty() {
-                return Err(ErrorKind::ImportCompilerError {
-                    path,
-                    errors: result.errors,
-                });
-            }
-
-            // Compilation succeeded, we can construct a thunk from whatever it spat
-            // out and return that.
-            let res = Value::Thunk(Thunk::new_suspended(result.lambda, current_span));
-
-            vm.import_cache.insert(path, res.clone());
-
-            for warning in result.warnings {
-                vm.push_warning(warning);
-            }
-
-            Ok(res)
-        },
-    )
+    result
 }