Create NativeCallable trait.
This commit is contained in:
parent
314ec5e4d2
commit
4a8710a4a9
@ -3,11 +3,12 @@
|
||||
use crate::any::{Dynamic, Union};
|
||||
use crate::calc_fn_hash;
|
||||
use crate::error::ParseErrorType;
|
||||
use crate::fn_native::{FnCallArgs, NativeFunction, SharedNativeFunction};
|
||||
use crate::optimize::OptimizationLevel;
|
||||
use crate::packages::{
|
||||
CorePackage, Package, PackageLibrary, PackageStore, PackagesCollection, StandardPackage,
|
||||
};
|
||||
use crate::parser::{Expr, FnAccess, FnDef, ReturnType, Stmt, AST};
|
||||
use crate::parser::{Expr, FnAccess, FnDef, ReturnType, SharedFnDef, Stmt, AST};
|
||||
use crate::result::EvalAltResult;
|
||||
use crate::scope::{EntryType as ScopeEntryType, Scope};
|
||||
use crate::token::Position;
|
||||
@ -46,19 +47,6 @@ pub type Array = Vec<Dynamic>;
|
||||
#[cfg(not(feature = "no_object"))]
|
||||
pub type Map = HashMap<String, Dynamic>;
|
||||
|
||||
pub type FnCallArgs<'a> = [&'a mut Dynamic];
|
||||
|
||||
#[cfg(feature = "sync")]
|
||||
pub type FnAny =
|
||||
dyn Fn(&mut FnCallArgs, Position) -> Result<Dynamic, Box<EvalAltResult>> + Send + Sync;
|
||||
#[cfg(not(feature = "sync"))]
|
||||
pub type FnAny = dyn Fn(&mut FnCallArgs, Position) -> Result<Dynamic, Box<EvalAltResult>>;
|
||||
|
||||
#[cfg(feature = "sync")]
|
||||
pub type IteratorFn = dyn Fn(Dynamic) -> Box<dyn Iterator<Item = Dynamic>> + Send + Sync;
|
||||
#[cfg(not(feature = "sync"))]
|
||||
pub type IteratorFn = dyn Fn(Dynamic) -> Box<dyn Iterator<Item = Dynamic>>;
|
||||
|
||||
#[cfg(debug_assertions)]
|
||||
pub const MAX_CALL_STACK_DEPTH: usize = 28;
|
||||
|
||||
@ -168,20 +156,6 @@ impl<'a> State<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
/// An external native Rust function.
|
||||
#[cfg(not(feature = "sync"))]
|
||||
pub type NativeFunction = Rc<Box<FnAny>>;
|
||||
/// An external native Rust function.
|
||||
#[cfg(feature = "sync")]
|
||||
pub type NativeFunction = Arc<Box<FnAny>>;
|
||||
|
||||
/// A sharable script-defined function.
|
||||
#[cfg(feature = "sync")]
|
||||
pub type ScriptedFunction = Arc<FnDef>;
|
||||
/// A sharable script-defined function.
|
||||
#[cfg(not(feature = "sync"))]
|
||||
pub type ScriptedFunction = Rc<FnDef>;
|
||||
|
||||
/// A type that holds a library (`HashMap`) of script-defined functions.
|
||||
///
|
||||
/// Since script-defined functions have `Dynamic` parameters, functions with the same name
|
||||
@ -190,7 +164,7 @@ pub type ScriptedFunction = Rc<FnDef>;
|
||||
/// The key of the `HashMap` is a `u64` hash calculated by the function `calc_fn_hash`
|
||||
/// with dummy parameter types `EMPTY_TYPE_ID()` repeated the correct number of times.
|
||||
#[derive(Debug, Clone, Default)]
|
||||
pub struct FunctionsLib(HashMap<u64, ScriptedFunction>);
|
||||
pub struct FunctionsLib(HashMap<u64, SharedFnDef>);
|
||||
|
||||
impl FunctionsLib {
|
||||
/// Create a new `FunctionsLib` from a collection of `FnDef`.
|
||||
@ -261,8 +235,8 @@ impl FunctionsLib {
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Vec<(u64, ScriptedFunction)>> for FunctionsLib {
|
||||
fn from(values: Vec<(u64, ScriptedFunction)>) -> Self {
|
||||
impl From<Vec<(u64, SharedFnDef)>> for FunctionsLib {
|
||||
fn from(values: Vec<(u64, SharedFnDef)>) -> Self {
|
||||
FunctionsLib(values.into_iter().collect())
|
||||
}
|
||||
}
|
||||
@ -596,7 +570,7 @@ impl Engine {
|
||||
.or_else(|| self.packages.get_function(hash_fn_spec))
|
||||
{
|
||||
// Run external function
|
||||
let result = func(args, pos)?;
|
||||
let result = func.call(args, pos)?;
|
||||
|
||||
// See if the function match print/debug (which requires special processing)
|
||||
return Ok(match fn_name {
|
||||
@ -1476,7 +1450,7 @@ impl Engine {
|
||||
let hash = *hash_fn_def ^ hash_fn_args;
|
||||
|
||||
match module.get_qualified_fn(name, hash, *pos) {
|
||||
Ok(func) => func(args.as_mut(), *pos),
|
||||
Ok(func) => func.call(args.as_mut(), *pos),
|
||||
Err(_) if def_val.is_some() => Ok(def_val.clone().unwrap()),
|
||||
Err(err) => Err(err),
|
||||
}
|
||||
|
52
src/fn_native.rs
Normal file
52
src/fn_native.rs
Normal file
@ -0,0 +1,52 @@
|
||||
use crate::any::Dynamic;
|
||||
use crate::result::EvalAltResult;
|
||||
use crate::token::Position;
|
||||
|
||||
use crate::stdlib::{boxed::Box, rc::Rc, sync::Arc};
|
||||
|
||||
pub type FnCallArgs<'a> = [&'a mut Dynamic];
|
||||
|
||||
#[cfg(feature = "sync")]
|
||||
pub type FnAny =
|
||||
dyn Fn(&mut FnCallArgs, Position) -> Result<Dynamic, Box<EvalAltResult>> + Send + Sync;
|
||||
#[cfg(not(feature = "sync"))]
|
||||
pub type FnAny = dyn Fn(&mut FnCallArgs, Position) -> Result<Dynamic, Box<EvalAltResult>>;
|
||||
|
||||
#[cfg(feature = "sync")]
|
||||
pub type IteratorFn = dyn Fn(Dynamic) -> Box<dyn Iterator<Item = Dynamic>> + Send + Sync;
|
||||
#[cfg(not(feature = "sync"))]
|
||||
pub type IteratorFn = dyn Fn(Dynamic) -> Box<dyn Iterator<Item = Dynamic>>;
|
||||
|
||||
/// A trait implemented by all native Rust functions that are callable by Rhai.
|
||||
pub trait NativeCallable {
|
||||
/// Call a native Rust function.
|
||||
fn call(&self, args: &mut FnCallArgs, pos: Position) -> Result<Dynamic, Box<EvalAltResult>>;
|
||||
}
|
||||
|
||||
/// A type encapsulating a native Rust function callable by Rhai.
|
||||
pub struct NativeFunction(Box<FnAny>);
|
||||
|
||||
impl NativeCallable for NativeFunction {
|
||||
fn call(&self, args: &mut FnCallArgs, pos: Position) -> Result<Dynamic, Box<EvalAltResult>> {
|
||||
(self.0)(args, pos)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Box<FnAny>> for NativeFunction {
|
||||
fn from(func: Box<FnAny>) -> Self {
|
||||
Self::new(func)
|
||||
}
|
||||
}
|
||||
impl NativeFunction {
|
||||
/// Create a new `NativeFunction`.
|
||||
pub fn new(func: Box<FnAny>) -> Self {
|
||||
Self(func)
|
||||
}
|
||||
}
|
||||
|
||||
/// An external native Rust function.
|
||||
#[cfg(not(feature = "sync"))]
|
||||
pub type SharedNativeFunction = Rc<Box<dyn NativeCallable>>;
|
||||
/// An external native Rust function.
|
||||
#[cfg(feature = "sync")]
|
||||
pub type SharedNativeFunction = Arc<Box<dyn NativeCallable>>;
|
@ -3,7 +3,8 @@
|
||||
#![allow(non_snake_case)]
|
||||
|
||||
use crate::any::{Dynamic, Variant};
|
||||
use crate::engine::{Engine, FnCallArgs};
|
||||
use crate::engine::Engine;
|
||||
use crate::fn_native::{FnCallArgs, NativeFunction};
|
||||
use crate::result::EvalAltResult;
|
||||
use crate::token::Position;
|
||||
use crate::utils::calc_fn_spec;
|
||||
@ -117,14 +118,14 @@ pub struct Mut<T>(T);
|
||||
//pub struct Ref<T>(T);
|
||||
|
||||
/// Dereference into &mut.
|
||||
#[inline]
|
||||
#[inline(always)]
|
||||
pub fn by_ref<T: Clone + 'static>(data: &mut Dynamic) -> &mut T {
|
||||
// Directly cast the &mut Dynamic into &mut T to access the underlying data.
|
||||
data.downcast_mut::<T>().unwrap()
|
||||
}
|
||||
|
||||
/// Dereference into value.
|
||||
#[inline]
|
||||
#[inline(always)]
|
||||
pub fn by_value<T: Clone + 'static>(data: &mut Dynamic) -> T {
|
||||
// We consume the argument and then replace it with () - the argument is not supposed to be used again.
|
||||
// This way, we avoid having to clone the argument again, because it is already a clone when passed here.
|
||||
@ -133,14 +134,13 @@ pub fn by_value<T: Clone + 'static>(data: &mut Dynamic) -> T {
|
||||
|
||||
/// This macro creates a closure wrapping a registered function.
|
||||
macro_rules! make_func {
|
||||
($fn_name:ident : $fn:ident : $map:expr ; $($par:ident => $convert:expr),*) => {
|
||||
// ^ function name
|
||||
($fn:ident : $map:expr ; $($par:ident => $convert:expr),*) => {
|
||||
// ^ function pointer
|
||||
// ^ result mapping function
|
||||
// ^ function parameter generic type name (A, B, C etc.)
|
||||
// ^ dereferencing function
|
||||
|
||||
move |args: &mut FnCallArgs, pos: Position| {
|
||||
NativeFunction::new(Box::new(move |args: &mut FnCallArgs, pos: Position| {
|
||||
// The arguments are assumed to be of the correct number and types!
|
||||
|
||||
#[allow(unused_variables, unused_mut)]
|
||||
@ -156,12 +156,12 @@ macro_rules! make_func {
|
||||
|
||||
// Map the result
|
||||
$map(r, pos)
|
||||
};
|
||||
}));
|
||||
};
|
||||
}
|
||||
|
||||
/// To Dynamic mapping function.
|
||||
#[inline]
|
||||
#[inline(always)]
|
||||
pub fn map_dynamic<T: Variant + Clone>(
|
||||
data: T,
|
||||
_pos: Position,
|
||||
@ -170,13 +170,13 @@ pub fn map_dynamic<T: Variant + Clone>(
|
||||
}
|
||||
|
||||
/// To Dynamic mapping function.
|
||||
#[inline]
|
||||
#[inline(always)]
|
||||
pub fn map_identity(data: Dynamic, _pos: Position) -> Result<Dynamic, Box<EvalAltResult>> {
|
||||
Ok(data)
|
||||
}
|
||||
|
||||
/// To `Result<Dynamic, Box<EvalAltResult>>` mapping function.
|
||||
#[inline]
|
||||
#[inline(always)]
|
||||
pub fn map_result<T: Variant + Clone>(
|
||||
data: Result<T, Box<EvalAltResult>>,
|
||||
pos: Position,
|
||||
@ -207,8 +207,7 @@ macro_rules! def_register {
|
||||
> RegisterFn<FN, ($($mark,)*), RET> for Engine
|
||||
{
|
||||
fn register_fn(&mut self, name: &str, f: FN) {
|
||||
let fn_name = name.to_string();
|
||||
let func = make_func!(fn_name : f : map_dynamic ; $($par => $clone),*);
|
||||
let func = make_func!(f : map_dynamic ; $($par => $clone),*);
|
||||
let hash = calc_fn_spec(empty(), name, [$(TypeId::of::<$par>()),*].iter().cloned());
|
||||
self.base_package.functions.insert(hash, Box::new(func));
|
||||
}
|
||||
@ -225,8 +224,7 @@ macro_rules! def_register {
|
||||
> RegisterDynamicFn<FN, ($($mark,)*)> for Engine
|
||||
{
|
||||
fn register_dynamic_fn(&mut self, name: &str, f: FN) {
|
||||
let fn_name = name.to_string();
|
||||
let func = make_func!(fn_name : f : map_identity ; $($par => $clone),*);
|
||||
let func = make_func!(f : map_identity ; $($par => $clone),*);
|
||||
let hash = calc_fn_spec(empty(), name, [$(TypeId::of::<$par>()),*].iter().cloned());
|
||||
self.base_package.functions.insert(hash, Box::new(func));
|
||||
}
|
||||
@ -244,8 +242,7 @@ macro_rules! def_register {
|
||||
> RegisterResultFn<FN, ($($mark,)*), RET> for Engine
|
||||
{
|
||||
fn register_result_fn(&mut self, name: &str, f: FN) {
|
||||
let fn_name = name.to_string();
|
||||
let func = make_func!(fn_name : f : map_result ; $($par => $clone),*);
|
||||
let func = make_func!(f : map_result ; $($par => $clone),*);
|
||||
let hash = calc_fn_spec(empty(), name, [$(TypeId::of::<$par>()),*].iter().cloned());
|
||||
self.base_package.functions.insert(hash, Box::new(func));
|
||||
}
|
||||
|
@ -75,6 +75,7 @@ mod engine;
|
||||
mod error;
|
||||
mod fn_call;
|
||||
mod fn_func;
|
||||
mod fn_native;
|
||||
mod fn_register;
|
||||
mod module;
|
||||
mod optimize;
|
||||
@ -90,6 +91,7 @@ pub use any::Dynamic;
|
||||
pub use engine::Engine;
|
||||
pub use error::{ParseError, ParseErrorType};
|
||||
pub use fn_call::FuncArgs;
|
||||
pub use fn_native::NativeCallable;
|
||||
pub use fn_register::{RegisterDynamicFn, RegisterFn, RegisterResultFn};
|
||||
pub use parser::{AST, INT};
|
||||
pub use result::EvalAltResult;
|
||||
|
@ -3,8 +3,9 @@
|
||||
|
||||
use crate::any::{Dynamic, Variant};
|
||||
use crate::calc_fn_hash;
|
||||
use crate::engine::{Engine, FnAny, FnCallArgs, FunctionsLib, NativeFunction, ScriptedFunction};
|
||||
use crate::parser::{FnAccess, FnDef, AST};
|
||||
use crate::engine::{Engine, FunctionsLib};
|
||||
use crate::fn_native::{FnAny, FnCallArgs, NativeCallable, NativeFunction, SharedNativeFunction};
|
||||
use crate::parser::{FnAccess, FnDef, SharedFnDef, AST};
|
||||
use crate::result::EvalAltResult;
|
||||
use crate::scope::{Entry as ScopeEntry, EntryType as ScopeEntryType, Scope};
|
||||
use crate::token::{Position, Token};
|
||||
@ -57,10 +58,10 @@ pub struct Module {
|
||||
all_variables: HashMap<u64, Dynamic>,
|
||||
|
||||
/// External Rust functions.
|
||||
functions: HashMap<u64, (String, FnAccess, Vec<TypeId>, NativeFunction)>,
|
||||
functions: HashMap<u64, (String, FnAccess, Vec<TypeId>, SharedNativeFunction)>,
|
||||
|
||||
/// Flattened collection of all external Rust functions, including those in sub-modules.
|
||||
all_functions: HashMap<u64, NativeFunction>,
|
||||
all_functions: HashMap<u64, SharedNativeFunction>,
|
||||
|
||||
/// Script-defined functions.
|
||||
fn_lib: FunctionsLib,
|
||||
@ -269,12 +270,14 @@ impl Module {
|
||||
) -> u64 {
|
||||
let hash = calc_fn_hash(empty(), &fn_name, params.iter().cloned());
|
||||
|
||||
let f = Box::new(NativeFunction::from(func)) as Box<dyn NativeCallable>;
|
||||
|
||||
#[cfg(not(feature = "sync"))]
|
||||
self.functions
|
||||
.insert(hash, (fn_name, access, params, Rc::new(func)));
|
||||
let func = Rc::new(f);
|
||||
#[cfg(feature = "sync")]
|
||||
self.functions
|
||||
.insert(hash, (fn_name, access, params, Arc::new(func)));
|
||||
let func = Arc::new(f);
|
||||
|
||||
self.functions.insert(hash, (fn_name, access, params, func));
|
||||
|
||||
hash
|
||||
}
|
||||
@ -528,7 +531,7 @@ impl Module {
|
||||
/// let hash = module.set_fn_1("calc", |x: i64| Ok(x + 1));
|
||||
/// assert!(module.get_fn(hash).is_some());
|
||||
/// ```
|
||||
pub fn get_fn(&self, hash: u64) -> Option<&Box<FnAny>> {
|
||||
pub fn get_fn(&self, hash: u64) -> Option<&Box<dyn NativeCallable>> {
|
||||
self.functions.get(&hash).map(|(_, _, _, v)| v.as_ref())
|
||||
}
|
||||
|
||||
@ -541,7 +544,7 @@ impl Module {
|
||||
name: &str,
|
||||
hash: u64,
|
||||
pos: Position,
|
||||
) -> Result<&Box<FnAny>, Box<EvalAltResult>> {
|
||||
) -> Result<&Box<dyn NativeCallable>, Box<EvalAltResult>> {
|
||||
self.all_functions
|
||||
.get(&hash)
|
||||
.map(|f| f.as_ref())
|
||||
@ -626,8 +629,8 @@ impl Module {
|
||||
module: &'a mut Module,
|
||||
qualifiers: &mut Vec<&'a str>,
|
||||
variables: &mut Vec<(u64, Dynamic)>,
|
||||
functions: &mut Vec<(u64, NativeFunction)>,
|
||||
fn_lib: &mut Vec<(u64, ScriptedFunction)>,
|
||||
functions: &mut Vec<(u64, SharedNativeFunction)>,
|
||||
fn_lib: &mut Vec<(u64, SharedFnDef)>,
|
||||
) {
|
||||
for (name, m) in module.modules.iter_mut() {
|
||||
// Index all the sub-modules first.
|
||||
|
@ -1,9 +1,9 @@
|
||||
use crate::any::Dynamic;
|
||||
use crate::calc_fn_hash;
|
||||
use crate::engine::{
|
||||
Engine, FnAny, FnCallArgs, FunctionsLib, KEYWORD_DEBUG, KEYWORD_EVAL, KEYWORD_PRINT,
|
||||
KEYWORD_TYPE_OF,
|
||||
Engine, FunctionsLib, KEYWORD_DEBUG, KEYWORD_EVAL, KEYWORD_PRINT, KEYWORD_TYPE_OF,
|
||||
};
|
||||
use crate::fn_native::FnCallArgs;
|
||||
use crate::packages::{PackageStore, PackagesCollection};
|
||||
use crate::parser::{map_dynamic_to_expr, Expr, FnDef, ReturnType, Stmt, AST};
|
||||
use crate::result::EvalAltResult;
|
||||
@ -123,7 +123,7 @@ fn call_fn(
|
||||
base_package
|
||||
.get_function(hash)
|
||||
.or_else(|| packages.get_function(hash))
|
||||
.map(|func| func(args, pos))
|
||||
.map(|func| func.call(args, pos))
|
||||
.transpose()
|
||||
}
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
//! This module contains all built-in _packages_ available to Rhai, plus facilities to define custom packages.
|
||||
|
||||
use crate::engine::{FnAny, IteratorFn};
|
||||
use crate::fn_native::{IteratorFn, NativeCallable};
|
||||
|
||||
use crate::stdlib::{any::TypeId, boxed::Box, collections::HashMap, rc::Rc, sync::Arc, vec::Vec};
|
||||
|
||||
@ -48,7 +48,7 @@ pub trait Package {
|
||||
/// Type to store all functions in the package.
|
||||
pub struct PackageStore {
|
||||
/// All functions, keyed by a hash created from the function name and parameter types.
|
||||
pub functions: HashMap<u64, Box<FnAny>>,
|
||||
pub functions: HashMap<u64, Box<dyn NativeCallable>>,
|
||||
|
||||
/// All iterator functions, keyed by the type producing the iterator.
|
||||
pub type_iterators: HashMap<TypeId, Box<IteratorFn>>,
|
||||
@ -64,7 +64,7 @@ impl PackageStore {
|
||||
self.functions.contains_key(&hash)
|
||||
}
|
||||
/// Get specified function via its hash key.
|
||||
pub fn get_function(&self, hash: u64) -> Option<&Box<FnAny>> {
|
||||
pub fn get_function(&self, hash: u64) -> Option<&Box<dyn NativeCallable>> {
|
||||
self.functions.get(&hash)
|
||||
}
|
||||
/// Does the specified TypeId iterator exist in the `PackageStore`?
|
||||
@ -113,7 +113,7 @@ impl PackagesCollection {
|
||||
self.packages.iter().any(|p| p.contains_function(hash))
|
||||
}
|
||||
/// Get specified function via its hash key.
|
||||
pub fn get_function(&self, hash: u64) -> Option<&Box<FnAny>> {
|
||||
pub fn get_function(&self, hash: u64) -> Option<&Box<dyn NativeCallable>> {
|
||||
self.packages
|
||||
.iter()
|
||||
.map(|p| p.get_function(hash))
|
||||
|
@ -2,7 +2,7 @@ use super::PackageStore;
|
||||
|
||||
use crate::any::{Dynamic, Variant};
|
||||
use crate::calc_fn_hash;
|
||||
use crate::engine::FnCallArgs;
|
||||
use crate::fn_native::{FnCallArgs, NativeFunction};
|
||||
use crate::result::EvalAltResult;
|
||||
use crate::token::Position;
|
||||
|
||||
@ -106,7 +106,7 @@ pub fn reg_none<R>(
|
||||
map_result(r, pos)
|
||||
});
|
||||
|
||||
lib.functions.insert(hash, f);
|
||||
lib.functions.insert(hash, Box::new(NativeFunction::new(f)));
|
||||
}
|
||||
|
||||
/// Add a function with one parameter to the package.
|
||||
@ -157,7 +157,7 @@ pub fn reg_unary<T: Variant + Clone, R>(
|
||||
map_result(r, pos)
|
||||
});
|
||||
|
||||
lib.functions.insert(hash, f);
|
||||
lib.functions.insert(hash, Box::new(NativeFunction::new(f)));
|
||||
}
|
||||
|
||||
/// Add a function with one mutable reference parameter to the package.
|
||||
@ -215,7 +215,7 @@ pub fn reg_unary_mut<T: Variant + Clone, R>(
|
||||
map_result(r, pos)
|
||||
});
|
||||
|
||||
lib.functions.insert(hash, f);
|
||||
lib.functions.insert(hash, Box::new(NativeFunction::new(f)));
|
||||
}
|
||||
|
||||
/// Add a function with two parameters to the package.
|
||||
@ -271,7 +271,7 @@ pub fn reg_binary<A: Variant + Clone, B: Variant + Clone, R>(
|
||||
map_result(r, pos)
|
||||
});
|
||||
|
||||
lib.functions.insert(hash, f);
|
||||
lib.functions.insert(hash, Box::new(NativeFunction::new(f)));
|
||||
}
|
||||
|
||||
/// Add a function with two parameters (the first one being a mutable reference) to the package.
|
||||
@ -334,7 +334,7 @@ pub fn reg_binary_mut<A: Variant + Clone, B: Variant + Clone, R>(
|
||||
map_result(r, pos)
|
||||
});
|
||||
|
||||
lib.functions.insert(hash, f);
|
||||
lib.functions.insert(hash, Box::new(NativeFunction::new(f)));
|
||||
}
|
||||
|
||||
/// Add a function with three parameters to the package.
|
||||
@ -374,7 +374,7 @@ pub fn reg_trinary<A: Variant + Clone, B: Variant + Clone, C: Variant + Clone, R
|
||||
map_result(r, pos)
|
||||
});
|
||||
|
||||
lib.functions.insert(hash, f);
|
||||
lib.functions.insert(hash, Box::new(NativeFunction::new(f)));
|
||||
}
|
||||
|
||||
/// Add a function with three parameters (the first one is a mutable reference) to the package.
|
||||
@ -414,5 +414,5 @@ pub fn reg_trinary_mut<A: Variant + Clone, B: Variant + Clone, C: Variant + Clon
|
||||
map_result(r, pos)
|
||||
});
|
||||
|
||||
lib.functions.insert(hash, f);
|
||||
lib.functions.insert(hash, Box::new(NativeFunction::new(f)));
|
||||
}
|
||||
|
@ -202,6 +202,13 @@ pub struct FnDef {
|
||||
pub pos: Position,
|
||||
}
|
||||
|
||||
/// A sharable script-defined function.
|
||||
#[cfg(feature = "sync")]
|
||||
pub type SharedFnDef = Arc<FnDef>;
|
||||
/// A sharable script-defined function.
|
||||
#[cfg(not(feature = "sync"))]
|
||||
pub type SharedFnDef = Rc<FnDef>;
|
||||
|
||||
/// `return`/`throw` statement.
|
||||
#[derive(Debug, PartialEq, Eq, Hash, Clone, Copy)]
|
||||
pub enum ReturnType {
|
||||
|
Loading…
Reference in New Issue
Block a user