Compare commits
4 Commits
d7f3ded7e0
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
| 682c732955 | |||
| 3c15045e60 | |||
| 8bd11678ab | |||
| 241a8f66bc |
58
Cargo.lock
generated
58
Cargo.lock
generated
@@ -1,70 +1,70 @@
|
|||||||
# This file is automatically @generated by Cargo.
|
# This file is automatically @generated by Cargo.
|
||||||
# It is not intended for manual editing.
|
# It is not intended for manual editing.
|
||||||
|
version = 3
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "lazy_static"
|
name = "lazy_static"
|
||||||
version = "1.3.0"
|
version = "1.4.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "proc-macro2"
|
name = "proc-macro2"
|
||||||
version = "0.4.4"
|
version = "1.0.39"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "c54b25569025b7fc9651de43004ae593a75ad88543b17178aa5e1b9c4f15f56f"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"unicode-ident",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "quote"
|
name = "quote"
|
||||||
version = "0.6.3"
|
version = "1.0.18"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a1feb54ed693b93a84e14094943b84b7c4eae204c512b7ccb95ab0c66d278ad1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
"proc-macro2",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rustijvm"
|
name = "rustijvm"
|
||||||
version = "1.0.0"
|
version = "1.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"lazy_static",
|
||||||
"serde 1.0.65 (registry+https://github.com/rust-lang/crates.io-index)",
|
"serde",
|
||||||
"serde_derive 1.0.65 (registry+https://github.com/rust-lang/crates.io-index)",
|
"serde_derive",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "serde"
|
name = "serde"
|
||||||
version = "1.0.65"
|
version = "1.0.137"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "61ea8d54c77f8315140a05f4c7237403bf38b72704d031543aa1d16abbf517d1"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "serde_derive"
|
name = "serde_derive"
|
||||||
version = "1.0.65"
|
version = "1.0.137"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1f26faba0c3959972377d3b2d306ee9f71faee9714294e41bb777f83f88578be"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
"proc-macro2",
|
||||||
"quote 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
"quote",
|
||||||
"syn 0.14.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"syn",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "syn"
|
name = "syn"
|
||||||
version = "0.14.1"
|
version = "1.0.96"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "0748dd251e24453cb8717f0354206b91557e4ec8703673a4b30208f2abaf1ebf"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
"proc-macro2",
|
||||||
"quote 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
"quote",
|
||||||
"unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"unicode-ident",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "unicode-xid"
|
name = "unicode-ident"
|
||||||
version = "0.1.0"
|
version = "1.0.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d22af068fba1eb5edcb4aea19d382b2a3deb4c8f9d475c589b6ada9e0fd493ee"
|
||||||
[metadata]
|
|
||||||
"checksum lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bc5729f27f159ddd61f4df6228e827e86643d4d3e7c32183cb30a1c08f604a14"
|
|
||||||
"checksum proc-macro2 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "1fa93823f53cfd0f5ac117b189aed6cfdfb2cfc0a9d82e956dd7927595ed7d46"
|
|
||||||
"checksum quote 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)" = "e44651a0dc4cdd99f71c83b561e221f714912d11af1a4dff0631f923d53af035"
|
|
||||||
"checksum serde 1.0.65 (registry+https://github.com/rust-lang/crates.io-index)" = "5d47469df098fe8701d4da22680da5145e83801bdaaafea0cf91a180436fc343"
|
|
||||||
"checksum serde_derive 1.0.65 (registry+https://github.com/rust-lang/crates.io-index)" = "35eff0f5f70b6a2e902a2bbf4b079be4aacb14afc9676ba4798e0486401cedcb"
|
|
||||||
"checksum syn 0.14.1 (registry+https://github.com/rust-lang/crates.io-index)" = "6dfd71b2be5a58ee30a6f8ea355ba8290d397131c00dfa55c3d34e6e13db5101"
|
|
||||||
"checksum unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc"
|
|
||||||
|
|||||||
25
Cargo.toml
25
Cargo.toml
@@ -1,25 +1,26 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "rustijvm"
|
name = "rustijvm"
|
||||||
version = "1.0.0"
|
version = "1.1.0"
|
||||||
|
edition = "2021"
|
||||||
authors = ["Jur van den Berg <Jurl.berg@gmail.com>"]
|
authors = ["Jur van den Berg <Jurl.berg@gmail.com>"]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
serde = "1.0"
|
serde = "1.0"
|
||||||
serde_derive = "1.0"
|
serde_derive = "1.0"
|
||||||
lazy_static = "1.3.0"
|
lazy_static = "1.4.0"
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
default = ["bonus", "extra"]
|
default = ["bonus", "extra"]
|
||||||
|
|
||||||
bonus = ["bonus:network", "bonus:heap"]
|
bonus = ["bonus.network", "bonus.heap"]
|
||||||
"bonus:network" = []
|
"bonus.network" = []
|
||||||
"bonus:heap" = []
|
"bonus.heap" = []
|
||||||
|
|
||||||
extra = ["extra:sleep", "extra:arithmetic"]
|
extra = ["extra.sleep", "extra.arithmetic"]
|
||||||
"extra:sleep" = []
|
"extra.sleep" = []
|
||||||
"extra:arithmetic" = []
|
"extra.arithmetic" = []
|
||||||
|
|
||||||
debug = ["debug:instr", "debug:frame", "debug:gc"]
|
debug = ["debug.instr", "debug.frame", "debug.gc"]
|
||||||
"debug:instr" = []
|
"debug.instr" = []
|
||||||
"debug:frame" = []
|
"debug.frame" = []
|
||||||
"debug:gc" = []
|
"debug.gc" = []
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ use test::Bencher;
|
|||||||
fn run_bfi(file: &str) {
|
fn run_bfi(file: &str) {
|
||||||
let file = File::open(file).expect("Missing bf file");
|
let file = File::open(file).expect("Missing bf file");
|
||||||
let rc = Arc::new(Mutex::new(Cursor::new(Vec::new())));
|
let rc = Arc::new(Mutex::new(Cursor::new(Vec::new())));
|
||||||
let mut machine = rustijvm::Machine::new_from_file("files/bonus/bfi.ijvm").unwrap();
|
let mut machine = rustijvm::machine::Machine::new_from_file("files/bonus/bfi.ijvm").unwrap();
|
||||||
machine.set_output(rc);
|
machine.set_output(rc);
|
||||||
machine.set_input(Box::new(file));
|
machine.set_input(Box::new(file));
|
||||||
machine.run().unwrap();
|
machine.run().unwrap();
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ use test::Bencher;
|
|||||||
|
|
||||||
fn run_calc(input: &'static str) {
|
fn run_calc(input: &'static str) {
|
||||||
let rc = Arc::new(Mutex::new(Cursor::new(Vec::new())));
|
let rc = Arc::new(Mutex::new(Cursor::new(Vec::new())));
|
||||||
let mut machine = rustijvm::Machine::new_from_file("files/advanced/SimpleCalc.ijvm").unwrap();
|
let mut machine = rustijvm::machine::Machine::new_from_file("files/advanced/SimpleCalc.ijvm").unwrap();
|
||||||
machine.set_output(rc);
|
machine.set_output(rc);
|
||||||
machine.set_input(Box::new(input.as_bytes()));
|
machine.set_input(Box::new(input.as_bytes()));
|
||||||
machine.run().unwrap();
|
machine.run().unwrap();
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
extern crate rustijvm;
|
extern crate rustijvm;
|
||||||
|
|
||||||
use rustijvm::Disassembly;
|
use rustijvm::disassembler::Disassembly;
|
||||||
use std::env;
|
use std::env;
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
use block::Block;
|
use crate::block::Block;
|
||||||
use ops::{num_to_op, Operation};
|
use crate::ops::{num_to_op, Operation};
|
||||||
use Result;
|
use crate::Result;
|
||||||
|
|
||||||
pub trait BinReadable {
|
pub trait BinReadable {
|
||||||
fn get(&mut self) -> Result<u8>;
|
fn get(&mut self) -> Result<u8>;
|
||||||
|
|||||||
@@ -1,10 +1,12 @@
|
|||||||
use std::ops;
|
use std::ops;
|
||||||
|
|
||||||
use Result;
|
use crate::Result;
|
||||||
use binread::BinReadable;
|
use crate::binread::BinReadable;
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct Block {
|
pub struct Block {
|
||||||
|
// Origin is part of the spec, and while we never use it, I'd rather keep it
|
||||||
|
#[allow(dead_code)]
|
||||||
origin: u32,
|
origin: u32,
|
||||||
|
|
||||||
length: usize,
|
length: usize,
|
||||||
|
|||||||
@@ -1,12 +1,12 @@
|
|||||||
use binread::{BinRead, BinReadable};
|
use crate::binread::{BinRead, BinReadable};
|
||||||
use block::Block;
|
use crate::block::Block;
|
||||||
use ijvmreader::IJVMReader;
|
use crate::ijvmreader::IJVMReader;
|
||||||
use machine::MAGIC_HEADER;
|
use crate::machine::MAGIC_HEADER;
|
||||||
use ops;
|
use crate::ops;
|
||||||
use Result;
|
use crate::Result;
|
||||||
|
|
||||||
use std::clone::Clone;
|
use std::clone::Clone;
|
||||||
use std::collections::HashMap;
|
use std::collections::{HashMap, HashSet};
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
|
|
||||||
@@ -47,27 +47,18 @@ impl DebugSymbols {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn lookup_method(&self, location: usize) -> Option<String> {
|
fn lookup_method(&self, location: usize) -> Option<String> {
|
||||||
match self.methods.get(&location) {
|
self.methods.get(&location).map(|name| name.to_string())
|
||||||
Some(name) => Some(name.to_string()),
|
|
||||||
None => None,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn lookup_method_idx(&self, idx: usize) -> Option<String> {
|
fn lookup_method_idx(&self, idx: usize) -> Option<String> {
|
||||||
if idx >= self.constants.len() {
|
if idx >= self.constants.len() {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
match self.methods.get(&self.constants[idx]) {
|
self.methods.get(&self.constants[idx]).map(|name| name.to_string())
|
||||||
Some(name) => Some(name.to_string()),
|
|
||||||
None => None,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn lookup_label(&self, location: usize) -> Option<String> {
|
fn lookup_label(&self, location: usize) -> Option<String> {
|
||||||
match self.labels.get(&location) {
|
self.labels.get(&location).map(|name| name.to_string())
|
||||||
Some(name) => Some(name.to_string()),
|
|
||||||
None => None,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -176,10 +167,7 @@ impl Method {
|
|||||||
.instructions
|
.instructions
|
||||||
.iter()
|
.iter()
|
||||||
.filter(|e| !e.types.is_empty())
|
.filter(|e| !e.types.is_empty())
|
||||||
.filter(|e| match e.types[0] {
|
.filter(|e| matches!(e.types[0], ops::Args::Var))
|
||||||
ops::Args::Var => true,
|
|
||||||
_ => false,
|
|
||||||
})
|
|
||||||
.map(|e| e.params[0])
|
.map(|e| e.params[0])
|
||||||
.max();
|
.max();
|
||||||
|
|
||||||
@@ -244,7 +232,7 @@ pub struct Disassembler {
|
|||||||
text: Block,
|
text: Block,
|
||||||
pool: Block,
|
pool: Block,
|
||||||
symbols: Rc<DebugSymbols>,
|
symbols: Rc<DebugSymbols>,
|
||||||
suspects: Vec<usize>,
|
suspects: HashSet<usize>,
|
||||||
found: Vec<usize>,
|
found: Vec<usize>,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -255,7 +243,7 @@ impl Disassembler {
|
|||||||
text,
|
text,
|
||||||
pool,
|
pool,
|
||||||
symbols: Rc::new(symbols),
|
symbols: Rc::new(symbols),
|
||||||
suspects: Vec::new(),
|
suspects: HashSet::new(),
|
||||||
found: Vec::new(),
|
found: Vec::new(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -278,6 +266,31 @@ impl Disassembler {
|
|||||||
|
|
||||||
let (name, args) = match ops::num_to_op(opcode) {
|
let (name, args) = match ops::num_to_op(opcode) {
|
||||||
ops::Operation::Invalid => {
|
ops::Operation::Invalid => {
|
||||||
|
|
||||||
|
|
||||||
|
// There is a slight edge case here. It *could* be that the invalid op was a dead method.
|
||||||
|
// (i.e. method that is not called)
|
||||||
|
// I will not try to convince anyone this will catch all dead methods, but it's worth a shot
|
||||||
|
// So see if a constant with that *value* exists, if so add it to the suspects list and pray
|
||||||
|
if self.disassembly.constants.iter().any(|v| v.value == pos as i32) {
|
||||||
|
self.suspects.insert(pos);
|
||||||
|
// And rewind the tape to before we started parsing this to let it try again
|
||||||
|
return self.text.seek(pos);
|
||||||
|
}
|
||||||
|
// Fine another edge case then:
|
||||||
|
// usually the first method byte is 0x00 -> nop
|
||||||
|
// if this is the case, check if the nop is the method start
|
||||||
|
if let Some(previous_instruction) = method.instructions.last().cloned() {
|
||||||
|
if previous_instruction.op == 0x00 && self.disassembly.constants.iter().any(|v| v.value == previous_instruction.pos as i32) {
|
||||||
|
// Oh wow, this might work then
|
||||||
|
self.suspects.insert(previous_instruction.pos);
|
||||||
|
method.instructions.pop();
|
||||||
|
// And rewind the tape to before we started parsing this to let it try again
|
||||||
|
return self.text.seek(previous_instruction.pos);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
eprintln!("INVALID OP 0x{:X}\n", opcode);
|
eprintln!("INVALID OP 0x{:X}\n", opcode);
|
||||||
return Err("Invalid operation");
|
return Err("Invalid operation");
|
||||||
}
|
}
|
||||||
@@ -375,9 +388,7 @@ impl Disassembler {
|
|||||||
Ok(method)
|
Ok(method)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn find_methods(&mut self) -> Result<Vec<usize>> {
|
fn find_method_suspects(&mut self) -> Result<()> {
|
||||||
let mut res = Vec::new();
|
|
||||||
|
|
||||||
while self.text.has_i8() {
|
while self.text.has_i8() {
|
||||||
let op = self.text.read_u8()?;
|
let op = self.text.read_u8()?;
|
||||||
// INVOKEVIRTUAL
|
// INVOKEVIRTUAL
|
||||||
@@ -391,13 +402,13 @@ impl Disassembler {
|
|||||||
|
|
||||||
let v = self.text[constant.value as usize];
|
let v = self.text[constant.value as usize];
|
||||||
if v == 0 {
|
if v == 0 {
|
||||||
res.push(constant.value as usize);
|
self.suspects.insert(constant.value as usize);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
self.text.seek(0)?;
|
self.text.seek(0)?;
|
||||||
|
|
||||||
Ok(res)
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn disassemble(&mut self) -> Result<Disassembly> {
|
pub fn disassemble(&mut self) -> Result<Disassembly> {
|
||||||
@@ -406,7 +417,15 @@ impl Disassembler {
|
|||||||
self.disassembly.constants.push(Constant::new(addr));
|
self.disassembly.constants.push(Constant::new(addr));
|
||||||
}
|
}
|
||||||
|
|
||||||
self.suspects = self.find_methods()?;
|
self.find_method_suspects()?;
|
||||||
|
if !self.symbols.methods.is_empty() {
|
||||||
|
for &pos in self.symbols.methods.keys() {
|
||||||
|
if pos == 0 {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
self.suspects.insert(pos);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
let mut main = self.disasm_method(-1, 0, 0, 0)?;
|
let mut main = self.disasm_method(-1, 0, 0, 0)?;
|
||||||
main.update_vars();
|
main.update_vars();
|
||||||
@@ -442,6 +461,7 @@ impl Disassembly {
|
|||||||
let mut symbols = DebugSymbols::default();
|
let mut symbols = DebugSymbols::default();
|
||||||
if let Ok(block) = reader.read_block() {
|
if let Ok(block) = reader.read_block() {
|
||||||
symbols.add_methods(block)?;
|
symbols.add_methods(block)?;
|
||||||
|
|
||||||
if let Ok(labels) = reader.read_block() {
|
if let Ok(labels) = reader.read_block() {
|
||||||
symbols.add_labels(labels)?;
|
symbols.add_labels(labels)?;
|
||||||
}
|
}
|
||||||
@@ -470,7 +490,7 @@ impl Disassembly {
|
|||||||
|
|
||||||
impl fmt::Display for Disassembly {
|
impl fmt::Display for Disassembly {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
if !self.constants.is_empty() {
|
if self.constants.iter().any(|c| !c.method) {
|
||||||
writeln!(f, ".constant")?;
|
writeln!(f, ".constant")?;
|
||||||
for (i, c) in self.constants.iter().enumerate() {
|
for (i, c) in self.constants.iter().enumerate() {
|
||||||
if !c.method {
|
if !c.method {
|
||||||
|
|||||||
10
src/frame.rs
10
src/frame.rs
@@ -1,6 +1,6 @@
|
|||||||
use stack::Stack;
|
use crate::stack::Stack;
|
||||||
use Result;
|
use crate::Result;
|
||||||
use value::Value;
|
use crate::value::Value;
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct Frame {
|
pub struct Frame {
|
||||||
@@ -12,7 +12,7 @@ pub struct Frame {
|
|||||||
|
|
||||||
impl Frame {
|
impl Frame {
|
||||||
pub fn new(num_locals: usize, base: usize) -> Frame {
|
pub fn new(num_locals: usize, base: usize) -> Frame {
|
||||||
if cfg!(feature = "debug:frame") {
|
if cfg!(feature = "debug.frame") {
|
||||||
println!("Initializing frame of len {}", num_locals);
|
println!("Initializing frame of len {}", num_locals);
|
||||||
}
|
}
|
||||||
Frame {
|
Frame {
|
||||||
@@ -24,7 +24,7 @@ impl Frame {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn new_extendable(base: usize) -> Frame {
|
pub fn new_extendable(base: usize) -> Frame {
|
||||||
if cfg!(feature = "debug:frame") {
|
if cfg!(feature = "debug.frame") {
|
||||||
println!("Initializing extendable frame");
|
println!("Initializing extendable frame");
|
||||||
}
|
}
|
||||||
Frame {
|
Frame {
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
use value::Value;
|
use crate::value::Value;
|
||||||
use std::rc::{Rc, Weak};
|
use std::rc::{Rc, Weak};
|
||||||
use std::cell::RefCell;
|
use std::cell::RefCell;
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
use std::io::Read;
|
use std::io::Read;
|
||||||
use std::fs::File;
|
use std::fs::File;
|
||||||
use Result;
|
use crate::Result;
|
||||||
use binread::BinReadable;
|
use crate::binread::BinReadable;
|
||||||
|
|
||||||
pub struct IJVMReader {
|
pub struct IJVMReader {
|
||||||
pointer: usize,
|
pointer: usize,
|
||||||
|
|||||||
@@ -14,15 +14,12 @@ pub mod pool;
|
|||||||
pub mod frame;
|
pub mod frame;
|
||||||
pub mod stubs;
|
pub mod stubs;
|
||||||
|
|
||||||
#[cfg(feature = "bonus:network")]
|
#[cfg(feature = "bonus.network")]
|
||||||
pub mod netstack;
|
pub mod netstack;
|
||||||
#[cfg(feature = "bonus:heap")]
|
#[cfg(feature = "bonus.heap")]
|
||||||
pub mod heap;
|
pub mod heap;
|
||||||
|
|
||||||
type Result<T> = ::std::result::Result<T, &'static str>;
|
type Result<T> = ::std::result::Result<T, &'static str>;
|
||||||
|
|
||||||
pub mod machine;
|
pub mod machine;
|
||||||
pub use machine::Machine;
|
|
||||||
|
|
||||||
pub mod disassembler;
|
pub mod disassembler;
|
||||||
pub use disassembler::{Disassembler, Disassembly};
|
|
||||||
|
|||||||
@@ -1,19 +1,19 @@
|
|||||||
use std::io::{Read, Write};
|
use std::io::{Read, Write};
|
||||||
use std::sync::{Arc, Mutex};
|
use std::sync::{Arc, Mutex};
|
||||||
|
|
||||||
use binread::{BinRead, BinReadable};
|
use crate::binread::{BinRead, BinReadable};
|
||||||
use block::Block;
|
use crate::block::Block;
|
||||||
use frame::Frame;
|
use crate::frame::Frame;
|
||||||
use ijvmreader::IJVMReader;
|
use crate::ijvmreader::IJVMReader;
|
||||||
use ops::{num_to_op, Args, Operation};
|
use crate::ops::{num_to_op, Args, Operation};
|
||||||
use pool::Pool;
|
use crate::pool::Pool;
|
||||||
use stack::Stack;
|
use crate::stack::Stack;
|
||||||
use Result;
|
use crate::Result;
|
||||||
|
|
||||||
#[cfg(feature = "bonus:heap")]
|
#[cfg(feature = "bonus.heap")]
|
||||||
use heap::Heaps;
|
use crate::heap::Heaps;
|
||||||
#[cfg(feature = "bonus:network")]
|
#[cfg(feature = "bonus.network")]
|
||||||
use netstack::NetStack;
|
use crate::netstack::NetStack;
|
||||||
use std::convert::TryInto;
|
use std::convert::TryInto;
|
||||||
|
|
||||||
pub const MAGIC_HEADER: u32 = 0x1DEA_DFAD;
|
pub const MAGIC_HEADER: u32 = 0x1DEA_DFAD;
|
||||||
@@ -25,9 +25,9 @@ pub struct Machine {
|
|||||||
pub block: Block,
|
pub block: Block,
|
||||||
pub frame: Vec<Frame>,
|
pub frame: Vec<Frame>,
|
||||||
|
|
||||||
#[cfg(feature = "bonus:network")]
|
#[cfg(feature = "bonus.network")]
|
||||||
pub net: NetStack,
|
pub net: Vec<NetStack>,
|
||||||
#[cfg(feature = "bonus:heap")]
|
#[cfg(feature = "bonus.heap")]
|
||||||
pub heap: Heaps,
|
pub heap: Heaps,
|
||||||
|
|
||||||
pub stream_in: Box<dyn Read + Send + Sync>,
|
pub stream_in: Box<dyn Read + Send + Sync>,
|
||||||
@@ -45,10 +45,10 @@ impl Machine {
|
|||||||
stream_in: Box::new(::std::io::stdin()),
|
stream_in: Box::new(::std::io::stdin()),
|
||||||
stream_out: Arc::new(Mutex::new(::std::io::stdout())),
|
stream_out: Arc::new(Mutex::new(::std::io::stdout())),
|
||||||
|
|
||||||
#[cfg(feature = "bonus:network")]
|
#[cfg(feature = "bonus.network")]
|
||||||
net: NetStack::new(),
|
net: Vec::new(),
|
||||||
|
|
||||||
#[cfg(feature = "bonus:heap")]
|
#[cfg(feature = "bonus.heap")]
|
||||||
heap: Heaps::new(),
|
heap: Heaps::new(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -85,7 +85,7 @@ impl Machine {
|
|||||||
pub fn step(&mut self) -> Result<()> {
|
pub fn step(&mut self) -> Result<()> {
|
||||||
match self.block.read_op() {
|
match self.block.read_op() {
|
||||||
Ok(Operation::Op(a, func, _)) => {
|
Ok(Operation::Op(a, func, _)) => {
|
||||||
if cfg!(feature = "debug:instr") {
|
if cfg!(feature = "debug.instr") {
|
||||||
println!("{}", a);
|
println!("{}", a);
|
||||||
println!("Stack: {:?}", self.cur_frame().stack.data);
|
println!("Stack: {:?}", self.cur_frame().stack.data);
|
||||||
let x = func(self);
|
let x = func(self);
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
use std::net::TcpStream;
|
use std::net::TcpStream;
|
||||||
|
|
||||||
use Result;
|
use crate::Result;
|
||||||
use std::io::{Read, Write};
|
use std::io::{Read, Write};
|
||||||
use std::net::TcpListener;
|
use std::net::TcpListener;
|
||||||
|
|
||||||
@@ -66,7 +66,7 @@ impl NetStack {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "bonus:network")]
|
#[cfg(feature = "bonus.network")]
|
||||||
pub fn write_byte(&mut self, byte: u8) -> Result<()> {
|
pub fn write_byte(&mut self, byte: u8) -> Result<()> {
|
||||||
match self.stream {
|
match self.stream {
|
||||||
Some(ref mut stream) => {
|
Some(ref mut stream) => {
|
||||||
|
|||||||
123
src/ops.rs
123
src/ops.rs
@@ -1,11 +1,12 @@
|
|||||||
use binread::BinRead;
|
use crate::binread::BinRead;
|
||||||
use frame::Frame;
|
use crate::frame::Frame;
|
||||||
use machine::Machine;
|
use crate::machine::Machine;
|
||||||
use std::io::Read;
|
use std::io::Read;
|
||||||
use std::num::Wrapping;
|
use std::num::Wrapping;
|
||||||
use Result;
|
use crate::Result;
|
||||||
use value::Value;
|
use crate::value::Value;
|
||||||
use std::convert::TryInto;
|
use std::convert::TryInto;
|
||||||
|
use crate::netstack::NetStack;
|
||||||
|
|
||||||
pub type OpFunc = fn(&mut Machine) -> Result<()>;
|
pub type OpFunc = fn(&mut Machine) -> Result<()>;
|
||||||
|
|
||||||
@@ -45,7 +46,7 @@ lazy_static! {
|
|||||||
m[0x60] = Operation::Op("IADD", iadd, vec![]);
|
m[0x60] = Operation::Op("IADD", iadd, vec![]);
|
||||||
m[0x64] = Operation::Op("ISUB", isub, vec![]);
|
m[0x64] = Operation::Op("ISUB", isub, vec![]);
|
||||||
|
|
||||||
#[cfg(feature = "extra:arithmetic")]
|
#[cfg(feature = "extra.arithmetic")]
|
||||||
{
|
{
|
||||||
m[0x70] = Operation::Op("SHL", shl, vec![]);
|
m[0x70] = Operation::Op("SHL", shl, vec![]);
|
||||||
m[0x71] = Operation::Op("SHR", shr, vec![]);
|
m[0x71] = Operation::Op("SHR", shr, vec![]);
|
||||||
@@ -68,7 +69,7 @@ lazy_static! {
|
|||||||
|
|
||||||
m[0xC4] = Operation::Op("WIDE", wide, vec![]);
|
m[0xC4] = Operation::Op("WIDE", wide, vec![]);
|
||||||
|
|
||||||
#[cfg(feature = "bonus:heap")]
|
#[cfg(feature = "bonus.heap")]
|
||||||
{
|
{
|
||||||
m[0xD1] = Operation::Op("NEWARRAY", newarray, vec![]);
|
m[0xD1] = Operation::Op("NEWARRAY", newarray, vec![]);
|
||||||
m[0xD2] = Operation::Op("IALOAD", iaload, vec![]);
|
m[0xD2] = Operation::Op("IALOAD", iaload, vec![]);
|
||||||
@@ -76,7 +77,7 @@ lazy_static! {
|
|||||||
m[0xD4] = Operation::Op("GC", gc, vec![]);
|
m[0xD4] = Operation::Op("GC", gc, vec![]);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "bonus:network")]
|
#[cfg(feature = "bonus.network")]
|
||||||
{
|
{
|
||||||
m[0xE1] = Operation::Op("NETBIND", netbind, vec![]);
|
m[0xE1] = Operation::Op("NETBIND", netbind, vec![]);
|
||||||
m[0xE2] = Operation::Op("NETCONNECT", netconnect, vec![]);
|
m[0xE2] = Operation::Op("NETCONNECT", netconnect, vec![]);
|
||||||
@@ -85,7 +86,7 @@ lazy_static! {
|
|||||||
m[0xE5] = Operation::Op("NETCLOSE", netclose, vec![]);
|
m[0xE5] = Operation::Op("NETCLOSE", netclose, vec![]);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "extra:sleep")]
|
#[cfg(feature = "extra.sleep")]
|
||||||
{
|
{
|
||||||
m[0xF0] = Operation::Op("SLP", slp, vec![Args::Byte]);
|
m[0xF0] = Operation::Op("SLP", slp, vec![Args::Byte]);
|
||||||
}
|
}
|
||||||
@@ -179,8 +180,15 @@ fn halt(machine: &mut Machine) -> Result<()> {
|
|||||||
|
|
||||||
fn ifeq(machine: &mut Machine) -> Result<()> {
|
fn ifeq(machine: &mut Machine) -> Result<()> {
|
||||||
let offset = i32::from(machine.block.read_i16()?) - JUMP_OFFSET;
|
let offset = i32::from(machine.block.read_i16()?) - JUMP_OFFSET;
|
||||||
let compare: i32 = machine.cur_stack().pop()?.try_into()?;
|
let tos = machine.cur_stack().pop()?;
|
||||||
if compare == 0 {
|
// IFEQ is special because it gets special support for NetRefs
|
||||||
|
let val = match tos {
|
||||||
|
Value::NetRef(v) => v as i32,
|
||||||
|
Value::Int(v) => v,
|
||||||
|
Value::HeapRef(_) => Err("cannot use heapref in IFEQ")?,
|
||||||
|
};
|
||||||
|
|
||||||
|
if val == 0 {
|
||||||
return machine.block.jump(offset);
|
return machine.block.jump(offset);
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
@@ -294,7 +302,7 @@ fn ireturn(machine: &mut Machine) -> Result<()> {
|
|||||||
machine.block.seek(return_addr as usize)
|
machine.block.seek(return_addr as usize)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "extra:sleep")]
|
#[cfg(feature = "extra.sleep")]
|
||||||
fn slp(machine: &mut Machine) -> Result<()> {
|
fn slp(machine: &mut Machine) -> Result<()> {
|
||||||
use std::thread;
|
use std::thread;
|
||||||
use std::time;
|
use std::time;
|
||||||
@@ -307,63 +315,78 @@ fn slp(machine: &mut Machine) -> Result<()> {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "bonus:network")]
|
#[cfg(feature = "bonus.network")]
|
||||||
fn netbind(machine: &mut Machine) -> Result<()> {
|
fn netbind(machine: &mut Machine) -> Result<()> {
|
||||||
let port: i32 = machine.cur_stack().pop()?.try_into()?;
|
let port: i32 = machine.cur_stack().pop()?.try_into()?;
|
||||||
|
|
||||||
let result = match machine.net.bind(port as u16) {
|
let mut stack = NetStack::new();
|
||||||
Ok(_) => 1,
|
if stack.bind(port as u16).is_err() {
|
||||||
Err(_) => 0,
|
machine.cur_stack().push(Value::Int(0));
|
||||||
};
|
return Ok(());
|
||||||
machine.cur_stack().push(Value::Int(result));
|
}
|
||||||
|
|
||||||
|
machine.net.push(stack);
|
||||||
|
let idx = machine.net.len();
|
||||||
|
machine.cur_stack().push(Value::NetRef(idx));
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "bonus:network")]
|
#[cfg(feature = "bonus.network")]
|
||||||
fn netconnect(machine: &mut Machine) -> Result<()> {
|
fn netconnect(machine: &mut Machine) -> Result<()> {
|
||||||
let port: i32 = machine.cur_stack().pop()?.try_into()?;
|
let port: i32 = machine.cur_stack().pop()?.try_into()?;
|
||||||
let host: i32 = machine.cur_stack().pop()?.try_into()?;
|
let host: i32 = machine.cur_stack().pop()?.try_into()?;
|
||||||
let result = match machine.net.connect(host as u32, port as u16) {
|
|
||||||
Ok(_) => 1,
|
let mut stack = NetStack::new();
|
||||||
Err(_) => 0,
|
if stack.connect(host as u32, port as u16).is_err() {
|
||||||
};
|
machine.cur_stack().push(Value::Int(0));
|
||||||
machine.cur_stack().push(Value::Int(result));
|
return Ok(());
|
||||||
|
}
|
||||||
|
machine.net.push(stack);
|
||||||
|
let idx = machine.net.len();
|
||||||
|
machine.cur_stack().push(Value::NetRef(idx));
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "bonus:network")]
|
#[cfg(feature = "bonus.network")]
|
||||||
fn netin(machine: &mut Machine) -> Result<()> {
|
fn netin(machine: &mut Machine) -> Result<()> {
|
||||||
let netref: i32 = machine.cur_stack().pop()?.try_into()?;
|
let idx = match machine.cur_stack().pop()? {
|
||||||
if netref != 1 {
|
Value::NetRef(x) => x,
|
||||||
return Err("Invalid netref to netin");
|
_ => Err("Invalid netref given to network instruction")?,
|
||||||
}
|
};
|
||||||
|
|
||||||
let byte = i32::from(machine.net.read_byte()?);
|
let conn = machine.net.get_mut(idx - 1).ok_or("Invalid network connection")?;
|
||||||
|
let byte = i32::from(conn.read_byte()?);
|
||||||
machine.cur_stack().push(Value::Int(byte));
|
machine.cur_stack().push(Value::Int(byte));
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "bonus:network")]
|
#[cfg(feature = "bonus.network")]
|
||||||
fn netout(machine: &mut Machine) -> Result<()> {
|
fn netout(machine: &mut Machine) -> Result<()> {
|
||||||
let netref: i32 = machine.cur_stack().pop()?.try_into()?;
|
let idx = match machine.cur_stack().pop()? {
|
||||||
if netref != 1 {
|
Value::NetRef(x) => x,
|
||||||
return Err("Invalid netref to netout");
|
_ => Err("Invalid netref given to network instruction")?,
|
||||||
}
|
};
|
||||||
|
|
||||||
let val: i32 = machine.cur_stack().pop()?.try_into()?;
|
let val: i32 = machine.cur_stack().pop()?.try_into()?;
|
||||||
machine.net.write_byte(val as u8)
|
let conn = machine.net.get_mut(idx - 1).ok_or("Invalid network connection")?;
|
||||||
|
conn.write_byte(val as u8)?;
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "bonus:network")]
|
#[cfg(feature = "bonus.network")]
|
||||||
fn netclose(machine: &mut Machine) -> Result<()> {
|
fn netclose(machine: &mut Machine) -> Result<()> {
|
||||||
let netref: i32 = machine.cur_stack().pop()?.try_into()?;
|
let idx = match machine.cur_stack().pop()? {
|
||||||
if netref != 1 {
|
Value::NetRef(x) => x,
|
||||||
return Err("Invalid netref to netclose");
|
_ => Err("Invalid netref given to network instruction")?,
|
||||||
}
|
};
|
||||||
machine.net.close()
|
|
||||||
|
machine.net.get_mut(idx - 1).ok_or("Invalid network connection")?.close()?;
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "bonus:heap")]
|
#[cfg(feature = "bonus.heap")]
|
||||||
fn newarray(machine: &mut Machine) -> Result<()> {
|
fn newarray(machine: &mut Machine) -> Result<()> {
|
||||||
let size: i32 = machine.cur_stack().pop()?.try_into()?;
|
let size: i32 = machine.cur_stack().pop()?.try_into()?;
|
||||||
let heap = machine.heap.alloc(size as usize);
|
let heap = machine.heap.alloc(size as usize);
|
||||||
@@ -371,7 +394,7 @@ fn newarray(machine: &mut Machine) -> Result<()> {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "bonus:heap")]
|
#[cfg(feature = "bonus.heap")]
|
||||||
fn iastore(machine: &mut Machine) -> Result<()> {
|
fn iastore(machine: &mut Machine) -> Result<()> {
|
||||||
use std::cell::RefCell;
|
use std::cell::RefCell;
|
||||||
|
|
||||||
@@ -387,7 +410,7 @@ fn iastore(machine: &mut Machine) -> Result<()> {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "bonus:heap")]
|
#[cfg(feature = "bonus.heap")]
|
||||||
fn iaload(machine: &mut Machine) -> Result<()> {
|
fn iaload(machine: &mut Machine) -> Result<()> {
|
||||||
let heap = match machine.cur_stack().pop()? {
|
let heap = match machine.cur_stack().pop()? {
|
||||||
Value::HeapRef(a) => a,
|
Value::HeapRef(a) => a,
|
||||||
@@ -404,13 +427,13 @@ fn iaload(machine: &mut Machine) -> Result<()> {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "bonus:heap")]
|
#[cfg(feature = "bonus.heap")]
|
||||||
fn gc(machine: &mut Machine) -> Result<()> {
|
fn gc(machine: &mut Machine) -> Result<()> {
|
||||||
machine.heap.gc();
|
machine.heap.gc();
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "extra:arithmetic")]
|
#[cfg(feature = "extra.arithmetic")]
|
||||||
fn shl(machine: &mut Machine) -> Result<()> {
|
fn shl(machine: &mut Machine) -> Result<()> {
|
||||||
let shift: i32 = machine.cur_stack().pop()?.try_into()?;
|
let shift: i32 = machine.cur_stack().pop()?.try_into()?;
|
||||||
let value: i32 = machine.cur_stack().pop()?.try_into()?;
|
let value: i32 = machine.cur_stack().pop()?.try_into()?;
|
||||||
@@ -419,7 +442,7 @@ fn shl(machine: &mut Machine) -> Result<()> {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "extra:arithmetic")]
|
#[cfg(feature = "extra.arithmetic")]
|
||||||
fn shr(machine: &mut Machine) -> Result<()> {
|
fn shr(machine: &mut Machine) -> Result<()> {
|
||||||
let shift: i32 = machine.cur_stack().pop()?.try_into()?;
|
let shift: i32 = machine.cur_stack().pop()?.try_into()?;
|
||||||
let value: i32 = machine.cur_stack().pop()?.try_into()?;
|
let value: i32 = machine.cur_stack().pop()?.try_into()?;
|
||||||
@@ -429,7 +452,7 @@ fn shr(machine: &mut Machine) -> Result<()> {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "extra:arithmetic")]
|
#[cfg(feature = "extra.arithmetic")]
|
||||||
fn imul(machine: &mut Machine) -> Result<()> {
|
fn imul(machine: &mut Machine) -> Result<()> {
|
||||||
let a: i32 = machine.cur_stack().pop()?.try_into()?;
|
let a: i32 = machine.cur_stack().pop()?.try_into()?;
|
||||||
let b: i32 = machine.cur_stack().pop()?.try_into()?;
|
let b: i32 = machine.cur_stack().pop()?.try_into()?;
|
||||||
@@ -438,7 +461,7 @@ fn imul(machine: &mut Machine) -> Result<()> {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "extra:arithmetic")]
|
#[cfg(feature = "extra.arithmetic")]
|
||||||
fn idiv(machine: &mut Machine) -> Result<()> {
|
fn idiv(machine: &mut Machine) -> Result<()> {
|
||||||
let divisor: i32 = machine.cur_stack().pop()?.try_into()?;
|
let divisor: i32 = machine.cur_stack().pop()?.try_into()?;
|
||||||
let value: i32 = machine.cur_stack().pop()?.try_into()?;
|
let value: i32 = machine.cur_stack().pop()?.try_into()?;
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
use Result;
|
use crate::Result;
|
||||||
use block::Block;
|
use crate::block::Block;
|
||||||
use binread::{BinRead, BinReadable};
|
use crate::binread::{BinRead, BinReadable};
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct Pool {
|
pub struct Pool {
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
use Result;
|
use crate::Result;
|
||||||
use value::Value;
|
use crate::value::Value;
|
||||||
|
|
||||||
|
|
||||||
#[derive(Debug, Default)]
|
#[derive(Debug, Default)]
|
||||||
|
|||||||
10
src/value.rs
10
src/value.rs
@@ -1,11 +1,13 @@
|
|||||||
use Result;
|
use crate::Result;
|
||||||
use std::convert::TryInto;
|
use std::convert::TryInto;
|
||||||
use heap::Heap;
|
use crate::heap::Heap;
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq)]
|
#[derive(Debug, Clone, PartialEq)]
|
||||||
pub enum Value {
|
pub enum Value {
|
||||||
Int(i32),
|
Int(i32),
|
||||||
HeapRef(Heap),
|
HeapRef(Heap),
|
||||||
|
#[cfg(feature = "bonus.network")]
|
||||||
|
NetRef(usize),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TryInto<i32> for Value {
|
impl TryInto<i32> for Value {
|
||||||
@@ -15,6 +17,8 @@ impl TryInto<i32> for Value {
|
|||||||
match self {
|
match self {
|
||||||
Value::Int(a) => Ok(a),
|
Value::Int(a) => Ok(a),
|
||||||
Value::HeapRef(_) => Err("Cannot use HeapRef as i32"),
|
Value::HeapRef(_) => Err("Cannot use HeapRef as i32"),
|
||||||
|
#[cfg(feature = "bonus.network")]
|
||||||
|
Value::NetRef(_) => Err("Cannot use NetRef as i32"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -26,6 +30,8 @@ impl TryInto<i32> for &Value {
|
|||||||
match *self {
|
match *self {
|
||||||
Value::Int(a) => Ok(a),
|
Value::Int(a) => Ok(a),
|
||||||
Value::HeapRef(_) => Err("Cannot use HeapRef as i32"),
|
Value::HeapRef(_) => Err("Cannot use HeapRef as i32"),
|
||||||
|
#[cfg(feature = "bonus.network")]
|
||||||
|
Value::NetRef(_) => Err("Cannot use NetRef as i32"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ extern crate rustijvm;
|
|||||||
|
|
||||||
use std::io::{Seek, SeekFrom, Read};
|
use std::io::{Seek, SeekFrom, Read};
|
||||||
|
|
||||||
fn steps(machine: &mut rustijvm::Machine, num: usize) {
|
fn steps(machine: &mut rustijvm::machine::Machine, num: usize) {
|
||||||
for _ in 0..num {
|
for _ in 0..num {
|
||||||
machine.step().unwrap();
|
machine.step().unwrap();
|
||||||
}
|
}
|
||||||
@@ -12,7 +12,7 @@ fn steps(machine: &mut rustijvm::Machine, num: usize) {
|
|||||||
fn advanced1() {
|
fn advanced1() {
|
||||||
let output = rustijvm::stubs::output_stub();
|
let output = rustijvm::stubs::output_stub();
|
||||||
let input = Box::new("A".as_bytes());
|
let input = Box::new("A".as_bytes());
|
||||||
let mut machine = rustijvm::Machine::new_from_file("files/task5/all_regular.ijvm").unwrap();
|
let mut machine = rustijvm::machine::Machine::new_from_file("files/task5/all_regular.ijvm").unwrap();
|
||||||
machine.set_input(input);
|
machine.set_input(input);
|
||||||
machine.set_output(output.clone());
|
machine.set_output(output.clone());
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
extern crate rustijvm;
|
extern crate rustijvm;
|
||||||
|
|
||||||
fn steps(machine: &mut rustijvm::Machine, num: usize) {
|
fn steps(machine: &mut rustijvm::machine::Machine, num: usize) {
|
||||||
for _ in 0..num {
|
for _ in 0..num {
|
||||||
machine.step().unwrap();
|
machine.step().unwrap();
|
||||||
}
|
}
|
||||||
@@ -8,7 +8,7 @@ fn steps(machine: &mut rustijvm::Machine, num: usize) {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn advanced2_nested_invoke_simple() {
|
fn advanced2_nested_invoke_simple() {
|
||||||
let mut machine = rustijvm::Machine::new_from_file("files/advanced/test-nestedinvoke-simple.ijvm").unwrap();
|
let mut machine = rustijvm::machine::Machine::new_from_file("files/advanced/test-nestedinvoke-simple.ijvm").unwrap();
|
||||||
machine.set_output(rustijvm::stubs::output_stub());
|
machine.set_output(rustijvm::stubs::output_stub());
|
||||||
|
|
||||||
steps(&mut machine, 1);
|
steps(&mut machine, 1);
|
||||||
@@ -35,7 +35,7 @@ fn advanced2_nested_invoke_simple() {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn advanced2_nested_invoke() {
|
fn advanced2_nested_invoke() {
|
||||||
let mut machine = rustijvm::Machine::new_from_file("files/advanced/test-nestedinvoke.ijvm").unwrap();
|
let mut machine = rustijvm::machine::Machine::new_from_file("files/advanced/test-nestedinvoke.ijvm").unwrap();
|
||||||
machine.set_output(rustijvm::stubs::output_stub());
|
machine.set_output(rustijvm::stubs::output_stub());
|
||||||
|
|
||||||
steps(&mut machine, 8);
|
steps(&mut machine, 8);
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
extern crate rustijvm;
|
extern crate rustijvm;
|
||||||
|
|
||||||
fn steps(machine: &mut rustijvm::Machine, num: usize) {
|
fn steps(machine: &mut rustijvm::machine::Machine, num: usize) {
|
||||||
for _ in 0..num {
|
for _ in 0..num {
|
||||||
machine.step().unwrap();
|
machine.step().unwrap();
|
||||||
}
|
}
|
||||||
@@ -10,7 +10,7 @@ fn steps(machine: &mut rustijvm::Machine, num: usize) {
|
|||||||
fn advanced3_wide1() {
|
fn advanced3_wide1() {
|
||||||
use rustijvm::value::Value::Int;
|
use rustijvm::value::Value::Int;
|
||||||
|
|
||||||
let mut machine = rustijvm::Machine::new_from_file("files/advanced/test-wide1.ijvm").unwrap();
|
let mut machine = rustijvm::machine::Machine::new_from_file("files/advanced/test-wide1.ijvm").unwrap();
|
||||||
machine.set_output(rustijvm::stubs::output_stub());
|
machine.set_output(rustijvm::stubs::output_stub());
|
||||||
|
|
||||||
steps(&mut machine, 6);
|
steps(&mut machine, 6);
|
||||||
@@ -27,7 +27,7 @@ fn advanced3_wide1() {
|
|||||||
#[test]
|
#[test]
|
||||||
fn advanced3_wide2() {
|
fn advanced3_wide2() {
|
||||||
use rustijvm::value::Value::Int;
|
use rustijvm::value::Value::Int;
|
||||||
let mut machine = rustijvm::Machine::new_from_file("files/advanced/test-wide2.ijvm").unwrap();
|
let mut machine = rustijvm::machine::Machine::new_from_file("files/advanced/test-wide2.ijvm").unwrap();
|
||||||
machine.set_output(rustijvm::stubs::output_stub());
|
machine.set_output(rustijvm::stubs::output_stub());
|
||||||
|
|
||||||
steps(&mut machine, 6);
|
steps(&mut machine, 6);
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ use std::io::{Seek, SeekFrom, Read};
|
|||||||
#[test]
|
#[test]
|
||||||
fn advanced4_tanenbaum() {
|
fn advanced4_tanenbaum() {
|
||||||
let rc = rustijvm::stubs::output_stub();
|
let rc = rustijvm::stubs::output_stub();
|
||||||
let mut machine = rustijvm::Machine::new_from_file("files/advanced/Tanenbaum.ijvm").unwrap();
|
let mut machine = rustijvm::machine::Machine::new_from_file("files/advanced/Tanenbaum.ijvm").unwrap();
|
||||||
|
|
||||||
machine.set_output(rc.clone());
|
machine.set_output(rc.clone());
|
||||||
machine.run().unwrap();
|
machine.run().unwrap();
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ use std::io::{Seek, SeekFrom, Read};
|
|||||||
|
|
||||||
fn run_calc(input: &'static str, expected: &str) {
|
fn run_calc(input: &'static str, expected: &str) {
|
||||||
let rc = rustijvm::stubs::output_stub();
|
let rc = rustijvm::stubs::output_stub();
|
||||||
let mut machine = rustijvm::Machine::new_from_file("files/advanced/SimpleCalc.ijvm").unwrap();
|
let mut machine = rustijvm::machine::Machine::new_from_file("files/advanced/SimpleCalc.ijvm").unwrap();
|
||||||
|
|
||||||
machine.set_input(Box::new(input.as_bytes()));
|
machine.set_input(Box::new(input.as_bytes()));
|
||||||
machine.set_output(rc.clone());
|
machine.set_output(rc.clone());
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ use std::io::{Seek, SeekFrom, Read};
|
|||||||
|
|
||||||
fn run_calc(input: &'static str, expected: &str) {
|
fn run_calc(input: &'static str, expected: &str) {
|
||||||
let rc = rustijvm::stubs::output_stub();
|
let rc = rustijvm::stubs::output_stub();
|
||||||
let mut machine = rustijvm::Machine::new_from_file("files/advanced/SimpleCalc.ijvm").unwrap();
|
let mut machine = rustijvm::machine::Machine::new_from_file("files/advanced/SimpleCalc.ijvm").unwrap();
|
||||||
|
|
||||||
machine.set_input(Box::new(input.as_bytes()));
|
machine.set_input(Box::new(input.as_bytes()));
|
||||||
machine.set_output(rc.clone());
|
machine.set_output(rc.clone());
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ use std::io::{SeekFrom, Seek, Read};
|
|||||||
#[ignore]
|
#[ignore]
|
||||||
fn advanced7() {
|
fn advanced7() {
|
||||||
let output = rustijvm::stubs::output_stub();
|
let output = rustijvm::stubs::output_stub();
|
||||||
let mut machine = rustijvm::Machine::new_from_file("files/advanced/mandelbread.ijvm").unwrap();
|
let mut machine = rustijvm::machine::Machine::new_from_file("files/advanced/mandelbread.ijvm").unwrap();
|
||||||
machine.set_output(output.clone());
|
machine.set_output(output.clone());
|
||||||
machine.run().unwrap();
|
machine.run().unwrap();
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ extern crate rustijvm;
|
|||||||
|
|
||||||
use std::convert::TryInto;
|
use std::convert::TryInto;
|
||||||
|
|
||||||
fn steps(machine: &mut rustijvm::Machine, num: usize) {
|
fn steps(machine: &mut rustijvm::machine::Machine, num: usize) {
|
||||||
for _ in 0..num {
|
for _ in 0..num {
|
||||||
machine.step().unwrap();
|
machine.step().unwrap();
|
||||||
}
|
}
|
||||||
@@ -10,7 +10,7 @@ fn steps(machine: &mut rustijvm::Machine, num: usize) {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn advancedstack_100() {
|
fn advancedstack_100() {
|
||||||
let mut machine = rustijvm::Machine::new_from_file("files/advanced/teststack.ijvm").unwrap();
|
let mut machine = rustijvm::machine::Machine::new_from_file("files/advanced/teststack.ijvm").unwrap();
|
||||||
machine.set_output(rustijvm::stubs::output_stub());
|
machine.set_output(rustijvm::stubs::output_stub());
|
||||||
|
|
||||||
steps(&mut machine, 1);
|
steps(&mut machine, 1);
|
||||||
@@ -20,7 +20,7 @@ fn advancedstack_100() {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn advancedstack_3000() {
|
fn advancedstack_3000() {
|
||||||
let mut machine = rustijvm::Machine::new_from_file("files/advanced/teststack.ijvm").unwrap();
|
let mut machine = rustijvm::machine::Machine::new_from_file("files/advanced/teststack.ijvm").unwrap();
|
||||||
machine.set_output(rustijvm::stubs::output_stub());
|
machine.set_output(rustijvm::stubs::output_stub());
|
||||||
|
|
||||||
steps(&mut machine, 1);
|
steps(&mut machine, 1);
|
||||||
@@ -30,7 +30,7 @@ fn advancedstack_3000() {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn advancedstack_50000() {
|
fn advancedstack_50000() {
|
||||||
let mut machine = rustijvm::Machine::new_from_file("files/advanced/teststack.ijvm").unwrap();
|
let mut machine = rustijvm::machine::Machine::new_from_file("files/advanced/teststack.ijvm").unwrap();
|
||||||
machine.set_output(rustijvm::stubs::output_stub());
|
machine.set_output(rustijvm::stubs::output_stub());
|
||||||
|
|
||||||
steps(&mut machine, 1);
|
steps(&mut machine, 1);
|
||||||
@@ -40,7 +40,7 @@ fn advancedstack_50000() {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn advancedstack_contents() {
|
fn advancedstack_contents() {
|
||||||
let mut machine = rustijvm::Machine::new_from_file("files/advanced/teststack.ijvm").unwrap();
|
let mut machine = rustijvm::machine::Machine::new_from_file("files/advanced/teststack.ijvm").unwrap();
|
||||||
machine.set_output(rustijvm::stubs::output_stub());
|
machine.set_output(rustijvm::stubs::output_stub());
|
||||||
|
|
||||||
steps(&mut machine, 1);
|
steps(&mut machine, 1);
|
||||||
@@ -58,7 +58,7 @@ fn advancedstack_contents() {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn advancedstack_method() {
|
fn advancedstack_method() {
|
||||||
let mut machine = rustijvm::Machine::new_from_file("files/advanced/teststack2.ijvm").unwrap();
|
let mut machine = rustijvm::machine::Machine::new_from_file("files/advanced/teststack2.ijvm").unwrap();
|
||||||
machine.set_output(rustijvm::stubs::output_stub());
|
machine.set_output(rustijvm::stubs::output_stub());
|
||||||
|
|
||||||
steps(&mut machine, 8);
|
steps(&mut machine, 8);
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ use std::io::{Seek, SeekFrom, Read};
|
|||||||
fn run_bfi(file: &str) -> String {
|
fn run_bfi(file: &str) -> String {
|
||||||
let file = File::open(file).expect("Missing bf file");
|
let file = File::open(file).expect("Missing bf file");
|
||||||
let rc = rustijvm::stubs::output_stub();
|
let rc = rustijvm::stubs::output_stub();
|
||||||
let mut machine = rustijvm::Machine::new_from_file("files/bonus/bfi.ijvm").unwrap();
|
let mut machine = rustijvm::machine::Machine::new_from_file("files/bonus/bfi.ijvm").unwrap();
|
||||||
machine.set_output(rc.clone());
|
machine.set_output(rc.clone());
|
||||||
machine.set_input(Box::new(file));
|
machine.set_input(Box::new(file));
|
||||||
|
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ fn test_create_from_slice() {
|
|||||||
let mut vec = Vec::<u8>::new();
|
let mut vec = Vec::<u8>::new();
|
||||||
File::open("files/task1/program1.ijvm").unwrap().read_to_end(&mut vec).unwrap();
|
File::open("files/task1/program1.ijvm").unwrap().read_to_end(&mut vec).unwrap();
|
||||||
|
|
||||||
let machine = rustijvm::Machine::new_from_slice(&vec).unwrap();
|
let machine = rustijvm::machine::Machine::new_from_slice(&vec).unwrap();
|
||||||
|
|
||||||
assert_eq!(machine.block.len(), 7);
|
assert_eq!(machine.block.len(), 7);
|
||||||
assert_eq!(machine.block[0], 0x10); // BIPUSH
|
assert_eq!(machine.block[0], 0x10); // BIPUSH
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ use rustijvm::binread::BinReadable;
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn task1_program1() {
|
fn task1_program1() {
|
||||||
let machine = rustijvm::Machine::new_from_file("files/task1/program1.ijvm").unwrap();
|
let machine = rustijvm::machine::Machine::new_from_file("files/task1/program1.ijvm").unwrap();
|
||||||
|
|
||||||
assert_eq!(machine.block.len(), 7);
|
assert_eq!(machine.block.len(), 7);
|
||||||
assert_eq!(machine.block[0], 0x10); // BIPUSH
|
assert_eq!(machine.block[0], 0x10); // BIPUSH
|
||||||
@@ -15,7 +15,7 @@ fn task1_program1() {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn task1_program2() {
|
fn task1_program2() {
|
||||||
let machine = rustijvm::Machine::new_from_file("files/task1/program2.ijvm").unwrap();
|
let machine = rustijvm::machine::Machine::new_from_file("files/task1/program2.ijvm").unwrap();
|
||||||
|
|
||||||
assert_eq!(machine.block.len(), 16);
|
assert_eq!(machine.block.len(), 16);
|
||||||
assert_eq!(machine.block[0], 0x0);
|
assert_eq!(machine.block[0], 0x0);
|
||||||
@@ -31,7 +31,7 @@ fn task1_program2() {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn task1_program_counter() {
|
fn task1_program_counter() {
|
||||||
let machine = rustijvm::Machine::new_from_file("files/task1/program1.ijvm").unwrap();
|
let machine = rustijvm::machine::Machine::new_from_file("files/task1/program1.ijvm").unwrap();
|
||||||
|
|
||||||
assert_eq!(machine.get_program_counter(), 0);
|
assert_eq!(machine.get_program_counter(), 0);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
extern crate rustijvm;
|
extern crate rustijvm;
|
||||||
|
|
||||||
fn steps(machine: &mut rustijvm::Machine, num: usize) {
|
fn steps(machine: &mut rustijvm::machine::Machine, num: usize) {
|
||||||
for _ in 0..num {
|
for _ in 0..num {
|
||||||
machine.step().unwrap();
|
machine.step().unwrap();
|
||||||
}
|
}
|
||||||
@@ -8,7 +8,7 @@ fn steps(machine: &mut rustijvm::Machine, num: usize) {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn task2_simple_bipush() {
|
fn task2_simple_bipush() {
|
||||||
let mut machine = rustijvm::Machine::new_from_file("files/task2/TestBipush1.ijvm").unwrap();
|
let mut machine = rustijvm::machine::Machine::new_from_file("files/task2/TestBipush1.ijvm").unwrap();
|
||||||
machine.set_output(rustijvm::stubs::output_stub());
|
machine.set_output(rustijvm::stubs::output_stub());
|
||||||
|
|
||||||
steps(&mut machine, 1);
|
steps(&mut machine, 1);
|
||||||
@@ -17,7 +17,7 @@ fn task2_simple_bipush() {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn task2_signed_bipush() {
|
fn task2_signed_bipush() {
|
||||||
let mut machine = rustijvm::Machine::new_from_file("files/task2/TestBipush2.ijvm").unwrap();
|
let mut machine = rustijvm::machine::Machine::new_from_file("files/task2/TestBipush2.ijvm").unwrap();
|
||||||
machine.set_output(rustijvm::stubs::output_stub());
|
machine.set_output(rustijvm::stubs::output_stub());
|
||||||
|
|
||||||
steps(&mut machine, 1);
|
steps(&mut machine, 1);
|
||||||
@@ -26,7 +26,7 @@ fn task2_signed_bipush() {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn task2_simple_iadd() {
|
fn task2_simple_iadd() {
|
||||||
let mut machine = rustijvm::Machine::new_from_file("files/task2/TestIadd1.ijvm").unwrap();
|
let mut machine = rustijvm::machine::Machine::new_from_file("files/task2/TestIadd1.ijvm").unwrap();
|
||||||
machine.set_output(rustijvm::stubs::output_stub());
|
machine.set_output(rustijvm::stubs::output_stub());
|
||||||
|
|
||||||
steps(&mut machine, 3);
|
steps(&mut machine, 3);
|
||||||
@@ -35,7 +35,7 @@ fn task2_simple_iadd() {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn task2_signed_iadd() {
|
fn task2_signed_iadd() {
|
||||||
let mut machine = rustijvm::Machine::new_from_file("files/task2/TestIadd2.ijvm").unwrap();
|
let mut machine = rustijvm::machine::Machine::new_from_file("files/task2/TestIadd2.ijvm").unwrap();
|
||||||
machine.set_output(rustijvm::stubs::output_stub());
|
machine.set_output(rustijvm::stubs::output_stub());
|
||||||
|
|
||||||
steps(&mut machine, 3);
|
steps(&mut machine, 3);
|
||||||
@@ -44,7 +44,7 @@ fn task2_signed_iadd() {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn task2_simple_isub() {
|
fn task2_simple_isub() {
|
||||||
let mut machine = rustijvm::Machine::new_from_file("files/task2/TestIsub1.ijvm").unwrap();
|
let mut machine = rustijvm::machine::Machine::new_from_file("files/task2/TestIsub1.ijvm").unwrap();
|
||||||
machine.set_output(rustijvm::stubs::output_stub());
|
machine.set_output(rustijvm::stubs::output_stub());
|
||||||
|
|
||||||
steps(&mut machine, 3);
|
steps(&mut machine, 3);
|
||||||
@@ -53,7 +53,7 @@ fn task2_simple_isub() {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn task2_signed_isub() {
|
fn task2_signed_isub() {
|
||||||
let mut machine = rustijvm::Machine::new_from_file("files/task2/TestIsub2.ijvm").unwrap();
|
let mut machine = rustijvm::machine::Machine::new_from_file("files/task2/TestIsub2.ijvm").unwrap();
|
||||||
machine.set_output(rustijvm::stubs::output_stub());
|
machine.set_output(rustijvm::stubs::output_stub());
|
||||||
|
|
||||||
steps(&mut machine, 3);
|
steps(&mut machine, 3);
|
||||||
@@ -62,7 +62,7 @@ fn task2_signed_isub() {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn task2_simple_iand() {
|
fn task2_simple_iand() {
|
||||||
let mut machine = rustijvm::Machine::new_from_file("files/task2/TestIAND1.ijvm").unwrap();
|
let mut machine = rustijvm::machine::Machine::new_from_file("files/task2/TestIAND1.ijvm").unwrap();
|
||||||
machine.set_output(rustijvm::stubs::output_stub());
|
machine.set_output(rustijvm::stubs::output_stub());
|
||||||
|
|
||||||
steps(&mut machine, 5);
|
steps(&mut machine, 5);
|
||||||
@@ -71,7 +71,7 @@ fn task2_simple_iand() {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn task2_simple_ior() {
|
fn task2_simple_ior() {
|
||||||
let mut machine = rustijvm::Machine::new_from_file("files/task2/TestIOR1.ijvm").unwrap();
|
let mut machine = rustijvm::machine::Machine::new_from_file("files/task2/TestIOR1.ijvm").unwrap();
|
||||||
machine.set_output(rustijvm::stubs::output_stub());
|
machine.set_output(rustijvm::stubs::output_stub());
|
||||||
|
|
||||||
steps(&mut machine, 5);
|
steps(&mut machine, 5);
|
||||||
@@ -80,7 +80,7 @@ fn task2_simple_ior() {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn task2_swap() {
|
fn task2_swap() {
|
||||||
let mut machine = rustijvm::Machine::new_from_file("files/task2/TestSwap1.ijvm").unwrap();
|
let mut machine = rustijvm::machine::Machine::new_from_file("files/task2/TestSwap1.ijvm").unwrap();
|
||||||
machine.set_output(rustijvm::stubs::output_stub());
|
machine.set_output(rustijvm::stubs::output_stub());
|
||||||
|
|
||||||
steps(&mut machine, 1);
|
steps(&mut machine, 1);
|
||||||
@@ -95,7 +95,7 @@ fn task2_swap() {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn task2_simple_stack_operations() {
|
fn task2_simple_stack_operations() {
|
||||||
let mut machine = rustijvm::Machine::new_from_file("files/task2/TestPop1.ijvm").unwrap();
|
let mut machine = rustijvm::machine::Machine::new_from_file("files/task2/TestPop1.ijvm").unwrap();
|
||||||
machine.set_output(rustijvm::stubs::output_stub());
|
machine.set_output(rustijvm::stubs::output_stub());
|
||||||
|
|
||||||
steps(&mut machine, 3);
|
steps(&mut machine, 3);
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
extern crate rustijvm;
|
extern crate rustijvm;
|
||||||
|
|
||||||
fn steps(machine: &mut rustijvm::Machine, num: usize) {
|
fn steps(machine: &mut rustijvm::machine::Machine, num: usize) {
|
||||||
for _ in 0..num {
|
for _ in 0..num {
|
||||||
machine.step().unwrap();
|
machine.step().unwrap();
|
||||||
}
|
}
|
||||||
@@ -8,7 +8,7 @@ fn steps(machine: &mut rustijvm::Machine, num: usize) {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn task3_goto1() {
|
fn task3_goto1() {
|
||||||
let mut machine = rustijvm::Machine::new_from_file("files/task3/GOTO1.ijvm").unwrap();
|
let mut machine = rustijvm::machine::Machine::new_from_file("files/task3/GOTO1.ijvm").unwrap();
|
||||||
machine.set_output(rustijvm::stubs::output_stub());
|
machine.set_output(rustijvm::stubs::output_stub());
|
||||||
|
|
||||||
steps(&mut machine, 1);
|
steps(&mut machine, 1);
|
||||||
@@ -20,7 +20,7 @@ fn task3_goto1() {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn task3_goto2() {
|
fn task3_goto2() {
|
||||||
let mut machine = rustijvm::Machine::new_from_file("files/task3/GOTO2.ijvm").unwrap();
|
let mut machine = rustijvm::machine::Machine::new_from_file("files/task3/GOTO2.ijvm").unwrap();
|
||||||
machine.set_output(rustijvm::stubs::output_stub());
|
machine.set_output(rustijvm::stubs::output_stub());
|
||||||
|
|
||||||
steps(&mut machine, 1);
|
steps(&mut machine, 1);
|
||||||
@@ -34,7 +34,7 @@ fn task3_goto2() {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn task3_ifeq1() {
|
fn task3_ifeq1() {
|
||||||
let mut machine = rustijvm::Machine::new_from_file("files/task3/IFEQ1.ijvm").unwrap();
|
let mut machine = rustijvm::machine::Machine::new_from_file("files/task3/IFEQ1.ijvm").unwrap();
|
||||||
machine.set_output(rustijvm::stubs::output_stub());
|
machine.set_output(rustijvm::stubs::output_stub());
|
||||||
|
|
||||||
steps(&mut machine, 1);
|
steps(&mut machine, 1);
|
||||||
@@ -73,7 +73,7 @@ fn task3_ifeq1() {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn task3_iflt1() {
|
fn task3_iflt1() {
|
||||||
let mut machine = rustijvm::Machine::new_from_file("files/task3/IFLT1.ijvm").unwrap();
|
let mut machine = rustijvm::machine::Machine::new_from_file("files/task3/IFLT1.ijvm").unwrap();
|
||||||
machine.set_output(rustijvm::stubs::output_stub());
|
machine.set_output(rustijvm::stubs::output_stub());
|
||||||
|
|
||||||
let mut pc = 0;
|
let mut pc = 0;
|
||||||
@@ -102,7 +102,7 @@ fn task3_iflt1() {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn task3_ificmpeq1() {
|
fn task3_ificmpeq1() {
|
||||||
let mut machine = rustijvm::Machine::new_from_file("files/task3/IFICMPEQ1.ijvm").unwrap();
|
let mut machine = rustijvm::machine::Machine::new_from_file("files/task3/IFICMPEQ1.ijvm").unwrap();
|
||||||
machine.set_output(rustijvm::stubs::output_stub());
|
machine.set_output(rustijvm::stubs::output_stub());
|
||||||
|
|
||||||
let mut pc = 0;
|
let mut pc = 0;
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ extern crate rustijvm;
|
|||||||
|
|
||||||
use std::io::{Read, Seek, SeekFrom};
|
use std::io::{Read, Seek, SeekFrom};
|
||||||
|
|
||||||
fn steps(machine: &mut rustijvm::Machine, num: usize) {
|
fn steps(machine: &mut rustijvm::machine::Machine, num: usize) {
|
||||||
for _ in 0..num {
|
for _ in 0..num {
|
||||||
machine.step().unwrap();
|
machine.step().unwrap();
|
||||||
}
|
}
|
||||||
@@ -10,7 +10,7 @@ fn steps(machine: &mut rustijvm::Machine, num: usize) {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn task4_ldcw1() {
|
fn task4_ldcw1() {
|
||||||
let mut machine = rustijvm::Machine::new_from_file("files/task4/LoadTest1.ijvm").unwrap();
|
let mut machine = rustijvm::machine::Machine::new_from_file("files/task4/LoadTest1.ijvm").unwrap();
|
||||||
machine.set_output(rustijvm::stubs::output_stub());
|
machine.set_output(rustijvm::stubs::output_stub());
|
||||||
|
|
||||||
steps(&mut machine, 1);
|
steps(&mut machine, 1);
|
||||||
@@ -23,7 +23,7 @@ fn task4_ldcw1() {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn task4_simple_load() {
|
fn task4_simple_load() {
|
||||||
let mut machine = rustijvm::Machine::new_from_file("files/task4/LoadTest3.ijvm").unwrap();
|
let mut machine = rustijvm::machine::Machine::new_from_file("files/task4/LoadTest3.ijvm").unwrap();
|
||||||
machine.set_output(rustijvm::stubs::output_stub());
|
machine.set_output(rustijvm::stubs::output_stub());
|
||||||
|
|
||||||
steps(&mut machine, 1);
|
steps(&mut machine, 1);
|
||||||
@@ -52,7 +52,7 @@ fn task4_simple_load() {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn task4_complex_load() {
|
fn task4_complex_load() {
|
||||||
let mut machine = rustijvm::Machine::new_from_file("files/task4/LoadTest2.ijvm").unwrap();
|
let mut machine = rustijvm::machine::Machine::new_from_file("files/task4/LoadTest2.ijvm").unwrap();
|
||||||
machine.set_output(rustijvm::stubs::output_stub());
|
machine.set_output(rustijvm::stubs::output_stub());
|
||||||
|
|
||||||
steps(&mut machine, 1);
|
steps(&mut machine, 1);
|
||||||
@@ -87,7 +87,7 @@ fn task4_complex_load() {
|
|||||||
fn task4_iteration_load() {
|
fn task4_iteration_load() {
|
||||||
let rc = rustijvm::stubs::output_stub();
|
let rc = rustijvm::stubs::output_stub();
|
||||||
|
|
||||||
let mut machine = rustijvm::Machine::new_from_file("files/task4/LoadTest4.ijvm").unwrap();
|
let mut machine = rustijvm::machine::Machine::new_from_file("files/task4/LoadTest4.ijvm").unwrap();
|
||||||
machine.set_output(rc.clone());
|
machine.set_output(rc.clone());
|
||||||
machine.run().unwrap();
|
machine.run().unwrap();
|
||||||
|
|
||||||
@@ -103,7 +103,7 @@ fn task4_iteration_load() {
|
|||||||
#[test]
|
#[test]
|
||||||
fn task4_iinc() {
|
fn task4_iinc() {
|
||||||
use rustijvm::value::Value::Int;
|
use rustijvm::value::Value::Int;
|
||||||
let mut machine = rustijvm::Machine::new_from_file("files/task4/IINCTest.ijvm").unwrap();
|
let mut machine = rustijvm::machine::Machine::new_from_file("files/task4/IINCTest.ijvm").unwrap();
|
||||||
machine.set_output(rustijvm::stubs::output_stub());
|
machine.set_output(rustijvm::stubs::output_stub());
|
||||||
|
|
||||||
steps(&mut machine, 4);
|
steps(&mut machine, 4);
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
extern crate rustijvm;
|
extern crate rustijvm;
|
||||||
fn steps(machine: &mut rustijvm::Machine, num: usize) {
|
fn steps(machine: &mut rustijvm::machine::Machine, num: usize) {
|
||||||
for _ in 0..num {
|
for _ in 0..num {
|
||||||
machine.step().unwrap();
|
machine.step().unwrap();
|
||||||
}
|
}
|
||||||
@@ -7,7 +7,7 @@ fn steps(machine: &mut rustijvm::Machine, num: usize) {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn task5_invokenoargs() {
|
fn task5_invokenoargs() {
|
||||||
let mut machine = rustijvm::Machine::new_from_file("files/task5/TestInvokeNoArgs.ijvm").unwrap();
|
let mut machine = rustijvm::machine::Machine::new_from_file("files/task5/TestInvokeNoArgs.ijvm").unwrap();
|
||||||
machine.set_output(rustijvm::stubs::output_stub());
|
machine.set_output(rustijvm::stubs::output_stub());
|
||||||
|
|
||||||
steps(&mut machine, 2);
|
steps(&mut machine, 2);
|
||||||
@@ -20,7 +20,7 @@ fn task5_invokenoargs() {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn task5_invoke1() {
|
fn task5_invoke1() {
|
||||||
let mut machine = rustijvm::Machine::new_from_file("files/task5/test-invokevirtual1.ijvm").unwrap();
|
let mut machine = rustijvm::machine::Machine::new_from_file("files/task5/test-invokevirtual1.ijvm").unwrap();
|
||||||
machine.set_output(rustijvm::stubs::output_stub());
|
machine.set_output(rustijvm::stubs::output_stub());
|
||||||
|
|
||||||
steps(&mut machine, 3);
|
steps(&mut machine, 3);
|
||||||
@@ -34,7 +34,7 @@ fn task5_invoke1() {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn task5_ireturn1() {
|
fn task5_ireturn1() {
|
||||||
let mut machine = rustijvm::Machine::new_from_file("files/task5/test-invokevirtual1.ijvm").unwrap();
|
let mut machine = rustijvm::machine::Machine::new_from_file("files/task5/test-invokevirtual1.ijvm").unwrap();
|
||||||
machine.set_output(rustijvm::stubs::output_stub());
|
machine.set_output(rustijvm::stubs::output_stub());
|
||||||
|
|
||||||
steps(&mut machine, 6);
|
steps(&mut machine, 6);
|
||||||
@@ -45,7 +45,7 @@ fn task5_ireturn1() {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn task5_invoke2() {
|
fn task5_invoke2() {
|
||||||
let mut machine = rustijvm::Machine::new_from_file("files/task5/test-invokevirtual2.ijvm").unwrap();
|
let mut machine = rustijvm::machine::Machine::new_from_file("files/task5/test-invokevirtual2.ijvm").unwrap();
|
||||||
machine.set_output(rustijvm::stubs::output_stub());
|
machine.set_output(rustijvm::stubs::output_stub());
|
||||||
|
|
||||||
steps(&mut machine, 5);
|
steps(&mut machine, 5);
|
||||||
@@ -61,7 +61,7 @@ fn task5_invoke2() {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn task5_ireturn2() {
|
fn task5_ireturn2() {
|
||||||
let mut machine = rustijvm::Machine::new_from_file("files/task5/test-invokevirtual2.ijvm").unwrap();
|
let mut machine = rustijvm::machine::Machine::new_from_file("files/task5/test-invokevirtual2.ijvm").unwrap();
|
||||||
machine.set_output(rustijvm::stubs::output_stub());
|
machine.set_output(rustijvm::stubs::output_stub());
|
||||||
|
|
||||||
steps(&mut machine, 10);
|
steps(&mut machine, 10);
|
||||||
|
|||||||
Reference in New Issue
Block a user