Limit Dynamic parameters to 16.

This commit is contained in:
Stephen Chung 2021-02-24 22:40:18 +08:00
parent 37540fda12
commit baaa0461bf
3 changed files with 14 additions and 23 deletions

View File

@ -193,6 +193,8 @@ pub const MAX_EXPR_DEPTH: usize = 64;
#[cfg(not(debug_assertions))] #[cfg(not(debug_assertions))]
pub const MAX_FUNCTION_EXPR_DEPTH: usize = 32; pub const MAX_FUNCTION_EXPR_DEPTH: usize = 32;
pub const MAX_DYNAMIC_PARAMETERS: usize = 16;
pub const KEYWORD_PRINT: &str = "print"; pub const KEYWORD_PRINT: &str = "print";
pub const KEYWORD_DEBUG: &str = "debug"; pub const KEYWORD_DEBUG: &str = "debug";
pub const KEYWORD_TYPE_OF: &str = "type_of"; pub const KEYWORD_TYPE_OF: &str = "type_of";
@ -1679,9 +1681,7 @@ impl Engine {
let pos = rhs.position(); let pos = rhs.position();
if self if self
.call_native_fn( .call_native_fn(mods, state, lib, OP_EQUALS, hash_fn, args, false, pos)?
mods, state, lib, OP_EQUALS, hash_fn, args, false, false, pos,
)?
.0 .0
.as_bool() .as_bool()
.unwrap_or(false) .unwrap_or(false)
@ -1961,7 +1961,7 @@ impl Engine {
let hash_fn = let hash_fn =
calc_native_fn_hash(empty(), op, args.iter().map(|a| a.type_id())).unwrap(); calc_native_fn_hash(empty(), op, args.iter().map(|a| a.type_id())).unwrap();
match self.call_native_fn(mods, state, lib, op, hash_fn, args, true, false, op_pos) { match self.call_native_fn(mods, state, lib, op, hash_fn, args, true, op_pos) {
Ok(_) => (), Ok(_) => (),
Err(err) if matches!(err.as_ref(), EvalAltResult::ErrorFunctionNotFound(f, _) if f.starts_with(op)) => Err(err) if matches!(err.as_ref(), EvalAltResult::ErrorFunctionNotFound(f, _) if f.starts_with(op)) =>
{ {
@ -1971,8 +1971,8 @@ impl Engine {
calc_native_fn_hash(empty(), op, args.iter().map(|a| a.type_id())).unwrap(); calc_native_fn_hash(empty(), op, args.iter().map(|a| a.type_id())).unwrap();
// Run function // Run function
let (value, _) = self let (value, _) =
.call_native_fn(mods, state, lib, op, hash_fn, args, true, false, op_pos)?; self.call_native_fn(mods, state, lib, op, hash_fn, args, true, op_pos)?;
*args[0] = value.flatten(); *args[0] = value.flatten();
} }

View File

@ -4,6 +4,7 @@ use crate::ast::{Expr, Stmt};
use crate::engine::{ use crate::engine::{
search_imports, Imports, State, KEYWORD_DEBUG, KEYWORD_EVAL, KEYWORD_FN_PTR, search_imports, Imports, State, KEYWORD_DEBUG, KEYWORD_EVAL, KEYWORD_FN_PTR,
KEYWORD_FN_PTR_CALL, KEYWORD_FN_PTR_CURRY, KEYWORD_IS_DEF_VAR, KEYWORD_PRINT, KEYWORD_TYPE_OF, KEYWORD_FN_PTR_CALL, KEYWORD_FN_PTR_CURRY, KEYWORD_IS_DEF_VAR, KEYWORD_PRINT, KEYWORD_TYPE_OF,
MAX_DYNAMIC_PARAMETERS,
}; };
use crate::fn_native::FnCallArgs; use crate::fn_native::FnCallArgs;
use crate::module::NamespaceRef; use crate::module::NamespaceRef;
@ -172,7 +173,6 @@ impl Engine {
hash_fn: NonZeroU64, hash_fn: NonZeroU64,
args: &mut FnCallArgs, args: &mut FnCallArgs,
is_ref: bool, is_ref: bool,
pub_only: bool,
pos: Position, pos: Position,
) -> Result<(Dynamic, bool), Box<EvalAltResult>> { ) -> Result<(Dynamic, bool), Box<EvalAltResult>> {
self.inc_operations(state, pos)?; self.inc_operations(state, pos)?;
@ -185,14 +185,15 @@ impl Engine {
.entry(hash_fn) .entry(hash_fn)
.or_insert_with(|| { .or_insert_with(|| {
let num_args = args.len(); let num_args = args.len();
let max_bitmask = 1usize << args.len().min(MAX_DYNAMIC_PARAMETERS);
let mut hash = hash_fn; let mut hash = hash_fn;
let mut bitmask = 1usize; // Bitmask of which parameter to replace with `Dynamic` let mut bitmask = 1usize; // Bitmask of which parameter to replace with `Dynamic`
loop { loop {
//lib.get_fn(hash, pub_only).or_else(|| //lib.get_fn(hash, false).or_else(||
match self match self
.global_namespace .global_namespace
.get_fn(hash, pub_only) .get_fn(hash, false)
.cloned() .cloned()
.map(|f| (f, None)) .map(|f| (f, None))
.or_else(|| { .or_else(|| {
@ -208,8 +209,8 @@ impl Engine {
// Specific version found // Specific version found
Some(f) => return Some(f), Some(f) => return Some(f),
// No parameters // Stop when all permutations are exhausted
_ if num_args == 0 => return None, _ if bitmask >= max_bitmask => return None,
// Try all permutations with `Dynamic` wildcards // Try all permutations with `Dynamic` wildcards
_ => { _ => {
@ -228,11 +229,6 @@ impl Engine {
) )
.unwrap(); .unwrap();
// Stop when all permutations are exhausted
if hash == hash_fn {
return None;
}
bitmask += 1; bitmask += 1;
} }
} }
@ -764,16 +760,12 @@ impl Engine {
Ok((result, false)) Ok((result, false))
} else { } else {
// Native function call // Native function call
self.call_native_fn( self.call_native_fn(mods, state, lib, fn_name, hash_fn, args, is_ref, pos)
mods, state, lib, fn_name, hash_fn, args, is_ref, pub_only, pos,
)
} }
} }
// Native function call // Native function call
_ => self.call_native_fn( _ => self.call_native_fn(mods, state, lib, fn_name, hash_fn, args, is_ref, pos),
mods, state, lib, fn_name, hash_fn, args, is_ref, pub_only, pos,
),
} }
} }

View File

@ -149,7 +149,6 @@ fn call_fn_with_constant_arguments(
hash_fn.unwrap(), hash_fn.unwrap(),
arg_values.iter_mut().collect::<StaticVec<_>>().as_mut(), arg_values.iter_mut().collect::<StaticVec<_>>().as_mut(),
false, false,
true,
Position::NONE, Position::NONE,
) )
.ok() .ok()