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>"]
|
||||
|
||||
[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 {
|
||||
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 {
|
||||
stack: Stack::new(),
|
||||
locals: vec![0; num_locals+1],
|
||||
|
||||
@@ -7,6 +7,7 @@ use ijvm::binread::BinRead;
|
||||
use ijvm::frame::Frame;
|
||||
use ijvm::stack::Stack;
|
||||
use ijvm::pool::Pool;
|
||||
use ijvm::netstack::NetStack;
|
||||
use ijvm::Result;
|
||||
|
||||
const MAGIC_HEADER:u32 = 0x1deadfad;
|
||||
@@ -16,7 +17,8 @@ pub struct Machine {
|
||||
pub wide: bool,
|
||||
pub pool: Pool,
|
||||
pub block: Block,
|
||||
pub frame: Vec<Frame>
|
||||
pub frame: Vec<Frame>,
|
||||
pub net: NetStack
|
||||
}
|
||||
|
||||
impl Machine {
|
||||
@@ -26,6 +28,7 @@ impl Machine {
|
||||
pool: pool,
|
||||
block: block,
|
||||
frame: vec![Frame::new(ANTI_BS_SIZE)],
|
||||
net: NetStack::new(),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -52,11 +55,15 @@ impl Machine {
|
||||
pub fn step(&mut self) -> Result<()> {
|
||||
match self.block.read_op() {
|
||||
Ok(Operation::Op(a, func)) => {
|
||||
// println!("{}", a);
|
||||
// println!("Stack: {:?}", self.cur_frame().stack.data);
|
||||
let x = func(self);
|
||||
// println!("Stack: {:?}", self.cur_frame().stack.data);
|
||||
x
|
||||
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!("OP: {}", a);
|
||||
|
||||
@@ -6,5 +6,6 @@ pub mod machine;
|
||||
pub mod stack;
|
||||
pub mod pool;
|
||||
pub mod frame;
|
||||
pub mod netstack;
|
||||
|
||||
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),
|
||||
0xFF => Operation::Op("HALT", halt),
|
||||
|
||||
#[cfg(feature = "extra:sleep")]
|
||||
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)
|
||||
}
|
||||
}
|
||||
@@ -232,6 +245,7 @@ fn ireturn(machine: &mut Machine) -> Result<()> {
|
||||
machine.block.seek(return_addr as usize)
|
||||
}
|
||||
|
||||
#[cfg(feature = "extra:sleep")]
|
||||
fn slp(machine: &mut Machine) -> Result<()> {
|
||||
use std::time;
|
||||
use std::thread;
|
||||
@@ -242,4 +256,35 @@ fn slp(machine: &mut Machine) -> Result<()> {
|
||||
let slpdur = time::Duration::from_millis(val*100);
|
||||
thread::sleep(slpdur);
|
||||
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) {
|
||||
self.data.push(val);
|
||||
}
|
||||
|
||||
pub fn len(&self) -> usize {
|
||||
self.data.len()
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user