Refine auto_restore syntax.

This commit is contained in:
Stephen Chung 2022-12-10 22:37:13 +08:00
parent f15a9a7c9c
commit 8bcb771281
8 changed files with 41 additions and 73 deletions

View File

@ -2,7 +2,7 @@
#![cfg(any(not(feature = "no_index"), not(feature = "no_object")))] #![cfg(any(not(feature = "no_index"), not(feature = "no_object")))]
use super::{Caches, GlobalRuntimeState, Target}; use super::{Caches, GlobalRuntimeState, Target};
use crate::ast::{ASTFlags, Expr, OpAssignment}; use crate::ast::{ASTFlags, BinaryExpr, Expr, OpAssignment};
use crate::config::hashing::SusLock; use crate::config::hashing::SusLock;
use crate::engine::{FN_IDX_GET, FN_IDX_SET}; use crate::engine::{FN_IDX_GET, FN_IDX_SET};
use crate::tokenizer::NO_TOKEN; use crate::tokenizer::NO_TOKEN;
@ -346,7 +346,7 @@ impl Engine {
) -> RhaiResult { ) -> RhaiResult {
let chain_type = ChainType::from(expr); let chain_type = ChainType::from(expr);
let crate::ast::BinaryExpr { lhs, rhs } = match expr { let BinaryExpr { lhs, rhs } = match expr {
#[cfg(not(feature = "no_index"))] #[cfg(not(feature = "no_index"))]
Expr::Index(x, ..) => &**x, Expr::Index(x, ..) => &**x,
#[cfg(not(feature = "no_object"))] #[cfg(not(feature = "no_object"))]
@ -378,11 +378,9 @@ impl Engine {
idx_values.push(rhs.get_literal_value().unwrap()) idx_values.push(rhs.get_literal_value().unwrap())
} }
// All other patterns - evaluate the arguments chain // All other patterns - evaluate the arguments chain
_ => { _ => self.eval_dot_index_chain_arguments(
self.eval_dot_index_chain_arguments(
global, caches, scope, this_ptr, expr, rhs, idx_values, global, caches, scope, this_ptr, expr, rhs, idx_values,
)?; )?,
}
} }
match lhs { match lhs {
@ -462,7 +460,7 @@ impl Engine {
Expr::Index(x, ..) | Expr::Dot(x, ..) Expr::Index(x, ..) | Expr::Dot(x, ..)
if !parent.options().contains(ASTFlags::BREAK) => if !parent.options().contains(ASTFlags::BREAK) =>
{ {
let crate::ast::BinaryExpr { lhs, rhs, .. } = &**x; let BinaryExpr { lhs, rhs, .. } = &**x;
let mut _arg_values = FnArgsVec::new_const(); let mut _arg_values = FnArgsVec::new_const();
@ -690,17 +688,14 @@ impl Engine {
let reset = let reset =
self.run_debugger_with_reset(global, caches, scope, this_ptr, rhs)?; self.run_debugger_with_reset(global, caches, scope, this_ptr, rhs)?;
#[cfg(feature = "debugging")] #[cfg(feature = "debugging")]
auto_restore!(global if reset.is_some() => move |g| g.debugger_mut().reset_status(reset)); auto_restore!(global if Some(reset) => move |g| g.debugger_mut().reset_status(reset));
let crate::ast::FnCallExpr { let crate::ast::FnCallExpr {
name, hashes, args, .. name, hashes, args, ..
} = &**x; } = &**x;
// Truncate the index values upon exit // Truncate the index values upon exit
auto_restore! { auto_restore! { idx_values => truncate; let offset = idx_values.len() - args.len(); }
idx_values => truncate;
let offset = idx_values.len() - args.len();
}
let call_args = &mut idx_values[offset..]; let call_args = &mut idx_values[offset..];
let arg1_pos = args.get(0).map_or(Position::NONE, Expr::position); let arg1_pos = args.get(0).map_or(Position::NONE, Expr::position);
@ -862,17 +857,14 @@ impl Engine {
global, caches, scope, this_ptr, _node, global, caches, scope, this_ptr, _node,
)?; )?;
#[cfg(feature = "debugging")] #[cfg(feature = "debugging")]
auto_restore!(global if reset.is_some() => move |g| g.debugger_mut().reset_status(reset)); auto_restore!(global if Some(reset) => move |g| g.debugger_mut().reset_status(reset));
let crate::ast::FnCallExpr { let crate::ast::FnCallExpr {
name, hashes, args, .. name, hashes, args, ..
} = &**x; } = &**x;
// Truncate the index values upon exit // Truncate the index values upon exit
auto_restore! { auto_restore! { idx_values => truncate; let offset = idx_values.len() - args.len(); }
idx_values => truncate;
let offset = idx_values.len() - args.len();
}
let call_args = &mut idx_values[offset..]; let call_args = &mut idx_values[offset..];
let arg1_pos = args.get(0).map_or(Position::NONE, Expr::position); let arg1_pos = args.get(0).map_or(Position::NONE, Expr::position);
@ -983,17 +975,14 @@ impl Engine {
global, caches, scope, this_ptr, _node, global, caches, scope, this_ptr, _node,
)?; )?;
#[cfg(feature = "debugging")] #[cfg(feature = "debugging")]
auto_restore!(global if reset.is_some() => move |g| g.debugger_mut().reset_status(reset)); auto_restore!(global if Some(reset) => move |g| g.debugger_mut().reset_status(reset));
let crate::ast::FnCallExpr { let crate::ast::FnCallExpr {
name, hashes, args, .. name, hashes, args, ..
} = &**f; } = &**f;
// Truncate the index values upon exit // Truncate the index values upon exit
auto_restore! { auto_restore! { idx_values => truncate; let offset = idx_values.len() - args.len(); }
idx_values => truncate;
let offset = idx_values.len() - args.len();
}
let call_args = &mut idx_values[offset..]; let call_args = &mut idx_values[offset..];
let pos1 = args.get(0).map_or(Position::NONE, Expr::position); let pos1 = args.get(0).map_or(Position::NONE, Expr::position);

View File

@ -314,14 +314,12 @@ impl Debugger {
None None
} }
} }
/// Override the status of this [`Debugger`] if it is [`Some`] the current status is /// Override the status of this [`Debugger`] if the current status is
/// [`CONTINUE`][DebuggerStatus::CONTINUE]. /// [`CONTINUE`][DebuggerStatus::CONTINUE].
#[inline(always)] #[inline(always)]
pub(crate) fn reset_status(&mut self, status: Option<DebuggerStatus>) { pub(crate) fn reset_status(&mut self, status: DebuggerStatus) {
if self.status == DebuggerStatus::CONTINUE { if self.status == DebuggerStatus::CONTINUE {
if let Some(cmd) = status { self.status = status;
self.status = cmd;
}
} }
} }
/// Returns the first break-point triggered by a particular [`AST` Node][ASTNode]. /// Returns the first break-point triggered by a particular [`AST` Node][ASTNode].

View File

@ -234,7 +234,7 @@ impl Engine {
#[cfg(feature = "debugging")] #[cfg(feature = "debugging")]
let reset = self.run_debugger_with_reset(global, caches, scope, this_ptr, expr)?; let reset = self.run_debugger_with_reset(global, caches, scope, this_ptr, expr)?;
#[cfg(feature = "debugging")] #[cfg(feature = "debugging")]
auto_restore!(global if reset.is_some() => move |g| g.debugger_mut().reset_status(reset)); auto_restore!(global if Some(reset) => move |g| g.debugger_mut().reset_status(reset));
self.track_operation(global, expr.position())?; self.track_operation(global, expr.position())?;
@ -265,7 +265,7 @@ impl Engine {
#[cfg(feature = "debugging")] #[cfg(feature = "debugging")]
let reset = self.run_debugger_with_reset(global, caches, scope, this_ptr, expr)?; let reset = self.run_debugger_with_reset(global, caches, scope, this_ptr, expr)?;
#[cfg(feature = "debugging")] #[cfg(feature = "debugging")]
auto_restore!(global if reset.is_some() => move |g| g.debugger_mut().reset_status(reset)); auto_restore!(global if Some(reset) => move |g| g.debugger_mut().reset_status(reset));
self.track_operation(global, expr.position())?; self.track_operation(global, expr.position())?;

View File

@ -41,10 +41,7 @@ impl Engine {
} }
// Restore scope at end of block if necessary // Restore scope at end of block if necessary
auto_restore! { auto_restore! { scope if restore_orig_state => rewind; let orig_scope_len = scope.len(); }
scope if restore_orig_state => rewind;
let orig_scope_len = scope.len();
}
// Restore global state at end of block if necessary // Restore global state at end of block if necessary
let orig_always_search_scope = global.always_search_scope; let orig_always_search_scope = global.always_search_scope;
@ -208,7 +205,7 @@ impl Engine {
#[cfg(feature = "debugging")] #[cfg(feature = "debugging")]
let reset = self.run_debugger_with_reset(global, caches, scope, this_ptr, stmt)?; let reset = self.run_debugger_with_reset(global, caches, scope, this_ptr, stmt)?;
#[cfg(feature = "debugging")] #[cfg(feature = "debugging")]
auto_restore!(global if reset.is_some() => move |g| g.debugger_mut().reset_status(reset)); auto_restore!(global if Some(reset) => move |g| g.debugger_mut().reset_status(reset));
// Coded this way for better branch prediction. // Coded this way for better branch prediction.
// Popular branches are lifted out of the `match` statement into their own branches. // Popular branches are lifted out of the `match` statement into their own branches.
@ -519,10 +516,8 @@ impl Engine {
let iter_func = iter_func.ok_or_else(|| ERR::ErrorFor(expr.start_position()))?; let iter_func = iter_func.ok_or_else(|| ERR::ErrorFor(expr.start_position()))?;
// Restore scope at end of statement // Restore scope at end of statement
auto_restore! { auto_restore! { scope => rewind; let orig_scope_len = scope.len(); }
scope => rewind;
let orig_scope_len = scope.len();
}
// Add the loop variables // Add the loop variables
let counter_index = if counter.is_empty() { let counter_index = if counter.is_empty() {
usize::MAX usize::MAX
@ -649,10 +644,7 @@ impl Engine {
}; };
// Restore scope at end of block // Restore scope at end of block
auto_restore! { auto_restore! { scope if !catch_var.is_empty() => rewind; let orig_scope_len = scope.len(); }
scope if !catch_var.is_empty() => rewind;
let orig_scope_len = scope.len();
}
if !catch_var.is_empty() { if !catch_var.is_empty() {
scope.push(catch_var.name.clone(), err_value); scope.push(catch_var.name.clone(), err_value);

View File

@ -725,7 +725,7 @@ impl Engine {
}) })
}); });
#[cfg(feature = "debugging")] #[cfg(feature = "debugging")]
auto_restore!(global if reset.is_some() => move |g| g.debugger_mut().reset_status(reset)); auto_restore!(global if Some(reset) => move |g| g.debugger_mut().reset_status(reset));
self.eval_expr(global, caches, scope, this_ptr, arg_expr) self.eval_expr(global, caches, scope, this_ptr, arg_expr)
.map(|r| (r, arg_expr.start_position())) .map(|r| (r, arg_expr.start_position()))
@ -1549,14 +1549,14 @@ impl Engine {
} }
// Normal function call // Normal function call
let (first_arg, args) = args.split_first().map_or_else( let (first_arg, rest_args) = args.split_first().map_or_else(
|| (None, args.as_ref()), || (None, args.as_ref()),
|(first, rest)| (Some(first), rest), |(first, rest)| (Some(first), rest),
); );
self.make_function_call( self.make_function_call(
global, caches, scope, this_ptr, name, op_token, first_arg, args, *hashes, *capture, global, caches, scope, this_ptr, name, op_token, first_arg, rest_args, *hashes,
pos, *capture, pos,
) )
} }
} }

