Add execution to VM via file, starting to iron out bugs
Signed-off-by: Alek Ratzloff <alekratz@gmail.com>
This commit is contained in:
63
src/vm/vm.rs
63
src/vm/vm.rs
@@ -1,4 +1,4 @@
|
||||
use crate::vm::{error::*, flags::*, mem::*, reg::*};
|
||||
use crate::vm::{error::*, flags::*, mem::*, obj::obj::*, reg::*};
|
||||
use byteorder::{WriteBytesExt, LE};
|
||||
use std::{io::Cursor, mem};
|
||||
|
||||
@@ -13,12 +13,67 @@ pub struct Vm {
|
||||
}
|
||||
|
||||
impl Vm {
|
||||
pub fn new(mem: Vec<u8>, registers: Registers) -> Self {
|
||||
Vm { mem, registers }
|
||||
pub fn new() -> Self {
|
||||
Vm {
|
||||
mem: Default::default(),
|
||||
registers: [0; 64],
|
||||
}
|
||||
}
|
||||
|
||||
/// Loads an object into this VM, clearing out all previous memory and resetting the registers.
|
||||
pub fn load_object(&mut self, object: Object, max_mem: usize) -> Result<()> {
|
||||
self.registers = [0; 64];
|
||||
// determine memory spread
|
||||
let mem_size = object
|
||||
.sections
|
||||
.iter()
|
||||
.filter_map(|s| match s {
|
||||
Section::Data { end, .. } | Section::Code { end, .. } => Some(*end),
|
||||
Section::Meta { .. } => None,
|
||||
})
|
||||
.max()
|
||||
.unwrap_or(0);
|
||||
if mem_size > (max_mem as u64) {
|
||||
todo!("raise max memory error");
|
||||
}
|
||||
self.mem = vec![0; mem_size as usize];
|
||||
|
||||
let mut entry = 0;
|
||||
// write sections to memory
|
||||
for section in object.sections.into_iter() {
|
||||
match section {
|
||||
Section::Data {
|
||||
start,
|
||||
contents,
|
||||
..
|
||||
}
|
||||
| Section::Code {
|
||||
start,
|
||||
contents,
|
||||
..
|
||||
} => {
|
||||
let start = start as usize;
|
||||
for (value, dest) in contents.into_iter().zip(&mut self.mem[start..])
|
||||
{
|
||||
*dest = value;
|
||||
}
|
||||
}
|
||||
Section::Meta { entries } => {
|
||||
if let Some(e) = entries.get("entry") {
|
||||
// set the entry point
|
||||
entry = *e;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
self.set_reg(IP, entry);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn mem_cursor(&self, at: usize) -> MemCursor {
|
||||
MemCursor::new(&self.mem[at..])
|
||||
let mut cursor = MemCursor::new(&self.mem);
|
||||
cursor.set_position(at as u64);
|
||||
cursor
|
||||
}
|
||||
|
||||
pub fn run(&mut self) -> Result<u64> {
|
||||
|
||||
Reference in New Issue
Block a user