From f995d09d8b1377c6f86318a3d8671a4010061dc5 Mon Sep 17 00:00:00 2001 From: Stephen Chung Date: Fri, 16 Oct 2020 21:16:06 +0800 Subject: [PATCH] Fix bug with calling scripted function. --- RELEASES.md | 1 - src/api.rs | 4 +--- src/fn_call.rs | 25 ++++++++++++------------- tests/modules.rs | 33 +++++++++++++++++++++++++++++++++ 4 files changed, 46 insertions(+), 17 deletions(-) diff --git a/RELEASES.md b/RELEASES.md index 63c761f4..19a0e65d 100644 --- a/RELEASES.md +++ b/RELEASES.md @@ -13,7 +13,6 @@ Breaking changes * `AST::iter_functions` now returns an iterator instead of taking a closure. * `Module::get_script_function_by_signature` renamed to `Module::get_script_fn` and returns `&>`. * `Module::num_fn`, `Module::num_var` and `Module::num_iter` are removed and merged into `Module::count`. -* `Module::set_iter` is renamed to `Module::set_iter_raw`. * The `merge_namespaces` parameter to `Module::eval_ast_as_new` is removed and now defaults to `true`. * `GlobalFileModuleResolver` is removed because its performance gain over the `FileModuleResolver` is no longer very significant. * The following `EvalAltResult` variants are removed and merged into `EvalAltResult::ErrorMismatchDataType`: `ErrorCharMismatch`, `ErrorNumericIndexExpr`, `ErrorStringIndexExpr`, `ErrorImportExpr`, `ErrorLogicGuard`, `ErrorBooleanArgMismatch` diff --git a/src/api.rs b/src/api.rs index 8018e447..573730e5 100644 --- a/src/api.rs +++ b/src/api.rs @@ -1652,9 +1652,7 @@ impl Engine { ensure_no_data_race(name, args, false)?; } - self.call_script_fn( - scope, &mut mods, &mut state, lib, this_ptr, name, fn_def, args, 0, - ) + self.call_script_fn(scope, &mut mods, &mut state, lib, this_ptr, fn_def, args, 0) } /// Optimize the `AST` with constants defined in an external Scope. diff --git a/src/fn_call.rs b/src/fn_call.rs index 915985d4..e0cf13e0 100644 --- a/src/fn_call.rs +++ b/src/fn_call.rs @@ -347,7 +347,6 @@ impl Engine { state: &mut State, lib: &Module, this_ptr: &mut Option<&mut Dynamic>, - fn_name: &str, fn_def: &ScriptFnDef, args: &mut FnCallArgs, level: usize, @@ -386,7 +385,7 @@ impl Engine { let mut lib_merged; let unified_lib = if let Some(ref env_lib) = fn_def.lib { - if !lib.is_empty() { + if lib.is_empty() { // In the special case of the main script not defining any function env_lib } else { @@ -408,14 +407,18 @@ impl Engine { EvalAltResult::Return(x, _) => Ok(x), EvalAltResult::ErrorInFunctionCall(name, err, _) => { EvalAltResult::ErrorInFunctionCall( - format!("{} > {}", fn_name, name), + format!("{} > {}", fn_def.name, name), err, Position::none(), ) .into() } - _ => EvalAltResult::ErrorInFunctionCall(fn_name.to_string(), err, Position::none()) - .into(), + _ => EvalAltResult::ErrorInFunctionCall( + fn_def.name.to_string(), + err, + Position::none(), + ) + .into(), }); // Remove all local variables @@ -594,7 +597,6 @@ impl Engine { state, lib, &mut Some(*first), - fn_name, func, rest, _level, @@ -605,9 +607,8 @@ impl Engine { let mut backup: ArgBackup = Default::default(); backup.change_first_arg_to_copy(is_ref, args); - let result = self.call_script_fn( - scope, mods, state, lib, &mut None, fn_name, func, args, _level, - ); + let result = self + .call_script_fn(scope, mods, state, lib, &mut None, func, args, _level); // Restore the original reference backup.restore_first_arg(args); @@ -1195,14 +1196,12 @@ impl Engine { } let args = args.as_mut(); - let func = f.get_fn_def(); + let fn_def = f.get_fn_def(); let new_scope = &mut Scope::new(); let mods = &mut Imports::new(); - self.call_script_fn( - new_scope, mods, state, lib, &mut None, name, func, args, level, - ) + self.call_script_fn(new_scope, mods, state, lib, &mut None, fn_def, args, level) } Some(f) if f.is_plugin_fn() => f.get_plugin_fn().call(args.as_mut()), Some(f) if f.is_native() => { diff --git a/tests/modules.rs b/tests/modules.rs index d2ee5e1c..3259aa07 100644 --- a/tests/modules.rs +++ b/tests/modules.rs @@ -399,3 +399,36 @@ fn test_module_ast_namespace() -> Result<(), Box> { Ok(()) } + +#[cfg(not(feature = "no_function"))] +#[test] +fn test_module_ast_namespace2() -> Result<(), Box> { + use rhai::{Engine, Module, Scope}; + + const MODULE_TEXT: &str = r#" + fn run_function(function) { + function.call() + } + "#; + + const SCRIPT: &str = r#" + import "test_module" as test; + + fn foo() { + print("foo"); + } + + test::run_function(Fn("foo")); + "#; + + let mut engine = Engine::new(); + let module_ast = engine.compile(MODULE_TEXT)?; + let module = Module::eval_ast_as_new(Scope::new(), &module_ast, &engine)?; + let mut static_modules = rhai::module_resolvers::StaticModuleResolver::new(); + static_modules.insert("test_module", module); + engine.set_module_resolver(Some(static_modules)); + + engine.consume(SCRIPT)?; + + Ok(()) +}