From e961ae23fdd312adbccd3f1d76bc56e5e2861d0a Mon Sep 17 00:00:00 2001 From: Stephen Chung Date: Tue, 16 Nov 2021 13:42:46 +0800 Subject: [PATCH] Eliminate script hashes under no_function. --- src/ast.rs | 40 +++++++++++++++++++++++++--------------- src/func/call.rs | 16 ++++++++++------ src/func/native.rs | 5 +++-- src/parser.rs | 15 +++++++++------ src/types/scope.rs | 1 + 5 files changed, 48 insertions(+), 29 deletions(-) diff --git a/src/ast.rs b/src/ast.rs index 45e4fe54..1269c170 100644 --- a/src/ast.rs +++ b/src/ast.rs @@ -1771,6 +1771,7 @@ impl OpAssignment<'_> { #[derive(Clone, Copy, Eq, PartialEq, Hash, Default)] pub struct FnCallHashes { /// Pre-calculated hash for a script-defined function ([`None`] if native functions only). + #[cfg(not(feature = "no_function"))] pub script: Option, /// Pre-calculated hash for a native Rust function with no parameter types. pub native: u64, @@ -1778,14 +1779,26 @@ pub struct FnCallHashes { impl fmt::Debug for FnCallHashes { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + #[cfg(not(feature = "no_function"))] if let Some(script) = self.script { - if script == self.native { + return if script == self.native { fmt::Debug::fmt(&self.native, f) } else { write!(f, "({}, {})", script, self.native) - } - } else { - write!(f, "{} (native only)", self.native) + }; + } + + write!(f, "{} (native only)", self.native) + } +} + +impl From for FnCallHashes { + #[inline(always)] + fn from(hash: u64) -> Self { + Self { + #[cfg(not(feature = "no_function"))] + script: Some(hash), + native: hash, } } } @@ -1796,24 +1809,17 @@ impl FnCallHashes { #[must_use] pub const fn from_native(hash: u64) -> Self { Self { + #[cfg(not(feature = "no_function"))] script: None, native: hash, } } - /// Create a [`FnCallHashes`] with both native Rust and script function hashes set to the same value. - #[inline(always)] - #[must_use] - pub const fn from_script(hash: u64) -> Self { - Self { - script: Some(hash), - native: hash, - } - } /// Create a [`FnCallHashes`] with both native Rust and script function hashes. #[inline(always)] #[must_use] - pub const fn from_script_and_native(script: u64, native: u64) -> Self { + pub const fn from_all(#[cfg(not(feature = "no_function"))] script: u64, native: u64) -> Self { Self { + #[cfg(not(feature = "no_function"))] script: Some(script), native, } @@ -1822,7 +1828,11 @@ impl FnCallHashes { #[inline(always)] #[must_use] pub const fn is_native_only(&self) -> bool { - self.script.is_none() + #[cfg(not(feature = "no_function"))] + return self.script.is_none(); + + #[cfg(feature = "no_function")] + return true; } } diff --git a/src/func/call.rs b/src/func/call.rs index 04841108..cbd05524 100644 --- a/src/func/call.rs +++ b/src/func/call.rs @@ -671,7 +671,7 @@ impl Engine { is_method_call: bool, pos: Position, scope: Option<&mut Scope>, - _level: usize, + level: usize, ) -> Result<(Dynamic, bool), Box> { fn no_method_err(name: &str, pos: Position) -> Result<(Dynamic, bool), Box> { let msg = format!("'{0}' should not be called this way. Try {0}(...);", name); @@ -682,6 +682,8 @@ impl Engine { #[cfg(not(feature = "no_closure"))] ensure_no_data_race(fn_name, args, is_ref_mut)?; + let _scope = scope; + let _level = level; let _is_method_call = is_method_call; // These may be redirected from method style calls. @@ -750,7 +752,7 @@ impl Engine { } let mut empty_scope; - let scope = if let Some(scope) = scope { + let scope = if let Some(scope) = _scope { scope } else { empty_scope = Scope::new(); @@ -914,7 +916,7 @@ impl Engine { let fn_name = fn_ptr.fn_name(); let args_len = call_args.len() + fn_ptr.curry().len(); // Recalculate hashes - let new_hash = FnCallHashes::from_script(calc_fn_hash(fn_name, args_len)); + let new_hash = calc_fn_hash(fn_name, args_len).into(); // Arguments are passed as-is, adding the curried arguments let mut curry = StaticVec::with_capacity(fn_ptr.num_curried()); curry.extend(fn_ptr.curry().iter().cloned()); @@ -948,7 +950,8 @@ impl Engine { let fn_name = fn_ptr.fn_name(); let args_len = call_args.len() + fn_ptr.curry().len(); // Recalculate hash - let new_hash = FnCallHashes::from_script_and_native( + let new_hash = FnCallHashes::from_all( + #[cfg(not(feature = "no_function"))] calc_fn_hash(fn_name, args_len), calc_fn_hash(fn_name, args_len + 1), ); @@ -1019,7 +1022,8 @@ impl Engine { call_args.insert_many(0, fn_ptr.curry().iter().cloned()); } // Recalculate the hash based on the new function name and new arguments - hash = FnCallHashes::from_script_and_native( + hash = FnCallHashes::from_all( + #[cfg(not(feature = "no_function"))] calc_fn_hash(fn_name, call_args.len()), calc_fn_hash(fn_name, call_args.len() + 1), ); @@ -1120,7 +1124,7 @@ impl Engine { // Recalculate hash let args_len = total_args + curry.len(); hashes = if !hashes.is_native_only() { - FnCallHashes::from_script(calc_fn_hash(name, args_len)) + calc_fn_hash(name, args_len).into() } else { FnCallHashes::from_native(calc_fn_hash(name, args_len)) }; diff --git a/src/func/native.rs b/src/func/native.rs index cf8064c7..e50e5da1 100644 --- a/src/func/native.rs +++ b/src/func/native.rs @@ -239,12 +239,13 @@ impl<'a> NativeCallContext<'a> { args: &mut [&mut Dynamic], ) -> Result> { let hash = if is_method_call { - FnCallHashes::from_script_and_native( + FnCallHashes::from_all( + #[cfg(not(feature = "no_function"))] calc_fn_hash(fn_name, args.len() - 1), calc_fn_hash(fn_name, args.len()), ) } else { - FnCallHashes::from_script(calc_fn_hash(fn_name, args.len())) + calc_fn_hash(fn_name, args.len()).into() }; self.engine() diff --git a/src/parser.rs b/src/parser.rs index ddf540c8..004261fa 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -494,7 +494,7 @@ fn parse_fn_call( ); let hashes = if is_valid_function_name(&id) { - FnCallHashes::from_script(hash) + hash.into() } else { FnCallHashes::from_native(hash) }; @@ -544,7 +544,7 @@ fn parse_fn_call( ); let hashes = if is_valid_function_name(&id) { - FnCallHashes::from_script(hash) + hash.into() } else { FnCallHashes::from_native(hash) }; @@ -1758,7 +1758,8 @@ fn make_dot_expr( } Expr::FnCall(mut func, func_pos) => { // Recalculate hash - func.hashes = FnCallHashes::from_script_and_native( + func.hashes = FnCallHashes::from_all( + #[cfg(not(feature = "no_function"))] calc_fn_hash(&func.name, func.args.len()), calc_fn_hash(&func.name, func.args.len() + 1), ); @@ -1808,10 +1809,12 @@ fn make_dot_expr( // lhs.func(...) (lhs, Expr::FnCall(mut func, func_pos)) => { // Recalculate hash - func.hashes = FnCallHashes::from_script_and_native( + func.hashes = FnCallHashes::from_all( + #[cfg(not(feature = "no_function"))] calc_fn_hash(&func.name, func.args.len()), calc_fn_hash(&func.name, func.args.len() + 1), ); + let rhs = Expr::FnCall(func, func_pos); Expr::Dot(BinaryExpr { lhs, rhs }.into(), false, op_pos) } @@ -1962,7 +1965,7 @@ fn parse_binary_op( // Convert into a call to `contains` FnCallExpr { - hashes: FnCallHashes::from_script(calc_fn_hash(OP_CONTAINS, 2)), + hashes: calc_fn_hash(OP_CONTAINS, 2).into(), args, name: state.get_identifier(OP_CONTAINS), ..op_base @@ -1981,7 +1984,7 @@ fn parse_binary_op( FnCallExpr { hashes: if is_valid_function_name(&s) { - FnCallHashes::from_script(hash) + hash.into() } else { FnCallHashes::from_native(hash) }, diff --git a/src/types/scope.rs b/src/types/scope.rs index 30fffcff..02094bea 100644 --- a/src/types/scope.rs +++ b/src/types/scope.rs @@ -589,6 +589,7 @@ impl<'a> Scope<'a> { /// /// Panics if the range is out of bounds. #[inline] + #[allow(dead_code)] pub(crate) fn remove_range(&mut self, start: usize, len: usize) { self.values.drain(start..start + len).for_each(|_| {}); self.names.drain(start..start + len).for_each(|_| {});