1
0
Fork 0
forked from koniifer/ableos

Adding a couple of tests

This commit is contained in:
able 2023-05-22 09:01:13 -05:00
parent 76302b4ca8
commit c7828a4940
4 changed files with 60 additions and 12 deletions

View file

@ -2,6 +2,8 @@ pub mod call_stack;
pub mod config; pub mod config;
pub mod enviroment_calls; pub mod enviroment_calls;
pub mod regs; pub mod regs;
#[cfg(test)]
pub mod tests;
use { use {
self::call_stack::CallStack, self::call_stack::CallStack,
@ -66,7 +68,7 @@ pub struct Engine {
pub last_timer_count: u32, pub last_timer_count: u32,
pub timer_callback: Option<fn() -> u32>, pub timer_callback: Option<fn() -> u32>,
pub memory: memory::Memory, pub memory: memory::Memory,
pub enviroment_call_table: [EnviromentCall; 256], pub enviroment_call_table: [Option<EnviromentCall>; 256],
pub call_stack: CallStack, pub call_stack: CallStack,
} }
use crate::engine::enviroment_calls::EnviromentCall; use crate::engine::enviroment_calls::EnviromentCall;
@ -87,7 +89,7 @@ impl Engine {
let _ = mem.set_addr8(addr as u64, byte); let _ = mem.set_addr8(addr as u64, byte);
} }
trace!("{:?}", mem.read_addr8(0)); trace!("{:?}", mem.read_addr8(0));
let ecall_table: [Option<EnviromentCall>; 256] = [None; 256];
Self { Self {
index: 0, index: 0,
program, program,
@ -95,7 +97,7 @@ impl Engine {
config: EngineConfig::default(), config: EngineConfig::default(),
last_timer_count: 0, last_timer_count: 0,
timer_callback: None, timer_callback: None,
enviroment_call_table: [empty_enviroment_call; 256], enviroment_call_table: ecall_table,
memory: mem, memory: mem,
call_stack: Vec::new(), call_stack: Vec::new(),
} }
@ -187,6 +189,9 @@ F5-F9 {:016X} {:016X} {:016X} {:016X} {:016X}",
} }
pub fn run(&mut self) -> Result<HaltStatus, RuntimeErrors> { pub fn run(&mut self) -> Result<HaltStatus, RuntimeErrors> {
use {HaltStatus::*, RuntimeErrors::*}; use {HaltStatus::*, RuntimeErrors::*};
if self.program.len() == 0 {
return Ok(Halted);
}
loop { loop {
// Break out of the loop // Break out of the loop
if self.index + 1 == self.program.len() { 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); let addr = usize::from_be_bytes(addr_array);
if addr > self.program.len() { if addr > self.program.len() {
panic!("Invalid jump address {}", addr) return Err(InvalidJumpAddress(addr as u64));
} else { } else {
let call = FnCall { ret: self.index }; let call = FnCall { ret: self.index };
self.call_stack.push(call); self.call_stack.push(call);
@ -434,7 +439,6 @@ F5-F9 {:016X} {:016X} {:016X} {:016X} {:016X}",
trace!("Jumping to {}", addr); trace!("Jumping to {}", addr);
self.dump(); self.dump();
// panic!();
} }
} }
@ -452,9 +456,8 @@ F5-F9 {:016X} {:016X} {:016X} {:016X} {:016X}",
self.index += 2; self.index += 2;
} }
_op_pair => { op_pair => {
// println!("OP Pair {}", op_pair.0); panic!("OP Pair {} - {}", op_pair.0, op_pair.1);
self.index += 1;
} }
} }
@ -465,6 +468,7 @@ F5-F9 {:016X} {:016X} {:016X} {:016X} {:016X}",
if (ret - self.last_timer_count) >= self.config.quantum { if (ret - self.last_timer_count) >= self.config.quantum {
return Ok(Running); return Ok(Running);
} }
self.last_timer_count = ret;
} }
} }
Ok(Halted) Ok(Halted)

View file

@ -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, );
}

View file

@ -5,15 +5,17 @@ pub mod bytecode;
pub mod engine; pub mod engine;
pub mod memory; pub mod memory;
#[derive(Debug)] #[derive(Debug, PartialEq)]
pub enum RuntimeErrors { pub enum RuntimeErrors {
InvalidOpcode(u8), InvalidOpcode(u8),
RegisterTooSmall, RegisterTooSmall,
HostError(u64), HostError(u64),
PageNotMapped(u64), PageNotMapped(u64),
InvalidJumpAddress(u64),
} }
// If you solve the halting problem feel free to remove this // If you solve the halting problem feel free to remove this
#[derive(PartialEq, Debug)]
pub enum HaltStatus { pub enum HaltStatus {
Halted, Halted,
Running, Running,

View file

@ -1,4 +1,4 @@
use holey_bytes::{ use hbvm::{
bytecode::ops::{Operations::*, RWSubTypes::*, SubTypes::*}, bytecode::ops::{Operations::*, RWSubTypes::*, SubTypes::*},
engine::Engine, engine::Engine,
RuntimeErrors, RuntimeErrors,
@ -8,7 +8,7 @@ fn main() -> Result<(), RuntimeErrors> {
#[rustfmt::skip] #[rustfmt::skip]
let prog: Vec<u8> = vec![ let prog: Vec<u8> = vec![
NOP as u8, NOP as u8, 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, 100, 20, 0xA7,
ADD as u8, ADD as u8,
EightBit as u8, 1, 0, 0xB0, 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, 0,
0, 0, 0, 0, 0, 0, 0, 2, 0xD0, 0, 0, 0, 0, 0, 0, 0, 2, 0xD0,
SUB as u8, EightBit as u8, 255, 0, 0xA7, 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, ADD as u8, Register8 as u8, 0xA7, 0xB0, 0xA7,
LOAD as u8, AddrToReg as u8, LOAD as u8, AddrToReg as u8,
0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 2,
0xA0, 0xA0,
// JUMP as u8, 0, 0, 0, 0, 0, 0, 0, 0,
JUMP as u8, 0, 0, 0, 0, 0, 0, 0, 0, JUMP as u8, 0, 0, 0, 0, 0, 0, 0, 0,
]; ];