Small improvements

This commit is contained in:
Erin 2023-06-08 23:23:23 +02:00 committed by ondra05
parent a34f2fc9f8
commit da6ad6d2c7
6 changed files with 58 additions and 51 deletions

View file

@ -1,7 +1,10 @@
use std::fmt::{Display, Formatter};
use { use {
logos::{Lexer, Logos, Span}, logos::{Lexer, Logos, Span},
std::{ops::Range, str::FromStr}, std::{
fmt::{Display, Formatter},
ops::Range,
str::FromStr,
},
}; };
macro_rules! tokendef { macro_rules! tokendef {
@ -131,23 +134,13 @@ pub fn assembly(code: &str, buf: &mut Vec<u8>) -> Result<(), Error> {
} }
fn rr(&mut self) -> Result<(), ErrorKind> { fn rr(&mut self) -> Result<(), ErrorKind> {
expect_matches!( expect_matches!(self, Token::Register(r0), Token::PSep, Token::Register(r1),);
self,
Token::Register(r0),
Token::PSep,
Token::Register(r1),
);
self.buf.extend([r0, r1]); self.buf.extend([r0, r1]);
Ok(()) Ok(())
} }
fn ri(&mut self) -> Result<(), ErrorKind> { fn ri(&mut self) -> Result<(), ErrorKind> {
expect_matches!( expect_matches!(self, Token::Register(r0), Token::PSep, Token::Integer(r1),);
self,
Token::Register(r0),
Token::PSep,
Token::Integer(r1),
);
self.buf.push(r0); self.buf.push(r0);
self.buf.extend(r1.to_le_bytes()); self.buf.extend(r1.to_le_bytes());
@ -169,10 +162,7 @@ pub fn assembly(code: &str, buf: &mut Vec<u8>) -> Result<(), Error> {
} }
fn i(&mut self) -> Result<(), ErrorKind> { fn i(&mut self) -> Result<(), ErrorKind> {
expect_matches!( expect_matches!(self, Token::Integer(imm),);
self,
Token::Integer(imm),
);
self.buf.extend(imm.to_le_bytes()); self.buf.extend(imm.to_le_bytes());
Ok(()) Ok(())
} }
@ -185,6 +175,6 @@ pub fn assembly(code: &str, buf: &mut Vec<u8>) -> Result<(), Error> {
asm.assemble().map_err(|kind| Error { asm.assemble().map_err(|kind| Error {
kind, kind,
span: asm.lexer.span() span: asm.lexer.span(),
}) })
} }

View file

@ -49,10 +49,14 @@ constmod!(pub opcode(u8) {
ECALL = 30, // N; Issue system call ECALL = 30, // N; Issue system call
}); });
#[repr(packed)] pub struct ParamRRR(pub u8, pub u8, pub u8); #[repr(packed)]
#[repr(packed)] pub struct ParamRRI(pub u8, pub u8, pub u64); pub struct ParamRRR(pub u8, pub u8, pub u8);
#[repr(packed)] pub struct ParamRR(pub u8, pub u8); #[repr(packed)]
#[repr(packed)] pub struct ParamRI(pub u8, pub u64); pub struct ParamRRI(pub u8, pub u8, pub u64);
#[repr(packed)]
pub struct ParamRR(pub u8, pub u8);
#[repr(packed)]
pub struct ParamRI(pub u8, pub u64);
/// # Safety /// # Safety
/// TODO. /// TODO.

View file

