aboutsummaryrefslogtreecommitdiffstats
path: root/src/main.rs
diff options
context:
space:
mode:
authorBrooks Rady <b.j.rady@gmail.com>2020-11-26 10:36:27 +0000
committerGitHub <noreply@github.com>2020-11-26 10:36:27 +0000
commit1586a705d2b36669ee4045b35377d8ddd591ccef (patch)
tree5ceedf618ff09c25ff316fa9fae80fea2787fcd4 /src/main.rs
parenthotfix(logging): atomically create tmp folders (diff)
parentfix(tests): improve atomic data access (diff)
downloadsl0ppij-1586a705d2b36669ee4045b35377d8ddd591ccef.tar.gz
sl0ppij-1586a705d2b36669ee4045b35377d8ddd591ccef.tar.xz
sl0ppij-1586a705d2b36669ee4045b35377d8ddd591ccef.zip
feat(tiles): initial WASM integration
The first steps towards WASM module integration
Diffstat (limited to 'src/main.rs')
-rw-r--r--src/main.rs108
1 files changed, 107 insertions, 1 deletions
diff --git a/src/main.rs b/src/main.rs
index 04e5d8de..105f3863 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -11,15 +11,19 @@ mod screen;
mod terminal_pane;
mod utils;
-use std::io::{Read, Write};
+use std::io::{self, Read, Write};
use std::os::unix::net::UnixStream;
use std::path::PathBuf;
use std::sync::mpsc::{channel, Receiver, Sender};
+use std::sync::{Arc, Mutex};
use std::thread;
use serde::{Deserialize, Serialize};
use structopt::StructOpt;
+use wasmer::{Exports, Function, Instance, Module, Store, Value};
+use wasmer_wasi::WasiState;
+
use crate::command_is_executing::CommandIsExecuting;
use crate::input::input_loop;
use crate::layout::Layout;
@@ -253,6 +257,108 @@ pub fn start(mut os_input: Box<dyn OsApi>, opts: Opt) {
.unwrap(),
);
+ // Here be dragons! This is very much a work in progress, and isn't quite functional
+ // yet. It's being left out of the tests because is slows them down massively (by
+ // recompiling a WASM module for every single test). Stay tuned for more updates!
+ #[cfg(not(test))]
+ active_threads.push(
+ thread::Builder::new()
+ .name("wasm".to_string())
+ .spawn(move || {
+ // TODO: Clone shared state here
+ move || -> Result<(), Box<dyn std::error::Error>> {
+ let store = Store::default();
+
+ println!("Compiling module...");
+ // FIXME: Switch to a higher performance compiler (`Store::default()`) and cache this on disk
+ // I could use `(de)serialize_to_file()` for that
+ let module = if let Ok(m) = Module::from_file(&store, "strider.wasm") {
+ m
+ } else {
+ return Ok(()); // Just abort this thread quietly if the WASM isn't found
+ };
+
+ // FIXME: Upstream the `Pipe` struct
+ //let output = fluff::Pipe::new();
+ //let input = fluff::Pipe::new();
+ let mut wasi_env = WasiState::new("mosaic")
+ .env("CLICOLOR_FORCE", "1")
+ .preopen(|p| {
+ p.directory(".") // TODO: Change this to a more meaningful dir
+ .alias(".")
+ .read(true)
+ .write(true)
+ .create(true)
+ })?
+ //.stdin(Box::new(input))
+ //.stdout(Box::new(output))
+ .finalize()?;
+
+ let mut import_object = wasi_env.import_object(&module)?;
+ // FIXME: Upstream an `ImportObject` merge method
+ let mut host_exports = Exports::new();
+ /* host_exports.insert(
+ "host_open_file",
+ Function::new_native_with_env(&store, Arc::clone(&wasi_env.state), host_open_file),
+ ); */
+ fn noop() {}
+ host_exports.insert("host_open_file", Function::new_native(&store, noop));
+ import_object.register("mosaic", host_exports);
+ let instance = Instance::new(&module, &import_object)?;
+
+ // WASI requires to explicitly set the memory for the `WasiEnv`
+ wasi_env.set_memory(instance.exports.get_memory("memory")?.clone());
+
+ let start = instance.exports.get_function("_start")?;
+ let handle_key = instance.exports.get_function("handle_key")?;
+ let draw = instance.exports.get_function("draw")?;
+
+ // This eventually calls the `.init()` method
+ start.call(&[])?;
+
+ loop {
+ break;
+ //let (cols, rows) = terminal::size()?;
+ //draw.call(&[Value::I32(rows as i32), Value::I32(cols as i32)])?;
+
+ // FIXME: This downcasting mess needs to be abstracted away
+ /* let mut state = wasi_env.state();
+ let wasi_file = state.fs.stdout_mut()?.as_mut().unwrap();
+ let output: &mut fluff::Pipe = wasi_file.downcast_mut().unwrap();
+ // Needed because raw mode doesn't implicitly return to the start of the line
+ write!(
+ io::stdout(),
+ "{}\n\r",
+ output.to_string().lines().collect::<Vec<_>>().join("\n\r")
+ )?;
+ output.clear();
+
+ let wasi_file = state.fs.stdin_mut()?.as_mut().unwrap();
+ let input: &mut fluff::Pipe = wasi_file.downcast_mut().unwrap();
+ input.clear(); */
+
+ /* match event::read()? {
+ Event::Key(KeyEvent {
+ code: KeyCode::Char('q'),
+ ..
+ }) => break,
+ Event::Key(e) => {
+ writeln!(input, "{}\r", serde_json::to_string(&e)?)?;
+ drop(state);
+ // Need to release the implicit `state` mutex or I deadlock!
+ handle_key.call(&[])?;
+ }
+ _ => (),
+ } */
+ }
+ debug_log_to_file("WASM module loaded and exited cleanly :)".to_string())?;
+ Ok(())
+ }()
+ .unwrap()
+ })
+ .unwrap(),
+ );
+
// TODO: currently we don't push this into active_threads
// because otherwise the app will hang. Need to fix this so it both
// listens to the ipc-bus and is able to quit cleanly