diff options
author | Vincent Ambo <mail@tazj.in> | 2022-08-30T16·55+0300 |
---|---|---|
committer | tazjin <tazjin@tvl.su> | 2022-09-07T15·25+0000 |
commit | 23a5caabec5617c01d5629bd50dd7e7649cbe5a6 (patch) | |
tree | 996c1740febd8297a39bcf287a2c2e3c96663928 /tvix/eval/src/compiler | |
parent | 727845645d4b6032e6b16dcfa997e14da9806084 (diff) |
feat(tvix/eval): construct attribute sets lazily r/4699
This thunks the construction of attribute sets. Because Tvix does not currently have a "strict output" mode, a test had to be disabled that now displays a thunk representation. The test will be re-enabled once that is available. Change-Id: I360332be64cd5c154f9caea21828f6f1b37a265c Reviewed-on: https://cl.tvl.fyi/c/depot/+/6363 Tested-by: BuildkiteCI Reviewed-by: sterni <sternenseemann@systemli.org>
Diffstat (limited to 'tvix/eval/src/compiler')
-rw-r--r-- | tvix/eval/src/compiler/mod.rs | 12 |
1 files changed, 10 insertions, 2 deletions
diff --git a/tvix/eval/src/compiler/mod.rs b/tvix/eval/src/compiler/mod.rs index 96c864110137..b1dec5df1db2 100644 --- a/tvix/eval/src/compiler/mod.rs +++ b/tvix/eval/src/compiler/mod.rs @@ -115,7 +115,7 @@ impl Compiler { ast::Expr::BinOp(op) => self.compile_binop(slot, op), ast::Expr::HasAttr(has_attr) => self.compile_has_attr(slot, has_attr), ast::Expr::List(list) => self.compile_list(slot, list), - ast::Expr::AttrSet(attrs) => self.compile_attr_set(slot, attrs), + ast::Expr::AttrSet(attrs) => self.thunk(slot, move |c, s| c.compile_attr_set(s, attrs)), ast::Expr::Select(select) => self.compile_select(slot, select), ast::Expr::Assert(assert) => self.compile_assert(slot, assert), ast::Expr::IfElse(if_else) => self.compile_if_else(slot, if_else), @@ -422,7 +422,8 @@ impl Compiler { for ident in inherit.idents() { count += 1; - // First emit the identifier itself + // First emit the identifier itself (this + // becomes the new key). self.emit_literal_ident(&ident); // Then emit the node that we're inheriting @@ -434,6 +435,7 @@ impl Compiler { // than pushing/popping the same attrs // potentially a lot of times. self.compile(slot, from.expr().unwrap()); + self.emit_force(); self.emit_literal_ident(&ident); self.chunk().push_op(OpCode::OpAttrsSelect); } @@ -494,6 +496,7 @@ impl Compiler { // Push the set onto the stack self.compile(slot, set); + self.emit_force(); // Compile each key fragment and emit access instructions. // @@ -542,6 +545,7 @@ impl Compiler { default: ast::Expr, ) { self.compile(slot, set); + self.emit_force(); let mut jumps = vec![]; for fragment in path.attrs() { @@ -645,6 +649,8 @@ impl Compiler { Some(from) => { for ident in inherit.idents() { self.compile(slot, from.expr().unwrap()); + self.emit_force(); + self.emit_literal_ident(&ident); self.chunk().push_op(OpCode::OpAttrsSelect); let idx = self.declare_local( @@ -788,6 +794,8 @@ impl Compiler { // resolve that directly (thus avoiding duplication on the // stack). self.compile(slot, node.namespace().unwrap()); + self.emit_force(); + let local_idx = self.scope_mut().declare_phantom(); let with_idx = self.scope().stack_index(local_idx); |