@ -1,5 +1,7 @@
use std::io::{Read, stdin}; use {
use hbvm::{validate::validate, vm::Vm, RuntimeErrors}; hbvm::{validate::validate, vm::Vm, RuntimeErrors},
std::io::{stdin, Read},
};
fn main() -> Result<(), Box<dyn std::error::Error>> { fn main() -> Result<(), Box<dyn std::error::Error>> {
let mut prog = vec![]; let mut prog = vec![];

View file

@ -1,8 +1,8 @@
macro_rules! bail { macro_rules! bail {
($kind:ident, $start:expr, $curr:expr, $offset:expr) => { ($kind:ident, $start:expr, $curr:expr, $offset:expr) => {
return Err(Error { return Err(Error {
kind: ErrorKind::$kind, kind: ErrorKind::$kind,
index: ($curr.as_ptr() as usize) - ($start.as_ptr() as usize) + $offset index: ($curr.as_ptr() as usize) - ($start.as_ptr() as usize) + $offset,
}) })
}; };
($kind:ident, $start:expr, $curr:expr) => { ($kind:ident, $start:expr, $curr:expr) => {
@ -62,12 +62,12 @@ pub fn validate(mut program: &[u8]) -> Result<(), Error> {
rest rest
} }
// RRI // RRI
[LD..=SO, _, _, _, _, _, _, _, _, _, _, rest @ ..] => { [LB..=SO, _, _, _, _, _, _, _, _, _, _, rest @ ..] => {
if let Some(n) = reg(&program[1..=2]) { if let Some(n) = reg(&program[1..=2]) {
bail!(InvalidRegister, start, program, n + 1); bail!(InvalidRegister, start, program, n + 1);
} }
rest rest
}, }
_ => bail!(InvalidInstruction, start, program), _ => bail!(InvalidInstruction, start, program),
} }
} }

View file

@ -5,11 +5,11 @@ use {
ma_size::MemAccessSize, ma_size::MemAccessSize,
}; };
pub const PAGE_SIZE: u64 = 8192; pub const PAGE_SIZE: usize = 8192;
#[derive(Clone, Debug, Default)] #[derive(Clone, Debug, Default)]
pub struct Memory { pub struct Memory {
pages: HashMap<u64, Box<[u8; PAGE_SIZE as usize]>>, pages: HashMap<u64, Box<[u8; PAGE_SIZE]>>,
} }
impl Memory { impl Memory {
@ -17,8 +17,8 @@ impl Memory {
// implemented. // implemented.
pub fn insert_test_page(&mut self) { pub fn insert_test_page(&mut self) {
self.pages.insert(0, unsafe { self.pages.insert(0, unsafe {
use alloc::alloc::{alloc_zeroed, Layout, handle_alloc_error}; use alloc::alloc::{alloc_zeroed, handle_alloc_error, Layout};
let layout = Layout::new::<[u8; PAGE_SIZE as usize]>(); let layout = Layout::new::<[u8; PAGE_SIZE]>();
let ptr = alloc_zeroed(layout); let ptr = alloc_zeroed(layout);
if ptr.is_null() { if ptr.is_null() {
handle_alloc_error(layout); handle_alloc_error(layout);
@ -29,13 +29,13 @@ impl Memory {
pub fn load<S: MemAccessSize>(&self, addr: u64) -> Option<Value> { pub fn load<S: MemAccessSize>(&self, addr: u64) -> Option<Value> {
let (page, offset) = split_addr(addr); let (page, offset) = split_addr(addr);
if offset + u16::from(S::BYTES) <= (PAGE_SIZE as u16 - 1) { if offset + S::BYTES <= PAGE_SIZE - 1 {
let mut value = MaybeUninit::<Value>::zeroed(); let mut value = MaybeUninit::<Value>::zeroed();
unsafe { unsafe {
core::ptr::copy_nonoverlapping( core::ptr::copy_nonoverlapping(
self.pages.get(&page)?.as_ptr().add(usize::from(offset)), self.pages.get(&page)?.as_ptr().add(offset),
value.as_mut_ptr().cast(), value.as_mut_ptr().cast(),
S::BYTES.into(), S::BYTES,
); );
Some(value.assume_init()) Some(value.assume_init())
} }
@ -46,7 +46,7 @@ impl Memory {
pub fn store<S: MemAccessSize>(&mut self, addr: u64, value: Value) -> Result<(), ()> { pub fn store<S: MemAccessSize>(&mut self, addr: u64, value: Value) -> Result<(), ()> {
let (page, offset) = split_addr(addr); let (page, offset) = split_addr(addr);
if offset + u16::from(S::BYTES) <= (PAGE_SIZE as u16 - 1) { if offset + S::BYTES <= PAGE_SIZE - 1 {
unsafe { unsafe {
core::ptr::copy_nonoverlapping( core::ptr::copy_nonoverlapping(
(&value as *const Value).cast::<u8>(), (&value as *const Value).cast::<u8>(),
@ -54,8 +54,8 @@ impl Memory {
.get_mut(&page) .get_mut(&page)
.ok_or(())? .ok_or(())?
.as_mut_ptr() .as_mut_ptr()
.add(usize::from(offset)), .add(offset),
S::BYTES.into(), S::BYTES,
) )
}; };
Ok(()) Ok(())
@ -66,21 +66,24 @@ impl Memory {
} }
#[inline] #[inline]
pub const fn split_addr(addr: u64) -> (u64, u16) { pub const fn split_addr(addr: u64) -> (u64, usize) {
(addr >> PAGE_SIZE.count_ones(), (addr & PAGE_SIZE) as u16) (addr >> PAGE_SIZE.count_ones(), (addr as usize & PAGE_SIZE))
} }
macro_rules! size_markers { macro_rules! size_markers {
($($name:ident = $size:expr),* $(,)?) => { ($($name:ident = $size:expr),* $(,)?) => {
pub mod ma_size { pub mod ma_size {
/// # Safety
/// Implementor has to assure that [`MemAccessSize::BYTES`] won't be larger than
/// size of [`Value`]
pub unsafe trait MemAccessSize { pub unsafe trait MemAccessSize {
const BYTES: u8; const BYTES: usize;
} }
$( $(
pub struct $name; pub struct $name;
unsafe impl MemAccessSize for $name { unsafe impl MemAccessSize for $name {
const BYTES: u8 = $size; const BYTES: usize = $size;
} }
)* )*
} }

View file

@ -1,8 +1,3 @@
use crate::validate;
mod mem;
mod value;
use { use {
core::ops, core::ops,
hbbytecode::{OpParam, ParamRI, ParamRR, ParamRRI, ParamRRR}, hbbytecode::{OpParam, ParamRI, ParamRR, ParamRRI, ParamRRR},
@ -11,6 +6,11 @@ use {
value::Value, value::Value,
}; };
use crate::validate;
mod mem;
mod value;
macro_rules! param { macro_rules! param {
($self:expr, $ty:ty) => {{ ($self:expr, $ty:ty) => {{
assert_impl_one!($ty: OpParam); assert_impl_one!($ty: OpParam);
@ -26,7 +26,14 @@ macro_rules! param {
macro_rules! binary_op { macro_rules! binary_op {
($self:expr, $ty:ident, $handler:expr) => {{ ($self:expr, $ty:ident, $handler:expr) => {{
let ParamRRR(tg, a0, a1) = param!($self, ParamRRR); let ParamRRR(tg, a0, a1) = param!($self, ParamRRR);
$self.write_reg(tg, $handler(Value::$ty(&$self.read_reg(a0)), Value::$ty(&$self.read_reg(a1))).into()); $self.write_reg(
tg,
$handler(
Value::$ty(&$self.read_reg(a0)),
Value::$ty(&$self.read_reg(a1)),
)
.into(),
);
}}; }};
} }
@ -35,9 +42,10 @@ macro_rules! load {
let ParamRRI(tg, a0, offset) = param!($self, ParamRRI); let ParamRRI(tg, a0, offset) = param!($self, ParamRRI);
$self.write_reg( $self.write_reg(
tg, tg,
$self.memory $self
.memory
.load::<$size>($self.read_reg(a0).int() + offset) .load::<$size>($self.read_reg(a0).int() + offset)
.ok_or(Exception::LoadAccess)? .ok_or(Exception::LoadAccess)?,
); );
}}; }};
} }