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>, } #[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 for SectionKind { type Error = ParseError; fn try_from(other: u8) -> std::result::Result { 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, } 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, } 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)>, } impl Section for MetaSection { fn header(&self) -> SectionHeader { self.header } }