diff options
| author | Brooks Rady <b.j.rady@gmail.com> | 2020-11-26 10:36:27 +0000 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2020-11-26 10:36:27 +0000 |
| commit | 1586a705d2b36669ee4045b35377d8ddd591ccef (patch) | |
| tree | 5ceedf618ff09c25ff316fa9fae80fea2787fcd4 /src/main.rs | |
| parent | hotfix(logging): atomically create tmp folders (diff) | |
| parent | fix(tests): improve atomic data access (diff) | |
| download | sl0ppij-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.rs | 108 |
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 |
