Adding a couple of tests
This commit is contained in:
parent
76302b4ca8
commit
c7828a4940
|
@ -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)
|
||||||
|
|
42
hbvm/src/engine/tests/mod.rs
Normal file
42
hbvm/src/engine/tests/mod.rs
Normal 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, );
|
||||||
|
}
|
|
@ -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,
|
||||||
|
|
|
@ -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,
|
||||||
|
|
||||||
];
|
];
|
||||||
|
|
Loading…
Reference in a new issue