From c41f5aefcb646e22e928300ec6362417b7d63653 Mon Sep 17 00:00:00 2001 From: Stephen Chung Date: Mon, 9 Nov 2020 22:44:20 +0800 Subject: [PATCH] Change sub-modules to shared. --- src/engine.rs | 5 ++-- src/fn_native.rs | 9 +++++++ src/module/mod.rs | 63 ++++++++++++++--------------------------------- 3 files changed, 30 insertions(+), 47 deletions(-) diff --git a/src/engine.rs b/src/engine.rs index 8a0035aa..57ced10c 100644 --- a/src/engine.rs +++ b/src/engine.rs @@ -18,7 +18,7 @@ use crate::{calc_native_fn_hash, StaticVec}; use crate::INT; #[cfg(not(feature = "no_module"))] -use crate::{fn_native::shared_try_take, module::ModuleResolver}; +use crate::{fn_native::shared_take_or_clone, module::ModuleResolver}; #[cfg(not(feature = "no_std"))] #[cfg(not(feature = "no_module"))] @@ -2159,8 +2159,7 @@ impl Engine { if let Some(name_def) = alias { if !module.is_indexed() { // Index the module (making a clone copy if necessary) if it is not indexed - let mut module = - shared_try_take(module).unwrap_or_else(|m| m.as_ref().clone()); + let mut module = shared_take_or_clone(module); module.build_index(); mods.push(name_def.name.clone(), module); } else { diff --git a/src/fn_native.rs b/src/fn_native.rs index cb6280c4..4e4fc6a7 100644 --- a/src/fn_native.rs +++ b/src/fn_native.rs @@ -176,6 +176,7 @@ impl<'e, 'a, 'm, 'pm> NativeCallContext<'e, 'a, 'm, 'pm> { /// Consume a `Shared` resource and return a mutable reference to the wrapped value. /// If the resource is shared (i.e. has other outstanding references), a cloned copy is used. +#[inline(always)] pub fn shared_make_mut(value: &mut Shared) -> &mut T { #[cfg(not(feature = "sync"))] return Rc::make_mut(value); @@ -183,7 +184,14 @@ pub fn shared_make_mut(value: &mut Shared) -> &mut T { return Arc::make_mut(value); } +/// Consume a `Shared` resource if is unique (i.e. not shared), or clone it otherwise. +#[inline(always)] +pub fn shared_take_or_clone(value: Shared) -> T { + shared_try_take(value).unwrap_or_else(|v| v.as_ref().clone()) +} + /// Consume a `Shared` resource if is unique (i.e. not shared). +#[inline(always)] pub fn shared_try_take(value: Shared) -> Result> { #[cfg(not(feature = "sync"))] return Rc::try_unwrap(value); @@ -196,6 +204,7 @@ pub fn shared_try_take(value: Shared) -> Result> { /// # Panics /// /// Panics if the resource is shared (i.e. has other outstanding references). +#[inline(always)] pub fn shared_take(value: Shared) -> T { shared_try_take(value).map_err(|_| ()).unwrap() } diff --git a/src/module/mod.rs b/src/module/mod.rs index 9983faed..f9d28d87 100644 --- a/src/module/mod.rs +++ b/src/module/mod.rs @@ -2,7 +2,10 @@ use crate::ast::{FnAccess, Ident}; use crate::dynamic::{Dynamic, Variant}; -use crate::fn_native::{CallableFunction, FnCallArgs, IteratorFn, NativeCallContext, SendSync}; +use crate::fn_native::{ + shared_make_mut, shared_take_or_clone, CallableFunction, FnCallArgs, IteratorFn, + NativeCallContext, SendSync, Shared, +}; use crate::fn_register::by_value as cast_arg; use crate::result::EvalAltResult; use crate::token::{Token, NO_POS}; @@ -10,7 +13,7 @@ use crate::utils::{ImmutableString, StraightHasherBuilder}; use crate::{calc_native_fn_hash, calc_script_fn_hash, StaticVec}; #[cfg(not(feature = "no_function"))] -use crate::{ast::ScriptFnDef, fn_native::Shared}; +use crate::ast::ScriptFnDef; #[cfg(not(feature = "no_module"))] use crate::{ast::AST, engine::Engine, scope::Scope}; @@ -56,10 +59,10 @@ pub struct FuncInfo { /// external Rust functions, and script-defined functions. /// /// Not available under the `no_module` feature. -#[derive(Default)] +#[derive(Default, Clone)] pub struct Module { /// Sub-modules. - modules: HashMap, + modules: HashMap>, /// Module variables. variables: HashMap, /// Flattened collection of all module variables, including those in sub-modules. @@ -99,19 +102,6 @@ impl fmt::Debug for Module { } } -impl Clone for Module { - #[inline(always)] - fn clone(&self) -> Self { - // Only clone the index at the top level - Self { - all_variables: self.all_variables.clone(), - all_functions: self.all_functions.clone(), - indexed: self.indexed, - ..self.do_clone(false) - } - } -} - impl AsRef for Module { #[inline(always)] fn as_ref(&self) -> &Module { @@ -195,25 +185,6 @@ impl Module { self.indexed } - /// Clone the module, optionally skipping the index. - #[inline(always)] - fn do_clone(&self, clone_index: bool) -> Self { - Self { - modules: if clone_index { - self.modules.clone() - } else { - self.modules - .iter() - .map(|(k, m)| (k.clone(), m.do_clone(clone_index))) - .collect() - }, - variables: self.variables.clone(), - functions: self.functions.clone(), - type_iterators: self.type_iterators.clone(), - ..Default::default() - } - } - /// Does a variable exist in the module? /// /// # Example @@ -377,7 +348,7 @@ impl Module { /// ``` #[inline(always)] pub fn get_sub_module(&self, name: &str) -> Option<&Module> { - self.modules.get(name) + self.modules.get(name).map(|m| m.as_ref()) } /// Get a mutable reference to a sub-module. @@ -394,7 +365,7 @@ impl Module { /// ``` #[inline(always)] pub fn get_sub_module_mut(&mut self, name: &str) -> Option<&mut Module> { - self.modules.get_mut(name) + self.modules.get_mut(name).map(shared_make_mut) } /// Set a sub-module into the module. @@ -412,7 +383,11 @@ impl Module { /// assert!(module.get_sub_module("question").is_some()); /// ``` #[inline(always)] - pub fn set_sub_module(&mut self, name: impl Into, sub_module: Module) -> &mut Self { + pub fn set_sub_module( + &mut self, + name: impl Into, + sub_module: impl Into>, + ) -> &mut Self { self.modules.insert(name.into(), sub_module.into()); self.indexed = false; self @@ -1160,7 +1135,7 @@ impl Module { #[inline] pub fn combine_flatten(&mut self, other: Self) -> &mut Self { other.modules.into_iter().for_each(|(_, m)| { - self.combine_flatten(m); + self.combine_flatten(shared_take_or_clone(m)); }); self.variables.extend(other.variables.into_iter()); self.functions.extend(other.functions.into_iter()); @@ -1213,7 +1188,7 @@ impl Module { other.modules.iter().for_each(|(k, v)| { let mut m = Self::new(); m.merge_filtered(v, _filter); - self.modules.insert(k.clone(), m); + self.set_sub_module(k, m); }); #[cfg(feature = "no_function")] self.modules @@ -1266,8 +1241,8 @@ impl Module { pub fn count(&self) -> (usize, usize, usize) { ( self.variables.len(), - self.variables.len(), - self.variables.len(), + self.functions.len(), + self.type_iterators.len(), ) } @@ -1393,7 +1368,7 @@ impl Module { // Modules left in the scope become sub-modules mods.iter().for_each(|(alias, m)| { - module.modules.insert(alias.to_string(), m.as_ref().clone()); + module.set_sub_module(alias, m); }); // Non-private functions defined become module functions