From f8575fcd747eb3fe05413611eb97e26981bc9e1b Mon Sep 17 00:00:00 2001 From: Vincent Ambo Date: Sat, 3 Sep 2022 03:06:20 +0300 Subject: fix(tvix/eval): compare *stack* slots when deciding whether to defer When deciding whether an upvalue needs to have a deferred resolution step, the *stack* indexes should be compared - not the locals indexes. The results are almost always the same, but there are tricky situations where this can cause errors. It's difficult to reproduce these errors in isolation, as they depend on other scope behaviour, so this is one in a series of commits to address the combination of issues which will gain some tests at the end. Change-Id: Iaa400b8d9500af58f493ab10e4f95022f3b5dd21 Reviewed-on: https://cl.tvl.fyi/c/depot/+/6423 Reviewed-by: sterni Tested-by: BuildkiteCI --- tvix/eval/src/compiler/mod.rs | 3 ++- tvix/eval/src/opcode.rs | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/tvix/eval/src/compiler/mod.rs b/tvix/eval/src/compiler/mod.rs index d02c0e69c5ca..68ff3d48a3df 100644 --- a/tvix/eval/src/compiler/mod.rs +++ b/tvix/eval/src/compiler/mod.rs @@ -969,6 +969,7 @@ impl Compiler<'_> { /// Emit the data instructions that the runtime needs to correctly /// assemble the provided upvalues array. fn emit_upvalue_data(&mut self, slot: LocalIdx, upvalues: Vec) { + let this_stack_slot = self.scope().stack_index(slot); for upvalue in upvalues { match upvalue.kind { UpvalueKind::Local(idx) => { @@ -978,7 +979,7 @@ impl Compiler<'_> { // closure, the upvalue resolution must be // deferred until the scope is fully initialised // and can be finalised. - if slot < idx { + if this_stack_slot < stack_idx { self.push_op(OpCode::DataDeferredLocal(stack_idx), &upvalue.node); self.scope_mut().mark_needs_finaliser(slot); } else { diff --git a/tvix/eval/src/opcode.rs b/tvix/eval/src/opcode.rs index b009686736bc..871111883ba4 100644 --- a/tvix/eval/src/opcode.rs +++ b/tvix/eval/src/opcode.rs @@ -13,7 +13,7 @@ pub struct CodeIdx(pub usize); /// Index of a value in the runtime stack. #[repr(transparent)] -#[derive(Clone, Copy, Debug, PartialEq, Eq)] +#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd)] pub struct StackIdx(pub usize); /// Index of an upvalue within a closure's upvalue list. -- cgit 1.4.1