From 65ef4024400df06177ac9fc1e86a68e291bc1bff Mon Sep 17 00:00:00 2001 From: Stephen Chung Date: Thu, 21 Oct 2021 19:17:34 +0800 Subject: [PATCH] Eliminate optimize module with no_optimize. --- CHANGELOG.md | 1 + src/engine.rs | 5 +++-- src/engine_api.rs | 29 ++++++++++++++++++++------- src/fn_call.rs | 4 ++-- src/lib.rs | 1 + src/parse.rs | 51 +++++++++++++++++++++++++++++++---------------- 6 files changed, 63 insertions(+), 28 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4826745c..f4efcd1e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,6 +16,7 @@ Enhancements * Array methods that take function pointers (e.g. closures) now optionally take the function name as a string. * Array adds the `dedup` method. * Inlining is disabled for error-path functions because errors are exceptional and scripts usually fail completely when an error is encountered. +* The `optimize` module is completely eliminated under `no_optimize`, which should yield smaller code size. Deprecated API's ---------------- diff --git a/src/engine.rs b/src/engine.rs index 0998d22f..b5349485 100644 --- a/src/engine.rs +++ b/src/engine.rs @@ -9,7 +9,6 @@ use crate::fn_native::{ OnVarCallback, }; use crate::module::NamespaceRef; -use crate::optimize::OptimizationLevel; use crate::packages::{Package, StandardPackage}; use crate::r#unsafe::unsafe_cast_var_name_to_lifetime; use crate::token::Token; @@ -979,7 +978,8 @@ pub struct Engine { pub(crate) progress: Option, /// Optimize the AST after compilation. - pub(crate) optimization_level: OptimizationLevel, + #[cfg(not(feature = "no_optimize"))] + pub(crate) optimization_level: crate::OptimizationLevel, /// Max limits. #[cfg(not(feature = "unchecked"))] @@ -1101,6 +1101,7 @@ impl Engine { #[cfg(not(feature = "unchecked"))] progress: None, + #[cfg(not(feature = "no_optimize"))] optimization_level: Default::default(), #[cfg(not(feature = "unchecked"))] diff --git a/src/engine_api.rs b/src/engine_api.rs index f78bfe97..50b720d7 100644 --- a/src/engine_api.rs +++ b/src/engine_api.rs @@ -5,7 +5,6 @@ use crate::engine::{EvalContext, EvalState, Imports}; use crate::fn_call::FnCallArgs; use crate::fn_native::SendSync; use crate::fn_register::RegisterNativeFunction; -use crate::optimize::OptimizationLevel; use crate::parse::ParseState; use crate::{ scope::Scope, Dynamic, Engine, EvalAltResult, FnAccess, FnNamespace, Identifier, Module, @@ -1171,7 +1170,12 @@ impl Engine { scope: &Scope, scripts: &[&str], ) -> Result { - self.compile_with_scope_and_optimization_level(scope, scripts, self.optimization_level) + self.compile_with_scope_and_optimization_level( + scope, + scripts, + #[cfg(not(feature = "no_optimize"))] + self.optimization_level, + ) } /// Join a list of strings and compile into an [`AST`] using own scope at a specific optimization level. #[inline] @@ -1179,7 +1183,7 @@ impl Engine { &self, scope: &Scope, scripts: &[&str], - optimization_level: OptimizationLevel, + #[cfg(not(feature = "no_optimize"))] optimization_level: crate::OptimizationLevel, ) -> Result { let (stream, tokenizer_control) = self.lex_raw(scripts, self.token_mapper.as_ref().map(Box::as_ref)); @@ -1188,6 +1192,7 @@ impl Engine { &mut stream.peekable(), &mut state, scope, + #[cfg(not(feature = "no_optimize"))] optimization_level, ) } @@ -1385,7 +1390,8 @@ impl Engine { &mut stream.peekable(), &mut state, &scope, - OptimizationLevel::None, + #[cfg(not(feature = "no_optimize"))] + crate::OptimizationLevel::None, )?; if has_null { scope.push_constant("null", ()); @@ -1470,7 +1476,13 @@ impl Engine { let mut peekable = stream.peekable(); let mut state = ParseState::new(self, tokenizer_control); - self.parse_global_expr(&mut peekable, &mut state, scope, self.optimization_level) + self.parse_global_expr( + &mut peekable, + &mut state, + scope, + #[cfg(not(feature = "no_optimize"))] + self.optimization_level, + ) } /// Evaluate a script file. /// @@ -1578,6 +1590,7 @@ impl Engine { let ast = self.compile_with_scope_and_optimization_level( scope, &[script], + #[cfg(not(feature = "no_optimize"))] self.optimization_level, )?; self.eval_ast_with_scope(scope, &ast) @@ -1637,7 +1650,8 @@ impl Engine { &mut stream.peekable(), &mut state, scope, - OptimizationLevel::None, + #[cfg(not(feature = "no_optimize"))] + crate::OptimizationLevel::None, )?; self.eval_ast_with_scope(scope, &ast) @@ -1782,6 +1796,7 @@ impl Engine { &mut stream.peekable(), &mut state, scope, + #[cfg(not(feature = "no_optimize"))] self.optimization_level, )?; @@ -2027,7 +2042,7 @@ impl Engine { &self, scope: &Scope, mut ast: AST, - optimization_level: OptimizationLevel, + optimization_level: crate::OptimizationLevel, ) -> AST { #[cfg(not(feature = "no_function"))] let lib = ast diff --git a/src/fn_call.rs b/src/fn_call.rs index 1ddca55d..2bafb66b 100644 --- a/src/fn_call.rs +++ b/src/fn_call.rs @@ -9,7 +9,6 @@ use crate::engine::{ use crate::fn_builtin::{get_builtin_binary_op_fn, get_builtin_op_assignment_fn}; use crate::fn_native::FnAny; use crate::module::NamespaceRef; -use crate::optimize::OptimizationLevel; use crate::{ ast::{Expr, Stmt}, fn_native::CallableFunction, @@ -859,7 +858,8 @@ impl Engine { let ast = self.compile_with_scope_and_optimization_level( &Default::default(), &[script], - OptimizationLevel::None, + #[cfg(not(feature = "no_optimize"))] + crate::OptimizationLevel::None, )?; // If new functions are defined within the eval string, it is an error diff --git a/src/lib.rs b/src/lib.rs index bb8e1ee9..9c953990 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -88,6 +88,7 @@ mod fn_ptr; mod fn_register; mod immutable_string; mod module; +#[cfg(not(feature = "no_optimize"))] mod optimize; pub mod packages; mod parse; diff --git a/src/parse.rs b/src/parse.rs index 4cdb91ef..6818bd62 100644 --- a/src/parse.rs +++ b/src/parse.rs @@ -9,7 +9,6 @@ use crate::dynamic::AccessMode; use crate::engine::{Precedence, KEYWORD_THIS, OP_CONTAINS}; use crate::fn_hash::get_hasher; use crate::module::NamespaceRef; -use crate::optimize::{optimize_into_ast, OptimizationLevel}; use crate::token::{ is_keyword_function, is_valid_function_name, is_valid_identifier, Token, TokenStream, TokenizerControl, @@ -3219,8 +3218,9 @@ impl Engine { input: &mut TokenStream, state: &mut ParseState, scope: &Scope, - optimization_level: OptimizationLevel, + #[cfg(not(feature = "no_optimize"))] optimization_level: crate::OptimizationLevel, ) -> Result { + let _scope = scope; let mut functions = Default::default(); let settings = ParseSettings { @@ -3249,16 +3249,17 @@ impl Engine { let mut statements = StaticVec::new(); statements.push(Stmt::Expr(expr)); - Ok( - // Optimize AST - optimize_into_ast( - self, - scope, - statements, - Default::default(), - optimization_level, - ), - ) + #[cfg(not(feature = "no_optimize"))] + return Ok(crate::optimize::optimize_into_ast( + self, + _scope, + statements, + Default::default(), + optimization_level, + )); + + #[cfg(feature = "no_optimize")] + return Ok(AST::new(statements, crate::Module::new())); } /// Parse the global level statements. @@ -3328,13 +3329,29 @@ impl Engine { input: &mut TokenStream, state: &mut ParseState, scope: &Scope, - optimization_level: OptimizationLevel, + #[cfg(not(feature = "no_optimize"))] optimization_level: crate::OptimizationLevel, ) -> Result { + let _scope = scope; let (statements, lib) = self.parse_global_level(input, state)?; - Ok( - // Optimize AST - optimize_into_ast(self, scope, statements, lib, optimization_level), - ) + #[cfg(not(feature = "no_optimize"))] + return Ok(crate::optimize::optimize_into_ast( + self, + _scope, + statements, + lib, + optimization_level, + )); + + #[cfg(feature = "no_optimize")] + { + let mut m = crate::Module::new(); + + lib.into_iter().for_each(|fn_def| { + m.set_script_fn(fn_def); + }); + + return Ok(AST::new(statements, m)); + } } }