Use SmartString for buffers and literal_syntax can panic.
This commit is contained in:
@@ -317,7 +317,7 @@ impl Engine {
|
||||
scope: &mut Scope,
|
||||
this_ptr: &mut Dynamic,
|
||||
expr: &Expr,
|
||||
new_val: &mut Option<(Dynamic, &OpAssignment)>,
|
||||
new_val: Option<(Dynamic, &OpAssignment)>,
|
||||
) -> RhaiResult {
|
||||
let chain_type = ChainType::from(expr);
|
||||
|
||||
@@ -507,7 +507,7 @@ impl Engine {
|
||||
target: &mut Target,
|
||||
rhs: &Expr,
|
||||
idx_values: &mut FnArgsVec<Dynamic>,
|
||||
new_val: &mut Option<(Dynamic, &OpAssignment)>,
|
||||
new_val: Option<(Dynamic, &OpAssignment)>,
|
||||
) -> RhaiResultOf<(Dynamic, bool)> {
|
||||
let is_ref_mut = target.is_ref();
|
||||
let op_pos = parent.position();
|
||||
@@ -576,7 +576,7 @@ impl Engine {
|
||||
#[cfg(feature = "debugging")]
|
||||
self.run_debugger(global, caches, scope, this_ptr, parent)?;
|
||||
|
||||
let (new_val, op_info) = new_val.take().expect("`Some`");
|
||||
let (new_val, op_info) = new_val.expect("`Some`");
|
||||
let idx_val = &mut idx_values.pop().unwrap();
|
||||
let idx = &mut idx_val.clone();
|
||||
|
||||
@@ -686,12 +686,12 @@ impl Engine {
|
||||
unreachable!("function call in dot chain should not be namespace-qualified")
|
||||
}
|
||||
// {xxx:map}.id op= ???
|
||||
Expr::Property(x, pos) if target.is_map() && new_val.is_some() => {
|
||||
Expr::Property(x, pos) if new_val.is_some() && target.is_map() => {
|
||||
#[cfg(feature = "debugging")]
|
||||
self.run_debugger(global, caches, scope, this_ptr, rhs)?;
|
||||
|
||||
let index = &mut x.2.clone().into();
|
||||
let (new_val, op_info) = new_val.take().expect("`Some`");
|
||||
let (new_val, op_info) = new_val.expect("`Some`");
|
||||
{
|
||||
let val_target = &mut self.get_indexed_mut(
|
||||
global, caches, target, index, *pos, op_pos, true, false,
|
||||
@@ -720,7 +720,7 @@ impl Engine {
|
||||
self.run_debugger(global, caches, scope, this_ptr, rhs)?;
|
||||
|
||||
let ((getter, hash_get), (setter, hash_set), name) = &**x;
|
||||
let (mut new_val, op_info) = new_val.take().expect("`Some`");
|
||||
let (mut new_val, op_info) = new_val.expect("`Some`");
|
||||
|
||||
if op_info.is_op_assignment() {
|
||||
let args = &mut [target.as_mut()];
|
||||
|
@@ -8,7 +8,7 @@ use std::borrow::Borrow;
|
||||
#[cfg(feature = "no_std")]
|
||||
use std::prelude::v1::*;
|
||||
|
||||
impl Engine {
|
||||
impl Dynamic {
|
||||
/// Recursively calculate the sizes of a value.
|
||||
///
|
||||
/// Sizes returned are `(` [`Array`][crate::Array], [`Map`][crate::Map] and [`String`] `)`.
|
||||
@@ -16,20 +16,20 @@ impl Engine {
|
||||
/// # Panics
|
||||
///
|
||||
/// Panics if any interior data is shared (should never happen).
|
||||
pub(crate) fn calc_data_sizes(value: &Dynamic, _top: bool) -> (usize, usize, usize) {
|
||||
match value.0 {
|
||||
pub(crate) fn calc_data_sizes(&self, _top: bool) -> (usize, usize, usize) {
|
||||
match self.0 {
|
||||
#[cfg(not(feature = "no_index"))]
|
||||
Union::Array(ref arr, ..) => {
|
||||
arr.iter()
|
||||
.fold((0, 0, 0), |(ax, mx, sx), value| match value.0 {
|
||||
Union::Array(..) => {
|
||||
let (a, m, s) = Self::calc_data_sizes(value, false);
|
||||
let (a, m, s) = value.calc_data_sizes(false);
|
||||
(ax + a + 1, mx + m, sx + s)
|
||||
}
|
||||
Union::Blob(ref a, ..) => (ax + 1 + a.len(), mx, sx),
|
||||
#[cfg(not(feature = "no_object"))]
|
||||
Union::Map(..) => {
|
||||
let (a, m, s) = Self::calc_data_sizes(value, false);
|
||||
let (a, m, s) = value.calc_data_sizes(false);
|
||||
(ax + a + 1, mx + m, sx + s)
|
||||
}
|
||||
Union::Str(ref s, ..) => (ax + 1, mx, sx + s.len()),
|
||||
@@ -44,13 +44,13 @@ impl Engine {
|
||||
.fold((0, 0, 0), |(ax, mx, sx), value| match value.0 {
|
||||
#[cfg(not(feature = "no_index"))]
|
||||
Union::Array(..) => {
|
||||
let (a, m, s) = Self::calc_data_sizes(value, false);
|
||||
let (a, m, s) = value.calc_data_sizes(false);
|
||||
(ax + a, mx + m + 1, sx + s)
|
||||
}
|
||||
#[cfg(not(feature = "no_index"))]
|
||||
Union::Blob(ref a, ..) => (ax + a.len(), mx, sx),
|
||||
Union::Map(..) => {
|
||||
let (a, m, s) = Self::calc_data_sizes(value, false);
|
||||
let (a, m, s) = value.calc_data_sizes(false);
|
||||
(ax + a, mx + m + 1, sx + s)
|
||||
}
|
||||
Union::Str(ref s, ..) => (ax, mx + 1, sx + s.len()),
|
||||
@@ -59,17 +59,17 @@ impl Engine {
|
||||
}
|
||||
Union::Str(ref s, ..) => (0, 0, s.len()),
|
||||
#[cfg(not(feature = "no_closure"))]
|
||||
Union::Shared(..) if _top => {
|
||||
Self::calc_data_sizes(&*value.read_lock::<Dynamic>().unwrap(), true)
|
||||
}
|
||||
Union::Shared(..) if _top => self.read_lock::<Dynamic>().unwrap().calc_data_sizes(true),
|
||||
#[cfg(not(feature = "no_closure"))]
|
||||
Union::Shared(..) => {
|
||||
unreachable!("shared values discovered within data: {}", value)
|
||||
unreachable!("shared values discovered within data: {}", self)
|
||||
}
|
||||
_ => (0, 0, 0),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Engine {
|
||||
/// Raise an error if any data size exceeds limit.
|
||||
///
|
||||
/// [`Position`] in [`EvalAltResult`][crate::EvalAltResult] is always [`NONE`][Position::NONE]
|
||||
@@ -125,7 +125,7 @@ impl Engine {
|
||||
return Ok(value);
|
||||
}
|
||||
|
||||
let sizes = Self::calc_data_sizes(value.borrow(), true);
|
||||
let sizes = value.borrow().calc_data_sizes(true);
|
||||
|
||||
self.raise_err_if_over_data_size_limit(sizes)
|
||||
.map(|_| value)
|
||||
|
@@ -307,7 +307,7 @@ impl Engine {
|
||||
|
||||
#[cfg(not(feature = "unchecked"))]
|
||||
if self.has_data_size_limit() {
|
||||
let val_sizes = Self::calc_data_sizes(&value, true);
|
||||
let val_sizes = value.calc_data_sizes(true);
|
||||
|
||||
total_data_sizes = (
|
||||
total_data_sizes.0 + val_sizes.0,
|
||||
@@ -339,7 +339,7 @@ impl Engine {
|
||||
|
||||
#[cfg(not(feature = "unchecked"))]
|
||||
if self.has_data_size_limit() {
|
||||
let delta = Self::calc_data_sizes(&value, true);
|
||||
let delta = value.calc_data_sizes(true);
|
||||
total_data_sizes = (
|
||||
total_data_sizes.0 + delta.0,
|
||||
total_data_sizes.1 + delta.1,
|
||||
@@ -411,13 +411,11 @@ impl Engine {
|
||||
|
||||
#[cfg(not(feature = "no_index"))]
|
||||
Expr::Index(..) => {
|
||||
self.eval_dot_index_chain(global, caches, scope, this_ptr, expr, &mut None)
|
||||
self.eval_dot_index_chain(global, caches, scope, this_ptr, expr, None)
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "no_object"))]
|
||||
Expr::Dot(..) => {
|
||||
self.eval_dot_index_chain(global, caches, scope, this_ptr, expr, &mut None)
|
||||
}
|
||||
Expr::Dot(..) => self.eval_dot_index_chain(global, caches, scope, this_ptr, expr, None),
|
||||
|
||||
_ => unreachable!("expression cannot be evaluated: {:?}", expr),
|
||||
}
|
||||
|
@@ -21,7 +21,9 @@ pub use eval_context::EvalContext;
|
||||
#[cfg(not(feature = "no_function"))]
|
||||
pub use global_state::GlobalConstants;
|
||||
pub use global_state::GlobalRuntimeState;
|
||||
pub use target::{calc_index, calc_offset_len, Target};
|
||||
#[cfg(not(feature = "no_index"))]
|
||||
pub use target::calc_offset_len;
|
||||
pub use target::{calc_index, Target};
|
||||
|
||||
#[cfg(feature = "unchecked")]
|
||||
mod unchecked {
|
||||
|
@@ -258,7 +258,7 @@ impl Engine {
|
||||
rhs_val = self.get_interned_string(value).into();
|
||||
}
|
||||
|
||||
let _new_val = &mut Some((rhs_val, op_info));
|
||||
let _new_val = Some((rhs_val, op_info));
|
||||
|
||||
// Must be either `var[index] op= val` or `var.prop op= val`
|
||||
match lhs {
|
||||
|
@@ -13,8 +13,8 @@ use std::{
|
||||
/// Negative starting positions count from the end.
|
||||
///
|
||||
/// Values going over bounds are limited to the actual length.
|
||||
#[cfg(not(feature = "no_index"))]
|
||||
#[inline]
|
||||
#[allow(dead_code)]
|
||||
pub fn calc_offset_len(length: usize, start: crate::INT, len: crate::INT) -> (usize, usize) {
|
||||
let start = if start < 0 {
|
||||
let abs_start = start.unsigned_abs();
|
||||
|
Reference in New Issue
Block a user