cleanup, auto deref Wd, Wr, RdObj

pull/21/head
Ondřej Hruška 4 years ago
parent 7a3cb539e1
commit 982ba27ed3
Signed by: MightyPork
GPG Key ID: 2C5FD5035250423D
  1. 12
      crsn/src/asm/data/rd.rs
  2. 6
      crsn/src/asm/data/wr.rs
  3. 16
      crsn/src/builtin/exec.rs
  4. 4
      crsn/src/runtime/run_thread/state.rs
  5. 96
      crsn_arith/src/exec.rs
  6. 56
      crsn_buf/src/exec.rs
  7. 30
      crsn_screen/src/exec.rs

@ -17,6 +17,12 @@ impl Rd {
}
}
impl From<&Rd> for Rd {
fn from(a: &Rd) -> Self {
*a
}
}
impl Display for Rd {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
write!(f, "{}", self.0) // TODO mask, when implemented
@ -43,6 +49,12 @@ impl RdObj {
}
}
impl From<&RdObj> for RdObj {
fn from(a: &RdObj) -> Self {
*a
}
}
impl Display for RdObj {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
write!(f, "@{}", self.0)

@ -31,6 +31,12 @@ impl Wr {
}
}
impl From<&Wr> for Wr {
fn from(a: &Wr) -> Self {
*a
}
}
impl Display for Wr {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
write!(f, "{}", self.0)

@ -69,7 +69,7 @@ impl OpTrait for BuiltinOp {
Ok(pos) => {
let mut values = Vec::with_capacity(args.len());
for arg in args {
values.push(state.read(*arg)?);
values.push(state.read(arg)?);
}
let mut frame2 = StackFrame::new(pos, &values);
@ -87,7 +87,7 @@ impl OpTrait for BuiltinOp {
Some(previous) => {
let mut values = Vec::with_capacity(retvals.len());
for arg in retvals {
values.push(state.read(*arg)?);
values.push(state.read(arg)?);
}
state.frame = previous;
state.frame.set_retvals(&values);
@ -98,16 +98,16 @@ impl OpTrait for BuiltinOp {
}
}
BuiltinOp::Skip(val) => {
let steps = state.read(*val)?;
let steps = state.read(val)?;
res.advance = i64::from_ne_bytes(steps.to_ne_bytes());
let pc = state.get_pc();
program.validate_jump(pc, Addr((pc.0 as i64 + res.advance) as u64))?;
}
BuiltinOp::MoveValue { dst, src } => {
state.clear_status();
let val = state.read(*src)?;
let val = state.read(src)?;
state.update_status(val);
state.write(*dst, val)?;
state.write(dst, val)?;
}
BuiltinOp::SwapValues { a, b } => {
let aa = state.read(a)?;
@ -117,14 +117,14 @@ impl OpTrait for BuiltinOp {
}
BuiltinOp::StoreFlags { dst } => {
let packed = state.frame.status.store();
state.write(*dst, packed)?;
state.write(dst, packed)?;
}
BuiltinOp::LoadFlags { src } => {
let x = state.read(*src)?;
let x = state.read(src)?;
state.frame.status.load(x);
}
BuiltinOp::Sleep { count: micros, unit_us } => {
std::thread::sleep(Duration::from_micros(state.read(*micros)? * unit_us.micros()))
std::thread::sleep(Duration::from_micros(state.read(micros)? * unit_us.micros()))
}
BuiltinOp::Delete(obj) => {
let x = state.read(Rd::new(RdData::Register(obj.reg())))?;

@ -88,8 +88,8 @@ impl RunState {
}
/// Read object handle value
pub fn read_obj(&mut self, rdo: RdObj) -> Result<Value, Fault> {
self.read(Rd::new(RdData::Register(rdo.reg())))
pub fn read_obj(&mut self, rdo: impl Into<RdObj>) -> Result<Value, Fault> {
self.read(Rd::new(RdData::Register(rdo.into().reg())))
}
/// Read a `Rd` value

@ -19,13 +19,13 @@ impl OpTrait for ArithOp {
match self {
ArithOp::Test { a } => {
state.clear_status();
let res = state.read(*a)?;
let res = state.read(a)?;
state.update_status(res);
}
ArithOp::Compare { a, b } => {
state.clear_status();
let x = state.read(*a)?;
let y = state.read(*b)?;
let x = state.read(a)?;
let y = state.read(b)?;
state.set_flag(Cond::Equal, x == y);
state.set_flag(Cond::Lower, x < y);
state.set_flag(Cond::Greater, x > y);
@ -36,9 +36,9 @@ impl OpTrait for ArithOp {
}
ArithOp::RangeTest { val, a, b } => {
state.clear_status();
let val = state.read(*val)?;
let a = state.read(*a)?;
let b = state.read(*b)?;
let val = state.read(val)?;
let a = state.read(a)?;
let b = state.read(b)?;
state.set_flag(Cond::Equal, val >= a && val <= b);
state.set_flag(Cond::Lower, val < a);
state.set_flag(Cond::Greater, val > b);
@ -46,8 +46,8 @@ impl OpTrait for ArithOp {
}
ArithOp::Add { dst, a, b } => {
state.clear_status();
let x = state.read(*a)?;
let y = state.read(*b)?;
let x = state.read(a)?;
let y = state.read(b)?;
let (res, ov) = if let Some(v) = x.checked_add(y) {
(v, false)
} else {
@ -55,12 +55,12 @@ impl OpTrait for ArithOp {
};
state.update_status(res);
state.set_flag(Cond::Overflow, ov);
state.write(*dst, res)?;
state.write(dst, res)?;
}
ArithOp::Sub { dst, a, b } => {
state.clear_status();
let x = state.read(*a)?;
let y = state.read(*b)?;
let x = state.read(a)?;
let y = state.read(b)?;
let (res, ov) = if let Some(v) = x.checked_sub(y) {
(v, false)
} else {
@ -68,12 +68,12 @@ impl OpTrait for ArithOp {
};
state.update_status(res);
state.set_flag(Cond::Overflow, ov);
state.write(*dst, res)?;
state.write(dst, res)?;
}
ArithOp::Mul { dst, a, b } => {
state.clear_status();
let x = state.read(*a)?;
let y = state.read(*b)?;
let x = state.read(a)?;
let y = state.read(b)?;
let res = if let Some(v) = x.checked_mul(y) {
v
} else {
@ -81,12 +81,12 @@ impl OpTrait for ArithOp {
x.wrapping_mul(y)
};
state.update_status(res);
state.write(*dst, res)?;
state.write(dst, res)?;
}
ArithOp::Div { dst, rem, a, div } => {
state.clear_status();
let x = state.read(*a)?;
let d = state.read(*div)?;
let x = state.read(a)?;
let d = state.read(div)?;
if d == 0 {
state.set_flag(Cond::Invalid, true);
} else {
@ -97,14 +97,14 @@ impl OpTrait for ArithOp {
};
state.update_status(res);
state.set_flag(Cond::Overflow, ov);
state.write(*dst, res)?;
state.write(*rem, remainder)?;
state.write(dst, res)?;
state.write(rem, remainder)?;
}
}
ArithOp::Mod { dst, a, div } => {
state.clear_status();
let x = state.read(*a)?;
let d = state.read(*div)?;
let x = state.read(a)?;
let d = state.read(div)?;
if d == 0 {
state.set_flag(Cond::Invalid, true);
} else {
@ -115,90 +115,90 @@ impl OpTrait for ArithOp {
};
state.update_status(remainder);
state.set_flag(Cond::Overflow, ov);
state.write(*dst, remainder)?;
state.write(dst, remainder)?;
}
}
ArithOp::And { dst, a, b } => {
state.clear_status();
let x = state.read(*a)?;
let y = state.read(*b)?;
let x = state.read(a)?;
let y = state.read(b)?;
let res = x & y;
state.update_status(res);
state.write(*dst, res)?;
state.write(dst, res)?;
}
ArithOp::Or { dst, a, b } => {
state.clear_status();
let x = state.read(*a)?;
let y = state.read(*b)?;
let x = state.read(a)?;
let y = state.read(b)?;
let res = x | y;
state.update_status(res);
state.write(*dst, res)?;
state.write(dst, res)?;
}
ArithOp::Xor { dst, a, b } => {
state.clear_status();
let x = state.read(*a)?;
let y = state.read(*b)?;
let x = state.read(a)?;
let y = state.read(b)?;
let res = x ^ y;
state.update_status(res);
state.write(*dst, res)?;
state.write(dst, res)?;
}
ArithOp::Cpl { dst, a } => {
state.clear_status();
let x = state.read(*a)?;
let x = state.read(a)?;
let res = !x;
state.update_status(res);
state.write(*dst, res)?;
state.write(dst, res)?;
}
ArithOp::Rol { dst, a, n } => {
state.clear_status();
let x = state.read(*a)?;
let y = state.read(*n)?;
let x = state.read(a)?;
let y = state.read(n)?;
if y > u32::MAX as u64 {
state.set_flag(Cond::Invalid, true);
} else {
let res = x.rotate_left(y as u32);
state.update_status(res);
state.write(*dst, res)?;
state.write(dst, res)?;
}
}
ArithOp::Ror { dst, a, n } => {
state.clear_status();
let x = state.read(*a)?;
let y = state.read(*n)?;
let x = state.read(a)?;
let y = state.read(n)?;
if y > u32::MAX as u64 {
state.set_flag(Cond::Invalid, true);
} else {
let res = x.rotate_right(y as u32);
state.update_status(res);
state.write(*dst, res)?;
state.write(dst, res)?;
}
}
ArithOp::Lsl { dst, a, n } => {
state.clear_status();
let x = state.read(*a)?;
let y = state.read(*n)?;
let x = state.read(a)?;
let y = state.read(n)?;
let res = x << y;
state.update_status(res);
state.write(*dst, res)?;
state.write(dst, res)?;
}
ArithOp::Lsr { dst, a, n } => {
state.clear_status();
let x = state.read(*a)?;
let y = state.read(*n)?;
let x = state.read(a)?;
let y = state.read(n)?;
let res = x >> y;
state.update_status(res);
state.write(*dst, res)?;
state.write(dst, res)?;
}
ArithOp::Asr { dst, a, n } => {
state.clear_status();
let x = state.read(*a)?;
let y = state.read(*n)?;
let x = state.read(a)?;
let y = state.read(n)?;
if y > u32::MAX as u64 {
state.set_flag(Cond::Invalid, true);
} else {
let res = x.signed_shr(y as u32);
state.update_status(res);
state.write(*dst, res)?;
state.write(dst, res)?;
}
}
}

@ -27,7 +27,7 @@ impl OpTrait for BufOps {
let que = match value {
BufValue::Zeros(len) => {
let len = state.read(*len)? as usize;
let len = state.read(len)? as usize;
let mut que = VecDeque::with_capacity(len);
que.resize(len, 0);
que
@ -35,7 +35,7 @@ impl OpTrait for BufOps {
BufValue::Values(vals) => {
let mut que = VecDeque::with_capacity(vals.len());
for val in vals {
que.push_back(state.read(*val)?);
que.push_back(state.read(val)?);
}
que
}
@ -50,13 +50,13 @@ impl OpTrait for BufOps {
let data: &mut ExtData = state.ext_mut();
data.store.insert(id, que);
state.write(*dst, id)?;
state.write(dst, id)?;
}
BufOps::Push { obj, src } => {
state.clear_status();
let val = state.read(*src)?;
let handle = state.read_obj(*obj)?;
let val = state.read(src)?;
let handle = state.read_obj(obj)?;
let stacks: &mut ExtData = state.ext_mut();
let stack = stacks.store.get_mut(&handle).ok_or_else(|| Fault::ObjectNotExist(handle))?;
stack.push_back(val);
@ -64,12 +64,12 @@ impl OpTrait for BufOps {
BufOps::Pop { dst, obj } => {
state.clear_status();
let handle = state.read_obj(*obj)?;
let handle = state.read_obj(obj)?;
let stacks: &mut ExtData = state.ext_mut();
let stack = stacks.store.get_mut(&handle).ok_or_else(|| Fault::ObjectNotExist(handle))?;
if let Some(val) = stack.pop_back() {
let empty = stack.is_empty();
state.write(*dst, val)?;
state.write(dst, val)?;
state.update_status(val);
state.set_flag(Cond::Empty, empty);
} else {
@ -80,14 +80,14 @@ impl OpTrait for BufOps {
BufOps::Read { dst, obj, idx } => {
state.clear_status();
let handle = state.read_obj(*obj)?;
let idx = state.read(*idx)?;
let handle = state.read_obj(obj)?;
let idx = state.read(idx)?;
let stacks: &mut ExtData = state.ext_mut();
let stack = stacks.store.get(&handle).ok_or_else(|| Fault::ObjectNotExist(handle))?;
if let Some(val) = stack.get(idx as usize) {
let val = *val;
state.update_status(val);
state.write(*dst, val)?;
state.write(dst, val)?;
} else {
state.set_flag(Cond::Overflow, true);
}
@ -95,19 +95,19 @@ impl OpTrait for BufOps {
BufOps::GetLen { dst, obj } => {
state.clear_status();
let handle = state.read_obj(*obj)?;
let handle = state.read_obj(obj)?;
let stacks: &mut ExtData = state.ext_mut();
let stack = stacks.store.get(&handle).ok_or_else(|| Fault::ObjectNotExist(handle))?;
let val = stack.len() as Value;
state.write(*dst, val)?;
state.write(dst, val)?;
state.update_status(val);
}
BufOps::Write { obj, idx, value } => {
state.clear_status();
let handle = state.read_obj(*obj)?;
let val = state.read(*value)?;
let idx = state.read(*idx)? as usize;
let handle = state.read_obj(obj)?;
let val = state.read(value)?;
let idx = state.read(idx)? as usize;
let stacks: &mut ExtData = state.ext_mut();
let stack = stacks.store.get_mut(&handle).ok_or_else(|| Fault::ObjectNotExist(handle))?;
if idx < stack.len() {
@ -121,9 +121,9 @@ impl OpTrait for BufOps {
BufOps::Insert { obj, idx, value } => {
state.clear_status();
let handle = state.read_obj(*obj)?;
let val = state.read(*value)?;
let idx = state.read(*idx)? as usize;
let handle = state.read_obj(obj)?;
let val = state.read(value)?;
let idx = state.read(idx)? as usize;
let stacks: &mut ExtData = state.ext_mut();
let stack = stacks.store.get_mut(&handle).ok_or_else(|| Fault::ObjectNotExist(handle))?;
if idx < stack.len() {
@ -137,15 +137,15 @@ impl OpTrait for BufOps {
BufOps::Remove { dst, obj, idx } => {
state.clear_status();
let handle = state.read_obj(*obj)?;
let idx = state.read(*idx)? as usize;
let handle = state.read_obj(obj)?;
let idx = state.read(idx)? as usize;
let stacks: &mut ExtData = state.ext_mut();
let stack = stacks.store.get_mut(&handle).ok_or_else(|| Fault::ObjectNotExist(handle))?;
if idx < stack.len() {
let val = stack.remove(idx).unwrap();
let empty = stack.is_empty();
state.update_status(val);
state.write(*dst, val)?;
state.write(dst, val)?;
state.set_flag(Cond::Empty, empty);
} else {
state.set_flag(Cond::Overflow, true);
@ -153,15 +153,15 @@ impl OpTrait for BufOps {
}
BufOps::Resize { obj, len } => {
let handle = state.read_obj(*obj)?;
let len = state.read(*len)? as usize;
let handle = state.read_obj(obj)?;
let len = state.read(len)? as usize;
let stacks: &mut ExtData = state.ext_mut();
let stack = stacks.store.get_mut(&handle).ok_or_else(|| Fault::ObjectNotExist(handle))?;
stack.resize(len, 0);
}
BufOps::Reverse { obj } => {
let handle = state.read_obj(*obj)?;
let handle = state.read_obj(obj)?;
let stacks: &mut ExtData = state.ext_mut();
let stack = stacks.store.get_mut(&handle).ok_or_else(|| Fault::ObjectNotExist(handle))?;
let len = stack.len();
@ -177,8 +177,8 @@ impl OpTrait for BufOps {
}
BufOps::AppendBuf { obj, obj2 } => {
let handle = state.read_obj(*obj)?;
let handle2 = state.read_obj(*obj2)?;
let handle = state.read_obj(obj)?;
let handle2 = state.read_obj(obj2)?;
let stacks: &mut ExtData = state.ext_mut();
let stack2 = stacks.store.get(&handle2).ok_or_else(|| Fault::ObjectNotExist(handle))?.clone();
let stack = stacks.store.get_mut(&handle).ok_or_else(|| Fault::ObjectNotExist(handle))?;
@ -186,8 +186,8 @@ impl OpTrait for BufOps {
}
BufOps::PrependBuf { obj, obj2 } => {
let handle = state.read_obj(*obj)?;
let handle2 = state.read_obj(*obj2)?;
let handle = state.read_obj(obj)?;
let handle2 = state.read_obj(obj2)?;
let stacks: &mut ExtData = state.ext_mut();
let stack2 = stacks.store.get(&handle2).ok_or_else(|| Fault::ObjectNotExist(handle))?.clone();
let stack = stacks.store.get_mut(&handle).ok_or_else(|| Fault::ObjectNotExist(handle))?;

@ -57,13 +57,13 @@ impl OpTrait for ScreenOp {
let eres = EvalRes::default();
match self {
ScreenOp::ScreenInit { width, height } => {
let w = state.read(*width)?;
let h = state.read(*height)?;
let w = state.read(width)?;
let h = state.read(height)?;
init(state, w, h)?;
}
ScreenOp::Erase { color } => {
let color = (state.read(*color)? & 0xffffff) as u32;
let color = (state.read(color)? & 0xffffff) as u32;
let backend: &mut Backend = state.ext_mut();
for n in 0..(backend.buffer.len()) {
backend.buffer[n] = color;
@ -72,8 +72,8 @@ impl OpTrait for ScreenOp {
ScreenOp::SetOpt { opt, val } => {
state.clear_status();
let opt = state.read(*opt)?;
let val = state.read(*val)?;
let opt = state.read(opt)?;
let val = state.read(val)?;
let backend: &mut Backend = state.ext_mut();
match opt {
@ -93,7 +93,7 @@ impl OpTrait for ScreenOp {
}
ScreenOp::Blit { force } => {
let force = state.read(*force)?;
let force = state.read(force)?;
let backend: &mut Backend = state.ext_mut();
if force != 0 {
@ -122,9 +122,9 @@ impl OpTrait for ScreenOp {
ScreenOp::SetPixel { x, y, color } => {
state.clear_status();
let x = state.read(*x)?;
let y = state.read(*y)?;
let color = state.read(*color)?;
let x = state.read(x)?;
let y = state.read(y)?;
let color = state.read(color)?;
let backend: &mut Backend = state.ext_mut();
@ -168,8 +168,8 @@ impl OpTrait for ScreenOp {
let xval = xf.round() as u64;
let yval = yf.round() as u64;
state.write(*x, xval)?;
state.write(*y, yval)?;
state.write(x, xval)?;
state.write(y, yval)?;
}
}
}
@ -181,7 +181,7 @@ impl OpTrait for ScreenOp {
ScreenOp::TestKey { pressed, code } => {
state.clear_status();
let num = num2key(state.read(*code)?);
let num = num2key(state.read(code)?);
let backend: &mut Backend = state.ext_mut();
match &mut backend.window {
Some(w) => {
@ -191,7 +191,7 @@ impl OpTrait for ScreenOp {
}
Some(kn) => {
let down = w.is_key_down(kn) as u64;
state.write(*pressed, down)?;
state.write(pressed, down)?;
state.update_status(down);
}
}
@ -205,7 +205,7 @@ impl OpTrait for ScreenOp {
ScreenOp::TestMouse { pressed, button } => {
state.clear_status();
let omb = match state.read(*button)? {
let omb = match state.read(button)? {
0 => Some(MouseButton::Left),
1 => Some(MouseButton::Right),
2 => Some(MouseButton::Middle),
@ -220,7 +220,7 @@ impl OpTrait for ScreenOp {
Some(w) => {
if let Some(mb) = omb {
let is_pressed = w.get_mouse_down(mb) as u64;
state.write(*pressed, is_pressed)?;
state.write(pressed, is_pressed)?;
state.update_status(is_pressed);
}
}

Loading…
Cancel
Save