Add new &Module parameter to native functions.
This commit is contained in:
78
src/api.rs
78
src/api.rs
@@ -6,6 +6,7 @@ use crate::error::ParseError;
|
||||
use crate::fn_call::FuncArgs;
|
||||
use crate::fn_native::{IteratorFn, SendSync};
|
||||
use crate::fn_register::RegisterFn;
|
||||
use crate::module::Module;
|
||||
use crate::optimize::{optimize_into_ast, OptimizationLevel};
|
||||
use crate::parser::AST;
|
||||
use crate::result::EvalAltResult;
|
||||
@@ -53,10 +54,10 @@ impl Engine {
|
||||
name: &str,
|
||||
args: &[TypeId],
|
||||
|
||||
#[cfg(not(feature = "sync"))] func: impl Fn(&Engine, &mut [&mut Dynamic]) -> Result<Dynamic, Box<EvalAltResult>>
|
||||
#[cfg(not(feature = "sync"))] func: impl Fn(&Engine, &Module, &mut [&mut Dynamic]) -> Result<Dynamic, Box<EvalAltResult>>
|
||||
+ 'static,
|
||||
|
||||
#[cfg(feature = "sync")] func: impl Fn(&Engine, &mut [&mut Dynamic]) -> Result<Dynamic, Box<EvalAltResult>>
|
||||
#[cfg(feature = "sync")] func: impl Fn(&Engine, &Module, &mut [&mut Dynamic]) -> Result<Dynamic, Box<EvalAltResult>>
|
||||
+ Send
|
||||
+ Sync
|
||||
+ 'static,
|
||||
@@ -459,7 +460,7 @@ impl Engine {
|
||||
self.register_indexer_set(setter);
|
||||
}
|
||||
|
||||
/// Compile a string into an [`AST`], which can be used later for evaluation.
|
||||
/// Compile a string into an `AST`, which can be used later for evaluation.
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
@@ -482,7 +483,7 @@ impl Engine {
|
||||
self.compile_with_scope(&Scope::new(), script)
|
||||
}
|
||||
|
||||
/// Compile a string into an [`AST`] using own scope, which can be used later for evaluation.
|
||||
/// Compile a string into an `AST` using own scope, which can be used later for evaluation.
|
||||
///
|
||||
/// The scope is useful for passing constants into the script for optimization
|
||||
/// when using `OptimizationLevel::Full`.
|
||||
@@ -525,7 +526,7 @@ impl Engine {
|
||||
}
|
||||
|
||||
/// When passed a list of strings, first join the strings into one large script,
|
||||
/// and then compile them into an [`AST`] using own scope, which can be used later for evaluation.
|
||||
/// and then compile them into an `AST` using own scope, which can be used later for evaluation.
|
||||
///
|
||||
/// The scope is useful for passing constants into the script for optimization
|
||||
/// when using `OptimizationLevel::Full`.
|
||||
@@ -578,7 +579,7 @@ impl Engine {
|
||||
self.compile_with_scope_and_optimization_level(scope, scripts, self.optimization_level)
|
||||
}
|
||||
|
||||
/// Join a list of strings and compile into an [`AST`] using own scope at a specific optimization level.
|
||||
/// Join a list of strings and compile into an `AST` using own scope at a specific optimization level.
|
||||
pub(crate) fn compile_with_scope_and_optimization_level(
|
||||
&self,
|
||||
scope: &Scope,
|
||||
@@ -614,7 +615,7 @@ impl Engine {
|
||||
Ok(contents)
|
||||
}
|
||||
|
||||
/// Compile a script file into an [`AST`], which can be used later for evaluation.
|
||||
/// Compile a script file into an `AST`, which can be used later for evaluation.
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
@@ -640,7 +641,7 @@ impl Engine {
|
||||
self.compile_file_with_scope(&Scope::new(), path)
|
||||
}
|
||||
|
||||
/// Compile a script file into an [`AST`] using own scope, which can be used later for evaluation.
|
||||
/// Compile a script file into an `AST` using own scope, which can be used later for evaluation.
|
||||
///
|
||||
/// The scope is useful for passing constants into the script for optimization
|
||||
/// when using `OptimizationLevel::Full`.
|
||||
@@ -722,7 +723,7 @@ impl Engine {
|
||||
self.eval_ast_with_scope(&mut scope, &ast)
|
||||
}
|
||||
|
||||
/// Compile a string containing an expression into an [`AST`],
|
||||
/// Compile a string containing an expression into an `AST`,
|
||||
/// which can be used later for evaluation.
|
||||
///
|
||||
/// # Example
|
||||
@@ -746,7 +747,7 @@ impl Engine {
|
||||
self.compile_expression_with_scope(&Scope::new(), script)
|
||||
}
|
||||
|
||||
/// Compile a string containing an expression into an [`AST`] using own scope,
|
||||
/// Compile a string containing an expression into an `AST` using own scope,
|
||||
/// which can be used later for evaluation.
|
||||
///
|
||||
/// The scope is useful for passing constants into the script for optimization
|
||||
@@ -954,7 +955,7 @@ impl Engine {
|
||||
self.eval_ast_with_scope(scope, &ast)
|
||||
}
|
||||
|
||||
/// Evaluate an [`AST`].
|
||||
/// Evaluate an `AST`.
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
@@ -976,7 +977,7 @@ impl Engine {
|
||||
self.eval_ast_with_scope(&mut Scope::new(), ast)
|
||||
}
|
||||
|
||||
/// Evaluate an [`AST`] with own scope.
|
||||
/// Evaluate an `AST` with own scope.
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
@@ -1024,7 +1025,7 @@ impl Engine {
|
||||
});
|
||||
}
|
||||
|
||||
/// Evaluate an [`AST`] with own scope.
|
||||
/// Evaluate an `AST` with own scope.
|
||||
pub(crate) fn eval_ast_with_scope_raw<'a>(
|
||||
&self,
|
||||
scope: &mut Scope,
|
||||
@@ -1090,7 +1091,7 @@ impl Engine {
|
||||
self.consume_ast_with_scope(&mut Scope::new(), ast)
|
||||
}
|
||||
|
||||
/// Evaluate an [`AST`] with own scope, but throw away the result and only return error (if any).
|
||||
/// Evaluate an `AST` with own scope, but throw away the result and only return error (if any).
|
||||
/// Useful for when you don't need the result, but still need to keep track of possible errors.
|
||||
pub fn consume_ast_with_scope(
|
||||
&self,
|
||||
@@ -1114,7 +1115,7 @@ impl Engine {
|
||||
)
|
||||
}
|
||||
|
||||
/// Call a script function defined in an [`AST`] with multiple arguments.
|
||||
/// Call a script function defined in an `AST` with multiple arguments.
|
||||
/// Arguments are passed as a tuple.
|
||||
///
|
||||
/// # Example
|
||||
@@ -1159,7 +1160,8 @@ impl Engine {
|
||||
args: A,
|
||||
) -> Result<T, Box<EvalAltResult>> {
|
||||
let mut arg_values = args.into_vec();
|
||||
let result = self.call_fn_dynamic_raw(scope, ast, name, &mut None, arg_values.as_mut())?;
|
||||
let result =
|
||||
self.call_fn_dynamic_raw(scope, ast.lib(), name, &mut None, arg_values.as_mut())?;
|
||||
|
||||
let typ = self.map_type_name(result.type_name());
|
||||
|
||||
@@ -1172,7 +1174,7 @@ impl Engine {
|
||||
});
|
||||
}
|
||||
|
||||
/// Call a script function defined in an [`AST`] with multiple `Dynamic` arguments
|
||||
/// Call a script function defined in an `AST` with multiple `Dynamic` arguments
|
||||
/// and optionally a value for binding to the 'this' pointer.
|
||||
///
|
||||
/// ## WARNING
|
||||
@@ -1203,19 +1205,19 @@ impl Engine {
|
||||
/// scope.push("foo", 42_i64);
|
||||
///
|
||||
/// // Call the script-defined function
|
||||
/// let result = engine.call_fn_dynamic(&mut scope, &ast, "add", None, [ String::from("abc").into(), 123_i64.into() ])?;
|
||||
/// // ^^^^ no 'this' pointer
|
||||
/// let result = engine.call_fn_dynamic(&mut scope, ast.into(), "add", None, [ String::from("abc").into(), 123_i64.into() ])?;
|
||||
/// // ^^^^ no 'this' pointer
|
||||
/// assert_eq!(result.cast::<i64>(), 168);
|
||||
///
|
||||
/// let result = engine.call_fn_dynamic(&mut scope, &ast, "add1", None, [ String::from("abc").into() ])?;
|
||||
/// let result = engine.call_fn_dynamic(&mut scope, ast.into(), "add1", None, [ String::from("abc").into() ])?;
|
||||
/// assert_eq!(result.cast::<i64>(), 46);
|
||||
///
|
||||
/// let result = engine.call_fn_dynamic(&mut scope, &ast, "bar", None, [])?;
|
||||
/// let result = engine.call_fn_dynamic(&mut scope, ast.into(), "bar", None, [])?;
|
||||
/// assert_eq!(result.cast::<i64>(), 21);
|
||||
///
|
||||
/// let mut value: Dynamic = 1_i64.into();
|
||||
/// let result = engine.call_fn_dynamic(&mut scope, &ast, "action", Some(&mut value), [ 41_i64.into() ])?;
|
||||
/// // ^^^^^^^^^^^^^^^^ binding the 'this' pointer
|
||||
/// let result = engine.call_fn_dynamic(&mut scope, ast.into(), "action", Some(&mut value), [ 41_i64.into() ])?;
|
||||
/// // ^^^^^^^^^^^^^^^^ binding the 'this' pointer
|
||||
/// assert_eq!(value.as_int().unwrap(), 42);
|
||||
/// # }
|
||||
/// # Ok(())
|
||||
@@ -1225,15 +1227,15 @@ impl Engine {
|
||||
pub fn call_fn_dynamic(
|
||||
&self,
|
||||
scope: &mut Scope,
|
||||
ast: &AST,
|
||||
lib: &Module,
|
||||
name: &str,
|
||||
mut this_ptr: Option<&mut Dynamic>,
|
||||
mut arg_values: impl AsMut<[Dynamic]>,
|
||||
) -> Result<Dynamic, Box<EvalAltResult>> {
|
||||
self.call_fn_dynamic_raw(scope, ast, name, &mut this_ptr, arg_values.as_mut())
|
||||
self.call_fn_dynamic_raw(scope, lib, name, &mut this_ptr, arg_values.as_mut())
|
||||
}
|
||||
|
||||
/// Call a script function defined in an [`AST`] with multiple `Dynamic` arguments.
|
||||
/// Call a script function defined in an `AST` with multiple `Dynamic` arguments.
|
||||
///
|
||||
/// ## WARNING
|
||||
///
|
||||
@@ -1245,14 +1247,14 @@ impl Engine {
|
||||
pub(crate) fn call_fn_dynamic_raw(
|
||||
&self,
|
||||
scope: &mut Scope,
|
||||
ast: &AST,
|
||||
lib: &Module,
|
||||
name: &str,
|
||||
this_ptr: &mut Option<&mut Dynamic>,
|
||||
arg_values: &mut [Dynamic],
|
||||
) -> Result<Dynamic, Box<EvalAltResult>> {
|
||||
let mut args: StaticVec<_> = arg_values.iter_mut().collect();
|
||||
let fn_def = get_script_function_by_signature(ast.lib(), name, args.len(), true)
|
||||
.ok_or_else(|| {
|
||||
let fn_def =
|
||||
get_script_function_by_signature(lib, name, args.len(), true).ok_or_else(|| {
|
||||
Box::new(EvalAltResult::ErrorFunctionNotFound(
|
||||
name.into(),
|
||||
Position::none(),
|
||||
@@ -1264,27 +1266,19 @@ impl Engine {
|
||||
let args = args.as_mut();
|
||||
|
||||
self.call_script_fn(
|
||||
scope,
|
||||
&mut mods,
|
||||
&mut state,
|
||||
ast.lib(),
|
||||
this_ptr,
|
||||
name,
|
||||
fn_def,
|
||||
args,
|
||||
0,
|
||||
scope, &mut mods, &mut state, lib, this_ptr, name, fn_def, args, 0,
|
||||
)
|
||||
}
|
||||
|
||||
/// Optimize the [`AST`] with constants defined in an external Scope.
|
||||
/// An optimized copy of the [`AST`] is returned while the original [`AST`] is consumed.
|
||||
/// Optimize the `AST` with constants defined in an external Scope.
|
||||
/// An optimized copy of the `AST` is returned while the original `AST` is consumed.
|
||||
///
|
||||
/// Although optimization is performed by default during compilation, sometimes it is necessary to
|
||||
/// _re_-optimize an AST. For example, when working with constants that are passed in via an
|
||||
/// external scope, it will be more efficient to optimize the [`AST`] once again to take advantage
|
||||
/// external scope, it will be more efficient to optimize the `AST` once again to take advantage
|
||||
/// of the new constants.
|
||||
///
|
||||
/// With this method, it is no longer necessary to recompile a large script. The script [`AST`] can be
|
||||
/// With this method, it is no longer necessary to recompile a large script. The script `AST` can be
|
||||
/// compiled just once. Before evaluation, constants are passed into the `Engine` via an external scope
|
||||
/// (i.e. with `scope.push_constant(...)`). Then, the `AST is cloned and the copy re-optimized before running.
|
||||
#[cfg(not(feature = "no_optimize"))]
|
||||
|
Reference in New Issue
Block a user