Modified memory interface
I have no idea what I am doing rn
This commit is contained in:
parent
a071a4a7ae
commit
3decd01619
|
@ -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::<u8>(self.pc as _)
|
||||
.ok_or(VmRunError::ProgramFetchLoadEx(self.pc as _))?
|
||||
{
|
||||
UN => {
|
||||
|
@ -368,13 +368,7 @@ where
|
|||
#[inline(always)]
|
||||
unsafe fn decode<T: OpParam>(&mut self) -> T {
|
||||
let pc1 = self.pc + 1;
|
||||
let data = self
|
||||
.memory
|
||||
.load_prog_unchecked(pc1..pc1 + size_of::<T>())
|
||||
.as_ptr()
|
||||
.cast::<T>()
|
||||
.read();
|
||||
|
||||
let data = self.memory.prog_read_unchecked::<T>(pc1 as _);
|
||||
self.pc += 1 + size_of::<T>();
|
||||
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<I>(&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<I>(&mut self, index: I) -> &I::Output
|
||||
where
|
||||
I: SliceIndex<[u8]>;
|
||||
/// - Data read have to be valid
|
||||
unsafe fn prog_read<T>(&mut self, addr: u64) -> Option<T>;
|
||||
|
||||
/// 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
|
||||
|
|
|
@ -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<I>(&mut self, index: I) -> Option<&I::Output>
|
||||
where
|
||||
I: SliceIndex<[u8]>,
|
||||
{
|
||||
self.program.get(index)
|
||||
unsafe fn prog_read<T>(&mut self, addr: u64) -> Option<T> {
|
||||
let addr = addr as usize;
|
||||
self.program
|
||||
.get(addr..addr + size_of::<T>())
|
||||
.map(|x| x.as_ptr().cast::<T>().read())
|
||||
}
|
||||
|
||||
/// Fetch slice from program memory section, unchecked!
|
||||
#[inline(always)]
|
||||
unsafe fn load_prog_unchecked<I>(&mut self, index: I) -> &I::Output
|
||||
where
|
||||
I: SliceIndex<[u8]>,
|
||||
{
|
||||
self.program.get_unchecked(index)
|
||||
unsafe fn prog_read_unchecked<T>(&mut self, addr: u64) -> T {
|
||||
self.program.as_ptr().add(addr as _).cast::<T>().read()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue