diff --git a/README.md b/README.md index c8363ac2..bb4a9256 100644 --- a/README.md +++ b/README.md @@ -26,7 +26,7 @@ Features * Freely pass Rust variables/constants into a script via an external [`Scope`](https://schungx.github.io/rhai/rust/scope.html). * Easily [call a script-defined function](https://schungx.github.io/rhai/engine/call-fn.html) from Rust. * Fairly low compile-time overhead. -* Fairly efficient evaluation (1 million iterations in 0.4 sec on a single core, 2.3 GHz Linux VM). +* Fairly efficient evaluation (1 million iterations in 0.3 sec on a single core, 2.3 GHz Linux VM). * Relatively little `unsafe` code (yes there are some for performance reasons, and most `unsafe` code is limited to one single source file, all with names starting with `"unsafe_"`). * Re-entrant scripting engine can be made `Send + Sync` (via the `sync` feature). diff --git a/doc/src/about/features.md b/doc/src/about/features.md index 3f19bf63..7d3ff3cd 100644 --- a/doc/src/about/features.md +++ b/doc/src/about/features.md @@ -22,7 +22,7 @@ Fast * Fairly low compile-time overhead. -* Fairly efficient evaluation (1 million iterations in 0.4 sec on a single core, 2.3 GHz Linux VM). +* Fairly efficient evaluation (1 million iterations in 0.3 sec on a single core, 2.3 GHz Linux VM). * Scripts are [optimized][script optimization] (useful for template-based machine-generated scripts) for repeated evaluations. diff --git a/src/any.rs b/src/any.rs index 2a2ae5a9..bd21404b 100644 --- a/src/any.rs +++ b/src/any.rs @@ -346,10 +346,8 @@ impl Dynamic { } #[cfg(not(feature = "no_float"))] - { - if let Some(result) = ::downcast_ref::(&value) { - return result.clone().into(); - } + if let Some(result) = ::downcast_ref::(&value) { + return result.clone().into(); } let mut boxed = Box::new(value); diff --git a/src/engine.rs b/src/engine.rs index 1de5d3d4..2bea2ab7 100644 --- a/src/engine.rs +++ b/src/engine.rs @@ -353,17 +353,14 @@ pub fn make_getter(id: &str) -> String { /// Extract the property name from a getter function name. fn extract_prop_from_getter(fn_name: &str) -> Option<&str> { #[cfg(not(feature = "no_object"))] - { - if fn_name.starts_with(FN_GET) { - Some(&fn_name[FN_GET.len()..]) - } else { - None - } - } - #[cfg(feature = "no_object")] - { + if fn_name.starts_with(FN_GET) { + Some(&fn_name[FN_GET.len()..]) + } else { None } + + #[cfg(feature = "no_object")] + None } /// Make setter function @@ -374,17 +371,14 @@ pub fn make_setter(id: &str) -> String { /// Extract the property name from a setter function name. fn extract_prop_from_setter(fn_name: &str) -> Option<&str> { #[cfg(not(feature = "no_object"))] - { - if fn_name.starts_with(FN_SET) { - Some(&fn_name[FN_SET.len()..]) - } else { - None - } - } - #[cfg(feature = "no_object")] - { + if fn_name.starts_with(FN_SET) { + Some(&fn_name[FN_SET.len()..]) + } else { None } + + #[cfg(feature = "no_object")] + None } /// Print/debug to stdout @@ -701,12 +695,10 @@ impl Engine { // Check for stack overflow #[cfg(not(feature = "no_function"))] #[cfg(not(feature = "unchecked"))] - { - if level > self.max_call_stack_depth { - return Err(Box::new( - EvalAltResult::ErrorStackOverflow(Position::none()), - )); - } + if level > self.max_call_stack_depth { + return Err(Box::new( + EvalAltResult::ErrorStackOverflow(Position::none()), + )); } let mut this_copy: Dynamic = Default::default(); @@ -2344,21 +2336,19 @@ impl Engine { .try_cast::() { #[cfg(not(feature = "no_module"))] - { - if let Some(resolver) = &self.module_resolver { - let mut module = resolver.resolve(self, &path, expr.position())?; - module.index_all_sub_modules(); - mods.push((name.clone().into(), module)); + if let Some(resolver) = &self.module_resolver { + let mut module = resolver.resolve(self, &path, expr.position())?; + module.index_all_sub_modules(); + mods.push((name.clone().into(), module)); - state.modules += 1; + state.modules += 1; - Ok(Default::default()) - } else { - Err(Box::new(EvalAltResult::ErrorModuleNotFound( - path.to_string(), - expr.position(), - ))) - } + Ok(Default::default()) + } else { + Err(Box::new(EvalAltResult::ErrorModuleNotFound( + path.to_string(), + expr.position(), + ))) } #[cfg(feature = "no_module")] @@ -2509,13 +2499,11 @@ impl Engine { state.operations += 1; #[cfg(not(feature = "unchecked"))] - { - // Guard against too many operations - if self.max_operations > 0 && state.operations > self.max_operations { - return Err(Box::new(EvalAltResult::ErrorTooManyOperations( - Position::none(), - ))); - } + // Guard against too many operations + if self.max_operations > 0 && state.operations > self.max_operations { + return Err(Box::new(EvalAltResult::ErrorTooManyOperations( + Position::none(), + ))); } // Report progress - only in steps @@ -2641,26 +2629,24 @@ fn run_builtin_binary_op( } #[cfg(not(feature = "no_float"))] - { - if args_type == TypeId::of::() { - let x = *x.downcast_ref::().unwrap(); - let y = *y.downcast_ref::().unwrap(); + if args_type == TypeId::of::() { + let x = *x.downcast_ref::().unwrap(); + let y = *y.downcast_ref::().unwrap(); - match op { - "+" => return Ok(Some((x + y).into())), - "-" => return Ok(Some((x - y).into())), - "*" => return Ok(Some((x * y).into())), - "/" => return Ok(Some((x / y).into())), - "%" => return Ok(Some((x % y).into())), - "~" => return pow_f_f(x, y).map(Into::into).map(Some), - "==" => return Ok(Some((x == y).into())), - "!=" => return Ok(Some((x != y).into())), - ">" => return Ok(Some((x > y).into())), - ">=" => return Ok(Some((x >= y).into())), - "<" => return Ok(Some((x < y).into())), - "<=" => return Ok(Some((x <= y).into())), - _ => (), - } + match op { + "+" => return Ok(Some((x + y).into())), + "-" => return Ok(Some((x - y).into())), + "*" => return Ok(Some((x * y).into())), + "/" => return Ok(Some((x / y).into())), + "%" => return Ok(Some((x % y).into())), + "~" => return pow_f_f(x, y).map(Into::into).map(Some), + "==" => return Ok(Some((x == y).into())), + "!=" => return Ok(Some((x != y).into())), + ">" => return Ok(Some((x > y).into())), + ">=" => return Ok(Some((x >= y).into())), + "<" => return Ok(Some((x < y).into())), + "<=" => return Ok(Some((x <= y).into())), + _ => (), } } @@ -2737,20 +2723,18 @@ fn run_builtin_op_assignment( } #[cfg(not(feature = "no_float"))] - { - if args_type == TypeId::of::() { - let x = x.downcast_mut::().unwrap(); - let y = *y.downcast_ref::().unwrap(); + if args_type == TypeId::of::() { + let x = x.downcast_mut::().unwrap(); + let y = *y.downcast_ref::().unwrap(); - match op { - "+=" => return Ok(Some(*x += y)), - "-=" => return Ok(Some(*x -= y)), - "*=" => return Ok(Some(*x *= y)), - "/=" => return Ok(Some(*x /= y)), - "%=" => return Ok(Some(*x %= y)), - "~=" => return Ok(Some(*x = pow_f_f(*x, y)?)), - _ => (), - } + match op { + "+=" => return Ok(Some(*x += y)), + "-=" => return Ok(Some(*x -= y)), + "*=" => return Ok(Some(*x *= y)), + "/=" => return Ok(Some(*x /= y)), + "%=" => return Ok(Some(*x %= y)), + "~=" => return Ok(Some(*x = pow_f_f(*x, y)?)), + _ => (), } } diff --git a/src/fn_native.rs b/src/fn_native.rs index a1110fd3..1279e430 100644 --- a/src/fn_native.rs +++ b/src/fn_native.rs @@ -27,13 +27,9 @@ pub type Shared = Arc; /// If the resource is shared (i.e. has other outstanding references), a cloned copy is used. pub fn shared_make_mut(value: &mut Shared) -> &mut T { #[cfg(not(feature = "sync"))] - { - Rc::make_mut(value) - } + return Rc::make_mut(value); #[cfg(feature = "sync")] - { - Arc::make_mut(value) - } + return Arc::make_mut(value); } /// Consume a `Shared` resource, assuming that it is unique (i.e. not shared). @@ -43,13 +39,9 @@ pub fn shared_make_mut(value: &mut Shared) -> &mut T { /// Panics if the resource is shared (i.e. has other outstanding references). pub fn shared_take(value: Shared) -> T { #[cfg(not(feature = "sync"))] - { - Rc::try_unwrap(value).map_err(|_| ()).unwrap() - } + return Rc::try_unwrap(value).map_err(|_| ()).unwrap(); #[cfg(feature = "sync")] - { - Arc::try_unwrap(value).map_err(|_| ()).unwrap() - } + return Arc::try_unwrap(value).map_err(|_| ()).unwrap(); } pub type FnCallArgs<'a> = [&'a mut Dynamic]; diff --git a/src/packages/arithmetic.rs b/src/packages/arithmetic.rs index 31808a2a..7a548ff0 100644 --- a/src/packages/arithmetic.rs +++ b/src/packages/arithmetic.rs @@ -190,42 +190,38 @@ fn modulo_u(x: T, y: T) -> FuncReturn<::Output> { // Checked power pub(crate) fn pow_i_i(x: INT, y: INT) -> FuncReturn { #[cfg(not(feature = "only_i32"))] - { - if y > (u32::MAX as INT) { - Err(Box::new(EvalAltResult::ErrorArithmetic( - format!("Integer raised to too large an index: {} ~ {}", x, y), + if y > (u32::MAX as INT) { + Err(Box::new(EvalAltResult::ErrorArithmetic( + format!("Integer raised to too large an index: {} ~ {}", x, y), + Position::none(), + ))) + } else if y < 0 { + Err(Box::new(EvalAltResult::ErrorArithmetic( + format!("Integer raised to a negative index: {} ~ {}", x, y), + Position::none(), + ))) + } else { + x.checked_pow(y as u32).ok_or_else(|| { + Box::new(EvalAltResult::ErrorArithmetic( + format!("Power overflow: {} ~ {}", x, y), Position::none(), - ))) - } else if y < 0 { - Err(Box::new(EvalAltResult::ErrorArithmetic( - format!("Integer raised to a negative index: {} ~ {}", x, y), - Position::none(), - ))) - } else { - x.checked_pow(y as u32).ok_or_else(|| { - Box::new(EvalAltResult::ErrorArithmetic( - format!("Power overflow: {} ~ {}", x, y), - Position::none(), - )) - }) - } + )) + }) } #[cfg(feature = "only_i32")] - { - if y < 0 { - Err(Box::new(EvalAltResult::ErrorArithmetic( - format!("Integer raised to a negative index: {} ~ {}", x, y), + if y < 0 { + Err(Box::new(EvalAltResult::ErrorArithmetic( + format!("Integer raised to a negative index: {} ~ {}", x, y), + Position::none(), + ))) + } else { + x.checked_pow(y as u32).ok_or_else(|| { + Box::new(EvalAltResult::ErrorArithmetic( + format!("Power overflow: {} ~ {}", x, y), Position::none(), - ))) - } else { - x.checked_pow(y as u32).ok_or_else(|| { - Box::new(EvalAltResult::ErrorArithmetic( - format!("Power overflow: {} ~ {}", x, y), - Position::none(), - )) - }) - } + )) + }) } } // Unchecked integer power - may panic on overflow or if the power index is too high (> u32::MAX) diff --git a/src/packages/array_basic.rs b/src/packages/array_basic.rs index bf06ed47..7c7b5681 100644 --- a/src/packages/array_basic.rs +++ b/src/packages/array_basic.rs @@ -30,15 +30,13 @@ fn pad(engine: &Engine, args: &mut [&mut Dynamic]) -> FuncRe // Check if array will be over max size limit #[cfg(not(feature = "unchecked"))] - { - if engine.max_array_size > 0 && len > 0 && (len as usize) > engine.max_array_size { - return Err(Box::new(EvalAltResult::ErrorDataTooLarge( - "Size of array".to_string(), - engine.max_array_size, - len as usize, - Position::none(), - ))); - } + if engine.max_array_size > 0 && len > 0 && (len as usize) > engine.max_array_size { + return Err(Box::new(EvalAltResult::ErrorDataTooLarge( + "Size of array".to_string(), + engine.max_array_size, + len as usize, + Position::none(), + ))); } if len > 0 { diff --git a/src/packages/string_more.rs b/src/packages/string_more.rs index 7bc10012..e6acbbb9 100644 --- a/src/packages/string_more.rs +++ b/src/packages/string_more.rs @@ -231,15 +231,13 @@ def_package!(crate:MoreStringPackage:"Additional string utilities, including str // Check if string will be over max size limit #[cfg(not(feature = "unchecked"))] - { - if engine.max_string_size > 0 && len > 0 && (len as usize) > engine.max_string_size { - return Err(Box::new(EvalAltResult::ErrorDataTooLarge( - "Length of string".to_string(), - engine.max_string_size, - len as usize, - Position::none(), - ))); - } + if engine.max_string_size > 0 && len > 0 && (len as usize) > engine.max_string_size { + return Err(Box::new(EvalAltResult::ErrorDataTooLarge( + "Length of string".to_string(), + engine.max_string_size, + len as usize, + Position::none(), + ))); } if len > 0 { diff --git a/src/packages/time_basic.rs b/src/packages/time_basic.rs index 9fd4e21f..cbf13f1b 100644 --- a/src/packages/time_basic.rs +++ b/src/packages/time_basic.rs @@ -33,17 +33,16 @@ def_package!(crate:BasicTimePackage:"Basic timing utilities.", lib, { let seconds = (ts2 - ts1).as_secs(); #[cfg(not(feature = "unchecked"))] - { - if seconds > (MAX_INT as u64) { - return Err(Box::new(EvalAltResult::ErrorArithmetic( - format!( - "Integer overflow for timestamp duration: {}", - -(seconds as i64) - ), - Position::none(), - ))); - } + if seconds > (MAX_INT as u64) { + return Err(Box::new(EvalAltResult::ErrorArithmetic( + format!( + "Integer overflow for timestamp duration: {}", + -(seconds as i64) + ), + Position::none(), + ))); } + return Ok(-(seconds as INT)); } } else { @@ -55,14 +54,13 @@ def_package!(crate:BasicTimePackage:"Basic timing utilities.", lib, { let seconds = (ts1 - ts2).as_secs(); #[cfg(not(feature = "unchecked"))] - { - if seconds > (MAX_INT as u64) { - return Err(Box::new(EvalAltResult::ErrorArithmetic( - format!("Integer overflow for timestamp duration: {}", seconds), - Position::none(), - ))); - } + if seconds > (MAX_INT as u64) { + return Err(Box::new(EvalAltResult::ErrorArithmetic( + format!("Integer overflow for timestamp duration: {}", seconds), + Position::none(), + ))); } + return Ok(seconds as INT); } } @@ -86,14 +84,13 @@ def_package!(crate:BasicTimePackage:"Basic timing utilities.", lib, { let seconds = timestamp.elapsed().as_secs(); #[cfg(not(feature = "unchecked"))] - { - if seconds > (MAX_INT as u64) { - return Err(Box::new(EvalAltResult::ErrorArithmetic( - format!("Integer overflow for timestamp.elapsed: {}", seconds), - Position::none(), - ))); - } + if seconds > (MAX_INT as u64) { + return Err(Box::new(EvalAltResult::ErrorArithmetic( + format!("Integer overflow for timestamp.elapsed: {}", seconds), + Position::none(), + ))); } + Ok(seconds as INT) } diff --git a/src/parser.rs b/src/parser.rs index 505c8e7e..37743e0f 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -1495,13 +1495,9 @@ fn parse_unary( .map(|i| Expr::IntegerConstant(Box::new((i, pos)))) .or_else(|| { #[cfg(not(feature = "no_float"))] - { - Some(Expr::FloatConstant(Box::new((-(x.0 as FLOAT), pos)))) - } + return Some(Expr::FloatConstant(Box::new((-(x.0 as FLOAT), pos)))); #[cfg(feature = "no_float")] - { - None - } + return None; }) .ok_or_else(|| LexError::MalformedNumber(format!("-{}", x.0)).into_err(pos)) } @@ -2618,7 +2614,6 @@ impl Engine { }; match input.peek().unwrap() { - #[cfg(not(feature = "no_function"))] (Token::Fn, pos) => { let mut state = ParseState::new( self.max_function_expr_depth, diff --git a/src/serde/de.rs b/src/serde/de.rs index be466508..82910073 100644 --- a/src/serde/de.rs +++ b/src/serde/de.rs @@ -208,24 +208,24 @@ impl<'de> Deserializer<'de> for &mut DynamicDeserializer<'de> { fn deserialize_f32>(self, visitor: V) -> Result> { #[cfg(not(feature = "no_float"))] - { - self.value - .downcast_ref::() - .map_or_else(|| self.type_error(), |&x| visitor.visit_f32(x)) - } + return self + .value + .downcast_ref::() + .map_or_else(|| self.type_error(), |&x| visitor.visit_f32(x)); + #[cfg(feature = "no_float")] - self.type_error_str("f32") + return self.type_error_str("f32"); } fn deserialize_f64>(self, visitor: V) -> Result> { #[cfg(not(feature = "no_float"))] - { - self.value - .downcast_ref::() - .map_or_else(|| self.type_error(), |&x| visitor.visit_f64(x)) - } + return self + .value + .downcast_ref::() + .map_or_else(|| self.type_error(), |&x| visitor.visit_f64(x)); + #[cfg(feature = "no_float")] - self.type_error_str("f64") + return self.type_error_str("f64"); } fn deserialize_char>(self, visitor: V) -> Result> { @@ -284,14 +284,13 @@ impl<'de> Deserializer<'de> for &mut DynamicDeserializer<'de> { fn deserialize_seq>(self, visitor: V) -> Result> { #[cfg(not(feature = "no_index"))] - { - self.value.downcast_ref::().map_or_else( - || self.type_error(), - |arr| visitor.visit_seq(IterateArray::new(arr.iter())), - ) - } + return self.value.downcast_ref::().map_or_else( + || self.type_error(), + |arr| visitor.visit_seq(IterateArray::new(arr.iter())), + ); + #[cfg(feature = "no_index")] - self.type_error() + return self.type_error(); } fn deserialize_tuple>( @@ -313,14 +312,13 @@ impl<'de> Deserializer<'de> for &mut DynamicDeserializer<'de> { fn deserialize_map>(self, visitor: V) -> Result> { #[cfg(not(feature = "no_object"))] - { - self.value.downcast_ref::().map_or_else( - || self.type_error(), - |map| visitor.visit_map(IterateMap::new(map.keys(), map.values())), - ) - } + return self.value.downcast_ref::().map_or_else( + || self.type_error(), + |map| visitor.visit_map(IterateMap::new(map.keys(), map.values())), + ); + #[cfg(feature = "no_object")] - self.type_error() + return self.type_error(); } fn deserialize_struct>(