refactor(tvix/eval): introduce Upvalues struct in closures & thunks
This struct will be responsible for tracking upvalues (and is a convenient place to introduce optimisations for reducing value clones) instead of a plain value vector. The main motivation for this is that the upvalues will have to capture the `with`-stack fully and I want to avoid duplicating the logic for this between the two capturing types. Change-Id: I6654f8739fc2e04ca046e6667d4a015f51724e99 Reviewed-on: https://cl.tvl.fyi/c/depot/+/6485 Tested-by: BuildkiteCI Reviewed-by: sterni <sternenseemann@systemli.org>
This commit is contained in:
parent
6c9abc1f68
commit
d75b207a63
4 changed files with 65 additions and 30 deletions
|
@ -4,7 +4,10 @@ use std::{
|
|||
rc::Rc,
|
||||
};
|
||||
|
||||
use crate::{chunk::Chunk, upvalues::UpvalueCarrier, Value};
|
||||
use crate::{
|
||||
chunk::Chunk,
|
||||
upvalues::{UpvalueCarrier, Upvalues},
|
||||
};
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct Lambda {
|
||||
|
@ -30,7 +33,7 @@ impl Lambda {
|
|||
#[derive(Clone, Debug)]
|
||||
pub struct InnerClosure {
|
||||
pub lambda: Rc<Lambda>,
|
||||
pub upvalues: Vec<Value>,
|
||||
upvalues: Upvalues,
|
||||
}
|
||||
|
||||
#[repr(transparent)]
|
||||
|
@ -40,7 +43,7 @@ pub struct Closure(Rc<RefCell<InnerClosure>>);
|
|||
impl Closure {
|
||||
pub fn new(lambda: Rc<Lambda>) -> Self {
|
||||
Closure(Rc::new(RefCell::new(InnerClosure {
|
||||
upvalues: Vec::with_capacity(lambda.upvalue_count),
|
||||
upvalues: Upvalues::with_capacity(lambda.upvalue_count),
|
||||
lambda,
|
||||
})))
|
||||
}
|
||||
|
@ -59,11 +62,11 @@ impl UpvalueCarrier for Closure {
|
|||
self.0.borrow().lambda.upvalue_count
|
||||
}
|
||||
|
||||
fn upvalues(&self) -> Ref<'_, [Value]> {
|
||||
Ref::map(self.0.borrow(), |c| c.upvalues.as_slice())
|
||||
fn upvalues(&self) -> Ref<'_, Upvalues> {
|
||||
Ref::map(self.0.borrow(), |c| &c.upvalues)
|
||||
}
|
||||
|
||||
fn upvalues_mut(&self) -> RefMut<'_, Vec<Value>> {
|
||||
fn upvalues_mut(&self) -> RefMut<'_, Upvalues> {
|
||||
RefMut::map(self.0.borrow_mut(), |c| &mut c.upvalues)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -24,7 +24,12 @@ use std::{
|
|||
rc::Rc,
|
||||
};
|
||||
|
||||
use crate::{errors::ErrorKind, upvalues::UpvalueCarrier, vm::VM, Value};
|
||||
use crate::{
|
||||
errors::ErrorKind,
|
||||
upvalues::{UpvalueCarrier, Upvalues},
|
||||
vm::VM,
|
||||
Value,
|
||||
};
|
||||
|
||||
use super::Lambda;
|
||||
|
||||
|
@ -35,7 +40,7 @@ enum ThunkRepr {
|
|||
/// execution.
|
||||
Suspended {
|
||||
lambda: Rc<Lambda>,
|
||||
upvalues: Vec<Value>,
|
||||
upvalues: Upvalues,
|
||||
},
|
||||
|
||||
/// Thunk currently under-evaluation; encountering a blackhole
|
||||
|
@ -52,7 +57,7 @@ pub struct Thunk(Rc<RefCell<ThunkRepr>>);
|
|||
impl Thunk {
|
||||
pub fn new(lambda: Rc<Lambda>) -> Self {
|
||||
Thunk(Rc::new(RefCell::new(ThunkRepr::Suspended {
|
||||
upvalues: Vec::with_capacity(lambda.upvalue_count),
|
||||
upvalues: Upvalues::with_capacity(lambda.upvalue_count),
|
||||
lambda: lambda.clone(),
|
||||
})))
|
||||
}
|
||||
|
@ -119,14 +124,14 @@ impl UpvalueCarrier for Thunk {
|
|||
panic!("upvalues() on non-suspended thunk");
|
||||
}
|
||||
|
||||
fn upvalues(&self) -> Ref<'_, [Value]> {
|
||||
fn upvalues(&self) -> Ref<'_, Upvalues> {
|
||||
Ref::map(self.0.borrow(), |thunk| match thunk {
|
||||
ThunkRepr::Suspended { upvalues, .. } => upvalues.as_slice(),
|
||||
ThunkRepr::Suspended { upvalues, .. } => upvalues,
|
||||
_ => panic!("upvalues() on non-suspended thunk"),
|
||||
})
|
||||
}
|
||||
|
||||
fn upvalues_mut(&self) -> RefMut<'_, Vec<Value>> {
|
||||
fn upvalues_mut(&self) -> RefMut<'_, Upvalues> {
|
||||
RefMut::map(self.0.borrow_mut(), |thunk| match thunk {
|
||||
ThunkRepr::Suspended { upvalues, .. } => upvalues,
|
||||
_ => panic!("upvalues() on non-suspended thunk"),
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue