From cf0660e36b5c41ac0e5014fca97ab575cef2168f Mon Sep 17 00:00:00 2001 From: Stephen Chung Date: Wed, 16 Feb 2022 12:57:26 +0800 Subject: [PATCH] Expand StmtBlock inline size. --- src/ast/ast.rs | 6 +++--- src/ast/mod.rs | 5 ++++- src/ast/stmt.rs | 16 +++++++++------- src/optimizer.rs | 15 +++++++-------- src/parser.rs | 9 +++++---- 5 files changed, 28 insertions(+), 23 deletions(-) diff --git a/src/ast/ast.rs b/src/ast/ast.rs index 06fe65ec..dcf43977 100644 --- a/src/ast/ast.rs +++ b/src/ast/ast.rs @@ -1,7 +1,7 @@ //! Module defining the AST (abstract syntax tree). -use super::{Expr, FnAccess, Stmt, StmtBlock, AST_OPTION_FLAGS::*}; -use crate::{Dynamic, FnNamespace, Identifier, Position, StaticVec}; +use super::{Expr, FnAccess, Stmt, StmtBlock, StmtBlockContainer, AST_OPTION_FLAGS::*}; +use crate::{Dynamic, FnNamespace, Identifier, Position}; #[cfg(feature = "no_std")] use std::prelude::v1::*; use std::{ @@ -197,7 +197,7 @@ impl AST { #[allow(dead_code)] #[inline(always)] #[must_use] - pub(crate) fn take_statements(&mut self) -> StaticVec { + pub(crate) fn take_statements(&mut self) -> StmtBlockContainer { self.body.take_statements() } /// Does this [`AST`] contain script-defined functions? diff --git a/src/ast/mod.rs b/src/ast/mod.rs index 009b1199..3bfe2389 100644 --- a/src/ast/mod.rs +++ b/src/ast/mod.rs @@ -16,7 +16,10 @@ pub use ident::Ident; pub use script_fn::EncapsulatedEnviron; #[cfg(not(feature = "no_function"))] pub use script_fn::{ScriptFnDef, ScriptFnMetadata}; -pub use stmt::{ConditionalStmtBlock, OpAssignment, Stmt, StmtBlock, SwitchCases, TryCatchBlock}; +pub use stmt::{ + ConditionalStmtBlock, OpAssignment, Stmt, StmtBlock, StmtBlockContainer, SwitchCases, + TryCatchBlock, +}; #[cfg(not(feature = "no_float"))] pub use expr::FloatWrapper; diff --git a/src/ast/stmt.rs b/src/ast/stmt.rs index 27962878..08ab0f21 100644 --- a/src/ast/stmt.rs +++ b/src/ast/stmt.rs @@ -131,10 +131,12 @@ pub struct TryCatchBlock { pub catch_block: StmtBlock, } +pub type StmtBlockContainer = smallvec::SmallVec<[Stmt; 8]>; + /// _(internals)_ A scoped block of statements. /// Exported under the `internals` feature only. #[derive(Clone, Hash, Default)] -pub struct StmtBlock(StaticVec, Span); +pub struct StmtBlock(StmtBlockContainer, Span); impl StmtBlock { /// A [`StmtBlock`] that does not exist. @@ -147,7 +149,7 @@ impl StmtBlock { start_pos: Position, end_pos: Position, ) -> Self { - let mut statements: StaticVec<_> = statements.into_iter().collect(); + let mut statements: smallvec::SmallVec<_> = statements.into_iter().collect(); statements.shrink_to_fit(); Self(statements, Span::new(start_pos, end_pos)) } @@ -155,7 +157,7 @@ impl StmtBlock { #[inline(always)] #[must_use] pub const fn empty(pos: Position) -> Self { - Self(StaticVec::new_const(), Span::new(pos, pos)) + Self(smallvec::SmallVec::new_const(), Span::new(pos, pos)) } /// Is this statements block empty? #[inline(always)] @@ -178,7 +180,7 @@ impl StmtBlock { /// Extract the statements. #[inline(always)] #[must_use] - pub(crate) fn take_statements(&mut self) -> StaticVec { + pub(crate) fn take_statements(&mut self) -> StmtBlockContainer { mem::take(&mut self.0) } /// Get an iterator over the statements of this statements block. @@ -223,7 +225,7 @@ impl StmtBlock { } impl Deref for StmtBlock { - type Target = StaticVec; + type Target = StmtBlockContainer; #[inline(always)] fn deref(&self) -> &Self::Target { @@ -268,7 +270,7 @@ impl From for StmtBlock { fn from(stmt: Stmt) -> Self { match stmt { Stmt::Block(mut block, span) => Self(block.iter_mut().map(mem::take).collect(), span), - Stmt::Noop(pos) => Self(StaticVec::new_const(), Span::new(pos, pos)), + Stmt::Noop(pos) => Self(smallvec::SmallVec::new_const(), Span::new(pos, pos)), _ => { let pos = stmt.position(); Self(vec![stmt].into(), Span::new(pos, Position::NONE)) @@ -279,7 +281,7 @@ impl From for StmtBlock { impl IntoIterator for StmtBlock { type Item = Stmt; - type IntoIter = smallvec::IntoIter<[Stmt; 3]>; + type IntoIter = smallvec::IntoIter<[Stmt; 8]>; #[inline(always)] fn into_iter(self) -> Self::IntoIter { diff --git a/src/optimizer.rs b/src/optimizer.rs index 220fae23..e60a9922 100644 --- a/src/optimizer.rs +++ b/src/optimizer.rs @@ -1,7 +1,7 @@ //! Module implementing the [`AST`] optimizer. #![cfg(not(feature = "no_optimize"))] -use crate::ast::{Expr, OpAssignment, Stmt, AST_OPTION_FLAGS::*}; +use crate::ast::{Expr, OpAssignment, Stmt, StmtBlockContainer, AST_OPTION_FLAGS::*}; use crate::engine::{KEYWORD_DEBUG, KEYWORD_EVAL, KEYWORD_FN_PTR, KEYWORD_PRINT, KEYWORD_TYPE_OF}; use crate::eval::{EvalState, GlobalRuntimeState}; use crate::func::builtin::get_builtin_binary_op_fn; @@ -184,12 +184,12 @@ fn has_native_fn_override( /// Optimize a block of [statements][Stmt]. fn optimize_stmt_block( - mut statements: StaticVec, + mut statements: StmtBlockContainer, state: &mut OptimizerState, preserve_result: bool, is_internal: bool, reduce_return: bool, -) -> StaticVec { +) -> StmtBlockContainer { if statements.is_empty() { return statements; } @@ -1155,12 +1155,12 @@ fn optimize_expr(expr: &mut Expr, state: &mut OptimizerState, chaining: bool) { /// /// Constants and variables from the scope are added. fn optimize_top_level( - statements: StaticVec, + statements: StmtBlockContainer, engine: &Engine, scope: &Scope, #[cfg(not(feature = "no_function"))] lib: &[&crate::Module], optimization_level: OptimizationLevel, -) -> StaticVec { +) -> StmtBlockContainer { let mut statements = statements; // If optimization level is None then skip optimizing @@ -1186,15 +1186,14 @@ fn optimize_top_level( } } - statements = optimize_stmt_block(statements, &mut state, true, false, true); - statements + optimize_stmt_block(statements, &mut state, true, false, true) } /// Optimize an [`AST`]. pub fn optimize_into_ast( engine: &Engine, scope: &Scope, - statements: StaticVec, + statements: StmtBlockContainer, #[cfg(not(feature = "no_function"))] functions: StaticVec< crate::Shared, >, diff --git a/src/parser.rs b/src/parser.rs index 74f97c2a..e43c0fd1 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -5,7 +5,8 @@ use crate::api::events::VarDefInfo; use crate::api::options::LanguageOptions; use crate::ast::{ BinaryExpr, ConditionalStmtBlock, CustomExpr, Expr, FnCallExpr, FnCallHashes, Ident, - OpAssignment, ScriptFnDef, Stmt, SwitchCases, TryCatchBlock, AST_OPTION_FLAGS::*, + OpAssignment, ScriptFnDef, Stmt, StmtBlockContainer, SwitchCases, TryCatchBlock, + AST_OPTION_FLAGS::*, }; use crate::engine::{Precedence, KEYWORD_THIS, OP_CONTAINS}; use crate::eval::{EvalState, GlobalRuntimeState}; @@ -3481,7 +3482,7 @@ impl Engine { } } - let mut statements = StaticVec::new_const(); + let mut statements = smallvec::SmallVec::new_const(); statements.push(Stmt::Expr(expr)); #[cfg(not(feature = "no_optimize"))] @@ -3507,8 +3508,8 @@ impl Engine { &self, input: &mut TokenStream, state: &mut ParseState, - ) -> ParseResult<(StaticVec, StaticVec>)> { - let mut statements = StaticVec::new_const(); + ) -> ParseResult<(StmtBlockContainer, StaticVec>)> { + let mut statements = smallvec::SmallVec::new_const(); let mut functions = BTreeMap::new(); while !input.peek().expect(NEVER_ENDS).0.is_eof() {