Update intermediate object representation

Signed-off-by: Alek Ratzloff <alekratz@gmail.com>
This commit is contained in:
2020-02-25 15:08:49 -05:00
parent ef83cf7ef3
commit 461cf59bb0
3 changed files with 38 additions and 28 deletions

View File

@@ -1,7 +1,7 @@
use crate::vm::{ use crate::vm::{
addr::*, addr::*,
inst, inst,
obj::{obj::*, syn::ast::*}, obj::{obj, syn::ast::*},
}; };
use byteorder::{WriteBytesExt, LE}; use byteorder::{WriteBytesExt, LE};
use snafu::Snafu; use snafu::Snafu;
@@ -55,7 +55,7 @@ impl Asm {
} }
impl Assemble for Vec<SectionDef> { impl Assemble for Vec<SectionDef> {
type Out = Object; type Out = obj::Object;
fn assemble(&self, asm: &mut Asm) -> Result<Self::Out> { fn assemble(&self, asm: &mut Asm) -> Result<Self::Out> {
// collect globals // collect globals
let mut globals = HashMap::new(); let mut globals = HashMap::new();
@@ -89,26 +89,26 @@ impl Assemble for Vec<SectionDef> {
.iter() .iter()
.map(|section| section.assemble(asm)) .map(|section| section.assemble(asm))
.collect::<Result<_>>()?; .collect::<Result<_>>()?;
Ok(Object { Ok(obj::Object {
version: OBJ_VERSION, version: obj::OBJ_VERSION,
sections, sections,
}) })
} }
} }
impl Assemble for SectionDef { impl Assemble for SectionDef {
type Out = Section; type Out = obj::Section;
fn assemble(&self, asm: &mut Asm) -> Result<Self::Out> { fn assemble(&self, asm: &mut Asm) -> Result<Self::Out> {
match self { match self {
SectionDef::Data(section) => section.assemble(asm), SectionDef::Data(section) => Ok(obj::Section::Data(section.assemble(asm)?)),
SectionDef::Meta(section) => section.assemble(asm), SectionDef::Meta(section) => section.assemble(asm),
} }
} }
} }
impl Assemble for DataSection { impl Assemble for DataSection {
type Out = Section; type Out = obj::DataSection;
fn assemble(&self, asm: &mut Asm) -> Result<Self::Out> { fn assemble(&self, asm: &mut Asm) -> Result<Self::Out> {
let names = asm.gather_names(self)?; let names = asm.gather_names(self)?;
@@ -142,7 +142,7 @@ impl Assemble for DataSection {
self.name self.name
); );
asm.names.pop(); asm.names.pop();
Ok(Section::Data { Ok(obj::DataSection {
start, start,
len: section_len, len: section_len,
contents, contents,
@@ -151,7 +151,7 @@ impl Assemble for DataSection {
} }
impl Assemble for MetaSection { impl Assemble for MetaSection {
type Out = Section; type Out = obj::Section;
fn assemble(&self, asm: &mut Asm) -> Result<Self::Out> { fn assemble(&self, asm: &mut Asm) -> Result<Self::Out> {
let mut entries = HashMap::new(); let mut entries = HashMap::new();
@@ -175,7 +175,7 @@ impl Assemble for MetaSection {
}; };
entries.insert(line.name.to_string(), value); entries.insert(line.name.to_string(), value);
} }
Ok(Section::Meta { entries }) Ok(obj::Section::Meta(obj::MetaSection { entries }))
} }
} }

View File

@@ -38,7 +38,7 @@ impl Object {
pub fn virtual_len(&self) -> usize { pub fn virtual_len(&self) -> usize {
self.sections.iter() self.sections.iter()
.map(|s| match s { .map(|s| match s {
Section::Data { start, len, .. } => { (start + len) as usize } Section::Data(DataSection { start, len, .. }) => { (start + len) as usize }
Section::Meta { .. } => { 0 } Section::Meta { .. } => { 0 }
}).max().unwrap_or(0) }).max().unwrap_or(0)
} }
@@ -81,14 +81,8 @@ section_kind! {
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub enum Section { pub enum Section {
Data { Data(DataSection),
start: u64, Meta(MetaSection),
len: u64,
contents: Vec<u8>,
},
Meta {
entries: HashMap<String, u64>,
},
} }
impl Section { impl Section {
@@ -100,24 +94,40 @@ impl Section {
let bytes = &cursor.get_ref()[start..end]; let bytes = &cursor.get_ref()[start..end];
let kind: SectionKind = cursor.read_u8()?.try_into()?; let kind: SectionKind = cursor.read_u8()?.try_into()?;
match kind { match kind {
SectionKind::Data => Section::data_section_from_bytes(bytes), SectionKind::Data => Ok(Section::Data(DataSection::from_bytes(bytes)?)),
SectionKind::Meta => Section::meta_section_from_bytes(bytes), SectionKind::Meta => Ok(Section::Meta(MetaSection::from_bytes(bytes)?)),
} }
} }
}
fn data_section_from_bytes(bytes: &[u8]) -> Result<Self> { #[derive(Debug, Clone)]
pub struct DataSection {
pub start: u64,
pub len: u64,
pub contents: Vec<u8>,
}
impl DataSection {
pub fn from_bytes(bytes: &[u8]) -> Result<Self> {
let mut cursor = Cursor::new(bytes); let mut cursor = Cursor::new(bytes);
let start = cursor.read_u64::<LE>()?; let start = cursor.read_u64::<LE>()?;
let len = cursor.read_u64::<LE>()?; let len = cursor.read_u64::<LE>()?;
let contents = &bytes[cursor.position() as usize..]; let contents = &bytes[cursor.position() as usize..];
Ok(Section::Data { Ok(DataSection {
start, start,
len, len,
contents: From::from(contents), contents: From::from(contents),
}) })
} }
}
fn meta_section_from_bytes(bytes: &[u8]) -> Result<Self> { #[derive(Debug, Clone)]
pub struct MetaSection {
pub entries: HashMap<String, u64>,
}
impl MetaSection {
pub fn from_bytes(bytes: &[u8]) -> Result<Self> {
let mut cursor = Cursor::new(bytes); let mut cursor = Cursor::new(bytes);
let entry_count = cursor.read_u64::<LE>()?; let entry_count = cursor.read_u64::<LE>()?;
let mut entries = HashMap::new(); let mut entries = HashMap::new();
@@ -132,6 +142,6 @@ impl Section {
let value = cursor.read_u64::<LE>()?; let value = cursor.read_u64::<LE>()?;
entries.insert(key, value); entries.insert(key, value);
} }
Ok(Section::Meta { entries }) Ok(MetaSection { entries })
} }
} }

View File

@@ -25,16 +25,16 @@ impl State {
let mut mem = vec![0u8; max_mem]; let mut mem = vec![0u8; max_mem];
for section in object.sections { for section in object.sections {
match section { match section {
Section::Data { Section::Data(DataSection {
start, start,
len, len,
contents, contents,
} => { }) => {
for offset in 0..len { for offset in 0..len {
mem[(start + offset) as usize] = contents[offset as usize]; mem[(start + offset) as usize] = contents[offset as usize];
} }
} }
Section::Meta { entries } => { Section::Meta(MetaSection { entries }) => {
if let Some(addr) = entries.get("entry") { if let Some(addr) = entries.get("entry") {
self.set_reg_unchecked(IP, *addr); self.set_reg_unchecked(IP, *addr);
} }