From d5de189af6ab9bbe9cceacca2112fc09c1ec35ab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Hru=C5=A1ka?= Date: Mon, 28 Sep 2020 19:36:15 +0200 Subject: [PATCH] add more sensible API for object handles, add drop instruction --- Cargo.lock | 108 +++++++++++------------ crsn/src/asm/data/mod.rs | 125 +++++++-------------------- crsn/src/asm/data/rd.rs | 58 +++++++++++++ crsn/src/asm/data/wr.rs | 39 +++++++++ crsn/src/asm/instr/flatten.rs | 6 +- crsn/src/asm/instr/op.rs | 2 +- crsn/src/asm/mod.rs | 6 +- crsn/src/asm/parse/arg_parser.rs | 14 ++- crsn/src/asm/parse/mod.rs | 4 +- crsn/src/asm/parse/parse_cond.rs | 4 +- crsn/src/asm/parse/parse_data.rs | 8 +- crsn/src/asm/parse/parse_instr.rs | 4 +- crsn/src/asm/parse/parse_op.rs | 8 +- crsn/src/asm/parse/parse_routines.rs | 4 +- crsn/src/builtin/defs.rs | 5 +- crsn/src/builtin/exec.rs | 17 ++++ crsn/src/builtin/parse.rs | 15 ++-- crsn/src/module/mod.rs | 36 +++++++- crsn/src/runtime/fault.rs | 5 +- crsn/src/runtime/program.rs | 5 +- crsn/src/runtime/run_thread.rs | 32 ++++--- crsn/src/runtime/run_thread/info.rs | 25 ++++++ crsn/src/runtime/run_thread/state.rs | 29 ++++--- crsn_arith/src/parse.rs | 6 +- crsn_stacks/src/defs.rs | 7 +- crsn_stacks/src/exec.rs | 85 +++++++++--------- crsn_stacks/src/parse.rs | 24 +++-- launcher/src/main.rs | 32 ++++--- 28 files changed, 444 insertions(+), 269 deletions(-) create mode 100644 crsn/src/asm/data/rd.rs create mode 100644 crsn/src/asm/data/wr.rs create mode 100644 crsn/src/runtime/run_thread/info.rs diff --git a/Cargo.lock b/Cargo.lock index 380662f..f7f6015 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -12,9 +12,9 @@ version = "0.2.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" dependencies = [ - "hermit-abi", - "libc", - "winapi", + "hermit-abi", + "libc", + "winapi", ] [[package]] @@ -35,9 +35,9 @@ version = "0.4.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "942f72db697d8767c22d46a598e01f2d3b475501ea43d0db4f16d90259182d0b" dependencies = [ - "num-integer", - "num-traits", - "time", + "num-integer", + "num-traits", + "time", ] [[package]] @@ -46,36 +46,36 @@ version = "1.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f4ffc801dacf156c5854b9df4f425a626539c3a6ef7893cc0c5084a23f0b6c59" dependencies = [ - "atty", - "lazy_static", - "winapi", + "atty", + "lazy_static", + "winapi", ] [[package]] name = "crsn" version = "0.1.0" dependencies = [ - "anyhow", - "dyn-clonable", - "log", - "num-traits", - "sexp", - "thiserror", + "anyhow", + "dyn-clonable", + "log", + "num-traits", + "sexp", + "thiserror", ] [[package]] name = "crsn_arith" version = "0.1.0" dependencies = [ - "crsn", - "num-traits", + "crsn", + "num-traits", ] [[package]] name = "crsn_stacks" version = "0.1.0" dependencies = [ - "crsn", + "crsn", ] [[package]] @@ -84,8 +84,8 @@ version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4e9232f0e607a262ceb9bd5141a3dfb3e4db6994b31989bbfd845878cba59fd4" dependencies = [ - "dyn-clonable-impl", - "dyn-clone", + "dyn-clonable-impl", + "dyn-clone", ] [[package]] @@ -94,9 +94,9 @@ version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "558e40ea573c374cf53507fd240b7ee2f5477df7cfebdb97323ec61c719399c5" dependencies = [ - "proc-macro2", - "quote", - "syn", + "proc-macro2", + "quote", + "syn", ] [[package]] @@ -111,20 +111,20 @@ version = "0.1.16" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4c30f6d0bc6b00693347368a67d41b58f2fb851215ff1da49e90fe2c5c667151" dependencies = [ - "libc", + "libc", ] [[package]] name = "launcher" version = "0.1.0" dependencies = [ - "anyhow", - "crsn", - "crsn_arith", - "crsn_stacks", - "log", - "simple_logger", - "thiserror", + "anyhow", + "crsn", + "crsn_arith", + "crsn_stacks", + "log", + "simple_logger", + "thiserror", ] [[package]] @@ -145,7 +145,7 @@ version = "0.4.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4fabed175da42fed1fa0746b0ea71f412aa9d35e76e95e59b192c64b9dc2bf8b" dependencies = [ - "cfg-if", + "cfg-if", ] [[package]] @@ -154,8 +154,8 @@ version = "0.1.43" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8d59457e662d541ba17869cf51cf177c0b5f0cbf476c66bdc90bf1edac4f875b" dependencies = [ - "autocfg", - "num-traits", + "autocfg", + "num-traits", ] [[package]] @@ -164,7 +164,7 @@ version = "0.2.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ac267bcc07f48ee5f8935ab0d24f316fb722d7a1292e2913f0cc196b29ffd611" dependencies = [ - "autocfg", + "autocfg", ] [[package]] @@ -173,7 +173,7 @@ version = "1.0.21" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "36e28516df94f3dd551a587da5357459d9b36d945a7c37c3557928c1c2ff2a2c" dependencies = [ - "unicode-xid", + "unicode-xid", ] [[package]] @@ -182,7 +182,7 @@ version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "aa563d17ecb180e500da1cfd2b028310ac758de548efdd203e18f283af693f37" dependencies = [ - "proc-macro2", + "proc-macro2", ] [[package]] @@ -197,11 +197,11 @@ version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "13a53ed2efd04911c8280f2da7bf9abd350c931b86bc7f9f2386fbafbf525ff9" dependencies = [ - "atty", - "chrono", - "colored", - "log", - "winapi", + "atty", + "chrono", + "colored", + "log", + "winapi", ] [[package]] @@ -210,9 +210,9 @@ version = "1.0.41" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6690e3e9f692504b941dc6c3b188fd28df054f7fb8469ab40680df52fdcc842b" dependencies = [ - "proc-macro2", - "quote", - "unicode-xid", + "proc-macro2", + "quote", + "unicode-xid", ] [[package]] @@ -221,7 +221,7 @@ version = "1.0.20" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7dfdd070ccd8ccb78f4ad66bf1982dc37f620ef696c6b5028fe2ed83dd3d0d08" dependencies = [ - "thiserror-impl", + "thiserror-impl", ] [[package]] @@ -230,9 +230,9 @@ version = "1.0.20" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bd80fc12f73063ac132ac92aceea36734f04a1d93c1240c6944e23a3b8841793" dependencies = [ - "proc-macro2", - "quote", - "syn", + "proc-macro2", + "quote", + "syn", ] [[package]] @@ -241,9 +241,9 @@ version = "0.1.44" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6db9e6914ab8b1ae1c260a4ae7a49b6c5611b40328a735b21862567685e73255" dependencies = [ - "libc", - "wasi", - "winapi", + "libc", + "wasi", + "winapi", ] [[package]] @@ -264,8 +264,8 @@ version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" dependencies = [ - "winapi-i686-pc-windows-gnu", - "winapi-x86_64-pc-windows-gnu", + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", ] [[package]] diff --git a/crsn/src/asm/data/mod.rs b/crsn/src/asm/data/mod.rs index de5957f..1865e02 100644 --- a/crsn/src/asm/data/mod.rs +++ b/crsn/src/asm/data/mod.rs @@ -13,6 +13,13 @@ pub mod literal; pub mod reg; pub mod mask; +mod rd; +pub use rd::Rd; +pub use rd::RdObj; + +mod wr; +pub use wr::Wr; + /// Data source disposition #[derive(Debug, Clone, Copy, Eq, PartialEq)] pub enum DataDisp { @@ -36,7 +43,7 @@ impl Display for DataDisp { write!(f, "{}", r) } DataDisp::ObjectPtr(r) => { - write!(f, "%{}", r) + write!(f, "@{}", r) } DataDisp::Discard => { write!(f, "_") @@ -45,29 +52,29 @@ impl Display for DataDisp { } } -impl From for DataDisp { - fn from(s: SrcDisp) -> Self { +impl From for DataDisp { + fn from(s: RdData) -> Self { match s { - SrcDisp::Immediate(x) => DataDisp::Immediate(x), - SrcDisp::Register(x) => DataDisp::Register(x), - SrcDisp::ObjectPtr(x) => DataDisp::ObjectPtr(x), + RdData::Immediate(x) => DataDisp::Immediate(x), + RdData::Register(x) => DataDisp::Register(x), + RdData::ObjectPtr(x) => DataDisp::ObjectPtr(x), } } } -impl From for DataDisp { - fn from(s: DstDisp) -> Self { +impl From for DataDisp { + fn from(s: WrData) -> Self { match s { - DstDisp::Register(x) => DataDisp::Register(x), - DstDisp::ObjectPtr(x) => DataDisp::ObjectPtr(x), - DstDisp::Discard => DataDisp::Discard, + WrData::Register(x) => DataDisp::Register(x), + WrData::ObjectPtr(x) => DataDisp::ObjectPtr(x), + WrData::Discard => DataDisp::Discard, } } } /// Data source disposition #[derive(Debug, Clone, Copy, Eq, PartialEq)] -pub enum SrcDisp { +pub enum RdData { /// Constant value Immediate(Value), /// Register @@ -76,14 +83,14 @@ pub enum SrcDisp { ObjectPtr(Register), } -impl TryFrom for SrcDisp { +impl TryFrom for RdData { type Error = AsmError; fn try_from(value: DataDisp) -> Result { match value { - DataDisp::Immediate(x) => Ok(SrcDisp::Immediate(x)), - DataDisp::Register(x) => Ok(SrcDisp::Register(x)), - DataDisp::ObjectPtr(x) => Ok(SrcDisp::ObjectPtr(x)), + DataDisp::Immediate(x) => Ok(RdData::Immediate(x)), + DataDisp::Register(x) => Ok(RdData::Register(x)), + DataDisp::ObjectPtr(x) => Ok(RdData::ObjectPtr(x)), DataDisp::Discard => Err(AsmError::DiscardAsValue), } } @@ -91,7 +98,7 @@ impl TryFrom for SrcDisp { /// Data destination disposition #[derive(Debug, Clone, Copy, Eq, PartialEq)] -pub enum DstDisp { +pub enum WrData { /// Register Register(Register), /// Pointer into memory, stored in a numbered register @@ -100,92 +107,26 @@ pub enum DstDisp { Discard, } -impl From for SrcDisp { - fn from(s: DstDisp) -> Self { +impl From for RdData { + fn from(s: WrData) -> Self { match s { - DstDisp::Register(x) => SrcDisp::Register(x), - DstDisp::ObjectPtr(x) => SrcDisp::ObjectPtr(x), - DstDisp::Discard => SrcDisp::Immediate(0), + WrData::Register(x) => RdData::Register(x), + WrData::ObjectPtr(x) => RdData::ObjectPtr(x), + WrData::Discard => RdData::Immediate(0), } } } -impl TryFrom for DstDisp { +impl TryFrom for WrData { type Error = AsmError; fn try_from(value: DataDisp) -> Result { match value { DataDisp::Immediate(_x) => Err(AsmError::ValueAsOutput), - DataDisp::Register(x) => Ok(DstDisp::Register(x)), - DataDisp::ObjectPtr(x) => Ok(DstDisp::ObjectPtr(x)), - DataDisp::Discard => Ok(DstDisp::Discard), - } - } -} - -/// Data source argument (read-only) -#[derive(Clone, Copy, Eq, PartialEq)] -pub struct Rd(SrcDisp, Mask); - -impl Rd { - pub fn new(src: SrcDisp) -> Self { - Rd(src, Mask::default()) - } - pub fn d(self) -> SrcDisp { - self.0 - } - pub fn mask(self) -> Mask { - self.1 - } - - pub fn immediate(val: Value) -> Rd { - Rd(SrcDisp::Immediate(val), Mask::default()) - } -} - -/// Data destination argument (read-write) -#[derive(Clone, Copy, Eq, PartialEq)] -pub struct Wr(DstDisp, Mask); - -impl Wr { - pub fn new(dst: DstDisp) -> Self { - Wr(dst, Mask::default()) - } - pub fn d(self) -> DstDisp { - self.0 - } - pub fn mask(self) -> Mask { - self.1 - } - pub fn as_rd(&self) -> Rd { - Rd(self.0.into(), self.1) - } - - pub fn discard() -> Wr { - Wr(DstDisp::Discard, Mask::default()) - } -} - -impl Debug for Rd { - fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { - write!(f, "Rd(")?; - let disp: DataDisp = self.0.into(); - write!(f, "{}", disp)?; - if !self.mask().is_default() { - write!(f, ",{:?}", self.mask())?; + DataDisp::Register(x) => Ok(WrData::Register(x)), + DataDisp::ObjectPtr(x) => Ok(WrData::ObjectPtr(x)), + DataDisp::Discard => Ok(WrData::Discard), } - write!(f, ")") } } -impl Debug for Wr { - fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { - write!(f, "Wr(")?; - let disp: DataDisp = self.0.into(); - write!(f, "{}", disp)?; - if !self.mask().is_default() { - write!(f, ",{:?}", self.mask())?; - } - write!(f, ")") - } -} diff --git a/crsn/src/asm/data/rd.rs b/crsn/src/asm/data/rd.rs new file mode 100644 index 0000000..525cfd2 --- /dev/null +++ b/crsn/src/asm/data/rd.rs @@ -0,0 +1,58 @@ +use crate::asm::data::{RdData, Mask, DataDisp, Register}; +use crate::asm::data::literal::Value; +use std::fmt::{Debug, Formatter}; +use std::fmt; + +/// Data source argument (read-only) +#[derive(Clone, Copy, Eq, PartialEq)] +pub struct Rd(pub RdData, pub Mask); + +impl Rd { + pub const fn new(src: RdData) -> Self { + Rd(src, Mask::FULL) + } + pub fn data(self) -> RdData { + self.0 + } + pub fn mask(self) -> Mask { + self.1 + } + + pub fn immediate(val: Value) -> Rd { + Rd(RdData::Immediate(val), Mask::default()) + } +} + +impl Debug for Rd { + fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { + write!(f, "Rd(")?; + let disp: DataDisp = self.0.into(); + write!(f, "{}", disp)?; + if !self.mask().is_default() { + write!(f, ",{:?}", self.mask())?; + } + write!(f, ")") + } +} + + +/// Reference an object through a handle +#[derive(Clone, Copy, Eq, PartialEq)] +pub struct RdObj(Register); + +impl RdObj { + pub fn new(reg: Register) -> Self { + RdObj(reg) + } + pub const fn reg(self) -> Register { + self.0 + } +} + +impl Debug for RdObj { + fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { + write!(f, "Obj(")?; + write!(f, "{}", self.reg())?; + write!(f, ")") + } +} diff --git a/crsn/src/asm/data/wr.rs b/crsn/src/asm/data/wr.rs new file mode 100644 index 0000000..9bac944 --- /dev/null +++ b/crsn/src/asm/data/wr.rs @@ -0,0 +1,39 @@ +use crate::asm::data::{RdData, Mask, DataDisp, WrData, Rd}; +use crate::asm::data::literal::Value; +use std::fmt::{Debug, Formatter}; +use std::fmt; + +/// Data destination argument (read-write) +#[derive(Clone, Copy, Eq, PartialEq)] +pub struct Wr(WrData, Mask); + +impl Wr { + pub fn new(dst: WrData) -> Self { + Wr(dst, Mask::default()) + } + pub fn d(self) -> WrData { + self.0 + } + pub fn mask(self) -> Mask { + self.1 + } + pub fn as_rd(&self) -> Rd { + Rd(self.0.into(), self.1) + } + + pub fn discard() -> Wr { + Wr(WrData::Discard, Mask::default()) + } +} + +impl Debug for Wr { + fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { + write!(f, "Wr(")?; + let disp: DataDisp = self.0.into(); + write!(f, "{}", disp)?; + if !self.mask().is_default() { + write!(f, ",{:?}", self.mask())?; + } + write!(f, ")") + } +} diff --git a/crsn/src/asm/instr/flatten.rs b/crsn/src/asm/instr/flatten.rs index 0ffe420..6cc2baa 100644 --- a/crsn/src/asm/instr/flatten.rs +++ b/crsn/src/asm/instr/flatten.rs @@ -1,7 +1,7 @@ use std::collections::HashMap; use std::sync::atomic::AtomicU32; -use crate::asm::data::{Rd, SrcDisp}; +use crate::asm::data::{Rd, RdData}; use crate::asm::data::literal::{Label, Value}; use crate::asm::error::{AsmError, Error}; use crate::asm::instr::{Cond, Instr, Op, Routine}; @@ -83,7 +83,7 @@ fn numbered_labels_to_skips(ops: Vec) -> Result, Error> { Op::BuiltIn(BuiltinOp::Jump(target @ Label::Numbered(_))) => { if let Some(dest) = label_positions.get(&target) { let skip = *dest as isize - n as isize + skipped; - cleaned.push(Op::BuiltIn(BuiltinOp::Skip(Rd::new(SrcDisp::Immediate(skip as Value))))); + cleaned.push(Op::BuiltIn(BuiltinOp::Skip(Rd::new(RdData::Immediate(skip as Value))))); } else { return Err(Error::Asm(AsmError::LabelNotDefined(target))); } @@ -91,7 +91,7 @@ fn numbered_labels_to_skips(ops: Vec) -> Result, Error> { Op::BuiltIn(BuiltinOp::JumpIf(cond, target @ Label::Numbered(_))) => { if let Some(dest) = label_positions.get(&target) { let skip = *dest as isize - n as isize + skipped; - cleaned.push(Op::BuiltIn(BuiltinOp::SkipIf(cond, Rd::new(SrcDisp::Immediate(skip as Value))))); + cleaned.push(Op::BuiltIn(BuiltinOp::SkipIf(cond, Rd::new(RdData::Immediate(skip as Value))))); } else { return Err(Error::Asm(AsmError::LabelNotDefined(target))); } diff --git a/crsn/src/asm/instr/op.rs b/crsn/src/asm/instr/op.rs index b339be6..4261280 100644 --- a/crsn/src/asm/instr/op.rs +++ b/crsn/src/asm/instr/op.rs @@ -3,7 +3,7 @@ use std::fmt::Debug; use crate::builtin::defs::BuiltinOp; use crate::module::{EvalRes, OpTrait}; use crate::runtime::fault::Fault; -use crate::runtime::run_thread::{state::RunState, ThreadInfo}; +use crate::runtime::run_thread::{state::RunState, info::ThreadInfo}; /// A higher level simple opration #[derive(Debug)] diff --git a/crsn/src/asm/mod.rs b/crsn/src/asm/mod.rs index 5830a5c..6229eca 100644 --- a/crsn/src/asm/mod.rs +++ b/crsn/src/asm/mod.rs @@ -1,6 +1,6 @@ use std::sync::Arc; -use crate::module::AsmModule; +use crate::module::CrsnExtension; use crate::runtime::program::Program; pub mod data; @@ -10,7 +10,7 @@ pub mod parse; pub mod patches; /// Parse a program from string and assemble a low level instruction sequence from it. -pub fn assemble(source: &str, parsers: &[Box]) -> Result, error::Error> { +pub fn assemble(source: &str, parsers: &'static [Box]) -> Result, error::Error> { let ops = parse::parse(source, parsers)?; trace!("--- Compiled program ---"); @@ -19,5 +19,5 @@ pub fn assemble(source: &str, parsers: &[Box]) -> Result anyhow::Result { + match parse_rd(self.next())? { + Rd(RdData::ObjectPtr(reg), Mask::FULL) => { + return Ok(RdObj::new(reg)); + } + other => { + anyhow::bail!("Not a valid object handle syntax: {:?}", other); + } + } + } + /// Get the next entry as write location pub fn next_wr(&mut self) -> anyhow::Result { parse_wr(self.next()) diff --git a/crsn/src/asm/parse/mod.rs b/crsn/src/asm/parse/mod.rs index a3fa226..27b7497 100644 --- a/crsn/src/asm/parse/mod.rs +++ b/crsn/src/asm/parse/mod.rs @@ -6,7 +6,7 @@ use parse_routines::parse_routines; use crate::asm::error::Error; use crate::asm::instr::{Flatten, Op, Routine}; use crate::asm::parse::sexp_expect::expect_list; -use crate::module::AsmModule; +use crate::module::CrsnExtension; mod parse_cond; mod parse_instr; @@ -17,7 +17,7 @@ mod parse_op; pub mod arg_parser; -pub fn parse(source: &str, parsers: &[Box]) -> Result, Error> { +pub fn parse(source: &str, parsers: &[Box]) -> Result, Error> { let root = sexp::parse(source)?; let subs: Vec = parse_routines(expect_list(Some(root), true)?, parsers)?; diff --git a/crsn/src/asm/parse/parse_cond.rs b/crsn/src/asm/parse/parse_cond.rs index 9d6feca..8532cb5 100644 --- a/crsn/src/asm/parse/parse_cond.rs +++ b/crsn/src/asm/parse/parse_cond.rs @@ -5,9 +5,9 @@ use crate::asm::instr::{Cond, cond, Instr}; use crate::asm::parse::parse_instr::parse_instructions; use crate::asm::parse::sexp_expect::{expect_list, expect_string_atom}; use crate::asm::patches::TryRemove; -use crate::module::AsmModule; +use crate::module::CrsnExtension; -pub fn parse_cond_branch(tok: Sexp, parsers: &[Box]) -> Result<(Cond, Vec), Error> { +pub fn parse_cond_branch(tok: Sexp, parsers: &[Box]) -> Result<(Cond, Vec), Error> { let mut list = expect_list(Some(tok), false)?; let kw = expect_string_atom(list.try_remove(0))?; diff --git a/crsn/src/asm/parse/parse_data.rs b/crsn/src/asm/parse/parse_data.rs index 1d83a05..414300a 100644 --- a/crsn/src/asm/parse/parse_data.rs +++ b/crsn/src/asm/parse/parse_data.rs @@ -2,7 +2,7 @@ use std::convert::TryFrom; use sexp::{Atom, Sexp}; -use crate::asm::data::{DataDisp, DstDisp, Rd, reg, SrcDisp, Wr}; +use crate::asm::data::{DataDisp, WrData, Rd, reg, RdData, Wr}; use crate::asm::data::literal::Label; use crate::asm::error::Error; use crate::asm::parse::sexp_expect::expect_string_atom; @@ -32,7 +32,7 @@ pub fn parse_data_disp(tok: Option) -> Result { return Ok(DataDisp::Discard); } - if let Some(reference) = s.strip_prefix('%') { + if let Some(reference) = s.strip_prefix('@') { Ok(DataDisp::ObjectPtr(reg::parse_reg(reference)?)) } else if s.starts_with(|c: char| c.is_ascii_digit()) { Ok(DataDisp::Immediate(unsafe { std::mem::transmute(parse_i64(s)?) })) @@ -65,9 +65,9 @@ pub fn parse_i64(literal: &str) -> anyhow::Result { } pub fn parse_rd(tok: Option) -> anyhow::Result { - Ok(Rd::new(SrcDisp::try_from(parse_data_disp(tok)?)?)) + Ok(Rd::new(RdData::try_from(parse_data_disp(tok)?)?)) } pub fn parse_wr(tok: Option) -> anyhow::Result { - Ok(Wr::new(DstDisp::try_from(parse_data_disp(tok)?)?)) + Ok(Wr::new(WrData::try_from(parse_data_disp(tok)?)?)) } diff --git a/crsn/src/asm/parse/parse_instr.rs b/crsn/src/asm/parse/parse_instr.rs index be18138..ccaa022 100644 --- a/crsn/src/asm/parse/parse_instr.rs +++ b/crsn/src/asm/parse/parse_instr.rs @@ -6,11 +6,11 @@ use crate::asm::parse::arg_parser::ArgParser; use crate::asm::parse::parse_cond::parse_cond_branch; use crate::asm::parse::sexp_expect::{expect_list, expect_string_atom}; use crate::asm::patches::SexpIsA; -use crate::module::AsmModule; +use crate::module::CrsnExtension; use super::parse_op::parse_op; -pub fn parse_instructions(instrs: Vec, parsers: &[Box]) -> Result, Error> { +pub fn parse_instructions(instrs: Vec, parsers: &[Box]) -> Result, Error> { let mut parsed = vec![]; for expr in instrs { let tokens = expect_list(Some(expr), false)?; diff --git a/crsn/src/asm/parse/parse_op.rs b/crsn/src/asm/parse/parse_op.rs index 250cd68..2a24057 100644 --- a/crsn/src/asm/parse/parse_op.rs +++ b/crsn/src/asm/parse/parse_op.rs @@ -1,12 +1,12 @@ use crate::asm::error::Error; use crate::asm::instr::Op; use crate::asm::parse::arg_parser::ArgParser; -use crate::builtin::parse::BuiltinOpParser; -use crate::module::{AsmModule, ParseOpRes}; +use crate::builtin::parse::BuiltinOps; +use crate::module::{CrsnExtension, ParseOpRes}; -pub fn parse_op(keyword: &str, mut arg_tokens: ArgParser, parsers: &[Box]) -> Result { +pub fn parse_op(keyword: &str, mut arg_tokens: ArgParser, parsers: &[Box]) -> Result { // Include built-in instructions - let builtins = [BuiltinOpParser::new()]; + let builtins = [BuiltinOps::new()]; for p in builtins.iter().chain(parsers) { arg_tokens = match p.parse_op(keyword, arg_tokens) { diff --git a/crsn/src/asm/parse/parse_routines.rs b/crsn/src/asm/parse/parse_routines.rs index 5322019..b7cd761 100644 --- a/crsn/src/asm/parse/parse_routines.rs +++ b/crsn/src/asm/parse/parse_routines.rs @@ -6,9 +6,9 @@ use crate::asm::instr::Routine; use crate::asm::parse::parse_instr::parse_instructions; use crate::asm::parse::sexp_expect::{expect_list, expect_string_atom}; use crate::asm::patches::TryRemove; -use crate::module::AsmModule; +use crate::module::CrsnExtension; -pub fn parse_routines(routines: Vec, parsers: &[Box]) -> Result, Error> { +pub fn parse_routines(routines: Vec, parsers: &[Box]) -> Result, Error> { let mut parsed = vec![]; for rt in routines { let mut def = expect_list(Some(rt), false)?; diff --git a/crsn/src/builtin/defs.rs b/crsn/src/builtin/defs.rs index cd05c45..289d29a 100644 --- a/crsn/src/builtin/defs.rs +++ b/crsn/src/builtin/defs.rs @@ -1,4 +1,4 @@ -use crate::asm::data::{Rd, Wr}; +use crate::asm::data::{Rd, Wr, RdObj}; use crate::asm::data::literal::{DebugMsg, Label, RoutineName}; use crate::asm::instr::{Cond, Op}; @@ -37,6 +37,9 @@ pub enum BuiltinOp { Barrier(Option), /// Generate a run-time fault with a debugger message Fault(Option), + /// Deallocate an object. + /// The object is released and the handle becomes invalid. + Drop(RdObj), /// Copy value Move { dst: Wr, src: Rd }, /// Store runtime status to a register diff --git a/crsn/src/builtin/exec.rs b/crsn/src/builtin/exec.rs index 3bb8d94..63cf057 100644 --- a/crsn/src/builtin/exec.rs +++ b/crsn/src/builtin/exec.rs @@ -4,6 +4,8 @@ use crate::module::{EvalRes, OpTrait}; use crate::runtime::fault::Fault; use crate::runtime::frame::StackFrame; use crate::runtime::run_thread::{state::RunState, ThreadInfo}; +use crate::asm::data::{Rd, RdData}; +use crate::asm::instr::Cond; impl OpTrait for BuiltinOp { fn execute(&self, info: &ThreadInfo, state: &mut RunState) -> Result { @@ -135,6 +137,21 @@ impl OpTrait for BuiltinOp { let x = state.read(*src)?; state.frame.status.load(x); } + BuiltinOp::Drop(obj) => { + let x = state.read(Rd::new(RdData::Register(obj.reg())))?; + + trace!("Drop object: {:#x}", x); + let mut dropped = false; + for ex in info.program.extensions { + if ex.drop_obj(info, state, x)?.is_some() { + dropped = true; + } + } + if !dropped { + warn!("Object {:#x} to drop does not exist!", x); + state.set_flag(Cond::Invalid, true); + } + } } Ok(res) diff --git a/crsn/src/builtin/parse.rs b/crsn/src/builtin/parse.rs index ee056b1..7c098fb 100644 --- a/crsn/src/builtin/parse.rs +++ b/crsn/src/builtin/parse.rs @@ -8,22 +8,23 @@ use crate::asm::parse::arg_parser::ArgParser; use crate::asm::parse::parse_data::{parse_label, parse_rd}; use crate::asm::parse::sexp_expect::expect_string_atom; use crate::builtin::defs::BuiltinOp; -use crate::module::{AsmModule, ParseOpRes}; +use crate::module::{CrsnExtension, ParseOpRes}; +use crate::asm::data::RdObj; #[derive(Debug, Clone)] -pub struct BuiltinOpParser { +pub struct BuiltinOps { _internal: () } -impl BuiltinOpParser { - pub fn new() -> Box { +impl BuiltinOps { + pub fn new() -> Box { Box::new(Self { _internal: () }) } } -impl AsmModule for BuiltinOpParser { +impl CrsnExtension for BuiltinOps { fn name(&self) -> &'static str { "builtin" } @@ -126,6 +127,10 @@ impl AsmModule for BuiltinOpParser { } } + "drop" => { + BuiltinOp::Drop(args.next_rdobj()?) + } + "far" => { if let Some(Sexp::Atom(Atom::S(ref label))) = args.peek() { if let Some(label) = label.strip_prefix(':') { diff --git a/crsn/src/module/mod.rs b/crsn/src/module/mod.rs index 95932b5..c0f3599 100644 --- a/crsn/src/module/mod.rs +++ b/crsn/src/module/mod.rs @@ -8,6 +8,8 @@ use crate::asm::parse::arg_parser::ArgParser; use crate::runtime::fault::Fault; use crate::runtime::run_thread::state::RunState; use crate::runtime::run_thread::ThreadInfo; +use crate::asm::data::literal::Value; +use crate::asm::data::Mask; mod eval_res; @@ -23,7 +25,7 @@ pub trait OpTrait: Debug + Send + Sync + 'static { fn execute(&self, ti: &ThreadInfo, state: &mut RunState) -> Result; } -pub trait AsmModule: Debug + Send + 'static { +pub trait CrsnExtension: Debug + Send + Sync + 'static { /// Get name of the module fn name(&self) -> &'static str; @@ -33,4 +35,36 @@ pub trait AsmModule: Debug + Send + 'static { /// /// If the instruction keyword is not recognized, return Unknown with the unchanged argument list. fn parse_op(&self, keyword: &str, arg_tokens: ArgParser) -> Result; + + /// Drop an object referenced by a handle + fn drop_obj(&self, + #[allow(unused)] ti: &ThreadInfo, + #[allow(unused)] state: &mut RunState, + #[allow(unused)] handle : Value) -> Result, Fault> + { + // Default impl - we do not support dropping this object + Ok(None) + } + + /// Run-time method called to read an object (using the object handle syntax) + fn read_obj(&self, + #[allow(unused)] ti: &ThreadInfo, + #[allow(unused)] state: &mut RunState, + #[allow(unused)] handle : Value, + #[allow(unused)] mask : Mask + ) -> Result, Fault> { + // Default impl - we do not support reading this object + Ok(None) + } + + /// Run-time method called to write an object (using the object handle syntax) + fn write_obj(&self, + #[allow(unused)] ti: &ThreadInfo, + #[allow(unused)] state: &mut RunState, + #[allow(unused)] handle : Value, + #[allow(unused)] mask : Mask + ) -> Result, Fault> { + // Default impl - we do not support writing this object + Ok(None) + } } diff --git a/crsn/src/runtime/fault.rs b/crsn/src/runtime/fault.rs index b6e40ac..2cd4a3b 100644 --- a/crsn/src/runtime/fault.rs +++ b/crsn/src/runtime/fault.rs @@ -1,6 +1,6 @@ use thiserror::Error; -use crate::asm::data::literal::{DebugMsg, Label, RoutineName}; +use crate::asm::data::literal::{DebugMsg, Label, RoutineName, Value}; use crate::asm::data::Register; #[derive(Error, Debug)] @@ -24,6 +24,9 @@ pub enum Fault { #[error("Program ended.")] Halt, + #[error("Object does not exist: {0:#x}")] + ObjectNotExist(Value), + // #[error("Memory region {area:?} is locked by thread {owner:?}")] // MemoryLocked { // area: MemorySpan, diff --git a/crsn/src/runtime/program.rs b/crsn/src/runtime/program.rs index a344541..f0424a8 100644 --- a/crsn/src/runtime/program.rs +++ b/crsn/src/runtime/program.rs @@ -5,19 +5,22 @@ use crate::asm::data::literal::{Addr, Label, RoutineName}; use crate::asm::instr::Op; use crate::builtin::defs::BuiltinOp; use crate::runtime::fault::Fault; +use crate::module::CrsnExtension; #[derive(Debug)] pub struct Program { pub ops: Vec, + pub extensions: &'static [Box], routines: HashMap, far_labels: HashMap, barriers: Vec, } impl Program { - pub fn new(ops: Vec) -> Arc { + pub fn new(ops: Vec, extensions: &'static [Box]) -> Arc { let mut p = Self { ops, + extensions, routines: Default::default(), far_labels: Default::default(), barriers: Default::default(), diff --git a/crsn/src/runtime/run_thread.rs b/crsn/src/runtime/run_thread.rs index e435095..0f55f09 100644 --- a/crsn/src/runtime/run_thread.rs +++ b/crsn/src/runtime/run_thread.rs @@ -1,13 +1,14 @@ use std::sync::Arc; +use std::sync::atomic::{AtomicU64, Ordering}; use std::thread::JoinHandle; use std::time::Duration; -use crate::asm::data::literal::Addr; +use crate::asm::data::literal::{Addr, Value}; use crate::module::EvalRes; use crate::runtime::fault::Fault; use crate::runtime::frame::StackFrame; use crate::runtime::program::Program; -use crate::runtime::run_thread::state::RunState; +use crate::runtime::run_thread::info::{UNIQ_BASE}; #[derive(Clone, Copy, Eq, PartialEq, Debug, Ord, PartialOrd)] pub struct ThreadToken(pub u32); @@ -17,22 +18,29 @@ pub struct RunThread { pub(crate) state: RunState, } -pub struct ThreadInfo { - /// Thread ID - pub id: ThreadToken, - /// Program to run - pub program: Arc, - /// Program to run - pub cycle_time: Duration, -} - +pub mod info; pub mod state; +pub use info::ThreadInfo; +pub use state::RunState; + +pub fn new_uniq() -> &'static AtomicU64 { + let uniq = AtomicU64::new(info::UNIQ_BASE); + Box::leak(Box::new(uniq)) +} impl RunThread { - pub fn new(id: ThreadToken, program: Arc, pc: Addr, args: &[u64]) -> Self { + pub fn new(id: ThreadToken, uniq: Option<&'static AtomicU64>, program: Arc, pc: Addr, args: &[u64]) -> Self { + let uniq = if let Some(u) = uniq { + u + } else { + let u = AtomicU64::new(UNIQ_BASE); + Box::leak(Box::new(u)) as &AtomicU64 + }; + Self { info: ThreadInfo { id, + uniq, program, cycle_time: Duration::default(), }, diff --git a/crsn/src/runtime/run_thread/info.rs b/crsn/src/runtime/run_thread/info.rs new file mode 100644 index 0000000..da5d9c4 --- /dev/null +++ b/crsn/src/runtime/run_thread/info.rs @@ -0,0 +1,25 @@ +use crate::runtime::run_thread::ThreadToken; +use std::sync::atomic::{AtomicU64, Ordering}; +use std::sync::Arc; +use crate::runtime::program::Program; +use std::time::Duration; +use crate::asm::data::literal::Value; + +pub struct ThreadInfo { + /// Thread ID + pub id: ThreadToken, + /// Thread ID + pub(crate) uniq: &'static AtomicU64, + /// Program to run + pub program: Arc, + /// Program to run + pub(crate) cycle_time: Duration, +} + +pub const UNIQ_BASE: u64 = 0x6372_736e_0000_0000; + +impl ThreadInfo { + pub fn uniq(&self) -> Value { + self.uniq.fetch_add(1, Ordering::Relaxed) + } +} diff --git a/crsn/src/runtime/run_thread/state.rs b/crsn/src/runtime/run_thread/state.rs index d3a72fb..ccaed87 100644 --- a/crsn/src/runtime/run_thread/state.rs +++ b/crsn/src/runtime/run_thread/state.rs @@ -1,7 +1,7 @@ use std::any::{Any, TypeId}; use std::collections::HashMap; -use crate::asm::data::{DstDisp, Rd, Register, SrcDisp, Wr}; +use crate::asm::data::{WrData, Rd, Register, RdData, Wr, RdObj}; use crate::asm::data::literal::{Addr, Value}; use crate::asm::instr::Cond; use crate::runtime::fault::Fault; @@ -61,11 +61,16 @@ impl RunState { self.frame.status.update(val); } + /// Read object handle value + pub fn read_obj(&mut self, rdo: RdObj) -> Result { + self.read(Rd::new(RdData::Register(rdo.reg()))) + } + /// Read a `Rd` value pub fn read(&mut self, rd: Rd) -> Result { - match rd.d() { - SrcDisp::Immediate(v) => Ok(v), - SrcDisp::Register(Register::Res(rn)) => { + match rd.data() { + RdData::Immediate(v) => Ok(v), + RdData::Register(Register::Res(rn)) => { if rn >= REG_COUNT as u8 { Err(Fault::RegisterNotExist { reg: Register::Res(rn) }) // TODO use match after @ when stabilized https://github.com/rust-lang/rust/issues/65490 } else { @@ -73,7 +78,7 @@ impl RunState { Ok(self.frame.res[rn as usize]) } } - SrcDisp::Register(Register::Arg(rn)) => { + RdData::Register(Register::Arg(rn)) => { if rn >= REG_COUNT as u8 { Err(Fault::RegisterNotExist { reg: Register::Arg(rn) }) } else { @@ -81,7 +86,7 @@ impl RunState { Ok(self.frame.arg[rn as usize]) } } - SrcDisp::Register(Register::Gen(rn)) => { + RdData::Register(Register::Gen(rn)) => { if rn >= REG_COUNT as u8 { Err(Fault::RegisterNotExist { reg: Register::Gen(rn) }) } else { @@ -89,7 +94,7 @@ impl RunState { Ok(self.frame.gen[rn as usize]) } } - SrcDisp::ObjectPtr(_) => { + RdData::ObjectPtr(_) => { unimplemented!("Read object ptr") } } @@ -100,25 +105,25 @@ impl RunState { trace!("WR {:?} := {}", wr, val); match wr.d() { - DstDisp::Discard => { + WrData::Discard => { /* Discard */ Ok(()) } - DstDisp::Register(Register::Res(rn)) => { + WrData::Register(Register::Res(rn)) => { if rn >= REG_COUNT as u8 { Err(Fault::RegisterNotExist { reg: Register::Res(rn) }) // TODO use match after @ when stabilized https://github.com/rust-lang/rust/issues/65490 } else { Err(Fault::RegisterNotWritable { reg: Register::Res(rn) }) } } - DstDisp::Register(Register::Arg(rn)) => { + WrData::Register(Register::Arg(rn)) => { if rn >= REG_COUNT as u8 { Err(Fault::RegisterNotExist { reg: Register::Arg(rn) }) } else { Err(Fault::RegisterNotWritable { reg: Register::Res(rn) }) } } - DstDisp::Register(Register::Gen(rn)) => { + WrData::Register(Register::Gen(rn)) => { if rn >= REG_COUNT as u8 { Err(Fault::RegisterNotExist { reg: Register::Gen(rn) }) } else { @@ -126,7 +131,7 @@ impl RunState { Ok(()) } } - DstDisp::ObjectPtr(_) => { + WrData::ObjectPtr(_) => { unimplemented!("Write object ptr") } } diff --git a/crsn_arith/src/parse.rs b/crsn_arith/src/parse.rs index 4c9049c..d641302 100644 --- a/crsn_arith/src/parse.rs +++ b/crsn_arith/src/parse.rs @@ -2,7 +2,7 @@ use crsn::asm::data::{Rd, Wr}; 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::ArithOp; @@ -12,14 +12,14 @@ pub struct ArithOps { } impl ArithOps { - pub fn new() -> Box { + pub fn new() -> Box { Box::new(Self { _internal: () }) } } -impl AsmModule for ArithOps { +impl CrsnExtension for ArithOps { fn name(&self) -> &'static str { "arith" } diff --git a/crsn_stacks/src/defs.rs b/crsn_stacks/src/defs.rs index a81d834..c78ba1d 100644 --- a/crsn_stacks/src/defs.rs +++ b/crsn_stacks/src/defs.rs @@ -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 }, } diff --git a/crsn_stacks/src/exec.rs b/crsn_stacks/src/exec.rs index 3283a4a..c6f14f2 100644 --- a/crsn_stacks/src/exec.rs +++ b/crsn_stacks/src/exec.rs @@ -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>, -} - -impl Default for Stacks { - fn default() -> Self { - Stacks { - stacks: vec![VecDeque::default(); 8], - } - } + store: HashMap>, } impl OpTrait for StackOp { - fn execute(&self, _ti: &ThreadInfo, state: &mut RunState) -> Result { + fn execute(&self, info: &ThreadInfo, state: &mut RunState) -> Result { 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 = match val { - None => { - state.set_flag(Cond::Overflow, true); - 0 - } - Some(val) => { - val - } - }; + let val = stack.pop_back(); - 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, Fault> { + let stacks: &mut Stacks = state.ext_mut(); + Ok(stacks.store.remove(&handle).map(|_| ())) +} diff --git a/crsn_stacks/src/parse.rs b/crsn_stacks/src/parse.rs index 4ef4a0d..dfedad0 100644 --- a/crsn_stacks/src/parse.rs +++ b/crsn_stacks/src/parse.rs @@ -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 { + pub fn new() -> Box { 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 { 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, Fault> + { + crate::exec::drop_stack(state, handle) + } } diff --git a/launcher/src/main.rs b/launcher/src/main.rs index d9db713..883b055 100644 --- a/launcher/src/main.rs +++ b/launcher/src/main.rs @@ -9,6 +9,8 @@ use crsn::asm::data::literal::Addr; use crsn::runtime::run_thread::{RunThread, ThreadToken}; use crsn_arith::ArithOps; use crsn_stacks::StackOps; +use std::sync::atomic::AtomicU64; +use crsn::runtime::run_thread; fn main() { SimpleLogger::new().init().unwrap(); @@ -70,34 +72,38 @@ fn main() { let program = " ( (main - (push 0 10) - (push 0 20) - (call emptystack 0) - (push 0 30) - (pop r0 0) - (pop r0 0) - (pop r0 0) + (stack r7) + (push @r7 10) + (push @r7 20) + (call emptystack r7) + (push @r7 30) + (pop r0 @r7) + (pop r0 @r7) + (drop @r7) + (pop r0 @r7) ; this fails (halt) ) (emptystack (:again) - (pop _ arg0 (nz? (j :again))) + (pop _ @arg0 (nz? (j :again))) (ret) ) ) "; - let parsers = vec![ + let parsers = Box::leak(Box::new(vec![ ArithOps::new(), StackOps::new(), - ]; + ])); let parsed = crsn::asm::assemble(program, parsers.as_slice()).unwrap(); - let mut thread1 = RunThread::new(ThreadToken(0), parsed.clone(), Addr(0), &[]); - thread1.set_speed(Duration::from_millis(250)); + let uniq = run_thread::new_uniq(); - let _thread2 = RunThread::new(ThreadToken(1), parsed.clone(), Addr(0), &[]); + let mut thread1 = RunThread::new(ThreadToken(0), Some(uniq), parsed.clone(), Addr(0), &[]); + //thread1.set_speed(Duration::from_millis(250)); + + let _thread2 = RunThread::new(ThreadToken(1), Some(uniq), parsed.clone(), Addr(0), &[]); let a = thread1.start(); //let b = thread2.start();