Remove Dynamic::NULL, use .as_deref_mut() for this_ptr.
This commit is contained in:
@@ -340,7 +340,7 @@ impl Engine {
|
||||
global: &mut GlobalRuntimeState,
|
||||
caches: &mut Caches,
|
||||
scope: &mut Scope,
|
||||
this_ptr: &mut Dynamic,
|
||||
mut this_ptr: Option<&mut Dynamic>,
|
||||
expr: &Expr,
|
||||
new_val: Option<(Dynamic, &OpAssignment)>,
|
||||
) -> RhaiResult {
|
||||
@@ -379,7 +379,13 @@ impl Engine {
|
||||
}
|
||||
// All other patterns - evaluate the arguments chain
|
||||
_ => self.eval_dot_index_chain_arguments(
|
||||
global, caches, scope, this_ptr, expr, rhs, idx_values,
|
||||
global,
|
||||
caches,
|
||||
scope,
|
||||
this_ptr.as_deref_mut(),
|
||||
expr,
|
||||
rhs,
|
||||
idx_values,
|
||||
)?,
|
||||
}
|
||||
|
||||
@@ -387,22 +393,13 @@ impl Engine {
|
||||
// id.??? or id[???]
|
||||
Expr::Variable(.., var_pos) => {
|
||||
#[cfg(feature = "debugging")]
|
||||
self.run_debugger(global, caches, scope, this_ptr, lhs)?;
|
||||
self.run_debugger(global, caches, scope, this_ptr.as_deref_mut(), lhs)?;
|
||||
self.track_operation(global, *var_pos)?;
|
||||
|
||||
let target = &mut self.search_namespace(global, caches, scope, this_ptr, lhs)?;
|
||||
let mut this_ptr = Dynamic::NULL;
|
||||
|
||||
self.eval_dot_index_chain_raw(
|
||||
global,
|
||||
caches,
|
||||
&mut this_ptr,
|
||||
lhs,
|
||||
expr,
|
||||
target,
|
||||
rhs,
|
||||
idx_values,
|
||||
new_val,
|
||||
global, caches, None, lhs, expr, target, rhs, idx_values, new_val,
|
||||
)
|
||||
}
|
||||
// {expr}.??? = ??? or {expr}[???] = ???
|
||||
@@ -410,7 +407,7 @@ impl Engine {
|
||||
// {expr}.??? or {expr}[???]
|
||||
lhs_expr => {
|
||||
let value = self
|
||||
.eval_expr(global, caches, scope, this_ptr, lhs_expr)?
|
||||
.eval_expr(global, caches, scope, this_ptr.as_deref_mut(), lhs_expr)?
|
||||
.flatten();
|
||||
let obj_ptr = &mut value.into();
|
||||
|
||||
@@ -428,7 +425,7 @@ impl Engine {
|
||||
global: &mut GlobalRuntimeState,
|
||||
caches: &mut Caches,
|
||||
scope: &mut Scope,
|
||||
this_ptr: &mut Dynamic,
|
||||
mut this_ptr: Option<&mut Dynamic>,
|
||||
parent: &Expr,
|
||||
expr: &Expr,
|
||||
idx_values: &mut FnArgsVec<Dynamic>,
|
||||
@@ -440,12 +437,10 @@ impl Engine {
|
||||
match expr {
|
||||
#[cfg(not(feature = "no_object"))]
|
||||
Expr::MethodCall(x, ..) if chain_type == ChainType::Dotting && !x.is_qualified() => {
|
||||
for arg_expr in &x.args {
|
||||
idx_values.push(
|
||||
self.get_arg_value(global, caches, scope, this_ptr, arg_expr)?
|
||||
.0
|
||||
.flatten(),
|
||||
);
|
||||
for expr in &x.args {
|
||||
let arg_value =
|
||||
self.get_arg_value(global, caches, scope, this_ptr.as_deref_mut(), expr)?;
|
||||
idx_values.push(arg_value.0.flatten());
|
||||
}
|
||||
}
|
||||
#[cfg(not(feature = "no_object"))]
|
||||
@@ -474,12 +469,15 @@ impl Engine {
|
||||
Expr::MethodCall(x, ..)
|
||||
if chain_type == ChainType::Dotting && !x.is_qualified() =>
|
||||
{
|
||||
for arg_expr in &x.args {
|
||||
_arg_values.push(
|
||||
self.get_arg_value(global, caches, scope, this_ptr, arg_expr)?
|
||||
.0
|
||||
.flatten(),
|
||||
);
|
||||
for expr in &x.args {
|
||||
let arg_value = self.get_arg_value(
|
||||
global,
|
||||
caches,
|
||||
scope,
|
||||
this_ptr.as_deref_mut(),
|
||||
expr,
|
||||
)?;
|
||||
_arg_values.push(arg_value.0.flatten());
|
||||
}
|
||||
}
|
||||
#[cfg(not(feature = "no_object"))]
|
||||
@@ -493,7 +491,7 @@ impl Engine {
|
||||
#[cfg(not(feature = "no_index"))]
|
||||
_ if chain_type == ChainType::Indexing => {
|
||||
_arg_values.push(
|
||||
self.eval_expr(global, caches, scope, this_ptr, lhs)?
|
||||
self.eval_expr(global, caches, scope, this_ptr.as_deref_mut(), lhs)?
|
||||
.flatten(),
|
||||
);
|
||||
}
|
||||
@@ -530,7 +528,7 @@ impl Engine {
|
||||
&self,
|
||||
global: &mut GlobalRuntimeState,
|
||||
caches: &mut Caches,
|
||||
this_ptr: &mut Dynamic,
|
||||
mut this_ptr: Option<&mut Dynamic>,
|
||||
root: &Expr,
|
||||
parent: &Expr,
|
||||
target: &mut Target,
|
||||
@@ -560,7 +558,7 @@ impl Engine {
|
||||
if !parent.options().contains(ASTFlags::BREAK) =>
|
||||
{
|
||||
#[cfg(feature = "debugging")]
|
||||
self.run_debugger(global, caches, scope, this_ptr, parent)?;
|
||||
self.run_debugger(global, caches, scope, this_ptr.as_deref_mut(), parent)?;
|
||||
|
||||
let idx_val = &mut idx_values.pop().unwrap();
|
||||
let mut idx_val_for_setter = idx_val.clone();
|
||||
@@ -843,7 +841,13 @@ impl Engine {
|
||||
let val_target = &mut match x.lhs {
|
||||
Expr::Property(ref p, pos) => {
|
||||
#[cfg(feature = "debugging")]
|
||||
self.run_debugger(global, caches, scope, this_ptr, _node)?;
|
||||
self.run_debugger(
|
||||
global,
|
||||
caches,
|
||||
scope,
|
||||
this_ptr.as_deref_mut(),
|
||||
_node,
|
||||
)?;
|
||||
|
||||
let index = &mut p.2.clone().into();
|
||||
self.get_indexed_mut(
|
||||
@@ -854,7 +858,11 @@ impl Engine {
|
||||
Expr::MethodCall(ref x, pos) if !x.is_qualified() => {
|
||||
#[cfg(feature = "debugging")]
|
||||
let reset = self.run_debugger_with_reset(
|
||||
global, caches, scope, this_ptr, _node,
|
||||
global,
|
||||
caches,
|
||||
scope,
|
||||
this_ptr.as_deref_mut(),
|
||||
_node,
|
||||
)?;
|
||||
#[cfg(feature = "debugging")]
|
||||
auto_restore!(global if Some(reset) => move |g| g.debugger_mut().reset_status(reset));
|
||||
@@ -896,7 +904,13 @@ impl Engine {
|
||||
// xxx.prop[expr] | xxx.prop.expr
|
||||
Expr::Property(ref p, pos) => {
|
||||
#[cfg(feature = "debugging")]
|
||||
self.run_debugger(global, caches, scope, this_ptr, _node)?;
|
||||
self.run_debugger(
|
||||
global,
|
||||
caches,
|
||||
scope,
|
||||
this_ptr.as_deref_mut(),
|
||||
_node,
|
||||
)?;
|
||||
|
||||
let ((getter, hash_get), (setter, hash_set), name) = &**p;
|
||||
let args = &mut [target.as_mut()];
|
||||
@@ -972,7 +986,11 @@ impl Engine {
|
||||
let val = {
|
||||
#[cfg(feature = "debugging")]
|
||||
let reset = self.run_debugger_with_reset(
|
||||
global, caches, scope, this_ptr, _node,
|
||||
global,
|
||||
caches,
|
||||
scope,
|
||||
this_ptr.as_deref_mut(),
|
||||
_node,
|
||||
)?;
|
||||
#[cfg(feature = "debugging")]
|
||||
auto_restore!(global if Some(reset) => move |g| g.debugger_mut().reset_status(reset));
|
||||
|
@@ -410,7 +410,7 @@ impl Engine {
|
||||
global: &mut GlobalRuntimeState,
|
||||
caches: &mut Caches,
|
||||
scope: &mut Scope,
|
||||
this_ptr: &mut Dynamic,
|
||||
this_ptr: Option<&mut Dynamic>,
|
||||
node: impl Into<ASTNode<'a>>,
|
||||
) -> RhaiResultOf<()> {
|
||||
if self.is_debugger_registered() {
|
||||
@@ -435,7 +435,7 @@ impl Engine {
|
||||
global: &mut GlobalRuntimeState,
|
||||
caches: &mut Caches,
|
||||
scope: &mut Scope,
|
||||
this_ptr: &mut Dynamic,
|
||||
this_ptr: Option<&mut Dynamic>,
|
||||
node: impl Into<ASTNode<'a>>,
|
||||
) -> RhaiResultOf<Option<DebuggerStatus>> {
|
||||
if self.is_debugger_registered() {
|
||||
@@ -456,7 +456,7 @@ impl Engine {
|
||||
global: &mut GlobalRuntimeState,
|
||||
caches: &mut Caches,
|
||||
scope: &mut Scope,
|
||||
this_ptr: &mut Dynamic,
|
||||
this_ptr: Option<&mut Dynamic>,
|
||||
node: impl Into<ASTNode<'a>>,
|
||||
) -> RhaiResultOf<Option<DebuggerStatus>> {
|
||||
let node = node.into();
|
||||
@@ -502,7 +502,7 @@ impl Engine {
|
||||
global: &mut GlobalRuntimeState,
|
||||
caches: &mut Caches,
|
||||
scope: &mut Scope,
|
||||
this_ptr: &mut Dynamic,
|
||||
this_ptr: Option<&mut Dynamic>,
|
||||
node: ASTNode<'a>,
|
||||
event: DebuggerEvent,
|
||||
) -> Result<Option<DebuggerStatus>, Box<crate::EvalAltResult>> {
|
||||
|
@@ -17,7 +17,7 @@ pub struct EvalContext<'a, 's, 'ps, 'g, 'c, 't> {
|
||||
/// The current [`Scope`].
|
||||
scope: &'s mut Scope<'ps>,
|
||||
/// The current bound `this` pointer, if any.
|
||||
this_ptr: &'t mut Dynamic,
|
||||
this_ptr: Option<&'t mut Dynamic>,
|
||||
}
|
||||
|
||||
impl<'a, 's, 'ps, 'g, 'c, 't> EvalContext<'a, 's, 'ps, 'g, 'c, 't> {
|
||||
@@ -29,7 +29,7 @@ impl<'a, 's, 'ps, 'g, 'c, 't> EvalContext<'a, 's, 'ps, 'g, 'c, 't> {
|
||||
global: &'g mut GlobalRuntimeState,
|
||||
caches: &'c mut Caches,
|
||||
scope: &'s mut Scope<'ps>,
|
||||
this_ptr: &'t mut Dynamic,
|
||||
this_ptr: Option<&'t mut Dynamic>,
|
||||
) -> Self {
|
||||
Self {
|
||||
engine,
|
||||
@@ -118,24 +118,16 @@ impl<'a, 's, 'ps, 'g, 'c, 't> EvalContext<'a, 's, 'ps, 'g, 'c, 't> {
|
||||
&self.global.lib
|
||||
}
|
||||
/// The current bound `this` pointer, if any.
|
||||
#[inline]
|
||||
#[inline(always)]
|
||||
#[must_use]
|
||||
pub fn this_ptr(&self) -> Option<&Dynamic> {
|
||||
if self.this_ptr.is_null() {
|
||||
None
|
||||
} else {
|
||||
Some(self.this_ptr)
|
||||
}
|
||||
self.this_ptr.as_deref()
|
||||
}
|
||||
/// Mutable reference to the current bound `this` pointer, if any.
|
||||
#[inline]
|
||||
#[inline(always)]
|
||||
#[must_use]
|
||||
pub fn this_ptr_mut(&mut self) -> Option<&mut Dynamic> {
|
||||
if self.this_ptr.is_null() {
|
||||
None
|
||||
} else {
|
||||
Some(self.this_ptr)
|
||||
}
|
||||
self.this_ptr.as_deref_mut()
|
||||
}
|
||||
/// The current nesting level of function calls.
|
||||
#[inline(always)]
|
||||
@@ -177,19 +169,20 @@ impl<'a, 's, 'ps, 'g, 'c, 't> EvalContext<'a, 's, 'ps, 'g, 'c, 't> {
|
||||
rewind_scope: bool,
|
||||
) -> crate::RhaiResult {
|
||||
let expr: &crate::ast::Expr = expr;
|
||||
let this_ptr = self.this_ptr.as_deref_mut();
|
||||
|
||||
match expr {
|
||||
crate::ast::Expr::Stmt(statements) => self.engine.eval_stmt_block(
|
||||
crate::ast::Expr::Stmt(stmts) => self.engine.eval_stmt_block(
|
||||
self.global,
|
||||
self.caches,
|
||||
self.scope,
|
||||
self.this_ptr,
|
||||
statements,
|
||||
this_ptr,
|
||||
stmts,
|
||||
rewind_scope,
|
||||
),
|
||||
_ => self
|
||||
.engine
|
||||
.eval_expr(self.global, self.caches, self.scope, self.this_ptr, expr),
|
||||
.eval_expr(self.global, self.caches, self.scope, this_ptr, expr),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -53,7 +53,7 @@ impl Engine {
|
||||
global: &mut GlobalRuntimeState,
|
||||
caches: &mut Caches,
|
||||
scope: &'s mut Scope,
|
||||
this_ptr: &'s mut Dynamic,
|
||||
this_ptr: Option<&'s mut Dynamic>,
|
||||
expr: &Expr,
|
||||
) -> RhaiResultOf<Target<'s>> {
|
||||
match expr {
|
||||
@@ -132,7 +132,7 @@ impl Engine {
|
||||
global: &mut GlobalRuntimeState,
|
||||
caches: &mut Caches,
|
||||
scope: &'s mut Scope,
|
||||
this_ptr: &'s mut Dynamic,
|
||||
this_ptr: Option<&'s mut Dynamic>,
|
||||
expr: &Expr,
|
||||
) -> RhaiResultOf<Target<'s>> {
|
||||
// Make sure that the pointer indirection is taken only when absolutely necessary.
|
||||
@@ -142,10 +142,10 @@ impl Engine {
|
||||
Expr::Variable(v, None, ..)
|
||||
if v.0.is_none() && v.1.is_empty() && v.3 == KEYWORD_THIS =>
|
||||
{
|
||||
return if this_ptr.is_null() {
|
||||
Err(ERR::ErrorUnboundThis(expr.position()).into())
|
||||
} else {
|
||||
return if let Some(this_ptr) = this_ptr {
|
||||
Ok(this_ptr.into())
|
||||
} else {
|
||||
Err(ERR::ErrorUnboundThis(expr.position()).into())
|
||||
};
|
||||
}
|
||||
|
||||
@@ -223,7 +223,7 @@ impl Engine {
|
||||
global: &mut GlobalRuntimeState,
|
||||
caches: &mut Caches,
|
||||
scope: &mut Scope,
|
||||
this_ptr: &mut Dynamic,
|
||||
mut this_ptr: Option<&mut Dynamic>,
|
||||
expr: &Expr,
|
||||
) -> RhaiResult {
|
||||
// Coded this way for better branch prediction.
|
||||
@@ -233,7 +233,8 @@ impl Engine {
|
||||
// binary operators are also function calls.
|
||||
if let Expr::FnCall(x, pos) = expr {
|
||||
#[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.as_deref_mut(), expr)?;
|
||||
#[cfg(feature = "debugging")]
|
||||
auto_restore!(global if Some(reset) => move |g| g.debugger_mut().reset_status(reset));
|
||||
|
||||
@@ -247,16 +248,14 @@ impl Engine {
|
||||
// will cost more than the mis-predicted `match` branch.
|
||||
if let Expr::Variable(x, index, var_pos) = expr {
|
||||
#[cfg(feature = "debugging")]
|
||||
self.run_debugger(global, caches, scope, this_ptr, expr)?;
|
||||
self.run_debugger(global, caches, scope, this_ptr.as_deref_mut(), expr)?;
|
||||
|
||||
self.track_operation(global, expr.position())?;
|
||||
|
||||
return if index.is_none() && x.0.is_none() && x.3 == KEYWORD_THIS {
|
||||
if this_ptr.is_null() {
|
||||
ERR::ErrorUnboundThis(*var_pos).into()
|
||||
} else {
|
||||
Ok(this_ptr.clone())
|
||||
}
|
||||
this_ptr
|
||||
.ok_or_else(|| ERR::ErrorUnboundThis(*var_pos).into())
|
||||
.cloned()
|
||||
} else {
|
||||
self.search_namespace(global, caches, scope, this_ptr, expr)
|
||||
.map(Target::take_or_clone)
|
||||
@@ -264,7 +263,8 @@ impl Engine {
|
||||
}
|
||||
|
||||
#[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.as_deref_mut(), expr)?;
|
||||
#[cfg(feature = "debugging")]
|
||||
auto_restore!(global if Some(reset) => move |g| g.debugger_mut().reset_status(reset));
|
||||
|
||||
@@ -291,7 +291,7 @@ impl Engine {
|
||||
x.iter()
|
||||
.try_for_each(|expr| {
|
||||
let item = self
|
||||
.eval_expr(global, caches, scope, this_ptr, expr)?
|
||||
.eval_expr(global, caches, scope, this_ptr.as_deref_mut(), expr)?
|
||||
.flatten();
|
||||
|
||||
op_info.pos = expr.start_position();
|
||||
@@ -312,7 +312,13 @@ impl Engine {
|
||||
crate::Array::with_capacity(x.len()),
|
||||
|mut array, item_expr| {
|
||||
let value = self
|
||||
.eval_expr(global, caches, scope, this_ptr, item_expr)?
|
||||
.eval_expr(
|
||||
global,
|
||||
caches,
|
||||
scope,
|
||||
this_ptr.as_deref_mut(),
|
||||
item_expr,
|
||||
)?
|
||||
.flatten();
|
||||
|
||||
#[cfg(not(feature = "unchecked"))]
|
||||
@@ -344,7 +350,7 @@ impl Engine {
|
||||
x.0.iter()
|
||||
.try_fold(x.1.clone(), |mut map, (key, value_expr)| {
|
||||
let value = self
|
||||
.eval_expr(global, caches, scope, this_ptr, value_expr)?
|
||||
.eval_expr(global, caches, scope, this_ptr.as_deref_mut(), value_expr)?
|
||||
.flatten();
|
||||
|
||||
#[cfg(not(feature = "unchecked"))]
|
||||
@@ -367,7 +373,7 @@ impl Engine {
|
||||
}
|
||||
|
||||
Expr::And(x, ..) => Ok((self
|
||||
.eval_expr(global, caches, scope, this_ptr, &x.lhs)?
|
||||
.eval_expr(global, caches, scope, this_ptr.as_deref_mut(), &x.lhs)?
|
||||
.as_bool()
|
||||
.map_err(|typ| self.make_type_mismatch_err::<bool>(typ, x.lhs.position()))?
|
||||
&& self
|
||||
@@ -377,7 +383,7 @@ impl Engine {
|
||||
.into()),
|
||||
|
||||
Expr::Or(x, ..) => Ok((self
|
||||
.eval_expr(global, caches, scope, this_ptr, &x.lhs)?
|
||||
.eval_expr(global, caches, scope, this_ptr.as_deref_mut(), &x.lhs)?
|
||||
.as_bool()
|
||||
.map_err(|typ| self.make_type_mismatch_err::<bool>(typ, x.lhs.position()))?
|
||||
|| self
|
||||
@@ -387,7 +393,8 @@ impl Engine {
|
||||
.into()),
|
||||
|
||||
Expr::Coalesce(x, ..) => {
|
||||
let value = self.eval_expr(global, caches, scope, this_ptr, &x.lhs)?;
|
||||
let value =
|
||||
self.eval_expr(global, caches, scope, this_ptr.as_deref_mut(), &x.lhs)?;
|
||||
|
||||
if value.is_unit() {
|
||||
self.eval_expr(global, caches, scope, this_ptr, &x.rhs)
|
||||
|
@@ -32,7 +32,7 @@ impl Engine {
|
||||
global: &mut GlobalRuntimeState,
|
||||
caches: &mut Caches,
|
||||
scope: &mut Scope,
|
||||
this_ptr: &mut Dynamic,
|
||||
mut this_ptr: Option<&mut Dynamic>,
|
||||
statements: &[Stmt],
|
||||
restore_orig_state: bool,
|
||||
) -> RhaiResult {
|
||||
@@ -71,6 +71,8 @@ impl Engine {
|
||||
|
||||
// Run the statements
|
||||
statements.iter().try_fold(Dynamic::UNIT, |_, stmt| {
|
||||
let this_ptr = this_ptr.as_deref_mut();
|
||||
|
||||
#[cfg(not(feature = "no_module"))]
|
||||
let imports_len = global.num_imports();
|
||||
|
||||
@@ -198,12 +200,13 @@ impl Engine {
|
||||
global: &mut GlobalRuntimeState,
|
||||
caches: &mut Caches,
|
||||
scope: &mut Scope,
|
||||
this_ptr: &mut Dynamic,
|
||||
mut this_ptr: Option<&mut Dynamic>,
|
||||
stmt: &Stmt,
|
||||
rewind_scope: bool,
|
||||
) -> RhaiResult {
|
||||
#[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.as_deref_mut(), stmt)?;
|
||||
#[cfg(feature = "debugging")]
|
||||
auto_restore!(global if Some(reset) => move |g| g.debugger_mut().reset_status(reset));
|
||||
|
||||
@@ -227,7 +230,7 @@ impl Engine {
|
||||
|
||||
if let Expr::Variable(x, ..) = lhs {
|
||||
let rhs_val = self
|
||||
.eval_expr(global, caches, scope, this_ptr, rhs)?
|
||||
.eval_expr(global, caches, scope, this_ptr.as_deref_mut(), rhs)?
|
||||
.flatten();
|
||||
|
||||
let mut target = self.search_namespace(global, caches, scope, this_ptr, lhs)?;
|
||||
@@ -259,7 +262,7 @@ impl Engine {
|
||||
#[cfg(any(not(feature = "no_index"), not(feature = "no_object")))]
|
||||
{
|
||||
let rhs_val = self
|
||||
.eval_expr(global, caches, scope, this_ptr, rhs)?
|
||||
.eval_expr(global, caches, scope, this_ptr.as_deref_mut(), rhs)?
|
||||
.flatten()
|
||||
.intern_string(self);
|
||||
|
||||
@@ -310,7 +313,7 @@ impl Engine {
|
||||
let (expr, if_block, else_block) = &**x;
|
||||
|
||||
let guard_val = self
|
||||
.eval_expr(global, caches, scope, this_ptr, expr)?
|
||||
.eval_expr(global, caches, scope, this_ptr.as_deref_mut(), expr)?
|
||||
.as_bool()
|
||||
.map_err(|typ| self.make_type_mismatch_err::<bool>(typ, expr.position()))?;
|
||||
|
||||
@@ -337,7 +340,7 @@ impl Engine {
|
||||
|
||||
let mut result = None;
|
||||
|
||||
let value = self.eval_expr(global, caches, scope, this_ptr, expr)?;
|
||||
let value = self.eval_expr(global, caches, scope, this_ptr.as_deref_mut(), expr)?;
|
||||
|
||||
if value.is_hashable() {
|
||||
let hasher = &mut get_hasher();
|
||||
@@ -354,7 +357,7 @@ impl Engine {
|
||||
let cond_result = match block.condition {
|
||||
Expr::BoolConstant(b, ..) => b,
|
||||
ref c => self
|
||||
.eval_expr(global, caches, scope, this_ptr, c)?
|
||||
.eval_expr(global, caches, scope, this_ptr.as_deref_mut(), c)?
|
||||
.as_bool()
|
||||
.map_err(|typ| {
|
||||
self.make_type_mismatch_err::<bool>(typ, c.position())
|
||||
@@ -376,7 +379,7 @@ impl Engine {
|
||||
let cond_result = match block.condition {
|
||||
Expr::BoolConstant(b, ..) => b,
|
||||
ref c => self
|
||||
.eval_expr(global, caches, scope, this_ptr, c)?
|
||||
.eval_expr(global, caches, scope, this_ptr.as_deref_mut(), c)?
|
||||
.as_bool()
|
||||
.map_err(|typ| {
|
||||
self.make_type_mismatch_err::<bool>(typ, c.position())
|
||||
@@ -409,14 +412,15 @@ impl Engine {
|
||||
}
|
||||
|
||||
loop {
|
||||
if let Err(err) =
|
||||
self.eval_stmt_block(global, caches, scope, this_ptr, body, true)
|
||||
{
|
||||
match *err {
|
||||
let this_ptr = this_ptr.as_deref_mut();
|
||||
|
||||
match self.eval_stmt_block(global, caches, scope, this_ptr, body, true) {
|
||||
Ok(..) => (),
|
||||
Err(err) => match *err {
|
||||
ERR::LoopBreak(false, ..) => (),
|
||||
ERR::LoopBreak(true, value, ..) => break Ok(value),
|
||||
_ => break Err(err),
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -427,7 +431,7 @@ impl Engine {
|
||||
|
||||
loop {
|
||||
let condition = self
|
||||
.eval_expr(global, caches, scope, this_ptr, expr)?
|
||||
.eval_expr(global, caches, scope, this_ptr.as_deref_mut(), expr)?
|
||||
.as_bool()
|
||||
.map_err(|typ| self.make_type_mismatch_err::<bool>(typ, expr.position()))?;
|
||||
|
||||
@@ -439,14 +443,15 @@ impl Engine {
|
||||
continue;
|
||||
}
|
||||
|
||||
if let Err(err) =
|
||||
self.eval_stmt_block(global, caches, scope, this_ptr, body, true)
|
||||
{
|
||||
match *err {
|
||||
let this_ptr = this_ptr.as_deref_mut();
|
||||
|
||||
match self.eval_stmt_block(global, caches, scope, this_ptr, body, true) {
|
||||
Ok(..) => (),
|
||||
Err(err) => match *err {
|
||||
ERR::LoopBreak(false, ..) => (),
|
||||
ERR::LoopBreak(true, value, ..) => break Ok(value),
|
||||
_ => break Err(err),
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -458,19 +463,20 @@ impl Engine {
|
||||
|
||||
loop {
|
||||
if !body.is_empty() {
|
||||
if let Err(err) =
|
||||
self.eval_stmt_block(global, caches, scope, this_ptr, body, true)
|
||||
{
|
||||
match *err {
|
||||
let this_ptr = this_ptr.as_deref_mut();
|
||||
|
||||
match self.eval_stmt_block(global, caches, scope, this_ptr, body, true) {
|
||||
Ok(..) => (),
|
||||
Err(err) => match *err {
|
||||
ERR::LoopBreak(false, ..) => continue,
|
||||
ERR::LoopBreak(true, value, ..) => break Ok(value),
|
||||
_ => break Err(err),
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
let condition = self
|
||||
.eval_expr(global, caches, scope, this_ptr, expr)?
|
||||
.eval_expr(global, caches, scope, this_ptr.as_deref_mut(), expr)?
|
||||
.as_bool()
|
||||
.map_err(|typ| self.make_type_mismatch_err::<bool>(typ, expr.position()))?;
|
||||
|
||||
@@ -485,7 +491,7 @@ impl Engine {
|
||||
let (var_name, counter, expr, statements) = &**x;
|
||||
|
||||
let iter_obj = self
|
||||
.eval_expr(global, caches, scope, this_ptr, expr)?
|
||||
.eval_expr(global, caches, scope, this_ptr.as_deref_mut(), expr)?
|
||||
.flatten();
|
||||
|
||||
let iter_type = iter_obj.type_id();
|
||||
@@ -566,6 +572,8 @@ impl Engine {
|
||||
continue;
|
||||
}
|
||||
|
||||
let this_ptr = this_ptr.as_deref_mut();
|
||||
|
||||
match self.eval_stmt_block(global, caches, scope, this_ptr, statements, true) {
|
||||
Ok(_) => (),
|
||||
Err(err) => match *err {
|
||||
@@ -603,7 +611,14 @@ impl Engine {
|
||||
catch_block,
|
||||
} = &**x;
|
||||
|
||||
match self.eval_stmt_block(global, caches, scope, this_ptr, try_block, true) {
|
||||
match self.eval_stmt_block(
|
||||
global,
|
||||
caches,
|
||||
scope,
|
||||
this_ptr.as_deref_mut(),
|
||||
try_block,
|
||||
true,
|
||||
) {
|
||||
r @ Ok(_) => r,
|
||||
Err(err) if err.is_pseudo_error() => Err(err),
|
||||
Err(err) if !err.is_catchable() => Err(err),
|
||||
@@ -650,6 +665,8 @@ impl Engine {
|
||||
scope.push(catch_var.name.clone(), err_value);
|
||||
}
|
||||
|
||||
let this_ptr = this_ptr.as_deref_mut();
|
||||
|
||||
self.eval_stmt_block(global, caches, scope, this_ptr, catch_block, true)
|
||||
.map(|_| Dynamic::UNIT)
|
||||
.map_err(|result_err| match *result_err {
|
||||
@@ -707,7 +724,8 @@ impl Engine {
|
||||
nesting_level: global.scope_level,
|
||||
will_shadow,
|
||||
};
|
||||
let context = EvalContext::new(self, global, caches, scope, this_ptr);
|
||||
let context =
|
||||
EvalContext::new(self, global, caches, scope, this_ptr.as_deref_mut());
|
||||
|
||||
if !filter(true, info, context)? {
|
||||
return Err(ERR::ErrorForbiddenVariable(var_name.to_string(), *pos).into());
|
||||
@@ -866,7 +884,7 @@ impl Engine {
|
||||
|
||||
/// Evaluate a list of statements with no `this` pointer.
|
||||
/// This is commonly used to evaluate a list of statements in an [`AST`][crate::AST] or a script function body.
|
||||
#[inline]
|
||||
#[inline(always)]
|
||||
pub(crate) fn eval_global_statements(
|
||||
&self,
|
||||
global: &mut GlobalRuntimeState,
|
||||
@@ -874,9 +892,7 @@ impl Engine {
|
||||
scope: &mut Scope,
|
||||
statements: &[Stmt],
|
||||
) -> RhaiResult {
|
||||
let mut this_ptr = Dynamic::NULL;
|
||||
|
||||
self.eval_stmt_block(global, caches, scope, &mut this_ptr, statements, false)
|
||||
self.eval_stmt_block(global, caches, scope, None, statements, false)
|
||||
.or_else(|err| match *err {
|
||||
ERR::Return(out, ..) => Ok(out),
|
||||
ERR::LoopBreak(..) => {
|
||||
|
Reference in New Issue
Block a user