diff --git a/src/api/call_fn.rs b/src/api/call_fn.rs index 07ea0c99..120c4f4c 100644 --- a/src/api/call_fn.rs +++ b/src/api/call_fn.rs @@ -233,7 +233,7 @@ impl Engine { let rewind_scope = options.rewind_scope; let result = if options.eval_ast && !statements.is_empty() { - auto_restore! { + defer! { scope if rewind_scope => rewind; let orig_scope_len = scope.len(); } diff --git a/src/api/eval.rs b/src/api/eval.rs index 2c93b182..60a9b816 100644 --- a/src/api/eval.rs +++ b/src/api/eval.rs @@ -242,7 +242,7 @@ impl Engine { ast.resolver().cloned(), ); - auto_restore! { global => move |g| { + defer! { global => move |g| { #[cfg(not(feature = "no_module"))] { g.embedded_module_resolver = orig_embedded_module_resolver; diff --git a/src/restore.rs b/src/defer.rs similarity index 65% rename from src/restore.rs rename to src/defer.rs index d369f6bc..f3947430 100644 --- a/src/restore.rs +++ b/src/defer.rs @@ -5,56 +5,56 @@ use std::ops::{Deref, DerefMut}; use std::prelude::v1::*; /// Automatically restore state at the end of the scope. -macro_rules! auto_restore { +macro_rules! defer { (let $temp:ident = $var:ident . $prop:ident; $code:stmt) => { - auto_restore!(let $temp = $var.$prop; $code => move |v| v.$prop = $temp); + defer!(let $temp = $var.$prop; $code => move |v| v.$prop = $temp); }; (let $temp:ident = $var:ident . $prop:ident; $code:stmt => $restore:expr) => { let $temp = $var.$prop; $code - auto_restore!($var => $restore); + defer!($var => $restore); }; ($var:ident => $restore:ident; let $temp:ident = $save:expr;) => { - auto_restore!($var => $restore; let $temp = $save; {}); + defer!($var => $restore; let $temp = $save; {}); }; ($var:ident if $guard:expr => $restore:ident; let $temp:ident = $save:expr;) => { - auto_restore!($var if $guard => $restore; let $temp = $save; {}); + defer!($var if $guard => $restore; let $temp = $save; {}); }; ($var:ident => $restore:ident; let $temp:ident = $save:expr; $code:stmt) => { let $temp = $save; $code - auto_restore!($var => move |v| { v.$restore($temp); }); + defer!($var => move |v| { v.$restore($temp); }); }; ($var:ident if $guard:expr => $restore:ident; let $temp:ident = $save:expr; $code:stmt) => { let $temp = $save; $code - auto_restore!($var if $guard => move |v| { v.$restore($temp); }); + defer!($var if $guard => move |v| { v.$restore($temp); }); }; ($var:ident => $restore:expr) => { - auto_restore!($var = $var => $restore); + defer!($var = $var => $restore); }; ($var:ident = $value:expr => $restore:expr) => { - let $var = &mut *crate::RestoreOnDrop::lock($value, $restore); + let $var = &mut *crate::Deferred::lock($value, $restore); }; ($var:ident if Some($guard:ident) => $restore:expr) => { - auto_restore!($var = ($var) if Some($guard) => $restore); + defer!($var = ($var) if Some($guard) => $restore); }; ($var:ident = ( $value:expr ) if Some($guard:ident) => $restore:expr) => { let mut __rx__; let $var = if let Some($guard) = $guard { - __rx__ = crate::RestoreOnDrop::lock($value, $restore); + __rx__ = crate::Deferred::lock($value, $restore); &mut *__rx__ } else { &mut *$value }; }; ($var:ident if $guard:expr => $restore:expr) => { - auto_restore!($var = ($var) if $guard => $restore); + defer!($var = ($var) if $guard => $restore); }; ($var:ident = ( $value:expr ) if $guard:expr => $restore:expr) => { let mut __rx__; let $var = if $guard { - __rx__ = crate::RestoreOnDrop::lock($value, $restore); + __rx__ = crate::Deferred::lock($value, $restore); &mut *__rx__ } else { &mut *$value @@ -64,13 +64,13 @@ macro_rules! auto_restore { /// Run custom restoration logic upon the end of scope. #[must_use] -pub struct RestoreOnDrop<'a, T: ?Sized, R: FnOnce(&mut T)> { +pub struct Deferred<'a, T: ?Sized, R: FnOnce(&mut T)> { value: &'a mut T, restore: Option, } -impl<'a, T: ?Sized, R: FnOnce(&mut T)> RestoreOnDrop<'a, T, R> { - /// Create a new [`RestoreOnDrop`] that locks a mutable reference and runs restoration logic at +impl<'a, T: ?Sized, R: FnOnce(&mut T)> Deferred<'a, T, R> { + /// Create a new [`Deferred`] that locks a mutable reference and runs restoration logic at /// the end of scope. /// /// Beware that the end of scope means the end of its lifetime, not necessarily waiting until @@ -84,14 +84,14 @@ impl<'a, T: ?Sized, R: FnOnce(&mut T)> RestoreOnDrop<'a, T, R> { } } -impl<'a, T: ?Sized, R: FnOnce(&mut T)> Drop for RestoreOnDrop<'a, T, R> { +impl<'a, T: ?Sized, R: FnOnce(&mut T)> Drop for Deferred<'a, T, R> { #[inline(always)] fn drop(&mut self) { self.restore.take().unwrap()(self.value); } } -impl<'a, T: ?Sized, R: FnOnce(&mut T)> Deref for RestoreOnDrop<'a, T, R> { +impl<'a, T: ?Sized, R: FnOnce(&mut T)> Deref for Deferred<'a, T, R> { type Target = T; #[inline(always)] @@ -100,7 +100,7 @@ impl<'a, T: ?Sized, R: FnOnce(&mut T)> Deref for RestoreOnDrop<'a, T, R> { } } -impl<'a, T: ?Sized, R: FnOnce(&mut T)> DerefMut for RestoreOnDrop<'a, T, R> { +impl<'a, T: ?Sized, R: FnOnce(&mut T)> DerefMut for Deferred<'a, T, R> { #[inline(always)] fn deref_mut(&mut self) -> &mut Self::Target { self.value diff --git a/src/eval/chaining.rs b/src/eval/chaining.rs index cda741a5..43570317 100644 --- a/src/eval/chaining.rs +++ b/src/eval/chaining.rs @@ -67,7 +67,7 @@ impl Engine { idx: &mut Dynamic, pos: Position, ) -> RhaiResultOf { - auto_restore! { let orig_level = global.level; global.level += 1 } + defer! { let orig_level = global.level; global.level += 1 } let hash = hash_idx().0; let args = &mut [target, idx]; @@ -88,7 +88,7 @@ impl Engine { is_ref_mut: bool, pos: Position, ) -> RhaiResultOf<(Dynamic, bool)> { - auto_restore! { let orig_level = global.level; global.level += 1 } + defer! { let orig_level = global.level; global.level += 1 } let hash = hash_idx().1; let args = &mut [target, idx, new_val]; @@ -689,14 +689,14 @@ impl Engine { let reset = self.run_debugger_with_reset(global, caches, scope, this_ptr, rhs)?; #[cfg(feature = "debugging")] - auto_restore! { global if Some(reset) => move |g| g.debugger_mut().reset_status(reset) } + defer! { global if Some(reset) => move |g| g.debugger_mut().reset_status(reset) } let crate::ast::FnCallExpr { name, hashes, args, .. } = &**x; // Truncate the index values upon exit - auto_restore! { idx_values => truncate; let offset = idx_values.len() - args.len(); } + defer! { idx_values => truncate; let offset = idx_values.len() - args.len(); } let call_args = &mut idx_values[offset..]; let arg1_pos = args.get(0).map_or(Position::NONE, Expr::position); @@ -858,14 +858,14 @@ impl Engine { let reset = self .run_debugger_with_reset(global, caches, scope, _tp, _node)?; #[cfg(feature = "debugging")] - auto_restore! { global if Some(reset) => move |g| g.debugger_mut().reset_status(reset) } + defer! { global if Some(reset) => move |g| g.debugger_mut().reset_status(reset) } let crate::ast::FnCallExpr { name, hashes, args, .. } = &**x; // Truncate the index values upon exit - auto_restore! { idx_values => truncate; let offset = idx_values.len() - args.len(); } + defer! { idx_values => truncate; let offset = idx_values.len() - args.len(); } let call_args = &mut idx_values[offset..]; let arg1_pos = args.get(0).map_or(Position::NONE, Expr::position); @@ -978,14 +978,14 @@ impl Engine { global, caches, scope, _tp, _node, )?; #[cfg(feature = "debugging")] - auto_restore! { global if Some(reset) => move |g| g.debugger_mut().reset_status(reset) } + defer! { global if Some(reset) => move |g| g.debugger_mut().reset_status(reset) } let crate::ast::FnCallExpr { name, hashes, args, .. } = &**f; // Truncate the index values upon exit - auto_restore! { idx_values => truncate; let offset = idx_values.len() - args.len(); } + defer! { idx_values => truncate; let offset = idx_values.len() - args.len(); } let call_args = &mut idx_values[offset..]; let pos1 = args.get(0).map_or(Position::NONE, Expr::position); diff --git a/src/eval/expr.rs b/src/eval/expr.rs index e728249e..f8af1f35 100644 --- a/src/eval/expr.rs +++ b/src/eval/expr.rs @@ -242,7 +242,7 @@ impl Engine { let reset = self.run_debugger_with_reset(global, caches, scope, this_ptr.as_deref_mut(), expr)?; #[cfg(feature = "debugging")] - auto_restore! { global if Some(reset) => move |g| g.debugger_mut().reset_status(reset) } + defer! { global if Some(reset) => move |g| g.debugger_mut().reset_status(reset) } match expr { // Constants diff --git a/src/eval/stmt.rs b/src/eval/stmt.rs index 021417d7..5d090b76 100644 --- a/src/eval/stmt.rs +++ b/src/eval/stmt.rs @@ -43,7 +43,7 @@ impl Engine { } // Restore scope at end of block if necessary - auto_restore! { scope if restore_orig_state => rewind; let orig_scope_len = scope.len(); } + defer! { scope if restore_orig_state => rewind; let orig_scope_len = scope.len(); } // Restore global state at end of block if necessary let orig_always_search_scope = global.always_search_scope; @@ -54,7 +54,7 @@ impl Engine { global.scope_level += 1; } - auto_restore! { global if restore_orig_state => move |g| { + defer! { global if restore_orig_state => move |g| { g.scope_level -= 1; #[cfg(not(feature = "no_module"))] @@ -66,7 +66,7 @@ impl Engine { }} // Pop new function resolution caches at end of block - auto_restore! { + defer! { caches => rewind_fn_resolution_caches; let orig_fn_resolution_caches_len = caches.fn_resolution_caches_len(); } @@ -209,7 +209,7 @@ impl Engine { get_builtin_op_assignment_fn(op_x, &*lock_guard, &new_val) { // We may not need to bump the level because built-in's do not need it. - //auto_restore! { let orig_level = global.level; global.level += 1 } + //defer! { let orig_level = global.level; global.level += 1 } let args = &mut [&mut *lock_guard, &mut new_val]; let context = need_context @@ -273,7 +273,7 @@ impl Engine { let reset = self.run_debugger_with_reset(global, caches, scope, this_ptr.as_deref_mut(), stmt)?; #[cfg(feature = "debugging")] - auto_restore! { global if Some(reset) => move |g| g.debugger_mut().reset_status(reset) } + defer! { global if Some(reset) => move |g| g.debugger_mut().reset_status(reset) } match stmt { // No-op @@ -673,7 +673,7 @@ impl Engine { let iter_func = iter_func.ok_or_else(|| ERR::ErrorFor(expr.start_position()))?; // Restore scope at end of statement - auto_restore! { scope => rewind; let orig_scope_len = scope.len(); } + defer! { scope => rewind; let orig_scope_len = scope.len(); } // Add the loop variables let counter_index = (!counter.is_empty()).then(|| { @@ -808,7 +808,7 @@ impl Engine { }; // Restore scope at end of block - auto_restore! { scope if !catch_var.is_unit() => rewind; let orig_scope_len = scope.len(); } + defer! { scope if !catch_var.is_unit() => rewind; let orig_scope_len = scope.len(); } if let Expr::Variable(x, ..) = catch_var { scope.push(x.3.clone(), err_value); diff --git a/src/func/call.rs b/src/func/call.rs index 61d54818..52400b3b 100644 --- a/src/func/call.rs +++ b/src/func/call.rs @@ -577,7 +577,7 @@ impl Engine { #[cfg(not(feature = "no_closure"))] ensure_no_data_race(fn_name, args, is_ref_mut)?; - auto_restore! { let orig_level = global.level; global.level += 1 } + defer! { let orig_level = global.level; global.level += 1 } // These may be redirected from method style calls. if hashes.is_native_only() { @@ -668,7 +668,7 @@ impl Engine { }; let orig_source = mem::replace(&mut global.source, source.clone()); - auto_restore! { global => move |g| g.source = orig_source } + defer! { global => move |g| g.source = orig_source } return if _is_method_call { // Method call of script function - map first argument to `this` @@ -696,7 +696,7 @@ impl Engine { backup.change_first_arg_to_copy(args); } - auto_restore! { args = (args) if swap => move |a| backup.restore_first_arg(a) } + defer! { args = (args) if swap => move |a| backup.restore_first_arg(a) } self.call_script_fn(global, caches, scope, None, environ, f, args, true, pos) } @@ -740,7 +740,7 @@ impl Engine { }) }); #[cfg(feature = "debugging")] - auto_restore! { global if Some(reset) => move |g| g.debugger_mut().reset_status(reset) } + defer! { global if Some(reset) => 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())) @@ -1451,7 +1451,7 @@ impl Engine { } } - auto_restore! { let orig_level = global.level; global.level += 1 } + defer! { let orig_level = global.level; global.level += 1 } match func { #[cfg(not(feature = "no_function"))] @@ -1462,7 +1462,7 @@ impl Engine { let scope = &mut Scope::new(); let orig_source = mem::replace(&mut global.source, module.id_raw().cloned()); - auto_restore! { global => move |g| g.source = orig_source } + defer! { global => move |g| g.source = orig_source } self.call_script_fn(global, caches, scope, None, environ, f, args, true, pos) } @@ -1729,7 +1729,7 @@ impl Engine { get_builtin_binary_op_fn(op_token.as_ref().unwrap(), operands[0], operands[1]) { // We may not need to bump the level because built-in's do not need it. - //auto_restore! { let orig_level = global.level; global.level += 1 } + //defer! { let orig_level = global.level; global.level += 1 } let context = need_context.then(|| (self, name.as_str(), None, &*global, pos).into()); diff --git a/src/lib.rs b/src/lib.rs index 8f4dda89..63b342ec 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -102,7 +102,7 @@ use std::prelude::v1::*; #[macro_use] mod reify; #[macro_use] -mod restore; +mod defer; mod api; mod ast; @@ -225,6 +225,7 @@ pub use api::custom_syntax::Expression; pub use api::files::{eval_file, run_file}; pub use api::{eval::eval, events::VarDefInfo, run::run}; pub use ast::{FnAccess, AST}; +use defer::Deferred; pub use engine::{Engine, OP_CONTAINS, OP_EQUALS}; pub use eval::EvalContext; #[cfg(not(feature = "no_function"))] @@ -233,7 +234,6 @@ use func::calc_typed_method_hash; use func::{calc_fn_hash, calc_fn_hash_full, calc_var_hash}; pub use func::{plugin, FuncArgs, NativeCallContext, RegisterNativeFunction}; pub use module::{FnNamespace, Module}; -use restore::RestoreOnDrop; pub use rhai_codegen::*; #[cfg(not(feature = "no_time"))] pub use types::Instant;