Skip to content

Commit

Permalink
Merge pull request #291 from schungx/master
Browse files Browse the repository at this point in the history
Change sub-modules to shared.
  • Loading branch information
schungx committed Nov 10, 2020
2 parents a55083f + c41f5ae commit 9bf8219
Show file tree
Hide file tree
Showing 3 changed files with 30 additions and 47 deletions.
5 changes: 2 additions & 3 deletions src/engine.rs
Expand Up @@ -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"))]
Expand Down Expand Up @@ -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 {
Expand Down
9 changes: 9 additions & 0 deletions src/fn_native.rs
Expand Up @@ -176,14 +176,22 @@ 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<T: Clone>(value: &mut Shared<T>) -> &mut T {
#[cfg(not(feature = "sync"))]
return Rc::make_mut(value);
#[cfg(feature = "sync")]
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<T: Clone>(value: Shared<T>) -> 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<T>(value: Shared<T>) -> Result<T, Shared<T>> {
#[cfg(not(feature = "sync"))]
return Rc::try_unwrap(value);
Expand All @@ -196,6 +204,7 @@ pub fn shared_try_take<T>(value: Shared<T>) -> Result<T, Shared<T>> {
/// # Panics
///
/// Panics if the resource is shared (i.e. has other outstanding references).
#[inline(always)]
pub fn shared_take<T>(value: Shared<T>) -> T {
shared_try_take(value).map_err(|_| ()).unwrap()
}
Expand Down
63 changes: 19 additions & 44 deletions src/module/mod.rs
Expand Up @@ -2,15 +2,18 @@

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};
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};
Expand Down Expand Up @@ -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<String, Module>,
modules: HashMap<String, Shared<Module>>,
/// Module variables.
variables: HashMap<String, Dynamic>,
/// Flattened collection of all module variables, including those in sub-modules.
Expand Down Expand Up @@ -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<Module> for Module {
#[inline(always)]
fn as_ref(&self) -> &Module {
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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.
Expand All @@ -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.
Expand All @@ -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<String>, sub_module: Module) -> &mut Self {
pub fn set_sub_module(
&mut self,
name: impl Into<String>,
sub_module: impl Into<Shared<Module>>,
) -> &mut Self {
self.modules.insert(name.into(), sub_module.into());
self.indexed = false;
self
Expand Down Expand Up @@ -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());
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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(),
)
}

Expand Down Expand Up @@ -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
Expand Down

0 comments on commit 9bf8219

Please sign in to comment.