Skip to content

Commit

Permalink
Use ThinVec.
Browse files Browse the repository at this point in the history
  • Loading branch information
schungx committed Dec 4, 2023
1 parent c82fa78 commit d9a0e94
Show file tree
Hide file tree
Showing 14 changed files with 41 additions and 55 deletions.
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ categories = ["no-std", "embedded", "wasm", "parser-implementations"]

[dependencies]
smallvec = { version = "1.7.0", default-features = false, features = ["union", "const_new", "const_generics"] }
thin-vec = { version = "0.2.13", default-features = false }
ahash = { version = "0.8.2", default-features = false, features = ["compile-time-rng"] }
num-traits = { version = "0.2.0", default-features = false }
once_cell = { version = "1.7.0", default-features = false, features = ["race"] }
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ Standard features
* Built-in support for most common [data types](https://rhai.rs/book/language/values-and-types.html) including booleans, [integers](https://rhai.rs/book/language/numbers.html), [floating-point numbers](https://rhai.rs/book/language/numbers.html) (including [`Decimal`](https://crates.io/crates/rust_decimal)), [strings](https://rhai.rs/book/language/strings-chars.html), [Unicode characters](https://rhai.rs/book/language/strings-chars.html), [arrays](https://rhai.rs/book/language/arrays.html) (including packed [byte arrays](https://rhai.rs/book/language/blobs.html)) and [object maps](https://rhai.rs/book/language/object-maps.html).
* Easily [call a script-defined function](https://rhai.rs/book/engine/call-fn.html) from Rust.
* Relatively little `unsafe` code (yes there are some for performance reasons).
* Few dependencies - currently only [`smallvec`](https://crates.io/crates/smallvec), [`num-traits`](https://crates.io/crates/num-traits), [`once_cell`](https://crates.io/crates/once_cell), [`ahash`](https://crates.io/crates/ahash), [`bitflags`](https://crates.io/crates/bitflags) and [`smartstring`](https://crates.io/crates/smartstring).
* Few dependencies - currently only [`smallvec`](https://crates.io/crates/smallvec), [`thin-vec`](https://crates.io/crates/thin-vec), [`num-traits`](https://crates.io/crates/num-traits), [`once_cell`](https://crates.io/crates/once_cell), [`ahash`](https://crates.io/crates/ahash), [`bitflags`](https://crates.io/crates/bitflags) and [`smartstring`](https://crates.io/crates/smartstring).
* Re-entrant scripting engine can be made `Send + Sync` (via the `sync` feature).
* Compile once to [AST](https://rhai.rs/book/engine/compile.html) form for repeated evaluations.
* Scripts are [optimized](https://rhai.rs/book/engine/optimize) (useful for template-based machine-generated scripts).
Expand Down
9 changes: 5 additions & 4 deletions src/ast/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ use crate::engine::KEYWORD_FN_PTR;
use crate::tokenizer::Token;
use crate::types::dynamic::Union;
use crate::{
calc_fn_hash, Dynamic, FnArgsVec, FnPtr, Identifier, ImmutableString, Position, SmartString,
StaticVec, INT,
calc_fn_hash, Dynamic, FnPtr, Identifier, ImmutableString, Position, SmartString, StaticVec,
INT,
};
#[cfg(feature = "no_std")]
use std::prelude::v1::*;
Expand All @@ -19,6 +19,7 @@ use std::{
mem,
num::{NonZeroU8, NonZeroUsize},
};
use thin_vec::ThinVec;

/// _(internals)_ A binary expression.
/// Exported under the `internals` feature only.
Expand Down Expand Up @@ -266,9 +267,9 @@ pub enum Expr {
/// [String][ImmutableString] constant.
StringConstant(ImmutableString, Position),
/// An interpolated [string][ImmutableString].
InterpolatedString(Box<FnArgsVec<Expr>>, Position),
InterpolatedString(ThinVec<Expr>, Position),
/// [ expr, ... ]
Array(Box<FnArgsVec<Expr>>, Position),
Array(ThinVec<Expr>, Position),
/// #{ name:expr, ... }
Map(
Box<(StaticVec<(Ident, Expr)>, BTreeMap<Identifier, Dynamic>)>,
Expand Down
19 changes: 0 additions & 19 deletions src/ast/namespace.rs
Original file line number Diff line number Diff line change
Expand Up @@ -66,25 +66,6 @@ impl fmt::Display for Namespace {
}
}

impl From<Vec<Ident>> for Namespace {
#[inline]
fn from(mut path: Vec<Ident>) -> Self {
path.shrink_to_fit();
Self {
index: None,
path: path.into(),
}
}
}

impl From<StaticVec<Ident>> for Namespace {
#[inline]
fn from(mut path: StaticVec<Ident>) -> Self {
path.shrink_to_fit();
Self { index: None, path }
}
}

impl Namespace {
/// Constant for no namespace.
pub const NONE: Self = Self {
Expand Down
2 changes: 1 addition & 1 deletion src/eval/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ pub fn search_scope_only<'s>(
{
let val: Dynamic = crate::FnPtr {
name: v.3.clone(),
curry: Vec::new(),
curry: thin_vec::ThinVec::new(),
environ: None,
fn_def: Some(fn_def.clone()),
}
Expand Down
12 changes: 6 additions & 6 deletions src/eval/global_state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,14 +25,14 @@ pub type SharedGlobalConstants =
pub struct GlobalRuntimeState {
/// Names of imported [modules][crate::Module].
#[cfg(not(feature = "no_module"))]
imports: Vec<ImmutableString>,
imports: thin_vec::ThinVec<ImmutableString>,
/// Stack of imported [modules][crate::Module].
#[cfg(not(feature = "no_module"))]
modules: Vec<crate::SharedModule>,
modules: thin_vec::ThinVec<crate::SharedModule>,

/// The current stack of loaded [modules][crate::Module] containing script-defined functions.
#[cfg(not(feature = "no_function"))]
pub lib: Vec<crate::SharedModule>,
pub lib: thin_vec::ThinVec<crate::SharedModule>,
/// Source of the current context.
///
/// No source if the string is empty.
Expand Down Expand Up @@ -82,11 +82,11 @@ impl GlobalRuntimeState {
pub fn new(engine: &Engine) -> Self {
Self {
#[cfg(not(feature = "no_module"))]
imports: Vec::new(),
imports: thin_vec::ThinVec::new(),
#[cfg(not(feature = "no_module"))]
modules: Vec::new(),
modules: thin_vec::ThinVec::new(),
#[cfg(not(feature = "no_function"))]
lib: Vec::new(),
lib: thin_vec::ThinVec::new(),
source: None,
num_operations: 0,
#[cfg(not(feature = "no_module"))]
Expand Down
2 changes: 1 addition & 1 deletion src/func/callable_function.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ pub struct EncapsulatedEnviron {
pub lib: crate::SharedModule,
/// Imported [modules][crate::Module].
#[cfg(not(feature = "no_module"))]
pub imports: Vec<(crate::ImmutableString, crate::SharedModule)>,
pub imports: thin_vec::ThinVec<(crate::ImmutableString, crate::SharedModule)>,
/// Globally-defined constants.
#[cfg(not(feature = "no_module"))]
#[cfg(not(feature = "no_function"))]
Expand Down
2 changes: 1 addition & 1 deletion src/module/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2195,7 +2195,7 @@ impl Module {
let mut module = Self::new();

// Extra modules left become sub-modules
let mut imports = Vec::new();
let mut imports = thin_vec::ThinVec::new();

if result.is_ok() {
global
Expand Down
2 changes: 1 addition & 1 deletion src/optimizer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ impl<'a> OptimizerState<'a> {

#[cfg(not(feature = "no_function"))]
{
_global.lib = _lib.to_vec();
_global.lib = _lib.into();
}

Self {
Expand Down
2 changes: 1 addition & 1 deletion src/packages/arithmetic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -381,7 +381,7 @@ mod f32_functions {
"Number raised to too large an index: {x} ** {y}"
)))
} else {
#[allow(clippy::cast_possible_truncation)]
#[allow(clippy::cast_possible_truncation, clippy::unnecessary_cast)]
Ok(x.powi(y as i32))
}
}
Expand Down
4 changes: 2 additions & 2 deletions src/packages/array_basic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,14 @@ use crate::engine::OP_EQUALS;
use crate::eval::{calc_index, calc_offset_len};
use crate::module::ModuleFlags;
use crate::plugin::*;

use crate::{
def_package, Array, Dynamic, ExclusiveRange, FnPtr, InclusiveRange, NativeCallContext,
Position, RhaiResultOf, ERR, INT, MAX_USIZE_INT,
};
#[cfg(feature = "no_std")]
use std::prelude::v1::*;
use std::{any::TypeId, cmp::Ordering, mem};
use thin_vec::ThinVec;

def_package! {
/// Package of basic array utilities.
Expand Down Expand Up @@ -1272,7 +1272,7 @@ pub mod array_functions {
pub fn dedup(ctx: NativeCallContext, array: &mut Array) {
let comparer = FnPtr {
name: ctx.engine().get_interned_string(OP_EQUALS),
curry: Vec::new(),
curry: ThinVec::new(),
environ: None,
#[cfg(not(feature = "no_function"))]
fn_def: None,
Expand Down
11 changes: 6 additions & 5 deletions src/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ use std::{
hash::{Hash, Hasher},
num::{NonZeroU8, NonZeroUsize},
};
use thin_vec::ThinVec;

pub type ParseResult<T> = Result<T, ParseError>;

Expand Down Expand Up @@ -956,7 +957,7 @@ impl Engine {
// [ ...
settings.pos = eat_token(input, &Token::LeftBracket);

let mut array = FnArgsVec::new_const();
let mut array = ThinVec::new();

loop {
const MISSING_RBRACKET: &str = "to end this array literal";
Expand Down Expand Up @@ -1010,7 +1011,7 @@ impl Engine {

array.shrink_to_fit();

Ok(Expr::Array(array.into(), settings.pos))
Ok(Expr::Array(array, settings.pos))
}

/// Parse a map literal.
Expand Down Expand Up @@ -1543,7 +1544,7 @@ impl Engine {

// Interpolated string
Token::InterpolatedString(..) => {
let mut segments = FnArgsVec::new_const();
let mut segments = ThinVec::new();
let settings = settings.level_up()?;

match input.next().unwrap() {
Expand Down Expand Up @@ -1601,7 +1602,7 @@ impl Engine {
Expr::StringConstant(state.get_interned_string(""), settings.pos)
} else {
segments.shrink_to_fit();
Expr::InterpolatedString(segments.into(), settings.pos)
Expr::InterpolatedString(segments, settings.pos)
}
}

Expand Down Expand Up @@ -3883,7 +3884,7 @@ impl Engine {

let fn_ptr = crate::FnPtr {
name: fn_name,
curry: Vec::new(),
curry: ThinVec::new(),
environ: None,
#[cfg(not(feature = "no_function"))]
fn_def: Some(script.clone()),
Expand Down
7 changes: 4 additions & 3 deletions src/types/fn_ptr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,14 @@ use std::{
mem,
ops::{Index, IndexMut},
};
use thin_vec::ThinVec;

/// A general function pointer, which may carry additional (i.e. curried) argument values
/// to be passed onto a function during a call.
#[derive(Clone)]
pub struct FnPtr {
pub(crate) name: ImmutableString,
pub(crate) curry: Vec<Dynamic>,
pub(crate) curry: ThinVec<Dynamic>,
pub(crate) environ: Option<Shared<EncapsulatedEnviron>>,
#[cfg(not(feature = "no_function"))]
pub(crate) fn_def: Option<Shared<crate::ast::ScriptFnDef>>,
Expand Down Expand Up @@ -469,7 +470,7 @@ impl TryFrom<ImmutableString> for FnPtr {
if is_valid_function_name(&value) {
Ok(Self {
name: value,
curry: Vec::new(),
curry: ThinVec::new(),
environ: None,
#[cfg(not(feature = "no_function"))]
fn_def: None,
Expand All @@ -492,7 +493,7 @@ impl<T: Into<Shared<crate::ast::ScriptFnDef>>> From<T> for FnPtr {

Self {
name: fn_def.name.clone(),
curry: Vec::new(),
curry: ThinVec::new(),
environ: None,
fn_def: Some(fn_def),
}
Expand Down
21 changes: 11 additions & 10 deletions src/types/scope.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ use std::{
iter::{Extend, FromIterator},
marker::PhantomData,
};
use thin_vec::ThinVec;

/// Minimum number of entries in the [`Scope`] to avoid reallocations.
pub const MIN_SCOPE_ENTRIES: usize = 8;
Expand Down Expand Up @@ -61,14 +62,14 @@ pub const MIN_SCOPE_ENTRIES: usize = 8;
#[derive(Debug, Hash, Default)]
pub struct Scope<'a> {
/// Current value of the entry.
values: Vec<Dynamic>,
values: ThinVec<Dynamic>,
/// Name of the entry.
names: Vec<ImmutableString>,
names: ThinVec<ImmutableString>,
/// Aliases of the entry.
///
/// This `Vec` is not filled until needed because aliases are used rarely
/// (only for `export` statements).
aliases: Vec<Box<[ImmutableString]>>,
aliases: ThinVec<Box<[ImmutableString]>>,
/// Phantom to keep the lifetime parameter in order not to break existing code.
dummy: PhantomData<&'a ()>,
}
Expand Down Expand Up @@ -176,11 +177,11 @@ impl Scope<'_> {
/// ```
#[inline(always)]
#[must_use]
pub const fn new() -> Self {
pub fn new() -> Self {
Self {
values: Vec::new(),
names: Vec::new(),
aliases: Vec::new(),
values: ThinVec::new(),
names: ThinVec::new(),
aliases: ThinVec::new(),
dummy: PhantomData,
}
}
Expand All @@ -200,9 +201,9 @@ impl Scope<'_> {
#[must_use]
pub fn with_capacity(capacity: usize) -> Self {
Self {
values: Vec::with_capacity(capacity),
names: Vec::with_capacity(capacity),
aliases: Vec::new(),
values: ThinVec::with_capacity(capacity),
names: ThinVec::with_capacity(capacity),
aliases: ThinVec::new(),
dummy: PhantomData,
}
}
Expand Down

0 comments on commit d9a0e94

Please sign in to comment.