From 6ce2c666c32a3ecb5512a5b186896ae1a1f84838 Mon Sep 17 00:00:00 2001 From: Vincent Ambo Date: Wed, 24 Aug 2022 22:08:26 +0300 Subject: refactor(tvix/eval): introduce Closure struct in Value type 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 Tested-by: BuildkiteCI --- tvix/eval/src/builtins/mod.rs | 2 +- tvix/eval/src/compiler/mod.rs | 6 ++++-- tvix/eval/src/value/function.rs | 28 ++++++++++++++++++++++++++++ tvix/eval/src/value/lambda.rs | 23 ----------------------- tvix/eval/src/value/mod.rs | 10 +++++----- tvix/eval/src/vm.rs | 4 ++-- 6 files changed, 40 insertions(+), 33 deletions(-) create mode 100644 tvix/eval/src/value/function.rs delete mode 100644 tvix/eval/src/value/lambda.rs (limited to 'tvix') diff --git a/tvix/eval/src/builtins/mod.rs b/tvix/eval/src/builtins/mod.rs index 11e0dc8d9fa7..99a63c97998d 100644 --- a/tvix/eval/src/builtins/mod.rs +++ b/tvix/eval/src/builtins/mod.rs @@ -44,7 +44,7 @@ fn pure_builtins() -> Vec { }), 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 5cb02a66b96a..3160c68c6e3c 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/function.rs b/tvix/eval/src/value/function.rs new file mode 100644 index 000000000000..45efc24f09f8 --- /dev/null +++ b/tvix/eval/src/value/function.rs @@ -0,0 +1,28 @@ +//! This module implements the runtime representation of functions. +use std::rc::Rc; + +use crate::chunk::Chunk; + +#[derive(Clone, Debug)] +pub struct Lambda { + // name: Option, + pub(crate) chunk: Rc, +} + +impl Lambda { + pub fn new_anonymous() -> Self { + Lambda { + // name: None, + chunk: Default::default(), + } + } + + pub fn chunk(&mut self) -> &mut Rc { + &mut self.chunk + } +} + +#[derive(Clone, Debug)] +pub struct Closure { + pub lambda: Lambda, +} diff --git a/tvix/eval/src/value/lambda.rs b/tvix/eval/src/value/lambda.rs deleted file mode 100644 index d8609f50f367..000000000000 --- a/tvix/eval/src/value/lambda.rs +++ /dev/null @@ -1,23 +0,0 @@ -//! This module implements the runtime representation of functions. -use std::rc::Rc; - -use crate::chunk::Chunk; - -#[derive(Clone, Debug)] -pub struct Lambda { - // name: Option, - pub(crate) chunk: Rc, -} - -impl Lambda { - pub fn new_anonymous() -> Self { - Lambda { - // name: None, - chunk: Default::default(), - } - } - - pub fn chunk(&mut self) -> &mut Rc { - &mut self.chunk - } -} diff --git a/tvix/eval/src/value/mod.rs b/tvix/eval/src/value/mod.rs index bf07c5d326d0..6bd1efde52ff 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), 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 1e39792cd56f..6a7ebd5e64d2 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)?; -- cgit 1.4.1