Refine auto_restore syntax.
This commit is contained in:
parent
3163d9d1d6
commit
e2bd0705b1
@ -238,8 +238,10 @@ impl Engine {
|
|||||||
let rewind_scope = options.rewind_scope;
|
let rewind_scope = options.rewind_scope;
|
||||||
|
|
||||||
let result = if options.eval_ast && !statements.is_empty() {
|
let result = if options.eval_ast && !statements.is_empty() {
|
||||||
|
auto_restore! {
|
||||||
|
scope if rewind_scope => rewind;
|
||||||
let orig_scope_len = scope.len();
|
let orig_scope_len = scope.len();
|
||||||
auto_restore!(scope; rewind_scope => move |s| { s.rewind(orig_scope_len); });
|
}
|
||||||
|
|
||||||
self.eval_global_statements(global, caches, scope, statements)
|
self.eval_global_statements(global, caches, scope, statements)
|
||||||
} else {
|
} else {
|
||||||
|
@ -684,15 +684,17 @@ 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; reset.is_some() => move |g| g.debugger_mut().reset_status(reset));
|
auto_restore!(global if reset.is_some() => 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! {
|
||||||
|
idx_values => truncate;
|
||||||
let offset = idx_values.len() - args.len();
|
let offset = idx_values.len() - args.len();
|
||||||
auto_restore!(idx_values => move |v| v.truncate(offset));
|
}
|
||||||
|
|
||||||
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);
|
||||||
@ -854,15 +856,17 @@ impl Engine {
|
|||||||
global, caches, scope, this_ptr, _node,
|
global, caches, scope, this_ptr, _node,
|
||||||
)?;
|
)?;
|
||||||
#[cfg(feature = "debugging")]
|
#[cfg(feature = "debugging")]
|
||||||
auto_restore!(global; reset.is_some() => move |g| g.debugger_mut().reset_status(reset));
|
auto_restore!(global if reset.is_some() => 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! {
|
||||||
|
idx_values => truncate;
|
||||||
let offset = idx_values.len() - args.len();
|
let offset = idx_values.len() - args.len();
|
||||||
auto_restore!(idx_values => move |v| v.truncate(offset));
|
}
|
||||||
|
|
||||||
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);
|
||||||
@ -973,15 +977,17 @@ impl Engine {
|
|||||||
global, caches, scope, this_ptr, _node,
|
global, caches, scope, this_ptr, _node,
|
||||||
)?;
|
)?;
|
||||||
#[cfg(feature = "debugging")]
|
#[cfg(feature = "debugging")]
|
||||||
auto_restore!(global; reset.is_some() => move |g| g.debugger_mut().reset_status(reset));
|
auto_restore!(global if reset.is_some() => 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! {
|
||||||
|
idx_values => truncate;
|
||||||
let offset = idx_values.len() - args.len();
|
let offset = idx_values.len() - args.len();
|
||||||
auto_restore!(idx_values => move |v| v.truncate(offset));
|
}
|
||||||
|
|
||||||
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);
|
||||||
|
@ -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; reset.is_some() => move |g| g.debugger_mut().reset_status(reset));
|
auto_restore!(global if reset.is_some() => 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; reset.is_some() => move |g| g.debugger_mut().reset_status(reset));
|
auto_restore!(global if reset.is_some() => move |g| g.debugger_mut().reset_status(reset));
|
||||||
|
|
||||||
self.track_operation(global, expr.position())?;
|
self.track_operation(global, expr.position())?;
|
||||||
|
|
||||||
|
@ -41,8 +41,10 @@ impl Engine {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Restore scope at end of block if necessary
|
// Restore scope at end of block if necessary
|
||||||
|
auto_restore! {
|
||||||
|
scope if restore_orig_state => rewind;
|
||||||
let orig_scope_len = scope.len();
|
let orig_scope_len = scope.len();
|
||||||
auto_restore!(scope; restore_orig_state => move |s| { s.rewind(orig_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;
|
||||||
@ -53,7 +55,7 @@ impl Engine {
|
|||||||
global.scope_level += 1;
|
global.scope_level += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto_restore!(global; restore_orig_state => move |g| {
|
auto_restore!(global if restore_orig_state => move |g| {
|
||||||
g.scope_level -= 1;
|
g.scope_level -= 1;
|
||||||
|
|
||||||
#[cfg(not(feature = "no_module"))]
|
#[cfg(not(feature = "no_module"))]
|
||||||
@ -65,8 +67,10 @@ impl Engine {
|
|||||||
});
|
});
|
||||||
|
|
||||||
// Pop new function resolution caches at end of block
|
// Pop new function resolution caches at end of block
|
||||||
|
auto_restore! {
|
||||||
|
caches => rewind_fn_resolution_caches;
|
||||||
let orig_fn_resolution_caches_len = caches.fn_resolution_caches_len();
|
let orig_fn_resolution_caches_len = caches.fn_resolution_caches_len();
|
||||||
auto_restore!(caches => move |c| c.rewind_fn_resolution_caches(orig_fn_resolution_caches_len));
|
}
|
||||||
|
|
||||||
// Run the statements
|
// Run the statements
|
||||||
statements.iter().try_fold(Dynamic::UNIT, |_, stmt| {
|
statements.iter().try_fold(Dynamic::UNIT, |_, stmt| {
|
||||||
@ -204,7 +208,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; reset.is_some() => move |g| g.debugger_mut().reset_status(reset));
|
auto_restore!(global if reset.is_some() => 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.
|
||||||
@ -515,8 +519,10 @@ 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! {
|
||||||
|
scope => rewind;
|
||||||
let orig_scope_len = scope.len();
|
let orig_scope_len = scope.len();
|
||||||
auto_restore!(scope => move |s| { s.rewind(orig_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
|
||||||
@ -643,8 +649,10 @@ impl Engine {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Restore scope at end of block
|
// Restore scope at end of block
|
||||||
|
auto_restore! {
|
||||||
|
scope if !catch_var.is_empty() => rewind;
|
||||||
let orig_scope_len = scope.len();
|
let orig_scope_len = scope.len();
|
||||||
auto_restore!(scope; !catch_var.is_empty() => move |s| { s.rewind(orig_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);
|
||||||
|
@ -380,7 +380,7 @@ impl Engine {
|
|||||||
// Clone the first argument
|
// Clone the first argument
|
||||||
backup.change_first_arg_to_copy(args);
|
backup.change_first_arg_to_copy(args);
|
||||||
}
|
}
|
||||||
auto_restore!(args; swap => move |a| backup.restore_first_arg(a));
|
auto_restore!(args if swap => move |a| backup.restore_first_arg(a));
|
||||||
|
|
||||||
#[cfg(feature = "debugging")]
|
#[cfg(feature = "debugging")]
|
||||||
if self.is_debugger_registered() {
|
if self.is_debugger_registered() {
|
||||||
@ -679,7 +679,7 @@ impl Engine {
|
|||||||
backup.change_first_arg_to_copy(_args);
|
backup.change_first_arg_to_copy(_args);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto_restore!(args = _args; swap => move |a| backup.restore_first_arg(a));
|
auto_restore!(args = (_args) if swap => move |a| backup.restore_first_arg(a));
|
||||||
|
|
||||||
let mut this = Dynamic::NULL;
|
let mut this = Dynamic::NULL;
|
||||||
|
|
||||||
@ -725,7 +725,7 @@ impl Engine {
|
|||||||
})
|
})
|
||||||
});
|
});
|
||||||
#[cfg(feature = "debugging")]
|
#[cfg(feature = "debugging")]
|
||||||
auto_restore!(global; reset.is_some() => move |g| g.debugger_mut().reset_status(reset));
|
auto_restore!(global if reset.is_some() => 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()))
|
||||||
|
@ -14,16 +14,32 @@ macro_rules! auto_restore {
|
|||||||
$code
|
$code
|
||||||
auto_restore!($var => $restore);
|
auto_restore!($var => $restore);
|
||||||
};
|
};
|
||||||
($var:ident => $restore: expr) => {
|
($var:ident => $restore:ident; let $temp:ident = $save:expr;) => {
|
||||||
|
auto_restore!($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; {});
|
||||||
|
};
|
||||||
|
($var:ident => $restore:ident; let $temp:ident = $save:expr; $code:stmt) => {
|
||||||
|
let $temp = $save;
|
||||||
|
$code
|
||||||
|
auto_restore!($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); });
|
||||||
|
};
|
||||||
|
($var:ident => $restore:expr) => {
|
||||||
auto_restore!($var = $var => $restore);
|
auto_restore!($var = $var => $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; $guard:expr => $restore: expr) => {
|
($var:ident if $guard:expr => $restore:expr) => {
|
||||||
auto_restore!($var = $var; $guard => $restore);
|
auto_restore!($var = ($var) if $guard => $restore);
|
||||||
};
|
};
|
||||||
($var:ident = $value:expr; $guard:expr => $restore: expr) => {
|
($var:ident = ( $value:expr ) if $guard:expr => $restore:expr) => {
|
||||||
let mut __rx__;
|
let mut __rx__;
|
||||||
let $var = if $guard {
|
let $var = if $guard {
|
||||||
__rx__ = crate::types::RestoreOnDrop::lock($value, $restore);
|
__rx__ = crate::types::RestoreOnDrop::lock($value, $restore);
|
||||||
|
@ -352,7 +352,7 @@ fn test_call_fn_events() -> Result<(), Box<EvalAltResult>> {
|
|||||||
|
|
||||||
let mut handler = Handler::new();
|
let mut handler = Handler::new();
|
||||||
assert!(!handler.scope.get_value::<bool>("state").unwrap());
|
assert!(!handler.scope.get_value::<bool>("state").unwrap());
|
||||||
handler.on_event("update", 999);
|
let _ = handler.on_event("update", 999);
|
||||||
assert!(handler.scope.get_value::<bool>("state").unwrap());
|
assert!(handler.scope.get_value::<bool>("state").unwrap());
|
||||||
assert_eq!(handler.on_event("start", 999).as_int().unwrap(), 1041);
|
assert_eq!(handler.on_event("start", 999).as_int().unwrap(), 1041);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user