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},
|
collections::{HashMap, HashSet},
|
||||||
fmt, format,
|
fmt, format,
|
||||||
hash::{Hash, Hasher},
|
hash::{Hash, Hasher},
|
||||||
iter::{empty, FromIterator},
|
iter::empty,
|
||||||
num::{NonZeroU64, NonZeroU8, NonZeroUsize},
|
num::{NonZeroU64, NonZeroU8, NonZeroUsize},
|
||||||
ops::DerefMut,
|
ops::DerefMut,
|
||||||
string::{String, ToString},
|
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(not(feature = "unchecked"))]
|
||||||
#[cfg(debug_assertions)]
|
#[cfg(debug_assertions)]
|
||||||
#[cfg(not(feature = "no_function"))]
|
#[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 {
|
impl Engine {
|
||||||
/// Create a new [`Engine`]
|
/// Create a new [`Engine`]
|
||||||
#[inline]
|
#[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,
|
/// Search for a variable within the scope or within imports,
|
||||||
/// depending on whether the variable name is namespace-qualified.
|
/// depending on whether the variable name is namespace-qualified.
|
||||||
pub(crate) fn search_namespace<'s>(
|
pub(crate) fn search_namespace<'s>(
|
||||||
@ -985,7 +969,7 @@ impl Engine {
|
|||||||
Expr::Variable(v) => match v.as_ref() {
|
Expr::Variable(v) => match v.as_ref() {
|
||||||
// Qualified variable
|
// Qualified variable
|
||||||
(_, Some((hash_var, modules)), Ident { name, pos }) => {
|
(_, 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| {
|
let target = module.get_qualified_var(*hash_var).map_err(|mut err| {
|
||||||
match *err {
|
match *err {
|
||||||
EvalAltResult::ErrorVariableNotFound(ref mut err_name, _) => {
|
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_obj = self.eval_expr(scope, mods, state, lib, this_ptr, expr, level)?;
|
||||||
let iter_type = iter_obj.type_id();
|
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
|
let func = self
|
||||||
.global_namespace
|
.global_namespace
|
||||||
.get_iter(iter_type)
|
.get_iter(iter_type)
|
||||||
@ -2183,7 +2174,12 @@ impl Engine {
|
|||||||
.iter()
|
.iter()
|
||||||
.find_map(|m| m.get_iter(iter_type))
|
.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 {
|
if let Some(func) = func {
|
||||||
// Add the loop variable
|
// Add the loop variable
|
||||||
|
@ -1503,7 +1503,7 @@ impl Engine {
|
|||||||
scope: &mut Scope,
|
scope: &mut Scope,
|
||||||
ast: &AST,
|
ast: &AST,
|
||||||
) -> Result<T, Box<EvalAltResult>> {
|
) -> 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)?;
|
let result = self.eval_ast_with_scope_raw(scope, mods, ast, 0)?;
|
||||||
|
|
||||||
@ -1598,7 +1598,7 @@ impl Engine {
|
|||||||
scope: &mut Scope,
|
scope: &mut Scope,
|
||||||
ast: &AST,
|
ast: &AST,
|
||||||
) -> Result<(), Box<EvalAltResult>> {
|
) -> Result<(), Box<EvalAltResult>> {
|
||||||
let mods = &mut (&self.global_sub_modules).into();
|
let mods = &mut Default::default();
|
||||||
let mut state: State = Default::default();
|
let mut state: State = Default::default();
|
||||||
state.source = ast.clone_source();
|
state.source = ast.clone_source();
|
||||||
#[cfg(not(feature = "no_module"))]
|
#[cfg(not(feature = "no_module"))]
|
||||||
@ -1766,7 +1766,7 @@ impl Engine {
|
|||||||
args: &mut FnCallArgs,
|
args: &mut FnCallArgs,
|
||||||
) -> Result<Dynamic, Box<EvalAltResult>> {
|
) -> Result<Dynamic, Box<EvalAltResult>> {
|
||||||
let state = &mut Default::default();
|
let state = &mut Default::default();
|
||||||
let mods = &mut (&self.global_sub_modules).into();
|
let mods = &mut Default::default();
|
||||||
let lib = &[ast.lib()];
|
let lib = &[ast.lib()];
|
||||||
|
|
||||||
if eval_ast {
|
if eval_ast {
|
||||||
|
@ -2,8 +2,8 @@
|
|||||||
|
|
||||||
use crate::ast::{Expr, Stmt};
|
use crate::ast::{Expr, Stmt};
|
||||||
use crate::engine::{
|
use crate::engine::{
|
||||||
search_imports, Imports, State, KEYWORD_DEBUG, KEYWORD_EVAL, KEYWORD_FN_PTR,
|
Imports, State, KEYWORD_DEBUG, KEYWORD_EVAL, KEYWORD_FN_PTR, KEYWORD_FN_PTR_CALL,
|
||||||
KEYWORD_FN_PTR_CALL, KEYWORD_FN_PTR_CURRY, KEYWORD_IS_DEF_VAR, KEYWORD_PRINT, KEYWORD_TYPE_OF,
|
KEYWORD_FN_PTR_CURRY, KEYWORD_IS_DEF_VAR, KEYWORD_PRINT, KEYWORD_TYPE_OF,
|
||||||
MAX_DYNAMIC_PARAMETERS,
|
MAX_DYNAMIC_PARAMETERS,
|
||||||
};
|
};
|
||||||
use crate::fn_native::FnCallArgs;
|
use crate::fn_native::FnCallArgs;
|
||||||
@ -212,7 +212,14 @@ 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 {
|
||||||
//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
|
match self
|
||||||
.global_namespace
|
.global_namespace
|
||||||
.get_fn(hash, false)
|
.get_fn(hash, false)
|
||||||
@ -227,6 +234,12 @@ impl Engine {
|
|||||||
.or_else(|| {
|
.or_else(|| {
|
||||||
mods.get_fn(hash)
|
mods.get_fn(hash)
|
||||||
.map(|(f, source)| (f.clone(), source.cloned()))
|
.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
|
// Specific version found
|
||||||
Some(f) => return Some(f),
|
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)
|
// First search in script-defined functions (can override built-in)
|
||||||
let func = match module.get_qualified_fn(hash_script) {
|
let func = match module.get_qualified_fn(hash_script) {
|
||||||
|
@ -1783,7 +1783,7 @@ impl Module {
|
|||||||
ast: &crate::AST,
|
ast: &crate::AST,
|
||||||
engine: &crate::Engine,
|
engine: &crate::Engine,
|
||||||
) -> Result<Self, Box<EvalAltResult>> {
|
) -> 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();
|
let orig_mods_len = mods.len();
|
||||||
|
|
||||||
// Run the script
|
// Run the script
|
||||||
|
@ -79,7 +79,7 @@ impl<'a> State<'a> {
|
|||||||
variables: vec![],
|
variables: vec![],
|
||||||
propagate_constants: true,
|
propagate_constants: true,
|
||||||
engine,
|
engine,
|
||||||
mods: (&engine.global_sub_modules).into(),
|
mods: Default::default(),
|
||||||
lib,
|
lib,
|
||||||
optimization_level: level,
|
optimization_level: level,
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user