Do not search for global functions if scripted.
This commit is contained in:
parent
5d275b5307
commit
6eef11123a
@ -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(
|
||||||
|| {
|
|| {
|
||||||
|
@ -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()
|
||||||
|
@ -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));
|
||||||
|
|
||||||
|
@ -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())
|
||||||
|
@ -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;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user