Do not construct function pointer for invalid function names.
This commit is contained in:
parent
d36e2d22d1
commit
5003d836d9
@ -10,13 +10,14 @@ use crate::func::hashing::get_hasher;
|
|||||||
use crate::tokenizer::Token;
|
use crate::tokenizer::Token;
|
||||||
use crate::types::dynamic::AccessMode;
|
use crate::types::dynamic::AccessMode;
|
||||||
use crate::{
|
use crate::{
|
||||||
calc_fn_hash, calc_fn_params_hash, combine_hashes, Dynamic, Engine, FnPtr, ImmutableString,
|
calc_fn_hash, calc_fn_params_hash, combine_hashes, Dynamic, Engine, FnPtr, Position, Scope,
|
||||||
Position, Scope, StaticVec, AST,
|
StaticVec, AST,
|
||||||
};
|
};
|
||||||
#[cfg(feature = "no_std")]
|
#[cfg(feature = "no_std")]
|
||||||
use std::prelude::v1::*;
|
use std::prelude::v1::*;
|
||||||
use std::{
|
use std::{
|
||||||
any::TypeId,
|
any::TypeId,
|
||||||
|
convert::TryFrom,
|
||||||
hash::{Hash, Hasher},
|
hash::{Hash, Hasher},
|
||||||
mem,
|
mem,
|
||||||
ops::DerefMut,
|
ops::DerefMut,
|
||||||
@ -902,7 +903,10 @@ fn optimize_expr(expr: &mut Expr, state: &mut OptimizerState, chaining: bool) {
|
|||||||
*expr = mem::take(lhs);
|
*expr = mem::take(lhs);
|
||||||
}
|
}
|
||||||
// lhs && rhs
|
// lhs && rhs
|
||||||
(lhs, rhs) => { optimize_expr(lhs, state, false); optimize_expr(rhs, state, false); }
|
(lhs, rhs) => {
|
||||||
|
optimize_expr(lhs, state, false);
|
||||||
|
optimize_expr(rhs, state, false);
|
||||||
|
}
|
||||||
},
|
},
|
||||||
// lhs || rhs
|
// lhs || rhs
|
||||||
Expr::Or(ref mut x, _) => match (&mut x.lhs, &mut x.rhs) {
|
Expr::Or(ref mut x, _) => match (&mut x.lhs, &mut x.rhs) {
|
||||||
@ -924,7 +928,10 @@ fn optimize_expr(expr: &mut Expr, state: &mut OptimizerState, chaining: bool) {
|
|||||||
*expr = mem::take(lhs);
|
*expr = mem::take(lhs);
|
||||||
}
|
}
|
||||||
// lhs || rhs
|
// lhs || rhs
|
||||||
(lhs, rhs) => { optimize_expr(lhs, state, false); optimize_expr(rhs, state, false); }
|
(lhs, rhs) => {
|
||||||
|
optimize_expr(lhs, state, false);
|
||||||
|
optimize_expr(rhs, state, false);
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
// eval!
|
// eval!
|
||||||
@ -936,24 +943,20 @@ fn optimize_expr(expr: &mut Expr, state: &mut OptimizerState, chaining: bool) {
|
|||||||
if !x.is_qualified() // Non-qualified
|
if !x.is_qualified() // Non-qualified
|
||||||
&& state.optimization_level == OptimizationLevel::Simple // simple optimizations
|
&& state.optimization_level == OptimizationLevel::Simple // simple optimizations
|
||||||
&& x.args.len() == 1
|
&& x.args.len() == 1
|
||||||
&& x.args[0].is_constant()
|
|
||||||
&& x.name == KEYWORD_FN_PTR
|
&& x.name == KEYWORD_FN_PTR
|
||||||
|
&& x.args[0].is_constant()
|
||||||
=> {
|
=> {
|
||||||
let fn_name = match x.args[0] {
|
let fn_name = match x.args[0] {
|
||||||
Expr::Stack(slot, _) => Some(x.constants[slot].clone()),
|
Expr::Stack(slot, _) => x.constants[slot].clone(),
|
||||||
Expr::StringConstant(ref s, _) => Some(s.clone().into()),
|
Expr::StringConstant(ref s, _) => s.clone().into(),
|
||||||
_ => None
|
_ => Dynamic::UNIT
|
||||||
};
|
};
|
||||||
|
|
||||||
if let Some(fn_name) = fn_name {
|
if let Ok(fn_ptr) = fn_name.into_immutable_string().map_err(|err| err.into()).and_then(FnPtr::try_from) {
|
||||||
if fn_name.is::<ImmutableString>() {
|
|
||||||
state.set_dirty();
|
state.set_dirty();
|
||||||
let fn_ptr = FnPtr::new_unchecked(
|
|
||||||
fn_name.as_str_ref().expect("`ImmutableString`").into(),
|
|
||||||
StaticVec::new_const()
|
|
||||||
);
|
|
||||||
*expr = Expr::DynamicConstant(Box::new(fn_ptr.into()), *pos);
|
*expr = Expr::DynamicConstant(Box::new(fn_ptr.into()), *pos);
|
||||||
}
|
} else {
|
||||||
|
optimize_expr(&mut x.args[0], state, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user