Lift function calls out of match block in eval_stmt.
This commit is contained in:
parent
80edb1200d
commit
de6cb36503
@ -251,7 +251,7 @@ pub enum Target<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> Target<'a> {
|
impl<'a> Target<'a> {
|
||||||
/// Is the `Target` a reference pointing to other data?
|
/// Is the [`Target`] a reference pointing to other data?
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
#[inline]
|
#[inline]
|
||||||
#[must_use]
|
#[must_use]
|
||||||
@ -268,7 +268,7 @@ impl<'a> Target<'a> {
|
|||||||
| Self::StringChar { .. } => false,
|
| Self::StringChar { .. } => false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/// Is the `Target` a temp value?
|
/// Is the [`Target`] a temp value?
|
||||||
#[inline]
|
#[inline]
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub const fn is_temp_value(&self) -> bool {
|
pub const fn is_temp_value(&self) -> bool {
|
||||||
@ -284,7 +284,7 @@ impl<'a> Target<'a> {
|
|||||||
| Self::StringChar { .. } => false,
|
| Self::StringChar { .. } => false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/// Is the `Target` a shared value?
|
/// Is the [`Target`] a shared value?
|
||||||
#[cfg(not(feature = "no_closure"))]
|
#[cfg(not(feature = "no_closure"))]
|
||||||
#[inline]
|
#[inline]
|
||||||
#[must_use]
|
#[must_use]
|
||||||
@ -301,7 +301,7 @@ impl<'a> Target<'a> {
|
|||||||
| Self::StringChar { .. } => false,
|
| Self::StringChar { .. } => false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/// Is the `Target` a specific type?
|
/// Is the [`Target`] a specific type?
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
#[inline]
|
#[inline]
|
||||||
#[must_use]
|
#[must_use]
|
||||||
@ -321,7 +321,7 @@ impl<'a> Target<'a> {
|
|||||||
Self::StringChar { .. } => TypeId::of::<T>() == TypeId::of::<char>(),
|
Self::StringChar { .. } => TypeId::of::<T>() == TypeId::of::<char>(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/// Get the value of the `Target` as a `Dynamic`, cloning a referenced value if necessary.
|
/// Get the value of the [`Target`] as a [`Dynamic`], cloning a referenced value if necessary.
|
||||||
#[inline]
|
#[inline]
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn take_or_clone(self) -> Dynamic {
|
pub fn take_or_clone(self) -> Dynamic {
|
||||||
@ -349,7 +349,7 @@ impl<'a> Target<'a> {
|
|||||||
_ => None,
|
_ => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/// Convert a shared or reference `Target` into a target with an owned value.
|
/// Convert a shared or reference [`Target`] into a target with an owned value.
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn into_owned(self) -> Self {
|
pub fn into_owned(self) -> Self {
|
||||||
@ -360,6 +360,25 @@ impl<'a> Target<'a> {
|
|||||||
_ => self,
|
_ => self,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
/// Get the source [`Dynamic`] of the [`Target`].
|
||||||
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
|
pub fn source(&self) -> &Dynamic {
|
||||||
|
match self {
|
||||||
|
Self::RefMut(r) => *r,
|
||||||
|
#[cfg(not(feature = "no_closure"))]
|
||||||
|
Self::SharedValue { source, .. } => source,
|
||||||
|
Self::TempValue(v) => v,
|
||||||
|
#[cfg(not(feature = "no_index"))]
|
||||||
|
Self::Bit { source, .. } => source,
|
||||||
|
#[cfg(not(feature = "no_index"))]
|
||||||
|
Self::BitField { source, .. } => source,
|
||||||
|
#[cfg(not(feature = "no_index"))]
|
||||||
|
Self::BlobByte { source, .. } => source,
|
||||||
|
#[cfg(not(feature = "no_index"))]
|
||||||
|
Self::StringChar { source, .. } => source,
|
||||||
|
}
|
||||||
|
}
|
||||||
/// Propagate a changed value back to the original source.
|
/// Propagate a changed value back to the original source.
|
||||||
/// This has no effect for direct references.
|
/// This has no effect for direct references.
|
||||||
#[inline]
|
#[inline]
|
||||||
@ -2431,8 +2450,6 @@ impl Engine {
|
|||||||
.map_err(|err| err.fill_position(expr.position()))?;
|
.map_err(|err| err.fill_position(expr.position()))?;
|
||||||
|
|
||||||
pos = expr.position();
|
pos = expr.position();
|
||||||
|
|
||||||
result = self.check_return_value(Ok(result), pos)?;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(result)
|
Ok(result)
|
||||||
@ -2718,7 +2735,9 @@ impl Engine {
|
|||||||
*target.as_mut() = new_val;
|
*target.as_mut() = new_val;
|
||||||
}
|
}
|
||||||
|
|
||||||
target.propagate_changed_value()
|
target.propagate_changed_value()?;
|
||||||
|
|
||||||
|
self.check_data_size(target.source(), Position::NONE)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Evaluate a statement.
|
/// Evaluate a statement.
|
||||||
@ -2738,10 +2757,21 @@ impl Engine {
|
|||||||
rewind_scope: bool,
|
rewind_scope: bool,
|
||||||
level: usize,
|
level: usize,
|
||||||
) -> RhaiResult {
|
) -> RhaiResult {
|
||||||
|
// Coded this way for better branch prediction.
|
||||||
|
// Popular branches are lifted out of the `match` statement into their own branches.
|
||||||
|
|
||||||
|
// Function calls should account for a relatively larger portion of statements.
|
||||||
|
if let Stmt::FnCall(x, pos) = stmt {
|
||||||
|
#[cfg(not(feature = "unchecked"))]
|
||||||
|
self.inc_operations(&mut global.num_operations, stmt.position())?;
|
||||||
|
|
||||||
|
return self.eval_fn_call_expr(scope, global, state, lib, this_ptr, x, *pos, level);
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(not(feature = "unchecked"))]
|
#[cfg(not(feature = "unchecked"))]
|
||||||
self.inc_operations(&mut global.num_operations, stmt.position())?;
|
self.inc_operations(&mut global.num_operations, stmt.position())?;
|
||||||
|
|
||||||
let result = match stmt {
|
match stmt {
|
||||||
// No-op
|
// No-op
|
||||||
Stmt::Noop(_) => Ok(Dynamic::UNIT),
|
Stmt::Noop(_) => Ok(Dynamic::UNIT),
|
||||||
|
|
||||||
@ -3124,11 +3154,6 @@ impl Engine {
|
|||||||
Err(ERR::LoopBreak(options.contains(AST_OPTION_BREAK_OUT), *pos).into())
|
Err(ERR::LoopBreak(options.contains(AST_OPTION_BREAK_OUT), *pos).into())
|
||||||
}
|
}
|
||||||
|
|
||||||
// Function call
|
|
||||||
Stmt::FnCall(x, pos) => {
|
|
||||||
self.eval_fn_call_expr(scope, global, state, lib, this_ptr, x, *pos, level)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Try/Catch statement
|
// Try/Catch statement
|
||||||
Stmt::TryCatch(x, _) => {
|
Stmt::TryCatch(x, _) => {
|
||||||
let (try_stmt, err_var, catch_stmt) = x.as_ref();
|
let (try_stmt, err_var, catch_stmt) = x.as_ref();
|
||||||
@ -3364,9 +3389,9 @@ impl Engine {
|
|||||||
}
|
}
|
||||||
Ok(Dynamic::UNIT)
|
Ok(Dynamic::UNIT)
|
||||||
}
|
}
|
||||||
};
|
|
||||||
|
|
||||||
self.check_return_value(result, stmt.position())
|
_ => unreachable!("statement cannot be evaluated: {:?}", stmt),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Check a result to ensure that the data size is within allowable limit.
|
/// Check a result to ensure that the data size is within allowable limit.
|
||||||
@ -3511,7 +3536,6 @@ impl Engine {
|
|||||||
|
|
||||||
/// Check whether the size of a [`Dynamic`] is within limits.
|
/// Check whether the size of a [`Dynamic`] is within limits.
|
||||||
#[cfg(not(feature = "unchecked"))]
|
#[cfg(not(feature = "unchecked"))]
|
||||||
#[inline]
|
|
||||||
fn check_data_size(&self, value: &Dynamic, pos: Position) -> RhaiResultOf<()> {
|
fn check_data_size(&self, value: &Dynamic, pos: Position) -> RhaiResultOf<()> {
|
||||||
// If no data size limits, just return
|
// If no data size limits, just return
|
||||||
if !self.has_data_size_limit() {
|
if !self.has_data_size_limit() {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user