Calculate whether contains global functions during indexing.
This commit is contained in:
parent
4e5039d4fe
commit
65ef32af19
@ -1893,7 +1893,7 @@ impl Engine {
|
|||||||
if mods
|
if mods
|
||||||
.scan_raw()
|
.scan_raw()
|
||||||
.skip(_mods_len)
|
.skip(_mods_len)
|
||||||
.any(|(_, m)| m.has_namespace(crate::FnNamespace::Global, true))
|
.any(|(_, m)| m.contains_indexed_global_functions())
|
||||||
{
|
{
|
||||||
if _restore_fn_resolution_cache {
|
if _restore_fn_resolution_cache {
|
||||||
// When new module is imported with global functions and there is already
|
// When new module is imported with global functions and there is already
|
||||||
|
@ -188,42 +188,6 @@ impl Engine {
|
|||||||
allow_dynamic: bool,
|
allow_dynamic: bool,
|
||||||
is_op_assignment: bool,
|
is_op_assignment: bool,
|
||||||
) -> &'s Option<(CallableFunction, Option<ImmutableString>)> {
|
) -> &'s Option<(CallableFunction, Option<ImmutableString>)> {
|
||||||
fn find_function(
|
|
||||||
engine: &Engine,
|
|
||||||
hash: NonZeroU64,
|
|
||||||
mods: &Imports,
|
|
||||||
lib: &[&Module],
|
|
||||||
) -> Option<(CallableFunction, Option<ImmutableString>)> {
|
|
||||||
lib.iter()
|
|
||||||
.find_map(|m| {
|
|
||||||
m.get_fn(hash, false)
|
|
||||||
.map(|f| (f.clone(), m.id_raw().cloned()))
|
|
||||||
})
|
|
||||||
.or_else(|| {
|
|
||||||
engine
|
|
||||||
.global_namespace
|
|
||||||
.get_fn(hash, false)
|
|
||||||
.cloned()
|
|
||||||
.map(|f| (f, None))
|
|
||||||
})
|
|
||||||
.or_else(|| {
|
|
||||||
engine.global_modules.iter().find_map(|m| {
|
|
||||||
m.get_fn(hash, false)
|
|
||||||
.map(|f| (f.clone(), m.id_raw().cloned()))
|
|
||||||
})
|
|
||||||
})
|
|
||||||
.or_else(|| {
|
|
||||||
mods.get_fn(hash)
|
|
||||||
.map(|(f, source)| (f.clone(), source.cloned()))
|
|
||||||
})
|
|
||||||
.or_else(|| {
|
|
||||||
engine.global_sub_modules.values().find_map(|m| {
|
|
||||||
m.get_qualified_fn(hash)
|
|
||||||
.map(|f| (f.clone(), m.id_raw().cloned()))
|
|
||||||
})
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
&*state
|
&*state
|
||||||
.fn_resolution_cache_mut()
|
.fn_resolution_cache_mut()
|
||||||
.entry(hash)
|
.entry(hash)
|
||||||
@ -237,7 +201,36 @@ impl Engine {
|
|||||||
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 {
|
||||||
match find_function(self, hash, mods, lib) {
|
let func = lib
|
||||||
|
.iter()
|
||||||
|
.find_map(|m| {
|
||||||
|
m.get_fn(hash, false)
|
||||||
|
.map(|f| (f.clone(), m.id_raw().cloned()))
|
||||||
|
})
|
||||||
|
.or_else(|| {
|
||||||
|
self.global_namespace
|
||||||
|
.get_fn(hash, false)
|
||||||
|
.cloned()
|
||||||
|
.map(|f| (f, None))
|
||||||
|
})
|
||||||
|
.or_else(|| {
|
||||||
|
self.global_modules.iter().find_map(|m| {
|
||||||
|
m.get_fn(hash, false)
|
||||||
|
.map(|f| (f.clone(), m.id_raw().cloned()))
|
||||||
|
})
|
||||||
|
})
|
||||||
|
.or_else(|| {
|
||||||
|
mods.get_fn(hash)
|
||||||
|
.map(|(f, source)| (f.clone(), source.cloned()))
|
||||||
|
})
|
||||||
|
.or_else(|| {
|
||||||
|
self.global_sub_modules.values().find_map(|m| {
|
||||||
|
m.get_qualified_fn(hash)
|
||||||
|
.map(|f| (f.clone(), m.id_raw().cloned()))
|
||||||
|
})
|
||||||
|
});
|
||||||
|
|
||||||
|
match func {
|
||||||
// Specific version found
|
// Specific version found
|
||||||
Some(f) => return Some(f),
|
Some(f) => return Some(f),
|
||||||
|
|
||||||
@ -520,18 +513,16 @@ impl Engine {
|
|||||||
);
|
);
|
||||||
|
|
||||||
// Merge in encapsulated environment, if any
|
// Merge in encapsulated environment, if any
|
||||||
let mut lib_merged: StaticVec<_>;
|
let lib_merged;
|
||||||
let mut unified = false;
|
|
||||||
|
|
||||||
let unified_lib = if let Some(ref env_lib) = fn_def.lib {
|
let (unified_lib, unified) = if let Some(ref env_lib) = fn_def.lib {
|
||||||
unified = true;
|
|
||||||
state.push_fn_resolution_cache();
|
state.push_fn_resolution_cache();
|
||||||
lib_merged = Default::default();
|
lib_merged = once(env_lib.as_ref())
|
||||||
lib_merged.push(env_lib.as_ref());
|
.chain(lib.iter().cloned())
|
||||||
lib_merged.extend(lib.iter().cloned());
|
.collect::<StaticVec<_>>();
|
||||||
lib_merged.as_ref()
|
(lib_merged.as_ref(), true)
|
||||||
} else {
|
} else {
|
||||||
lib
|
(lib, false)
|
||||||
};
|
};
|
||||||
|
|
||||||
#[cfg(not(feature = "no_module"))]
|
#[cfg(not(feature = "no_module"))]
|
||||||
|
@ -127,6 +127,8 @@ pub struct Module {
|
|||||||
all_type_iterators: HashMap<TypeId, IteratorFn>,
|
all_type_iterators: HashMap<TypeId, IteratorFn>,
|
||||||
/// Is the [`Module`] indexed?
|
/// Is the [`Module`] indexed?
|
||||||
indexed: bool,
|
indexed: bool,
|
||||||
|
/// Does the [`Module`] contain indexed functions that have been exposed to the global namespace?
|
||||||
|
contains_indexed_global_functions: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for Module {
|
impl Default for Module {
|
||||||
@ -141,6 +143,7 @@ impl Default for Module {
|
|||||||
type_iterators: Default::default(),
|
type_iterators: Default::default(),
|
||||||
all_type_iterators: Default::default(),
|
all_type_iterators: Default::default(),
|
||||||
indexed: false,
|
indexed: false,
|
||||||
|
contains_indexed_global_functions: false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -434,6 +437,7 @@ impl Module {
|
|||||||
) -> &mut Self {
|
) -> &mut Self {
|
||||||
self.variables.insert(name.into(), Dynamic::from(value));
|
self.variables.insert(name.into(), Dynamic::from(value));
|
||||||
self.indexed = false;
|
self.indexed = false;
|
||||||
|
self.contains_indexed_global_functions = false;
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -477,6 +481,7 @@ impl Module {
|
|||||||
},
|
},
|
||||||
);
|
);
|
||||||
self.indexed = false;
|
self.indexed = false;
|
||||||
|
self.contains_indexed_global_functions = false;
|
||||||
hash_script
|
hash_script
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -521,6 +526,7 @@ impl Module {
|
|||||||
self.all_variables.clear();
|
self.all_variables.clear();
|
||||||
self.all_type_iterators.clear();
|
self.all_type_iterators.clear();
|
||||||
self.indexed = false;
|
self.indexed = false;
|
||||||
|
self.contains_indexed_global_functions = false;
|
||||||
|
|
||||||
&mut self.modules
|
&mut self.modules
|
||||||
}
|
}
|
||||||
@ -581,6 +587,7 @@ impl Module {
|
|||||||
) -> &mut Self {
|
) -> &mut Self {
|
||||||
self.modules.insert(name.into(), sub_module.into());
|
self.modules.insert(name.into(), sub_module.into());
|
||||||
self.indexed = false;
|
self.indexed = false;
|
||||||
|
self.contains_indexed_global_functions = false;
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -649,6 +656,7 @@ impl Module {
|
|||||||
f.namespace = namespace;
|
f.namespace = namespace;
|
||||||
}
|
}
|
||||||
self.indexed = false;
|
self.indexed = false;
|
||||||
|
self.contains_indexed_global_functions = false;
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -704,6 +712,7 @@ impl Module {
|
|||||||
);
|
);
|
||||||
|
|
||||||
self.indexed = false;
|
self.indexed = false;
|
||||||
|
self.contains_indexed_global_functions = false;
|
||||||
|
|
||||||
hash_fn
|
hash_fn
|
||||||
}
|
}
|
||||||
@ -1497,6 +1506,7 @@ impl Module {
|
|||||||
self.all_variables.clear();
|
self.all_variables.clear();
|
||||||
self.all_type_iterators.clear();
|
self.all_type_iterators.clear();
|
||||||
self.indexed = false;
|
self.indexed = false;
|
||||||
|
self.contains_indexed_global_functions = false;
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1515,6 +1525,7 @@ impl Module {
|
|||||||
self.all_variables.clear();
|
self.all_variables.clear();
|
||||||
self.all_type_iterators.clear();
|
self.all_type_iterators.clear();
|
||||||
self.indexed = false;
|
self.indexed = false;
|
||||||
|
self.contains_indexed_global_functions = false;
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1542,6 +1553,7 @@ impl Module {
|
|||||||
self.all_variables.clear();
|
self.all_variables.clear();
|
||||||
self.all_type_iterators.clear();
|
self.all_type_iterators.clear();
|
||||||
self.indexed = false;
|
self.indexed = false;
|
||||||
|
self.contains_indexed_global_functions = false;
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1602,6 +1614,7 @@ impl Module {
|
|||||||
self.all_variables.clear();
|
self.all_variables.clear();
|
||||||
self.all_type_iterators.clear();
|
self.all_type_iterators.clear();
|
||||||
self.indexed = false;
|
self.indexed = false;
|
||||||
|
self.contains_indexed_global_functions = false;
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1634,6 +1647,7 @@ impl Module {
|
|||||||
self.all_variables.clear();
|
self.all_variables.clear();
|
||||||
self.all_type_iterators.clear();
|
self.all_type_iterators.clear();
|
||||||
self.indexed = false;
|
self.indexed = false;
|
||||||
|
self.contains_indexed_global_functions = false;
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1820,29 +1834,14 @@ impl Module {
|
|||||||
Ok(module)
|
Ok(module)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Are there functions (or type iterators) marked for the specified namespace?
|
/// Does the [`Module`] contain indexed functions that have been exposed to the global namespace?
|
||||||
pub fn has_namespace(&self, namespace: FnNamespace, recursive: bool) -> bool {
|
///
|
||||||
// Type iterators are default global
|
/// # Panics
|
||||||
if !self.type_iterators.is_empty() {
|
///
|
||||||
return true;
|
/// Panics if the [`Module`] is not yet indexed via [`build_index`][Module::build_index].
|
||||||
}
|
#[inline(always)]
|
||||||
// Any function marked global?
|
pub fn contains_indexed_global_functions(&self) -> bool {
|
||||||
if self.functions.values().any(|f| f.namespace == namespace) {
|
self.contains_indexed_global_functions
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Scan sub-modules
|
|
||||||
if recursive {
|
|
||||||
if self
|
|
||||||
.modules
|
|
||||||
.values()
|
|
||||||
.any(|m| m.has_namespace(namespace, recursive))
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
false
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Scan through all the sub-modules in the [`Module`] and build a hash index of all
|
/// Scan through all the sub-modules in the [`Module`] and build a hash index of all
|
||||||
@ -1857,11 +1856,15 @@ impl Module {
|
|||||||
variables: &mut HashMap<NonZeroU64, Dynamic, StraightHasherBuilder>,
|
variables: &mut HashMap<NonZeroU64, Dynamic, StraightHasherBuilder>,
|
||||||
functions: &mut HashMap<NonZeroU64, CallableFunction, StraightHasherBuilder>,
|
functions: &mut HashMap<NonZeroU64, CallableFunction, StraightHasherBuilder>,
|
||||||
type_iterators: &mut HashMap<TypeId, IteratorFn>,
|
type_iterators: &mut HashMap<TypeId, IteratorFn>,
|
||||||
) {
|
) -> bool {
|
||||||
|
let mut contains_indexed_global_functions = false;
|
||||||
|
|
||||||
module.modules.iter().for_each(|(name, m)| {
|
module.modules.iter().for_each(|(name, m)| {
|
||||||
// Index all the sub-modules first.
|
// Index all the sub-modules first.
|
||||||
qualifiers.push(name);
|
qualifiers.push(name);
|
||||||
index_module(m, qualifiers, variables, functions, type_iterators);
|
if index_module(m, qualifiers, variables, functions, type_iterators) {
|
||||||
|
contains_indexed_global_functions = true;
|
||||||
|
}
|
||||||
qualifiers.pop();
|
qualifiers.pop();
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -1875,6 +1878,7 @@ impl Module {
|
|||||||
// Index type iterators
|
// Index type iterators
|
||||||
module.type_iterators.iter().for_each(|(&type_id, func)| {
|
module.type_iterators.iter().for_each(|(&type_id, func)| {
|
||||||
type_iterators.insert(type_id, func.clone());
|
type_iterators.insert(type_id, func.clone());
|
||||||
|
contains_indexed_global_functions = true;
|
||||||
});
|
});
|
||||||
|
|
||||||
// Index all Rust functions
|
// Index all Rust functions
|
||||||
@ -1895,6 +1899,7 @@ impl Module {
|
|||||||
FnNamespace::Global => {
|
FnNamespace::Global => {
|
||||||
// Flatten all functions with global namespace
|
// Flatten all functions with global namespace
|
||||||
functions.insert(hash, func.clone());
|
functions.insert(hash, func.clone());
|
||||||
|
contains_indexed_global_functions = true;
|
||||||
}
|
}
|
||||||
FnNamespace::Internal => (),
|
FnNamespace::Internal => (),
|
||||||
}
|
}
|
||||||
@ -1927,6 +1932,8 @@ impl Module {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
|
contains_indexed_global_functions
|
||||||
}
|
}
|
||||||
|
|
||||||
if !self.indexed {
|
if !self.indexed {
|
||||||
@ -1937,7 +1944,7 @@ impl Module {
|
|||||||
|
|
||||||
qualifiers.push("root");
|
qualifiers.push("root");
|
||||||
|
|
||||||
index_module(
|
self.contains_indexed_global_functions = index_module(
|
||||||
self,
|
self,
|
||||||
&mut qualifiers,
|
&mut qualifiers,
|
||||||
&mut variables,
|
&mut variables,
|
||||||
@ -1968,6 +1975,7 @@ impl Module {
|
|||||||
pub fn set_iter(&mut self, typ: TypeId, func: IteratorFn) -> &mut Self {
|
pub fn set_iter(&mut self, typ: TypeId, func: IteratorFn) -> &mut Self {
|
||||||
self.type_iterators.insert(typ, func);
|
self.type_iterators.insert(typ, func);
|
||||||
self.indexed = false;
|
self.indexed = false;
|
||||||
|
self.contains_indexed_global_functions = false;
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -24,10 +24,12 @@ fn test_module_sub_module() -> Result<(), Box<EvalAltResult>> {
|
|||||||
sub_module2.set_var("answer", 41 as INT);
|
sub_module2.set_var("answer", 41 as INT);
|
||||||
|
|
||||||
let hash_inc = sub_module2.set_fn_1_mut("inc", FnNamespace::Internal, |x: &mut INT| Ok(*x + 1));
|
let hash_inc = sub_module2.set_fn_1_mut("inc", FnNamespace::Internal, |x: &mut INT| Ok(*x + 1));
|
||||||
assert!(!sub_module2.has_namespace(FnNamespace::Global, true));
|
sub_module2.build_index();
|
||||||
|
assert!(!sub_module2.contains_indexed_global_functions());
|
||||||
|
|
||||||
sub_module2.set_fn_1_mut("super_inc", FnNamespace::Global, |x: &mut INT| Ok(*x + 1));
|
sub_module2.set_fn_1_mut("super_inc", FnNamespace::Global, |x: &mut INT| Ok(*x + 1));
|
||||||
assert!(sub_module2.has_namespace(FnNamespace::Global, true));
|
sub_module2.build_index();
|
||||||
|
assert!(sub_module2.contains_indexed_global_functions());
|
||||||
|
|
||||||
#[cfg(not(feature = "no_object"))]
|
#[cfg(not(feature = "no_object"))]
|
||||||
sub_module2.set_getter_fn("doubled", |x: &mut INT| Ok(*x * 2));
|
sub_module2.set_getter_fn("doubled", |x: &mut INT| Ok(*x * 2));
|
||||||
@ -35,9 +37,9 @@ fn test_module_sub_module() -> Result<(), Box<EvalAltResult>> {
|
|||||||
sub_module.set_sub_module("universe", sub_module2);
|
sub_module.set_sub_module("universe", sub_module2);
|
||||||
module.set_sub_module("life", sub_module);
|
module.set_sub_module("life", sub_module);
|
||||||
module.set_var("MYSTIC_NUMBER", Dynamic::from(42 as INT));
|
module.set_var("MYSTIC_NUMBER", Dynamic::from(42 as INT));
|
||||||
|
module.build_index();
|
||||||
|
|
||||||
assert!(module.has_namespace(FnNamespace::Global, true));
|
assert!(module.contains_indexed_global_functions());
|
||||||
assert!(!module.has_namespace(FnNamespace::Global, false));
|
|
||||||
|
|
||||||
assert!(module.contains_sub_module("life"));
|
assert!(module.contains_sub_module("life"));
|
||||||
let m = module.get_sub_module("life").unwrap();
|
let m = module.get_sub_module("life").unwrap();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user