diff --git a/src/protocol/mod.rs b/src/protocol/mod.rs index d0dd2453c06c9f49d1cce7f935c3c0f092dba0ce..7a24b96535d8103cb1f74cf06665c8af8a27de4f 100644 --- a/src/protocol/mod.rs +++ b/src/protocol/mod.rs @@ -296,6 +296,12 @@ impl<'a> TypeInspector<'a> { let type_table = self.type_table.variant.as_union(); return UnionTypeInspector{ heap, type_table }; } + + pub fn as_struct(&'a self) -> StructTypeInspector<'a> { + let heap = self.heap.as_struct(); + let type_table = self.type_table.variant.as_struct(); + return StructTypeInspector{ heap, type_table }; + } } pub struct UnionTypeInspector<'a> { @@ -310,4 +316,18 @@ impl UnionTypeInspector<'_> { .position(|v| v.identifier.value.as_bytes() == variant_name)?; return Some(variant_index as i64); } +} + +pub struct StructTypeInspector<'a> { + heap: &'a StructDefinition, + type_table: &'a StructMonomorph, +} + +impl StructTypeInspector<'_> { + /// Retrieves struct field index + pub fn get_struct_field_index(&self, field_name: &[u8]) -> Option { + let field_index = self.heap.fields.iter() + .position(|v| v.field.value.as_bytes() == field_name)?; + return Some(field_index); + } } \ No newline at end of file diff --git a/src/protocol/parser/type_table.rs b/src/protocol/parser/type_table.rs index 2084a2474138f966eba4120d4ecf030ee1b506b1..6704ab82d2db754d64ff0e8256dd727d34d33d9b 100644 --- a/src/protocol/parser/type_table.rs +++ b/src/protocol/parser/type_table.rs @@ -224,6 +224,13 @@ impl MonoTypeVariant { } } + pub(crate) fn as_struct(&self) -> &StructMonomorph { + match self { + MonoTypeVariant::Struct(v) => v, + _ => unreachable!(), + } + } + fn as_tuple_mut(&mut self) -> &mut TupleMonomorph { match self { MonoTypeVariant::Tuple(v) => v, diff --git a/src/runtime2/component/component_internet.rs b/src/runtime2/component/component_internet.rs index 8d2f67a13e88cf98e39c0edd0eddb4eb2043896c..decdae7dadc7d079f18c0af714a1f380dd820798 100644 --- a/src/runtime2/component/component_internet.rs +++ b/src/runtime2/component/component_internet.rs @@ -10,24 +10,24 @@ use super::consensus::*; use std::io::ErrorKind as IoErrorKind; -enum SocketState { +// ----------------------------------------------------------------------------- +// ComponentTcpClient +// ----------------------------------------------------------------------------- + +enum ClientSocketState { Connected(SocketTcpClient), Error, } -impl SocketState { +impl ClientSocketState { fn get_socket(&self) -> &SocketTcpClient { match self { - SocketState::Connected(v) => v, - SocketState::Error => unreachable!(), + ClientSocketState::Connected(v) => v, + ClientSocketState::Error => unreachable!(), } } } -// ----------------------------------------------------------------------------- -// ComponentTcpClient -// ----------------------------------------------------------------------------- - /// States from the point of view of the component that is connecting to this /// TCP component (i.e. from the point of view of attempting to interface with /// a socket). @@ -42,13 +42,14 @@ enum ClientSyncState { pub struct ComponentTcpClient { // Properties for the tcp socket - socket_state: SocketState, + socket_state: ClientSocketState, sync_state: ClientSyncState, poll_ticket: Option, inbox_main: InboxMain, inbox_backup: InboxBackup, pdl_input_port_id: PortId, // input from PDL, so transmitted over socket pdl_output_port_id: PortId, // output towards PDL, so received over socket + // Information about union tags, extracted from PDL input_union_send_tag_value: i64, input_union_receive_tag_value: i64, input_union_finish_tag_value: i64, @@ -76,7 +77,7 @@ impl Component for ComponentTcpClient { self.input_union_shutdown_tag_value = cmd_type.get_variant_tag_value(b"Shutdown").unwrap(); // Register socket for async events - if let SocketState::Connected(socket) = &self.socket_state { + if let ClientSocketState::Connected(socket) = &self.socket_state { let self_handle = sched_ctx.runtime.get_component_public(id); let poll_ticket = sched_ctx.polling.register(socket, self_handle, true, true) .expect("registering tcp component"); @@ -140,7 +141,7 @@ impl Component for ComponentTcpClient { CompMode::NonSync => { // When in non-sync mode match &mut self.socket_state { - SocketState::Connected(_socket) => { + ClientSocketState::Connected(_socket) => { if self.sync_state == ClientSyncState::FinishSyncThenQuit { // Previous request was to let the component shut down self.exec_state.set_as_start_exit(ExitReason::Termination); @@ -153,7 +154,7 @@ impl Component for ComponentTcpClient { } return CompScheduling::Immediate; }, - SocketState::Error => { + ClientSocketState::Error => { // Could potentially send an error message to the // connected component. self.exec_state.set_as_start_exit(ExitReason::ErrorNonSync); @@ -320,7 +321,7 @@ impl ComponentTcpClient { } return Self{ - socket_state: SocketState::Connected(socket.unwrap()), + socket_state: ClientSocketState::Connected(socket.unwrap()), sync_state: ClientSyncState::AwaitingCmd, poll_ticket: None, inbox_main: vec![None], @@ -389,3 +390,20 @@ impl ComponentTcpClient { // ComponentTcpListener // ----------------------------------------------------------------------------- +enum ListenerSocketState { + Connected(SocketTcpListener), + Error, +} + +pub struct ComponentTcpListener { + // Properties for the tcp socket + socket_state: ListenerSocketState, + poll_ticket: Option, + inbox_main: InboxMain, + inbox_backup: InboxBackup, + pdl_output_port_id: PortId, // output port, sends + // Information about union tags + output_struct_rx_index: i64, + output_struct_tx_index: i64, + // Generic component state +} \ No newline at end of file diff --git a/src/runtime2/tests/internet.rs b/src/runtime2/tests/internet.rs new file mode 100644 index 0000000000000000000000000000000000000000..601a6e486d9eb5ef61df9a328b2ff0074ff411ce --- /dev/null +++ b/src/runtime2/tests/internet.rs @@ -0,0 +1,71 @@ +use super::*; + +// silly test to make sure that the PDL will never be an issue when doing TCP +// stuff with the actual components +#[test] +fn test_stdlib_file() { + compile_and_create_component(" + import std.internet as inet; + + primitive fake_listener_once(out tx) { + channel cmd_tx -> cmd_rx; + channel data_tx -> data_rx; + new fake_client(cmd_rx, data_tx); + sync put(tx, inet::TcpConnection{ + tx: cmd_tx, + rx: data_rx, + }); + } + + primitive fake_socket(in cmds, out tx) { + auto to_send = {}; + + auto shutdown = false; + while (!shutdown) { + auto keep_going = true; + sync { + while (keep_going) { + let cmd = get(cmds); + if (let inet::Cmd::Send(data) = cmd) { + to_send = data; + } else if (let inet::Cmd::Receive(data) = cmd) { + put(tx, to_send); + } else if (let inet::Cmd::Finish = cmd) { + keep_going = false; + } else if (let inet::Cmd::Shutdown = cmd) { + keep_going = false; + shutdown = true; + } + } + } + } + } + + primitive fake_client(inet::TcpConnection conn) { + sync put(conn.tx, inet::Cmd::Send({1, 3, 3, 7})); + sync { + put(conn.tx, inet::Cmd::Receive); + auto val = get(conn.rx); + while (val[0] != 1 || val[1] != 3 || val[2] != 3 || val[3] != 7) {} + put(conn.tx, inet::Cmd::Finish); + } + sync put(conn.tx, inet::Cmd::Shutdown); + } + + composite constructor() { + channel conn_tx -> conn_rx; + new fake_listener_once(conn_tx); + + // Same crap as before: + channel cmd_tx -> unused_cmd_rx; + channel unused_data_tx -> data_rx; + auto connection = inet::TcpConnection{ tx: cmd_tx, rx: data_rx }; + + sync { + connection = get(conn_rx); + } + + new fake_client(connection); + } + ", "constructor", no_args()); +} \ No newline at end of file diff --git a/src/runtime2/tests/mod.rs b/src/runtime2/tests/mod.rs index 85572c586c717aafef2405f6d35172c9dfe4b791..d145eddbcfaffa2ec557fe8c29f1c4fb17a18d56 100644 --- a/src/runtime2/tests/mod.rs +++ b/src/runtime2/tests/mod.rs @@ -6,6 +6,7 @@ use crate::runtime2::component::{CompCtx, CompPDL}; mod messaging; mod error_handling; mod transfer_ports; +mod internet; const LOG_LEVEL: LogLevel = LogLevel::Debug; const NUM_THREADS: u32 = 1; diff --git a/std/std.internet.pdl b/std/std.internet.pdl index 3e016622c4f8586d89ec371eb4e778dcc28f719e..ea2f6078695f9c8dd8c2aae3490107cd5848fb86 100644 --- a/std/std.internet.pdl +++ b/std/std.internet.pdl @@ -10,3 +10,12 @@ union Cmd { primitive tcp_client(u8[] ip, u16 port, in cmds, out rx) { #builtin } + +struct TcpConnection { + in tx, + out rx, +} + +/* primitive tcp_listener(u8[] ip, u16 port, out rx) { + #builtin +} */ \ No newline at end of file