diff --git a/src/machine.rs b/src/machine.rs
index 7f70249..62b0563 100644
--- a/src/machine.rs
+++ b/src/machine.rs
@@ -26,7 +26,7 @@ pub struct Machine {
pub frame: Vec,
#[cfg(feature = "bonus.network")]
- pub net: NetStack,
+ pub net: Vec,
#[cfg(feature = "bonus.heap")]
pub heap: Heaps,
@@ -46,7 +46,7 @@ impl Machine {
stream_out: Arc::new(Mutex::new(::std::io::stdout())),
#[cfg(feature = "bonus.network")]
- net: NetStack::new(),
+ net: Vec::new(),
#[cfg(feature = "bonus.heap")]
heap: Heaps::new(),
diff --git a/src/ops.rs b/src/ops.rs
index cf3a216..fd5376d 100644
--- a/src/ops.rs
+++ b/src/ops.rs
@@ -6,6 +6,7 @@ use std::num::Wrapping;
use Result;
use value::Value;
use std::convert::TryInto;
+use netstack::NetStack;
pub type OpFunc = fn(&mut Machine) -> Result<()>;
@@ -179,8 +180,15 @@ fn halt(machine: &mut Machine) -> Result<()> {
fn ifeq(machine: &mut Machine) -> Result<()> {
let offset = i32::from(machine.block.read_i16()?) - JUMP_OFFSET;
- let compare: i32 = machine.cur_stack().pop()?.try_into()?;
- if compare == 0 {
+ let tos = machine.cur_stack().pop()?;
+ // 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);
}
Ok(())
@@ -311,11 +319,16 @@ fn slp(machine: &mut Machine) -> Result<()> {
fn netbind(machine: &mut Machine) -> Result<()> {
let port: i32 = machine.cur_stack().pop()?.try_into()?;
- let result = match machine.net.bind(port as u16) {
- Ok(_) => 1,
- Err(_) => 0,
- };
- machine.cur_stack().push(Value::Int(result));
+ let mut stack = NetStack::new();
+ if stack.bind(port as u16).is_err() {
+ machine.cur_stack().push(Value::Int(0));
+ return Ok(());
+ }
+
+ machine.net.push(stack);
+ let idx = machine.net.len();
+ machine.cur_stack().push(Value::NetRef(idx));
+
Ok(())
}
@@ -323,44 +336,54 @@ fn netbind(machine: &mut Machine) -> Result<()> {
fn netconnect(machine: &mut Machine) -> Result<()> {
let port: 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,
- Err(_) => 0,
- };
- machine.cur_stack().push(Value::Int(result));
+
+ let mut stack = NetStack::new();
+ if stack.connect(host as u32, port as u16).is_err() {
+ machine.cur_stack().push(Value::Int(0));
+ return Ok(());
+ }
+ machine.net.push(stack);
+ let idx = machine.net.len();
+ machine.cur_stack().push(Value::NetRef(idx));
+
Ok(())
}
#[cfg(feature = "bonus.network")]
fn netin(machine: &mut Machine) -> Result<()> {
- let netref: i32 = machine.cur_stack().pop()?.try_into()?;
- if netref != 1 {
- return Err("Invalid netref to netin");
- }
+ let idx = match machine.cur_stack().pop()? {
+ Value::NetRef(x) => x,
+ _ => 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));
Ok(())
}
#[cfg(feature = "bonus.network")]
fn netout(machine: &mut Machine) -> Result<()> {
- let netref: i32 = machine.cur_stack().pop()?.try_into()?;
- if netref != 1 {
- return Err("Invalid netref to netout");
- }
+ let idx = match machine.cur_stack().pop()? {
+ Value::NetRef(x) => x,
+ _ => Err("Invalid netref given to network instruction")?,
+ };
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")]
fn netclose(machine: &mut Machine) -> Result<()> {
- let netref: i32 = machine.cur_stack().pop()?.try_into()?;
- if netref != 1 {
- return Err("Invalid netref to netclose");
- }
- machine.net.close()
+ let idx = match machine.cur_stack().pop()? {
+ Value::NetRef(x) => x,
+ _ => Err("Invalid netref given to network instruction")?,
+ };
+
+ machine.net.get_mut(idx - 1).ok_or("Invalid network connection")?.close()?;
+ Ok(())
}
#[cfg(feature = "bonus.heap")]
diff --git a/src/value.rs b/src/value.rs
index a5d2b10..2e480ae 100644
--- a/src/value.rs
+++ b/src/value.rs
@@ -6,6 +6,8 @@ use heap::Heap;
pub enum Value {
Int(i32),
HeapRef(Heap),
+ #[cfg(feature = "bonus.network")]
+ NetRef(usize),
}
impl TryInto for Value {
@@ -15,6 +17,8 @@ impl TryInto for Value {
match self {
Value::Int(a) => Ok(a),
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 for &Value {
match *self {
Value::Int(a) => Ok(a),
Value::HeapRef(_) => Err("Cannot use HeapRef as i32"),
+ #[cfg(feature = "bonus.network")]
+ Value::NetRef(_) => Err("Cannot use NetRef as i32"),
}
}
}