Most tests yay
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
use block::Block;
|
||||
use std::io::{Read, Write};
|
||||
|
||||
use block::Block;
|
||||
use ops::Operation;
|
||||
use ijvmreader::IJVMReader;
|
||||
use binread::{BinRead, BinReadable};
|
||||
@@ -8,26 +9,36 @@ use stack::Stack;
|
||||
use pool::Pool;
|
||||
use netstack::NetStack;
|
||||
use Result;
|
||||
use std::sync::Mutex;
|
||||
use std::rc::Rc;
|
||||
|
||||
const MAGIC_HEADER:u32 = 0x1DEA_DFAD;
|
||||
const ANTI_BS_SIZE:usize = 0xFFFF;
|
||||
|
||||
pub struct Machine {
|
||||
pub wide: bool,
|
||||
pub halted: bool,
|
||||
pub pool: Pool,
|
||||
pub block: Block,
|
||||
pub frame: Vec<Frame>,
|
||||
pub net: NetStack
|
||||
pub net: NetStack,
|
||||
|
||||
pub stream_in: Box<Read>,
|
||||
pub stream_out: Rc<Mutex<Write>>,
|
||||
|
||||
}
|
||||
|
||||
impl Machine {
|
||||
pub fn new(pool: Pool, block: Block) -> Machine{
|
||||
Machine {
|
||||
wide: false,
|
||||
halted: false,
|
||||
pool,
|
||||
block,
|
||||
frame: vec![Frame::new(ANTI_BS_SIZE)],
|
||||
net: NetStack::new(),
|
||||
stream_in: Box::new(::std::io::stdin()),
|
||||
stream_out: Rc::new(Mutex::new(::std::io::stdout())),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -72,14 +83,25 @@ impl Machine {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn run(&mut self) -> Result<()> {
|
||||
while self.has_step() {
|
||||
self.step()?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn has_step(&self) -> bool {
|
||||
self.block.has_i8()
|
||||
!self.halted && self.block.has_i8()
|
||||
}
|
||||
|
||||
pub fn get_program_counter(&self) -> usize {
|
||||
self.block.cur()
|
||||
}
|
||||
|
||||
pub fn get_tos(&mut self) -> Result<i32> {
|
||||
self.cur_stack().top()
|
||||
}
|
||||
|
||||
pub fn cur_frame(&mut self) -> &mut Frame {
|
||||
self.frame.last_mut().unwrap()
|
||||
}
|
||||
@@ -88,6 +110,10 @@ impl Machine {
|
||||
&mut self.cur_frame().stack
|
||||
}
|
||||
|
||||
pub fn cur_instruction(&mut self) -> u8 {
|
||||
self.block[self.get_program_counter()]
|
||||
}
|
||||
|
||||
// pub fn get_stack_pointer(&self) -> usize {
|
||||
// return self.frame.last().unwrap().stack.len();
|
||||
// }
|
||||
@@ -99,4 +125,12 @@ impl Machine {
|
||||
}
|
||||
Ok(self.block.read_u8()? as usize)
|
||||
}
|
||||
|
||||
pub fn set_input(&mut self, instream: Box<Read>) {
|
||||
self.stream_in = instream;
|
||||
}
|
||||
|
||||
pub fn set_output(&mut self, outstream: Rc<Mutex<Write>>) {
|
||||
self.stream_out = outstream;
|
||||
}
|
||||
}
|
||||
33
src/ops.rs
33
src/ops.rs
@@ -2,8 +2,7 @@ use binread::BinRead;
|
||||
use machine::Machine;
|
||||
use frame::Frame;
|
||||
use Result;
|
||||
use std::io::Write;
|
||||
use std::io::Read;
|
||||
use std::io::{Read};
|
||||
|
||||
pub type OpFunc = fn(&mut Machine) -> Result<()>;
|
||||
|
||||
@@ -79,8 +78,10 @@ fn dup(machine: &mut Machine) -> Result<()> {
|
||||
|
||||
fn out(machine: &mut Machine) -> Result<()> {
|
||||
let val = machine.cur_stack().pop()?;
|
||||
print!("{}", val as u8 as char);
|
||||
::std::io::stdout().flush().unwrap();
|
||||
let buffer = [val as u8];
|
||||
let mut out = machine.stream_out.lock().unwrap();
|
||||
out.write_all(&buffer).unwrap();
|
||||
out.flush().unwrap();
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -104,14 +105,10 @@ fn isub(machine: &mut Machine) -> Result<()> {
|
||||
}
|
||||
|
||||
fn _in(machine: &mut Machine) -> Result<()> {
|
||||
let char: Option<u8> =
|
||||
::std::io::stdin()
|
||||
.bytes()
|
||||
.next()
|
||||
.and_then(|r| r.ok());
|
||||
let val = match char {
|
||||
None => 0i32,
|
||||
Some(i) => i32::from(i)
|
||||
let mut buffer = [0; 1];
|
||||
let val = match machine.stream_in.read_exact(&mut buffer) {
|
||||
Err(_) => 0i32,
|
||||
Ok(_) => i32::from(buffer[0]),
|
||||
};
|
||||
machine.cur_stack().push(val);
|
||||
Ok(())
|
||||
@@ -122,8 +119,9 @@ fn goto(machine: &mut Machine) -> Result<()> {
|
||||
machine.block.jump(offset)
|
||||
}
|
||||
|
||||
fn halt(_: &mut Machine) -> Result<()> {
|
||||
Err("Halt")
|
||||
fn halt(machine: &mut Machine) -> Result<()> {
|
||||
machine.halted = true;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn ifeq(machine: &mut Machine) -> Result<()> {
|
||||
@@ -181,7 +179,7 @@ fn swap(machine: &mut Machine) -> Result<()> {
|
||||
|
||||
fn wide(machine: &mut Machine) -> Result<()> {
|
||||
machine.wide = true;
|
||||
Ok(())
|
||||
machine.step()
|
||||
}
|
||||
|
||||
fn iload(machine: &mut Machine) -> Result<()> {
|
||||
@@ -208,7 +206,7 @@ fn invokevirtual(machine: &mut Machine) -> Result<()> {
|
||||
let method_index = machine.block.read_u16()?;
|
||||
let invoke_addr = machine.pool.get(method_index as usize)?;
|
||||
let return_addr = machine.get_program_counter();
|
||||
// println!("METHOD {}", method_index);
|
||||
|
||||
machine.block.seek(invoke_addr as usize)?;
|
||||
let arg_count = machine.block.read_u16()?;
|
||||
let var_count = machine.block.read_u16()?;
|
||||
@@ -224,7 +222,6 @@ fn invokevirtual(machine: &mut Machine) -> Result<()> {
|
||||
cur_stack.pop()?; // Nuke the OBJREF
|
||||
}
|
||||
|
||||
// println!("retaddr set {}" ,return_addr);
|
||||
newframe.set(0, return_addr as i32)?;
|
||||
|
||||
machine.frame.push(newframe);
|
||||
@@ -237,10 +234,8 @@ fn ireturn(machine: &mut Machine) -> Result<()> {
|
||||
Some(a) => a,
|
||||
None => return Err("Got no frame... somehow...")
|
||||
};
|
||||
// println!("stack: {:?}", prev_frame.stack);
|
||||
let result = prev_frame.stack.pop()?;
|
||||
let return_addr = prev_frame.get(0)?;
|
||||
// println!("result: {}\nretaddr: {}", result, return_addr);
|
||||
machine.cur_stack().push(result);
|
||||
machine.block.seek(return_addr as usize)
|
||||
}
|
||||
|
||||
10
src/stack.rs
10
src/stack.rs
@@ -12,9 +12,13 @@ impl Stack {
|
||||
}
|
||||
}
|
||||
|
||||
// pub fn len(&self) -> usize {
|
||||
// return self.data.len();
|
||||
// }
|
||||
pub fn len(&self) -> usize {
|
||||
self.data.len()
|
||||
}
|
||||
|
||||
pub fn get(&self, i: usize) -> i32 {
|
||||
self.data[i]
|
||||
}
|
||||
|
||||
pub fn top(&self) -> Result<i32> {
|
||||
Ok(match self.data.last() {
|
||||
|
||||
Reference in New Issue
Block a user