Use macro auto_restore!.

This commit is contained in:
Stephen Chung
2022-12-04 14:06:54 +08:00
parent 58769dbb52
commit de0707f64f
23 changed files with 122 additions and 162 deletions

View File

@@ -9,7 +9,6 @@ use crate::engine::{
};
use crate::eval::{Caches, FnResolutionCacheEntry, GlobalRuntimeState};
use crate::tokenizer::{is_valid_function_name, Token, NO_TOKEN};
use crate::types::RestoreOnDrop;
use crate::{
calc_fn_hash, calc_fn_hash_full, Dynamic, Engine, FnArgsVec, FnPtr, ImmutableString,
OptimizationLevel, Position, RhaiError, RhaiResult, RhaiResultOf, Scope, Shared, ERR,
@@ -381,9 +380,7 @@ impl Engine {
// Clone the first argument
backup.change_first_arg_to_copy(args);
}
let args =
&mut *RestoreOnDrop::lock_if(swap, args, move |a| backup.restore_first_arg(a));
auto_restore!(args; swap => move |a| backup.restore_first_arg(a));
#[cfg(feature = "debugging")]
if self.is_debugger_registered() {
@@ -583,9 +580,7 @@ impl Engine {
#[cfg(not(feature = "no_closure"))]
ensure_no_data_race(fn_name, _args, is_ref_mut)?;
let orig_level = global.level;
global.level += 1;
let global = &mut *RestoreOnDrop::lock(global, move |g| g.level = orig_level);
auto_restore! { let orig_level = global.level; global.level += 1 }
// These may be redirected from method style calls.
if hashes.is_native_only() {
@@ -664,7 +659,7 @@ impl Engine {
};
let orig_source = mem::replace(&mut global.source, source.clone());
let global = &mut *RestoreOnDrop::lock(global, move |g| g.source = orig_source);
auto_restore!(global => move |g| g.source = orig_source);
return if _is_method_call {
// Method call of script function - map first argument to `this`
@@ -684,9 +679,7 @@ impl Engine {
backup.change_first_arg_to_copy(_args);
}
let args = &mut *RestoreOnDrop::lock_if(swap, _args, move |a| {
backup.restore_first_arg(a)
});
auto_restore!(args = _args; swap => move |a| backup.restore_first_arg(a));
let mut this = Dynamic::NULL;
@@ -732,9 +725,7 @@ impl Engine {
})
});
#[cfg(feature = "debugging")]
let global = &mut *RestoreOnDrop::lock_if(reset.is_some(), global, move |g| {
g.debugger_mut().reset_status(reset)
});
auto_restore!(global; reset.is_some() => move |g| g.debugger_mut().reset_status(reset));
self.eval_expr(global, caches, scope, this_ptr, arg_expr)
.map(|r| (r, arg_expr.start_position()))
@@ -1370,9 +1361,7 @@ impl Engine {
}
}
let orig_level = global.level;
global.level += 1;
let global = &mut *RestoreOnDrop::lock(global, move |g| g.level = orig_level);
auto_restore! { let orig_level = global.level; global.level += 1 }
match func {
#[cfg(not(feature = "no_function"))]
@@ -1382,7 +1371,7 @@ impl Engine {
let mut this = Dynamic::NULL;
let orig_source = mem::replace(&mut global.source, module.id_raw().cloned());
let global = &mut *RestoreOnDrop::lock(global, move |g| g.source = orig_source);
auto_restore!(global => move |g| g.source = orig_source);
self.call_script_fn(
global, caches, new_scope, &mut this, fn_def, &mut args, true, pos,
@@ -1534,12 +1523,10 @@ impl Engine {
get_builtin_binary_op_fn(op_token.clone(), operands[0], operands[1])
{
// Built-in found
let orig_level = global.level;
global.level += 1;
let global = &*RestoreOnDrop::lock(global, move |g| g.level = orig_level);
auto_restore! { let orig_level = global.level; global.level += 1 }
let context = if ctx {
Some((self, name.as_str(), None, global, pos).into())
Some((self, name.as_str(), None, &*global, pos).into())
} else {
None
};

View File

@@ -136,7 +136,7 @@ impl CallableFunction {
Self::Script(..) => false,
}
}
/// Is there a [`NativeCallContext`] parameter?
/// Is there a [`NativeCallContext`][crate::NativeCallContext] parameter?
#[inline]
#[must_use]
pub fn has_context(&self) -> bool {

View File

@@ -12,7 +12,7 @@ use std::prelude::v1::*;
/// Trait to create a Rust closure from a script.
///
/// Not available under `no_function`.
pub trait Func<ARGS, RET> {
pub trait Func<A, R> {
/// The closure's output type.
type Output;
@@ -91,14 +91,14 @@ macro_rules! def_anonymous_fn {
impl<$($par: Variant + Clone,)* RET: Variant + Clone> Func<($($par,)*), RET> for Engine
{
#[cfg(feature = "sync")]
type Output = Box<dyn Fn($($par),*) -> RhaiResultOf<RET> + Send + Sync>;
type Output = Box<dyn Fn($($par,)*) -> RhaiResultOf<RET> + Send + Sync>;
#[cfg(not(feature = "sync"))]
type Output = Box<dyn Fn($($par),*) -> RhaiResultOf<RET>>;
type Output = Box<dyn Fn($($par,)*) -> RhaiResultOf<RET>>;
#[inline]
fn create_from_ast(self, ast: AST, entry_point: &str) -> Self::Output {
let fn_name: SmartString = entry_point.into();
Box::new(move |$($par),*| self.call_fn(&mut Scope::new(), &ast, &fn_name, ($($par,)*)))
Box::new(move |$($par,)*| self.call_fn(&mut Scope::new(), &ast, &fn_name, ($($par,)*)))
}
#[inline]

View File

@@ -7,8 +7,8 @@ use crate::plugin::PluginFunction;
use crate::tokenizer::{is_valid_function_name, Token, TokenizeState, NO_TOKEN};
use crate::types::dynamic::Variant;
use crate::{
calc_fn_hash, reify, Dynamic, Engine, EvalContext, FuncArgs, Position, RhaiResult,
RhaiResultOf, StaticVec, VarDefInfo, ERR,
calc_fn_hash, Dynamic, Engine, EvalContext, FuncArgs, Position, RhaiResult, RhaiResultOf,
StaticVec, VarDefInfo, ERR,
};
use std::any::{type_name, TypeId};
#[cfg(feature = "no_std")]

View File

@@ -9,7 +9,7 @@ use super::call::FnCallArgs;
use super::callable_function::CallableFunction;
use super::native::{SendSync, Shared};
use crate::types::dynamic::{DynamicWriteLock, Variant};
use crate::{reify, Dynamic, Identifier, NativeCallContext, RhaiResultOf};
use crate::{Dynamic, Identifier, NativeCallContext, RhaiResultOf};
#[cfg(feature = "no_std")]
use std::prelude::v1::*;
use std::{
@@ -70,44 +70,61 @@ pub fn by_value<T: Variant + Clone>(data: &mut Dynamic) -> T {
///
/// # Type Parameters
///
/// * `ARGS` - a tuple containing parameter types, with `&mut T` represented by `Mut<T>`.
/// * `NUM` - a constant generic containing the number of parameters, must be consistent with `ARGS`.
/// * `CTX` - a constant boolean generic indicating whether there is a `NativeCallContext` parameter.
/// * `RET` - return type of the function; if the function returns `Result`, it is the unwrapped inner value type.
/// * `FALL` - a constant boolean generic indicating whether the function is fallible (i.e. returns `Result<T, Box<EvalAltResult>>`).
pub trait RegisterNativeFunction<ARGS, const NUM: usize, const CTX: bool, RET, const FALL: bool> {
/// * `A` - a tuple containing parameter types, with `&mut T` represented by `Mut<T>`.
/// * `N` - a constant generic containing the number of parameters, must be consistent with `ARGS`.
/// * `X` - a constant boolean generic indicating whether there is a `NativeCallContext` parameter.
/// * `R` - return type of the function; if the function returns `Result`, it is the unwrapped inner value type.
/// * `F` - a constant boolean generic indicating whether the function is fallible (i.e. returns `Result<T, Box<EvalAltResult>>`).
pub trait RegisterNativeFunction<
A: 'static,
const N: usize,
const X: bool,
R: 'static,
const F: bool,
>
{
/// Convert this function into a [`CallableFunction`].
#[must_use]
fn into_callable_function(self, name: Identifier, no_const: bool) -> CallableFunction;
/// Get the type ID's of this function's parameters.
#[must_use]
fn param_types() -> [TypeId; NUM];
fn param_types() -> [TypeId; N];
/// Get the number of parameters for this function.
#[inline(always)]
#[must_use]
fn num_params() -> usize {
NUM
N
}
/// Is there a [`NativeCallContext`] parameter for this function?
#[inline(always)]
#[must_use]
fn has_context() -> bool;
fn has_context() -> bool {
X
}
/// _(metadata)_ Get the type names of this function's parameters.
/// Exported under the `metadata` feature only.
#[cfg(feature = "metadata")]
#[must_use]
fn param_names() -> [&'static str; NUM];
fn param_names() -> [&'static str; N];
/// _(metadata)_ Get the type ID of this function's return value.
/// Exported under the `metadata` feature only.
#[cfg(feature = "metadata")]
#[inline(always)]
#[must_use]
fn return_type() -> TypeId;
fn return_type() -> TypeId {
if F {
TypeId::of::<RhaiResultOf<R>>()
} else {
TypeId::of::<R>()
}
}
/// _(metadata)_ Get the type name of this function's return value.
/// Exported under the `metadata` feature only.
#[cfg(feature = "metadata")]
#[inline(always)]
#[must_use]
fn return_type_name() -> &'static str {
type_name::<RET>()
type_name::<R>()
}
}
@@ -143,9 +160,7 @@ macro_rules! def_register {
RET: Variant + Clone,
> RegisterNativeFunction<($($mark,)*), $n, false, RET, false> for FN {
#[inline(always)] fn param_types() -> [TypeId;$n] { [$(TypeId::of::<$par>()),*] }
#[inline(always)] fn has_context() -> bool { false }
#[cfg(feature = "metadata")] #[inline(always)] fn param_names() -> [&'static str;$n] { [$(type_name::<$param>()),*] }
#[cfg(feature = "metadata")] #[inline(always)] fn return_type() -> TypeId { TypeId::of::<RET>() }
#[inline(always)] fn into_callable_function(self, fn_name: Identifier, no_const: bool) -> CallableFunction {
CallableFunction::$abi(Shared::new(move |_, args: &mut FnCallArgs| {
// The arguments are assumed to be of the correct number and types!
@@ -169,9 +184,7 @@ macro_rules! def_register {
RET: Variant + Clone,
> RegisterNativeFunction<($($mark,)*), $n, true, RET, false> for FN {
#[inline(always)] fn param_types() -> [TypeId;$n] { [$(TypeId::of::<$par>()),*] }
#[inline(always)] fn has_context() -> bool { true }
#[cfg(feature = "metadata")] #[inline(always)] fn param_names() -> [&'static str;$n] { [$(type_name::<$param>()),*] }
#[cfg(feature = "metadata")] #[inline(always)] fn return_type() -> TypeId { TypeId::of::<RET>() }
#[inline(always)] fn into_callable_function(self, fn_name: Identifier, no_const: bool) -> CallableFunction {
CallableFunction::$abi(Shared::new(move |ctx: Option<NativeCallContext>, args: &mut FnCallArgs| {
let ctx = ctx.unwrap();
@@ -197,9 +210,7 @@ macro_rules! def_register {
RET: Variant + Clone
> RegisterNativeFunction<($($mark,)*), $n, false, RET, true> for FN {
#[inline(always)] fn param_types() -> [TypeId;$n] { [$(TypeId::of::<$par>()),*] }
#[inline(always)] fn has_context() -> bool { false }
#[cfg(feature = "metadata")] #[inline(always)] fn param_names() -> [&'static str;$n] { [$(type_name::<$param>()),*] }
#[cfg(feature = "metadata")] #[inline(always)] fn return_type() -> TypeId { TypeId::of::<RhaiResultOf<RET>>() }
#[cfg(feature = "metadata")] #[inline(always)] fn return_type_name() -> &'static str { type_name::<RhaiResultOf<RET>>() }
#[inline(always)] fn into_callable_function(self, fn_name: Identifier, no_const: bool) -> CallableFunction {
CallableFunction::$abi(Shared::new(move |_, args: &mut FnCallArgs| {
@@ -221,9 +232,7 @@ macro_rules! def_register {
RET: Variant + Clone
> RegisterNativeFunction<($($mark,)*), $n, true, RET, true> for FN {
#[inline(always)] fn param_types() -> [TypeId;$n] { [$(TypeId::of::<$par>()),*] }
#[inline(always)] fn has_context() -> bool { true }
#[cfg(feature = "metadata")] #[inline(always)] fn param_names() -> [&'static str;$n] { [$(type_name::<$param>()),*] }
#[cfg(feature = "metadata")] #[inline(always)] fn return_type() -> TypeId { TypeId::of::<RhaiResultOf<RET>>() }
#[cfg(feature = "metadata")] #[inline(always)] fn return_type_name() -> &'static str { type_name::<RhaiResultOf<RET>>() }
#[inline(always)] fn into_callable_function(self, fn_name: Identifier, no_const: bool) -> CallableFunction {
CallableFunction::$abi(Shared::new(move |ctx: Option<NativeCallContext>, args: &mut FnCallArgs| {