add more sensible API for object handles, add drop instruction

This commit is contained in:
2020-09-28 19:36:15 +02:00
parent 79d5aa3cd5
commit d5de189af6
28 changed files with 444 additions and 269 deletions
+4 -3
View File
@@ -1,7 +1,8 @@
use crsn::asm::data::{Rd, Wr};
use crsn::asm::data::{Rd, Wr, RdObj};
#[derive(Clone, Debug, Eq, PartialEq)]
pub enum StackOp {
Push { num: Rd, src: Rd },
Pop { dst: Wr, num: Rd },
NewStack { dst: Wr },
Push { obj: RdObj, src: Rd },
Pop { dst: Wr, obj: RdObj },
}
+43 -42
View File
@@ -1,69 +1,65 @@
use std::collections::VecDeque;
use std::collections::{VecDeque, HashMap};
use crsn::asm::data::literal::Value;
use crsn::asm::instr::Cond;
use crsn::module::{EvalRes, OpTrait};
use crsn::module::{EvalRes, OpTrait, CrsnExtension};
use crsn::runtime::fault::Fault;
use crsn::runtime::run_thread::{state::RunState, ThreadInfo};
use crate::defs::StackOp;
use crate::StackOps;
#[derive(Debug, Default)]
struct Stacks {
stacks: Vec<VecDeque<Value>>,
}
impl Default for Stacks {
fn default() -> Self {
Stacks {
stacks: vec![VecDeque::default(); 8],
}
}
store: HashMap<Value, VecDeque<Value>>,
}
impl OpTrait for StackOp {
fn execute(&self, _ti: &ThreadInfo, state: &mut RunState) -> Result<EvalRes, Fault> {
fn execute(&self, info: &ThreadInfo, state: &mut RunState) -> Result<EvalRes, Fault> {
let eres = EvalRes::default();
match self {
StackOp::Push { num, src } => {
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 stack_num = state.read(*num)?;
let handle = state.read_obj(*obj)?;
let val = state.read(*src)?;
if stack_num > 8 {
state.set_flag(Cond::Invalid, true);
} else {
let obj: &mut Stacks = state.ext_mut();
obj.stacks[stack_num as usize].push_back(val);
}
let stacks: &mut Stacks = state.ext_mut();
stacks.store.get_mut(&handle)
.ok_or_else(|| Fault::ObjectNotExist(handle))?
.push_back(val);
}
StackOp::Pop { dst, num } => {
StackOp::Pop { dst, obj } => {
state.clear_status();
let stack_num = state.read(*num)?;
let handle = state.read_obj(*obj)?;
if stack_num > 8 {
state.set_flag(Cond::Invalid, true);
} else {
let obj: &mut Stacks = state.ext_mut();
let val = obj.stacks[stack_num as usize].pop_back();
let stacks: &mut Stacks = state.ext_mut();
let stack = stacks.store.get_mut(&handle)
.ok_or_else(|| Fault::ObjectNotExist(handle))?;
if obj.stacks[stack_num as usize].is_empty() {
state.set_flag(Cond::Zero, true);
}
let val = stack.pop_back();
let val = match val {
None => {
state.set_flag(Cond::Overflow, true);
0
}
Some(val) => {
val
}
};
state.write(*dst, val)?;
if stack.is_empty() {
state.set_flag(Cond::Zero, true);
}
// TODO
let val = match val {
None => {
state.set_flag(Cond::Overflow, true);
0
}
Some(val) => {
val
}
};
state.write(*dst, val)?;
}
}
@@ -71,3 +67,8 @@ impl OpTrait for StackOp {
}
//
}
pub(crate) fn drop_stack(state: &mut RunState, handle : Value) -> Result<Option<()>, Fault> {
let stacks: &mut Stacks = state.ext_mut();
Ok(stacks.store.remove(&handle).map(|_| ()))
}
+19 -5
View File
@@ -1,9 +1,12 @@
use crsn::asm::error::Error;
use crsn::asm::instr::Op;
use crsn::asm::parse::arg_parser::ArgParser;
use crsn::module::{AsmModule, ParseOpRes};
use crsn::module::{CrsnExtension, ParseOpRes};
use crate::defs::StackOp;
use crsn::runtime::run_thread::{ThreadInfo, RunState};
use crsn::asm::data::literal::Value;
use crsn::runtime::fault::Fault;
#[derive(Debug, Clone)]
pub struct StackOps {
@@ -11,23 +14,29 @@ pub struct StackOps {
}
impl StackOps {
pub fn new() -> Box<dyn AsmModule> {
pub fn new() -> Box<dyn CrsnExtension> {
Box::new(Self {
_internal: ()
})
}
}
impl AsmModule for StackOps {
impl CrsnExtension for StackOps {
fn name(&self) -> &'static str {
"stacks"
}
fn parse_op(&self, keyword: &str, mut args: ArgParser) -> Result<ParseOpRes, Error> {
Ok(ParseOpRes::Parsed(Op::Ext(Box::new(match keyword {
"stack" => {
StackOp::NewStack {
dst: args.next_wr()?,
}
}
"push" => {
StackOp::Push {
num: args.next_rd()?,
obj: args.next_rdobj()?,
src: args.next_rd()?,
}
}
@@ -35,7 +44,7 @@ impl AsmModule for StackOps {
"pop" => {
StackOp::Pop {
dst: args.next_wr()?,
num: args.next_rd()?,
obj: args.next_rdobj()?,
}
}
@@ -44,4 +53,9 @@ impl AsmModule for StackOps {
}
}))))
}
fn drop_obj(&self, _ti: &ThreadInfo, state: &mut RunState, handle : Value) -> Result<Option<()>, Fault>
{
crate::exec::drop_stack(state, handle)
}
}