forked from AbleOS/holey-bytes
Small improvements
This commit is contained in:
parent
a34f2fc9f8
commit
da6ad6d2c7
|
@ -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(),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -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.
|
||||||
|
|
|
@ -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![];
|
||||||
|
|
|
@ -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),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
)*
|
)*
|
||||||
}
|
}
|
||||||
|
|
|
@ -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)?,
|
||||||
);
|
);
|
||||||
}};
|
}};
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue