remove stable hash and fix CI

This commit is contained in:
l1npengtul 2022-11-01 21:25:45 +09:00
parent 79e7c305bf
commit 5816d571b3
5 changed files with 180 additions and 217 deletions

View File

@ -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 metadata = ["serde", "serde_json", "rhai_codegen/metadata", "smartstring/serde"] # enable exporting functions metadata
internals = [] # expose internal data structures internals = [] # expose internal data structures
debugging = ["internals"] # enable debugging debugging = ["internals"] # enable debugging
static_hash = []
serde = ["dep:serde", "smartstring/serde", "smallvec/serde"] # implement serde for rhai types serde = ["dep:serde", "smartstring/serde", "smallvec/serde"] # implement serde for rhai types
# compiling for no-std # compiling for no-std

View File

@ -8,21 +8,19 @@ fn main() {
// Tell Cargo that if the given environment variable changes, to rerun this build script. // 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-changed=build.template");
println!("cargo:rerun-if-env-changed=RHAI_AHASH_SEED"); 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") File::open("build.template")
.expect("cannot open `build.template`") .expect("cannot open `build.template`")
.read_to_string(&mut contents) .read_to_string(&mut contents)
.expect("cannot read from `build.template`"); .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") File::create("src/config/hashing.rs")
.expect("cannot create `config.rs`") .expect("cannot create `config.rs`")
.write_all(contents.as_bytes()) .write_all(contents.as_bytes())
.expect("cannot write to `config/hashing.rs`"); .expect("cannot write to `config/hashing.rs`");
}
} }

View File

@ -10,120 +10,103 @@
//! E.g. `env RHAI_AHASH_SEED ="[236,800,954,213]"` //! 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 // [236,800,954,213], haha funny yume nikki reference epic uboachan face numberworld nexus moment 100
pub use internal::get_ahash_seed; use core::{
#[cfg(feature = "static_hash")] cell::UnsafeCell,
pub use internal::set_ahash_seed; marker::PhantomData,
mem::MaybeUninit,
panic::{RefUnwindSafe, UnwindSafe},
sync::atomic::{AtomicBool, Ordering},
};
#[cfg(feature = "static_hash")] // Safety: lol
mod internal { struct SusLock<T>
use core::{ where
cell::UnsafeCell, T: 'static,
marker::PhantomData, {
mem::MaybeUninit, initalized: AtomicBool,
sync::atomic::{AtomicBool, Ordering}, data: UnsafeCell<MaybeUninit<T>>,
panic::{RefUnwindSafe, UnwindSafe} _marker: PhantomData<T>,
}; }
struct SusLock<T> where T: 'static { impl<T> SusLock<T> {
initalized: AtomicBool, pub const fn new() -> SusLock<T> {
data: UnsafeCell<MaybeUninit<T>>, SusLock {
_marker: PhantomData<T>, initalized: AtomicBool::new(false),
} data: UnsafeCell::new(MaybeUninit::uninit()),
_marker: PhantomData,
impl<T> SusLock<T> {
pub const fn new() -> SusLock<T> {
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(())
}
} }
} }
unsafe impl<T: Sync + Send> Sync for SusLock<T> {} pub fn get(&self) -> Option<&T> {
unsafe impl<T: Send> Send for SusLock<T> {} if self.initalized.load(Ordering::SeqCst) {
impl<T: RefUnwindSafe + UnwindSafe> RefUnwindSafe for SusLock<T> {} Some(unsafe { (&*self.data.get()).assume_init_ref() })
} else {
impl<T> Drop for SusLock<T> { return None;
fn drop(&mut self) {
if self.initalized.load(Ordering::SeqCst) {
unsafe { (&mut *self.data.get()).assume_init_drop() };
}
} }
} }
static AHASH_SEED: SusLock<Option<[u64; 4]>> = 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"))] self.get()
/// 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. pub fn set(&self, value: T) -> Result<(), T> {
/// The default seed is not stable and may change between versions. if self.initalized.load(Ordering::SeqCst) {
/// Err(value)
/// See [`set_rhai_ahash_seed`] for more. } else {
pub fn get_ahash_seed() -> Option<[u64; 4]> { let _ = self.get_or_init(|| value);
const FUNNY_YUMENIKKI_REFERENCE: [u64; 4] = [236,800,954,213]; Ok(())
}
AHASH_SEED.get_or_init(|| Some(FUNNY_YUMENIKKI_REFERENCE)).map(|x| *x).flatten()
} }
} }
#[cfg(not(feature = "static_hash"))] unsafe impl<T: Sync + Send> Sync for SusLock<T> {}
mod internal { unsafe impl<T: Send> Send for SusLock<T> {}
const AHASH_SEED: Option<[u64; 4]> = {{ AHASH_SEED }}; impl<T: RefUnwindSafe + UnwindSafe> RefUnwindSafe for SusLock<T> {}
/// Gets the current Rhai Ahash Seed. If the seed is not yet defined, this will automatically set a seed. impl<T> Drop for SusLock<T> {
/// The default seed is not stable and may change between versions. fn drop(&mut self) {
/// if self.initalized.load(Ordering::SeqCst) {
/// See [`set_ahash_seed`] for more. unsafe { (&mut *self.data.get()).assume_init_drop() };
pub fn get_ahash_seed() -> Option<[u64; 4]> { }
AHASH_SEED
} }
} }
static AHASH_SEED: SusLock<Option<[u64; 4]>> = 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()
}

