Do not call function when optimizing if there is a script-defined function overridding it.
This commit is contained in:
parent
36b7124dd5
commit
283602cdd8
@ -438,15 +438,19 @@ fn optimize_expr<'a>(expr: Expr, state: &mut State<'a>) -> Expr {
|
|||||||
|
|
||||||
// Do not optimize anything within built-in function keywords
|
// Do not optimize anything within built-in function keywords
|
||||||
Expr::FunctionCall(id, args, def_value, pos) if DONT_EVAL_KEYWORDS.contains(&id.as_str())=>
|
Expr::FunctionCall(id, args, def_value, pos) if DONT_EVAL_KEYWORDS.contains(&id.as_str())=>
|
||||||
Expr::FunctionCall(id,
|
Expr::FunctionCall(id, args.into_iter().map(|a| optimize_expr(a, state)).collect(), def_value, pos),
|
||||||
args.into_iter().map(|a| optimize_expr(a, state)).collect(),
|
|
||||||
def_value, pos),
|
|
||||||
|
|
||||||
// Eagerly call functions
|
// Eagerly call functions
|
||||||
Expr::FunctionCall(id, args, def_value, pos)
|
Expr::FunctionCall(id, args, def_value, pos)
|
||||||
if state.engine.optimization_level == OptimizationLevel::Full // full optimizations
|
if state.engine.optimization_level == OptimizationLevel::Full // full optimizations
|
||||||
&& args.iter().all(|expr| expr.is_constant()) // all arguments are constants
|
&& args.iter().all(|expr| expr.is_constant()) // all arguments are constants
|
||||||
=> {
|
=> {
|
||||||
|
// First search in script-defined functions (can override built-in)
|
||||||
|
if state.engine.script_functions.binary_search_by(|f| f.compare(&id, args.len())).is_ok() {
|
||||||
|
// A script-defined function overrides the built-in function - do not make the call
|
||||||
|
return Expr::FunctionCall(id, args.into_iter().map(|a| optimize_expr(a, state)).collect(), def_value, pos);
|
||||||
|
}
|
||||||
|
|
||||||
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 call_args: FnCallArgs = arg_values.iter_mut().map(Dynamic::as_mut).collect();
|
||||||
|
|
||||||
@ -477,19 +481,14 @@ fn optimize_expr<'a>(expr: Expr, state: &mut State<'a>) -> Expr {
|
|||||||
|
|
||||||
// id(args ..) -> optimize function call arguments
|
// id(args ..) -> optimize function call arguments
|
||||||
Expr::FunctionCall(id, args, def_value, pos) =>
|
Expr::FunctionCall(id, args, def_value, pos) =>
|
||||||
Expr::FunctionCall(id,
|
Expr::FunctionCall(id, args.into_iter().map(|a| optimize_expr(a, state)).collect(), def_value, pos),
|
||||||
args.into_iter().map(|a| optimize_expr(a, state)).collect(),
|
|
||||||
def_value, pos),
|
|
||||||
|
|
||||||
// constant-name
|
// constant-name
|
||||||
Expr::Variable(ref name, _) if state.contains_constant(name) => {
|
Expr::Variable(ref name, _) if state.contains_constant(name) => {
|
||||||
state.set_dirty();
|
state.set_dirty();
|
||||||
|
|
||||||
// Replace constant with value
|
// Replace constant with value
|
||||||
state
|
state.find_constant(name).expect("should find constant in scope!").clone()
|
||||||
.find_constant(name)
|
|
||||||
.expect("should find constant in scope!")
|
|
||||||
.clone()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// All other expressions - skip
|
// All other expressions - skip
|
||||||
|
Loading…
x
Reference in New Issue
Block a user