Refine auto_restore syntax.
This commit is contained in:
parent
f15a9a7c9c
commit
8bcb771281
@ -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);
|
||||||
|
@ -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].
|
||||||
|
@ -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())?;
|
||||||
|
|
||||||
|
@ -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);
|
||||||
|
@ -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,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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
|
||||||
|
@ -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;
|
||||||
|
@ -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);
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user