From 3decd01619f241e79d48aa4f6bf7b2ce485abe7f Mon Sep 17 00:00:00 2001 From: Erin Date: Tue, 15 Aug 2023 17:05:10 +0200 Subject: [PATCH] Modified memory interface I have no idea what I am doing rn --- hbvm/src/lib.rs | 54 ++++++++-------------------------- hbvm/src/mem/softpaging/mod.rs | 23 ++++++--------- 2 files changed, 22 insertions(+), 55 deletions(-) diff --git a/hbvm/src/lib.rs b/hbvm/src/lib.rs index 3594a1d..a87366b 100644 --- a/hbvm/src/lib.rs +++ b/hbvm/src/lib.rs @@ -24,7 +24,7 @@ mod bmc; use { bmc::BlockCopier, - core::{cmp::Ordering, mem::size_of, ops, slice::SliceIndex}, + core::{cmp::Ordering, mem::size_of, ops}, derive_more::Display, hbbytecode::{OpParam, ParamBB, ParamBBB, ParamBBBB, ParamBBD, ParamBBDH, ParamBBW, ParamBD}, value::{Value, ValueVariant}, @@ -96,9 +96,9 @@ where // - Yes, we assume you run 64 bit CPU. Else ?conradluget a better CPU // sorry 8 bit fans, HBVM won't run on your Speccy :( unsafe { - match *self + match self .memory - .load_prog(self.pc) + .prog_read::(self.pc as _) .ok_or(VmRunError::ProgramFetchLoadEx(self.pc as _))? { UN => { @@ -368,13 +368,7 @@ where #[inline(always)] unsafe fn decode(&mut self) -> T { let pc1 = self.pc + 1; - let data = self - .memory - .load_prog_unchecked(pc1..pc1 + size_of::()) - .as_ptr() - .cast::() - .read(); - + let data = self.memory.prog_read_unchecked::(pc1 as _); self.pc += 1 + size_of::(); data } @@ -517,39 +511,17 @@ pub trait Memory { count: usize, ) -> Result<(), StoreError>; - /// Fetch bytes from program section - /// - /// # 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(&mut self, index: I) -> Option<&I::Output> - where - I: SliceIndex<[u8]>; - - /// Fetch bytes from program section, unchecked. + /// Read from program memory to execute /// /// # Safety - /// You really have to be sure you get the bytes, got me? - unsafe fn load_prog_unchecked(&mut self, index: I) -> &I::Output - where - I: SliceIndex<[u8]>; + /// - Data read have to be valid + unsafe fn prog_read(&mut self, addr: u64) -> Option; + + /// Read from program memory to exectue + /// + /// # Safety + /// - You have to be really sure that these bytes are there, understand? + unsafe fn prog_read_unchecked(&mut self, addr: u64) -> T; } /// Unhandled load access trap diff --git a/hbvm/src/mem/softpaging/mod.rs b/hbvm/src/mem/softpaging/mod.rs index f8c66dd..b50640e 100644 --- a/hbvm/src/mem/softpaging/mod.rs +++ b/hbvm/src/mem/softpaging/mod.rs @@ -1,5 +1,7 @@ //! Platform independent, software paged memory implementation +use core::mem::size_of; + pub mod lookup; pub mod paging; @@ -63,22 +65,15 @@ impl<'p, PfH: HandlePageFault> Memory for SoftPagedMem<'p, PfH> { .map_err(StoreError) } - /// Fetch slice from program memory section - #[inline(always)] - fn load_prog(&mut self, index: I) -> Option<&I::Output> - where - I: SliceIndex<[u8]>, - { - self.program.get(index) + unsafe fn prog_read(&mut self, addr: u64) -> Option { + let addr = addr as usize; + self.program + .get(addr..addr + size_of::()) + .map(|x| x.as_ptr().cast::().read()) } - /// Fetch slice from program memory section, unchecked! - #[inline(always)] - unsafe fn load_prog_unchecked(&mut self, index: I) -> &I::Output - where - I: SliceIndex<[u8]>, - { - self.program.get_unchecked(index) + unsafe fn prog_read_unchecked(&mut self, addr: u64) -> T { + self.program.as_ptr().add(addr as _).cast::().read() } }