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