Skip to content

Commit

Permalink
refactor code to fit with refactored WASM lib + benchmark test modifi…
Browse files Browse the repository at this point in the history
…cations
  • Loading branch information
Erik Chi committed Oct 5, 2023
1 parent 0269e91 commit 05cb957
Show file tree
Hide file tree
Showing 16 changed files with 333 additions and 89 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ The repo will contain 2 parts of purposes:

### What is needed for the library / cli
#### The Host side:
**Config**: calls main program / some library entry func -> use claps to get args (making use of some `Args` struct) -> then convert it to a `Config` struct.
**Config**: calls main program / some library entry func -> use claps to get args (making use of some `Args` struct) -> then convert it to a `WATERConfig` struct.

**execute**:
1. wasmtime runtime creation
Expand Down
Binary file removed proxy.wasm
Binary file not shown.
8 changes: 4 additions & 4 deletions src/cli/mod.rs
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
use crate::{config::Config, runtime};
use crate::{config::WATERConfig, runtime};

use std::sync::Arc;

pub fn parse() -> Result<Config, anyhow::Error> {
pub fn parse() -> Result<WATERConfig, anyhow::Error> {
// Parse command-line arguments and execute the appropriate commands
let conf = Config::from_args()?;
let conf = WATERConfig::from_args()?;
Ok(conf)
}

pub fn parse_and_execute() -> Result<(), anyhow::Error> {
execute(parse()?)
}

pub fn execute(conf: Config) -> Result<(), anyhow::Error> {
pub fn execute(conf: WATERConfig) -> Result<(), anyhow::Error> {
let mut water_client = runtime::WATERClient::new(conf)?;

// // FIXME: hardcoded the addr & port for now
Expand Down
16 changes: 11 additions & 5 deletions src/config/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,28 +30,34 @@ struct Args {
/// Optional argument specifying the client_type, default to be Runner
#[arg(short, long, default_value_t = 2)]
type_client: u32,

/// Optional argument specifying the client_type, default to be Runner
#[arg(short, long, default_value_t = false)]
debug: bool,
}

pub struct Config {
pub struct WATERConfig {
pub filepath: String,
pub entry_fn: String,
pub config_wasm: String,
pub client_type: u32,
pub debug: bool,
}

impl Config {
impl WATERConfig {
pub fn from_args() -> Result<Self, anyhow::Error> {
let args = Args::parse();

Self::init(args.wasm_path, args.entry_fn, args.config_wasm, args.type_client)
Self::init(args.wasm_path, args.entry_fn, args.config_wasm, args.type_client, args.debug)
}

pub fn init(wasm_path: String, entry_fn: String, config_wasm: String, client_type: u32) -> Result<Self, anyhow::Error> {
Ok(Config {
pub fn init(wasm_path: String, entry_fn: String, config_wasm: String, client_type: u32, debug: bool) -> Result<Self, anyhow::Error> {
Ok(WATERConfig {
filepath: wasm_path,
entry_fn: entry_fn,
config_wasm: config_wasm,
client_type: client_type,
debug: debug,
})
}
}
8 changes: 4 additions & 4 deletions src/globals.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,12 @@ const DEALLOC_FN: &str = "dealloc";
pub const MAIN: &str = "main";
pub const VERSION_FN: &str = "_version";
pub const INIT_FN: &str = "_init";
pub const CONFIG_FN: &str = "_process_config";
pub const CONFIG_FN: &str = "_config";
pub const USER_READ_FN: &str = "_user_will_read";
pub const WRITE_DONE_FN: &str = "_user_write_done";
pub const WATER_BRIDGING_FN: &str = "_water_bridging";
pub const READER_FN: &str = "_read_from_net";
pub const WRITER_FN: &str = "_write_2_net";
pub const WATER_BRIDGING_FN: &str = "_set_inbound";
pub const READER_FN: &str = "_read";
pub const WRITER_FN: &str = "_write";

pub const RUNTIME_VERSION_MAJOR: i32 = 0x001aaaaa;
pub const RUNTIME_VERSION: &str = "v0.1-alpha";
49 changes: 36 additions & 13 deletions src/runtime/core.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ pub struct Host {
}

pub struct H2O<Host> {
pub version: Version,

pub engine: Engine,
pub linker: Linker<Host>,
pub instance: Instance,
Expand All @@ -15,7 +17,7 @@ pub struct H2O<Host> {
}

impl H2O<Host> {
pub fn init(conf: &Config) -> Result<Self, anyhow::Error> {
pub fn init(conf: &WATERConfig) -> Result<Self, anyhow::Error> {
info!("[HOST] WATERCore H2O initing...");

let mut wasm_config = wasmtime::Config::new();
Expand All @@ -25,10 +27,25 @@ impl H2O<Host> {
let mut linker: Linker<Host> = Linker::new(&engine);

let module = Module::from_file(&engine, &conf.filepath)?;

let host = Host::default();
let mut store = Store::new(&engine, host);

let version = module.exports().find_map(|global| {
info!("[HOST] WATERCore finding exported symbols from WASM bin: {:?}", global.name());
match Version::from_str(global.name()) {
Some(v) => {
info!("[HOST] WATERCore found version: {:?}", v.as_str());
Some(v)
},
None => None,
}
});

if version.is_none() {
return Err(anyhow::Error::msg("WASM module version not found"));
}

// let path = unsafe { Dir::open_ambient_dir(".", ambient_authority())? };

// store.data_mut().preview1_ctx = Some(WasiCtxBuilder::new().inherit_stdio().preopened_dir(path, ".")?.build());
Expand All @@ -51,14 +68,21 @@ impl H2O<Host> {
h.wasi_threads.as_ref().unwrap()
})?;
}

// export functions -- link connect functions
export_tcp_connect(&mut linker);
export_tcplistener_create(&mut linker);

// export functions -- link connect functions -- has to be done before instantiate
match &version {
Some(Version::V0) => {
v0::funcs::export_tcp_connect(&mut linker);
v0::funcs::export_tcplistener_create(&mut linker);
},
_ => {} // add export funcs for other versions here
}

let instance = linker.instantiate(&mut store, &module)?;

Ok(H2O {
version: version.unwrap(),

engine: engine,
linker: linker,
instance: instance,
Expand All @@ -67,14 +91,14 @@ impl H2O<Host> {
})
}

pub fn _prepare(&mut self, conf: &Config) -> Result<(), anyhow::Error> {
pub fn _prepare(&mut self, conf: &WATERConfig) -> Result<(), anyhow::Error> {
self._version()?;
self._init()?;
self._init(conf.debug)?;
self._process_config(&conf)?;
Ok(())
}

pub fn _init(&mut self) -> Result<(), anyhow::Error> {
pub fn _init(&mut self, debug: bool) -> Result<(), anyhow::Error> {
info!("[HOST] WATERCore H2O calling _init from WASM...");

let init_fn = match self.instance.get_func(&mut self.store, INIT_FN) {
Expand All @@ -83,7 +107,8 @@ impl H2O<Host> {
};

// TODO: check if we need to pass in any arguments / configs later
match init_fn.call(&mut self.store, &[], &mut []) {
let params = vec![Val::I32(debug as i32); init_fn.ty(&self.store).params().len()];
match init_fn.call(&mut self.store, &params, &mut []) {
Ok(_) => {},
Err(e) => return Err(anyhow::Error::msg(format!("init function failed: {}", e))),
}
Expand Down Expand Up @@ -117,7 +142,6 @@ impl H2O<Host> {
)
.collect(); // collect the default values into a Vec

// TODO: add error handling code like this for all other func.call()'s
match version_fn.call(&mut self.store, &[], &mut res) {
Ok(_) => {},
Err(e) => return Err(anyhow::Error::msg(format!("version function failed: {}", e))),
Expand All @@ -136,7 +160,7 @@ impl H2O<Host> {
Ok(())
}

pub fn _process_config(&mut self, config: &Config) -> Result<(), anyhow::Error> {
pub fn _process_config(&mut self, config: &WATERConfig) -> Result<(), anyhow::Error> {
info!("[HOST] WATERCore H2O calling _process_config from WASM...");

// _required to implement _process_config(i32) in WASM, which will be parsing all the configurations
Expand All @@ -150,7 +174,6 @@ impl H2O<Host> {
let wasi_file = dir.open_with(&config.config_wasm, OpenOptions::new().read(true).write(true))?;
let wasi_file = wasmtime_wasi::sync::file::File::from_cap_std(wasi_file);

// TODO: might be better to ask WASM for the fd? Or if it is fixed in the pipeline, then 3 is fine
let ctx = self.store.data_mut().preview1_ctx.as_mut().unwrap();
let config_fd = ctx.push_file(Box::new(wasi_file), FileAccessMode::all())? as i32;

Expand Down
4 changes: 2 additions & 2 deletions src/runtime/listener.rs
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ impl WATERListener<Host> {
}

/// Listening at the addr:port with running the WASM listen function
pub fn listen(&mut self, conf: &Config, addr: &str, port: u16) -> Result<(), anyhow::Error> {
pub fn listen(&mut self, conf: &WATERConfig, addr: &str, port: u16) -> Result<(), anyhow::Error> {
info!("[HOST] WATERStream listening...");

// TODO: add addr:port sharing with WASM, for now WASM is using config.json's remote_addr:port
Expand All @@ -90,7 +90,7 @@ impl WATERListener<Host> {
Ok(())
}

pub fn init(conf: &Config) -> Result<Self, anyhow::Error> {
pub fn init(conf: &WATERConfig) -> Result<Self, anyhow::Error> {
info!("[HOST] WATERStream init...");

let mut core = H2O::init(conf)?;
Expand Down
18 changes: 9 additions & 9 deletions src/runtime/mod.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
pub mod net;
pub mod funcs;
pub mod v0;
pub mod stream;
pub mod core;
pub mod listener;
pub mod runner;
pub mod version;

use std::sync::Arc;
use anyhow::{Context, Result};
Expand All @@ -27,27 +28,26 @@ use std::os::unix::io::{AsRawFd, FromRawFd};
// use system_interface::io::io_ext::IoExt;
use std::io::{Read, Write};

use tracing::{info, trace};
use tracing::{info, trace, debug};

use cap_std::net::{TcpListener, TcpStream};

use crate::config::Config;
use crate::config::WATERConfig;
use crate::config::wasm_shared_config::WASMSharedConfig;
use crate::globals::READER_FN;
use crate::globals::WRITER_FN;

use net::{File, FileName, ListenFile, ConnectFile};
use funcs::{export_tcplistener_create, export_tcp_connect};

use crate::globals::{VERSION_FN, RUNTIME_VERSION_MAJOR, RUNTIME_VERSION, INIT_FN, USER_READ_FN, WRITE_DONE_FN, CONFIG_FN, WATER_BRIDGING_FN};

use stream::{WATERStream};
use listener::{WATERListener};
use runner::{WATERRunner};
use version::Version;
// use core::WATERCore;
use core::{H2O, Host};


pub enum WATERClientType {
Dialer(WATERStream<Host>),
Listener(WATERListener<Host>),
Expand All @@ -57,12 +57,12 @@ pub enum WATERClientType {
pub struct WATERClient {
debug: bool,

pub config: Config,
pub config: WATERConfig,
pub stream: WATERClientType,
}

impl WATERClient {
pub fn new(conf: Config) -> Result<Self, anyhow::Error> {
pub fn new(conf: WATERConfig) -> Result<Self, anyhow::Error> {
// client_type: 0 -> Dialer, 1 -> Listener, 2 -> Runner
let mut water: WATERClientType;
if conf.client_type == 0 {
Expand Down Expand Up @@ -105,7 +105,7 @@ impl WATERClient {

pub fn connect(&mut self, addr: &str, port: u16) -> Result<(), anyhow::Error> {
info!("[HOST] WATERClient connecting ...");
// NOTE: After creating the WATERStream, do some initial calls to WASM (e.g. version, init, etc.)

match &mut self.stream {
WATERClientType::Dialer(dialer) => {
dialer.connect(&self.config, addr, port)?;
Expand All @@ -119,7 +119,7 @@ impl WATERClient {

pub fn listen(&mut self, addr: &str, port: u16) -> Result<(), anyhow::Error> {
info!("[HOST] WATERClient listening ...");
// NOTE: After creating the WATERStream, do some initial calls to WASM (e.g. version, init, etc.)

match &mut self.stream {
WATERClientType::Listener(listener) => {
listener.listen(&self.config, addr, port)?;
Expand Down
4 changes: 2 additions & 2 deletions src/runtime/runner.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ pub struct WATERRunner<Host> {

impl WATERRunner<Host> {
/// Run the entry function
pub fn run(&mut self, conf: &Config) -> Result<(), anyhow::Error> {
pub fn run(&mut self, conf: &WATERConfig) -> Result<(), anyhow::Error> {
info!("[HOST] WATERRunner running...");

let fnc = self.core.instance.get_func(&mut self.core.store, &conf.entry_fn).unwrap();
Expand All @@ -18,7 +18,7 @@ impl WATERRunner<Host> {
Ok(())
}

pub fn init(conf: &Config) -> Result<Self, anyhow::Error> {
pub fn init(conf: &WATERConfig) -> Result<Self, anyhow::Error> {
info!("[HOST] WATERRunner init...");

let mut core = H2O::init(conf)?;
Expand Down
Loading

0 comments on commit 05cb957

Please sign in to comment.