View File

@ -92,14 +92,7 @@ impl StringsInterner {
let result = match self.cache.entry(hash) { let result = match self.cache.entry(hash) {
Entry::Occupied(e) => return e.get().clone(), Entry::Occupied(e) => return e.get().clone(),
Entry::Vacant(e) => { Entry::Vacant(e) => e.insert(mapper(text)).clone(),
let value = mapper(text);
if value.strong_count() > 1 {
return value;
}
e.insert(value).clone()
}
}; };
// Throttle the cache upon exit // Throttle the cache upon exit

View File

@ -10,7 +10,7 @@ use std::{
}; };
/// A location (line number + character position) in the input script. /// A location (line number + character position) in the input script.
#[derive(Eq, PartialEq, Ord, PartialOrd, Hash, Clone, Copy)] #[derive(Eq, PartialEq, Ord, PartialOrd, Hash, Clone, Copy, Default)]
pub struct Position; pub struct Position;
impl Position { impl Position {
@ -81,14 +81,6 @@ impl Position {
} }
} }
impl Default for Position {
#[inline(always)]
#[must_use]
fn default() -> Self {
Self
}
}
impl fmt::Display for Position { impl fmt::Display for Position {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "none") write!(f, "none")
@ -119,17 +111,9 @@ impl AddAssign for Position {
/// _(internals)_ A span consisting of a starting and an ending [positions][Position]. /// _(internals)_ A span consisting of a starting and an ending [positions][Position].
/// Exported under the `internals` feature only. /// Exported under the `internals` feature only.
#[derive(Eq, PartialEq, Ord, PartialOrd, Hash, Clone, Copy)] #[derive(Eq, PartialEq, Ord, PartialOrd, Hash, Clone, Copy, Default)]
pub struct Span; pub struct Span;
impl Default for Span {
#[inline(always)]
#[must_use]
fn default() -> Self {
Self
}
}
impl Span { impl Span {
/// Empty [`Span`]. /// Empty [`Span`].
pub const NONE: Self = Self; pub const NONE: Self = Self;

View File

@ -36,6 +36,18 @@ macro_rules! auto_restore {
($var:ident = $value:expr => $restore:expr) => { ($var:ident = $value:expr => $restore:expr) => {
let $var = &mut *crate::types::RestoreOnDrop::lock($value, $restore); let $var = &mut *crate::types::RestoreOnDrop::lock($value, $restore);
}; };
($var:ident if Some($guard:ident) => $restore:expr) => {
auto_restore!($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::types::RestoreOnDrop::lock($value, $restore);
&mut *__rx__
} else {
&mut *$value
};
};
($var:ident if $guard:expr => $restore:expr) => { ($var:ident if $guard:expr => $restore:expr) => {
auto_restore!($var = ($var) if $guard => $restore); auto_restore!($var = ($var) if $guard => $restore);
}; };