about summary refs log tree commit diff
diff options
context:
space:
mode:
authorVincent Ambo <mail@tazj.in>2022-08-23T19·54+0300
committertazjin <tazjin@tvl.su>2022-09-01T21·56+0000
commit6f31c895ffe2dc5dd8281d812252d5db0644ec77 (patch)
tree9e45e371bc7d066b8666a3df532c6d241ee1165b
parent4715f9a3a0135e1b6bc1f24fbafc9b1ce1a9bc20 (diff)
refactor(tvix/eval): return a lambda from the compiler r/4576
Changes the internal compiler plumbing to not just return a chunk of
code, but the same chunk wrapped inside of a lambda value.

This is one more step towards compiling runtime lambdas.

Change-Id: If0035f8e65a2970c5ae123fc068a2396e1d8fd72
Reviewed-on: https://cl.tvl.fyi/c/depot/+/6240
Tested-by: BuildkiteCI
Reviewed-by: grfn <grfn@gws.fyi>
-rw-r--r--tvix/eval/src/chunk.rs2
-rw-r--r--tvix/eval/src/compiler.rs13
-rw-r--r--tvix/eval/src/eval.rs4
-rw-r--r--tvix/eval/src/value/lambda.rs19
-rw-r--r--tvix/eval/src/vm.rs6
5 files changed, 28 insertions, 16 deletions
diff --git a/tvix/eval/src/chunk.rs b/tvix/eval/src/chunk.rs
index 03071b3008de..7526add169d6 100644
--- a/tvix/eval/src/chunk.rs
+++ b/tvix/eval/src/chunk.rs
@@ -1,7 +1,7 @@
 use crate::opcode::{CodeIdx, ConstantIdx, OpCode};
 use crate::value::Value;
 
-#[derive(Debug, Default)]
+#[derive(Clone, Debug, Default)]
 pub struct Chunk {
     pub code: Vec<OpCode>,
     pub constants: Vec<Value>,
diff --git a/tvix/eval/src/compiler.rs b/tvix/eval/src/compiler.rs
index 7ccb00432782..167ac731d68c 100644
--- a/tvix/eval/src/compiler.rs
+++ b/tvix/eval/src/compiler.rs
@@ -21,14 +21,14 @@ use std::path::{Path, PathBuf};
 use crate::chunk::Chunk;
 use crate::errors::{Error, ErrorKind, EvalResult};
 use crate::opcode::{CodeIdx, OpCode};
-use crate::value::Value;
+use crate::value::{Lambda, Value};
 use crate::warnings::{EvalWarning, WarningKind};
 
 /// Represents the result of compiling a piece of Nix code. If
 /// compilation was successful, the resulting bytecode can be passed
 /// to the VM.
 pub struct CompilationResult {
-    pub chunk: Chunk,
+    pub lambda: Lambda,
     pub warnings: Vec<EvalWarning>,
     pub errors: Vec<Error>,
 }
@@ -90,7 +90,7 @@ struct Scope {
 }
 
 struct Compiler {
-    chunk: Chunk,
+    lambda: Lambda,
     scope: Scope,
 
     warnings: Vec<EvalWarning>,
@@ -102,7 +102,8 @@ struct Compiler {
 // structures of the compiler.
 impl Compiler {
     fn chunk(&mut self) -> &mut Chunk {
-        &mut self.chunk
+        std::rc::Rc::<Chunk>::get_mut(self.lambda.chunk())
+            .expect("compiler flaw: long-lived chunk reference")
     }
 
     fn emit_constant(&mut self, value: Value) {
@@ -910,7 +911,7 @@ pub fn compile(expr: ast::Expr, location: Option<PathBuf>) -> EvalResult<Compila
 
     let mut c = Compiler {
         root_dir,
-        chunk: Chunk::default(),
+        lambda: Lambda::new_anonymous(),
         warnings: vec![],
         errors: vec![],
         scope: Default::default(),
@@ -919,7 +920,7 @@ pub fn compile(expr: ast::Expr, location: Option<PathBuf>) -> EvalResult<Compila
     c.compile(expr);
 
     Ok(CompilationResult {
-        chunk: c.chunk,
+        lambda: c.lambda,
         warnings: c.warnings,
         errors: c.errors,
     })
diff --git a/tvix/eval/src/eval.rs b/tvix/eval/src/eval.rs
index 10d36904e4b4..d81744220568 100644
--- a/tvix/eval/src/eval.rs
+++ b/tvix/eval/src/eval.rs
@@ -31,7 +31,7 @@ pub fn interpret(code: &str, location: Option<PathBuf>) -> EvalResult<Value> {
     let result = crate::compiler::compile(root_expr, location)?;
 
     #[cfg(feature = "disassembler")]
-    crate::disassembler::disassemble_chunk(&result.chunk);
+    crate::disassembler::disassemble_chunk(&result.lambda.chunk);
 
     for warning in result.warnings {
         eprintln!(
@@ -49,5 +49,5 @@ pub fn interpret(code: &str, location: Option<PathBuf>) -> EvalResult<Value> {
         return Err(err.clone());
     }
 
-    crate::vm::run_chunk(result.chunk)
+    crate::vm::run_lambda(result.lambda)
 }
diff --git a/tvix/eval/src/value/lambda.rs b/tvix/eval/src/value/lambda.rs
index 2cecb4f5373b..d8609f50f367 100644
--- a/tvix/eval/src/value/lambda.rs
+++ b/tvix/eval/src/value/lambda.rs
@@ -3,10 +3,21 @@ use std::rc::Rc;
 
 use crate::chunk::Chunk;
 
-use super::NixString;
-
 #[derive(Clone, Debug)]
 pub struct Lambda {
-    name: Option<NixString>,
-    chunk: Rc<Chunk>,
+    // name: Option<NixString>,
+    pub(crate) chunk: Rc<Chunk>,
+}
+
+impl Lambda {
+    pub fn new_anonymous() -> Self {
+        Lambda {
+            // name: None,
+            chunk: Default::default(),
+        }
+    }
+
+    pub fn chunk(&mut self) -> &mut Rc<Chunk> {
+        &mut self.chunk
+    }
 }
diff --git a/tvix/eval/src/vm.rs b/tvix/eval/src/vm.rs
index 7a6a6454eadc..c9b09be82b1c 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::{NixAttrs, NixList, Value},
+    value::{Lambda, NixAttrs, NixList, Value},
 };
 
 #[cfg(feature = "disassembler")]
@@ -365,9 +365,9 @@ impl VM {
     }
 }
 
-pub fn run_chunk(chunk: Chunk) -> EvalResult<Value> {
+pub fn run_lambda(lambda: Lambda) -> EvalResult<Value> {
     let mut vm = VM {
-        chunk,
+        chunk: Rc::<Chunk>::try_unwrap(lambda.chunk).unwrap(),
         ip: 0,
         stack: vec![],
         with_stack: vec![],