Add next_instruction helper and bump version
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "rustijvm"
|
||||
version = "0.1.0"
|
||||
version = "1.0.0"
|
||||
authors = ["Jur van den Berg <Jurl.berg@gmail.com>"]
|
||||
|
||||
[dependencies]
|
||||
|
||||
@@ -15,16 +15,14 @@ fn main() {
|
||||
let ijvmfile = &args[1];
|
||||
|
||||
let mut machine = Machine::new_from_file(ijvmfile).unwrap();
|
||||
while machine.has_step() {
|
||||
match machine.step() {
|
||||
Ok(_) => (),
|
||||
Err(str) => {
|
||||
println!("\n\nERROR: pc=0x{:x} fp=0x{:x}: {}\nProgram exit",
|
||||
machine.get_program_counter(),
|
||||
machine.frame.len() - 1,
|
||||
str);
|
||||
return;
|
||||
}
|
||||
match machine.run() {
|
||||
Ok(_) => (),
|
||||
Err(str) => {
|
||||
println!("\n\nERROR: pc=0x{:x} fp=0x{:x}: {}\nProgram exit",
|
||||
machine.get_program_counter(),
|
||||
machine.frame.len() - 1,
|
||||
str);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3,7 +3,7 @@ use std::sync::{Mutex, Arc};
|
||||
|
||||
use Result;
|
||||
use block::Block;
|
||||
use ops::Operation;
|
||||
use ops::{Operation, Args, num_to_op};
|
||||
use ijvmreader::IJVMReader;
|
||||
use binread::{BinRead, BinReadable};
|
||||
use frame::Frame;
|
||||
@@ -135,6 +135,45 @@ impl Machine {
|
||||
self.block[self.get_program_counter()]
|
||||
}
|
||||
|
||||
pub fn next_instruction(&mut self) -> Result<(String, Vec<i32>)> {
|
||||
let checkpoint = self.block.cur();
|
||||
|
||||
let mut opcode = self.block.read_u8()?;
|
||||
let mut params = Vec::new();
|
||||
let mut wide = false;
|
||||
|
||||
// WIDE
|
||||
if opcode == 0xC4 {
|
||||
wide = true;
|
||||
opcode = self.block.read_u8()?;
|
||||
}
|
||||
|
||||
let (name, args) = match num_to_op(opcode) {
|
||||
Operation::Invalid(_) => return Err("Invalid operation"),
|
||||
Operation::Op(name, _, args) => (name, args),
|
||||
};
|
||||
|
||||
for arg in &args {
|
||||
let v = match arg {
|
||||
Args::Byte => self.block.read_i8()? as i32,
|
||||
Args::Short => self.block.read_i16()? as i32,
|
||||
Args::Var => {
|
||||
if wide {
|
||||
self.block.read_u16()? as i32
|
||||
} else {
|
||||
self.block.read_u8()? as i32
|
||||
}
|
||||
},
|
||||
Args::Label => self.block.read_i16()? as i32,
|
||||
Args::Constant => self.block.read_u16()? as i32,
|
||||
};
|
||||
params.push(v);
|
||||
}
|
||||
|
||||
self.block.seek(checkpoint).unwrap();
|
||||
Ok((name.to_string(), params))
|
||||
}
|
||||
|
||||
// pub fn get_stack_pointer(&self) -> usize {
|
||||
// return self.frame.last().unwrap().stack.len();
|
||||
// }
|
||||
|
||||
Reference in New Issue
Block a user