Expand StmtBlock inline size.

This commit is contained in:
Stephen Chung 2022-02-16 12:57:26 +08:00
parent 487d523e67
commit cf0660e36b
5 changed files with 28 additions and 23 deletions

View File

@ -1,7 +1,7 @@
//! Module defining the AST (abstract syntax tree). //! Module defining the AST (abstract syntax tree).
use super::{Expr, FnAccess, Stmt, StmtBlock, AST_OPTION_FLAGS::*}; use super::{Expr, FnAccess, Stmt, StmtBlock, StmtBlockContainer, AST_OPTION_FLAGS::*};
use crate::{Dynamic, FnNamespace, Identifier, Position, StaticVec}; use crate::{Dynamic, FnNamespace, Identifier, Position};
#[cfg(feature = "no_std")] #[cfg(feature = "no_std")]
use std::prelude::v1::*; use std::prelude::v1::*;
use std::{ use std::{
@ -197,7 +197,7 @@ impl AST {
#[allow(dead_code)] #[allow(dead_code)]
#[inline(always)] #[inline(always)]
#[must_use] #[must_use]
pub(crate) fn take_statements(&mut self) -> StaticVec<Stmt> { pub(crate) fn take_statements(&mut self) -> StmtBlockContainer {
self.body.take_statements() self.body.take_statements()
} }
/// Does this [`AST`] contain script-defined functions? /// Does this [`AST`] contain script-defined functions?

View File

@ -16,7 +16,10 @@ pub use ident::Ident;
pub use script_fn::EncapsulatedEnviron; pub use script_fn::EncapsulatedEnviron;
#[cfg(not(feature = "no_function"))] #[cfg(not(feature = "no_function"))]
pub use script_fn::{ScriptFnDef, ScriptFnMetadata}; 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"))] #[cfg(not(feature = "no_float"))]
pub use expr::FloatWrapper; pub use expr::FloatWrapper;

View File

@ -131,10 +131,12 @@ pub struct TryCatchBlock {
pub catch_block: StmtBlock, pub catch_block: StmtBlock,
} }
pub type StmtBlockContainer = smallvec::SmallVec<[Stmt; 8]>;
/// _(internals)_ A scoped block of statements. /// _(internals)_ A scoped block of statements.
/// Exported under the `internals` feature only. /// Exported under the `internals` feature only.
#[derive(Clone, Hash, Default)] #[derive(Clone, Hash, Default)]
pub struct StmtBlock(StaticVec<Stmt>, Span); pub struct StmtBlock(StmtBlockContainer, Span);
impl StmtBlock { impl StmtBlock {
/// A [`StmtBlock`] that does not exist. /// A [`StmtBlock`] that does not exist.
@ -147,7 +149,7 @@ impl StmtBlock {
start_pos: Position, start_pos: Position,
end_pos: Position, end_pos: Position,
) -> Self { ) -> Self {
let mut statements: StaticVec<_> = statements.into_iter().collect(); let mut statements: smallvec::SmallVec<_> = statements.into_iter().collect();
statements.shrink_to_fit(); statements.shrink_to_fit();
Self(statements, Span::new(start_pos, end_pos)) Self(statements, Span::new(start_pos, end_pos))
} }
@ -155,7 +157,7 @@ impl StmtBlock {
#[inline(always)] #[inline(always)]
#[must_use] #[must_use]
pub const fn empty(pos: Position) -> Self { 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? /// Is this statements block empty?
#[inline(always)] #[inline(always)]
@ -178,7 +180,7 @@ impl StmtBlock {
/// Extract the statements. /// Extract the statements.
#[inline(always)] #[inline(always)]
#[must_use] #[must_use]
pub(crate) fn take_statements(&mut self) -> StaticVec<Stmt> { pub(crate) fn take_statements(&mut self) -> StmtBlockContainer {
mem::take(&mut self.0) mem::take(&mut self.0)
} }
/// Get an iterator over the statements of this statements block. /// Get an iterator over the statements of this statements block.
@ -223,7 +225,7 @@ impl StmtBlock {
} }
impl Deref for StmtBlock { impl Deref for StmtBlock {
type Target = StaticVec<Stmt>; type Target = StmtBlockContainer;
#[inline(always)] #[inline(always)]
fn deref(&self) -> &Self::Target { fn deref(&self) -> &Self::Target {
@ -268,7 +270,7 @@ impl From<Stmt> for StmtBlock {
fn from(stmt: Stmt) -> Self { fn from(stmt: Stmt) -> Self {
match stmt { match stmt {
Stmt::Block(mut block, span) => Self(block.iter_mut().map(mem::take).collect(), span), 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(); let pos = stmt.position();
Self(vec![stmt].into(), Span::new(pos, Position::NONE)) Self(vec![stmt].into(), Span::new(pos, Position::NONE))
@ -279,7 +281,7 @@ impl From<Stmt> for StmtBlock {
impl IntoIterator for StmtBlock { impl IntoIterator for StmtBlock {
type Item = Stmt; type Item = Stmt;
type IntoIter = smallvec::IntoIter<[Stmt; 3]>; type IntoIter = smallvec::IntoIter<[Stmt; 8]>;
#[inline(always)] #[inline(always)]
fn into_iter(self) -> Self::IntoIter { fn into_iter(self) -> Self::IntoIter {

View File

@ -1,7 +1,7 @@
//! Module implementing the [`AST`] optimizer. //! Module implementing the [`AST`] optimizer.
#![cfg(not(feature = "no_optimize"))] #![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::engine::{KEYWORD_DEBUG, KEYWORD_EVAL, KEYWORD_FN_PTR, KEYWORD_PRINT, KEYWORD_TYPE_OF};
use crate::eval::{EvalState, GlobalRuntimeState}; use crate::eval::{EvalState, GlobalRuntimeState};
use crate::func::builtin::get_builtin_binary_op_fn; use crate::func::builtin::get_builtin_binary_op_fn;
@ -184,12 +184,12 @@ fn has_native_fn_override(
/// Optimize a block of [statements][Stmt]. /// Optimize a block of [statements][Stmt].
fn optimize_stmt_block( fn optimize_stmt_block(
mut statements: StaticVec<Stmt>, mut statements: StmtBlockContainer,
state: &mut OptimizerState, state: &mut OptimizerState,
preserve_result: bool, preserve_result: bool,
is_internal: bool, is_internal: bool,
reduce_return: bool, reduce_return: bool,
) -> StaticVec<Stmt> { ) -> StmtBlockContainer {
if statements.is_empty() { if statements.is_empty() {
return statements; 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. /// Constants and variables from the scope are added.
fn optimize_top_level( fn optimize_top_level(
statements: StaticVec<Stmt>, statements: StmtBlockContainer,
engine: &Engine, engine: &Engine,
scope: &Scope, scope: &Scope,
#[cfg(not(feature = "no_function"))] lib: &[&crate::Module], #[cfg(not(feature = "no_function"))] lib: &[&crate::Module],
optimization_level: OptimizationLevel, optimization_level: OptimizationLevel,
) -> StaticVec<Stmt> { ) -> StmtBlockContainer {
let mut statements = statements; let mut statements = statements;
// If optimization level is None then skip optimizing // 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); optimize_stmt_block(statements, &mut state, true, false, true)
statements
} }
/// Optimize an [`AST`]. /// Optimize an [`AST`].
pub fn optimize_into_ast( pub fn optimize_into_ast(
engine: &Engine, engine: &Engine,
scope: &Scope, scope: &Scope,
statements: StaticVec<Stmt>, statements: StmtBlockContainer,
#[cfg(not(feature = "no_function"))] functions: StaticVec< #[cfg(not(feature = "no_function"))] functions: StaticVec<
crate::Shared<crate::ast::ScriptFnDef>, crate::Shared<crate::ast::ScriptFnDef>,
>, >,

View File

@ -5,7 +5,8 @@ use crate::api::events::VarDefInfo;
use crate::api::options::LanguageOptions; use crate::api::options::LanguageOptions;
use crate::ast::{ use crate::ast::{
BinaryExpr, ConditionalStmtBlock, CustomExpr, Expr, FnCallExpr, FnCallHashes, Ident, 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::engine::{Precedence, KEYWORD_THIS, OP_CONTAINS};
use crate::eval::{EvalState, GlobalRuntimeState}; 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)); statements.push(Stmt::Expr(expr));
#[cfg(not(feature = "no_optimize"))] #[cfg(not(feature = "no_optimize"))]
@ -3507,8 +3508,8 @@ impl Engine {
&self, &self,
input: &mut TokenStream, input: &mut TokenStream,
state: &mut ParseState, state: &mut ParseState,
) -> ParseResult<(StaticVec<Stmt>, StaticVec<Shared<ScriptFnDef>>)> { ) -> ParseResult<(StmtBlockContainer, StaticVec<Shared<ScriptFnDef>>)> {
let mut statements = StaticVec::new_const(); let mut statements = smallvec::SmallVec::new_const();
let mut functions = BTreeMap::new(); let mut functions = BTreeMap::new();
while !input.peek().expect(NEVER_ENDS).0.is_eof() { while !input.peek().expect(NEVER_ENDS).0.is_eof() {