Add object layout, object parsing, instruction layout
* Object layout and parsing are done in the vm::obj module * Add MemCursor, a wrapper around the std::io::Cursor type for walking through VM memory * Add vm::tick module for containing the Vm::tick() method implementation, since it's pretty big * Instructions are now variable-sized, and are read lazily, one-at-a-time directly from memory. * Add VM runtime error structure * Probably some other stuff I forgot Signed-off-by: Alek Ratzloff <alekratz@gmail.com>
This commit is contained in:
107
src/vm/obj/obj.rs
Normal file
107
src/vm/obj/obj.rs
Normal file
@@ -0,0 +1,107 @@
|
||||
use crate::vm::obj::error::ParseError;
|
||||
use std::{
|
||||
convert::TryFrom,
|
||||
fmt::Debug,
|
||||
};
|
||||
|
||||
pub const MAGIC: u64 = 0xDEAD_BEA7_BA5E_BA11;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Object {
|
||||
pub header: Header,
|
||||
pub sections: Vec<Box<dyn Section>>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
pub struct Header {
|
||||
pub version: u16,
|
||||
pub sections: u16,
|
||||
}
|
||||
|
||||
macro_rules! section_kind {
|
||||
(
|
||||
pub enum $enum_name:ident {
|
||||
$($name:ident = $value:expr),* $(,)?
|
||||
}
|
||||
) => {
|
||||
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
#[repr(u8)]
|
||||
pub enum $enum_name {
|
||||
$($name = $value),*
|
||||
}
|
||||
|
||||
impl TryFrom<u8> for SectionKind {
|
||||
type Error = ParseError;
|
||||
|
||||
fn try_from(other: u8) -> std::result::Result<Self, Self::Error> {
|
||||
match other {
|
||||
$(
|
||||
$value => Ok($enum_name::$name),
|
||||
)*
|
||||
_ => Err(ParseError::UnknownSectionKind { kind: other }),
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
section_kind! {
|
||||
pub enum SectionKind {
|
||||
Data = 0x00,
|
||||
Code = 0x10,
|
||||
Meta = 0xFF,
|
||||
}
|
||||
}
|
||||
|
||||
pub trait Section: Debug {
|
||||
fn header(&self) -> SectionHeader;
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
pub struct SectionHeader {
|
||||
pub kind: SectionKind,
|
||||
pub checksum: u32,
|
||||
pub len: u64,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct DataSection {
|
||||
pub header: SectionHeader,
|
||||
pub load_location: u64,
|
||||
pub contents: Vec<u8>,
|
||||
}
|
||||
|
||||
impl Section for DataSection {
|
||||
fn header(&self) -> SectionHeader {
|
||||
self.header
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct CodeSection {
|
||||
pub header: SectionHeader,
|
||||
pub load_location: u64,
|
||||
pub contents: Vec<u8>,
|
||||
}
|
||||
|
||||
impl Section for CodeSection {
|
||||
fn header(&self) -> SectionHeader {
|
||||
self.header
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct MetaSection {
|
||||
pub header: SectionHeader,
|
||||
pub entry_count: u64,
|
||||
pub entries: Vec<(String, Vec<u8>)>,
|
||||
}
|
||||
|
||||
impl Section for MetaSection {
|
||||
fn header(&self) -> SectionHeader {
|
||||
self.header
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user