difftreelog
perf switch to external storage for object comp
in: master
1 file changed
crates/jrsonnet-evaluator/src/evaluate.rsdiffbeforeafterboth1use crate::{1use crate::{2 error::Error::*, lazy_val, push, throw, with_state, Context, ContextCreator, FuncDesc, FuncVal,2 equals, error::Error::*, lazy_val, push, throw, with_state, ArrValue, Context, ContextCreator,3 FutureWrapper, LazyBinding, LazyVal, ObjMember, ObjValue, Result, Val,3 FuncDesc, FuncVal, FutureWrapper, LazyBinding, LazyVal, ObjMember, ObjValue, Result, Val,4 equals,5};4};6use closure::closure;5use closure::closure;7use jrsonnet_interner::IStr;6use jrsonnet_interner::IStr;209 })208 })210}209}211210212pub fn evaluate_comp<T>(211pub fn evaluate_comp(213 context: Context,212 context: Context,213 specs: &[CompSpec],214 value: &impl Fn(Context) -> Result<T>,214 callback: &mut impl FnMut(Context) -> Result<()>,215 specs: &[CompSpec],216) -> Result<Option<Vec<T>>> {215) -> Result<()> {217 Ok(match specs.get(0) {216 match specs.get(0) {218 None => Some(vec![value(context)?]),217 None => callback(context)?,219 Some(CompSpec::IfSpec(IfSpecData(cond))) => {218 Some(CompSpec::IfSpec(IfSpecData(cond))) => {220 if evaluate(context.clone(), cond)?.try_cast_bool("if spec")? {219 if evaluate(context.clone(), cond)?.try_cast_bool("if spec")? {221 evaluate_comp(context, value, &specs[1..])?220 evaluate_comp(context, &specs[1..], callback)?222 } else {221 }223 None224 }225 }222 }226 Some(CompSpec::ForSpec(ForSpecData(var, expr))) => match evaluate(context.clone(), expr)? {223 Some(CompSpec::ForSpec(ForSpecData(var, expr))) => match evaluate(context.clone(), expr)? {227 Val::Arr(list) => {224 Val::Arr(list) => {228 let mut out = Vec::new();229 for item in list.iter() {225 for item in list.iter() {230 out.push(evaluate_comp(226 evaluate_comp(231 context.clone().with_var(var.clone(), item?.clone()),227 context.clone().with_var(var.clone(), item?.clone()),232 value,233 &specs[1..],228 &specs[1..],229 callback,234 )?);230 )?235 }231 }236 Some(out.into_iter().flatten().flatten().collect())237 }232 }238 _ => throw!(InComprehensionCanOnlyIterateOverArray),233 _ => throw!(InComprehensionCanOnlyIterateOverArray),239 },234 },240 })235 }236 Ok(())241}237}242238243pub fn evaluate_member_list_object(context: Context, members: &[Member]) -> Result<ObjValue> {239pub fn evaluate_member_list_object(context: Context, members: &[Member]) -> Result<ObjValue> {342 ObjBody::ObjComp(obj) => {338 ObjBody::ObjComp(obj) => {343 let future_this = FutureWrapper::new();339 let future_this = FutureWrapper::new();344 let mut new_members = FxHashMap::default();340 let mut new_members = FxHashMap::default();345 for (k, v) in evaluate_comp(341 evaluate_comp(context.clone(), &obj.compspecs, &mut |ctx| {346 context.clone(),347 &|ctx| {348 let new_bindings = FutureWrapper::new();342 let new_bindings = FutureWrapper::new();360 let ctx = ctx.extend_unbound(bindings, None, None, None)?;358 let ctx = ctx.extend_unbound(bindings, None, None, None)?;361 let key = evaluate(ctx.clone(), &obj.key)?;359 let key = evaluate(ctx.clone(), &obj.key)?;360361 match key {362 Val::Null => {}363 Val::Str(n) => {364 new_members.insert(365 n,366 ObjMember {367 add: false,368 visibility: Visibility::Normal,362 let value = LazyBinding::Bindable(Rc::new(369 invoke: LazyBinding::Bindable(Rc::new(363 closure!(clone ctx, clone obj.value, |this, _super_obj| {370 closure!(clone ctx, clone obj.value, |this, _super_obj| {364 Ok(LazyVal::new_resolved(evaluate(ctx.clone().extend(FxHashMap::default(), None, this, None), &value)?))371 Ok(LazyVal::new_resolved(evaluate(ctx.clone().extend(FxHashMap::default(), None, this, None), &value)?))365 }),372 }),366 ));373 )),374 location: obj.value.1.clone(),375 },376 );377 }378 v => throw!(FieldMustBeStringGot(v.value_type())),379 }367380368 Ok((key, value))381 Ok(())369 },382 })?;370 &obj.compspecs,371 )?372 .unwrap()373 {374 match k {382 invoke: v,383 location: obj.value.1.clone(),384 },385 );386 }387 v => throw!(FieldMustBeStringGot(v.value_type())),388 }389 }390383391 let this = ObjValue::new(context, None, Rc::new(new_members), Rc::new(Vec::new()));384 let this = ObjValue::new(context, None, Rc::new(new_members), Rc::new(Vec::new()));392 future_this.fill(this.clone());385 future_this.fill(this.clone());567 }557 }568 Val::Arr(out.into())558 Val::Arr(out.into())569 }559 }570 ArrComp(expr, comp_specs) => Val::Arr(560 ArrComp(expr, comp_specs) => {571 // First comp_spec should be for_spec, so no "None" possible here561 let mut out = Vec::new();572 evaluate_comp(context, &|ctx| evaluate(ctx, expr), comp_specs)?562 evaluate_comp(context, comp_specs, &mut |ctx| {573 .unwrap()563 out.push(evaluate(ctx, expr)?);574 .into(),564 Ok(())575 ),565 })?;566 Val::Arr(ArrValue::Eager(Rc::new(out)))567 }576 Obj(body) => Val::Obj(evaluate_object(context, body)?),568 Obj(body) => Val::Obj(evaluate_object(context, body)?),577 ObjExtend(s, t) => evaluate_add_op(569 ObjExtend(s, t) => evaluate_add_op(578 &evaluate(context.clone(), s)?,570 &evaluate(context.clone(), s)?,