use crate::value::Value;
use alloc::vec::Vec;
use super::{
errors::{Result, VmError},
execution_model::ExecutionState,
machine::RegoVM,
};
impl RegoVM {
pub(super) fn reset_execution_state(&mut self) {
self.executed_instructions = 0;
self.pc = 0;
self.evaluated = Value::new_object();
self.cache_hits = 0;
self.execution_stack.clear();
self.execution_state = ExecutionState::Ready;
self.return_to_pools();
self.rule_cache = alloc::vec![(false, Value::Undefined); self.program.rule_infos.len()];
self.registers.clear();
self.registers
.resize(self.base_register_count, Value::Undefined);
self.builtins_cache.clear();
}
pub(super) fn return_to_pools(&mut self) {
self.loop_stack.clear();
self.call_rule_stack.clear();
self.comprehension_stack.clear();
while let Some(registers) = self.register_stack.pop() {
self.return_register_window(registers);
}
}
pub(super) fn new_register_window(&mut self) -> Vec<Value> {
self.register_window_pool.pop().unwrap_or_default()
}
pub(super) fn return_register_window(&mut self, mut window: Vec<Value>) {
window.clear(); self.register_window_pool.push(window);
}
pub(super) fn validate_vm_state(&self) -> Result<()> {
if self.registers.len() < self.base_register_count {
return Err(VmError::RegisterCountBelowBase {
register_count: self.registers.len(),
base_count: self.base_register_count,
pc: self.pc,
});
}
if self.pc >= self.program.instructions.len() {
return Err(VmError::ProgramCounterOutOfBounds {
pc: self.pc,
instruction_count: self.program.instructions.len(),
});
}
if self.rule_cache.len() != self.program.rule_infos.len() {
return Err(VmError::RuleCacheSizeMismatch {
cache_size: self.rule_cache.len(),
rule_info_count: self.program.rule_infos.len(),
pc: self.pc,
});
}
Ok(())
}
}