No need to copy sub-modules.
This commit is contained in:
parent
1221190771
commit
1300ad8677
@ -17,7 +17,7 @@ use crate::stdlib::{
|
||||
collections::{HashMap, HashSet},
|
||||
fmt, format,
|
||||
hash::{Hash, Hasher},
|
||||
iter::{empty, FromIterator},
|
||||
iter::empty,
|
||||
num::{NonZeroU64, NonZeroU8, NonZeroUsize},
|
||||
ops::DerefMut,
|
||||
string::{String, ToString},
|
||||
@ -151,24 +151,6 @@ impl Imports {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, T: IntoIterator<Item = (&'a ImmutableString, &'a Shared<Module>)>> From<T> for Imports {
|
||||
#[inline(always)]
|
||||
fn from(value: T) -> Self {
|
||||
Self(
|
||||
value
|
||||
.into_iter()
|
||||
.map(|(k, v)| (k.clone(), v.clone()))
|
||||
.collect(),
|
||||
)
|
||||
}
|
||||
}
|
||||
impl FromIterator<(ImmutableString, Shared<Module>)> for Imports {
|
||||
#[inline(always)]
|
||||
fn from_iter<T: IntoIterator<Item = (ImmutableString, Shared<Module>)>>(iter: T) -> Self {
|
||||
Self(iter.into_iter().collect())
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "unchecked"))]
|
||||
#[cfg(debug_assertions)]
|
||||
#[cfg(not(feature = "no_function"))]
|
||||
@ -824,32 +806,6 @@ fn default_debug(_s: &str, _source: Option<&str>, _pos: Position) {
|
||||
}
|
||||
}
|
||||
|
||||
/// Search for a module within an imports stack.
|
||||
/// [`Position`] in [`EvalAltResult`] is [`None`][Position::None] and must be set afterwards.
|
||||
pub fn search_imports(
|
||||
mods: &Imports,
|
||||
state: &mut State,
|
||||
namespace: &NamespaceRef,
|
||||
) -> Result<Shared<Module>, Box<EvalAltResult>> {
|
||||
let Ident { name: root, pos } = &namespace[0];
|
||||
|
||||
// Qualified - check if the root module is directly indexed
|
||||
let index = if state.always_search {
|
||||
None
|
||||
} else {
|
||||
namespace.index()
|
||||
};
|
||||
|
||||
Ok(if let Some(index) = index {
|
||||
let offset = mods.len() - index.get();
|
||||
mods.get(offset).expect("invalid index in Imports")
|
||||
} else {
|
||||
mods.find(root)
|
||||
.map(|n| mods.get(n).expect("invalid index in Imports"))
|
||||
.ok_or_else(|| EvalAltResult::ErrorModuleNotFound(root.to_string(), *pos))?
|
||||
})
|
||||
}
|
||||
|
||||
impl Engine {
|
||||
/// Create a new [`Engine`]
|
||||
#[inline]
|
||||
@ -970,6 +926,34 @@ impl Engine {
|
||||
}
|
||||
}
|
||||
|
||||
/// Search for a module within an imports stack.
|
||||
/// [`Position`] in [`EvalAltResult`] is [`None`][Position::None] and must be set afterwards.
|
||||
pub fn search_imports(
|
||||
&self,
|
||||
mods: &Imports,
|
||||
state: &mut State,
|
||||
namespace: &NamespaceRef,
|
||||
) -> Result<Shared<Module>, Box<EvalAltResult>> {
|
||||
let Ident { name: root, pos } = &namespace[0];
|
||||
|
||||
// Qualified - check if the root module is directly indexed
|
||||
let index = if state.always_search {
|
||||
None
|
||||
} else {
|
||||
namespace.index()
|
||||
};
|
||||
|
||||
Ok(if let Some(index) = index {
|
||||
let offset = mods.len() - index.get();
|
||||
mods.get(offset).expect("invalid index in Imports")
|
||||
} else {
|
||||
mods.find(root)
|
||||
.map(|n| mods.get(n).expect("invalid index in Imports"))
|
||||
.or_else(|| self.global_sub_modules.get(root).cloned())
|
||||
.ok_or_else(|| EvalAltResult::ErrorModuleNotFound(root.to_string(), *pos))?
|
||||
})
|
||||
}
|
||||
|
||||
/// Search for a variable within the scope or within imports,
|
||||
/// depending on whether the variable name is namespace-qualified.
|
||||
pub(crate) fn search_namespace<'s>(
|
||||
@ -985,7 +969,7 @@ impl Engine {
|
||||
Expr::Variable(v) => match v.as_ref() {
|
||||
// Qualified variable
|
||||
(_, Some((hash_var, modules)), Ident { name, pos }) => {
|
||||
let module = search_imports(mods, state, modules)?;
|
||||
let module = self.search_imports(mods, state, modules)?;
|
||||
let target = module.get_qualified_var(*hash_var).map_err(|mut err| {
|
||||
match *err {
|
||||
EvalAltResult::ErrorVariableNotFound(ref mut err_name, _) => {
|
||||
@ -2175,6 +2159,13 @@ impl Engine {
|
||||
let iter_obj = self.eval_expr(scope, mods, state, lib, this_ptr, expr, level)?;
|
||||
let iter_type = iter_obj.type_id();
|
||||
|
||||
// lib should only contain scripts, so technically they cannot have iterators
|
||||
|
||||
// Search order:
|
||||
// 1) Global namespace - functions registered via Engine::register_XXX
|
||||
// 2) Global modules - packages
|
||||
// 3) Imported modules - functions marked with global namespace
|
||||
// 4) Global sub-modules - functions marked with global namespace
|
||||
let func = self
|
||||
.global_namespace
|
||||
.get_iter(iter_type)
|
||||
@ -2183,7 +2174,12 @@ impl Engine {
|
||||
.iter()
|
||||
.find_map(|m| m.get_iter(iter_type))
|
||||
})
|
||||
.or_else(|| mods.get_iter(iter_type));
|
||||
.or_else(|| mods.get_iter(iter_type))
|
||||
.or_else(|| {
|
||||
self.global_sub_modules
|
||||
.values()
|
||||
.find_map(|m| m.get_qualified_iter(iter_type))
|
||||
});
|
||||
|
||||
if let Some(func) = func {
|
||||
// Add the loop variable
|
||||
|
@ -1503,7 +1503,7 @@ impl Engine {
|
||||
scope: &mut Scope,
|
||||
ast: &AST,
|
||||
) -> Result<T, Box<EvalAltResult>> {
|
||||
let mods = &mut (&self.global_sub_modules).into();
|
||||
let mods = &mut Default::default();
|
||||
|
||||
let result = self.eval_ast_with_scope_raw(scope, mods, ast, 0)?;
|
||||
|
||||
@ -1598,7 +1598,7 @@ impl Engine {
|
||||
scope: &mut Scope,
|
||||
ast: &AST,
|
||||
) -> Result<(), Box<EvalAltResult>> {
|
||||
let mods = &mut (&self.global_sub_modules).into();
|
||||
let mods = &mut Default::default();
|
||||
let mut state: State = Default::default();
|
||||
state.source = ast.clone_source();
|
||||
#[cfg(not(feature = "no_module"))]
|
||||
@ -1766,7 +1766,7 @@ impl Engine {
|
||||
args: &mut FnCallArgs,
|
||||
) -> Result<Dynamic, Box<EvalAltResult>> {
|
||||
let state = &mut Default::default();
|
||||
let mods = &mut (&self.global_sub_modules).into();
|
||||
let mods = &mut Default::default();
|
||||
let lib = &[ast.lib()];
|
||||
|
||||
if eval_ast {
|
||||
|
@ -2,8 +2,8 @@
|
||||
|
||||
use crate::ast::{Expr, Stmt};
|
||||
use crate::engine::{
|
||||
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,
|
||||
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,
|
||||
MAX_DYNAMIC_PARAMETERS,
|
||||
};
|
||||
use crate::fn_native::FnCallArgs;
|
||||
@ -212,7 +212,14 @@ impl Engine {
|
||||
let mut bitmask = 1usize; // Bitmask of which parameter to replace with `Dynamic`
|
||||
|
||||
loop {
|
||||
//lib.get_fn(hash, false).or_else(||
|
||||
// lib should only contain scripts, so technically speaking we don't have to check it
|
||||
// lib.iter().find_map(|m| m.get_fn(hash, false).map(|f| (f.clone(), m.id_raw().cloned()))).or_else(|| {
|
||||
|
||||
// Search order:
|
||||
// 1) Global namespace - functions registered via Engine::register_XXX
|
||||
// 2) Global modules - packages
|
||||
// 3) Imported modules - functions marked with global namespace
|
||||
// 4) Global sub-modules - functions marked with global namespace
|
||||
match self
|
||||
.global_namespace
|
||||
.get_fn(hash, false)
|
||||
@ -227,6 +234,12 @@ impl Engine {
|
||||
.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()))
|
||||
})
|
||||
}) {
|
||||
// Specific version found
|
||||
Some(f) => return Some(f),
|
||||
@ -1297,7 +1310,7 @@ impl Engine {
|
||||
}
|
||||
}
|
||||
|
||||
let module = search_imports(mods, state, namespace)?;
|
||||
let module = self.search_imports(mods, state, namespace)?;
|
||||
|
||||
// First search in script-defined functions (can override built-in)
|
||||
let func = match module.get_qualified_fn(hash_script) {
|
||||
|
@ -1783,7 +1783,7 @@ impl Module {
|
||||
ast: &crate::AST,
|
||||
engine: &crate::Engine,
|
||||
) -> Result<Self, Box<EvalAltResult>> {
|
||||
let mut mods: crate::engine::Imports = (&engine.global_sub_modules).into();
|
||||
let mut mods: crate::engine::Imports = Default::default();
|
||||
let orig_mods_len = mods.len();
|
||||
|
||||
// Run the script
|
||||
|
@ -79,7 +79,7 @@ impl<'a> State<'a> {
|
||||
variables: vec![],
|
||||
propagate_constants: true,
|
||||
engine,
|
||||
mods: (&engine.global_sub_modules).into(),
|
||||
mods: Default::default(),
|
||||
lib,
|
||||
optimization_level: level,
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user