diff --git a/Cargo.toml b/Cargo.toml index e5edb293..3999b7de 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -63,7 +63,6 @@ unicode-xid-ident = ["unicode-xid"] # allow Unicode Standard Annex #31 for ident metadata = ["serde", "serde_json", "rhai_codegen/metadata", "smartstring/serde"] # enable exporting functions metadata internals = [] # expose internal data structures debugging = ["internals"] # enable debugging -static_hash = [] serde = ["dep:serde", "smartstring/serde", "smallvec/serde"] # implement serde for rhai types # compiling for no-std diff --git a/build.rs b/build.rs index a994ef69..e95b1dc3 100644 --- a/build.rs +++ b/build.rs @@ -8,21 +8,19 @@ fn main() { // Tell Cargo that if the given environment variable changes, to rerun this build script. println!("cargo:rerun-if-changed=build.template"); println!("cargo:rerun-if-env-changed=RHAI_AHASH_SEED"); - if !cfg!(feature = "stable_hash") { - let mut contents = String::new(); + let mut contents = String::new(); - File::open("build.template") - .expect("cannot open `build.template`") - .read_to_string(&mut contents) - .expect("cannot read from `build.template`"); + File::open("build.template") + .expect("cannot open `build.template`") + .read_to_string(&mut contents) + .expect("cannot read from `build.template`"); - let seed = env::var("RHAI_AHASH_SEED").map_or_else(|_| "None".into(), |s| format!("Some({s})")); + let seed = env::var("RHAI_AHASH_SEED").map_or_else(|_| "None".into(), |s| format!("Some({s})")); - contents = contents.replace("{{ AHASH_SEED }}", &seed); + contents = contents.replace("{{ AHASH_SEED }}", &seed); - File::create("src/config/hashing.rs") - .expect("cannot create `config.rs`") - .write_all(contents.as_bytes()) - .expect("cannot write to `config/hashing.rs`"); - } + File::create("src/config/hashing.rs") + .expect("cannot create `config.rs`") + .write_all(contents.as_bytes()) + .expect("cannot write to `config/hashing.rs`"); } diff --git a/build.template b/build.template index 709a3f65..89b0e403 100644 --- a/build.template +++ b/build.template @@ -10,120 +10,103 @@ //! E.g. `env RHAI_AHASH_SEED ="[236,800,954,213]"` // [236,800,954,213], haha funny yume nikki reference epic uboachan face numberworld nexus moment 100 -pub use internal::get_ahash_seed; -#[cfg(feature = "static_hash")] -pub use internal::set_ahash_seed; +use core::{ + cell::UnsafeCell, + marker::PhantomData, + mem::MaybeUninit, + panic::{RefUnwindSafe, UnwindSafe}, + sync::atomic::{AtomicBool, Ordering}, +}; -#[cfg(feature = "static_hash")] -mod internal { - use core::{ - cell::UnsafeCell, - marker::PhantomData, - mem::MaybeUninit, - sync::atomic::{AtomicBool, Ordering}, - panic::{RefUnwindSafe, UnwindSafe} - }; +// Safety: lol +struct SusLock +where + T: 'static, +{ + initalized: AtomicBool, + data: UnsafeCell>, + _marker: PhantomData, +} - struct SusLock where T: 'static { - initalized: AtomicBool, - data: UnsafeCell>, - _marker: PhantomData, - } - - impl SusLock { - pub const fn new() -> SusLock { - SusLock { - initalized: AtomicBool::new(false), - data: UnsafeCell::new(MaybeUninit::uninit()), - _marker: PhantomData - } - } - - pub fn get(&self) -> Option<&T> { - if self.initalized.load(Ordering::SeqCst) { - Some( - unsafe { - (&*self.data.get()).assume_init_ref() - } - ) - } else { - return None - } - } - - pub fn get_or_init(&self, f: impl FnOnce() -> T) -> Option<&T> { - let value = f(); - if !self.initalized.load(Ordering::SeqCst) { - unsafe { - self.data.get().write(MaybeUninit::new(value)); - } - self.initalized.store(true, Ordering::SeqCst); - } - - self.get() - } - - pub fn set(&self, value: T) -> Result<(), T> { - if self.initalized.load(Ordering::SeqCst) { - Err(value) - } else { - let _ = self.get_or_init(|| value); - Ok(()) - } +impl SusLock { + pub const fn new() -> SusLock { + SusLock { + initalized: AtomicBool::new(false), + data: UnsafeCell::new(MaybeUninit::uninit()), + _marker: PhantomData, } } - unsafe impl Sync for SusLock {} - unsafe impl Send for SusLock {} - impl RefUnwindSafe for SusLock {} - - impl Drop for SusLock { - fn drop(&mut self) { - if self.initalized.load(Ordering::SeqCst) { - unsafe { (&mut *self.data.get()).assume_init_drop() }; - } + pub fn get(&self) -> Option<&T> { + if self.initalized.load(Ordering::SeqCst) { + Some(unsafe { (&*self.data.get()).assume_init_ref() }) + } else { + return None; } } - static AHASH_SEED: SusLock> = SusLock::new(); + pub fn get_or_init(&self, f: impl FnOnce() -> T) -> Option<&T> { + let value = f(); + if !self.initalized.load(Ordering::SeqCst) { + unsafe { + self.data.get().write(MaybeUninit::new(value)); + } + self.initalized.store(true, Ordering::SeqCst); + } - // #[doc(cfg(feature = "stable_hash"))] - /// Sets the Rhai Ahash seed. This is used to hash functions and the like. - /// - /// This is a global variable, and thus will affect every Rhai instance. - /// This should not be used _unless_ you know you need it. - /// - /// # Warnings - /// - You can only call this function **ONCE** for the whole of your program execution. - /// - You should gracefully handle the `Err(())`. - /// - You **MUST** call this before **ANY** Rhai operation occurs (e.g. creating an [`Engine`]). - /// - /// # Errors - /// This will error if the AHashSeed is already set. - pub fn set_ahash_seed(new_seed: Option<[u64; 4]>) -> Result<(), Option<[u64; 4]>> { - AHASH_SEED.set(new_seed) + self.get() } - /// Gets the current Rhai Ahash Seed. If the seed is not yet defined, this will automatically set a seed. - /// The default seed is not stable and may change between versions. - /// - /// See [`set_rhai_ahash_seed`] for more. - pub fn get_ahash_seed() -> Option<[u64; 4]> { - const FUNNY_YUMENIKKI_REFERENCE: [u64; 4] = [236,800,954,213]; - - AHASH_SEED.get_or_init(|| Some(FUNNY_YUMENIKKI_REFERENCE)).map(|x| *x).flatten() + pub fn set(&self, value: T) -> Result<(), T> { + if self.initalized.load(Ordering::SeqCst) { + Err(value) + } else { + let _ = self.get_or_init(|| value); + Ok(()) + } } } -#[cfg(not(feature = "static_hash"))] -mod internal { - const AHASH_SEED: Option<[u64; 4]> = {{ AHASH_SEED }}; +unsafe impl Sync for SusLock {} +unsafe impl Send for SusLock {} +impl RefUnwindSafe for SusLock {} - /// Gets the current Rhai Ahash Seed. If the seed is not yet defined, this will automatically set a seed. - /// The default seed is not stable and may change between versions. - /// - /// See [`set_ahash_seed`] for more. - pub fn get_ahash_seed() -> Option<[u64; 4]> { - AHASH_SEED +impl Drop for SusLock { + fn drop(&mut self) { + if self.initalized.load(Ordering::SeqCst) { + unsafe { (&mut *self.data.get()).assume_init_drop() }; + } } -} \ No newline at end of file +} + +static AHASH_SEED: SusLock> = SusLock::new(); + +// #[doc(cfg(feature = "stable_hash"))] +/// Sets the Rhai Ahash seed. This is used to hash functions and the like. +/// +/// This is a global variable, and thus will affect every Rhai instance. +/// This should not be used _unless_ you know you need it. +/// +/// # Warnings +/// - You can only call this function **ONCE** for the whole of your program execution. +/// - You should gracefully handle the `Err(())`. +/// - You **MUST** call this before **ANY** Rhai operation occurs (e.g. creating an [`Engine`]). +/// +/// # Errors +/// This will error if the AHashSeed is already set. +pub fn set_ahash_seed(new_seed: Option<[u64; 4]>) -> Result<(), Option<[u64; 4]>> { + AHASH_SEED.set(new_seed) +} + +/// Gets the current Rhai Ahash Seed. If the seed is not yet defined, this will automatically set a seed. +/// The default seed is not stable and may change between versions. +/// +/// See [`set_rhai_ahash_seed`] for more. +pub fn get_ahash_seed() -> Option<[u64; 4]> { + const FUNNY_YUMENIKKI_REFERENCE: Option<[u64; 4]> = {{ AHASH_SEED }}; + + AHASH_SEED + .get_or_init(|| FUNNY_YUMENIKKI_REFERENCE) + .map(|x| *x) + .flatten() +} diff --git a/src/config/hashing.rs b/src/config/hashing.rs index 19423149..3f318fef 100644 --- a/src/config/hashing.rs +++ b/src/config/hashing.rs @@ -10,120 +10,103 @@ //! E.g. `env RHAI_AHASH_SEED ="[236,800,954,213]"` // [236,800,954,213], haha funny yume nikki reference epic uboachan face numberworld nexus moment 100 -pub use internal::get_ahash_seed; -#[cfg(feature = "static_hash")] -pub use internal::set_ahash_seed; +use core::{ + cell::UnsafeCell, + marker::PhantomData, + mem::MaybeUninit, + panic::{RefUnwindSafe, UnwindSafe}, + sync::atomic::{AtomicBool, Ordering}, +}; -#[cfg(feature = "static_hash")] -mod internal { - use core::{ - cell::UnsafeCell, - marker::PhantomData, - mem::MaybeUninit, - sync::atomic::{AtomicBool, Ordering}, - panic::{RefUnwindSafe, UnwindSafe} - }; +// Safety: lol +struct SusLock +where + T: 'static, +{ + initalized: AtomicBool, + data: UnsafeCell>, + _marker: PhantomData, +} - struct SusLock where T: 'static { - initalized: AtomicBool, - data: UnsafeCell>, - _marker: PhantomData, - } - - impl SusLock { - pub const fn new() -> SusLock { - SusLock { - initalized: AtomicBool::new(false), - data: UnsafeCell::new(MaybeUninit::uninit()), - _marker: PhantomData - } - } - - pub fn get(&self) -> Option<&T> { - if self.initalized.load(Ordering::SeqCst) { - Some( - unsafe { - (&*self.data.get()).assume_init_ref() - } - ) - } else { - return None - } - } - - pub fn get_or_init(&self, f: impl FnOnce() -> T) -> Option<&T> { - let value = f(); - if !self.initalized.load(Ordering::SeqCst) { - unsafe { - self.data.get().write(MaybeUninit::new(value)); - } - self.initalized.store(true, Ordering::SeqCst); - } - - self.get() - } - - pub fn set(&self, value: T) -> Result<(), T> { - if self.initalized.load(Ordering::SeqCst) { - Err(value) - } else { - let _ = self.get_or_init(|| value); - Ok(()) - } +impl SusLock { + pub const fn new() -> SusLock { + SusLock { + initalized: AtomicBool::new(false), + data: UnsafeCell::new(MaybeUninit::uninit()), + _marker: PhantomData, } } - unsafe impl Sync for SusLock {} - unsafe impl Send for SusLock {} - impl RefUnwindSafe for SusLock {} - - impl Drop for SusLock { - fn drop(&mut self) { - if self.initalized.load(Ordering::SeqCst) { - unsafe { (&mut *self.data.get()).assume_init_drop() }; - } + pub fn get(&self) -> Option<&T> { + if self.initalized.load(Ordering::SeqCst) { + Some(unsafe { (&*self.data.get()).assume_init_ref() }) + } else { + return None; } } - static AHASH_SEED: SusLock> = SusLock::new(); + pub fn get_or_init(&self, f: impl FnOnce() -> T) -> Option<&T> { + let value = f(); + if !self.initalized.load(Ordering::SeqCst) { + unsafe { + self.data.get().write(MaybeUninit::new(value)); + } + self.initalized.store(true, Ordering::SeqCst); + } - // #[doc(cfg(feature = "stable_hash"))] - /// Sets the Rhai Ahash seed. This is used to hash functions and the like. - /// - /// This is a global variable, and thus will affect every Rhai instance. - /// This should not be used _unless_ you know you need it. - /// - /// # Warnings - /// - You can only call this function **ONCE** for the whole of your program execution. - /// - You should gracefully handle the `Err(())`. - /// - You **MUST** call this before **ANY** Rhai operation occurs (e.g. creating an [`Engine`]). - /// - /// # Errors - /// This will error if the AHashSeed is already set. - pub fn set_ahash_seed(new_seed: Option<[u64; 4]>) -> Result<(), Option<[u64; 4]>> { - AHASH_SEED.set(new_seed) + self.get() } - /// Gets the current Rhai Ahash Seed. If the seed is not yet defined, this will automatically set a seed. - /// The default seed is not stable and may change between versions. - /// - /// See [`set_rhai_ahash_seed`] for more. - pub fn get_ahash_seed() -> Option<[u64; 4]> { - const FUNNY_YUMENIKKI_REFERENCE: [u64; 4] = [236,800,954,213]; - - AHASH_SEED.get_or_init(|| Some(FUNNY_YUMENIKKI_REFERENCE)).map(|x| *x).flatten() + pub fn set(&self, value: T) -> Result<(), T> { + if self.initalized.load(Ordering::SeqCst) { + Err(value) + } else { + let _ = self.get_or_init(|| value); + Ok(()) + } } } -#[cfg(not(feature = "static_hash"))] -mod internal { - const AHASH_SEED: Option<[u64; 4]> = None; +unsafe impl Sync for SusLock {} +unsafe impl Send for SusLock {} +impl RefUnwindSafe for SusLock {} - /// Gets the current Rhai Ahash Seed. If the seed is not yet defined, this will automatically set a seed. - /// The default seed is not stable and may change between versions. - /// - /// See [`set_ahash_seed`] for more. - pub fn get_ahash_seed() -> Option<[u64; 4]> { - AHASH_SEED +impl Drop for SusLock { + fn drop(&mut self) { + if self.initalized.load(Ordering::SeqCst) { + unsafe { (&mut *self.data.get()).assume_init_drop() }; + } } -} \ No newline at end of file +} + +static AHASH_SEED: SusLock> = SusLock::new(); + +// #[doc(cfg(feature = "stable_hash"))] +/// Sets the Rhai Ahash seed. This is used to hash functions and the like. +/// +/// This is a global variable, and thus will affect every Rhai instance. +/// This should not be used _unless_ you know you need it. +/// +/// # Warnings +/// - You can only call this function **ONCE** for the whole of your program execution. +/// - You should gracefully handle the `Err(())`. +/// - You **MUST** call this before **ANY** Rhai operation occurs (e.g. creating an [`Engine`]). +/// +/// # Errors +/// This will error if the AHashSeed is already set. +pub fn set_ahash_seed(new_seed: Option<[u64; 4]>) -> Result<(), Option<[u64; 4]>> { + AHASH_SEED.set(new_seed) +} + +/// Gets the current Rhai Ahash Seed. If the seed is not yet defined, this will automatically set a seed. +/// The default seed is not stable and may change between versions. +/// +/// See [`set_rhai_ahash_seed`] for more. +pub fn get_ahash_seed() -> Option<[u64; 4]> { + const FUNNY_YUMENIKKI_REFERENCE: Option<[u64; 4]> = None; + + AHASH_SEED + .get_or_init(|| FUNNY_YUMENIKKI_REFERENCE) + .map(|x| *x) + .flatten() +} diff --git a/src/config/mod.rs b/src/config/mod.rs index 194ac6da..e2748d4a 100644 --- a/src/config/mod.rs +++ b/src/config/mod.rs @@ -1,3 +1,3 @@ //! Contains Configuration for Rhai. -pub mod hashing; \ No newline at end of file +pub mod hashing;