From 58a2fc1656f73c41c98d9bf1319357c7b57d8b63 Mon Sep 17 00:00:00 2001 From: Brooks J Rady Date: Thu, 7 Jan 2021 15:23:54 +0000 Subject: [PATCH] Finished plugin system! (Added file opening) --- Cargo.lock | 44 ++++++++++++++++++++++---------------------- Cargo.toml | 4 ++-- src/main.rs | 21 +++++++++++++++------ src/wasm_vm.rs | 37 +++++++++++++++++++------------------ 4 files changed, 58 insertions(+), 48 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index e887b40d..a8656836 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1743,9 +1743,9 @@ checksum = "93b162580e34310e5931c4b792560108b10fd14d64915d7fff8ff00180e70092" [[package]] name = "wasmer" -version = "1.0.0-rc1" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ffe7fb8734c3e522aea0bed12315115e4c5d684c3d312db5f3ef6a8a312b1b47" +checksum = "94b1ece7c894857344ae93506686ae36ccd867b4ed55819c06d2316d009098d4" dependencies = [ "cfg-if 0.1.10", "indexmap", @@ -1766,9 +1766,9 @@ dependencies = [ [[package]] name = "wasmer-compiler" -version = "1.0.0-rc1" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97789fdc5968ea3d29528648dc2422e0c795ca195b88a59c30a56f0e52805690" +checksum = "fc85134b257e5fba5870693441e300b601d08f18833ac4fa6934f0b72afc56d2" dependencies = [ "enumset", "raw-cpuid", @@ -1784,9 +1784,9 @@ dependencies = [ [[package]] name = "wasmer-compiler-cranelift" -version = "1.0.0-rc1" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e80c86796019ef6d4519e1a66f2b99ab73b937a4e43e723772956b3e8c8df23" +checksum = "60d68fb05dbe908724901b680070560944d99d04c52c763e98124aa988ac6dd0" dependencies = [ "cranelift-codegen", "cranelift-frontend", @@ -1803,9 +1803,9 @@ dependencies = [ [[package]] name = "wasmer-derive" -version = "1.0.0-rc1" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c74a84dc4ba0d60e9419f335734fa807097caf4938b2b44bc0703688a42b467" +checksum = "ca24205ffdf2d3b1a9c01219f4f3f0a1382658680abe73bc5b146f941adeeb8e" dependencies = [ "proc-macro-error", "proc-macro2", @@ -1815,9 +1815,9 @@ dependencies = [ [[package]] name = "wasmer-engine" -version = "1.0.0-rc1" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e787fb8e42b5ad32c1c8dcf105e42d2919dfb3ea4b8e286de3e43f306ae1457b" +checksum = "d91ed16436a9813d92f434e1d40fdf91b45ca30f351a799f793015359acca86b" dependencies = [ "backtrace", "bincode", @@ -1836,9 +1836,9 @@ dependencies = [ [[package]] name = "wasmer-engine-jit" -version = "1.0.0-rc1" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "552f4252f8d7984279c55df0970ca1d42b1e4c63d918e7af1cd004e427e5008c" +checksum = "df1e3ca5e34eacd4ab6d9d32edd41b51d2e39cf3d75453611c9c57cee3a64691" dependencies = [ "bincode", "cfg-if 0.1.10", @@ -1854,9 +1854,9 @@ dependencies = [ [[package]] name = "wasmer-engine-native" -version = "1.0.0-rc1" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5264031a9b398a071fa128fe89fb55bc75f9c0ac5eaa7f1f9ef9efcee08afa1c" +checksum = "6a21d6c5ae0c384ba2f01f598c95b01d4da2eaec3376fb96de2ded38c54143a0" dependencies = [ "bincode", "cfg-if 0.1.10", @@ -1875,9 +1875,9 @@ dependencies = [ [[package]] name = "wasmer-object" -version = "1.0.0-rc1" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e22ccf03052d73b3588bd30de94db9ee949957a543d0c317122f2b87b7d1f309" +checksum = "06e007e73ec7775aecc61045092dabfcff1e9f228129cd129e76a3e6aae26454" dependencies = [ "object", "thiserror", @@ -1887,9 +1887,9 @@ dependencies = [ [[package]] name = "wasmer-types" -version = "1.0.0-rc1" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c3ea5b135db86baf39ce45f6cf98cc97d6e4234d3f75ac56a026f94bd8b68b1" +checksum = "2dbba7a95edb61b40daa43079979fc3212234e1645a15b8c527c36decad59fc6" dependencies = [ "cranelift-entity", "serde", @@ -1898,9 +1898,9 @@ dependencies = [ [[package]] name = "wasmer-vm" -version = "1.0.0-rc1" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88d766b8db150b7e524c83b244e14a1180bf919b4f8bea6f063bae9a8e8d4156" +checksum = "9cd9acd4d53c004a11fcaff17f2a2528ae8f1748c6d5c4aea7d8bed2d9236f0f" dependencies = [ "backtrace", "cc", @@ -1918,9 +1918,9 @@ dependencies = [ [[package]] name = "wasmer-wasi" -version = "1.0.0-rc1" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28b9e383c0a20fb697080b8e87613a0bb2e901a9f06ca710030b4a521ebcc398" +checksum = "5de224b58d5813a37dce64c483347909c478c5c2dcb15a93d67cfe6a863fd92c" dependencies = [ "bincode", "byteorder", diff --git a/Cargo.toml b/Cargo.toml index a231a45b..e0f7e347 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -23,8 +23,8 @@ termios = "0.3" unicode-truncate = "0.1.1" unicode-width = "0.1.8" vte = "0.8.0" -wasmer = "1.0.0-rc" -wasmer-wasi = "1.0.0-rc" +wasmer = "1.0.0" +wasmer-wasi = "1.0.0" [dependencies.async-std] version = "1.3.0" diff --git a/src/main.rs b/src/main.rs index 3d358399..96809688 100644 --- a/src/main.rs +++ b/src/main.rs @@ -27,6 +27,7 @@ use panes::PaneId; use serde::{Deserialize, Serialize}; use structopt::StructOpt; use termion::input::TermRead; +use wasm_vm::PluginEnv; use wasmer::{ChainableNamedResolver, Instance, Module, Store, Value}; use wasmer_wasi::{Pipe, WasiState}; @@ -408,6 +409,7 @@ pub fn start(mut os_input: Box, opts: Opt) { thread::Builder::new() .name("wasm".to_string()) .spawn({ + let mut send_pty_instructions = send_pty_instructions.clone(); let mut send_screen_instructions = send_screen_instructions.clone(); move || { @@ -422,6 +424,7 @@ pub fn start(mut os_input: Box, opts: Opt) { .expect("failed to receive event on channel"); err_ctx.add_call(ContextType::Plugin(PluginContext::from(&event))); send_screen_instructions.update(err_ctx); + send_pty_instructions.update(err_ctx); match event { PluginInstruction::Load(pid_tx, path) => { // FIXME: Cache this compiled module on disk. I could use `(de)serialize_to_file()` for that @@ -445,7 +448,13 @@ pub fn start(mut os_input: Box, opts: Opt) { .unwrap(); let wasi = wasi_env.import_object(&module).unwrap(); - let mosaic = mosaic_imports(&store, &wasi_env); + + let plugin_env = PluginEnv { + send_pty_instructions: send_pty_instructions.clone(), + wasi_env, + }; + + let mosaic = mosaic_imports(&store, &plugin_env); let instance = Instance::new(&module, &mosaic.chain_back(wasi)).unwrap(); @@ -454,29 +463,29 @@ pub fn start(mut os_input: Box, opts: Opt) { // This eventually calls the `.init()` method start.call(&[]).unwrap(); - plugin_map.insert(plugin_id, (instance, wasi_env)); + plugin_map.insert(plugin_id, (instance, plugin_env)); pid_tx.send(plugin_id).unwrap(); plugin_id += 1; } PluginInstruction::Draw(buf_tx, pid, rows, cols) => { - let (instance, wasi_env) = plugin_map.get(&pid).unwrap(); + let (instance, plugin_env) = plugin_map.get(&pid).unwrap(); let draw = instance.exports.get_function("draw").unwrap(); draw.call(&[Value::I32(rows as i32), Value::I32(cols as i32)]) .unwrap(); - buf_tx.send(wasi_stdout(&wasi_env)).unwrap(); + buf_tx.send(wasi_stdout(&plugin_env.wasi_env)).unwrap(); } PluginInstruction::Input(pid, input_bytes) => { - let (instance, wasi_env) = plugin_map.get(&pid).unwrap(); + let (instance, plugin_env) = plugin_map.get(&pid).unwrap(); let handle_key = instance.exports.get_function("handle_key").unwrap(); for key in input_bytes.keys() { if let Ok(key) = key { wasi_write_string( - wasi_env, + &plugin_env.wasi_env, &serde_json::to_string(&key).unwrap(), ); handle_key.call(&[]).unwrap(); diff --git a/src/wasm_vm.rs b/src/wasm_vm.rs index 6d2d4a19..51bd9375 100644 --- a/src/wasm_vm.rs +++ b/src/wasm_vm.rs @@ -1,11 +1,9 @@ -use std::{ - path::PathBuf, - process::{Command, Stdio}, - sync::mpsc::Sender, -}; -use wasmer::{imports, Function, ImportObject, Store}; +use std::{path::PathBuf, sync::mpsc::Sender}; +use wasmer::{imports, Function, ImportObject, Store, WasmerEnv}; use wasmer_wasi::WasiEnv; +use crate::{pty_bus::PtyInstruction, SenderWithContext}; + #[derive(Clone, Debug)] pub enum PluginInstruction { Load(Sender, PathBuf), @@ -15,29 +13,32 @@ pub enum PluginInstruction { Quit, } -// Plugin API ----------------------------------------------------------------- +#[derive(WasmerEnv, Clone)] +pub struct PluginEnv { + pub send_pty_instructions: SenderWithContext, // FIXME: This should be a big bundle of all of the channels + pub wasi_env: WasiEnv, +} -pub fn mosaic_imports(store: &Store, wasi_env: &WasiEnv) -> ImportObject { +// Plugin API --------------------------------------------------------------------------------------------------------- + +pub fn mosaic_imports(store: &Store, plugin_env: &PluginEnv) -> ImportObject { imports! { "mosaic" => { - "host_open_file" => Function::new_native_with_env(store, wasi_env.clone(), host_open_file) + "host_open_file" => Function::new_native_with_env(store, plugin_env.clone(), host_open_file) } } } // FIXME: Bundle up all of the channels! Pair that with WasiEnv? -fn host_open_file(wasi_env: &WasiEnv) { - Command::new("xdg-open") - .arg(format!( - "./{}", - wasi_stdout(wasi_env).lines().next().unwrap() - )) - .stderr(Stdio::null()) - .spawn() +fn host_open_file(plugin_env: &PluginEnv) { + let path = PathBuf::from(wasi_stdout(&plugin_env.wasi_env).lines().next().unwrap()); + plugin_env + .send_pty_instructions + .send(PtyInstruction::SpawnTerminal(Some(path))) .unwrap(); } -// Helper Functions ----------------------------------------------------------- +// Helper Functions --------------------------------------------------------------------------------------------------- // FIXME: Unwrap city pub fn wasi_stdout(wasi_env: &WasiEnv) -> String {