diff --git a/src/libvm/build.rs b/src/libvm/build.rs index 22a5461..7b3aab8 100644 --- a/src/libvm/build.rs +++ b/src/libvm/build.rs @@ -1,6 +1,6 @@ use cfgrammar::yacc::YaccKind; use lrlex::LexerBuilder; -use lrpar::{CTParserBuilder}; +use lrpar::CTParserBuilder; use rerun_except::rerun_except; fn main() -> Result<(), Box> { @@ -10,9 +10,6 @@ fn main() -> Result<(), Box> { LexerBuilder::new() .rule_ids_map(lex_rule_ids_map) .process_file_in_src("obj/syn/lexer.l")?; - rerun_except(&[ - "examples/*.asm", - "tests/*.asm", - ]).unwrap(); + rerun_except(&["examples/*.asm", "tests/*.asm"]).unwrap(); Ok(()) } diff --git a/src/libvm/src/addr.rs b/src/libvm/src/addr.rs index e13ab95..e51da37 100644 --- a/src/libvm/src/addr.rs +++ b/src/libvm/src/addr.rs @@ -33,7 +33,7 @@ macro_rules! impl_add_assign { self.0 = self.0 + (rhs as u64); } } - } + }; } impl_add_assign!(usize); @@ -53,7 +53,7 @@ macro_rules! impl_cmp { self.0.partial_cmp(&other) } } - } + }; } impl_cmp!(usize); @@ -66,7 +66,7 @@ macro_rules! impl_from { Addr(other as u64) } } - } + }; } impl_from!(usize); diff --git a/src/libvm/src/error.rs b/src/libvm/src/error.rs index c55f0a3..4868d33 100644 --- a/src/libvm/src/error.rs +++ b/src/libvm/src/error.rs @@ -1,4 +1,4 @@ -use crate::{inst::InstOp, reg::Reg, addr::*,}; +use crate::{addr::*, inst::InstOp, reg::Reg}; use snafu::Snafu; #[derive(Snafu, Debug, Clone)] diff --git a/src/libvm/src/inst.rs b/src/libvm/src/inst.rs index e03a812..4776a27 100644 --- a/src/libvm/src/inst.rs +++ b/src/libvm/src/inst.rs @@ -125,34 +125,28 @@ impl Inst { pub fn len(&self) -> usize { match self { Inst::Add(dest, source) - | Inst::Sub(dest, source) - | Inst::Mul(dest, source) - | Inst::Div(dest, source) - | Inst::IDiv(dest, source) - | Inst::Mod(dest, source) - | Inst::And(dest, source) - | Inst::Or(dest, source) - | Inst::Xor(dest, source) - | Inst::Shl(dest, source) - | Inst::Shr(dest, source) - | Inst::INeg(dest, source) - | Inst::Inv(dest, source) - | Inst::Not(dest, source) - | Inst::Mov(dest, source) => { 3 + dest.len() + source.len() } - Inst::CmpEq(s1, s2) - | Inst::CmpLt(s1, s2) - | Inst::Int(s1, s2) => { 3 + s1.len() + s2.len() } - Inst::Jmp(v) - | Inst::Jz(v) - | Inst::Jnz(v) - | Inst::Call(v) - | Inst::Push(v) => { 3 + v.len() } - Inst::Pop(v) => { 3 + v.len() } - Inst::Ret - | Inst::Halt - | Inst::Nop - | Inst::Dump - | Inst::IRet => { 2 } + | Inst::Sub(dest, source) + | Inst::Mul(dest, source) + | Inst::Div(dest, source) + | Inst::IDiv(dest, source) + | Inst::Mod(dest, source) + | Inst::And(dest, source) + | Inst::Or(dest, source) + | Inst::Xor(dest, source) + | Inst::Shl(dest, source) + | Inst::Shr(dest, source) + | Inst::INeg(dest, source) + | Inst::Inv(dest, source) + | Inst::Not(dest, source) + | Inst::Mov(dest, source) => 3 + dest.len() + source.len(), + Inst::CmpEq(s1, s2) | Inst::CmpLt(s1, s2) | Inst::Int(s1, s2) => { + 3 + s1.len() + s2.len() + } + Inst::Jmp(v) | Inst::Jz(v) | Inst::Jnz(v) | Inst::Call(v) | Inst::Push(v) => { + 3 + v.len() + } + Inst::Pop(v) => 3 + v.len(), + Inst::Ret | Inst::Halt | Inst::Nop | Inst::Dump | Inst::IRet => 2, } } } @@ -176,7 +170,10 @@ impl Source { pub fn len(&self) -> usize { match self { Source::Addr64(_) | Source::Addr32(_) | Source::Addr16(_) | Source::Addr8(_) => 8, - Source::RegAddr64(_) | Source::RegAddr32(_) | Source::RegAddr16(_) | Source::RegAddr8(_) => 1, + Source::RegAddr64(_) + | Source::RegAddr32(_) + | Source::RegAddr16(_) + | Source::RegAddr8(_) => 1, Source::Reg(_) => 1, Source::Imm(_) => 8, } diff --git a/src/libvm/src/interrupt.rs b/src/libvm/src/interrupt.rs index 1f563ba..80fb5a6 100644 --- a/src/libvm/src/interrupt.rs +++ b/src/libvm/src/interrupt.rs @@ -26,7 +26,7 @@ pub const IVT_LENGTH: usize = 512; pub struct Interrupt(u64); const ENABLED_MASK: u64 = 0x8000_0000_0000_0000; -const ADDR_MASK: u64 = 0x07ff_ffff_ffff_ffff; +const ADDR_MASK: u64 = 0x07ff_ffff_ffff_ffff; impl Interrupt { pub fn enabled(&self) -> bool { @@ -37,7 +37,7 @@ impl Interrupt { let enabled = (enabled as u64) << 63; self.0 |= enabled; } - + pub fn addr(&self) -> Addr { Addr((self.0 & ADDR_MASK) << 5) } diff --git a/src/libvm/src/mem.rs b/src/libvm/src/mem.rs index 335f24c..2ccb8c5 100644 --- a/src/libvm/src/mem.rs +++ b/src/libvm/src/mem.rs @@ -8,11 +8,14 @@ pub struct MemCursor { } impl MemCursor - where Cursor: ReadBytesExt, - T: AsRef<[u8]> +where + Cursor: ReadBytesExt, + T: AsRef<[u8]>, { pub fn new(mem: T) -> Self { - MemCursor { cursor: Cursor::new(mem) } + MemCursor { + cursor: Cursor::new(mem), + } } pub fn position(&self) -> u64 { @@ -32,7 +35,7 @@ impl MemCursor let end = start + count; self.check_addr(end as u64 - 1)?; self.cursor.set_position(end as u64); - Ok(&self.cursor.get_ref().as_ref()[start .. end]) + Ok(&self.cursor.get_ref().as_ref()[start..end]) } pub fn next_u8_unchecked(&mut self) -> u8 { @@ -61,7 +64,7 @@ impl MemCursor self.check_addr(self.position() + 3) .map(|_| self.next_u32_unchecked()) } - + pub fn next_u64_unchecked(&mut self) -> u64 { self.cursor.read_u64::().unwrap() } @@ -220,7 +223,8 @@ impl MemCursor } impl MemCursor - where T: AsRef<[u8]> +where + T: AsRef<[u8]>, { fn check_addr(&self, addr: u64) -> Result<()> { if addr >= (self.cursor.get_ref().as_ref().len() as u64) { @@ -232,8 +236,9 @@ impl MemCursor } impl MemCursor - where Cursor: WriteBytesExt, - T: AsRef<[u8]> +where + Cursor: WriteBytesExt, + T: AsRef<[u8]>, { pub fn write_u8_unchecked(&mut self, value: u8) { self.cursor.write_u8(value).unwrap(); diff --git a/src/libvm/src/obj/assemble.rs b/src/libvm/src/obj/assemble.rs index 05359ed..d15f108 100644 --- a/src/libvm/src/obj/assemble.rs +++ b/src/libvm/src/obj/assemble.rs @@ -1,7 +1,7 @@ pub mod error; -pub mod session; mod includes; mod names; +pub mod session; use self::{error::*, session::AsmSession}; use crate::{ @@ -11,7 +11,7 @@ use crate::{ obj::{ obj::{self, Object}, syn::ast::*, - } + }, }; use byteorder::{WriteBytesExt, LE}; use std::{collections::HashMap, path::Path}; @@ -48,7 +48,7 @@ impl Asm for Directive { match self { Directive::Data(section) => Ok(Some(obj::Section::Data(section.assemble(asm)?))), Directive::Meta(section) => section.assemble(asm).map(Some), - Directive::Include(_) => { Ok(None) } + Directive::Include(_) => Ok(None), } } } @@ -81,7 +81,10 @@ impl Asm for DataSection { let mut contents = Vec::with_capacity(content_len as usize); for (pos, line) in self.lines(start) { let expected_len = pos - (start as usize); - assert!(expected_len >= contents.len(), "next line size would cause section to shrink"); + assert!( + expected_len >= contents.len(), + "next line size would cause section to shrink" + ); // resize contents if necessary, this pads out aligned values contents.resize(expected_len, 0); contents.extend(line.assemble(session)?); @@ -93,11 +96,7 @@ impl Asm for DataSection { "in section {}", self.name ); - assert_eq!( - session.pos - start, content_len, - "in section {}", - self.name - ); + assert_eq!(session.pos - start, content_len, "in section {}", self.name); session.name_stack.pop(); Ok(obj::DataSection { @@ -122,8 +121,15 @@ impl Asm for MetaSection { } let value = match &line.value { Value::Int(i) => *i, - Value::Name(s) => session.lookup_name(s.as_str()) - .ok_or_else(|| AsmError::UnknownName { name: s.to_string() })?.addr.0, + Value::Name(s) => { + session + .lookup_name(s.as_str()) + .ok_or_else(|| AsmError::UnknownName { + name: s.to_string(), + })? + .addr + .0 + } Value::Reg(_) | Value::Here | Value::Addr(_, _) => { return Err(AsmError::IllegalMetaValue { name: line.name.to_string(), @@ -218,10 +224,7 @@ impl Asm for Inst { let dest_encoding = dest.source_encoding() << 4; bytes.write_u8(dest_encoding).unwrap(); bytes.extend(dest.assemble(session)?); - assert_eq!( - len, - bytes.len(), - ); + assert_eq!(len, bytes.len(),); Ok(bytes) } Inst::Int(v1, v2) => self.map_source_source(session, inst::INT, v1, v2), @@ -235,47 +238,56 @@ impl Asm for Inst { } impl Inst { - fn map_dest_source(&self, session: &mut AsmSession, op: inst::InstOp, dest: &Value, source: &Value) -> Result> { + fn map_dest_source( + &self, + session: &mut AsmSession, + op: inst::InstOp, + dest: &Value, + source: &Value, + ) -> Result> { let len = self.len(); let mut bytes = Vec::with_capacity(len); bytes.write_u16::(op).unwrap(); - let dest_encoding = - dest.dest_encoding() - .ok_or_else(|| AsmError::IllegalDestValue { - value: dest.clone(), - })?; + let dest_encoding = dest + .dest_encoding() + .ok_or_else(|| AsmError::IllegalDestValue { + value: dest.clone(), + })?; let source_encoding = source.source_encoding(); bytes .write_u8((dest_encoding << 4) | source_encoding) .unwrap(); bytes.extend(dest.assemble(session)?); bytes.extend(source.assemble(session)?); - assert_eq!( - len, - bytes.len(), - ); + assert_eq!(len, bytes.len(),); Ok(bytes) } - fn map_source_source(&self, session: &mut AsmSession, op: inst::InstOp, s1: &Value, s2: &Value) -> Result> { + fn map_source_source( + &self, + session: &mut AsmSession, + op: inst::InstOp, + s1: &Value, + s2: &Value, + ) -> Result> { let len = self.len(); let mut bytes = Vec::with_capacity(len); bytes.write_u16::(op).unwrap(); let s1_encoding = s1.source_encoding(); let s2_encoding = s2.source_encoding(); - bytes - .write_u8((s1_encoding << 4) | s2_encoding) - .unwrap(); + bytes.write_u8((s1_encoding << 4) | s2_encoding).unwrap(); bytes.extend(s1.assemble(session)?); bytes.extend(s2.assemble(session)?); - assert_eq!( - len, - bytes.len(), - ); + assert_eq!(len, bytes.len(),); Ok(bytes) } - fn map_source(&self, session: &mut AsmSession, op: inst::InstOp, source: &Value) -> Result> { + fn map_source( + &self, + session: &mut AsmSession, + op: inst::InstOp, + source: &Value, + ) -> Result> { let len = self.len(); let mut bytes = Vec::with_capacity(len); bytes.write_u16::(op).unwrap(); @@ -290,10 +302,7 @@ impl Inst { let len = self.len(); let mut bytes = Vec::with_capacity(len); bytes.write_u16::(op).unwrap(); - assert_eq!( - len, - bytes.len(), - ); + assert_eq!(len, bytes.len(),); Ok(bytes) } } @@ -306,8 +315,12 @@ impl Asm for Value { Value::Int(i) => Ok(i.to_le_bytes().to_vec()), Value::Reg(r) => Ok(vec![*r]), Value::Name(name) => { - let value = session.lookup_name(name.as_str()) - .ok_or_else(|| AsmError::UnknownName { name: name.to_string() })?; + let value = + session + .lookup_name(name.as_str()) + .ok_or_else(|| AsmError::UnknownName { + name: name.to_string(), + })?; Ok(value.addr.0.to_le_bytes().to_vec()) } Value::Here => Ok(session.pos.to_le_bytes().to_vec()), @@ -331,7 +344,7 @@ mod test { fn test_inst_len() { let mut session = AsmSession::default(); //asm.names - //.push(vec![("test".to_string(), Addr(0u64))].into_iter().collect()); + //.push(vec![("test".to_string(), Addr(0u64))].into_iter().collect()); macro_rules! assert_len { ($inst:expr) => {{ diff --git a/src/libvm/src/obj/assemble/error.rs b/src/libvm/src/obj/assemble/error.rs index 0ddc932..1791814 100644 --- a/src/libvm/src/obj/assemble/error.rs +++ b/src/libvm/src/obj/assemble/error.rs @@ -112,4 +112,3 @@ impl From for SyntaxError { } pub type Result = std::result::Result; - diff --git a/src/libvm/src/obj/assemble/names.rs b/src/libvm/src/obj/assemble/names.rs index 062ce86..c465f5d 100644 --- a/src/libvm/src/obj/assemble/names.rs +++ b/src/libvm/src/obj/assemble/names.rs @@ -1,14 +1,14 @@ use crate::{ addr::Addr, obj::{ - assemble::{ - session::AsmSession, - error::*, - }, - syn::ast::{DataSection, DataLine, Directive}, + assemble::{error::*, session::AsmSession}, + syn::ast::{DataLine, DataSection, Directive}, }, }; -use std::{collections::{HashMap, HashSet}, rc::Rc}; +use std::{ + collections::{HashMap, HashSet}, + rc::Rc, +}; // TODO(asm) make custom Names type that has "merge" that will catch errors with duplicate names pub type Names = HashMap; @@ -53,12 +53,15 @@ pub fn get_section_names(section: &DataSection) -> Result { return Err(AsmError::DuplicateLabel { name: name.clone() }); } let export = exports.remove(name); - - names.insert(name.clone(), Name { - name: name.clone(), - addr: Addr(pos as u64), - export, - }); + + names.insert( + name.clone(), + Name { + name: name.clone(), + addr: Addr(pos as u64), + export, + }, + ); } } @@ -66,7 +69,9 @@ pub fn get_section_names(section: &DataSection) -> Result { if exports.is_empty() { Ok(names) } else { - Err(AsmError::UnknownExport { name: exports.iter().next().unwrap().to_string() }) + Err(AsmError::UnknownExport { + name: exports.iter().next().unwrap().to_string(), + }) } } @@ -93,12 +98,16 @@ pub fn get_exports(session: &mut AsmSession) -> Result { for name_map in all_exports.iter() { let names_set: HashSet<_> = name_map.keys().collect(); if let Some(dupe) = exports.intersection(&names_set).next() { - return Err(AsmError::DuplicateExport { name: dupe.to_string() }); + return Err(AsmError::DuplicateExport { + name: dupe.to_string(), + }); } exports.extend(names_set); } // NOTE: this can probably be done with a fancy combinator chain - Ok(all_exports.into_iter() - .fold(Names::new(), |mut acc, val| { acc.extend(val); acc })) + Ok(all_exports.into_iter().fold(Names::new(), |mut acc, val| { + acc.extend(val); + acc + })) } diff --git a/src/libvm/src/obj/assemble/session.rs b/src/libvm/src/obj/assemble/session.rs index dd1c7c0..a267568 100644 --- a/src/libvm/src/obj/assemble/session.rs +++ b/src/libvm/src/obj/assemble/session.rs @@ -1,14 +1,12 @@ -use crate::{ - obj::{ - assemble::{ - Asm, - includes::GetIncludes, - names::{self, Name, Names}, - error::*, - }, - obj::Object, - syn::ast::Ast, +use crate::obj::{ + assemble::{ + error::*, + includes::GetIncludes, + names::{self, Name, Names}, + Asm, }, + obj::Object, + syn::ast::Ast, }; use std::{ collections::BTreeMap, @@ -19,19 +17,17 @@ use std::{ /// A shared session for the assembler. #[derive(Debug, Default)] pub struct AsmSession { - pub (in super) includes: Rc>, - pub (in super) include_search_paths: Vec, - pub (in super) include_stack: Vec, - pub (in super) name_stack: Vec, - pub (in super) pos: u64, + pub(super) includes: Rc>, + pub(super) include_search_paths: Vec, + pub(super) include_stack: Vec, + pub(super) name_stack: Vec, + pub(super) pos: u64, } impl AsmSession { pub fn assemble(&mut self) -> Result { let includes = Rc::clone(&self.includes); - let sections: Vec<_> = includes.iter() - .flat_map(|(_, ast)| ast) - .collect(); + let sections: Vec<_> = includes.iter().flat_map(|(_, ast)| ast).collect(); sections.assemble(self) } @@ -46,19 +42,21 @@ impl AsmSession { Ok(()) } - pub (in super) fn current_include_path(&self) -> Option<&Path> { + pub(super) fn current_include_path(&self) -> Option<&Path> { self.include_stack.last().map(PathBuf::as_path) } - pub (in super) fn resolve_include_path(&self, path: impl AsRef) -> Option { + pub(super) fn resolve_include_path(&self, path: impl AsRef) -> Option { let path = path.as_ref(); self.current_include_path() .and_then(|last_path| last_path.parent()) .map(|last_dir| last_dir.join(path)) - .or_else(|| self.include_search_paths - .iter() - .filter_map(|include| include.join(path).canonicalize().ok()) - .next()) + .or_else(|| { + self.include_search_paths + .iter() + .filter_map(|include| include.join(path).canonicalize().ok()) + .next() + }) } pub fn lookup_name(&self, name: &str) -> Option<&Name> { diff --git a/src/libvm/src/obj/disassemble.rs b/src/libvm/src/obj/disassemble.rs index 6f7a3a0..dc8ae71 100644 --- a/src/libvm/src/obj/disassemble.rs +++ b/src/libvm/src/obj/disassemble.rs @@ -1,8 +1,9 @@ use crate::{mem::MemCursor, obj::obj::*}; -use prettytable::{Table, row, cell}; -use std::io::{self, Write as Write}; +use prettytable::{cell, row, Table}; +use std::io::{self, Write}; -const SEP: &str = "================================================================================"; +const SEP: &str = + "================================================================================"; pub trait Disasm { fn disasm(&self, writer: &mut dyn Write) -> io::Result<()>; @@ -61,8 +62,8 @@ impl Disasm for DataSection { if let Ok(inst) = cursor.next_inst() { let start = cursor_pos as usize; let end = start + inst.len(); - let data = &self.contents.as_slice()[start .. end]; - table.add_row(row! [ + let data = &self.contents.as_slice()[start..end]; + table.add_row(row![ format!("{:016x} <{}+{:x}>", pos, self.name, cursor_pos), bytes_hex(data), format!("{:?}", inst), diff --git a/src/libvm/src/obj/error.rs b/src/libvm/src/obj/error.rs index ed45922..229bcbc 100644 --- a/src/libvm/src/obj/error.rs +++ b/src/libvm/src/obj/error.rs @@ -42,4 +42,3 @@ into_parse_error! { } pub type Result = std::result::Result; - diff --git a/src/libvm/src/obj/obj.rs b/src/libvm/src/obj/obj.rs index 2cad6e3..c380f25 100644 --- a/src/libvm/src/obj/obj.rs +++ b/src/libvm/src/obj/obj.rs @@ -114,8 +114,8 @@ pub enum Section { impl Section { pub fn len(&self) -> usize { match self { - Section::Data(s) => { 1 + 8 + s.len() }, - Section::Meta(s) => { 1 + 8 + s.len() }, + Section::Data(s) => 1 + 8 + s.len(), + Section::Meta(s) => 1 + 8 + s.len(), } } @@ -129,7 +129,7 @@ impl Section { Section::Meta(s) => { cursor.write_u8(SectionKind::Meta.into()).unwrap(); s.to_bytes() - }, + } }; cursor.write_u64::(bytes.len() as u64).unwrap(); cursor.write(&bytes).unwrap(); @@ -181,7 +181,7 @@ impl DataSection { let name_len = cursor.read_u16::()? as usize; let name_start = cursor.position() as usize; let name_end = name_start + name_len; - let name_bytes = &bytes[name_start .. name_end]; + let name_bytes = &bytes[name_start..name_end]; let name_string = String::from_utf8(name_bytes.to_vec())?; cursor.set_position(name_end as u64); @@ -205,7 +205,9 @@ pub struct MetaSection { impl MetaSection { pub fn len(&self) -> usize { - 8 + self.entries.iter() + 8 + self + .entries + .iter() .map(|(k, _)| 8 + k.as_bytes().len() + 8) .sum::() } @@ -254,11 +256,11 @@ mod test { name: "data".to_string(), start: 0, len: 16, - contents: vec!(0u8; 16), + contents: vec![0u8; 16], }), Section::Meta(MetaSection { entries: Default::default(), - }) + }), ], }; diff --git a/src/libvm/src/obj/syn/ast.rs b/src/libvm/src/obj/syn/ast.rs index e979a8c..160714b 100644 --- a/src/libvm/src/obj/syn/ast.rs +++ b/src/libvm/src/obj/syn/ast.rs @@ -1,8 +1,4 @@ -use crate::{ - interrupt::Interrupt, - inst, - reg::Reg, -}; +use crate::{inst, interrupt::Interrupt, reg::Reg}; pub type Ast = Vec; @@ -182,7 +178,7 @@ impl Value { Value::Addr(v, _) => v.len(), } } - + pub fn dest_encoding(&self) -> Option { match self { Value::Int(_) | Value::Name(_) | Value::Here => None, @@ -291,34 +287,30 @@ impl Inst { pub fn len(&self) -> usize { match self { Inst::Add(v1, v2) - | Inst::Sub(v1, v2) - | Inst::Mul(v1, v2) - | Inst::Div(v1, v2) - | Inst::IDiv(v1, v2) - | Inst::Mod(v1, v2) - | Inst::And(v1, v2) - | Inst::Or(v1, v2) - | Inst::Xor(v1, v2) - | Inst::Shl(v1, v2) - | Inst::Shr(v1, v2) - | Inst::INeg(v1, v2) - | Inst::Inv(v1, v2) - | Inst::Not(v1, v2) - | Inst::CmpEq(v1, v2) - | Inst::CmpLt(v1, v2) - | Inst::Int(v1, v2) - | Inst::Mov(v1, v2) => { 3 + v1.len() + v2.len() } + | Inst::Sub(v1, v2) + | Inst::Mul(v1, v2) + | Inst::Div(v1, v2) + | Inst::IDiv(v1, v2) + | Inst::Mod(v1, v2) + | Inst::And(v1, v2) + | Inst::Or(v1, v2) + | Inst::Xor(v1, v2) + | Inst::Shl(v1, v2) + | Inst::Shr(v1, v2) + | Inst::INeg(v1, v2) + | Inst::Inv(v1, v2) + | Inst::Not(v1, v2) + | Inst::CmpEq(v1, v2) + | Inst::CmpLt(v1, v2) + | Inst::Int(v1, v2) + | Inst::Mov(v1, v2) => 3 + v1.len() + v2.len(), Inst::Jmp(v) - | Inst::Jz(v) - | Inst::Jnz(v) - | Inst::Call(v) - | Inst::Push(v) - | Inst::Pop(v) => { 3 + v.len() } - Inst::Ret - | Inst::IRet - | Inst::Halt - | Inst::Nop - | Inst::Dump => { 2 } + | Inst::Jz(v) + | Inst::Jnz(v) + | Inst::Call(v) + | Inst::Push(v) + | Inst::Pop(v) => 3 + v.len(), + Inst::Ret | Inst::IRet | Inst::Halt | Inst::Nop | Inst::Dump => 2, } } } diff --git a/src/libvm/src/state.rs b/src/libvm/src/state.rs index 24161bf..f2cfb6c 100644 --- a/src/libvm/src/state.rs +++ b/src/libvm/src/state.rs @@ -146,21 +146,25 @@ impl State { pub fn ivt(&self) -> Result<&[Interrupt]> { let ivt_addr = self.get_reg_unchecked(IVT); if ivt_addr % 64 != 0 { - panic!("illegal IVT address {:#x}; must be divisible by 64", ivt_addr); + panic!( + "illegal IVT address {:#x}; must be divisible by 64", + ivt_addr + ); } let start = ivt_addr as usize; let end = start + (IVT_LENGTH * mem::size_of::()); if end > self.mem.len() { - return Err(VmError::MemOutOfBounds { addr: Addr(ivt_addr) }); + return Err(VmError::MemOutOfBounds { + addr: Addr(ivt_addr), + }); } // This is safe because we check the bounds above let slice_ptr = (&self.mem[start..]).as_ptr(); - let slice = unsafe { - std::slice::from_raw_parts(slice_ptr as *const Interrupt, IVT_LENGTH) - }; + let slice = + unsafe { std::slice::from_raw_parts(slice_ptr as *const Interrupt, IVT_LENGTH) }; Ok(slice) } @@ -383,10 +387,12 @@ impl State { fn push(&mut self, source: Source) -> Result<()> { let value = self.load_source(source)?; let mut stack_addr = self.sp(); - + // create a destination based on the size of the source let dest = match source { - Source::Addr64(_) | Source::RegAddr64(_) | Source::Reg(_) | Source::Imm(_) => Dest::Addr64(Addr(stack_addr)), + Source::Addr64(_) | Source::RegAddr64(_) | Source::Reg(_) | Source::Imm(_) => { + Dest::Addr64(Addr(stack_addr)) + } Source::Addr32(_) | Source::RegAddr32(_) => Dest::Addr32(Addr(stack_addr)), Source::Addr16(_) | Source::RegAddr16(_) => Dest::Addr16(Addr(stack_addr)), Source::Addr8(_) | Source::RegAddr8(_) => Dest::Addr8(Addr(stack_addr)), diff --git a/src/main.rs b/src/main.rs index c628bd8..ae213dc 100644 --- a/src/main.rs +++ b/src/main.rs @@ -2,21 +2,26 @@ mod common; extern crate libvm as vm; -use structopt::StructOpt; use snafu::Snafu; -use std::{fs, io::{stdout, Write}, path::{Path, PathBuf}, process}; +use std::{ + fs, + io::{stdout, Write}, + path::{Path, PathBuf}, + process, +}; +use structopt::StructOpt; const DEFAULT_MAX_MEM: usize = 64 * 1024 * 1024; #[derive(Snafu, Debug, Clone, PartialEq)] enum ArgParseError<'a> { #[snafu(display("invalid specified size: {} (sizes may end in G, M, or K)", text))] - InvalidSize { text: &'a str } + InvalidSize { text: &'a str }, } fn from_bytes_size<'a>(mut text: &'a str) -> std::result::Result> { if text.is_empty() { - return Err(ArgParseError::InvalidSize { text }) + return Err(ArgParseError::InvalidSize { text }); } let multiplier = match text.chars().last().unwrap() { 'k' | 'K' => 1024, @@ -26,9 +31,11 @@ fn from_bytes_size<'a>(mut text: &'a str) -> std::result::Result().map_err(|_| ArgParseError::InvalidSize { text })?; + let value = text + .parse::() + .map_err(|_| ArgParseError::InvalidSize { text })?; Ok(value * multiplier) } @@ -56,7 +63,6 @@ fn test_bytes_size() { struct Options { // maybe some other options: // * debug - /// The input file to work with. /// /// By default, the file will be executed. If -c is passed, it will not run and only compile. @@ -82,7 +88,6 @@ struct Options { /// Only compile the input file to an object. #[structopt(short = "c", long)] compile_only: bool, - } type Result = std::result::Result>; @@ -107,8 +112,8 @@ fn get_writer(path: impl AsRef) -> Result> { fn main() -> Result<()> { use vm::{ - state::State, obj::{assemble, disassemble::Disasm}, + state::State, }; let opt = Options::from_args(); @@ -125,7 +130,9 @@ fn main() -> Result<()> { writer.write(&bytes)?; Ok(()) } else if opt.disassemble { - let outfile = opt.out.as_ref() + let outfile = opt + .out + .as_ref() .map(|p| p.as_path()) .unwrap_or_else(|| Path::new("-")); let mut writer = get_writer(&outfile)?; @@ -138,4 +145,3 @@ fn main() -> Result<()> { process::exit((status & 0xffff_ffff) as i32); } } -