From 3e6a3a2759dba46ae976497e65c89040311edfa3 Mon Sep 17 00:00:00 2001 From: l1npengtul Date: Mon, 31 Oct 2022 22:14:09 +0900 Subject: [PATCH] Stable Hash: Add feature, adjust CI, modify build.rs, add new API for accessing and setting the ahash seed in config.rs, make config.rs public --- .github/workflows/build.yml | 31 +++++++++++++++++++ .gitignore | 3 ++ Cargo.toml | 1 + build.rs | 25 +++++++-------- build.template | 61 ++++++++++++++++++++++++++++++++++--- src/config.rs | 53 +++++++++++++++++++++++++++++--- src/func/hashing.rs | 2 +- src/lib.rs | 4 ++- 8 files changed, 157 insertions(+), 23 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 6823d676..11ca384f 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -89,6 +89,37 @@ jobs: command: test args: ${{matrix.flags}} + nightly_features_build: + name: NightlyFeatureBuild + runs-on: ${{matrix.os}} + continue-on-error: ${{matrix.experimental}} + strategy: + matrix: + os: [ubuntu-latest] + flags: + - "--features stable_hash" + toolchain: [ nightly ] + experimental: [ false ] + include: + # smoketests for different toolchains + - { toolchain: nightly, os: windows-latest, experimental: false, flags: "" } + - { toolchain: nightly, os: macos-latest, experimental: false, flags: "" } + fail-fast: false + steps: + - name: Checkout + uses: actions/checkout@v2 + - name: Setup Toolchain + uses: actions-rs/toolchain@v1 + with: + toolchain: ${{matrix.toolchain}} + override: true + - name: Test + uses: actions-rs/cargo@v1 + with: + command: test + args: ${{matrix.flags}} + + # no-std builds are a bit more extensive to test no_std_build: name: NoStdBuild diff --git a/.gitignore b/.gitignore index fe87b992..10e86a86 100644 --- a/.gitignore +++ b/.gitignore @@ -8,3 +8,6 @@ Rhai.toml **/*.bat doc/rhai-sync.json doc/rhai.json +.idea/ +.idea +.idea/* diff --git a/Cargo.toml b/Cargo.toml index 3999b7de..310ceb40 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -63,6 +63,7 @@ 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 +stable_hash = ["std"] 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 66903154..76abd9ee 100644 --- a/build.rs +++ b/build.rs @@ -8,20 +8,21 @@ 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.rs") - .expect("cannot create `config.rs`") - .write(contents.as_bytes()) - .expect("cannot write to `config.rs`"); + File::create("src/config.rs") + .expect("cannot create `config.rs`") + .write_all(contents.as_bytes()) + .expect("cannot write to `config.rs`"); + } } diff --git a/build.template b/build.template index 6f09909f..ed5e161d 100644 --- a/build.template +++ b/build.template @@ -1,7 +1,60 @@ -//! Configuration settings for this Rhai build -//! -//! This file is auto-generated from `build.template` +#[cfg(feature = "stable_hash")] +use core::cell::OnceCell; +// [236,800,954,213], haha funny yume nikki reference + +#[cfg(not(feature = "stable_hash"))] /// Fixed hashing seeds for stable hashing. +/// /// Set to [`None`] to disable stable hashing. -pub const AHASH_SEED: Option<[u64; 4]> = {{AHASH_SEED}}; +/// +/// See [`set_rhai_ahash_seed`] for more. +/// +/// You can also set this at compile time by disabling `stable_hash` and setting the `RHAI_AHASH_SEED` +/// environment variable instead. +/// +/// E.g. `env RHAI_AHASH_SEED ="[236,800,954,213]"` +const AHASH_SEED: Option<[u64; 4]> = {{AHASH_SEED}}; +#[cfg(feature = "stable_hash")] +/// Fixed hashing seeds for stable hashing. +/// +/// Set to [`None`] to disable stable hashing. +/// +/// See [`set_rhai_ahash_seed`] for more. +/// +/// You can also set this at compile time by disabling `stable_hash` and setting the `RHAI_AHASH_SEED` +/// environment variable instead. +/// +/// E.g. `env RHAI_AHASH_SEED ="[236,800,954,213]"` +static AHASH_SEED: OnceCell> = OnceCell::new(); + +#[cfg(feature = "stable_hash")] +#[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. +/// +/// **WARNING**: +/// - 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`]). +pub fn set_rhai_ahash_seed(new_seed: Option<[u64; 4]>) -> Result<(), Option<[u64; 4]>> { + AHASH_SEED.set(new_seed) +} + +#[cfg(feature = "stable_hash")] +/// Gets the current Rhai Ahash Seed. +/// +/// See [`set_rhai_ahash_seed`] for more. +pub fn get_rhai_ahash_seed() -> Option<[u64; 4]> { + AHASH_SEED.get().map(|x| *x).flatten() +} + +#[cfg(not(feature = "stable_hash"))] +/// Gets the current Rhai Ahash Seed. +/// +/// See [`AHASH_SEED`] and [`set_rhai_ahash_seed`] for more. +pub fn get_rhai_ahash_seed() -> Option<[u64; 4]> { + AHASH_SEED +} \ No newline at end of file diff --git a/src/config.rs b/src/config.rs index 93db79d5..4297fa07 100644 --- a/src/config.rs +++ b/src/config.rs @@ -1,7 +1,50 @@ -//! Configuration settings for this Rhai build +//! Fixed hashing seeds for stable hashing. //! -//! This file is auto-generated from `build.template` +//! Set to [`None`] to disable stable hashing. +//! +//! See [`set_rhai_ahash_seed`] for more. +//! +//! Alternatively, You can also set this at compile time by disabling `stable_hash` and setting the `RHAI_AHASH_SEED` +//! environment variable instead. +//! +//! 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 -/// Fixed hashing seeds for stable hashing. -/// Set to [`None`] to disable stable hashing. -pub const AHASH_SEED: Option<[u64; 4]> = None; +#[cfg(feature = "stable_hash")] +use std::sync::OnceLock; + +#[cfg(not(feature = "stable_hash"))] +const AHASH_SEED: Option<[u64; 4]> = None; +#[cfg(feature = "stable_hash")] +static AHASH_SEED: OnceLock> = OnceLock::new(); + +#[cfg(feature = "stable_hash")] +// #[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. +/// +/// **WARNING**: +/// - 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`]). +pub fn set_rhai_ahash_seed(new_seed: Option<[u64; 4]>) -> Result<(), Option<[u64; 4]>> { + AHASH_SEED.set(new_seed) +} + +#[cfg(feature = "stable_hash")] +/// Gets the current Rhai Ahash Seed. +/// +/// See [`set_rhai_ahash_seed`] for more. +pub fn get_rhai_ahash_seed() -> Option<[u64; 4]> { + AHASH_SEED.get().map(|x| *x).flatten() +} + +#[cfg(not(feature = "stable_hash"))] +/// Gets the current Rhai Ahash Seed. +/// +/// See [`AHASH_SEED`] and [`set_rhai_ahash_seed`] for more. +pub fn get_rhai_ahash_seed() -> Option<[u64; 4]> { + AHASH_SEED +} diff --git a/src/func/hashing.rs b/src/func/hashing.rs index 5f6a806c..406a21c6 100644 --- a/src/func/hashing.rs +++ b/src/func/hashing.rs @@ -77,7 +77,7 @@ impl BuildHasher for StraightHasherBuilder { #[inline(always)] #[must_use] pub fn get_hasher() -> ahash::AHasher { - match config::AHASH_SEED { + match config::get_rhai_ahash_seed() { Some([seed1, seed2, seed3, seed4]) if seed1 | seed2 | seed3 | seed4 != 0 => { ahash::RandomState::with_seeds(seed1, seed2, seed3, seed4).build_hasher() } diff --git a/src/lib.rs b/src/lib.rs index 199edb75..d2d6eae7 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -71,6 +71,8 @@ #![allow(clippy::negative_feature_names)] #![allow(clippy::module_inception)] +#![cfg_attr(feature = "stable_hash", feature(once_cell))] + #[cfg(feature = "no_std")] extern crate alloc; @@ -83,7 +85,7 @@ use std::prelude::v1::*; // Internal modules mod api; mod ast; -mod config; +pub mod config; mod engine; mod eval; mod func;