Fix bug where plugin module parameters are consumed.

This commit is contained in:
Stephen Chung 2021-01-23 09:37:27 +08:00
parent 8aae3ac46c
commit 3b42cc5bb2
3 changed files with 43 additions and 22 deletions

View File

@ -17,6 +17,7 @@ Breaking changes
Bug fixes
---------
* Parameters passed to plugin module functions were sometimes erroneously consumed. This is now fixed.
* Fixes compilation errors in `metadata` feature build.
New features

View File

@ -1210,16 +1210,18 @@ impl Engine {
r => r,
};
// Clone first argument if the function is not a method after-all
if let Some(first) = first_arg_value {
if !func.map(|f| f.is_method()).unwrap_or(true) {
let first_val = args[0].clone();
args[0] = first;
*args[0] = first_val;
}
}
match func {
#[cfg(not(feature = "no_function"))]
Some(f) if f.is_script() => {
// Clone first argument
if let Some(first) = first_arg_value {
let first_val = args[0].clone();
args[0] = first;
*args[0] = first_val;
}
let args = args.as_mut();
let new_scope = &mut Default::default();
let fn_def = f.get_fn_def().clone();
@ -1241,21 +1243,10 @@ impl Engine {
(self, fn_name, module.id(), &*mods, lib).into(),
args.as_mut(),
),
Some(f) if f.is_native() => {
if !f.is_method() {
// Clone first argument
if let Some(first) = first_arg_value {
let first_val = args[0].clone();
args[0] = first;
*args[0] = first_val;
}
}
f.get_native_fn()(
(self, fn_name, module.id(), &*mods, lib).into(),
args.as_mut(),
)
}
Some(f) if f.is_native() => f.get_native_fn()(
(self, fn_name, module.id(), &*mods, lib).into(),
args.as_mut(),
),
Some(f) => unreachable!("unknown function type: {:?}", f),
None if def_val.is_some() => Ok(def_val.unwrap().clone()),
None => EvalAltResult::ErrorFunctionNotFound(

View File

@ -101,3 +101,32 @@ fn test_plugins_package() -> Result<(), Box<EvalAltResult>> {
Ok(())
}
#[test]
fn test_plugins_parameters() -> Result<(), Box<EvalAltResult>> {
#[export_module]
mod rhai_std {
use rhai::*;
pub fn noop(_: &str) {}
}
let mut engine = Engine::new();
let std = exported_module!(rhai_std);
engine.register_static_module("std", std.into());
assert_eq!(
engine.eval::<String>(
r#"
let s = "hello";
std::noop(s);
s
"#
)?,
"hello"
);
Ok(())
}