From 4e5d009386341b928895a4026029cbd7b4dab6d0 Mon Sep 17 00:00:00 2001 From: Stephen Chung Date: Fri, 12 Mar 2021 13:26:47 +0800 Subject: [PATCH] Inline scope entries. --- Cargo.toml | 60 +++++++++++++++++++++++----------------------------- src/scope.rs | 26 +++++++++++++++-------- 2 files changed, 43 insertions(+), 43 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 9ce632c5..f1759877 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,8 +1,5 @@ [workspace] -members = [ - ".", - "codegen" -] +members = [".", "codegen"] [package] name = "rhai" @@ -14,14 +11,9 @@ homepage = "https://rhai.rs" repository = "https://github.com/rhaiscript" readme = "README.md" license = "MIT OR Apache-2.0" -include = [ - "**/*.rs", - "scripts/*.rhai", - "**/*.md", - "Cargo.toml" -] -keywords = [ "scripting", "scripting-engine", "scripting-language", "embedded" ] -categories = [ "no-std", "embedded", "wasm", "parser-implementations" ] +include = ["**/*.rs", "scripts/*.rhai", "**/*.md", "Cargo.toml"] +keywords = ["scripting", "scripting-engine", "scripting-language", "embedded"] +categories = ["no-std", "embedded", "wasm", "parser-implementations"] [dependencies] smallvec = { version = "1.6", default-features = false, features = ["union"] } @@ -31,29 +23,29 @@ rhai_codegen = { version = "0.3.3", path = "codegen" } [features] default = [] -unchecked = [] # unchecked arithmetic -sync = [] # restrict to only types that implement Send + Sync -no_optimize = [] # no script optimizer -no_float = [] # no floating-point -f32_float = [] # set FLOAT=f32 -only_i32 = [] # set INT=i32 (useful for 32-bit systems) -only_i64 = [] # set INT=i64 (default) and disable support for all other integer types -decimal = [ "rust_decimal" ] # add the Decimal number type -no_index = [] # no arrays and indexing -no_object = [] # no custom objects -no_function = [ "no_closure" ] # no script-defined functions (meaning no closures) -no_closure = [] # no automatic sharing and capture of anonymous functions to external variables -no_module = [] # no modules -internals = [] # expose internal data structures -unicode-xid-ident = [ "unicode-xid" ] # allow Unicode Standard Annex #31 for identifiers. -metadata = [ "serde", "serde_json" ] # enables exporting functions metadata to JSON +unchecked = [] # unchecked arithmetic +sync = [] # restrict to only types that implement Send + Sync +no_optimize = [] # no script optimizer +no_float = [] # no floating-point +f32_float = [] # set FLOAT=f32 +only_i32 = [] # set INT=i32 (useful for 32-bit systems) +only_i64 = [] # set INT=i64 (default) and disable support for all other integer types +decimal = ["rust_decimal"] # add the Decimal number type +no_index = [] # no arrays and indexing +no_object = [] # no custom objects +no_function = ["no_closure"] # no script-defined functions (meaning no closures) +no_closure = [] # no automatic sharing and capture of anonymous functions to external variables +no_module = [] # no modules +internals = [] # expose internal data structures +unicode-xid-ident = ["unicode-xid"] # allow Unicode Standard Annex #31 for identifiers. +metadata = ["serde", "serde_json"] # enables exporting functions metadata to JSON # compiling for no-std -no_std = [ "smallvec/union", "num-traits/libm", "hashbrown", "core-error", "libm", "ahash/compile-time-rng" ] +no_std = ["smallvec/union", "num-traits/libm", "hashbrown", "core-error", "libm", "ahash/compile-time-rng"] # compiling for WASM -wasm-bindgen = [ "instant/wasm-bindgen" ] -stdweb = [ "instant/stdweb" ] +wasm-bindgen = ["instant/wasm-bindgen"] +stdweb = ["instant/stdweb"] [profile.release] lto = "fat" @@ -101,10 +93,10 @@ default_features = false optional = true [target.'cfg(target_arch = "wasm32")'.dependencies] -instant= { version = "0.1" } # WASM implementation of std::time::Instant +instant = { version = "0.1" } # WASM implementation of std::time::Instant [target.'cfg(target_arch = "wasm64")'.dependencies] -instant= { version = "0.1" } # WASM implementation of std::time::Instant +instant = { version = "0.1" } # WASM implementation of std::time::Instant [package.metadata.docs.rs] -features = [ "metadata", "internals", "decimal" ] +features = ["metadata", "internals", "decimal"] diff --git a/src/scope.rs b/src/scope.rs index 2071a75d..2fa8f235 100644 --- a/src/scope.rs +++ b/src/scope.rs @@ -4,6 +4,9 @@ use crate::dynamic::{AccessMode, Variant}; use crate::stdlib::{borrow::Cow, boxed::Box, iter, vec::Vec}; use crate::{Dynamic, ImmutableString, StaticVec}; +/// Keep a number of entries inline (since [`Dynamic`] is usually small enough). +const SCOPE_SIZE: usize = 16; + /// Type containing information about the current scope. /// Useful for keeping state between [`Engine`][crate::Engine] evaluation runs. /// @@ -49,17 +52,17 @@ use crate::{Dynamic, ImmutableString, StaticVec}; #[derive(Debug, Clone, Hash)] pub struct Scope<'a> { /// Current value of the entry. - values: Vec, + values: smallvec::SmallVec<[Dynamic; SCOPE_SIZE]>, /// (Name, aliases) of the entry. - names: Vec<(Cow<'a, str>, Box>)>, + names: Vec<(Cow<'a, str>, Option>>)>, } impl Default for Scope<'_> { #[inline(always)] fn default() -> Self { Self { - values: Vec::with_capacity(16), - names: Vec::with_capacity(16), + values: Default::default(), + names: Vec::with_capacity(SCOPE_SIZE), } } } @@ -244,7 +247,7 @@ impl<'a> Scope<'a> { access: AccessMode, mut value: Dynamic, ) -> &mut Self { - self.names.push((name.into(), Box::new(Default::default()))); + self.names.push((name.into(), None)); value.set_access_mode(access); self.values.push(value.into()); self @@ -413,8 +416,11 @@ impl<'a> Scope<'a> { alias: impl Into + PartialEq, ) -> &mut Self { let entry = self.names.get_mut(index).expect("invalid index in Scope"); - if !entry.1.iter().any(|a| &alias == a) { - entry.1.push(alias.into()); + if entry.1.is_none() { + entry.1 = Some(Default::default()); + } + if !entry.1.as_ref().unwrap().iter().any(|a| &alias == a) { + entry.1.as_mut().unwrap().push(alias.into()); } self } @@ -446,7 +452,9 @@ impl<'a> Scope<'a> { self.names .into_iter() .zip(self.values.into_iter()) - .map(|((name, alias), value)| (name, value, alias.to_vec())) + .map(|((name, alias), value)| { + (name, value, alias.map(|a| a.to_vec()).unwrap_or_default()) + }) } /// Get an iterator to entries in the [`Scope`]. /// Shared values are flatten-cloned. @@ -493,7 +501,7 @@ impl<'a, K: Into>> iter::Extend<(K, Dynamic)> for Scope<'a> { #[inline(always)] fn extend>(&mut self, iter: T) { iter.into_iter().for_each(|(name, value)| { - self.names.push((name.into(), Box::new(Default::default()))); + self.names.push((name.into(), None)); self.values.push(value); }); }