Restructure to library / binary combo
This commit is contained in:
102
src/machine.rs
Normal file
102
src/machine.rs
Normal file
@@ -0,0 +1,102 @@
|
||||
use block::Block;
|
||||
|
||||
use ops::Operation;
|
||||
use ijvmreader::IJVMReader;
|
||||
use binread::{BinRead, BinReadable};
|
||||
use frame::Frame;
|
||||
use stack::Stack;
|
||||
use pool::Pool;
|
||||
use netstack::NetStack;
|
||||
use Result;
|
||||
|
||||
const MAGIC_HEADER:u32 = 0x1DEA_DFAD;
|
||||
const ANTI_BS_SIZE:usize = 0xFFFF;
|
||||
|
||||
pub struct Machine {
|
||||
pub wide: bool,
|
||||
pub pool: Pool,
|
||||
pub block: Block,
|
||||
pub frame: Vec<Frame>,
|
||||
pub net: NetStack
|
||||
}
|
||||
|
||||
impl Machine {
|
||||
pub fn new(pool: Pool, block: Block) -> Machine{
|
||||
Machine {
|
||||
wide: false,
|
||||
pool,
|
||||
block,
|
||||
frame: vec![Frame::new(ANTI_BS_SIZE)],
|
||||
net: NetStack::new(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn new_from_file(file: &str) -> Result<Machine> {
|
||||
let mut reader = IJVMReader::new(file).unwrap();
|
||||
let magic = reader.read_u32()?;
|
||||
if magic != MAGIC_HEADER {
|
||||
return Err("Invalid magic header");
|
||||
}
|
||||
let constants = match reader.read_block() {
|
||||
Ok(a) => a,
|
||||
Err(_) => return Err("Failed to read constants block")
|
||||
};
|
||||
let text = match reader.read_block() {
|
||||
Ok(block) => block,
|
||||
Err(_) => return Err("Failed to read text block")
|
||||
};
|
||||
|
||||
let pool = Pool::new(constants)?;
|
||||
|
||||
Ok(Machine::new(pool, text))
|
||||
}
|
||||
|
||||
pub fn step(&mut self) -> Result<()> {
|
||||
match self.block.read_op() {
|
||||
Ok(Operation::Op(a, func)) => {
|
||||
if cfg!(feature = "debug:instr") {
|
||||
println!("{}", a);
|
||||
println!("Stack: {:?}", self.cur_frame().stack.data);
|
||||
let x = func(self);
|
||||
println!("Stack: {:?}", self.cur_frame().stack.data);
|
||||
x
|
||||
} else {
|
||||
func(self)
|
||||
}
|
||||
},
|
||||
Ok(Operation::Invalid(a)) => {
|
||||
println!("UNDEFINED OP: 0x{:X}", a);
|
||||
Err("Invalid op")
|
||||
},
|
||||
Err(str) => Err(str)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn has_step(&self) -> bool {
|
||||
self.block.has_i8()
|
||||
}
|
||||
|
||||
pub fn get_program_counter(&self) -> usize {
|
||||
self.block.cur()
|
||||
}
|
||||
|
||||
pub fn cur_frame(&mut self) -> &mut Frame {
|
||||
self.frame.last_mut().unwrap()
|
||||
}
|
||||
|
||||
pub fn cur_stack(&mut self) -> &mut Stack {
|
||||
&mut self.cur_frame().stack
|
||||
}
|
||||
|
||||
// pub fn get_stack_pointer(&self) -> usize {
|
||||
// return self.frame.last().unwrap().stack.len();
|
||||
// }
|
||||
|
||||
pub fn read_index(&mut self) -> Result<usize> {
|
||||
if self.wide {
|
||||
self.wide = false;
|
||||
return Ok(self.block.read_u16()? as usize)
|
||||
}
|
||||
Ok(self.block.read_u8()? as usize)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user