From 3c15045e604d661b8af3359d957f5220c7edff2e Mon Sep 17 00:00:00 2001 From: Jur van den Berg Date: Sun, 12 Jun 2022 00:29:47 +0200 Subject: [PATCH] Add multi net conn --- src/machine.rs | 4 +-- src/ops.rs | 77 ++++++++++++++++++++++++++++++++------------------ src/value.rs | 6 ++++ 3 files changed, 58 insertions(+), 29 deletions(-) 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"), } } }