diff options
Diffstat (limited to 'tvix')
-rw-r--r-- | tvix/eval/src/compiler/attrs.rs | 62 | ||||
-rw-r--r-- | tvix/eval/src/compiler/mod.rs | 62 |
2 files changed, 62 insertions, 62 deletions
diff --git a/tvix/eval/src/compiler/attrs.rs b/tvix/eval/src/compiler/attrs.rs index db8410fcdb8b..b5ebfe23998f 100644 --- a/tvix/eval/src/compiler/attrs.rs +++ b/tvix/eval/src/compiler/attrs.rs @@ -20,6 +20,68 @@ impl Compiler<'_, '_> { } } + /// Compiles inherited values in an attribute set. Inherited + /// values are *always* inherited from the outer scope, even if + /// there is a matching name within a recursive attribute set. + fn compile_inherit_attrs( + &mut self, + slot: LocalIdx, + inherits: AstChildren<ast::Inherit>, + ) -> usize { + // Count the number of inherited values, so that the outer + // constructor can emit the correct number of pairs when + // constructing attribute sets. + let mut count = 0; + + for inherit in inherits { + match inherit.from() { + Some(from) => { + for ident in inherit.idents() { + count += 1; + + // First emit the identifier itself (this + // becomes the new key). + self.emit_literal_ident(&ident); + let ident_span = self.span_for(&ident); + self.scope_mut().declare_phantom(ident_span, true); + + // Then emit the node that we're inheriting + // from. + // + // TODO: Likely significant optimisation + // potential in having a multi-select + // instruction followed by a merge, rather + // than pushing/popping the same attrs + // potentially a lot of times. + let val_idx = self.scope_mut().declare_phantom(ident_span, false); + self.compile(val_idx, from.expr().unwrap()); + self.emit_force(&from.expr().unwrap()); + self.emit_literal_ident(&ident); + self.push_op(OpCode::OpAttrsSelect, &ident); + self.scope_mut().mark_initialised(val_idx); + } + } + + None => { + for ident in inherit.idents() { + let ident_span = self.span_for(&ident); + count += 1; + + // Emit the key to use for OpAttrs + self.emit_literal_ident(&ident); + self.scope_mut().declare_phantom(ident_span, true); + + // Emit the value. + self.compile_ident(slot, ident); + self.scope_mut().declare_phantom(ident_span, true); + } + } + } + } + + count + } + /// Compile the statically known entries of an attribute set. Which /// keys are which is not known from the iterator, so discovered /// dynamic keys are returned from here. diff --git a/tvix/eval/src/compiler/mod.rs b/tvix/eval/src/compiler/mod.rs index 4a5966ae83a8..cd8f46aec80f 100644 --- a/tvix/eval/src/compiler/mod.rs +++ b/tvix/eval/src/compiler/mod.rs @@ -476,68 +476,6 @@ impl Compiler<'_, '_> { self.scope_mut().end_scope(); } - /// Compiles inherited values in an attribute set. Inherited - /// values are *always* inherited from the outer scope, even if - /// there is a matching name within a recursive attribute set. - fn compile_inherit_attrs( - &mut self, - slot: LocalIdx, - inherits: AstChildren<ast::Inherit>, - ) -> usize { - // Count the number of inherited values, so that the outer - // constructor can emit the correct number of pairs when - // constructing attribute sets. - let mut count = 0; - - for inherit in inherits { - match inherit.from() { - Some(from) => { - for ident in inherit.idents() { - count += 1; - - // First emit the identifier itself (this - // becomes the new key). - self.emit_literal_ident(&ident); - let ident_span = self.span_for(&ident); - self.scope_mut().declare_phantom(ident_span, true); - - // Then emit the node that we're inheriting - // from. - // - // TODO: Likely significant optimisation - // potential in having a multi-select - // instruction followed by a merge, rather - // than pushing/popping the same attrs - // potentially a lot of times. - let val_idx = self.scope_mut().declare_phantom(ident_span, false); - self.compile(val_idx, from.expr().unwrap()); - self.emit_force(&from.expr().unwrap()); - self.emit_literal_ident(&ident); - self.push_op(OpCode::OpAttrsSelect, &ident); - self.scope_mut().mark_initialised(val_idx); - } - } - - None => { - for ident in inherit.idents() { - let ident_span = self.span_for(&ident); - count += 1; - - // Emit the key to use for OpAttrs - self.emit_literal_ident(&ident); - self.scope_mut().declare_phantom(ident_span, true); - - // Emit the value. - self.compile_ident(slot, ident); - self.scope_mut().declare_phantom(ident_span, true); - } - } - } - } - - count - } - fn compile_assert(&mut self, slot: LocalIdx, node: ast::Assert) { // Compile the assertion condition to leave its value on the stack. self.compile(slot, node.condition().unwrap()); |