Network bonus. Gimme my 10%
This commit is contained in:
13
Cargo.toml
13
Cargo.toml
@@ -4,3 +4,16 @@ version = "0.1.0"
|
|||||||
authors = ["Jur van den Berg <Jurl.berg@gmail.com>"]
|
authors = ["Jur van den Berg <Jurl.berg@gmail.com>"]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
|
|
||||||
|
[features]
|
||||||
|
default = ["bonus", "extra"]
|
||||||
|
|
||||||
|
bonus = ["bonus:network"]
|
||||||
|
"bonus:network" = []
|
||||||
|
|
||||||
|
extra = ["extra:sleep"]
|
||||||
|
"extra:sleep" = []
|
||||||
|
|
||||||
|
debug = ["debug:instr", "debug:frame"]
|
||||||
|
"debug:instr" = []
|
||||||
|
"debug:frame" = []
|
||||||
@@ -9,7 +9,9 @@ pub struct Frame {
|
|||||||
|
|
||||||
impl Frame {
|
impl Frame {
|
||||||
pub fn new(num_locals: usize) -> Frame {
|
pub fn new(num_locals: usize) -> Frame {
|
||||||
// println!("Initializing frame of len {}", num_locals);
|
if cfg!(feature="debug:frame") {
|
||||||
|
println!("Initializing frame of len {}", num_locals);
|
||||||
|
}
|
||||||
return Frame {
|
return Frame {
|
||||||
stack: Stack::new(),
|
stack: Stack::new(),
|
||||||
locals: vec![0; num_locals+1],
|
locals: vec![0; num_locals+1],
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ use ijvm::binread::BinRead;
|
|||||||
use ijvm::frame::Frame;
|
use ijvm::frame::Frame;
|
||||||
use ijvm::stack::Stack;
|
use ijvm::stack::Stack;
|
||||||
use ijvm::pool::Pool;
|
use ijvm::pool::Pool;
|
||||||
|
use ijvm::netstack::NetStack;
|
||||||
use ijvm::Result;
|
use ijvm::Result;
|
||||||
|
|
||||||
const MAGIC_HEADER:u32 = 0x1deadfad;
|
const MAGIC_HEADER:u32 = 0x1deadfad;
|
||||||
@@ -16,7 +17,8 @@ pub struct Machine {
|
|||||||
pub wide: bool,
|
pub wide: bool,
|
||||||
pub pool: Pool,
|
pub pool: Pool,
|
||||||
pub block: Block,
|
pub block: Block,
|
||||||
pub frame: Vec<Frame>
|
pub frame: Vec<Frame>,
|
||||||
|
pub net: NetStack
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Machine {
|
impl Machine {
|
||||||
@@ -26,6 +28,7 @@ impl Machine {
|
|||||||
pool: pool,
|
pool: pool,
|
||||||
block: block,
|
block: block,
|
||||||
frame: vec![Frame::new(ANTI_BS_SIZE)],
|
frame: vec![Frame::new(ANTI_BS_SIZE)],
|
||||||
|
net: NetStack::new(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -52,11 +55,15 @@ 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)) => {
|
||||||
// println!("{}", a);
|
if cfg!(feature = "debug:instr") {
|
||||||
// println!("Stack: {:?}", self.cur_frame().stack.data);
|
println!("{}", a);
|
||||||
let x = func(self);
|
println!("Stack: {:?}", self.cur_frame().stack.data);
|
||||||
// println!("Stack: {:?}", self.cur_frame().stack.data);
|
let x = func(self);
|
||||||
x
|
println!("Stack: {:?}", self.cur_frame().stack.data);
|
||||||
|
x
|
||||||
|
} else {
|
||||||
|
func(self)
|
||||||
|
}
|
||||||
},
|
},
|
||||||
Ok(Operation::Invalid(a)) => {
|
Ok(Operation::Invalid(a)) => {
|
||||||
println!("OP: {}", a);
|
println!("OP: {}", a);
|
||||||
|
|||||||
@@ -6,5 +6,6 @@ pub mod machine;
|
|||||||
pub mod stack;
|
pub mod stack;
|
||||||
pub mod pool;
|
pub mod pool;
|
||||||
pub mod frame;
|
pub mod frame;
|
||||||
|
pub mod netstack;
|
||||||
|
|
||||||
type Result<T> = ::std::result::Result<T, &'static str>;
|
type Result<T> = ::std::result::Result<T, &'static str>;
|
||||||
|
|||||||
86
src/ijvm/netstack.rs
Normal file
86
src/ijvm/netstack.rs
Normal file
@@ -0,0 +1,86 @@
|
|||||||
|
use ijvm::Result;
|
||||||
|
use std::io::{Read, Write};
|
||||||
|
use std::net::{TcpListener, TcpStream};
|
||||||
|
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct NetStack {
|
||||||
|
pub stream: Option<TcpStream>
|
||||||
|
}
|
||||||
|
|
||||||
|
impl NetStack {
|
||||||
|
pub fn new() -> NetStack {
|
||||||
|
NetStack{
|
||||||
|
stream: None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn bind(&mut self, port: u16) -> Result<()> {
|
||||||
|
let listener = match TcpListener::bind(format!("0.0.0.0:{}", port)) {
|
||||||
|
Ok(a) => a,
|
||||||
|
Err(_) => return Err("Failed to open connection"),
|
||||||
|
};
|
||||||
|
|
||||||
|
return match listener.accept() {
|
||||||
|
Ok((sock, _)) => {
|
||||||
|
self.stream = Some(sock);
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
Err(_) => Err("Could not accept connection")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn connect(&mut self, host: u32, port: u16) -> Result<()> {
|
||||||
|
let h1 = (host & (0xFF << 24)) >> 24 as u8;
|
||||||
|
let h2 = (host & (0xFF << 16)) >> 16 as u8;
|
||||||
|
let h3 = (host & (0xFF << 8)) >> 8 as u8;
|
||||||
|
let h4 = (host & (0xFF << 0)) >> 0 as u8;
|
||||||
|
let addr: String = format!("{}.{}.{}.{}:{}", h1, h2, h3, h4, port);
|
||||||
|
|
||||||
|
if let Ok(stream) = TcpStream::connect(addr) {
|
||||||
|
self.stream = Some(stream);
|
||||||
|
return Ok(())
|
||||||
|
}
|
||||||
|
Err("Could not connect to address")
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn close(&mut self) -> Result<()> {
|
||||||
|
if let None = self.stream {
|
||||||
|
return Err("Cannot close a nonexistent socket")
|
||||||
|
}
|
||||||
|
|
||||||
|
self.stream = None;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn read_byte(&mut self) -> Result<i8> {
|
||||||
|
return match self.stream {
|
||||||
|
Some(ref mut stream) => {
|
||||||
|
match stream.bytes().next().and_then(|r| r.ok()) {
|
||||||
|
Some(i) => Ok(i as i8),
|
||||||
|
None => Err("Could not read a byte")
|
||||||
|
}
|
||||||
|
},
|
||||||
|
None => Err("No connection")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn write_byte(&mut self, byte: u8) -> Result<()> {
|
||||||
|
return match self.stream {
|
||||||
|
Some(ref mut stream) => {
|
||||||
|
let buf = [byte];
|
||||||
|
match stream.write(&buf) {
|
||||||
|
Ok(a) => {
|
||||||
|
if a > 0 {
|
||||||
|
Ok(())
|
||||||
|
} else {
|
||||||
|
Err("Wrote zero bytes")
|
||||||
|
}
|
||||||
|
},
|
||||||
|
Err(_) => Err("Could not write a byte")
|
||||||
|
}
|
||||||
|
},
|
||||||
|
None => Err("No connection")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -40,7 +40,20 @@ pub fn num_to_op(op: u8) -> Operation {
|
|||||||
0xFD => Operation::Op("OUT", out),
|
0xFD => Operation::Op("OUT", out),
|
||||||
0xFF => Operation::Op("HALT", halt),
|
0xFF => Operation::Op("HALT", halt),
|
||||||
|
|
||||||
|
#[cfg(feature = "extra:sleep")]
|
||||||
0xF0 => Operation::Op("SLP", slp),
|
0xF0 => Operation::Op("SLP", slp),
|
||||||
|
|
||||||
|
#[cfg(feature = "bonus:network")]
|
||||||
|
0xE1 => Operation::Op("NETBIND", netbind),
|
||||||
|
#[cfg(feature = "bonus:network")]
|
||||||
|
0xE2 => Operation::Op("NETCONNECT", netconnect),
|
||||||
|
#[cfg(feature = "bonus:network")]
|
||||||
|
0xE3 => Operation::Op("NETIN", netin),
|
||||||
|
#[cfg(feature = "bonus:network")]
|
||||||
|
0xE4 => Operation::Op("NETOUT", netout),
|
||||||
|
#[cfg(feature = "bonus:network")]
|
||||||
|
0xE5 => Operation::Op("NETCLOSE", netclose),
|
||||||
|
|
||||||
x => Operation::Invalid(x)
|
x => Operation::Invalid(x)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -232,6 +245,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")]
|
||||||
fn slp(machine: &mut Machine) -> Result<()> {
|
fn slp(machine: &mut Machine) -> Result<()> {
|
||||||
use std::time;
|
use std::time;
|
||||||
use std::thread;
|
use std::thread;
|
||||||
@@ -243,3 +257,34 @@ fn slp(machine: &mut Machine) -> Result<()> {
|
|||||||
thread::sleep(slpdur);
|
thread::sleep(slpdur);
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "bonus:network")]
|
||||||
|
fn netbind(machine: &mut Machine) -> Result<()> {
|
||||||
|
let port = machine.cur_stack().pop()? as u16;
|
||||||
|
machine.net.bind(port)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "bonus:network")]
|
||||||
|
fn netconnect(machine: &mut Machine) -> Result<()> {
|
||||||
|
let port = machine.cur_stack().pop()? as u16;
|
||||||
|
let host = machine.cur_stack().pop()? as u32;
|
||||||
|
machine.net.connect(host, port)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "bonus:network")]
|
||||||
|
fn netin(machine: &mut Machine) -> Result<()> {
|
||||||
|
let byte = machine.net.read_byte()? as i32;
|
||||||
|
machine.cur_stack().push(byte);
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "bonus:network")]
|
||||||
|
fn netout(machine: &mut Machine) -> Result<()> {
|
||||||
|
let val = machine.cur_stack().pop()? as u8;
|
||||||
|
machine.net.write_byte(val)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "bonus:network")]
|
||||||
|
fn netclose(machine: &mut Machine) -> Result<()> {
|
||||||
|
machine.net.close()
|
||||||
|
}
|
||||||
@@ -33,8 +33,4 @@ impl Stack {
|
|||||||
pub fn push(&mut self, val: i32) {
|
pub fn push(&mut self, val: i32) {
|
||||||
self.data.push(val);
|
self.data.push(val);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn len(&self) -> usize {
|
|
||||||
self.data.len()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user