--- a/crates/jrsonnet-evaluator/src/function/arglike.rs +++ b/crates/jrsonnet-evaluator/src/function/arglike.rs @@ -89,18 +89,6 @@ } } -// TODO: Is this implementation really required, as there is no Context to use? -// Maybe something a bit stricter is possible to add, especially with precompiled calls? -impl ArgLike for TlaArg { - fn evaluate_arg(&self, _ctx: Context, tailstrict: bool) -> Result> { - if tailstrict { - self.evaluate_tailstrict().map(Thunk::evaluated) - } else { - self.evaluate() - } - } -} - pub trait ArgsLike { fn unnamed_len(&self) -> usize; fn unnamed_iter( @@ -205,121 +193,5 @@ fn is_empty(&self) -> bool { self.unnamed.is_empty() && self.named.is_empty() - } -} - -impl ArgsLike for HashMap { - fn unnamed_len(&self) -> usize { - 0 - } - - fn unnamed_iter( - &self, - _ctx: Context, - _tailstrict: bool, - _handler: &mut dyn FnMut(usize, Thunk) -> Result<()>, - ) -> Result<()> { - Ok(()) - } - - fn named_iter( - &self, - ctx: Context, - tailstrict: bool, - handler: &mut dyn FnMut(&IStr, Thunk) -> Result<()>, - ) -> Result<()> { - for (name, value) in self { - handler(name, value.evaluate_arg(ctx.clone(), tailstrict)?)?; - } - Ok(()) - } - - fn named_names(&self, handler: &mut dyn FnMut(&IStr)) { - for name in self.keys() { - handler(name); - } - } - - fn is_empty(&self) -> bool { - self.is_empty() - } -} - -macro_rules! impl_args_like { - ($count:expr; $($gen:ident)*) => { - impl<$($gen: ArgLike,)*> ArgsLike for ($($gen,)*) { - fn unnamed_len(&self) -> usize { - $count - } - #[allow(non_snake_case, unused_assignments)] - fn unnamed_iter( - &self, - ctx: Context, - tailstrict: bool, - handler: &mut dyn FnMut(usize, Thunk) -> Result<()>, - ) -> Result<()> { - let mut i = 0usize; - let ($($gen,)*) = self; - $( - handler(i, $gen.evaluate_arg(ctx.clone(), tailstrict)?)?; - i+=1; - )* - Ok(()) - } - fn named_iter( - &self, - _ctx: Context, - _tailstrict: bool, - _handler: &mut dyn FnMut(&IStr, Thunk) -> Result<()>, - ) -> Result<()> { - Ok(()) - } - fn named_names(&self, _handler: &mut dyn FnMut(&IStr)) {} - - fn is_empty(&self) -> bool { - // impl_args_like only implements non-empty tuples. - false - } - } - }; - ($count:expr; $($cur:ident)* @ $c:ident $($rest:ident)*) => { - impl_args_like!($count; $($cur)*); - impl_args_like!($count + 1usize; $($cur)* $c @ $($rest)*); - }; - ($count:expr; $($cur:ident)* @) => { - impl_args_like!($count; $($cur)*); - } -} -impl_args_like! { - // First argument is already in position, so count starts from 1 - 1usize; A @ B C D E F G H I J K L -} - -impl ArgsLike for () { - fn unnamed_len(&self) -> usize { - 0 - } - - fn unnamed_iter( - &self, - _ctx: Context, - _tailstrict: bool, - _handler: &mut dyn FnMut(usize, Thunk) -> Result<()>, - ) -> Result<()> { - Ok(()) - } - - fn named_iter( - &self, - _ctx: Context, - _tailstrict: bool, - _handler: &mut dyn FnMut(&IStr, Thunk) -> Result<()>, - ) -> Result<()> { - Ok(()) - } - - fn named_names(&self, _handler: &mut dyn FnMut(&IStr)) {} - fn is_empty(&self) -> bool { - true } } --- a/crates/jrsonnet-evaluator/src/tla.rs +++ b/crates/jrsonnet-evaluator/src/tla.rs @@ -1,11 +1,10 @@ use std::{collections::HashMap, hash::BuildHasher}; use jrsonnet_interner::IStr; -use jrsonnet_parser::Source; use crate::{ - function::{CallLocation, TlaArg}, - in_description_frame, with_state, Result, Val, + function::{CallLocation, PreparedFuncVal, TlaArg}, + in_description_frame, Result, Val, }; pub fn apply_tla(args: &HashMap, val: Val) -> Result { @@ -13,17 +12,14 @@ in_description_frame( || "during TLA call".to_owned(), || { - func.evaluate( - with_state(|s| { - s.create_default_context(Source::new_virtual( - "".into(), - IStr::empty(), - )) - }), - CallLocation::native(), - args, - false, - ) + let mut names = Vec::with_capacity(args.len()); + let mut values = Vec::with_capacity(args.len()); + for (name, value) in args { + names.push(name.clone()); + values.push(value.evaluate()?); + } + let prepared = PreparedFuncVal::new(func, 0, &names)?; + prepared.call(CallLocation::native(), &[], &values) }, )? } else {