spo_rhai/api/optimize.rs
1//! Module that defines the script optimization API of [`Engine`].
2#![cfg(not(feature = "no_optimize"))]
3
4use crate::{optimizer::optimize_into_ast, Engine, OptimizationLevel, Scope, AST};
5
6impl Engine {
7 /// Control whether and how the [`Engine`] will optimize an [`AST`] after compilation.
8 ///
9 /// Not available under `no_optimize`.
10 #[inline(always)]
11 pub fn set_optimization_level(&mut self, optimization_level: OptimizationLevel) -> &mut Self {
12 self.optimization_level = optimization_level;
13 self
14 }
15
16 /// The current optimization level.
17 /// It controls whether and how the [`Engine`] will optimize an [`AST`] after compilation.
18 ///
19 /// Not available under `no_optimize`.
20 #[inline(always)]
21 #[must_use]
22 pub const fn optimization_level(&self) -> OptimizationLevel {
23 self.optimization_level
24 }
25
26 /// Optimize the [`AST`] with constants defined in an external Scope.
27 /// An optimized copy of the [`AST`] is returned while the original [`AST`] is consumed.
28 ///
29 /// Not available under `no_optimize`.
30 ///
31 /// Although optimization is performed by default during compilation, sometimes it is necessary
32 /// to _re_-optimize an [`AST`].
33 ///
34 /// For example, when working with constants that are passed in via an external scope,
35 /// it will be more efficient to optimize the [`AST`] once again to take advantage of the new constants.
36 ///
37 /// With this method, it is no longer necessary to recompile a large script.
38 /// The script [`AST`] can be compiled just once.
39 ///
40 /// Before evaluation, constants are passed into the [`Engine`] via an external scope
41 /// (i.e. with [`Scope::push_constant`][Scope::push_constant]).
42 ///
43 /// Then, the [`AST`] is cloned and the copy re-optimized before running.
44 #[inline]
45 #[must_use]
46 pub fn optimize_ast(
47 &self,
48 scope: &Scope,
49 ast: AST,
50 optimization_level: OptimizationLevel,
51 ) -> AST {
52 let mut ast = ast;
53
54 let mut _new_ast = optimize_into_ast(
55 self,
56 Some(scope),
57 std::mem::take(ast.statements_mut()).to_vec().into(),
58 #[cfg(not(feature = "no_function"))]
59 ast.shared_lib()
60 .iter_fn()
61 .map(|(f, _)| f.get_script_fn_def().cloned().expect("`ScriptFuncDef`"))
62 .collect(),
63 optimization_level,
64 );
65
66 #[cfg(feature = "metadata")]
67 {
68 _new_ast.doc = std::mem::take(&mut ast.doc);
69 }
70
71 _new_ast
72 }
73}