--- a/crates/jrsonnet-evaluator/src/evaluate.rs +++ b/crates/jrsonnet-evaluator/src/evaluate.rs @@ -786,7 +786,7 @@ .super_obj() .clone() .expect("no super found") - .get_raw(&name, &context.this().clone().expect("no this found"))? + .get_raw(name, &context.this().clone().expect("no this found"))? .expect("value not found") } Index(value, index) => { --- a/crates/jrsonnet-evaluator/src/obj.rs +++ b/crates/jrsonnet-evaluator/src/obj.rs @@ -15,7 +15,7 @@ pub struct ObjValueInternals { super_obj: Option, this_entries: Rc, ObjMember>>, - value_cache: RefCell, Val>>, + value_cache: RefCell, usize), Option>>, } #[derive(Clone)] pub struct ObjValue(pub(crate) Rc); @@ -96,19 +96,15 @@ visible_fields } pub fn get(&self, key: Rc) -> Result> { - if let Some(v) = self.0.value_cache.borrow().get(&key) { - return Ok(Some(v.clone())); - } - if let Some(v) = self.get_raw(&key, self)? { - let v = v.unwrap_if_lazy()?; - self.0.value_cache.borrow_mut().insert(key, v.clone()); - Ok(Some(v)) - } else { - Ok(None) - } + Ok(self.get_raw(key, self)?) } - pub(crate) fn get_raw(&self, key: &str, real_this: &ObjValue) -> Result> { - match (self.0.this_entries.get(key), &self.0.super_obj) { + pub(crate) fn get_raw(&self, key: Rc, real_this: &ObjValue) -> Result> { + let cache_key = (key.clone(), Rc::as_ptr(&real_this.0) as usize); + + if let Some(v) = self.0.value_cache.borrow().get(&cache_key) { + return Ok(v.clone()); + } + let value = match (self.0.this_entries.get(&key), &self.0.super_obj) { (Some(k), None) => Ok(Some(self.evaluate_this(k, real_this)?)), (Some(k), Some(s)) => { let our = self.evaluate_this(k, real_this)?; @@ -123,7 +119,12 @@ } (None, Some(s)) => s.get_raw(key, real_this), (None, None) => Ok(None), - } + }?; + self.0 + .value_cache + .borrow_mut() + .insert(cache_key, value.clone()); + Ok(value) } fn evaluate_this(&self, v: &ObjMember, real_this: &ObjValue) -> Result { Ok(v.invoke