diff --git a/src/engine.rs b/src/engine.rs index f99a47a3..fa928fce 100644 --- a/src/engine.rs +++ b/src/engine.rs @@ -25,9 +25,9 @@ use crate::stdlib::{ #[cfg(not(feature = "no_index"))] pub type Array = Vec; -pub type FnCallArgs<'a> = Vec<&'a mut Variant>; +pub type FnCallArgs<'a> = [&'a mut Variant]; -pub type FnAny = dyn Fn(FnCallArgs, Position) -> Result; +pub type FnAny = dyn Fn(&mut FnCallArgs, Position) -> Result; type IteratorFn = dyn Fn(&Dynamic) -> Box>; @@ -143,7 +143,7 @@ impl Engine<'_> { pub(crate) fn call_ext_fn_raw( &self, fn_name: &str, - args: FnCallArgs, + args: &mut FnCallArgs, pos: Position, ) -> Result, EvalAltResult> { let spec = FnSpec { @@ -165,7 +165,7 @@ impl Engine<'_> { pub(crate) fn call_fn_raw( &mut self, fn_name: &str, - args: FnCallArgs, + args: &mut FnCallArgs, def_val: Option<&Dynamic>, pos: Position, ) -> Result { @@ -255,11 +255,11 @@ impl Engine<'_> { } // Raise error - let types_list = args + let types_list: Vec<_> = args .iter() .map(|x| (*x).type_name()) .map(|name| self.map_type_name(name)) - .collect::>(); + .collect(); Err(EvalAltResult::ErrorFunctionNotFound( format!("{} ({})", fn_name, types_list.join(", ")), @@ -310,18 +310,18 @@ impl Engine<'_> { let this_ptr = get_this_ptr(scope, src, target); - let args = once(this_ptr) + let mut arg_values: Vec<_> = once(this_ptr) .chain(values.iter_mut().map(Dynamic::as_mut)) .collect(); - self.call_fn_raw(fn_name, args, def_val.as_ref(), *pos) + self.call_fn_raw(fn_name, &mut arg_values, def_val.as_ref(), *pos) } // xxx.id Expr::Property(id, pos) => { let get_fn_name = format!("{}{}", FUNC_GETTER, id); let this_ptr = get_this_ptr(scope, src, target); - self.call_fn_raw(&get_fn_name, vec![this_ptr], None, *pos) + self.call_fn_raw(&get_fn_name, &mut [this_ptr], None, *pos) } // xxx.idx_lhs[idx_expr] @@ -333,7 +333,7 @@ impl Engine<'_> { let get_fn_name = format!("{}{}", FUNC_GETTER, id); let this_ptr = get_this_ptr(scope, src, target); ( - self.call_fn_raw(&get_fn_name, vec![this_ptr], None, *pos)?, + self.call_fn_raw(&get_fn_name, &mut [this_ptr], None, *pos)?, *pos, ) } @@ -363,7 +363,7 @@ impl Engine<'_> { let get_fn_name = format!("{}{}", FUNC_GETTER, id); let this_ptr = get_this_ptr(scope, src, target); - self.call_fn_raw(&get_fn_name, vec![this_ptr], None, *pos) + self.call_fn_raw(&get_fn_name, &mut [this_ptr], None, *pos) .and_then(|mut v| { self.get_dot_val_helper(scope, None, Some(v.as_mut()), rhs) }) @@ -377,7 +377,7 @@ impl Engine<'_> { let get_fn_name = format!("{}{}", FUNC_GETTER, id); let this_ptr = get_this_ptr(scope, src, target); ( - self.call_fn_raw(&get_fn_name, vec![this_ptr], None, *pos)?, + self.call_fn_raw(&get_fn_name, &mut [this_ptr], None, *pos)?, *pos, ) } @@ -678,7 +678,12 @@ impl Engine<'_> { Expr::Property(id, pos) => { let set_fn_name = format!("{}{}", FUNC_SETTER, id); - self.call_fn_raw(&set_fn_name, vec![this_ptr, new_val.0.as_mut()], None, *pos) + self.call_fn_raw( + &set_fn_name, + &mut [this_ptr, new_val.0.as_mut()], + None, + *pos, + ) } // xxx.lhs[idx_expr] @@ -689,7 +694,7 @@ impl Engine<'_> { Expr::Property(id, pos) => { let get_fn_name = format!("{}{}", FUNC_GETTER, id); - self.call_fn_raw(&get_fn_name, vec![this_ptr], None, *pos) + self.call_fn_raw(&get_fn_name, &mut [this_ptr], None, *pos) .and_then(|v| { let idx = self.eval_index_value(scope, idx_expr)?; Self::update_indexed_value( @@ -701,7 +706,7 @@ impl Engine<'_> { }) .and_then(|mut v| { let set_fn_name = format!("{}{}", FUNC_SETTER, id); - self.call_fn_raw(&set_fn_name, vec![this_ptr, v.as_mut()], None, *pos) + self.call_fn_raw(&set_fn_name, &mut [this_ptr, v.as_mut()], None, *pos) }) } @@ -718,7 +723,7 @@ impl Engine<'_> { Expr::Property(id, pos) => { let get_fn_name = format!("{}{}", FUNC_GETTER, id); - self.call_fn_raw(&get_fn_name, vec![this_ptr], None, *pos) + self.call_fn_raw(&get_fn_name, &mut [this_ptr], None, *pos) .and_then(|mut v| { self.set_dot_val_helper(scope, v.as_mut(), rhs, new_val) .map(|_| v) // Discard Ok return value @@ -726,7 +731,7 @@ impl Engine<'_> { .and_then(|mut v| { let set_fn_name = format!("{}{}", FUNC_SETTER, id); - self.call_fn_raw(&set_fn_name, vec![this_ptr, v.as_mut()], None, *pos) + self.call_fn_raw(&set_fn_name, &mut [this_ptr, v.as_mut()], None, *pos) }) } @@ -738,7 +743,7 @@ impl Engine<'_> { Expr::Property(id, pos) => { let get_fn_name = format!("{}{}", FUNC_GETTER, id); - self.call_fn_raw(&get_fn_name, vec![this_ptr], None, *pos) + self.call_fn_raw(&get_fn_name, &mut [this_ptr], None, *pos) .and_then(|v| { let idx = self.eval_index_value(scope, idx_expr)?; let (mut target, _) = @@ -752,10 +757,9 @@ impl Engine<'_> { }) .and_then(|mut v| { let set_fn_name = format!("{}{}", FUNC_SETTER, id); - self.call_fn_raw( &set_fn_name, - vec![this_ptr, v.as_mut()], + &mut [this_ptr, v.as_mut()], None, *pos, ) @@ -1007,7 +1011,7 @@ impl Engine<'_> { // Redirect call to `print` self.call_fn_raw( KEYWORD_PRINT, - vec![result.into_dynamic().as_mut()], + &mut [result.into_dynamic().as_mut()], None, pos, ) @@ -1068,14 +1072,12 @@ impl Engine<'_> { let mut values = args_expr_list .iter() .map(|expr| self.eval_expr(scope, expr)) - .collect::, _>>()?; + .collect::, _>>()?; - self.call_fn_raw( - fn_name, - values.iter_mut().map(|b| b.as_mut()).collect(), - def_val.as_ref(), - *pos, - ) + let mut arg_values: Vec<_> = + values.iter_mut().map(Dynamic::as_mut).collect(); + + self.call_fn_raw(fn_name, &mut arg_values, def_val.as_ref(), *pos) } } } diff --git a/src/fn_register.rs b/src/fn_register.rs index 3152c428..acf0822d 100644 --- a/src/fn_register.rs +++ b/src/fn_register.rs @@ -145,7 +145,7 @@ macro_rules! def_register { fn register_fn(&mut self, name: &str, f: FN) { let fn_name = name.to_string(); - let fun = move |mut args: FnCallArgs, pos: Position| { + let fun = move |args: &mut FnCallArgs, pos: Position| { // Check for length at the beginning to avoid per-element bound checks. const NUM_ARGS: usize = count_args!($($par)*); @@ -154,7 +154,7 @@ macro_rules! def_register { } #[allow(unused_variables, unused_mut)] - let mut drain = args.drain(..); + let mut drain = args.iter_mut(); $( // Downcast every element, return in case of a type mismatch let $par = drain.next().unwrap().downcast_mut::<$par>().unwrap(); @@ -177,7 +177,7 @@ macro_rules! def_register { fn register_dynamic_fn(&mut self, name: &str, f: FN) { let fn_name = name.to_string(); - let fun = move |mut args: FnCallArgs, pos: Position| { + let fun = move |args: &mut FnCallArgs, pos: Position| { // Check for length at the beginning to avoid per-element bound checks. const NUM_ARGS: usize = count_args!($($par)*); @@ -186,7 +186,7 @@ macro_rules! def_register { } #[allow(unused_variables, unused_mut)] - let mut drain = args.drain(..); + let mut drain = args.iter_mut(); $( // Downcast every element, return in case of a type mismatch let $par = drain.next().unwrap().downcast_mut::<$par>().unwrap(); @@ -209,7 +209,7 @@ macro_rules! def_register { fn register_result_fn(&mut self, name: &str, f: FN) { let fn_name = name.to_string(); - let fun = move |mut args: FnCallArgs, pos: Position| { + let fun = move |args: &mut FnCallArgs, pos: Position| { // Check for length at the beginning to avoid per-element bound checks. const NUM_ARGS: usize = count_args!($($par)*); @@ -218,7 +218,7 @@ macro_rules! def_register { } #[allow(unused_variables, unused_mut)] - let mut drain = args.drain(..); + let mut drain = args.iter_mut(); $( // Downcast every element, return in case of a type mismatch let $par = drain.next().unwrap().downcast_mut::<$par>().unwrap(); diff --git a/src/optimize.rs b/src/optimize.rs index 819df9c5..185fccc1 100644 --- a/src/optimize.rs +++ b/src/optimize.rs @@ -2,8 +2,7 @@ use crate::any::{Any, Dynamic}; use crate::engine::{ - Engine, FnCallArgs, KEYWORD_DEBUG, KEYWORD_DUMP_AST, KEYWORD_EVAL, KEYWORD_PRINT, - KEYWORD_TYPE_OF, + Engine, KEYWORD_DEBUG, KEYWORD_DUMP_AST, KEYWORD_EVAL, KEYWORD_PRINT, KEYWORD_TYPE_OF, }; use crate::parser::{map_dynamic_to_expr, Expr, FnDef, ReturnType, Stmt, AST}; use crate::scope::{Entry as ScopeEntry, EntryType as ScopeEntryType, Scope}; @@ -452,7 +451,7 @@ fn optimize_expr<'a>(expr: Expr, state: &mut State<'a>) -> Expr { } let mut arg_values: Vec<_> = args.iter().map(Expr::get_constant_value).collect(); - let call_args: FnCallArgs = arg_values.iter_mut().map(Dynamic::as_mut).collect(); + let mut call_args: Vec<_> = arg_values.iter_mut().map(Dynamic::as_mut).collect(); // Save the typename of the first argument if it is `type_of()` // This is to avoid `call_args` being passed into the closure @@ -462,7 +461,7 @@ fn optimize_expr<'a>(expr: Expr, state: &mut State<'a>) -> Expr { "" }; - state.engine.call_ext_fn_raw(&id, call_args, pos).ok().map(|r| + state.engine.call_ext_fn_raw(&id, &mut call_args, pos).ok().map(|r| r.or_else(|| { if !arg_for_type_of.is_empty() { // Handle `type_of()`