Update intermediate object representation
Signed-off-by: Alek Ratzloff <alekratz@gmail.com>
This commit is contained in:
@@ -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 }))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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 })
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user