use std::collections::{HashMap, VecDeque}; use crsn::asm::data::literal::Value; use crsn::asm::instr::Cond; use crsn::module::{CrsnExtension, EvalRes, OpTrait}; use crsn::runtime::fault::Fault; use crsn::runtime::run_thread::{state::RunState, ThreadInfo}; use crate::defs::StackOp; #[derive(Debug, Default)] struct Stacks { store: HashMap>, } impl OpTrait for StackOp { fn execute(&self, info: &ThreadInfo, state: &mut RunState) -> Result { let eres = EvalRes::default(); match self { StackOp::NewStack { dst } => { let id = info.uniq(); let stacks: &mut Stacks = state.ext_mut(); stacks.store.insert(id, VecDeque::new()); state.write(*dst, id)?; } StackOp::Push { obj, src } => { state.clear_status(); let handle = state.read_obj(*obj)?; let val = state.read(*src)?; let stacks: &mut Stacks = state.ext_mut(); stacks.store.get_mut(&handle) .ok_or_else(|| Fault::ObjectNotExist(handle))? .push_back(val); } StackOp::Pop { dst, obj } => { state.clear_status(); let handle = state.read_obj(*obj)?; let stacks: &mut Stacks = state.ext_mut(); let stack = stacks.store.get_mut(&handle) .ok_or_else(|| Fault::ObjectNotExist(handle))?; let val = stack.pop_back(); if stack.is_empty() { state.set_flag(Cond::Zero, true); } let val = match val { None => { state.set_flag(Cond::Overflow, true); 0 } Some(val) => { val } }; state.write(*dst, val)?; } } Ok(eres) } // } pub(crate) fn drop_stack(state: &mut RunState, handle: Value) -> Result, Fault> { let stacks: &mut Stacks = state.ext_mut(); Ok(stacks.store.remove(&handle).map(|_| ())) }