about summary refs log tree commit diff
path: root/tvix
diff options
context:
space:
mode:
authorVincent Ambo <mail@tazj.in>2022-08-24T19·08+0300
committertazjin <tazjin@tvl.su>2022-09-03T00·47+0000
commit6ce2c666c32a3ecb5512a5b186896ae1a1f84838 (patch)
treea78a11e2f9080dc59e87470b3b11f14a6c653dac /tvix
parentaf9dca36635df677fce559c5fdd3f08680d84557 (diff)
refactor(tvix/eval): introduce Closure struct in Value type r/4605
This struct will carry the upvalue machinery in addition to the lambda
itself. For now, all lambdas are wrapped in closures (though
technically analysis of the environment can later remove innermost
Closure wrapper, but this optimisation may not be worth it).

Change-Id: If2b68549ec1ea4ab838fdc47a2181c694ac937f2
Reviewed-on: https://cl.tvl.fyi/c/depot/+/6269
Reviewed-by: grfn <grfn@gws.fyi>
Tested-by: BuildkiteCI
Diffstat (limited to 'tvix')
-rw-r--r--tvix/eval/src/builtins/mod.rs2
-rw-r--r--tvix/eval/src/compiler/mod.rs6
-rw-r--r--tvix/eval/src/value/function.rs (renamed from tvix/eval/src/value/lambda.rs)5
-rw-r--r--tvix/eval/src/value/mod.rs10
-rw-r--r--tvix/eval/src/vm.rs4
5 files changed, 17 insertions, 10 deletions
diff --git a/tvix/eval/src/builtins/mod.rs b/tvix/eval/src/builtins/mod.rs
index 11e0dc8d9f..99a63c9799 100644
--- a/tvix/eval/src/builtins/mod.rs
+++ b/tvix/eval/src/builtins/mod.rs
@@ -44,7 +44,7 @@ fn pure_builtins() -> Vec<Builtin> {
         }),
         Builtin::new("isFunction", 1, |args| {
             Ok(Value::Bool(match args[0] {
-                Value::Lambda(_) => true,
+                Value::Closure(_) => true,
                 Value::Builtin(_) => true,
                 _ => false,
             }))
diff --git a/tvix/eval/src/compiler/mod.rs b/tvix/eval/src/compiler/mod.rs
index 5cb02a66b9..3160c68c6e 100644
--- a/tvix/eval/src/compiler/mod.rs
+++ b/tvix/eval/src/compiler/mod.rs
@@ -23,7 +23,7 @@ use std::rc::Rc;
 use crate::chunk::Chunk;
 use crate::errors::{Error, ErrorKind, EvalResult};
 use crate::opcode::{CodeIdx, OpCode};
-use crate::value::{Lambda, Value};
+use crate::value::{Closure, Lambda, Value};
 use crate::warnings::{EvalWarning, WarningKind};
 
 /// Represents the result of compiling a piece of Nix code. If
@@ -822,7 +822,9 @@ impl Compiler {
             crate::disassembler::disassemble_chunk(&compiled.lambda.chunk);
         }
 
-        self.emit_constant(Value::Lambda(compiled.lambda));
+        self.emit_constant(Value::Closure(Closure {
+            lambda: compiled.lambda,
+        }));
     }
 
     fn compile_apply(&mut self, node: ast::Apply) {
diff --git a/tvix/eval/src/value/lambda.rs b/tvix/eval/src/value/function.rs
index d8609f50f3..45efc24f09 100644
--- a/tvix/eval/src/value/lambda.rs
+++ b/tvix/eval/src/value/function.rs
@@ -21,3 +21,8 @@ impl Lambda {
         &mut self.chunk
     }
 }
+
+#[derive(Clone, Debug)]
+pub struct Closure {
+    pub lambda: Lambda,
+}
diff --git a/tvix/eval/src/value/mod.rs b/tvix/eval/src/value/mod.rs
index bf07c5d326..6bd1efde52 100644
--- a/tvix/eval/src/value/mod.rs
+++ b/tvix/eval/src/value/mod.rs
@@ -5,14 +5,14 @@ use std::{fmt::Display, path::PathBuf};
 
 mod attrs;
 mod builtin;
-mod lambda;
+mod function;
 mod list;
 mod string;
 
 use crate::errors::{ErrorKind, EvalResult};
 pub use attrs::NixAttrs;
 pub use builtin::Builtin;
-pub use lambda::Lambda;
+pub use function::{Closure, Lambda};
 pub use list::NixList;
 pub use string::NixString;
 
@@ -27,7 +27,7 @@ pub enum Value {
     Path(PathBuf),
     Attrs(Rc<NixAttrs>),
     List(NixList),
-    Lambda(Lambda),
+    Closure(Closure),
     Builtin(Builtin),
 
     // Internal values that, while they technically exist at runtime,
@@ -52,7 +52,7 @@ impl Value {
             Value::Path(_) => "path",
             Value::Attrs(_) => "set",
             Value::List(_) => "list",
-            Value::Lambda(_) | Value::Builtin(_) => "lambda",
+            Value::Closure(_) | Value::Builtin(_) => "lambda",
 
             // Internal types
             Value::AttrPath(_) | Value::Blackhole | Value::NotFound => "internal",
@@ -130,7 +130,7 @@ impl Display for Value {
             Value::Path(p) => p.display().fmt(f),
             Value::Attrs(attrs) => attrs.fmt(f),
             Value::List(list) => list.fmt(f),
-            Value::Lambda(_) => f.write_str("lambda"), // TODO: print position
+            Value::Closure(_) => f.write_str("lambda"), // TODO: print position
             Value::Builtin(builtin) => builtin.fmt(f),
 
             // Nix prints floats with a maximum precision of 5 digits
diff --git a/tvix/eval/src/vm.rs b/tvix/eval/src/vm.rs
index 1e39792cd5..6a7ebd5e64 100644
--- a/tvix/eval/src/vm.rs
+++ b/tvix/eval/src/vm.rs
@@ -7,7 +7,7 @@ use crate::{
     chunk::Chunk,
     errors::{ErrorKind, EvalResult},
     opcode::OpCode,
-    value::{Lambda, NixAttrs, NixList, Value},
+    value::{Closure, Lambda, NixAttrs, NixList, Value},
 };
 
 #[cfg(feature = "disassembler")]
@@ -357,7 +357,7 @@ impl VM {
                 OpCode::OpCall => {
                     let callable = self.pop();
                     match callable {
-                        Value::Lambda(lambda) => self.call(lambda, 1),
+                        Value::Closure(Closure { lambda }) => self.call(lambda, 1),
                         Value::Builtin(builtin) => {
                             let arg = self.pop();
                             let result = builtin.apply(arg)?;