Skip to content

Commit

Permalink
Merge pull request #687 from schungx/master
Browse files Browse the repository at this point in the history
Prepare for release.
  • Loading branch information
schungx committed Dec 30, 2022
2 parents 8805f02 + a478d57 commit 4c2630b
Show file tree
Hide file tree
Showing 10 changed files with 201 additions and 186 deletions.
4 changes: 3 additions & 1 deletion src/api/deprecated.rs
@@ -1,7 +1,6 @@
//! Module containing all deprecated API that will be removed in the next major version.

use crate::func::RegisterNativeFunction;
use crate::plugin::*;
use crate::types::dynamic::Variant;
use crate::{
Dynamic, Engine, EvalAltResult, FnPtr, Identifier, ImmutableString, Module, NativeCallContext,
Expand Down Expand Up @@ -633,6 +632,9 @@ impl Module {
}
}

#[cfg(not(feature = "no_index"))]
use crate::plugin::*;

#[cfg(not(feature = "no_index"))]
#[export_module]
pub mod deprecated_array_functions {
Expand Down
12 changes: 7 additions & 5 deletions src/ast/expr.rs
Expand Up @@ -489,11 +489,13 @@ impl Expr {

#[cfg(not(feature = "no_object"))]
Self::Map(x, ..) if self.is_constant() => {
Dynamic::from_map(x.0.iter().fold(x.1.clone(), |mut map, (k, v)| {
let value_ref = map.get_mut(k.name.as_str()).unwrap();
*value_ref = v.get_literal_value().unwrap();
map
}))
let mut map = x.1.clone();

for (k, v) in &x.0 {
*map.get_mut(k.name.as_str()).unwrap() = v.get_literal_value().unwrap();
}

Dynamic::from_map(map)
}

// Interpolated string
Expand Down
87 changes: 58 additions & 29 deletions src/eval/data_check.rs
Expand Up @@ -18,23 +18,37 @@ impl Dynamic {
/// Panics if any interior data is shared (should never happen).
#[cfg(not(feature = "no_index"))]
#[inline]
pub(crate) fn calc_array_sizes(array: &crate::Array, _top: bool) -> (usize, usize, usize) {
array
.iter()
.fold((0, 0, 0), |(ax, mx, sx), value| match value.0 {
Union::Array(..) => {
let (a, m, s) = value.calc_data_sizes(false);
(ax + a + 1, mx + m, sx + s)
pub(crate) fn calc_array_sizes(array: &crate::Array) -> (usize, usize, usize) {
let (mut ax, mut mx, mut sx) = (0, 0, 0);

for value in array {
ax += 1;

match value.0 {
Union::Array(ref a, ..) => {
let (a, m, s) = Self::calc_array_sizes(a);
ax += a;
mx += m;
sx += s;
}
Union::Blob(ref a, ..) => (ax + 1 + a.len(), mx, sx),
Union::Blob(ref a, ..) => ax += 1 + a.len(),
#[cfg(not(feature = "no_object"))]
Union::Map(..) => {
let (a, m, s) = value.calc_data_sizes(false);
(ax + a + 1, mx + m, sx + s)
Union::Map(ref m, ..) => {
let (a, m, s) = Self::calc_map_sizes(m);
ax += a;
mx += m;
sx += s;
}
Union::Str(ref s, ..) => sx += s.len(),
#[cfg(not(feature = "no_closure"))]
Union::Shared(..) => {
unreachable!("shared values discovered within data")
}
Union::Str(ref s, ..) => (ax + 1, mx, sx + s.len()),
_ => (ax + 1, mx, sx),
})
_ => (),
}
}

(ax, mx, sx)
}
/// Recursively calculate the sizes of a map.
///
Expand All @@ -45,23 +59,38 @@ impl Dynamic {
/// Panics if any interior data is shared (should never happen).
#[cfg(not(feature = "no_object"))]
#[inline]
pub(crate) fn calc_map_sizes(map: &crate::Map, _top: bool) -> (usize, usize, usize) {
map.values()
.fold((0, 0, 0), |(ax, mx, sx), value| match value.0 {
pub(crate) fn calc_map_sizes(map: &crate::Map) -> (usize, usize, usize) {
let (mut ax, mut mx, mut sx) = (0, 0, 0);

for value in map.values() {
mx += 1;

match value.0 {
#[cfg(not(feature = "no_index"))]
Union::Array(..) => {
let (a, m, s) = value.calc_data_sizes(false);
(ax + a, mx + m + 1, sx + s)
Union::Array(ref a, ..) => {
let (a, m, s) = Self::calc_array_sizes(a);
ax += a;
mx += m;
sx += s;
}
#[cfg(not(feature = "no_index"))]
Union::Blob(ref a, ..) => (ax + a.len(), mx, sx),
Union::Map(..) => {
let (a, m, s) = value.calc_data_sizes(false);
(ax + a, mx + m + 1, sx + s)
Union::Blob(ref a, ..) => ax += 1 + a.len(),
Union::Map(ref m, ..) => {
let (a, m, s) = Self::calc_map_sizes(m);
ax += a;
mx += m;
sx += s;
}
Union::Str(ref s, ..) => sx += s.len(),
#[cfg(not(feature = "no_closure"))]
Union::Shared(..) => {
unreachable!("shared values discovered within data")
}
Union::Str(ref s, ..) => (ax, mx + 1, sx + s.len()),
_ => (ax, mx + 1, sx),
})
_ => (),
}
}

(ax, mx, sx)
}
/// Recursively calculate the sizes of a value.
///
Expand All @@ -74,11 +103,11 @@ impl Dynamic {
pub(crate) fn calc_data_sizes(&self, _top: bool) -> (usize, usize, usize) {
match self.0 {
#[cfg(not(feature = "no_index"))]
Union::Array(ref arr, ..) => Self::calc_array_sizes(&**arr, _top),
Union::Array(ref arr, ..) => Self::calc_array_sizes(&**arr),
#[cfg(not(feature = "no_index"))]
Union::Blob(ref blob, ..) => (blob.len(), 0, 0),
#[cfg(not(feature = "no_object"))]
Union::Map(ref map, ..) => Self::calc_map_sizes(&**map, _top),
Union::Map(ref map, ..) => Self::calc_map_sizes(&**map),
Union::Str(ref s, ..) => (0, 0, s.len()),
#[cfg(not(feature = "no_closure"))]
Union::Shared(..) if _top => self.read_lock::<Self>().unwrap().calc_data_sizes(true),
Expand Down
49 changes: 21 additions & 28 deletions src/eval/expr.rs
Expand Up @@ -286,7 +286,7 @@ impl Engine {
Expr::InterpolatedString(x, _) => {
let mut concat = SmartString::new_const();

x.iter().try_for_each(|expr| -> RhaiResultOf<()> {
for expr in &**x {
let item = &mut self
.eval_expr(global, caches, scope, this_ptr.as_deref_mut(), expr)?
.flatten();
Expand All @@ -304,9 +304,7 @@ impl Engine {
#[cfg(not(feature = "unchecked"))]
self.throw_on_size((0, 0, concat.len()))
.map_err(|err| err.fill_position(pos))?;

Ok(())
})?;
}

Ok(self.get_interned_string(concat).into())
}
Expand All @@ -318,7 +316,7 @@ impl Engine {
#[cfg(not(feature = "unchecked"))]
let mut total_data_sizes = (0, 0, 0);

x.iter().try_for_each(|item_expr| -> RhaiResultOf<()> {
for item_expr in &**x {
let value = self
.eval_expr(global, caches, scope, this_ptr.as_deref_mut(), item_expr)?
.flatten();
Expand All @@ -337,9 +335,7 @@ impl Engine {
}

array.push(value);

Ok(())
})?;
}

Ok(Dynamic::from_array(array))
}
Expand All @@ -351,28 +347,25 @@ impl Engine {
#[cfg(not(feature = "unchecked"))]
let mut total_data_sizes = (0, 0, 0);

x.0.iter()
.try_for_each(|(key, value_expr)| -> RhaiResultOf<()> {
let value = self
.eval_expr(global, caches, scope, this_ptr.as_deref_mut(), value_expr)?
.flatten();

#[cfg(not(feature = "unchecked"))]
if self.has_data_size_limit() {
let delta = value.calc_data_sizes(true);
total_data_sizes = (
total_data_sizes.0 + delta.0,
total_data_sizes.1 + delta.1 + 1,
total_data_sizes.2 + delta.2,
);
self.throw_on_size(total_data_sizes)
.map_err(|err| err.fill_position(value_expr.position()))?;
}
for (key, value_expr) in &x.0 {
let value = self
.eval_expr(global, caches, scope, this_ptr.as_deref_mut(), value_expr)?
.flatten();

*map.get_mut(key.as_str()).unwrap() = value;
#[cfg(not(feature = "unchecked"))]
if self.has_data_size_limit() {
let delta = value.calc_data_sizes(true);
total_data_sizes = (
total_data_sizes.0 + delta.0,
total_data_sizes.1 + delta.1 + 1,
total_data_sizes.2 + delta.2,
);
self.throw_on_size(total_data_sizes)
.map_err(|err| err.fill_position(value_expr.position()))?;
}

Ok(())
})?;
*map.get_mut(key.as_str()).unwrap() = value;
}

Ok(Dynamic::from_map(map))
}
Expand Down
63 changes: 29 additions & 34 deletions src/eval/stmt.rs
Expand Up @@ -129,9 +129,9 @@ impl Engine {
let OpAssignment {
hash_op_assign,
hash_op,
op_assign: op_assign_token,
op: op_token,
pos: op_pos,
op_assign,
op,
pos,
} = op_info;

let mut lock_guard = target.write_lock::<Dynamic>().unwrap();
Expand All @@ -141,39 +141,36 @@ impl Engine {

if self.fast_operators() {
if let Some((func, need_context)) =
get_builtin_op_assignment_fn(op_assign_token.clone(), args[0], args[1])
get_builtin_op_assignment_fn(op_assign.clone(), args[0], args[1])
{
// Built-in found
let op = op_assign_token.literal_syntax();
auto_restore! { let orig_level = global.level; global.level += 1 }

let context = if need_context {
let op = op_assign.literal_syntax();
let source = global.source();
Some((self, op, source, &*global, *op_pos).into())
Some((self, op, source, &*global, *pos).into())
} else {
None
};
return func(context, args).map(|_| ());
}
}

let op_assign = op_assign_token.literal_syntax();
let op = op_token.literal_syntax();
let token = Some(op_assign_token.clone());
let token = Some(op_assign.clone());
let op_assign = op_assign.literal_syntax();

match self
.exec_native_fn_call(global, caches, op_assign, token, hash, args, true, *op_pos)
match self.exec_native_fn_call(global, caches, op_assign, token, hash, args, true, *pos)
{
Ok(_) => (),
Err(err) if matches!(*err, ERR::ErrorFunctionNotFound(ref f, ..) if f.starts_with(op_assign)) =>
{
// Expand to `var = var op rhs`
let token = Some(op_token.clone());
let token = Some(op.clone());
let op = op.literal_syntax();

*args[0] = self
.exec_native_fn_call(
global, caches, op, token, *hash_op, args, true, *op_pos,
)?
.exec_native_fn_call(global, caches, op, token, *hash_op, args, true, *pos)?
.0;
}
Err(err) => return Err(err),
Expand Down Expand Up @@ -864,25 +861,23 @@ impl Engine {
// Share statement
#[cfg(not(feature = "no_closure"))]
Stmt::Share(x) => {
x.iter()
.try_for_each(|(name, index, pos)| {
index
.map(|n| scope.len() - n.get())
.or_else(|| scope.search(name))
.map_or_else(
|| Err(ERR::ErrorVariableNotFound(name.to_string(), *pos).into()),
|index| {
let val = scope.get_mut_by_index(index);

if !val.is_shared() {
// Replace the variable with a shared value.
*val = std::mem::take(val).into_shared();
}
Ok(())
},
)
})
.map(|_| Dynamic::UNIT)
for (name, index, pos) in &**x {
if let Some(index) = index
.map(|n| scope.len() - n.get())
.or_else(|| scope.search(name))
{
let val = scope.get_mut_by_index(index);

if !val.is_shared() {
// Replace the variable with a shared value.
*val = std::mem::take(val).into_shared();
}
} else {
return Err(ERR::ErrorVariableNotFound(name.to_string(), *pos).into());
}
}

Ok(Dynamic::UNIT)
}

_ => unreachable!("statement cannot be evaluated: {:?}", stmt),
Expand Down

0 comments on commit 4c2630b

Please sign in to comment.