Remove unnecessary unchecked gates.

This commit is contained in:
Stephen Chung
2022-10-05 15:07:54 +08:00
parent 80f95b6f2a
commit 42c0eeed57
12 changed files with 178 additions and 211 deletions

View File

@@ -131,7 +131,6 @@ impl Engine {
self.eval_op_assignment(
global, caches, lib, op_info, obj_ptr, root, new_val, level,
)?;
#[cfg(not(feature = "unchecked"))]
self.check_data_size(obj_ptr, op_info.pos)?;
None
}
@@ -159,7 +158,6 @@ impl Engine {
)?;
// Replace new value
new_val = val.take_or_clone();
#[cfg(not(feature = "unchecked"))]
self.check_data_size(&new_val, op_info.pos)?;
}
}
@@ -246,7 +244,6 @@ impl Engine {
global, caches, lib, op_info, val_target, root, new_val, level,
)?;
}
#[cfg(not(feature = "unchecked"))]
self.check_data_size(target.source(), op_info.pos)?;
Ok((Dynamic::UNIT, true))
}
@@ -606,9 +603,7 @@ impl Engine {
Expr::Variable(x, .., var_pos) => {
#[cfg(feature = "debugging")]
self.run_debugger(scope, global, lib, this_ptr, lhs, level)?;
#[cfg(not(feature = "unchecked"))]
self.inc_operations(&mut global.num_operations, *var_pos)?;
self.track_operation(global, *var_pos)?;
let (mut target, ..) =
self.search_namespace(scope, global, lib, this_ptr, lhs, level)?;
@@ -655,8 +650,7 @@ impl Engine {
idx_values: &mut FnArgsVec<Dynamic>,
level: usize,
) -> RhaiResultOf<()> {
#[cfg(not(feature = "unchecked"))]
self.inc_operations(&mut global.num_operations, expr.position())?;
self.track_operation(global, expr.position())?;
match expr {
#[cfg(not(feature = "no_object"))]
@@ -814,8 +808,7 @@ impl Engine {
use_indexers: bool,
level: usize,
) -> RhaiResultOf<Target<'t>> {
#[cfg(not(feature = "unchecked"))]
self.inc_operations(&mut global.num_operations, Position::NONE)?;
self.track_operation(global, Position::NONE)?;
match target {
#[cfg(not(feature = "no_index"))]

View File

@@ -1,6 +1,7 @@
//! Data size checks during evaluation.
#![cfg(not(feature = "unchecked"))]
use super::GlobalRuntimeState;
use crate::types::dynamic::Union;
use crate::{Dynamic, Engine, Position, RhaiResultOf, ERR};
use std::num::NonZeroUsize;
@@ -15,7 +16,6 @@ impl Engine {
/// # Panics
///
/// Panics if any interior data is shared (should never happen).
#[cfg(not(feature = "unchecked"))]
pub(crate) fn calc_data_sizes(value: &Dynamic, _top: bool) -> (usize, usize, usize) {
match value.0 {
#[cfg(not(feature = "no_index"))]
@@ -71,24 +71,11 @@ impl Engine {
}
/// Is there a data size limit set?
#[cfg(not(feature = "unchecked"))]
pub(crate) const fn has_data_size_limit(&self) -> bool {
let mut _limited = self.limits.max_string_size.is_some();
#[cfg(not(feature = "no_index"))]
{
_limited = _limited || self.limits.max_array_size.is_some();
}
#[cfg(not(feature = "no_object"))]
{
_limited = _limited || self.limits.max_map_size.is_some();
}
_limited
self.max_string_size() > 0 || self.max_array_size() > 0 || self.max_map_size() > 0
}
/// Raise an error if any data size exceeds limit.
#[cfg(not(feature = "unchecked"))]
pub(crate) fn raise_err_if_over_data_size_limit(
&self,
sizes: (usize, usize, usize),
@@ -128,7 +115,6 @@ impl Engine {
}
/// Check whether the size of a [`Dynamic`] is within limits.
#[cfg(not(feature = "unchecked"))]
pub(crate) fn check_data_size(&self, value: &Dynamic, pos: Position) -> RhaiResultOf<()> {
// If no data size limits, just return
if !self.has_data_size_limit() {
@@ -143,29 +129,30 @@ impl Engine {
/// Raise an error if the size of a [`Dynamic`] is out of limits (if any).
///
/// Not available under `unchecked`.
#[cfg(not(feature = "unchecked"))]
#[inline(always)]
pub fn ensure_data_size_within_limits(&self, value: &Dynamic) -> RhaiResultOf<()> {
self.check_data_size(value, Position::NONE)
}
/// Check if the number of operations stay within limit.
#[cfg(not(feature = "unchecked"))]
pub(crate) fn inc_operations(
pub(crate) fn track_operation(
&self,
num_operations: &mut u64,
global: &mut GlobalRuntimeState,
pos: Position,
) -> RhaiResultOf<()> {
*num_operations += 1;
global.num_operations += 1;
// Guard against too many operations
if self.max_operations() > 0 && *num_operations > self.max_operations() {
let max = self.max_operations();
let num_operations = global.num_operations;
if max > 0 && num_operations > max {
return Err(ERR::ErrorTooManyOperations(pos).into());
}
// Report progress - only in steps
if let Some(ref progress) = self.progress {
if let Some(token) = progress(*num_operations) {
if let Some(token) = progress(num_operations) {
// Terminate script if progress returns a termination token
return Err(ERR::ErrorTerminated(token, pos).into());
}

View File

@@ -318,8 +318,7 @@ impl Engine {
let reset_debugger =
self.run_debugger_with_reset(scope, global, lib, this_ptr, expr, level)?;
#[cfg(not(feature = "unchecked"))]
self.inc_operations(&mut global.num_operations, expr.position())?;
self.track_operation(global, expr.position())?;
let result =
self.eval_fn_call_expr(scope, global, caches, lib, this_ptr, x, x.pos, level);
@@ -337,8 +336,7 @@ impl Engine {
#[cfg(feature = "debugging")]
self.run_debugger(scope, global, lib, this_ptr, expr, level)?;
#[cfg(not(feature = "unchecked"))]
self.inc_operations(&mut global.num_operations, expr.position())?;
self.track_operation(global, expr.position())?;
return if index.is_none() && x.0.is_none() && x.3 == KEYWORD_THIS {
this_ptr
@@ -355,8 +353,7 @@ impl Engine {
let reset_debugger =
self.run_debugger_with_reset(scope, global, lib, this_ptr, expr, level)?;
#[cfg(not(feature = "unchecked"))]
self.inc_operations(&mut global.num_operations, expr.position())?;
self.track_operation(global, expr.position())?;
let result = match expr {
// Constants
@@ -410,7 +407,7 @@ impl Engine {
let mut result = Ok(Dynamic::UNIT);
#[cfg(not(feature = "unchecked"))]
let mut sizes = (0, 0, 0);
let mut total_data_sizes = (0, 0, 0);
for item_expr in &**x {
let value = match self
@@ -424,19 +421,21 @@ impl Engine {
};
#[cfg(not(feature = "unchecked"))]
let val_sizes = Self::calc_data_sizes(&value, true);
if self.has_data_size_limit() {
let val_sizes = Self::calc_data_sizes(&value, true);
total_data_sizes = (
total_data_sizes.0 + val_sizes.0,
total_data_sizes.1 + val_sizes.1,
total_data_sizes.2 + val_sizes.2,
);
self.raise_err_if_over_data_size_limit(
total_data_sizes,
item_expr.position(),
)?;
}
array.push(value);
#[cfg(not(feature = "unchecked"))]
if self.has_data_size_limit() {
sizes = (
sizes.0 + val_sizes.0,
sizes.1 + val_sizes.1,
sizes.2 + val_sizes.2,
);
self.raise_err_if_over_data_size_limit(sizes, item_expr.position())?;
}
}
result.map(|_| array.into())
@@ -448,7 +447,7 @@ impl Engine {
let mut result = Ok(Dynamic::UNIT);
#[cfg(not(feature = "unchecked"))]
let mut sizes = (0, 0, 0);
let mut total_data_sizes = (0, 0, 0);
for (key, value_expr) in &x.0 {
let value = match self
@@ -462,15 +461,20 @@ impl Engine {
};
#[cfg(not(feature = "unchecked"))]
let delta = Self::calc_data_sizes(&value, true);
if self.has_data_size_limit() {
let delta = Self::calc_data_sizes(&value, true);
total_data_sizes = (
total_data_sizes.0 + delta.0,
total_data_sizes.1 + delta.1,
total_data_sizes.2 + delta.2,
);
self.raise_err_if_over_data_size_limit(
total_data_sizes,
value_expr.position(),
)?;
}
*map.get_mut(key.as_str()).unwrap() = value;
#[cfg(not(feature = "unchecked"))]
if self.has_data_size_limit() {
sizes = (sizes.0 + delta.0, sizes.1 + delta.1, sizes.2 + delta.2);
self.raise_err_if_over_data_size_limit(sizes, value_expr.position())?;
}
}
result.map(|_| map.into())

View File

@@ -152,7 +152,6 @@ impl Engine {
let context = (self, op, None, &*global, lib, *op_pos, level).into();
let result = func(context, args).map(|_| ());
#[cfg(not(feature = "unchecked"))]
self.check_data_size(args[0], root.1)?;
return result;
@@ -165,10 +164,7 @@ impl Engine {
match self.call_native_fn(
global, caches, lib, op_assign, hash, args, true, true, *op_pos, level,
) {
Ok(_) => {
#[cfg(not(feature = "unchecked"))]
self.check_data_size(args[0], root.1)?;
}
Ok(_) => self.check_data_size(args[0], root.1)?,
Err(err) if matches!(*err, ERR::ErrorFunctionNotFound(ref f, ..) if f.starts_with(op_assign)) =>
{
// Expand to `var = var op rhs`
@@ -218,8 +214,7 @@ impl Engine {
// Function calls should account for a relatively larger portion of statements.
if let Stmt::FnCall(x, ..) = stmt {
#[cfg(not(feature = "unchecked"))]
self.inc_operations(&mut global.num_operations, stmt.position())?;
self.track_operation(global, stmt.position())?;
let result =
self.eval_fn_call_expr(scope, global, caches, lib, this_ptr, x, x.pos, level);
@@ -236,8 +231,7 @@ impl Engine {
if let Stmt::Assignment(x, ..) = stmt {
let (op_info, BinaryExpr { lhs, rhs }) = &**x;
#[cfg(not(feature = "unchecked"))]
self.inc_operations(&mut global.num_operations, stmt.position())?;
self.track_operation(global, stmt.position())?;
let result = if let Expr::Variable(x, ..) = lhs {
let rhs_result = self
@@ -267,8 +261,7 @@ impl Engine {
);
}
#[cfg(not(feature = "unchecked"))]
self.inc_operations(&mut global.num_operations, pos)?;
self.track_operation(global, pos)?;
let root = (var_name, pos);
let lhs_ptr = &mut lhs_ptr;
@@ -339,8 +332,7 @@ impl Engine {
return result;
}
#[cfg(not(feature = "unchecked"))]
self.inc_operations(&mut global.num_operations, stmt.position())?;
self.track_operation(global, stmt.position())?;
let result = match stmt {
// No-op
@@ -512,8 +504,7 @@ impl Engine {
let (.., body) = &**x;
if body.is_empty() {
#[cfg(not(feature = "unchecked"))]
self.inc_operations(&mut global.num_operations, body.position())?;
self.track_operation(global, body.position())?;
} else {
match self
.eval_stmt_block(scope, global, caches, lib, this_ptr, body, true, level)
@@ -668,10 +659,7 @@ impl Engine {
*scope.get_mut_by_index(index).write_lock().unwrap() = value;
#[cfg(not(feature = "unchecked"))]
if let Err(err) = self
.inc_operations(&mut global.num_operations, statements.position())
{
if let Err(err) = self.track_operation(global, statements.position()) {
loop_result = Err(err);
break;
}