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:
parent
d75b207a63
commit
07ea30370e
5 changed files with 122 additions and 148 deletions
|
|
@ -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 {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue