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