Eliminate optimize module with no_optimize.

This commit is contained in:
Stephen Chung 2021-10-21 19:17:34 +08:00
parent 315a891ba6
commit 65ef402440
6 changed files with 63 additions and 28 deletions

View File

@ -16,6 +16,7 @@ Enhancements
* Array methods that take function pointers (e.g. closures) now optionally take the function name as a string. * Array methods that take function pointers (e.g. closures) now optionally take the function name as a string.
* Array adds the `dedup` method. * 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. * 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 Deprecated API's
---------------- ----------------

View File

@ -9,7 +9,6 @@ use crate::fn_native::{
OnVarCallback, OnVarCallback,
}; };
use crate::module::NamespaceRef; use crate::module::NamespaceRef;
use crate::optimize::OptimizationLevel;
use crate::packages::{Package, StandardPackage}; use crate::packages::{Package, StandardPackage};
use crate::r#unsafe::unsafe_cast_var_name_to_lifetime; use crate::r#unsafe::unsafe_cast_var_name_to_lifetime;
use crate::token::Token; use crate::token::Token;
@ -979,7 +978,8 @@ pub struct Engine {
pub(crate) progress: Option<crate::fn_native::OnProgressCallback>, pub(crate) progress: Option<crate::fn_native::OnProgressCallback>,
/// Optimize the AST after compilation. /// Optimize the AST after compilation.
pub(crate) optimization_level: OptimizationLevel, #[cfg(not(feature = "no_optimize"))]
pub(crate) optimization_level: crate::OptimizationLevel,
/// Max limits. /// Max limits.
#[cfg(not(feature = "unchecked"))] #[cfg(not(feature = "unchecked"))]
@ -1101,6 +1101,7 @@ impl Engine {
#[cfg(not(feature = "unchecked"))] #[cfg(not(feature = "unchecked"))]
progress: None, progress: None,
#[cfg(not(feature = "no_optimize"))]
optimization_level: Default::default(), optimization_level: Default::default(),
#[cfg(not(feature = "unchecked"))] #[cfg(not(feature = "unchecked"))]

View File

@ -5,7 +5,6 @@ use crate::engine::{EvalContext, EvalState, Imports};
use crate::fn_call::FnCallArgs; use crate::fn_call::FnCallArgs;
use crate::fn_native::SendSync; use crate::fn_native::SendSync;
use crate::fn_register::RegisterNativeFunction; use crate::fn_register::RegisterNativeFunction;
use crate::optimize::OptimizationLevel;
use crate::parse::ParseState; use crate::parse::ParseState;
use crate::{ use crate::{
scope::Scope, Dynamic, Engine, EvalAltResult, FnAccess, FnNamespace, Identifier, Module, scope::Scope, Dynamic, Engine, EvalAltResult, FnAccess, FnNamespace, Identifier, Module,
@ -1171,7 +1170,12 @@ impl Engine {
scope: &Scope, scope: &Scope,
scripts: &[&str], scripts: &[&str],
) -> Result<AST, ParseError> { ) -> Result<AST, ParseError> {
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. /// Join a list of strings and compile into an [`AST`] using own scope at a specific optimization level.
#[inline] #[inline]
@ -1179,7 +1183,7 @@ impl Engine {
&self, &self,
scope: &Scope, scope: &Scope,
scripts: &[&str], scripts: &[&str],
optimization_level: OptimizationLevel, #[cfg(not(feature = "no_optimize"))] optimization_level: crate::OptimizationLevel,
) -> Result<AST, ParseError> { ) -> Result<AST, ParseError> {
let (stream, tokenizer_control) = let (stream, tokenizer_control) =
self.lex_raw(scripts, self.token_mapper.as_ref().map(Box::as_ref)); self.lex_raw(scripts, self.token_mapper.as_ref().map(Box::as_ref));
@ -1188,6 +1192,7 @@ impl Engine {
&mut stream.peekable(), &mut stream.peekable(),
&mut state, &mut state,
scope, scope,
#[cfg(not(feature = "no_optimize"))]
optimization_level, optimization_level,
) )
} }
@ -1385,7 +1390,8 @@ impl Engine {
&mut stream.peekable(), &mut stream.peekable(),
&mut state, &mut state,
&scope, &scope,
OptimizationLevel::None, #[cfg(not(feature = "no_optimize"))]
crate::OptimizationLevel::None,
)?; )?;
if has_null { if has_null {
scope.push_constant("null", ()); scope.push_constant("null", ());
@ -1470,7 +1476,13 @@ impl Engine {
let mut peekable = stream.peekable(); let mut peekable = stream.peekable();
let mut state = ParseState::new(self, tokenizer_control); 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. /// Evaluate a script file.
/// ///
@ -1578,6 +1590,7 @@ impl Engine {
let ast = self.compile_with_scope_and_optimization_level( let ast = self.compile_with_scope_and_optimization_level(
scope, scope,
&[script], &[script],
#[cfg(not(feature = "no_optimize"))]
self.optimization_level, self.optimization_level,
)?; )?;
self.eval_ast_with_scope(scope, &ast) self.eval_ast_with_scope(scope, &ast)
@ -1637,7 +1650,8 @@ impl Engine {
&mut stream.peekable(), &mut stream.peekable(),
&mut state, &mut state,
scope, scope,
OptimizationLevel::None, #[cfg(not(feature = "no_optimize"))]
crate::OptimizationLevel::None,
)?; )?;
self.eval_ast_with_scope(scope, &ast) self.eval_ast_with_scope(scope, &ast)
@ -1782,6 +1796,7 @@ impl Engine {
&mut stream.peekable(), &mut stream.peekable(),
&mut state, &mut state,
scope, scope,
#[cfg(not(feature = "no_optimize"))]
self.optimization_level, self.optimization_level,
)?; )?;
@ -2027,7 +2042,7 @@ impl Engine {
&self, &self,
scope: &Scope, scope: &Scope,
mut ast: AST, mut ast: AST,
optimization_level: OptimizationLevel, optimization_level: crate::OptimizationLevel,
) -> AST { ) -> AST {
#[cfg(not(feature = "no_function"))] #[cfg(not(feature = "no_function"))]
let lib = ast let lib = ast

View File

@ -9,7 +9,6 @@ use crate::engine::{
use crate::fn_builtin::{get_builtin_binary_op_fn, get_builtin_op_assignment_fn}; use crate::fn_builtin::{get_builtin_binary_op_fn, get_builtin_op_assignment_fn};
use crate::fn_native::FnAny; use crate::fn_native::FnAny;
use crate::module::NamespaceRef; use crate::module::NamespaceRef;
use crate::optimize::OptimizationLevel;
use crate::{ use crate::{
ast::{Expr, Stmt}, ast::{Expr, Stmt},
fn_native::CallableFunction, fn_native::CallableFunction,
@ -859,7 +858,8 @@ impl Engine {
let ast = self.compile_with_scope_and_optimization_level( let ast = self.compile_with_scope_and_optimization_level(
&Default::default(), &Default::default(),
&[script], &[script],
OptimizationLevel::None, #[cfg(not(feature = "no_optimize"))]
crate::OptimizationLevel::None,
)?; )?;
// If new functions are defined within the eval string, it is an error // If new functions are defined within the eval string, it is an error

View File

@ -88,6 +88,7 @@ mod fn_ptr;
mod fn_register; mod fn_register;
mod immutable_string; mod immutable_string;
mod module; mod module;
#[cfg(not(feature = "no_optimize"))]
mod optimize; mod optimize;
pub mod packages; pub mod packages;
mod parse; mod parse;

View File

@ -9,7 +9,6 @@ use crate::dynamic::AccessMode;
use crate::engine::{Precedence, KEYWORD_THIS, OP_CONTAINS}; use crate::engine::{Precedence, KEYWORD_THIS, OP_CONTAINS};
use crate::fn_hash::get_hasher; use crate::fn_hash::get_hasher;
use crate::module::NamespaceRef; use crate::module::NamespaceRef;
use crate::optimize::{optimize_into_ast, OptimizationLevel};
use crate::token::{ use crate::token::{
is_keyword_function, is_valid_function_name, is_valid_identifier, Token, TokenStream, is_keyword_function, is_valid_function_name, is_valid_identifier, Token, TokenStream,
TokenizerControl, TokenizerControl,
@ -3219,8 +3218,9 @@ impl Engine {
input: &mut TokenStream, input: &mut TokenStream,
state: &mut ParseState, state: &mut ParseState,
scope: &Scope, scope: &Scope,
optimization_level: OptimizationLevel, #[cfg(not(feature = "no_optimize"))] optimization_level: crate::OptimizationLevel,
) -> Result<AST, ParseError> { ) -> Result<AST, ParseError> {
let _scope = scope;
let mut functions = Default::default(); let mut functions = Default::default();
let settings = ParseSettings { let settings = ParseSettings {
@ -3249,16 +3249,17 @@ impl Engine {
let mut statements = StaticVec::new(); let mut statements = StaticVec::new();
statements.push(Stmt::Expr(expr)); statements.push(Stmt::Expr(expr));
Ok( #[cfg(not(feature = "no_optimize"))]
// Optimize AST return Ok(crate::optimize::optimize_into_ast(
optimize_into_ast(
self, self,
scope, _scope,
statements, statements,
Default::default(), Default::default(),
optimization_level, optimization_level,
), ));
)
#[cfg(feature = "no_optimize")]
return Ok(AST::new(statements, crate::Module::new()));
} }
/// Parse the global level statements. /// Parse the global level statements.
@ -3328,13 +3329,29 @@ impl Engine {
input: &mut TokenStream, input: &mut TokenStream,
state: &mut ParseState, state: &mut ParseState,
scope: &Scope, scope: &Scope,
optimization_level: OptimizationLevel, #[cfg(not(feature = "no_optimize"))] optimization_level: crate::OptimizationLevel,
) -> Result<AST, ParseError> { ) -> Result<AST, ParseError> {
let _scope = scope;
let (statements, lib) = self.parse_global_level(input, state)?; let (statements, lib) = self.parse_global_level(input, state)?;
Ok( #[cfg(not(feature = "no_optimize"))]
// Optimize AST return Ok(crate::optimize::optimize_into_ast(
optimize_into_ast(self, scope, statements, lib, optimization_level), 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));
}
} }
} }