View File

@ -10,120 +10,103 @@
//! E.g. `env RHAI_AHASH_SEED ="[236,800,954,213]"` //! 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 // [236,800,954,213], haha funny yume nikki reference epic uboachan face numberworld nexus moment 100
pub use internal::get_ahash_seed; use core::{
#[cfg(feature = "static_hash")] cell::UnsafeCell,
pub use internal::set_ahash_seed; marker::PhantomData,
mem::MaybeUninit,
panic::{RefUnwindSafe, UnwindSafe},
sync::atomic::{AtomicBool, Ordering},
};
#[cfg(feature = "static_hash")] // Safety: lol
mod internal { struct SusLock<T>
use core::{ where
cell::UnsafeCell, T: 'static,
marker::PhantomData, {
mem::MaybeUninit, initalized: AtomicBool,
sync::atomic::{AtomicBool, Ordering}, data: UnsafeCell<MaybeUninit<T>>,
panic::{RefUnwindSafe, UnwindSafe} _marker: PhantomData<T>,
}; }
struct SusLock<T> where T: 'static { impl<T> SusLock<T> {
initalized: AtomicBool, pub const fn new() -> SusLock<T> {
data: UnsafeCell<MaybeUninit<T>>, SusLock {
_marker: PhantomData<T>, initalized: AtomicBool::new(false),
} data: UnsafeCell::new(MaybeUninit::uninit()),
_marker: PhantomData,
impl<T> SusLock<T> {
pub const fn new() -> SusLock<T> {
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(())
}
} }
} }
unsafe impl<T: Sync + Send> Sync for SusLock<T> {} pub fn get(&self) -> Option<&T> {
unsafe impl<T: Send> Send for SusLock<T> {} if self.initalized.load(Ordering::SeqCst) {
impl<T: RefUnwindSafe + UnwindSafe> RefUnwindSafe for SusLock<T> {} Some(unsafe { (&*self.data.get()).assume_init_ref() })
} else {
impl<T> Drop for SusLock<T> { return None;
fn drop(&mut self) {
if self.initalized.load(Ordering::SeqCst) {
unsafe { (&mut *self.data.get()).assume_init_drop() };
}
} }
} }
static AHASH_SEED: SusLock<Option<[u64; 4]>> = 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"))] self.get()
/// 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. pub fn set(&self, value: T) -> Result<(), T> {
/// The default seed is not stable and may change between versions. if self.initalized.load(Ordering::SeqCst) {
/// Err(value)
/// See [`set_rhai_ahash_seed`] for more. } else {
pub fn get_ahash_seed() -> Option<[u64; 4]> { let _ = self.get_or_init(|| value);
const FUNNY_YUMENIKKI_REFERENCE: [u64; 4] = [236,800,954,213]; Ok(())
}
AHASH_SEED.get_or_init(|| Some(FUNNY_YUMENIKKI_REFERENCE)).map(|x| *x).flatten()
} }
} }
#[cfg(not(feature = "static_hash"))] unsafe impl<T: Sync + Send> Sync for SusLock<T> {}
mod internal { unsafe impl<T: Send> Send for SusLock<T> {}
const AHASH_SEED: Option<[u64; 4]> = None; impl<T: RefUnwindSafe + UnwindSafe> RefUnwindSafe for SusLock<T> {}
/// Gets the current Rhai Ahash Seed. If the seed is not yet defined, this will automatically set a seed. impl<T> Drop for SusLock<T> {
/// The default seed is not stable and may change between versions. fn drop(&mut self) {
/// if self.initalized.load(Ordering::SeqCst) {
/// See [`set_ahash_seed`] for more. unsafe { (&mut *self.data.get()).assume_init_drop() };
pub fn get_ahash_seed() -> Option<[u64; 4]> { }
AHASH_SEED
} }
} }
static AHASH_SEED: SusLock<Option<[u64; 4]>> = 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()
}

View File

@ -1,3 +1,3 @@
//! Contains Configuration for Rhai. //! Contains Configuration for Rhai.
pub mod hashing; pub mod hashing;