Added valider

wip/its-not-my-fault
ondra05 2023-06-06 22:56:28 +02:00
parent 4f1fddfa4c
commit 21a598df49
No known key found for this signature in database
GPG Key ID: 0DA6D2BB2285E881
3 changed files with 80 additions and 7 deletions

View File

@ -9,7 +9,7 @@ macro_rules! constmod {
}
constmod!(pub opcode(u8) {
NOP = 0, // _
NOP = 0, // N
ADD = 1, // RRR
SUB = 2, // RRR
MUL = 3, // RRR
@ -37,8 +37,8 @@ constmod!(pub opcode(u8) {
JMP = 100, // I
JMPCOND = 101, // I
RET = 103, // _
ECALL = 255, // _
RET = 103, // N
ECALL = 255, // N
});
#[repr(packed)] pub struct ParamRRR(pub u8, pub u8, pub u8);

View File

@ -1,13 +1,18 @@
use hbvm::{vm::Vm, RuntimeErrors};
use hbvm::{validate::validate, vm::Vm, RuntimeErrors};
fn main() -> Result<(), RuntimeErrors> {
// TODO: Grab program from cmdline
#[rustfmt::skip]
let prog = &[];
unsafe {
let mut vm = Vm::new_unchecked(prog);
vm.run();
if let Err(e) = validate(prog) {
eprintln!("Program validation error: {e:?}");
return Ok(());
} else {
unsafe {
let mut vm = Vm::new_unchecked(prog);
vm.run();
}
}
Ok(())
}

View File

@ -0,0 +1,68 @@
macro_rules! bail {
($kind:ident, $start:expr, $curr:expr, $offset:expr) => {
return Err(Error {
kind: ErrorKind::$kind,
index: ($curr.as_ptr() as usize) - ($start.as_ptr() as usize) + $offset
})
};
($kind:ident, $start:expr, $curr:expr) => {
bail!($kind, $start, $curr, 0)
};
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum ErrorKind {
InvalidInstruction,
InvalidRegister,
Unimplemented,
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub struct Error {
kind: ErrorKind,
index: usize,
}
pub fn validate(mut program: &[u8]) -> Result<(), Error> {
use crate::bytecode::opcode::*;
#[inline]
fn reg(regs: &[u8]) -> Option<usize> {
regs.iter()
.enumerate()
.filter_map(|(n, &r)| (r > 59).then_some(n))
.next()
}
let start = program;
loop {
program = match program {
[] => return Ok(()),
// N
[NOP | RET | ECALL, rest @ ..] => rest,
// RRR
[ADD..=XOR | ADDF..=DIVF, _, _, _, rest @ ..] => {
if let Some(n) = reg(&program[1..=3]) {
bail!(InvalidRegister, start, program, n + 1)
}
rest
}
// RR
[NOT, _, _, rest @ ..] => {
if let Some(n) = reg(&program[1..=2]) {
bail!(InvalidRegister, start, program, n + 1)
}
rest
}
// RI
[LI, reg, _, _, _, _, _, _, _, _, rest @ ..] => {
if *reg > 59 {
bail!(InvalidRegister, start, program, 1)
}
rest
}
[LD | ST, ..] => bail!(Unimplemented, start, program),
_ => bail!(InvalidInstruction, start, program),
}
}
}