Clarify non-zero hashes.
This commit is contained in:
parent
54f78c5cd9
commit
206b5051eb
12
src/ast.rs
12
src/ast.rs
@ -1,7 +1,7 @@
|
|||||||
//! Module defining the AST (abstract syntax tree).
|
//! Module defining the AST (abstract syntax tree).
|
||||||
|
|
||||||
use crate::calc_fn_hash;
|
use crate::calc_fn_hash;
|
||||||
use crate::func::hashing::DEFAULT_HASH;
|
use crate::func::hashing::ALT_ZERO_HASH;
|
||||||
use crate::module::NamespaceRef;
|
use crate::module::NamespaceRef;
|
||||||
use crate::tokenizer::Token;
|
use crate::tokenizer::Token;
|
||||||
use crate::types::dynamic::Union;
|
use crate::types::dynamic::Union;
|
||||||
@ -1800,7 +1800,7 @@ impl OpAssignment<'_> {
|
|||||||
/// to possible function overloading for different parameter types.
|
/// to possible function overloading for different parameter types.
|
||||||
#[derive(Clone, Copy, Eq, PartialEq, Hash, Default)]
|
#[derive(Clone, Copy, Eq, PartialEq, Hash, Default)]
|
||||||
pub struct FnCallHashes {
|
pub struct FnCallHashes {
|
||||||
/// Pre-calculated hash for a script-defined function ([`None`] if native functions only).
|
/// Pre-calculated hash for a script-defined function (zero if native functions only).
|
||||||
#[cfg(not(feature = "no_function"))]
|
#[cfg(not(feature = "no_function"))]
|
||||||
pub script: u64,
|
pub script: u64,
|
||||||
/// Pre-calculated hash for a native Rust function with no parameter types.
|
/// Pre-calculated hash for a native Rust function with no parameter types.
|
||||||
@ -1825,7 +1825,7 @@ impl fmt::Debug for FnCallHashes {
|
|||||||
impl From<u64> for FnCallHashes {
|
impl From<u64> for FnCallHashes {
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn from(hash: u64) -> Self {
|
fn from(hash: u64) -> Self {
|
||||||
let hash = if hash == 0 { DEFAULT_HASH } else { hash };
|
let hash = if hash == 0 { ALT_ZERO_HASH } else { hash };
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
#[cfg(not(feature = "no_function"))]
|
#[cfg(not(feature = "no_function"))]
|
||||||
@ -1843,7 +1843,7 @@ impl FnCallHashes {
|
|||||||
Self {
|
Self {
|
||||||
#[cfg(not(feature = "no_function"))]
|
#[cfg(not(feature = "no_function"))]
|
||||||
script: 0,
|
script: 0,
|
||||||
native: if hash == 0 { DEFAULT_HASH } else { hash },
|
native: if hash == 0 { ALT_ZERO_HASH } else { hash },
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/// Create a [`FnCallHashes`] with both native Rust and script function hashes.
|
/// Create a [`FnCallHashes`] with both native Rust and script function hashes.
|
||||||
@ -1852,8 +1852,8 @@ impl FnCallHashes {
|
|||||||
pub const fn from_all(#[cfg(not(feature = "no_function"))] script: u64, native: u64) -> Self {
|
pub const fn from_all(#[cfg(not(feature = "no_function"))] script: u64, native: u64) -> Self {
|
||||||
Self {
|
Self {
|
||||||
#[cfg(not(feature = "no_function"))]
|
#[cfg(not(feature = "no_function"))]
|
||||||
script: if script == 0 { DEFAULT_HASH } else { script },
|
script: if script == 0 { ALT_ZERO_HASH } else { script },
|
||||||
native: if native == 0 { DEFAULT_HASH } else { native },
|
native: if native == 0 { ALT_ZERO_HASH } else { native },
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/// Is this [`FnCallHashes`] native Rust only?
|
/// Is this [`FnCallHashes`] native Rust only?
|
||||||
|
@ -8,13 +8,24 @@ use std::{
|
|||||||
iter::empty,
|
iter::empty,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub const DEFAULT_HASH: u64 = 42;
|
/// Dummy hash value to map zeros to. This value can be anything.
|
||||||
|
///
|
||||||
|
/// # Notes
|
||||||
|
///
|
||||||
|
/// Hashes are `u64`, and they can be zero (although extremely unlikely).
|
||||||
|
/// It is possible to hijack the zero value to indicate non-existence,
|
||||||
|
/// like [`None`] in [`Option<u64>`].
|
||||||
|
///
|
||||||
|
/// When a hash is calculated to be zero, it gets mapped to this alternate hash value.
|
||||||
|
/// This has the effect of releasing the zero value at the expense of causing the probability of
|
||||||
|
/// this value to double, which has minor impacts.
|
||||||
|
pub const ALT_ZERO_HASH: u64 = 42;
|
||||||
|
|
||||||
/// A hasher that only takes one single [`u64`] and returns it as a non-zero hash key.
|
/// A hasher that only takes one single [`u64`] and returns it as a non-zero hash key.
|
||||||
///
|
///
|
||||||
/// # Zeros
|
/// # Zeros
|
||||||
///
|
///
|
||||||
/// If the value is zero, then it is mapped to `DEFAULT_HASH`.
|
/// If the value is zero, it is mapped to `ALT_ZERO_HASH`.
|
||||||
///
|
///
|
||||||
/// # Panics
|
/// # Panics
|
||||||
///
|
///
|
||||||
@ -37,7 +48,7 @@ impl Hasher for StraightHasher {
|
|||||||
self.0 = u64::from_ne_bytes(key);
|
self.0 = u64::from_ne_bytes(key);
|
||||||
|
|
||||||
if self.0 == 0 {
|
if self.0 == 0 {
|
||||||
self.0 = DEFAULT_HASH
|
self.0 = ALT_ZERO_HASH
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -51,7 +62,7 @@ impl BuildHasher for StraightHasherBuilder {
|
|||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn build_hasher(&self) -> Self::Hasher {
|
fn build_hasher(&self) -> Self::Hasher {
|
||||||
StraightHasher(DEFAULT_HASH)
|
StraightHasher(ALT_ZERO_HASH)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -92,7 +103,7 @@ pub fn calc_qualified_var_hash<'a>(
|
|||||||
var_name.as_ref().hash(s);
|
var_name.as_ref().hash(s);
|
||||||
|
|
||||||
match s.finish() {
|
match s.finish() {
|
||||||
0 => DEFAULT_HASH,
|
0 => ALT_ZERO_HASH,
|
||||||
r => r,
|
r => r,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -130,7 +141,7 @@ pub fn calc_qualified_fn_hash(
|
|||||||
num.hash(s);
|
num.hash(s);
|
||||||
|
|
||||||
match s.finish() {
|
match s.finish() {
|
||||||
0 => DEFAULT_HASH,
|
0 => ALT_ZERO_HASH,
|
||||||
r => r,
|
r => r,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -165,7 +176,7 @@ pub fn calc_fn_params_hash(params: impl Iterator<Item = TypeId>) -> u64 {
|
|||||||
len.hash(s);
|
len.hash(s);
|
||||||
|
|
||||||
match s.finish() {
|
match s.finish() {
|
||||||
0 => DEFAULT_HASH,
|
0 => ALT_ZERO_HASH,
|
||||||
r => r,
|
r => r,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -179,7 +190,7 @@ pub fn calc_fn_params_hash(params: impl Iterator<Item = TypeId>) -> u64 {
|
|||||||
#[must_use]
|
#[must_use]
|
||||||
pub const fn combine_hashes(a: u64, b: u64) -> u64 {
|
pub const fn combine_hashes(a: u64, b: u64) -> u64 {
|
||||||
match a ^ b {
|
match a ^ b {
|
||||||
0 => DEFAULT_HASH,
|
0 => ALT_ZERO_HASH,
|
||||||
r => r,
|
r => r,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -96,8 +96,7 @@ impl FuncInfo {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// _(internals)_ Calculate a [`u64`] hash key from a namespace-qualified function name and
|
/// _(internals)_ Calculate a non-zero [`u64`] hash key from a namespace-qualified function name and parameter types.
|
||||||
/// parameter types.
|
|
||||||
/// Exported under the `internals` feature only.
|
/// Exported under the `internals` feature only.
|
||||||
///
|
///
|
||||||
/// Module names are passed in via `&str` references from an iterator.
|
/// Module names are passed in via `&str` references from an iterator.
|
||||||
@ -667,7 +666,7 @@ impl Module {
|
|||||||
type_id
|
type_id
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Set a Rust function into the [`Module`], returning a hash key.
|
/// Set a Rust function into the [`Module`], returning a non-zero hash key.
|
||||||
///
|
///
|
||||||
/// If there is an existing Rust function of the same hash, it is replaced.
|
/// If there is an existing Rust function of the same hash, it is replaced.
|
||||||
///
|
///
|
||||||
@ -729,7 +728,7 @@ impl Module {
|
|||||||
|
|
||||||
/// Set a Rust function taking a reference to the scripting [`Engine`][crate::Engine],
|
/// Set a Rust function taking a reference to the scripting [`Engine`][crate::Engine],
|
||||||
/// the current set of functions, plus a list of mutable [`Dynamic`] references
|
/// the current set of functions, plus a list of mutable [`Dynamic`] references
|
||||||
/// into the [`Module`], returning a hash key.
|
/// into the [`Module`], returning a non-zero hash key.
|
||||||
///
|
///
|
||||||
/// Use this to register a built-in function which must reference settings on the scripting
|
/// Use this to register a built-in function which must reference settings on the scripting
|
||||||
/// [`Engine`][crate::Engine] (e.g. to prevent growing an array beyond the allowed maximum size),
|
/// [`Engine`][crate::Engine] (e.g. to prevent growing an array beyond the allowed maximum size),
|
||||||
@ -822,7 +821,7 @@ impl Module {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Set a Rust function into the [`Module`], returning a hash key.
|
/// Set a Rust function into the [`Module`], returning a non-zero hash key.
|
||||||
///
|
///
|
||||||
/// If there is a similar existing Rust function, it is replaced.
|
/// If there is a similar existing Rust function, it is replaced.
|
||||||
///
|
///
|
||||||
@ -861,7 +860,7 @@ impl Module {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Set a Rust getter function taking one mutable parameter, returning a hash key.
|
/// Set a Rust getter function taking one mutable parameter, returning a non-zero hash key.
|
||||||
/// This function is automatically exposed to the global namespace.
|
/// This function is automatically exposed to the global namespace.
|
||||||
///
|
///
|
||||||
/// If there is a similar existing Rust getter function, it is replaced.
|
/// If there is a similar existing Rust getter function, it is replaced.
|
||||||
@ -898,7 +897,7 @@ impl Module {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Set a Rust setter function taking two parameters (the first one mutable) into the [`Module`],
|
/// Set a Rust setter function taking two parameters (the first one mutable) into the [`Module`],
|
||||||
/// returning a hash key.
|
/// returning a non-zero hash key.
|
||||||
/// This function is automatically exposed to the global namespace.
|
/// This function is automatically exposed to the global namespace.
|
||||||
///
|
///
|
||||||
/// If there is a similar existing setter Rust function, it is replaced.
|
/// If there is a similar existing setter Rust function, it is replaced.
|
||||||
@ -939,7 +938,7 @@ impl Module {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Set a Rust index getter taking two parameters (the first one mutable) into the [`Module`],
|
/// Set a Rust index getter taking two parameters (the first one mutable) into the [`Module`],
|
||||||
/// returning a hash key.
|
/// returning a non-zero hash key.
|
||||||
/// This function is automatically exposed to the global namespace.
|
/// This function is automatically exposed to the global namespace.
|
||||||
///
|
///
|
||||||
/// If there is a similar existing setter Rust function, it is replaced.
|
/// If there is a similar existing setter Rust function, it is replaced.
|
||||||
@ -1000,7 +999,7 @@ impl Module {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Set a Rust index setter taking three parameters (the first one mutable) into the [`Module`],
|
/// Set a Rust index setter taking three parameters (the first one mutable) into the [`Module`],
|
||||||
/// returning a hash key.
|
/// returning a non-zero hash key.
|
||||||
/// This function is automatically exposed to the global namespace.
|
/// This function is automatically exposed to the global namespace.
|
||||||
///
|
///
|
||||||
/// If there is a similar existing Rust function, it is replaced.
|
/// If there is a similar existing Rust function, it is replaced.
|
||||||
@ -1060,7 +1059,7 @@ impl Module {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Set a pair of Rust index getter and setter functions, returning both hash keys.
|
/// Set a pair of Rust index getter and setter functions, returning both non-zero hash keys.
|
||||||
/// This is a short-hand for [`set_indexer_get_fn`][Module::set_indexer_get_fn] and
|
/// This is a short-hand for [`set_indexer_get_fn`][Module::set_indexer_get_fn] and
|
||||||
/// [`set_indexer_set_fn`][Module::set_indexer_set_fn].
|
/// [`set_indexer_set_fn`][Module::set_indexer_set_fn].
|
||||||
///
|
///
|
||||||
|
Loading…
Reference in New Issue
Block a user