Skip to content

Commit

Permalink
core: fix how cf and ch controls execution
Browse files Browse the repository at this point in the history
  • Loading branch information
dr-orlovsky committed Oct 22, 2024
1 parent b57aab8 commit ed3602e
Show file tree
Hide file tree
Showing 4 changed files with 37 additions and 23 deletions.
23 changes: 7 additions & 16 deletions src/core/core.rs
Original file line number Diff line number Diff line change
Expand Up @@ -89,14 +89,14 @@ pub struct Core<Id: SiteId, const CALL_STACK_SIZE: usize = { CALL_STACK_SIZE_MAX

// --------------------------------------------------------------------------------------------
// Control flow registers
/// Halt register. If set to `true`, halts program when `ck` is set to `true` for the first
/// time.
/// Halt register. If set to `true`, halts program when `ck` is set to [`Status::Failed`] for
/// the first time.
///
/// # See also
///
/// - [`Core::ck`] register
/// - [`Core::cf`] register
ch: bool,
pub(super) ch: bool,

/// Check register, which is set on any failure (accessing register in `None` state, zero
/// division etc.). Can be reset.
Expand All @@ -107,13 +107,13 @@ pub struct Core<Id: SiteId, const CALL_STACK_SIZE: usize = { CALL_STACK_SIZE_MAX
/// - [`Core::cf`] register
pub(super) ck: Status,

/// Failure register, which is set on the first time `ck` is set, and can't be reset.
/// Failure register, which counts how many times `ck` was set, and can't be reset.
///
/// # See also
///
/// - [`Core::ch`] register
/// - [`Core::ck`] register
cf: Status,
pub(super) cf: u64,

/// Test register, which acts as boolean test result (also a carry flag).
pub(super) co: bool,
Expand All @@ -137,7 +137,7 @@ pub struct Core<Id: SiteId, const CALL_STACK_SIZE: usize = { CALL_STACK_SIZE_MAX
///
/// If this register has a value set, once [`Core::ca`] will reach this value the VM will
/// stop program execution setting `ck` to `false`.
cl: Option<u64>,
pub(super) cl: Option<u64>,

/// Call stack.
///
Expand Down Expand Up @@ -208,7 +208,7 @@ impl<Id: SiteId, const CALL_STACK_SIZE: usize> Core<Id, CALL_STACK_SIZE> {
//b: Default::default(),
ch: config.halt,
ck: Status::Ok,
cf: Status::Ok,
cf: 0,
co: false,
cy: 0,
ca: 0,
Expand All @@ -218,15 +218,6 @@ impl<Id: SiteId, const CALL_STACK_SIZE: usize> Core<Id, CALL_STACK_SIZE> {
}
}

/// Microcode for flag registers.
impl<Id: SiteId, const CALL_STACK_SIZE: usize> Core<Id, CALL_STACK_SIZE> {
/// Return whether check register `ck` was set to a failed state for at least once.
pub fn had_failed(&self) -> bool { self.cf == Status::Fail }

/// Return complexity limit value.
pub fn cl(&self) -> Option<u64> { self.cl }
}

impl<Id: SiteId, const CALL_STACK_SIZE: usize> Debug for Core<Id, CALL_STACK_SIZE> {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
let (sect, reg, val, reset) =
Expand Down
17 changes: 15 additions & 2 deletions src/core/microcode/base.rs
Original file line number Diff line number Diff line change
Expand Up @@ -202,13 +202,23 @@ impl<Id: SiteId, const CALL_STACK_SIZE: usize> Core<Id, CALL_STACK_SIZE> {
pub fn co(&self) -> bool { self.co }

/// Set overflow/carry flag to a value.
pub fn set_co(&mut self, co: bool) { self.co = co }
pub fn set_co(&mut self, co: bool) { self.co = co; }

/// Return whether check register `ck` was set to a failed state for at least once.
pub fn cf(&self) -> u64 { self.cf }

/// Return whether check register `ck` was set to a failed state for at least once.
pub fn ck(&self) -> Status { self.ck }

/// Set `ck` register to a failed state.
pub fn fail_ck(&mut self) { self.ck = Status::Fail }
///
/// Returns whether further execution should be stopped (i.e. `ch` register value).
#[must_use]
pub fn fail_ck(&mut self) -> bool {
self.ck = Status::Fail;
self.cf += 1;
self.ch
}

/// Reset `ck` register.
pub fn reset_ck(&mut self) { self.ck = Status::Ok }
Expand All @@ -229,6 +239,9 @@ impl<Id: SiteId, const CALL_STACK_SIZE: usize> Core<Id, CALL_STACK_SIZE> {
/// Pops a call stack item.
pub fn pop_cs(&mut self) -> Option<Site<Id>> { self.cs.pop() }

/// Return complexity limit value.
pub fn cl(&self) -> Option<u64> { self.cl }

/// Accumulate complexity value.
///
/// # Returns
Expand Down
10 changes: 8 additions & 2 deletions src/isa/alu/exec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,11 @@ impl<Id: SiteId> Instruction<Id> for CtrlInstr<Id> {
return ExecStep::Stop;
}
}
CtrlInstr::FailCk => core.fail_ck(),
CtrlInstr::FailCk => {
if core.fail_ck() {
return ExecStep::Stop;
}
}
CtrlInstr::RsetCk => {
core.set_co(core.ck() == Status::Fail);
core.reset_ck()
Expand Down Expand Up @@ -209,7 +213,9 @@ impl<Id: SiteId> Instruction<Id> for RegInstr {
dst: _,
val: MaybeU128::NoData,
} => {
core.fail_ck();
if core.fail_ck() {
return ExecStep::Stop;
}
}
RegInstr::Put {
dst,
Expand Down
10 changes: 7 additions & 3 deletions src/library/exec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ impl Lib {
return None;
}
ExecStep::StopFail => {
registers.fail_ck();
let _ = registers.fail_ck();
#[cfg(feature = "log")]
eprintln!("halting, {d}ck{z} is set to {r}false{z}");
return None;
Expand All @@ -123,7 +123,11 @@ impl Lib {
continue;
}
ExecStep::NextFail => {
registers.fail_ck();
if registers.fail_ck() {
#[cfg(feature = "log")]
eprintln!("halting, {d}ck{z} is set to {r}false{z} and {d}ch{z} is {r}true{z}");
return None;
}
#[cfg(feature = "log")]
eprintln!("failing, {d}ck{z} is set to {r}false{z}");
continue;
Expand All @@ -132,7 +136,7 @@ impl Lib {
#[cfg(feature = "log")]
eprintln!("{}", pos);
if marshaller.seek(pos).is_err() {
registers.fail_ck();
let _ = registers.fail_ck();
#[cfg(feature = "log")]
eprintln!("jump to non-existing offset; halting, {d}ck{z} is set to {r}fail{z}");
return None;
Expand Down

0 comments on commit ed3602e

Please sign in to comment.