diff --git a/src/api/mod.rs b/src/api/mod.rs index c296c81e..5f85f140 100644 --- a/src/api/mod.rs +++ b/src/api/mod.rs @@ -35,9 +35,6 @@ pub mod definitions; use crate::{Dynamic, Engine, Identifier}; -#[cfg(not(feature = "no_custom_syntax"))] -use crate::{engine::Precedence, tokenizer::Token}; - #[cfg(feature = "no_std")] use std::prelude::v1::*; @@ -150,8 +147,10 @@ impl Engine { keyword: impl AsRef, precedence: u8, ) -> Result<&mut Self, String> { - let precedence = - Precedence::new(precedence).ok_or_else(|| "precedence cannot be zero".to_string())?; + use crate::tokenizer::Token; + + let precedence = crate::engine::Precedence::new(precedence) + .ok_or_else(|| "precedence cannot be zero".to_string())?; let keyword = keyword.as_ref(); @@ -215,3 +214,71 @@ impl Engine { self } } + +#[cfg(feature = "unchecked")] +impl Engine { + /// The maximum levels of function calls allowed for a script. + /// + /// Always returns [`usize::MAX`] under `unchecked`. + #[inline(always)] + #[must_use] + pub const fn max_call_levels(&self) -> usize { + usize::MAX + } + /// The maximum number of operations allowed for a script to run (0 for unlimited). + /// + /// Always returns zero under `unchecked`. + #[inline(always)] + #[must_use] + pub const fn max_operations(&self) -> u64 { + 0 + } + /// The maximum number of imported [modules][crate::Module] allowed for a script. + /// + /// Always returns [`usize::MAX`] under `unchecked`. + #[inline(always)] + #[must_use] + pub const fn max_modules(&self) -> usize { + usize::MAX + } + /// The depth limit for expressions (0 for unlimited). + /// + /// Always returns zero under `unchecked`. + #[inline(always)] + #[must_use] + pub const fn max_expr_depth(&self) -> usize { + 0 + } + /// The depth limit for expressions in functions (0 for unlimited). + /// + /// Always returns zero under `unchecked`. + #[inline(always)] + #[must_use] + pub const fn max_function_expr_depth(&self) -> usize { + 0 + } + /// The maximum length of [strings][crate::ImmutableString] (0 for unlimited). + /// + /// Always returns zero under `unchecked`. + #[inline(always)] + #[must_use] + pub const fn max_string_size(&self) -> usize { + 0 + } + /// The maximum length of [arrays][crate::Array] (0 for unlimited). + /// + /// Always returns zero under `unchecked`. + #[inline(always)] + #[must_use] + pub const fn max_array_size(&self) -> usize { + 0 + } + /// The maximum size of [object maps][crate::Map] (0 for unlimited). + /// + /// Always returns zero under `unchecked`. + #[inline(always)] + #[must_use] + pub const fn max_map_size(&self) -> usize { + 0 + } +} diff --git a/src/ast/expr.rs b/src/ast/expr.rs index 4adaaecf..72d866fc 100644 --- a/src/ast/expr.rs +++ b/src/ast/expr.rs @@ -212,19 +212,19 @@ impl fmt::Debug for FnCallExpr { if !self.namespace.is_empty() { ff.field("namespace", &self.namespace); } - if self.capture_parent_scope { - ff.field("capture_parent_scope", &self.capture_parent_scope); - } + ff.field("hash", &self.hashes) + .field("name", &self.name) + .field("args", &self.args); if let Some(ref token) = self.operator_token { ff.field("operator_token", token); } + if self.capture_parent_scope { + ff.field("capture_parent_scope", &self.capture_parent_scope); + } #[cfg(not(feature = "no_function"))] if self.can_be_script { ff.field("can_be_script", &self.can_be_script); } - ff.field("hash", &self.hashes) - .field("name", &self.name) - .field("args", &self.args); ff.field("pos", &self.pos); ff.finish() } diff --git a/src/engine.rs b/src/engine.rs index 323f05b5..8edc62ff 100644 --- a/src/engine.rs +++ b/src/engine.rs @@ -9,8 +9,7 @@ use crate::packages::{Package, StandardPackage}; use crate::tokenizer::Token; use crate::types::StringsInterner; use crate::{ - Dynamic, Identifier, ImmutableString, Locked, Module, OptimizationLevel, Position, RhaiResult, - Shared, StaticVec, + Dynamic, Identifier, ImmutableString, Locked, Module, OptimizationLevel, Shared, StaticVec, }; #[cfg(feature = "no_std")] use std::prelude::v1::*; @@ -345,93 +344,4 @@ impl Engine { pub fn const_empty_string(&self) -> ImmutableString { self.get_interned_string("") } - - /// Check a result to ensure that it is valid. - #[cfg(not(feature = "unchecked"))] - #[inline] - pub(crate) fn check_return_value(&self, result: RhaiResult, _pos: Position) -> RhaiResult { - if let Ok(ref r) = result { - self.check_data_size(r, _pos)?; - } - - result - } -} - -#[cfg(feature = "unchecked")] -impl Engine { - /// The maximum levels of function calls allowed for a script. - #[inline(always)] - #[must_use] - pub const fn max_call_levels(&self) -> usize { - usize::MAX - } - /// The maximum number of operations allowed for a script to run (0 for unlimited). - #[inline(always)] - #[must_use] - pub const fn max_operations(&self) -> u64 { - 0 - } - /// The maximum number of imported [modules][crate::Module] allowed for a script. - #[inline(always)] - #[must_use] - pub const fn max_modules(&self) -> usize { - usize::MAX - } - /// The depth limit for expressions (0 for unlimited). - #[inline(always)] - #[must_use] - pub const fn max_expr_depth(&self) -> usize { - 0 - } - /// The depth limit for expressions in functions (0 for unlimited). - #[inline(always)] - #[must_use] - pub const fn max_function_expr_depth(&self) -> usize { - 0 - } - /// The maximum length of [strings][crate::ImmutableString] (0 for unlimited). - #[inline(always)] - #[must_use] - pub const fn max_string_size(&self) -> usize { - 0 - } - /// The maximum length of [arrays][crate::Array] (0 for unlimited). - #[inline(always)] - #[must_use] - pub const fn max_array_size(&self) -> usize { - 0 - } - /// The maximum size of [object maps][crate::Map] (0 for unlimited). - #[inline(always)] - #[must_use] - pub const fn max_map_size(&self) -> usize { - 0 - } - - /// Check if the number of operations stay within limit. - #[inline(always)] - pub(crate) const fn track_operation( - &self, - _: &crate::eval::GlobalRuntimeState, - _: Position, - ) -> crate::RhaiResultOf<()> { - Ok(()) - } - - /// Check whether the size of a [`Dynamic`] is within limits. - #[inline(always)] - pub(crate) const fn check_data_size( - &self, - _: &Dynamic, - _: Position, - ) -> crate::RhaiResultOf<()> { - Ok(()) - } - - /// Check a result to ensure that it is valid. - #[inline(always)] - pub(crate) const fn check_return_value(&self, result: RhaiResult, _: Position) -> RhaiResult { - result - } } diff --git a/src/eval/data_check.rs b/src/eval/data_check.rs index 76cf7a5c..bc8953ca 100644 --- a/src/eval/data_check.rs +++ b/src/eval/data_check.rs @@ -3,7 +3,7 @@ use super::GlobalRuntimeState; use crate::types::dynamic::Union; -use crate::{Dynamic, Engine, Position, RhaiResultOf, ERR}; +use crate::{Dynamic, Engine, Position, RhaiResult, RhaiResultOf, ERR}; #[cfg(feature = "no_std")] use std::prelude::v1::*; @@ -150,4 +150,14 @@ impl Engine { Ok(()) } + + /// Check a result to ensure that it is valid. + #[inline] + pub(crate) fn check_return_value(&self, result: RhaiResult, pos: Position) -> RhaiResult { + if let Ok(ref r) = result { + self.check_data_size(r, pos)?; + } + + result + } } diff --git a/src/eval/mod.rs b/src/eval/mod.rs index 2daf2432..1daf85ae 100644 --- a/src/eval/mod.rs +++ b/src/eval/mod.rs @@ -22,3 +22,36 @@ pub use eval_context::EvalContext; pub use global_state::GlobalConstants; pub use global_state::GlobalRuntimeState; pub use target::{calc_index, calc_offset_len, Target}; + +#[cfg(feature = "unchecked")] +mod unchecked { + use crate::{eval::GlobalRuntimeState, Dynamic, Engine, Position, RhaiResult, RhaiResultOf}; + + impl Engine { + /// Check if the number of operations stay within limit. + #[inline(always)] + pub(crate) const fn track_operation( + &self, + _: &GlobalRuntimeState, + _: Position, + ) -> RhaiResultOf<()> { + Ok(()) + } + + /// Check whether the size of a [`Dynamic`] is within limits. + #[inline(always)] + pub(crate) const fn check_data_size(&self, _: &Dynamic, _: Position) -> RhaiResultOf<()> { + Ok(()) + } + + /// Check a result to ensure that it is valid. + #[inline(always)] + pub(crate) const fn check_return_value( + &self, + result: RhaiResult, + _: Position, + ) -> RhaiResult { + result + } + } +} diff --git a/src/optimizer.rs b/src/optimizer.rs index dea68ea3..20145659 100644 --- a/src/optimizer.rs +++ b/src/optimizer.rs @@ -175,21 +175,26 @@ fn has_native_fn_override( // First check the global namespace and packages, but skip modules that are standard because // they should never conflict with system functions. - let result = engine + if engine .global_modules .iter() .filter(|m| !m.standard) - .any(|m| m.contains_fn(hash)); + .any(|m| m.contains_fn(hash)) + { + return true; + } - #[cfg(not(feature = "no_module"))] // Then check sub-modules - let result = result - || engine - .global_sub_modules - .values() - .any(|m| m.contains_qualified_fn(hash)); + #[cfg(not(feature = "no_module"))] + if engine + .global_sub_modules + .values() + .any(|m| m.contains_qualified_fn(hash)) + { + return true; + } - result + false } /// Optimize a block of [statements][Stmt].