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}