Do not search for global functions if scripted.

This commit is contained in:
Stephen Chung 2022-09-21 18:30:12 +08:00
parent 5d275b5307
commit 6eef11123a
5 changed files with 28 additions and 28 deletions

View File

@ -865,7 +865,7 @@ impl Engine {
#[cfg(not(feature = "no_module"))] #[cfg(not(feature = "no_module"))]
if global.scope_level == 0 if global.scope_level == 0
&& access == AccessMode::ReadOnly && access == AccessMode::ReadOnly
&& lib.iter().any(|&m| !m.is_empty()) && lib.iter().copied().any(Module::is_empty)
{ {
crate::func::locked_write(global.constants.get_or_insert_with( crate::func::locked_write(global.constants.get_or_insert_with(
|| { || {

View File

@ -215,19 +215,21 @@ impl Engine {
loop { loop {
let func = lib let func = lib
.iter() .iter()
.find_map(|&m| m.get_fn(hash).map(|f| (f, m.id()))) .copied()
.or_else(|| { .chain(self.global_modules.iter().map(|m| m.as_ref()))
self.global_modules .find_map(|m| m.get_fn(hash).map(|f| (f, m.id())));
.iter()
.find_map(|m| m.get_fn(hash).map(|f| (f, m.id())))
});
#[cfg(not(feature = "no_module"))] #[cfg(not(feature = "no_module"))]
let func = func.or_else(|| _global.get_qualified_fn(hash)).or_else(|| { let func = if args.is_none() {
// Scripted functions are not exposed globally
func
} else {
func.or_else(|| _global.get_qualified_fn(hash)).or_else(|| {
self.global_sub_modules self.global_sub_modules
.values() .values()
.find_map(|m| m.get_qualified_fn(hash).map(|f| (f, m.id()))) .find_map(|m| m.get_qualified_fn(hash).map(|f| (f, m.id())))
}); })
};
if let Some((f, s)) = func { if let Some((f, s)) = func {
// Specific version found // Specific version found
@ -247,7 +249,7 @@ impl Engine {
// Check `Dynamic` parameters for functions with parameters // Check `Dynamic` parameters for functions with parameters
if allow_dynamic && max_bitmask == 0 && num_args > 0 { if allow_dynamic && max_bitmask == 0 && num_args > 0 {
let is_dynamic = lib.iter().any(|&m| m.may_contain_dynamic_fn(hash_base)) let is_dynamic = lib.iter().any(|m| m.may_contain_dynamic_fn(hash_base))
|| self || self
.global_modules .global_modules
.iter() .iter()

View File

@ -240,7 +240,7 @@ impl Engine {
} }
// First check script-defined functions // First check script-defined functions
let result = lib.iter().any(|&m| m.contains_fn(hash_script)) let result = lib.iter().any(|m| m.contains_fn(hash_script))
// Then check the global namespace and packages // Then check the global namespace and packages
|| self.global_modules.iter().any(|m| m.contains_fn(hash_script)); || self.global_modules.iter().any(|m| m.contains_fn(hash_script));

View File

@ -182,8 +182,8 @@ pub struct Module {
/// Flattened collection of all functions, native Rust and scripted. /// Flattened collection of all functions, native Rust and scripted.
/// including those in sub-modules. /// including those in sub-modules.
all_functions: Option<StraightHashMap<CallableFunction>>, all_functions: Option<StraightHashMap<CallableFunction>>,
/// Native Rust functions (in scripted hash format) that contain [`Dynamic`] parameters. /// Bloom filter on native Rust functions (in scripted hash format) that contain [`Dynamic`] parameters.
dynamic_functions: BloomFilterU64, dynamic_functions_filter: BloomFilterU64,
/// Iterator functions, keyed by the type producing the iterator. /// Iterator functions, keyed by the type producing the iterator.
type_iterators: Option<BTreeMap<TypeId, Shared<IteratorFn>>>, type_iterators: Option<BTreeMap<TypeId, Shared<IteratorFn>>>,
/// Flattened collection of iterator functions, including those in sub-modules. /// Flattened collection of iterator functions, including those in sub-modules.
@ -300,7 +300,7 @@ impl Module {
all_variables: None, all_variables: None,
functions: StraightHashMap::with_capacity_and_hasher(capacity, Default::default()), functions: StraightHashMap::with_capacity_and_hasher(capacity, Default::default()),
all_functions: None, all_functions: None,
dynamic_functions: BloomFilterU64::new(), dynamic_functions_filter: BloomFilterU64::new(),
type_iterators: None, type_iterators: None,
all_type_iterators: None, all_type_iterators: None,
indexed: true, indexed: true,
@ -442,7 +442,7 @@ impl Module {
self.all_variables = None; self.all_variables = None;
self.functions.clear(); self.functions.clear();
self.all_functions = None; self.all_functions = None;
self.dynamic_functions.clear(); self.dynamic_functions_filter.clear();
self.type_iterators = None; self.type_iterators = None;
self.all_type_iterators = None; self.all_type_iterators = None;
self.indexed = false; self.indexed = false;
@ -1026,7 +1026,7 @@ impl Module {
let hash_fn = combine_hashes(hash_script, hash_params); let hash_fn = combine_hashes(hash_script, hash_params);
if is_dynamic { if is_dynamic {
self.dynamic_functions.mark(hash_script); self.dynamic_functions_filter.mark(hash_script);
} }
self.functions.insert( self.functions.insert(
@ -1547,7 +1547,7 @@ impl Module {
#[inline(always)] #[inline(always)]
#[must_use] #[must_use]
pub(crate) fn may_contain_dynamic_fn(&self, hash_script: u64) -> bool { pub(crate) fn may_contain_dynamic_fn(&self, hash_script: u64) -> bool {
!self.dynamic_functions.is_absent(hash_script) !self.dynamic_functions_filter.is_absent(hash_script)
} }
/// Does the particular namespace-qualified function exist in the [`Module`]? /// Does the particular namespace-qualified function exist in the [`Module`]?
@ -1592,7 +1592,7 @@ impl Module {
None => self.variables = other.variables, None => self.variables = other.variables,
} }
self.functions.extend(other.functions.into_iter()); self.functions.extend(other.functions.into_iter());
self.dynamic_functions += &other.dynamic_functions; self.dynamic_functions_filter += &other.dynamic_functions_filter;
match self.type_iterators { match self.type_iterators {
Some(ref mut m) if other.type_iterators.is_some() => { Some(ref mut m) if other.type_iterators.is_some() => {
m.extend(other.type_iterators.unwrap().into_iter()) m.extend(other.type_iterators.unwrap().into_iter())
@ -1635,7 +1635,7 @@ impl Module {
None => self.variables = other.variables, None => self.variables = other.variables,
} }
self.functions.extend(other.functions.into_iter()); self.functions.extend(other.functions.into_iter());
self.dynamic_functions += &other.dynamic_functions; self.dynamic_functions_filter += &other.dynamic_functions_filter;
match self.type_iterators { match self.type_iterators {
Some(ref mut m) if other.type_iterators.is_some() => { Some(ref mut m) if other.type_iterators.is_some() => {
m.extend(other.type_iterators.unwrap().into_iter()) m.extend(other.type_iterators.unwrap().into_iter())
@ -1685,7 +1685,7 @@ impl Module {
for (&k, v) in &other.functions { for (&k, v) in &other.functions {
self.functions.entry(k).or_insert_with(|| v.clone()); self.functions.entry(k).or_insert_with(|| v.clone());
} }
self.dynamic_functions += &other.dynamic_functions; self.dynamic_functions_filter += &other.dynamic_functions_filter;
if let Some(ref type_iterators) = other.type_iterators { if let Some(ref type_iterators) = other.type_iterators {
let t = self let t = self
.type_iterators .type_iterators
@ -1761,7 +1761,7 @@ impl Module {
}) })
.map(|(&k, v)| (k, v.clone())), .map(|(&k, v)| (k, v.clone())),
); );
self.dynamic_functions += &other.dynamic_functions; self.dynamic_functions_filter += &other.dynamic_functions_filter;
if let Some(ref type_iterators) = other.type_iterators { if let Some(ref type_iterators) = other.type_iterators {
if let Some(ref mut t) = self.type_iterators { if let Some(ref mut t) = self.type_iterators {
@ -1805,7 +1805,7 @@ impl Module {
}) })
.collect(); .collect();
self.dynamic_functions.clear(); self.dynamic_functions_filter.clear();
self.all_functions = None; self.all_functions = None;
self.all_variables = None; self.all_variables = None;
self.all_type_iterators = None; self.all_type_iterators = None;
@ -2136,7 +2136,6 @@ impl Module {
if let Some(ref t) = module.type_iterators { if let Some(ref t) = module.type_iterators {
for (&type_id, func) in t { for (&type_id, func) in t {
type_iterators.insert(type_id, func.clone()); type_iterators.insert(type_id, func.clone());
contains_indexed_global_functions = true;
} }
} }
@ -2249,7 +2248,6 @@ impl Module {
self.all_type_iterators self.all_type_iterators
.get_or_insert_with(|| Default::default()) .get_or_insert_with(|| Default::default())
.insert(type_id, func.clone()); .insert(type_id, func.clone());
self.contains_indexed_global_functions = true;
} }
self.type_iterators self.type_iterators
.get_or_insert_with(|| Default::default()) .get_or_insert_with(|| Default::default())

View File

@ -1229,7 +1229,7 @@ fn optimize_expr(expr: &mut Expr, state: &mut OptimizerState, _chaining: bool) {
=> { => {
// First search for script-defined functions (can override built-in) // First search for script-defined functions (can override built-in)
#[cfg(not(feature = "no_function"))] #[cfg(not(feature = "no_function"))]
let has_script_fn = state.lib.iter().any(|&m| m.get_script_fn(&x.name, x.args.len()).is_some()); let has_script_fn = state.lib.iter().copied().any(|m| m.get_script_fn(&x.name, x.args.len()).is_some());
#[cfg(feature = "no_function")] #[cfg(feature = "no_function")]
let has_script_fn = false; let has_script_fn = false;