Small improvements

wip/its-not-my-fault
ondra05 2023-06-08 23:23:23 +02:00
parent 8d6ee04eb8
commit cfad4761ba
No known key found for this signature in database
GPG Key ID: 0DA6D2BB2285E881
6 changed files with 58 additions and 51 deletions

View File

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

View File

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

View File

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

View File

@ -5,11 +5,11 @@ use {
ma_size::MemAccessSize,
};
pub const PAGE_SIZE: u64 = 8192;
pub const PAGE_SIZE: usize = 8192;
#[derive(Clone, Debug, Default)]
pub struct Memory {
pages: HashMap<u64, Box<[u8; PAGE_SIZE as usize]>>,
pages: HashMap<u64, Box<[u8; PAGE_SIZE]>>,
}
impl Memory {
@ -17,8 +17,8 @@ impl Memory {
// implemented.
pub fn insert_test_page(&mut self) {
self.pages.insert(0, unsafe {
use alloc::alloc::{alloc_zeroed, Layout, handle_alloc_error};
let layout = Layout::new::<[u8; PAGE_SIZE as usize]>();
use alloc::alloc::{alloc_zeroed, handle_alloc_error, Layout};
let layout = Layout::new::<[u8; PAGE_SIZE]>();
let ptr = alloc_zeroed(layout);
if ptr.is_null() {
handle_alloc_error(layout);
@ -29,13 +29,13 @@ impl Memory {
pub fn load<S: MemAccessSize>(&self, addr: u64) -> Option<Value> {
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();
unsafe {
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(),
S::BYTES.into(),
S::BYTES,
);
Some(value.assume_init())
}
@ -46,7 +46,7 @@ impl Memory {
pub fn store<S: MemAccessSize>(&mut self, addr: u64, value: Value) -> Result<(), ()> {
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 {
core::ptr::copy_nonoverlapping(
(&value as *const Value).cast::<u8>(),
@ -54,8 +54,8 @@ impl Memory {
.get_mut(&page)
.ok_or(())?
.as_mut_ptr()
.add(usize::from(offset)),
S::BYTES.into(),
.add(offset),
S::BYTES,
)
};
Ok(())
@ -66,21 +66,24 @@ impl Memory {
}
#[inline]
pub const fn split_addr(addr: u64) -> (u64, u16) {
(addr >> PAGE_SIZE.count_ones(), (addr & PAGE_SIZE) as u16)
pub const fn split_addr(addr: u64) -> (u64, usize) {
(addr >> PAGE_SIZE.count_ones(), (addr as usize & PAGE_SIZE))
}
macro_rules! size_markers {
($($name:ident = $size:expr),* $(,)?) => {
pub mod ma_size {
/// # Safety
/// Implementor has to assure that [`MemAccessSize::BYTES`] won't be larger than
/// size of [`Value`]
pub unsafe trait MemAccessSize {
const BYTES: u8;
const BYTES: usize;
}
$(
pub struct $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 {
core::ops,
hbbytecode::{OpParam, ParamRI, ParamRR, ParamRRI, ParamRRR},
@ -11,6 +6,11 @@ use {
value::Value,
};
use crate::validate;
mod mem;
mod value;
macro_rules! param {
($self:expr, $ty:ty) => {{
assert_impl_one!($ty: OpParam);
@ -26,7 +26,14 @@ macro_rules! param {
macro_rules! binary_op {
($self:expr, $ty:ident, $handler:expr) => {{
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);
$self.write_reg(
tg,
$self.memory
$self
.memory
.load::<$size>($self.read_reg(a0).int() + offset)
.ok_or(Exception::LoadAccess)?
.ok_or(Exception::LoadAccess)?,
);
}};
}