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::{
addr::*,
inst,
obj::{obj::*, syn::ast::*},
obj::{obj, syn::ast::*},
};
use byteorder::{WriteBytesExt, LE};
use snafu::Snafu;
@@ -55,7 +55,7 @@ impl Asm {
}
impl Assemble for Vec<SectionDef> {
type Out = Object;
type Out = obj::Object;
fn assemble(&self, asm: &mut Asm) -> Result<Self::Out> {
// collect globals
let mut globals = HashMap::new();
@@ -89,26 +89,26 @@ impl Assemble for Vec<SectionDef> {
.iter()
.map(|section| section.assemble(asm))
.collect::<Result<_>>()?;
Ok(Object {
version: OBJ_VERSION,
Ok(obj::Object {
version: obj::OBJ_VERSION,
sections,
})
}
}
impl Assemble for SectionDef {
type Out = Section;
type Out = obj::Section;
fn assemble(&self, asm: &mut Asm) -> Result<Self::Out> {
match self {
SectionDef::Data(section) => section.assemble(asm),
SectionDef::Data(section) => Ok(obj::Section::Data(section.assemble(asm)?)),
SectionDef::Meta(section) => section.assemble(asm),
}
}
}
impl Assemble for DataSection {
type Out = Section;
type Out = obj::DataSection;
fn assemble(&self, asm: &mut Asm) -> Result<Self::Out> {
let names = asm.gather_names(self)?;
@@ -142,7 +142,7 @@ impl Assemble for DataSection {
self.name
);
asm.names.pop();
Ok(Section::Data {
Ok(obj::DataSection {
start,
len: section_len,
contents,
@@ -151,7 +151,7 @@ impl Assemble for DataSection {
}
impl Assemble for MetaSection {
type Out = Section;
type Out = obj::Section;
fn assemble(&self, asm: &mut Asm) -> Result<Self::Out> {
let mut entries = HashMap::new();
@@ -175,7 +175,7 @@ impl Assemble for MetaSection {
};
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 {
self.sections.iter()
.map(|s| match s {
Section::Data { start, len, .. } => { (start + len) as usize }
Section::Data(DataSection { start, len, .. }) => { (start + len) as usize }
Section::Meta { .. } => { 0 }
}).max().unwrap_or(0)
}
@@ -81,14 +81,8 @@ section_kind! {
#[derive(Debug, Clone)]
pub enum Section {
Data {
start: u64,
len: u64,
contents: Vec<u8>,
},
Meta {
entries: HashMap<String, u64>,
},
Data(DataSection),
Meta(MetaSection),
}
impl Section {
@@ -100,24 +94,40 @@ impl Section {
let bytes = &cursor.get_ref()[start..end];
let kind: SectionKind = cursor.read_u8()?.try_into()?;
match kind {
SectionKind::Data => Section::data_section_from_bytes(bytes),
SectionKind::Meta => Section::meta_section_from_bytes(bytes),
SectionKind::Data => Ok(Section::Data(DataSection::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 start = cursor.read_u64::<LE>()?;
let len = cursor.read_u64::<LE>()?;
let contents = &bytes[cursor.position() as usize..];
Ok(Section::Data {
Ok(DataSection {
start,
len,
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 entry_count = cursor.read_u64::<LE>()?;
let mut entries = HashMap::new();
@@ -132,6 +142,6 @@ impl Section {
let value = cursor.read_u64::<LE>()?;
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];
for section in object.sections {
match section {
Section::Data {
Section::Data(DataSection {
start,
len,
contents,
} => {
}) => {
for offset in 0..len {
mem[(start + offset) as usize] = contents[offset as usize];
}
}
Section::Meta { entries } => {
Section::Meta(MetaSection { entries }) => {
if let Some(addr) = entries.get("entry") {
self.set_reg_unchecked(IP, *addr);
}