Fix function calls.
This commit is contained in:
parent
599fe846cb
commit
f406fc0ac0
105
src/fn_call.rs
105
src/fn_call.rs
@ -221,6 +221,7 @@ impl Engine {
|
|||||||
let func = self
|
let func = self
|
||||||
.global_module
|
.global_module
|
||||||
.get_fn(hash_fn, pub_only)
|
.get_fn(hash_fn, pub_only)
|
||||||
|
.or_else(|| lib.get_fn(hash_fn, pub_only))
|
||||||
.or_else(|| self.packages.get_fn(hash_fn, pub_only));
|
.or_else(|| self.packages.get_fn(hash_fn, pub_only));
|
||||||
|
|
||||||
if let Some(func) = func {
|
if let Some(func) = func {
|
||||||
@ -439,9 +440,9 @@ impl Engine {
|
|||||||
|
|
||||||
// First check script-defined functions
|
// First check script-defined functions
|
||||||
lib.contains_fn(hash_script, pub_only)
|
lib.contains_fn(hash_script, pub_only)
|
||||||
//|| lib.contains_fn(hash_fn, pub_only)
|
|| lib.contains_fn(hash_fn, pub_only)
|
||||||
// Then check registered functions
|
// Then check registered functions
|
||||||
//|| self.global_module.contains_fn(hash_script, pub_only)
|
|| self.global_module.contains_fn(hash_script, pub_only)
|
||||||
|| self.global_module.contains_fn(hash_fn, pub_only)
|
|| self.global_module.contains_fn(hash_fn, pub_only)
|
||||||
// Then check packages
|
// Then check packages
|
||||||
|| self.packages.contains_fn(hash_script, pub_only)
|
|| self.packages.contains_fn(hash_script, pub_only)
|
||||||
@ -522,58 +523,76 @@ impl Engine {
|
|||||||
.into()
|
.into()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Normal script function call
|
// Script-like function found
|
||||||
#[cfg(not(feature = "no_function"))]
|
#[cfg(not(feature = "no_function"))]
|
||||||
_ if lib.contains_fn(hash_script, pub_only)
|
_ if self.global_module.contains_fn(hash_script, pub_only)
|
||||||
|
|| lib.contains_fn(hash_script, pub_only)
|
||||||
|| self.packages.contains_fn(hash_script, pub_only) =>
|
|| self.packages.contains_fn(hash_script, pub_only) =>
|
||||||
{
|
{
|
||||||
// Get scripted function
|
// Get function
|
||||||
let func = lib
|
let func = self
|
||||||
|
.global_module
|
||||||
.get_fn(hash_script, pub_only)
|
.get_fn(hash_script, pub_only)
|
||||||
|
.or_else(|| lib.get_fn(hash_script, pub_only))
|
||||||
.or_else(|| self.packages.get_fn(hash_script, pub_only))
|
.or_else(|| self.packages.get_fn(hash_script, pub_only))
|
||||||
.unwrap()
|
.unwrap();
|
||||||
.get_fn_def();
|
|
||||||
|
|
||||||
let scope = &mut Scope::new();
|
if func.is_script() {
|
||||||
let mods = &mut Imports::new();
|
let func = func.get_fn_def();
|
||||||
|
|
||||||
// Add captured variables into scope
|
let scope = &mut Scope::new();
|
||||||
#[cfg(not(feature = "no_closure"))]
|
let mods = &mut Imports::new();
|
||||||
if let Some(captured) = _capture {
|
|
||||||
add_captured_variables_into_scope(&func.externals, captured, scope);
|
|
||||||
}
|
|
||||||
|
|
||||||
let result = if _is_method {
|
// Add captured variables into scope
|
||||||
// Method call of script function - map first argument to `this`
|
#[cfg(not(feature = "no_closure"))]
|
||||||
let (first, rest) = args.split_first_mut().unwrap();
|
if let Some(captured) = _capture {
|
||||||
self.call_script_fn(
|
add_captured_variables_into_scope(&func.externals, captured, scope);
|
||||||
scope,
|
}
|
||||||
mods,
|
|
||||||
|
let result = if _is_method {
|
||||||
|
// Method call of script function - map first argument to `this`
|
||||||
|
let (first, rest) = args.split_first_mut().unwrap();
|
||||||
|
self.call_script_fn(
|
||||||
|
scope,
|
||||||
|
mods,
|
||||||
|
state,
|
||||||
|
lib,
|
||||||
|
&mut Some(*first),
|
||||||
|
fn_name,
|
||||||
|
func,
|
||||||
|
rest,
|
||||||
|
_level,
|
||||||
|
)?
|
||||||
|
} else {
|
||||||
|
// Normal call of script function - map first argument to `this`
|
||||||
|
// The first argument is a reference?
|
||||||
|
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,
|
||||||
|
);
|
||||||
|
|
||||||
|
// Restore the original reference
|
||||||
|
backup.restore_first_arg(args);
|
||||||
|
|
||||||
|
result?
|
||||||
|
};
|
||||||
|
|
||||||
|
Ok((result, false))
|
||||||
|
} else {
|
||||||
|
// If it is a native function, redirect it
|
||||||
|
self.call_native_fn(
|
||||||
state,
|
state,
|
||||||
lib,
|
lib,
|
||||||
&mut Some(*first),
|
|
||||||
fn_name,
|
fn_name,
|
||||||
func,
|
hash_script,
|
||||||
rest,
|
args,
|
||||||
_level,
|
is_ref,
|
||||||
)?
|
pub_only,
|
||||||
} else {
|
def_val,
|
||||||
// Normal call of script function - map first argument to `this`
|
)
|
||||||
// The first argument is a reference?
|
}
|
||||||
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,
|
|
||||||
);
|
|
||||||
|
|
||||||
// Restore the original reference
|
|
||||||
backup.restore_first_arg(args);
|
|
||||||
|
|
||||||
result?
|
|
||||||
};
|
|
||||||
|
|
||||||
Ok((result, false))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Normal native function call
|
// Normal native function call
|
||||||
|
@ -262,7 +262,7 @@ fn test_module_from_ast() -> Result<(), Box<EvalAltResult>> {
|
|||||||
|
|
||||||
engine.set_module_resolver(Some(resolver1));
|
engine.set_module_resolver(Some(resolver1));
|
||||||
|
|
||||||
let module = Module::eval_ast_as_new(Scope::new(), &ast, &engine)?;
|
let module = Module::eval_ast_as_new(Scope::new(), &ast, true, &engine)?;
|
||||||
|
|
||||||
let mut resolver2 = StaticModuleResolver::new();
|
let mut resolver2 = StaticModuleResolver::new();
|
||||||
resolver2.insert("testing", module);
|
resolver2.insert("testing", module);
|
||||||
|
@ -34,12 +34,15 @@ fn test_packages() -> Result<(), Box<EvalAltResult>> {
|
|||||||
#[test]
|
#[test]
|
||||||
fn test_packages_with_script() -> Result<(), Box<EvalAltResult>> {
|
fn test_packages_with_script() -> Result<(), Box<EvalAltResult>> {
|
||||||
let mut engine = Engine::new();
|
let mut engine = Engine::new();
|
||||||
let ast = engine.compile("fn foo(x) { x + 1 }")?;
|
let ast = engine.compile("fn foo(x) { x + 1 } fn bar(x) { foo(x) + 1 }")?;
|
||||||
let module = Module::eval_ast_as_new(Scope::new(), &ast, &engine)?;
|
|
||||||
|
|
||||||
|
let module = Module::eval_ast_as_new(Scope::new(), &ast, false, &engine)?;
|
||||||
engine.load_package(module);
|
engine.load_package(module);
|
||||||
|
|
||||||
assert_eq!(engine.eval::<INT>("foo(41)")?, 42);
|
assert_eq!(engine.eval::<INT>("foo(41)")?, 42);
|
||||||
|
|
||||||
|
let module = Module::eval_ast_as_new(Scope::new(), &ast, true, &engine)?;
|
||||||
|
engine.load_package(module);
|
||||||
|
assert_eq!(engine.eval::<INT>("bar(40)")?, 42);
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user