diff --git a/src/api/call_fn.rs b/src/api/call_fn.rs index 3774be31c..01dcdf20d 100644 --- a/src/api/call_fn.rs +++ b/src/api/call_fn.rs @@ -174,13 +174,13 @@ impl Engine { args.parse(&mut arg_values); self._call_fn( + options, scope, - &mut self.new_global_runtime_state(), - &mut Caches::new(), ast, name.as_ref(), arg_values.as_mut(), - options, + &mut self.new_global_runtime_state(), + &mut Caches::new(), ) .and_then(|result| { result.try_cast_result().map_err(|r| { @@ -206,22 +206,24 @@ impl Engine { #[inline(always)] pub(crate) fn _call_fn( &self, + options: CallFnOptions, scope: &mut Scope, - global: &mut GlobalRuntimeState, - caches: &mut Caches, ast: &AST, name: &str, arg_values: &mut [Dynamic], - options: CallFnOptions, + global: &mut GlobalRuntimeState, + caches: &mut Caches, ) -> RhaiResult { let statements = ast.statements(); + let orig_source = mem::replace(&mut global.source, ast.source_raw().cloned()); + let orig_lib_len = global.lib.len(); + global.lib.push(ast.shared_lib().clone()); let orig_tag = options.tag.map(|v| mem::replace(&mut global.tag, v)); - let mut this_ptr = options.this_ptr; - global.lib.push(ast.shared_lib().clone()); + let mut this_ptr = options.this_ptr; #[cfg(not(feature = "no_module"))] let orig_embedded_module_resolver = @@ -229,6 +231,16 @@ impl Engine { let rewind_scope = options.rewind_scope; + defer! { global => move |g| { + #[cfg(not(feature = "no_module"))] + { + g.embedded_module_resolver = orig_embedded_module_resolver; + } + if let Some(orig_tag) = orig_tag { g.tag = orig_tag; } + g.lib.truncate(orig_lib_len); + g.source = orig_source; + }} + let global_result = if options.eval_ast && !statements.is_empty() { defer! { scope if rewind_scope => rewind; @@ -278,17 +290,6 @@ impl Engine { self.dbg(global, caches, scope, this_ptr, node)?; } - #[cfg(not(feature = "no_module"))] - { - global.embedded_module_resolver = orig_embedded_module_resolver; - } - - if let Some(value) = orig_tag { - global.tag = value; - } - - global.lib.truncate(orig_lib_len); - result.map_err(|err| match *err { ERR::ErrorInFunctionCall(fn_name, _, inner_err, _) if fn_name == name => inner_err, _ => err, diff --git a/src/api/deprecated.rs b/src/api/deprecated.rs index 98fc181aa..755560312 100644 --- a/src/api/deprecated.rs +++ b/src/api/deprecated.rs @@ -177,13 +177,13 @@ impl Engine { }; self._call_fn( + options, scope, - &mut self.new_global_runtime_state(), - &mut crate::eval::Caches::new(), ast, name.as_ref(), arg_values.as_mut(), - options, + &mut self.new_global_runtime_state(), + &mut crate::eval::Caches::new(), ) } /// Register a custom fallible function with the [`Engine`]. diff --git a/tests/print.rs b/tests/print.rs index 21657ab31..feb43fa95 100644 --- a/tests/print.rs +++ b/tests/print.rs @@ -1,4 +1,4 @@ -use rhai::{Engine, Scope, INT}; +use rhai::{Dynamic, Engine, Scope, INT}; use std::sync::{Arc, RwLock}; #[cfg(not(feature = "only_i32"))] @@ -36,9 +36,10 @@ fn test_print_debug() { engine.run("print(40 + 2)").unwrap(); let mut ast = engine.compile(r#"let x = "hello!"; debug(x)"#).unwrap(); ast.set_source("world"); - engine.run_ast(&ast).unwrap(); + let r = engine.eval_ast::(&ast).unwrap(); // 'logbook' captures all the 'print' and 'debug' output + assert!(r.is_unit()); assert_eq!(logbook.read().unwrap().len(), 2); assert_eq!(logbook.read().unwrap()[0], "entry: 42"); assert_eq!(logbook.read().unwrap()[1], if cfg!(not(feature = "no_position")) { r#"DEBUG of world at 1:19: "hello!""# } else { r#"DEBUG of world at none: "hello!""# });