feat: less clone, avoid evaluating not depended thunk
This commit is contained in:
@@ -1,15 +1,15 @@
|
||||
use std::rc::Rc;
|
||||
|
||||
use crate::env::VmEnv;
|
||||
use crate::env::Env;
|
||||
|
||||
use crate::ir;
|
||||
pub struct Func<'gc> {
|
||||
pub func: &'gc ir::Func,
|
||||
pub env: Rc<VmEnv>,
|
||||
pub env: Rc<Env>,
|
||||
}
|
||||
|
||||
impl<'gc> Func<'gc> {
|
||||
pub fn new(func: &'gc ir::Func, env: Rc<VmEnv>) -> Self {
|
||||
pub fn new(func: &'gc ir::Func, env: Rc<Env>) -> Self {
|
||||
Self { func, env }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@ use ecow::EcoVec;
|
||||
use hashbrown::HashSet;
|
||||
|
||||
use crate::engine::Engine;
|
||||
use crate::env::VmEnv;
|
||||
use crate::env::Env;
|
||||
use crate::ty::public as p;
|
||||
|
||||
use super::Value;
|
||||
|
||||
@@ -10,7 +10,7 @@ use super::common::*;
|
||||
use super::public as p;
|
||||
|
||||
use crate::engine::Engine;
|
||||
use crate::env::{VmEnv, VmEnvWeak};
|
||||
use crate::env::{Env, VmEnvWeak};
|
||||
use crate::error::*;
|
||||
|
||||
mod attrset;
|
||||
@@ -23,45 +23,6 @@ pub use attrset::*;
|
||||
pub use list::List;
|
||||
pub use primop::*;
|
||||
|
||||
#[derive(Clone)]
|
||||
pub enum EnvRef {
|
||||
Strong(VmEnv),
|
||||
Weak(VmEnvWeak),
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct ThunkRef {
|
||||
pub idx: usize,
|
||||
// pub env: Option<EnvRef>,
|
||||
}
|
||||
|
||||
impl ThunkRef {
|
||||
pub fn new(idx: usize) -> Self {
|
||||
ThunkRef {
|
||||
idx, /* env: None */
|
||||
}
|
||||
}
|
||||
/*
|
||||
pub fn capture(&mut self, env: EnvRef) {
|
||||
let _ = self.env.insert(env);
|
||||
}
|
||||
|
||||
pub fn upgrade(&mut self) {
|
||||
replace_with_or_abort(&mut self.env, |env| {
|
||||
env.map(|env| EnvRef::Strong(env.upgraded()))
|
||||
});
|
||||
} */
|
||||
}
|
||||
/*
|
||||
impl EnvRef {
|
||||
pub fn upgraded(self) -> VmEnv {
|
||||
match self {
|
||||
EnvRef::Weak(weak) => weak.upgrade(),
|
||||
EnvRef::Strong(strong) => strong,
|
||||
}
|
||||
}
|
||||
} */
|
||||
|
||||
#[derive(IsVariant, Unwrap, Clone, Debug)]
|
||||
pub enum Value {
|
||||
Int(i64),
|
||||
@@ -69,7 +30,7 @@ pub enum Value {
|
||||
Bool(bool),
|
||||
String(EcoString),
|
||||
Null,
|
||||
Thunk(ThunkRef),
|
||||
Thunk(usize),
|
||||
AttrSet(Rc<AttrSet>),
|
||||
List(List),
|
||||
Catchable(EcoString),
|
||||
@@ -129,7 +90,7 @@ pub enum ValueAsRef<'v> {
|
||||
Bool(bool),
|
||||
String(&'v EcoString),
|
||||
Null,
|
||||
Thunk(&'v ThunkRef),
|
||||
Thunk(usize),
|
||||
AttrSet(&'v AttrSet),
|
||||
List(&'v List),
|
||||
Catchable(&'v str),
|
||||
@@ -149,7 +110,7 @@ impl Value {
|
||||
Bool(x) => R::Bool(*x),
|
||||
String(x) => R::String(x),
|
||||
Null => R::Null,
|
||||
Thunk(x) => R::Thunk(x),
|
||||
Thunk(x) => R::Thunk(*x),
|
||||
AttrSet(x) => R::AttrSet(x),
|
||||
List(x) => R::List(x),
|
||||
Catchable(x) => R::Catchable(x),
|
||||
@@ -192,7 +153,7 @@ impl Value {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn call(&mut self, args: Vec<Self>, engine: &mut Engine, env: &mut VmEnv) -> Result<()> {
|
||||
pub fn call(&mut self, args: Vec<Self>, engine: &mut Engine, env: &mut Env) -> Result<()> {
|
||||
use Value::*;
|
||||
for arg in args.iter() {
|
||||
if matches!(arg, Value::Catchable(_)) {
|
||||
@@ -206,6 +167,7 @@ impl Value {
|
||||
PartialFunc(idx, old) => {
|
||||
let idx = *idx;
|
||||
let len = args.len() + old.len();
|
||||
env.reserve_args(len);
|
||||
env.enter_args(std::mem::take(old));
|
||||
env.enter_cache_level(|env| {
|
||||
let mut args = args.into_iter().peekable();
|
||||
@@ -240,6 +202,7 @@ impl Value {
|
||||
&mut Func(idx) => {
|
||||
let len = args.len();
|
||||
let mut args = args.into_iter().peekable();
|
||||
env.reserve_args(len);
|
||||
env.enter_cache_level(|env| {
|
||||
env.enter_arg(args.next().unwrap());
|
||||
let mut ret = engine.eval_thunk(idx, env)?;
|
||||
@@ -510,18 +473,9 @@ impl Value {
|
||||
self
|
||||
}
|
||||
|
||||
pub fn force(&mut self, engine: &mut Engine, env: &mut VmEnv) -> Result<&mut Self> {
|
||||
if let Value::Thunk(thunk) = self {
|
||||
unsafe {
|
||||
let old = std::ptr::read(thunk);
|
||||
match env.lookup_cache(old.idx, |env| engine.eval_thunk(old.idx, env)) {
|
||||
Ok(ok) => std::ptr::write(self, ok),
|
||||
Err(err) => {
|
||||
std::ptr::write(self, Self::Null);
|
||||
return Err(err);
|
||||
}
|
||||
}
|
||||
}
|
||||
pub fn force(&mut self, engine: &mut Engine, env: &mut Env) -> Result<&mut Self> {
|
||||
if let &mut Value::Thunk(idx) = self {
|
||||
*self = env.lookup_cache(idx, |env| engine.eval_thunk(idx, env))?
|
||||
}
|
||||
Ok(self)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user