From 6eef11123a43391dc56d9568647bcfa192d362f2 Mon Sep 17 00:00:00 2001 From: Stephen Chung Date: Wed, 21 Sep 2022 18:30:12 +0800 Subject: [PATCH] Do not search for global functions if scripted. --- src/eval/stmt.rs | 2 +- src/func/call.rs | 26 ++++++++++++++------------ src/func/script.rs | 2 +- src/module/mod.rs | 24 +++++++++++------------- src/optimizer.rs | 2 +- 5 files changed, 28 insertions(+), 28 deletions(-) diff --git a/src/eval/stmt.rs b/src/eval/stmt.rs index 75d56a04..a176b670 100644 --- a/src/eval/stmt.rs +++ b/src/eval/stmt.rs @@ -865,7 +865,7 @@ impl Engine { #[cfg(not(feature = "no_module"))] if global.scope_level == 0 && 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( || { diff --git a/src/func/call.rs b/src/func/call.rs index a09bd70d..e91d63a8 100644 --- a/src/func/call.rs +++ b/src/func/call.rs @@ -215,19 +215,21 @@ impl Engine { loop { let func = lib .iter() - .find_map(|&m| m.get_fn(hash).map(|f| (f, m.id()))) - .or_else(|| { - self.global_modules - .iter() - .find_map(|m| m.get_fn(hash).map(|f| (f, m.id()))) - }); + .copied() + .chain(self.global_modules.iter().map(|m| m.as_ref())) + .find_map(|m| m.get_fn(hash).map(|f| (f, m.id()))); #[cfg(not(feature = "no_module"))] - let func = func.or_else(|| _global.get_qualified_fn(hash)).or_else(|| { - self.global_sub_modules - .values() - .find_map(|m| m.get_qualified_fn(hash).map(|f| (f, m.id()))) - }); + 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 + .values() + .find_map(|m| m.get_qualified_fn(hash).map(|f| (f, m.id()))) + }) + }; if let Some((f, s)) = func { // Specific version found @@ -247,7 +249,7 @@ impl Engine { // Check `Dynamic` parameters for functions with parameters 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 .global_modules .iter() diff --git a/src/func/script.rs b/src/func/script.rs index 8309c6ba..8ccc876b 100644 --- a/src/func/script.rs +++ b/src/func/script.rs @@ -240,7 +240,7 @@ impl Engine { } // 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 || self.global_modules.iter().any(|m| m.contains_fn(hash_script)); diff --git a/src/module/mod.rs b/src/module/mod.rs index ccee905d..a07a82d3 100644 --- a/src/module/mod.rs +++ b/src/module/mod.rs @@ -182,8 +182,8 @@ pub struct Module { /// Flattened collection of all functions, native Rust and scripted. /// including those in sub-modules. all_functions: Option>, - /// Native Rust functions (in scripted hash format) that contain [`Dynamic`] parameters. - dynamic_functions: BloomFilterU64, + /// Bloom filter on native Rust functions (in scripted hash format) that contain [`Dynamic`] parameters. + dynamic_functions_filter: BloomFilterU64, /// Iterator functions, keyed by the type producing the iterator. type_iterators: Option>>, /// Flattened collection of iterator functions, including those in sub-modules. @@ -300,7 +300,7 @@ impl Module { all_variables: None, functions: StraightHashMap::with_capacity_and_hasher(capacity, Default::default()), all_functions: None, - dynamic_functions: BloomFilterU64::new(), + dynamic_functions_filter: BloomFilterU64::new(), type_iterators: None, all_type_iterators: None, indexed: true, @@ -442,7 +442,7 @@ impl Module { self.all_variables = None; self.functions.clear(); self.all_functions = None; - self.dynamic_functions.clear(); + self.dynamic_functions_filter.clear(); self.type_iterators = None; self.all_type_iterators = None; self.indexed = false; @@ -1026,7 +1026,7 @@ impl Module { let hash_fn = combine_hashes(hash_script, hash_params); if is_dynamic { - self.dynamic_functions.mark(hash_script); + self.dynamic_functions_filter.mark(hash_script); } self.functions.insert( @@ -1547,7 +1547,7 @@ impl Module { #[inline(always)] #[must_use] 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`]? @@ -1592,7 +1592,7 @@ impl Module { None => self.variables = other.variables, } 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 { Some(ref mut m) if other.type_iterators.is_some() => { m.extend(other.type_iterators.unwrap().into_iter()) @@ -1635,7 +1635,7 @@ impl Module { None => self.variables = other.variables, } 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 { Some(ref mut m) if other.type_iterators.is_some() => { m.extend(other.type_iterators.unwrap().into_iter()) @@ -1685,7 +1685,7 @@ impl Module { for (&k, v) in &other.functions { 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 { let t = self .type_iterators @@ -1761,7 +1761,7 @@ impl Module { }) .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 mut t) = self.type_iterators { @@ -1805,7 +1805,7 @@ impl Module { }) .collect(); - self.dynamic_functions.clear(); + self.dynamic_functions_filter.clear(); self.all_functions = None; self.all_variables = None; self.all_type_iterators = None; @@ -2136,7 +2136,6 @@ impl Module { if let Some(ref t) = module.type_iterators { for (&type_id, func) in t { type_iterators.insert(type_id, func.clone()); - contains_indexed_global_functions = true; } } @@ -2249,7 +2248,6 @@ impl Module { self.all_type_iterators .get_or_insert_with(|| Default::default()) .insert(type_id, func.clone()); - self.contains_indexed_global_functions = true; } self.type_iterators .get_or_insert_with(|| Default::default()) diff --git a/src/optimizer.rs b/src/optimizer.rs index 86739689..b9a4dd97 100644 --- a/src/optimizer.rs +++ b/src/optimizer.rs @@ -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) #[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")] let has_script_fn = false;