refactor(tvix/eval): capture entire with_stack in upvalues

This completely rewrites the handling of "dynamic upvalues" to,
instead of resolving them at thunk/closure instantiation time (which
forces some values too early), capture the entire with stack of parent
contexts if it exists.

There are a couple of things in here that could be written more
efficiently, but I'm first working through this to get to a bug
related to with + recursion and the code complexity of some of the
optimisations is distracting.

Change-Id: Ia538e06c9146e3bf8decb9adf02dd726d2c651cf
Reviewed-on: https://cl.tvl.fyi/c/depot/+/6486
Tested-by: BuildkiteCI
Reviewed-by: sterni <sternenseemann@systemli.org>
This commit is contained in:
Vincent Ambo 2022-09-06 23:13:48 +03:00 committed by tazjin
parent d75b207a63
commit 07ea30370e
5 changed files with 122 additions and 148 deletions

View file

@ -16,12 +16,14 @@ use crate::{opcode::UpvalueIdx, Value};
#[derive(Clone, Debug)]
pub struct Upvalues {
upvalues: Vec<Value>,
with_stack: Option<Vec<Value>>,
}
impl Upvalues {
pub fn with_capacity(count: usize) -> Self {
Upvalues {
upvalues: Vec::with_capacity(count),
with_stack: None,
}
}
@ -29,6 +31,22 @@ impl Upvalues {
pub fn push(&mut self, value: Value) {
self.upvalues.push(value);
}
/// Set the captured with stack.
pub fn set_with_stack(&mut self, with_stack: Vec<Value>) {
self.with_stack = Some(with_stack);
}
pub fn with_stack(&self) -> Option<&Vec<Value>> {
self.with_stack.as_ref()
}
pub fn with_stack_len(&self) -> usize {
match &self.with_stack {
None => 0,
Some(stack) => stack.len(),
}
}
}
impl Index<UpvalueIdx> for Upvalues {