From c7828a49406ee6c6813505d8d524c068a41f360f Mon Sep 17 00:00:00 2001 From: able Date: Mon, 22 May 2023 09:01:13 -0500 Subject: [PATCH] Adding a couple of tests --- hbvm/src/engine/mod.rs | 20 ++++++++++------- hbvm/src/engine/tests/mod.rs | 42 ++++++++++++++++++++++++++++++++++++ hbvm/src/lib.rs | 4 +++- hbvm/src/main.rs | 6 +++--- 4 files changed, 60 insertions(+), 12 deletions(-) create mode 100644 hbvm/src/engine/tests/mod.rs diff --git a/hbvm/src/engine/mod.rs b/hbvm/src/engine/mod.rs index 23a11bfd..e1269286 100644 --- a/hbvm/src/engine/mod.rs +++ b/hbvm/src/engine/mod.rs @@ -2,6 +2,8 @@ pub mod call_stack; pub mod config; pub mod enviroment_calls; pub mod regs; +#[cfg(test)] +pub mod tests; use { self::call_stack::CallStack, @@ -66,7 +68,7 @@ pub struct Engine { pub last_timer_count: u32, pub timer_callback: Option u32>, pub memory: memory::Memory, - pub enviroment_call_table: [EnviromentCall; 256], + pub enviroment_call_table: [Option; 256], pub call_stack: CallStack, } use crate::engine::enviroment_calls::EnviromentCall; @@ -87,7 +89,7 @@ impl Engine { let _ = mem.set_addr8(addr as u64, byte); } trace!("{:?}", mem.read_addr8(0)); - + let ecall_table: [Option; 256] = [None; 256]; Self { index: 0, program, @@ -95,7 +97,7 @@ impl Engine { config: EngineConfig::default(), last_timer_count: 0, timer_callback: None, - enviroment_call_table: [empty_enviroment_call; 256], + enviroment_call_table: ecall_table, memory: mem, call_stack: Vec::new(), } @@ -187,6 +189,9 @@ F5-F9 {:016X} {:016X} {:016X} {:016X} {:016X}", } pub fn run(&mut self) -> Result { use {HaltStatus::*, RuntimeErrors::*}; + if self.program.len() == 0 { + return Ok(Halted); + } loop { // Break out of the loop if self.index + 1 == self.program.len() { @@ -425,7 +430,7 @@ F5-F9 {:016X} {:016X} {:016X} {:016X} {:016X}", let addr = usize::from_be_bytes(addr_array); if addr > self.program.len() { - panic!("Invalid jump address {}", addr) + return Err(InvalidJumpAddress(addr as u64)); } else { let call = FnCall { ret: self.index }; self.call_stack.push(call); @@ -434,7 +439,6 @@ F5-F9 {:016X} {:016X} {:016X} {:016X} {:016X}", trace!("Jumping to {}", addr); self.dump(); - // panic!(); } } @@ -452,9 +456,8 @@ F5-F9 {:016X} {:016X} {:016X} {:016X} {:016X}", self.index += 2; } - _op_pair => { - // println!("OP Pair {}", op_pair.0); - self.index += 1; + op_pair => { + panic!("OP Pair {} - {}", op_pair.0, op_pair.1); } } @@ -465,6 +468,7 @@ F5-F9 {:016X} {:016X} {:016X} {:016X} {:016X}", if (ret - self.last_timer_count) >= self.config.quantum { return Ok(Running); } + self.last_timer_count = ret; } } Ok(Halted) diff --git a/hbvm/src/engine/tests/mod.rs b/hbvm/src/engine/tests/mod.rs new file mode 100644 index 00000000..6e9aaf24 --- /dev/null +++ b/hbvm/src/engine/tests/mod.rs @@ -0,0 +1,42 @@ +use { + super::Engine, + crate::{HaltStatus, RuntimeErrors}, + alloc::vec, +}; + +#[test] +fn empty_program() { + let prog = vec![]; + let mut eng = Engine::new(prog); + let ret = eng.run(); + assert_eq!(ret, Ok(HaltStatus::Halted)); +} + +#[test] +fn max_quantum_reached() { + let prog = vec![0, 0, 0, 0]; + let mut eng = Engine::new(prog); + eng.set_timer_callback(|| { + return 1; + }); + eng.config.quantum = 1; + let ret = eng.run(); + assert_eq!(ret, Ok(HaltStatus::Running)); +} + +#[test] +fn jump_out_of_bounds() { + use crate::engine::Operations::JUMP; + let prog = vec![JUMP as u8, 0, 0, 0, 0, 0, 0, 1, 0]; + let mut eng = Engine::new(prog); + let ret = eng.run(); + assert_eq!(ret, Err(RuntimeErrors::InvalidJumpAddress(256))); +} + +#[test] +fn invalid_system_call() { + let prog = vec![255, 0]; + let mut eng = Engine::new(prog); + let ret = eng.run(); + // assert_eq!(ret, ); +} diff --git a/hbvm/src/lib.rs b/hbvm/src/lib.rs index 1b042b02..705c25c2 100644 --- a/hbvm/src/lib.rs +++ b/hbvm/src/lib.rs @@ -5,15 +5,17 @@ pub mod bytecode; pub mod engine; pub mod memory; -#[derive(Debug)] +#[derive(Debug, PartialEq)] pub enum RuntimeErrors { InvalidOpcode(u8), RegisterTooSmall, HostError(u64), PageNotMapped(u64), + InvalidJumpAddress(u64), } // If you solve the halting problem feel free to remove this +#[derive(PartialEq, Debug)] pub enum HaltStatus { Halted, Running, diff --git a/hbvm/src/main.rs b/hbvm/src/main.rs index e84a17ee..3c384260 100644 --- a/hbvm/src/main.rs +++ b/hbvm/src/main.rs @@ -1,4 +1,4 @@ -use holey_bytes::{ +use hbvm::{ bytecode::ops::{Operations::*, RWSubTypes::*, SubTypes::*}, engine::Engine, RuntimeErrors, @@ -8,7 +8,7 @@ fn main() -> Result<(), RuntimeErrors> { #[rustfmt::skip] let prog: Vec = vec![ NOP as u8, NOP as u8, - 10, 10, + 255, 10, ADD as u8, EightBit as u8, 100, 20, 0xA7, ADD as u8, EightBit as u8, 1, 0, 0xB0, @@ -17,11 +17,11 @@ fn main() -> Result<(), RuntimeErrors> { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0xD0, SUB as u8, EightBit as u8, 255, 0, 0xA7, + DIV as u8, EightBit as u8, 12, 5, 0xA8, ADD as u8, Register8 as u8, 0xA7, 0xB0, 0xA7, LOAD as u8, AddrToReg as u8, 0, 0, 0, 0, 0, 0, 0, 2, 0xA0, - // JUMP as u8, 0, 0, 0, 0, 0, 0, 0, 0, JUMP as u8, 0, 0, 0, 0, 0, 0, 0, 0, ];