Add no_optimize feature to disable optimizations.

This commit is contained in:
Stephen Chung 2020-03-14 20:06:10 +08:00
parent 26bdc8ba08
commit 973153e832
3 changed files with 37 additions and 20 deletions

View File

@ -26,6 +26,7 @@ no_stdlib = [] # no standard library of utility functions
no_index = [] # no arrays and indexing no_index = [] # no arrays and indexing
no_float = [] # no floating-point no_float = [] # no floating-point
no_function = [] # no script-defined functions no_function = [] # no script-defined functions
no_optimize = [] # no script optimizer
only_i32 = [] # set INT=i32 (useful for 32-bit systems) only_i32 = [] # set INT=i32 (useful for 32-bit systems)
only_i64 = [] # set INT=i64 (default) and disable support for all other integer types only_i64 = [] # set INT=i64 (default) and disable support for all other integer types

View File

@ -46,6 +46,7 @@ Optional features
| `no_function` | Disable script-defined functions if you don't need them. | | `no_function` | Disable script-defined functions if you don't need them. |
| `no_index` | Disable arrays and indexing features if you don't need them. | | `no_index` | Disable arrays and indexing features if you don't need them. |
| `no_float` | Disable floating-point numbers and math if you don't need them. | | `no_float` | Disable floating-point numbers and math if you don't need them. |
| `no_optimize` | Disable the script optimizer. |
| `only_i32` | Set the system integer type to `i32` and disable all other integer types. | | `only_i32` | Set the system integer type to `i32` and disable all other integer types. |
| `only_i64` | Set the system integer type to `i64` and disable all other integer types. | | `only_i64` | Set the system integer type to `i64` and disable all other integer types. |
@ -1099,6 +1100,7 @@ Optimizations
============= =============
Rhai includes an _optimizer_ that tries to optimize a script after parsing. This can reduce resource utilization and increase execution speed. Rhai includes an _optimizer_ that tries to optimize a script after parsing. This can reduce resource utilization and increase execution speed.
Script optimization can be turned off via the [`no_optimize`] feature.
For example, in the following: For example, in the following:
@ -1228,6 +1230,7 @@ engine.set_optimization(false); // turn off the optimizer
[`no_index`]: #optional-features [`no_index`]: #optional-features
[`no_float`]: #optional-features [`no_float`]: #optional-features
[`no_function`]: #optional-features [`no_function`]: #optional-features
[`no_optimize`]: #optional-features
[`only_i32`]: #optional-features [`only_i32`]: #optional-features
[`only_i64`]: #optional-features [`only_i64`]: #optional-features

View File

@ -2,9 +2,11 @@
use crate::any::Dynamic; use crate::any::Dynamic;
use crate::error::{LexError, ParseError, ParseErrorType}; use crate::error::{LexError, ParseError, ParseErrorType};
use crate::optimize::optimize;
use crate::scope::{Scope, VariableType}; use crate::scope::{Scope, VariableType};
#[cfg(not(feature = "no_optimize"))]
use crate::optimize::optimize;
use std::{ use std::{
borrow::Cow, char, cmp::Ordering, fmt, iter::Peekable, str::Chars, str::FromStr, sync::Arc, borrow::Cow, char, cmp::Ordering, fmt, iter::Peekable, str::Chars, str::FromStr, sync::Arc,
usize, usize,
@ -23,6 +25,7 @@ pub type INT = i64;
pub type INT = i32; pub type INT = i32;
/// The system floating-point type /// The system floating-point type
#[cfg(not(feature = "no_float"))]
pub type FLOAT = f64; pub type FLOAT = f64;
type LERR = LexError; type LERR = LexError;
@ -161,6 +164,7 @@ impl AST {
/// constant values. The script AST can be compiled just once. During actual evaluation, /// constant values. The script AST can be compiled just once. During actual evaluation,
/// constants are passed into the Engine via an external scope (i.e. with `scope.push_constant(...)`). /// constants are passed into the Engine via an external scope (i.e. with `scope.push_constant(...)`).
/// Then, the AST is cloned and the copy re-optimized before running. /// Then, the AST is cloned and the copy re-optimized before running.
#[cfg(not(feature = "no_optimize"))]
pub fn optimize(self, scope: &Scope) -> Self { pub fn optimize(self, scope: &Scope) -> Self {
AST( AST(
crate::optimize::optimize(self.0, scope), crate::optimize::optimize(self.0, scope),
@ -2140,25 +2144,34 @@ fn parse_top_level<'a>(
} }
} }
return Ok(AST( Ok(
if optimize_ast { #[cfg(not(feature = "no_optimize"))]
optimize(statements, &scope) AST(
} else { if optimize_ast {
statements optimize(statements, &scope)
}, } else {
#[cfg(not(feature = "no_function"))] statements
functions },
.into_iter() #[cfg(not(feature = "no_function"))]
.map(|mut fn_def| { functions
if optimize_ast { .into_iter()
let pos = fn_def.body.position(); .map(|mut fn_def| {
let mut body = optimize(vec![fn_def.body], &scope); if optimize_ast {
fn_def.body = body.pop().unwrap_or_else(|| Stmt::Noop(pos)); let pos = fn_def.body.position();
} let mut body = optimize(vec![fn_def.body], &scope);
Arc::new(fn_def) fn_def.body = body.pop().unwrap_or_else(|| Stmt::Noop(pos));
}) }
.collect(), Arc::new(fn_def)
)); })
.collect(),
),
#[cfg(feature = "no_optimize")]
AST(
statements,
#[cfg(not(feature = "no_function"))]
functions.into_iter().map(Arc::new).collect(),
),
)
} }
pub fn parse<'a>( pub fn parse<'a>(