Skip to main content

rhai/eval/
eval_context.rs

1//! Evaluation context.
2
3use super::{Caches, GlobalRuntimeState};
4use crate::ast::FnCallHashes;
5use crate::tokenizer::{is_valid_function_name, Token};
6use crate::types::dynamic::Variant;
7use crate::{
8    calc_fn_hash, expose_under_internals, Dynamic, Engine, FnArgsVec, FuncArgs, ImmutableString,
9    Position, RhaiResult, RhaiResultOf, Scope, StaticVec, ERR,
10};
11#[cfg(feature = "no_std")]
12use std::prelude::v1::*;
13use std::{
14    any::type_name,
15    mem,
16    ops::{Deref, DerefMut},
17};
18
19/// Context of a script evaluation process.
20#[allow(dead_code)]
21pub struct EvalContext<'a, 's, 'ps, 'g, 'c, 't> {
22    /// The current [`Engine`].
23    engine: &'a Engine,
24    /// The current [`GlobalRuntimeState`].
25    global: &'g mut GlobalRuntimeState,
26    /// The current [caches][Caches], if available.
27    caches: &'c mut Caches,
28    /// The current [`Scope`].
29    scope: &'s mut Scope<'ps>,
30    /// The current bound `this` pointer, if any.
31    this_ptr: Option<&'t mut Dynamic>,
32}
33
34impl<'a, 's, 'ps, 'g, 'c, 't> EvalContext<'a, 's, 'ps, 'g, 'c, 't> {
35    /// Create a new [`EvalContext`].
36    #[expose_under_internals]
37    #[inline(always)]
38    #[must_use]
39    fn new(
40        engine: &'a Engine,
41        global: &'g mut GlobalRuntimeState,
42        caches: &'c mut Caches,
43        scope: &'s mut Scope<'ps>,
44        this_ptr: Option<&'t mut Dynamic>,
45    ) -> Self {
46        Self {
47            engine,
48            global,
49            caches,
50            scope,
51            this_ptr,
52        }
53    }
54    /// The current [`Engine`].
55    #[inline(always)]
56    #[must_use]
57    pub const fn engine(&self) -> &'a Engine {
58        self.engine
59    }
60    /// The current source.
61    #[inline(always)]
62    #[must_use]
63    pub fn source(&self) -> Option<&str> {
64        self.global.source()
65    }
66    /// Get a mutable reference to the current source.
67    #[inline(always)]
68    #[must_use]
69    pub fn source_mut(&mut self) -> &mut Option<ImmutableString> {
70        &mut self.global.source
71    }
72
73    /// The current [`Scope`].
74    #[inline(always)]
75    #[must_use]
76    pub const fn scope(&self) -> &Scope<'ps> {
77        self.scope
78    }
79    /// Get a mutable reference to the current [`Scope`].
80    #[inline(always)]
81    #[must_use]
82    pub fn scope_mut(&mut self) -> &mut Scope<'ps> {
83        self.scope
84    }
85    /// Get an iterator over the current set of modules imported via `import` statements,
86    /// in reverse order (i.e. modules imported last come first).
87    #[cfg(not(feature = "no_module"))]
88    #[inline(always)]
89    pub fn iter_imports(&self) -> impl Iterator<Item = (&str, &crate::Module)> {
90        self.global.iter_imports()
91    }
92    /// Custom state kept in a [`Dynamic`].
93    #[inline(always)]
94    pub const fn tag(&self) -> &Dynamic {
95        &self.global.tag
96    }
97    /// Mutable reference to the custom state kept in a [`Dynamic`].
98    #[inline(always)]
99    pub fn tag_mut(&mut self) -> &mut Dynamic {
100        &mut self.global.tag
101    }
102    /// _(internals)_ The current [`GlobalRuntimeState`].
103    /// Exported under the `internals` feature only.
104    #[cfg(feature = "internals")]
105    #[inline(always)]
106    #[must_use]
107    pub const fn global_runtime_state(&self) -> &GlobalRuntimeState {
108        self.global
109    }
110    /// _(internals)_ Get a mutable reference to the current [`GlobalRuntimeState`].
111    /// Exported under the `internals` feature only.
112    #[cfg(feature = "internals")]
113    #[inline(always)]
114    #[must_use]
115    pub fn global_runtime_state_mut(&mut self) -> &mut GlobalRuntimeState {
116        self.global
117    }
118    /// Get an iterator over the namespaces containing definition of all script-defined functions.
119    ///
120    /// Not available under `no_function`.
121    #[cfg(not(feature = "no_function"))]
122    #[inline]
123    pub fn iter_namespaces(&self) -> impl Iterator<Item = &crate::Module> {
124        self.global.lib.iter().map(<_>::as_ref)
125    }
126    /// _(internals)_ The current set of namespaces containing definitions of all script-defined functions.
127    /// Exported under the `internals` feature only.
128    ///
129    /// Not available under `no_function`.
130    #[cfg(not(feature = "no_function"))]
131    #[cfg(feature = "internals")]
132    #[inline(always)]
133    #[must_use]
134    pub fn namespaces(&self) -> &[crate::SharedModule] {
135        &self.global.lib
136    }
137    /// _(internals)_ Mutable reference to the current set of namespaces containing definitions of all script-defined functions.
138    /// Exported under the `internals` feature only.
139    ///
140    /// Not available under `no_function`.
141    #[cfg(not(feature = "no_function"))]
142    #[cfg(feature = "internals")]
143    #[inline(always)]
144    #[must_use]
145    pub fn namespaces_mut(&mut self) -> &mut [crate::SharedModule] {
146        self.global.lib.as_mut()
147    }
148    /// The current bound `this` pointer, if any.
149    #[inline(always)]
150    #[must_use]
151    pub fn this_ptr(&self) -> Option<&Dynamic> {
152        self.this_ptr.as_deref()
153    }
154    /// Mutable reference to the current bound `this` pointer, if any.
155    #[inline(always)]
156    #[must_use]
157    pub fn this_ptr_mut(&mut self) -> Option<&mut Dynamic> {
158        self.this_ptr.as_deref_mut()
159    }
160    /// The current nesting level of function calls.
161    #[inline(always)]
162    #[must_use]
163    pub const fn call_level(&self) -> usize {
164        self.global.level
165    }
166    /// _(internals, debugging)_ Debugging interface.
167    /// Exported under the `debugging` and `internals` features only.
168    #[cfg(feature = "debugging")]
169    #[cfg(feature = "internals")]
170    #[inline(always)]
171    #[must_use]
172    pub fn debugger(&self) -> Option<&crate::debugger::Debugger> {
173        self.global.debugger.as_deref()
174    }
175    /// _(internals, debugging)_ Mutable reference to the debugging interface.
176    /// Exported under the `debugging` and `internals` features only.
177    #[cfg(feature = "debugging")]
178    #[cfg(feature = "internals")]
179    #[inline(always)]
180    #[must_use]
181    pub fn debugger_mut(&mut self) -> Option<&mut crate::debugger::Debugger> {
182        self.global.debugger.as_deref_mut()
183    }
184
185    /// Evaluate an [expression tree][crate::Expression] within this [evaluation context][`EvalContext`].
186    ///
187    /// # WARNING - Low Level API
188    ///
189    /// This function is very low level.  It evaluates an expression from an [`AST`][crate::AST].
190    #[cfg(not(feature = "no_custom_syntax"))]
191    #[inline(always)]
192    pub fn eval_expression_tree(&mut self, expr: &crate::Expression) -> crate::RhaiResult {
193        #[allow(deprecated)]
194        self.eval_expression_tree_raw(expr, true)
195    }
196    /// Evaluate an [expression tree][crate::Expression] within this [evaluation context][`EvalContext`].
197    ///
198    /// The following option is available:
199    ///
200    /// * whether to rewind the [`Scope`] after evaluation if the expression is a [`StmtBlock`][crate::ast::StmtBlock]
201    ///
202    /// # WARNING - Unstable API
203    ///
204    /// This API is volatile and may change in the future.
205    ///
206    /// # WARNING - Low Level API
207    ///
208    /// This function is _extremely_ low level.  It evaluates an expression from an [`AST`][crate::AST].
209    #[cfg(not(feature = "no_custom_syntax"))]
210    #[deprecated = "This API is NOT deprecated, but it is considered volatile and may change in the future."]
211    #[inline]
212    pub fn eval_expression_tree_raw(
213        &mut self,
214        expr: &crate::Expression,
215        rewind_scope: bool,
216    ) -> crate::RhaiResult {
217        let expr: &crate::ast::Expr = expr;
218        let this_ptr = self.this_ptr.as_deref_mut();
219
220        match expr {
221            crate::ast::Expr::Stmt(stmts) => self.engine.eval_stmt_block(
222                self.global,
223                self.caches,
224                self.scope,
225                this_ptr,
226                stmts.statements(),
227                rewind_scope,
228            ),
229            _ => self
230                .engine
231                .eval_expr(self.global, self.caches, self.scope, this_ptr, expr),
232        }
233    }
234
235    /// Call a function inside the [evaluation context][`EvalContext`] with the provided arguments.
236    pub fn call_fn<T: Variant + Clone>(
237        &mut self,
238        fn_name: impl AsRef<str>,
239        args: impl FuncArgs,
240    ) -> RhaiResultOf<T> {
241        let engine = self.engine();
242
243        let mut arg_values = StaticVec::new_const();
244        args.parse(&mut arg_values);
245
246        let args = &mut arg_values.iter_mut().collect::<FnArgsVec<_>>();
247
248        let is_ref_mut = if let Some(this_ptr) = self.this_ptr.as_deref_mut() {
249            args.insert(0, this_ptr);
250            true
251        } else {
252            false
253        };
254
255        _call_fn_raw(
256            engine,
257            self.global,
258            self.caches,
259            self.scope,
260            fn_name,
261            args,
262            false,
263            is_ref_mut,
264            false,
265        )
266        .and_then(|result| {
267            result.try_cast_result().map_err(|r| {
268                let result_type = engine.map_type_name(r.type_name());
269                let cast_type = match type_name::<T>() {
270                    typ if typ.contains("::") => engine.map_type_name(typ),
271                    typ => typ,
272                };
273                ERR::ErrorMismatchOutputType(cast_type.into(), result_type.into(), Position::NONE)
274                    .into()
275            })
276        })
277    }
278    /// Call a registered native Rust function inside the [evaluation context][`EvalContext`] with
279    /// the provided arguments.
280    ///
281    /// This is often useful because Rust functions typically only want to cross-call other
282    /// registered Rust functions and not have to worry about scripted functions hijacking the
283    /// process unknowingly (or deliberately).
284    pub fn call_native_fn<T: Variant + Clone>(
285        &mut self,
286        fn_name: impl AsRef<str>,
287        args: impl FuncArgs,
288    ) -> RhaiResultOf<T> {
289        let engine = self.engine();
290
291        let mut arg_values = StaticVec::new_const();
292        args.parse(&mut arg_values);
293
294        let args = &mut arg_values.iter_mut().collect::<FnArgsVec<_>>();
295
296        let is_ref_mut = self.this_ptr.as_deref_mut().map_or(false, |this_ptr| {
297            args.insert(0, this_ptr);
298            true
299        });
300
301        _call_fn_raw(
302            engine,
303            self.global,
304            self.caches,
305            self.scope,
306            fn_name,
307            args,
308            true,
309            is_ref_mut,
310            false,
311        )
312        .and_then(|result| {
313            result.try_cast_result().map_err(|r| {
314                let result_type = engine.map_type_name(r.type_name());
315                let cast_type = match type_name::<T>() {
316                    typ if typ.contains("::") => engine.map_type_name(typ),
317                    typ => typ,
318                };
319                ERR::ErrorMismatchOutputType(cast_type.into(), result_type.into(), Position::NONE)
320                    .into()
321            })
322        })
323    }
324    /// Call a function (native Rust or scripted) inside the [evaluation context][`EvalContext`].
325    ///
326    /// If `is_method_call` is [`true`], the first argument is assumed to be the `this` pointer for
327    /// a script-defined function (or the object of a method call).
328    ///
329    /// # WARNING - Low Level API
330    ///
331    /// This function is very low level.
332    ///
333    /// # Arguments
334    ///
335    /// All arguments may be _consumed_, meaning that they may be replaced by `()`. This is to avoid
336    /// unnecessarily cloning the arguments.
337    ///
338    /// **DO NOT** reuse the arguments after this call. If they are needed afterwards, clone them
339    /// _before_ calling this function.
340    ///
341    /// If `is_ref_mut` is [`true`], the first argument is assumed to be passed by reference and is
342    /// not consumed.
343    #[inline(always)]
344    pub fn call_fn_raw(
345        &mut self,
346        fn_name: impl AsRef<str>,
347        is_ref_mut: bool,
348        is_method_call: bool,
349        args: &mut [&mut Dynamic],
350    ) -> RhaiResult {
351        let name = fn_name.as_ref();
352        let native_only = !is_valid_function_name(name);
353        #[cfg(not(feature = "no_function"))]
354        let native_only = native_only && !crate::parser::is_anonymous_fn(name);
355
356        _call_fn_raw(
357            self.engine(),
358            self.global,
359            self.caches,
360            self.scope,
361            fn_name,
362            args,
363            native_only,
364            is_ref_mut,
365            is_method_call,
366        )
367    }
368    /// Call a registered native Rust function inside the [evaluation context][`EvalContext`].
369    ///
370    /// This is often useful because Rust functions typically only want to cross-call other
371    /// registered Rust functions and not have to worry about scripted functions hijacking the
372    /// process unknowingly (or deliberately).
373    ///
374    /// # WARNING - Low Level API
375    ///
376    /// This function is very low level.
377    ///
378    /// # Arguments
379    ///
380    /// All arguments may be _consumed_, meaning that they may be replaced by `()`. This is to avoid
381    /// unnecessarily cloning the arguments.
382    ///
383    /// **DO NOT** reuse the arguments after this call. If they are needed afterwards, clone them
384    /// _before_ calling this function.
385    ///
386    /// If `is_ref_mut` is [`true`], the first argument is assumed to be passed by reference and is
387    /// not consumed.
388    #[inline(always)]
389    pub fn call_native_fn_raw(
390        &mut self,
391        fn_name: impl AsRef<str>,
392        is_ref_mut: bool,
393        args: &mut [&mut Dynamic],
394    ) -> RhaiResult {
395        _call_fn_raw(
396            self.engine(),
397            self.global,
398            self.caches,
399            self.scope,
400            fn_name,
401            args,
402            true,
403            is_ref_mut,
404            false,
405        )
406    }
407
408    /// Create a new isolated runtime frame guard, restoring field values upon `Drop`.
409    ///
410    /// The [frame guard][EvalContextFrameGuard] returned derefs to [`EvalContext`].
411    ///
412    /// # Examples
413    ///
414    /// ```rust,ignore
415    /// // The following pushes a new, empty, caching layer to make sure that new function resolutions
416    /// // do not persist. This is useful if the resolution will be volatile.
417    /// let result: i64 = context.new_frame()
418    ///                          .with_new_caching_layer()
419    ///                          .call_fn("foo", (0_i64,))?;
420    ///
421    /// // In the above example, the resolution to function 'foo' will not be cached outside the frame.
422    /// // The next call to 'foo' will be resolved again instead of using the cached resolution,
423    /// // even if 'foo' is redefined.
424    ///
425    /// // The following modifies the [`EvalContext`] before using, restoring its state afterwards.
426    /// {
427    ///     // Modify the context before using...
428    ///     let context = context.new_frame()
429    ///                          .rewind_scope(true)            // rewinds the scope...
430    ///                          .with_source("new source")     // new source...
431    ///                          .with_namespace(new_module)    // add new namespace module...
432    ///                          .up_call_level();
433    ///
434    ///     // Call a function with the modified context...
435    ///     let result: i64 = context.call_fn("foo", (0_i64,))?;
436    ///
437    ///     // ... at end of block, context automatically restored to previous state.
438    /// }
439    /// ```
440    ///
441    /// ## `Drop` behavior
442    ///
443    /// Upon `Drop`, the following fields will be automatically restored to the previous values:
444    ///
445    /// * the stack of imported [modules][crate::Module] will be rewound to the original depth if more have been added via [`EvalContextFrameGuard::with_import`].
446    /// * the stack of scripted function [modules][crate::Module] will be rewound to the original depth if more have been added via [`EvalContextFrameGuard::with_namespace`].
447    /// * the original functions resolution cache will be restored if a new caching layer was created via [`EvalContextFrameGuard::with_new_caching_layer`].
448    /// * the original [scope][EvalContext::scope] will be rewound if [`EvalContextFrameGuard::rewind_scope`] was set to `true`.
449    /// * the [source][GlobalRuntimeState::source] will be restored if a new source was set via [`EvalContextFrameGuard::with_source`] or cleared via [`EvalContextFrameGuard::clear_source`].
450    /// * the current [nesting level][GlobalRuntimeState::level] of function calls will be restored if modified via [`EvalContextFrameGuard::up_call_level`].
451    /// * the current [`tag`][GlobalRuntimeState::tag] will be restored if modified via [`EvalContextFrameGuard::with_tag`] or [`EvalContextFrameGuard::clear_tag`].
452    pub fn new_frame<'f>(&'f mut self) -> EvalContextFrameGuard<'f, 'a, 's, 'ps, 'g, 'c, 't> {
453        EvalContextFrameGuard {
454            #[cfg(feature = "internals")]
455            #[cfg(not(feature = "no_module"))]
456            imports_len: None,
457            #[cfg(feature = "internals")]
458            #[cfg(not(feature = "no_function"))]
459            lib_len: None,
460            caches_len: None,
461            scope_len: None,
462            source: None,
463            #[cfg(feature = "internals")]
464            level: None,
465            tag: None,
466
467            context: self,
468        }
469    }
470}
471
472/// Call a function (native Rust or scripted) inside the [evaluation context][`EvalContext`].
473fn _call_fn_raw(
474    engine: &Engine,
475    global: &mut GlobalRuntimeState,
476    caches: &mut Caches,
477    scope: &mut Scope,
478    fn_name: impl AsRef<str>,
479    args: &mut [&mut Dynamic],
480    native_only: bool,
481    is_ref_mut: bool,
482    is_method_call: bool,
483) -> RhaiResult {
484    defer! { let orig_level = global.level; global.level += 1 }
485
486    let fn_name = fn_name.as_ref();
487    let op_token = Token::lookup_symbol_from_syntax(fn_name);
488    let op_token = op_token.as_ref();
489    let args_len = args.len();
490
491    if native_only {
492        let hash = calc_fn_hash(None, fn_name, args_len);
493
494        return engine
495            .exec_native_fn_call(
496                global,
497                caches,
498                fn_name,
499                op_token,
500                hash,
501                args,
502                is_ref_mut,
503                false,
504                Position::NONE,
505            )
506            .map(|(r, ..)| r);
507    }
508
509    // Native or script
510
511    let hash = match is_method_call {
512        #[cfg(not(feature = "no_function"))]
513        true => FnCallHashes::from_script_and_native(
514            calc_fn_hash(None, fn_name, args_len - 1),
515            calc_fn_hash(None, fn_name, args_len),
516        ),
517        #[cfg(feature = "no_function")]
518        true => FnCallHashes::from_native_only(calc_fn_hash(None, fn_name, args_len)),
519        _ => FnCallHashes::from_hash(calc_fn_hash(None, fn_name, args_len)),
520    };
521
522    engine
523        .exec_fn_call(
524            global,
525            caches,
526            Some(scope),
527            fn_name,
528            op_token,
529            hash,
530            args,
531            is_ref_mut,
532            is_method_call,
533            Position::NONE,
534        )
535        .map(|(r, ..)| r)
536}
537
538/// A new frame guard for [`EvalContext`], restoring field values upon `Drop`.
539pub struct EvalContextFrameGuard<'f, 'a, 's, 'ps, 'g, 'c, 't> {
540    context: &'f mut EvalContext<'a, 's, 'ps, 'g, 'c, 't>,
541
542    caches_len: Option<usize>,
543    scope_len: Option<usize>,
544    #[cfg(feature = "internals")]
545    #[cfg(not(feature = "no_module"))]
546    imports_len: Option<usize>,
547    #[cfg(feature = "internals")]
548    #[cfg(not(feature = "no_function"))]
549    lib_len: Option<usize>,
550    source: Option<Option<ImmutableString>>,
551    #[cfg(feature = "internals")]
552    level: Option<usize>,
553    tag: Option<Dynamic>,
554}
555
556impl Drop for EvalContextFrameGuard<'_, '_, '_, '_, '_, '_, '_> {
557    #[inline(always)]
558    fn drop(&mut self) {
559        if let Some(caches_len) = self.caches_len {
560            self.context.caches.rewind_fn_resolution_caches(caches_len);
561        }
562        if let Some(scope_len) = self.scope_len {
563            self.context.scope.rewind(scope_len);
564        }
565        #[cfg(feature = "internals")]
566        #[cfg(not(feature = "no_module"))]
567        if let Some(imports_len) = self.imports_len {
568            self.context.global.truncate_imports(imports_len);
569        }
570        #[cfg(feature = "internals")]
571        #[cfg(not(feature = "no_function"))]
572        if let Some(lib_len) = self.lib_len {
573            self.context.global.lib.truncate(lib_len);
574        }
575        if let Some(source) = self.source.take() {
576            *self.context.source_mut() = source;
577        }
578        #[cfg(feature = "internals")]
579        if let Some(level) = self.level {
580            self.context.global.level = level;
581        }
582        if let Some(tag) = self.tag.take() {
583            *self.context.tag_mut() = tag;
584        }
585    }
586}
587
588impl<'a, 's, 'ps, 'g, 'c, 't> Deref for EvalContextFrameGuard<'_, 'a, 's, 'ps, 'g, 'c, 't> {
589    type Target = EvalContext<'a, 's, 'ps, 'g, 'c, 't>;
590
591    #[inline(always)]
592    fn deref(&self) -> &Self::Target {
593        self.context
594    }
595}
596
597impl<'a, 's, 'ps, 'g, 'c, 't> DerefMut for EvalContextFrameGuard<'_, 'a, 's, 'ps, 'g, 'c, 't> {
598    #[inline(always)]
599    fn deref_mut(&mut self) -> &mut Self::Target {
600        self.context
601    }
602}
603
604impl<'t> EvalContextFrameGuard<'_, '_, '_, '_, '_, '_, 't> {
605    /// Push a new caching layer for function resolution results.
606    pub fn with_new_caching_layer(mut self) -> Self {
607        self.caches_len = Some(self.context.caches.fn_resolution_caches_len());
608        self.context.caches.push_fn_resolution_cache();
609        self
610    }
611    /// Rewind the [scope][EvalContext::scope].
612    #[inline(always)]
613    pub fn rewind_scope(mut self, enable: bool) -> Self {
614        self.scope_len = if enable {
615            Some(self.context.scope().len())
616        } else {
617            None
618        };
619        self
620    }
621    /// Modify the current source.
622    #[inline(always)]
623    pub fn with_source(mut self, source: impl Into<ImmutableString>) -> Self {
624        self.source = Some(Some(source.into()));
625        mem::swap(self.context.source_mut(), self.source.as_mut().unwrap());
626        self
627    }
628    /// Clear the current source.
629    #[inline(always)]
630    pub fn clear_source(mut self) -> Self {
631        self.source = Some(None);
632        mem::swap(self.context.source_mut(), self.source.as_mut().unwrap());
633        self
634    }
635    /// Modify the custom state.
636    #[inline(always)]
637    pub fn with_tag(mut self, tag: Dynamic) -> Self {
638        self.tag = Some(tag);
639        mem::swap(self.context.tag_mut(), self.tag.as_mut().unwrap());
640        self
641    }
642    /// Modify the custom state to [`Dynamic::UNIT`].
643    #[inline(always)]
644    pub fn clear_tag(mut self) -> Self {
645        self.tag = Some(Dynamic::UNIT);
646        mem::swap(self.context.tag_mut(), self.tag.as_mut().unwrap());
647        self
648    }
649    /// _(internals)_ Add a new imported [module][crate::Module].
650    /// Exported under the `internals` feature only.
651    ///
652    /// Not available under `no_module`.
653    #[cfg(feature = "internals")]
654    #[cfg(not(feature = "no_module"))]
655    pub fn with_import(
656        mut self,
657        name: impl Into<ImmutableString>,
658        module: impl Into<crate::SharedModule>,
659    ) -> Self {
660        self.imports_len = Some(self.context.global.num_imports());
661        self.context.global.push_import(name.into(), module.into());
662        self
663    }
664    /// _(internals)_ Add a new [module][crate::Module] containing script-defined functions.
665    /// Exported under the `internals` feature only.
666    ///
667    /// Not available under `no_function`.
668    #[cfg(feature = "internals")]
669    #[cfg(not(feature = "no_function"))]
670    #[inline(always)]
671    #[must_use]
672    pub fn with_namespace(mut self, module: impl Into<crate::SharedModule>) -> Self {
673        self.lib_len = Some(self.context.global.lib.len());
674        self.context.global.lib.push(module.into());
675        self
676    }
677    /// _(internals)_ Increment the current nesting level of function calls.
678    /// Exported under the `internals` feature only.
679    #[cfg(feature = "internals")]
680    #[inline(always)]
681    pub fn up_call_level(mut self) -> Self {
682        self.level = Some(self.context.global.level);
683        self.context.global.level += 1;
684        self
685    }
686}