Modified memory interface

I have no idea what I am doing rn
This commit is contained in:
Erin 2023-08-15 17:05:10 +02:00
parent a071a4a7ae
commit 3decd01619
2 changed files with 22 additions and 55 deletions

View file

@ -24,7 +24,7 @@ mod bmc;
use { use {
bmc::BlockCopier, bmc::BlockCopier,
core::{cmp::Ordering, mem::size_of, ops, slice::SliceIndex}, core::{cmp::Ordering, mem::size_of, ops},
derive_more::Display, derive_more::Display,
hbbytecode::{OpParam, ParamBB, ParamBBB, ParamBBBB, ParamBBD, ParamBBDH, ParamBBW, ParamBD}, hbbytecode::{OpParam, ParamBB, ParamBBB, ParamBBBB, ParamBBD, ParamBBDH, ParamBBW, ParamBD},
value::{Value, ValueVariant}, value::{Value, ValueVariant},
@ -96,9 +96,9 @@ where
// - Yes, we assume you run 64 bit CPU. Else ?conradluget a better CPU // - Yes, we assume you run 64 bit CPU. Else ?conradluget a better CPU
// sorry 8 bit fans, HBVM won't run on your Speccy :( // sorry 8 bit fans, HBVM won't run on your Speccy :(
unsafe { unsafe {
match *self match self
.memory .memory
.load_prog(self.pc) .prog_read::<u8>(self.pc as _)
.ok_or(VmRunError::ProgramFetchLoadEx(self.pc as _))? .ok_or(VmRunError::ProgramFetchLoadEx(self.pc as _))?
{ {
UN => { UN => {
@ -368,13 +368,7 @@ where
#[inline(always)] #[inline(always)]
unsafe fn decode<T: OpParam>(&mut self) -> T { unsafe fn decode<T: OpParam>(&mut self) -> T {
let pc1 = self.pc + 1; let pc1 = self.pc + 1;
let data = self let data = self.memory.prog_read_unchecked::<T>(pc1 as _);
.memory
.load_prog_unchecked(pc1..pc1 + size_of::<T>())
.as_ptr()
.cast::<T>()
.read();
self.pc += 1 + size_of::<T>(); self.pc += 1 + size_of::<T>();
data data
} }
@ -517,39 +511,17 @@ pub trait Memory {
count: usize, count: usize,
) -> Result<(), StoreError>; ) -> Result<(), StoreError>;
/// Fetch bytes from program section /// Read from program memory to execute
///
/// # Why?
/// Even Holey Bytes programs operate with
/// single address space, the actual implementation
/// may be different, so for these reasons there is a
/// separate function.
///
/// Also if your memory implementation differentiates between
/// readable and executable memory, this is the way to distinguish
/// the loads.
///
/// # Notice for implementors
/// This is a hot function. This is called on each opcode fetch
/// and instruction decode. Inlining the implementation is highly
/// recommended!
///
/// If you utilise some more heavy memory implementation, consider
/// performing caching as HBVM does not do that for you.
///
/// Has to return all the requested data. If cannot fetch data of requested
/// length, return [`None`].
fn load_prog<I>(&mut self, index: I) -> Option<&I::Output>
where
I: SliceIndex<[u8]>;
/// Fetch bytes from program section, unchecked.
/// ///
/// # Safety /// # Safety
/// You really have to be sure you get the bytes, got me? /// - Data read have to be valid
unsafe fn load_prog_unchecked<I>(&mut self, index: I) -> &I::Output unsafe fn prog_read<T>(&mut self, addr: u64) -> Option<T>;
where
I: SliceIndex<[u8]>; /// Read from program memory to exectue
///
/// # Safety
/// - You have to be really sure that these bytes are there, understand?
unsafe fn prog_read_unchecked<T>(&mut self, addr: u64) -> T;
} }
/// Unhandled load access trap /// Unhandled load access trap

View file

@ -1,5 +1,7 @@
//! Platform independent, software paged memory implementation //! Platform independent, software paged memory implementation
use core::mem::size_of;
pub mod lookup; pub mod lookup;
pub mod paging; pub mod paging;
@ -63,22 +65,15 @@ impl<'p, PfH: HandlePageFault> Memory for SoftPagedMem<'p, PfH> {
.map_err(StoreError) .map_err(StoreError)
} }
/// Fetch slice from program memory section unsafe fn prog_read<T>(&mut self, addr: u64) -> Option<T> {
#[inline(always)] let addr = addr as usize;
fn load_prog<I>(&mut self, index: I) -> Option<&I::Output> self.program
where .get(addr..addr + size_of::<T>())
I: SliceIndex<[u8]>, .map(|x| x.as_ptr().cast::<T>().read())
{
self.program.get(index)
} }
/// Fetch slice from program memory section, unchecked! unsafe fn prog_read_unchecked<T>(&mut self, addr: u64) -> T {
#[inline(always)] self.program.as_ptr().add(addr as _).cast::<T>().read()
unsafe fn load_prog_unchecked<I>(&mut self, index: I) -> &I::Output
where
I: SliceIndex<[u8]>,
{
self.program.get_unchecked(index)
} }
} }