From 91415b9750c77abca2831b8cfe3cf13867cbfd63 Mon Sep 17 00:00:00 2001 From: Stephen Chung Date: Sat, 29 Oct 2022 14:59:20 +0800 Subject: [PATCH] Use ImmutableString in more places. --- src/api/definitions/mod.rs | 4 +-- src/ast/expr.rs | 2 +- src/bin/rhai-dbg.rs | 4 +-- src/eval/debugger.rs | 31 ++++++++----------- src/func/call.rs | 2 +- src/module/mod.rs | 2 +- src/packages/debugging.rs | 2 +- src/packages/fn_basic.rs | 2 +- src/tests.rs | 2 +- src/types/fn_ptr.rs | 61 ++++++++------------------------------ src/types/scope.rs | 18 ++++++----- 11 files changed, 45 insertions(+), 85 deletions(-) diff --git a/src/api/definitions/mod.rs b/src/api/definitions/mod.rs index 18d9c992..3ee43af0 100644 --- a/src/api/definitions/mod.rs +++ b/src/api/definitions/mod.rs @@ -442,8 +442,8 @@ impl Module { if f.access != FnAccess::Private { #[cfg(not(feature = "no_custom_syntax"))] - let operator = def.engine.custom_keywords.contains_key(&f.name) - || (!f.name.contains('$') && !is_valid_function_name(&f.name)); + let operator = def.engine.custom_keywords.contains_key(f.name.as_str()) + || (!f.name.contains('$') && !is_valid_function_name(f.name.as_str())); #[cfg(feature = "no_custom_syntax")] let operator = !f.name.contains('$') && !is_valid_function_name(&f.name); diff --git a/src/ast/expr.rs b/src/ast/expr.rs index 88bac79b..863299c8 100644 --- a/src/ast/expr.rs +++ b/src/ast/expr.rs @@ -619,7 +619,7 @@ impl Expr { if !x.is_qualified() && x.args.len() == 1 && x.name == KEYWORD_FN_PTR => { if let Self::StringConstant(ref s, ..) = x.args[0] { - FnPtr::new(s).ok()?.into() + FnPtr::new(s.clone()).ok()?.into() } else { return None; } diff --git a/src/bin/rhai-dbg.rs b/src/bin/rhai-dbg.rs index 5649c0c1..04284050 100644 --- a/src/bin/rhai-dbg.rs +++ b/src/bin/rhai-dbg.rs @@ -516,7 +516,7 @@ fn debug_callback( if range.contains(&n) { let bp = rhai::debugger::BreakPoint::AtPosition { - source: source.unwrap_or("").into(), + source: source.map(|s| s.into()), pos: Position::new(n as u16, 0), enabled: true, }; @@ -546,7 +546,7 @@ fn debug_callback( #[cfg(not(feature = "no_position"))] ["break" | "b"] => { let bp = rhai::debugger::BreakPoint::AtPosition { - source: source.unwrap_or("").into(), + source: source.map(|s| s.into()), pos, enabled: true, }; diff --git a/src/eval/debugger.rs b/src/eval/debugger.rs index 913f66a5..f87e4a81 100644 --- a/src/eval/debugger.rs +++ b/src/eval/debugger.rs @@ -4,8 +4,7 @@ use super::{EvalContext, GlobalRuntimeState}; use crate::ast::{ASTNode, Expr, Stmt}; use crate::{ - Dynamic, Engine, EvalAltResult, Identifier, ImmutableString, Module, Position, RhaiResultOf, - Scope, + Dynamic, Engine, EvalAltResult, ImmutableString, Module, Position, RhaiResultOf, Scope, }; #[cfg(feature = "no_std")] use std::prelude::v1::*; @@ -103,12 +102,10 @@ pub enum BreakPoint { /// Break at a particular position under a particular source. /// /// Not available under `no_position`. - /// - /// Source is empty if not available. #[cfg(not(feature = "no_position"))] AtPosition { /// Source (empty if not available) of the break-point. - source: Identifier, + source: Option, /// [Position] of the break-point. pos: Position, /// Is the break-point enabled? @@ -117,14 +114,14 @@ pub enum BreakPoint { /// Break at a particular function call. AtFunctionName { /// Function name. - name: Identifier, + name: ImmutableString, /// Is the break-point enabled? enabled: bool, }, /// Break at a particular function call with a particular number of arguments. AtFunctionCall { /// Function name. - name: Identifier, + name: ImmutableString, /// Number of arguments. args: usize, /// Is the break-point enabled? @@ -136,7 +133,7 @@ pub enum BreakPoint { #[cfg(not(feature = "no_object"))] AtProperty { /// Property name. - name: Identifier, + name: ImmutableString, /// Is the break-point enabled? enabled: bool, }, @@ -151,7 +148,7 @@ impl fmt::Display for BreakPoint { pos, enabled, } => { - if !source.is_empty() { + if let Some(ref source) = source { write!(f, "{source} ")?; } write!(f, "@ {pos:?}")?; @@ -226,7 +223,7 @@ impl BreakPoint { #[derive(Debug, Clone, Hash)] pub struct CallStackFrame { /// Function name. - pub fn_name: Identifier, + pub fn_name: ImmutableString, /// Copies of function call arguments, if any. pub args: crate::StaticVec, /// Source of the function. @@ -296,7 +293,7 @@ impl Debugger { #[inline(always)] pub(crate) fn push_call_stack_frame( &mut self, - fn_name: impl Into, + fn_name: ImmutableString, args: crate::StaticVec, source: Option, pos: Position, @@ -331,7 +328,7 @@ impl Debugger { } /// Returns the first break-point triggered by a particular [`AST` Node][ASTNode]. #[must_use] - pub fn is_break_point(&self, src: &str, node: ASTNode) -> Option { + pub fn is_break_point(&self, src: Option<&str>, node: ASTNode) -> Option { let _src = src; self.break_points() @@ -343,11 +340,12 @@ impl Debugger { BreakPoint::AtPosition { pos, .. } if pos.is_none() => false, #[cfg(not(feature = "no_position"))] BreakPoint::AtPosition { source, pos, .. } if pos.is_beginning_of_line() => { - node.position().line().unwrap_or(0) == pos.line().unwrap() && _src == source + node.position().line().unwrap_or(0) == pos.line().unwrap() + && _src == source.as_ref().map(|s| s.as_str()) } #[cfg(not(feature = "no_position"))] BreakPoint::AtPosition { source, pos, .. } => { - node.position() == *pos && _src == source + node.position() == *pos && _src == source.as_ref().map(|s| s.as_str()) } BreakPoint::AtFunctionName { name, .. } => match node { ASTNode::Expr(Expr::FnCall(x, ..)) | ASTNode::Stmt(Stmt::FnCall(x, ..)) => { @@ -490,10 +488,7 @@ impl Engine { let event = match event { Some(e) => e, - None => match global - .debugger - .is_break_point(global.source().unwrap_or(""), node) - { + None => match global.debugger.is_break_point(global.source(), node) { Some(bp) => DebuggerEvent::BreakPoint(bp), None => return Ok(None), }, diff --git a/src/func/call.rs b/src/func/call.rs index 5c3fbf43..ef5d77e7 100644 --- a/src/func/call.rs +++ b/src/func/call.rs @@ -400,7 +400,7 @@ impl Engine { #[cfg(feature = "debugging")] if self.debugger.is_some() { global.debugger.push_call_stack_frame( - name, + self.get_interned_string(name), args.iter().map(|v| (*v).clone()).collect(), source.clone().or_else(|| global.source.clone()), pos, diff --git a/src/module/mod.rs b/src/module/mod.rs index 37a0e167..59ead075 100644 --- a/src/module/mod.rs +++ b/src/module/mod.rs @@ -72,7 +72,7 @@ pub struct FuncInfo { /// Function access mode. pub access: FnAccess, /// Function name. - pub name: Identifier, + pub name: ImmutableString, /// Number of parameters. pub num_params: usize, /// Parameter types (if applicable). diff --git a/src/packages/debugging.rs b/src/packages/debugging.rs index eba64f5e..8a800c1b 100644 --- a/src/packages/debugging.rs +++ b/src/packages/debugging.rs @@ -40,7 +40,7 @@ mod debugging_functions { .iter() .rev() .filter(|crate::debugger::CallStackFrame { fn_name, args, .. }| { - fn_name != "back_trace" || !args.is_empty() + fn_name.as_str() != "back_trace" || !args.is_empty() }) .map( |frame @ crate::debugger::CallStackFrame { diff --git a/src/packages/fn_basic.rs b/src/packages/fn_basic.rs index 505a08b5..130646c3 100644 --- a/src/packages/fn_basic.rs +++ b/src/packages/fn_basic.rs @@ -27,7 +27,7 @@ mod fn_ptr_functions { /// ``` #[rhai_fn(name = "name", get = "name", pure)] pub fn name(fn_ptr: &mut FnPtr) -> ImmutableString { - fn_ptr.fn_name_raw().into() + fn_ptr.fn_name_raw().clone() } /// Return `true` if the function is an anonymous function. diff --git a/src/tests.rs b/src/tests.rs index c91a1e1e..34186402 100644 --- a/src/tests.rs +++ b/src/tests.rs @@ -35,7 +35,7 @@ fn check_struct_sizes() { #[cfg(target_pointer_width = "64")] { assert_eq!(size_of::(), 536); - assert_eq!(size_of::(), 80); + assert_eq!(size_of::(), 64); assert_eq!(size_of::(), 56); assert_eq!( size_of::(), diff --git a/src/types/fn_ptr.rs b/src/types/fn_ptr.rs index ab39e9b9..8c5d4b1f 100644 --- a/src/types/fn_ptr.rs +++ b/src/types/fn_ptr.rs @@ -3,7 +3,7 @@ use crate::tokenizer::is_valid_identifier; use crate::types::dynamic::Variant; use crate::{ - Dynamic, Engine, FuncArgs, Identifier, Module, NativeCallContext, Position, RhaiError, + Dynamic, Engine, FuncArgs, ImmutableString, Module, NativeCallContext, Position, RhaiError, RhaiResult, RhaiResultOf, StaticVec, AST, ERR, }; #[cfg(feature = "no_std")] @@ -18,7 +18,7 @@ use std::{ /// to be passed onto a function during a call. #[derive(Clone, Hash)] pub struct FnPtr { - name: Identifier, + name: ImmutableString, curry: StaticVec, } @@ -42,13 +42,16 @@ impl fmt::Debug for FnPtr { impl FnPtr { /// Create a new function pointer. #[inline(always)] - pub fn new(name: impl Into) -> RhaiResultOf { + pub fn new(name: impl Into) -> RhaiResultOf { name.into().try_into() } /// Create a new function pointer without checking its parameters. #[inline(always)] #[must_use] - pub(crate) fn new_unchecked(name: impl Into, curry: StaticVec) -> Self { + pub(crate) fn new_unchecked( + name: impl Into, + curry: StaticVec, + ) -> Self { Self { name: name.into(), curry, @@ -63,13 +66,13 @@ impl FnPtr { /// Get the name of the function. #[inline(always)] #[must_use] - pub(crate) const fn fn_name_raw(&self) -> &Identifier { + pub(crate) const fn fn_name_raw(&self) -> &ImmutableString { &self.name } /// Get the underlying data of the function pointer. #[inline(always)] #[must_use] - pub(crate) fn take_data(self) -> (Identifier, StaticVec) { + pub(crate) fn take_data(self) -> (ImmutableString, StaticVec) { (self.name, self.curry) } /// Get the curried arguments. @@ -246,11 +249,11 @@ impl fmt::Display for FnPtr { } } -impl TryFrom for FnPtr { +impl TryFrom for FnPtr { type Error = RhaiError; - #[inline] - fn try_from(value: Identifier) -> RhaiResultOf { + #[inline(always)] + fn try_from(value: ImmutableString) -> RhaiResultOf { if is_valid_identifier(value.chars()) { Ok(Self { name: value, @@ -261,43 +264,3 @@ impl TryFrom for FnPtr { } } } - -impl TryFrom for FnPtr { - type Error = RhaiError; - - #[inline(always)] - fn try_from(value: crate::ImmutableString) -> RhaiResultOf { - let s: Identifier = value.into(); - Self::try_from(s) - } -} - -impl TryFrom for FnPtr { - type Error = RhaiError; - - #[inline(always)] - fn try_from(value: String) -> RhaiResultOf { - let s: Identifier = value.into(); - Self::try_from(s) - } -} - -impl TryFrom> for FnPtr { - type Error = RhaiError; - - #[inline(always)] - fn try_from(value: Box) -> RhaiResultOf { - let s: Identifier = value.into(); - Self::try_from(s) - } -} - -impl TryFrom<&str> for FnPtr { - type Error = RhaiError; - - #[inline(always)] - fn try_from(value: &str) -> RhaiResultOf { - let s: Identifier = value.into(); - Self::try_from(s) - } -} diff --git a/src/types/scope.rs b/src/types/scope.rs index 435042e8..ba699c24 100644 --- a/src/types/scope.rs +++ b/src/types/scope.rs @@ -1,7 +1,7 @@ //! Module that defines the [`Scope`] type representing a function call-stack scope. use super::dynamic::{AccessMode, Variant}; -use crate::{Dynamic, Identifier}; +use crate::{Dynamic, Identifier, ImmutableString}; use smallvec::SmallVec; #[cfg(feature = "no_std")] use std::prelude::v1::*; @@ -75,7 +75,7 @@ pub struct Scope<'a, const N: usize = SCOPE_ENTRIES_INLINED> { /// Name of the entry. names: SmallVec<[Identifier; SCOPE_ENTRIES_INLINED]>, /// Aliases of the entry. - aliases: SmallVec<[Vec; SCOPE_ENTRIES_INLINED]>, + aliases: SmallVec<[Vec; SCOPE_ENTRIES_INLINED]>, /// Phantom to keep the lifetime parameter in order not to break existing code. dummy: PhantomData<&'a ()>, } @@ -125,7 +125,7 @@ impl Clone for Scope<'_> { } impl IntoIterator for Scope<'_> { - type Item = (String, Dynamic, Vec); + type Item = (String, Dynamic, Vec); type IntoIter = Box>; #[must_use] @@ -140,7 +140,7 @@ impl IntoIterator for Scope<'_> { } impl<'a> IntoIterator for &'a Scope<'_> { - type Item = (&'a Identifier, &'a Dynamic, &'a Vec); + type Item = (&'a Identifier, &'a Dynamic, &'a Vec); type IntoIter = Box + 'a>; #[must_use] @@ -669,7 +669,7 @@ impl Scope<'_> { /// Panics if the index is out of bounds. #[cfg(not(feature = "no_module"))] #[inline] - pub(crate) fn add_alias_by_index(&mut self, index: usize, alias: Identifier) -> &mut Self { + pub(crate) fn add_alias_by_index(&mut self, index: usize, alias: ImmutableString) -> &mut Self { let aliases = self.aliases.get_mut(index).unwrap(); if aliases.is_empty() || !aliases.contains(&alias) { aliases.push(alias); @@ -690,11 +690,11 @@ impl Scope<'_> { pub fn set_alias( &mut self, name: impl AsRef + Into, - alias: impl Into, + alias: impl Into, ) { if let Some(index) = self.search(name.as_ref()) { let alias = match alias.into() { - x if x.is_empty() => name.into(), + x if x.is_empty() => name.into().into(), x => x, }; self.add_alias_by_index(index, alias); @@ -727,7 +727,9 @@ impl Scope<'_> { } /// Get an iterator to entries in the [`Scope`]. #[allow(dead_code)] - pub(crate) fn into_iter(self) -> impl Iterator)> { + pub(crate) fn into_iter( + self, + ) -> impl Iterator)> { self.names .into_iter() .zip(self.values.into_iter().zip(self.aliases.into_iter()))