diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index c9c1eccc..cf4e2368 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -22,6 +22,7 @@ jobs: run: | cargo test --all-features cargo test --release --all-features + cargo bench msrv_test_suite: runs-on: ubuntu-latest diff --git a/starlight/src/ensemble/state.rs b/starlight/src/ensemble/state.rs index ce52eb64..446c085c 100644 --- a/starlight/src/ensemble/state.rs +++ b/starlight/src/ensemble/state.rs @@ -12,7 +12,10 @@ use awint::awint_dag::{ use super::{Referent, Value}; use crate::{ awi, - ensemble::{Ensemble, PBack}, + ensemble::{ + value::{Change, Eval}, + Ensemble, PBack, + }, epoch::EpochShared, }; @@ -130,6 +133,23 @@ impl Ensemble { let source = self.stator.states[p_state].op.operands()[i]; self.dec_rc(source).unwrap(); } + // if the `op` is manually replaced outside of the specially handled lowering + // `Copy` replacements, we need to check the values or else this change could be + // lost if this was done after initializing `p_self_bits` + let state = &mut self.stator.states[p_state]; + if !state.p_self_bits.is_empty() { + assert_eq!(state.p_self_bits.len(), x.bw()); + for i in 0..x.bw() { + if let Some(p_bit) = state.p_self_bits[i] { + let p_equiv = self.backrefs.get_val(p_bit).unwrap().p_self_equiv; + self.evaluator.insert(Eval::Change(Change { + depth: 0, + p_equiv, + value: Value::Const(x.get(i).unwrap()), + })); + } + } + } self.stator.states[p_state].op = Literal(x); Ok(()) } diff --git a/starlight/src/ensemble/value.rs b/starlight/src/ensemble/value.rs index e0750874..1f586c59 100644 --- a/starlight/src/ensemble/value.rs +++ b/starlight/src/ensemble/value.rs @@ -88,16 +88,16 @@ pub enum EvalPhase { #[derive(Debug, Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord)] pub struct RequestTNode { - depth: i64, - number_a: u8, - p_back_tnode: PBack, + pub depth: i64, + pub number_a: u8, + pub p_back_tnode: PBack, } #[derive(Debug, Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord)] pub struct Change { - depth: i64, - p_equiv: PBack, - value: Value, + pub depth: i64, + pub p_equiv: PBack, + pub value: Value, } #[derive(Debug, Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord)] @@ -430,7 +430,13 @@ impl Ensemble { Eval::Change(change) => { let equiv = self.backrefs.get_val_mut(change.p_equiv).unwrap(); equiv.change_visit = self.evaluator.change_visit_gen(); - equiv.val = change.value; + // Handles a rare case where the evaluator decides to change to a const, and + // something later tries to set it to an unknown. TODO not sure if this is a bug + // that should be resolved some other way, the relevant part is where `Change`s + // are pushed in `eval_state`. + if !equiv.val.is_const() { + equiv.val = change.value; + } let mut adv = self.backrefs.advancer_surject(change.p_equiv); while let Some(p_back) = adv.advance(&self.backrefs) { let referent = *self.backrefs.get_key(p_back).unwrap(); diff --git a/testcrate/src/lib.rs b/testcrate/src/lib.rs index 22162f35..806fa525 100644 --- a/testcrate/src/lib.rs +++ b/testcrate/src/lib.rs @@ -2,6 +2,6 @@ use std::path::PathBuf; use starlight::{awint_dag::EvalError, Epoch}; -fn _render(epoch: &Epoch) -> Result<(), EvalError> { +pub fn _render(epoch: &Epoch) -> Result<(), EvalError> { epoch.render_to_svgs_in_dir(PathBuf::from("./".to_owned())) } diff --git a/testcrate/tests/fuzz_lower.rs b/testcrate/tests/fuzz_lower.rs index 9cd79fcd..ac1fe316 100644 --- a/testcrate/tests/fuzz_lower.rs +++ b/testcrate/tests/fuzz_lower.rs @@ -1,3 +1,5 @@ +// This is copied from `fuzzing` in `awint` and should be kept up to date + use std::{ cmp::{max, min}, num::NonZeroUsize, @@ -16,12 +18,10 @@ use starlight::{ }; // miri is just here to check that the unsized deref hacks are working -const N: (u32, u32) = if cfg!(miri) { - (1, 1) -} else if cfg!(debug_assertions) { - (32, 100) +const N: (u32, u32) = if cfg!(debug_assertions) { + (32, 30) } else { - (32, 1000) + (32, 300) }; ptr_struct!(P0);