Network bonus. Gimme my 10%

This commit is contained in:
2017-06-06 21:21:21 +02:00
parent 1b3c582ee2
commit e23a9e8fb8
7 changed files with 161 additions and 11 deletions

View File

@@ -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" = []

View File

@@ -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],

View File

@@ -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);

View File

@@ -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
View 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")
}
}
}

View File

@@ -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()
}

View File

@@ -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()
}
}