diff --git a/Cargo.lock b/Cargo.lock index 9443d8a90..aa51a0630 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2195,7 +2195,7 @@ dependencies = [ "wasmer-runtime-core 0.11.0", "wasmer-singlepass-backend 0.11.0", "wasmer-wasi 0.11.0", - "wasmer-wasi-framebuffer 0.11.0", + "wasmer-wasi-experimental-io-devices 0.11.0", "wasmer-wasi-tests 0.11.0", ] @@ -2450,7 +2450,7 @@ dependencies = [ ] [[package]] -name = "wasmer-wasi-framebuffer" +name = "wasmer-wasi-experimental-io-devices" version = "0.11.0" dependencies = [ "minifb 0.13.0 (registry+https://github.com/rust-lang/crates.io-index)", diff --git a/Cargo.toml b/Cargo.toml index eb6019280..7bf93592f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -37,7 +37,7 @@ wasmer-dev-utils = { path = "lib/dev-utils", optional = true } wasmer-wasi-tests = { path = "lib/wasi-tests", optional = true } wasmer-middleware-common-tests = { path = "lib/middleware-common-tests", optional = true } wasmer-emscripten-tests = { path = "lib/emscripten-tests", optional = true } -wasmer-wasi-framebuffer = { path = "lib/wasi-framebuffer", optional = true } +wasmer-wasi-experimental-io-devices = { path = "lib/wasi-experimental-io-devices", optional = true } [workspace] members = [ @@ -57,7 +57,7 @@ members = [ "lib/kernel-loader", "lib/kernel-net", "lib/dev-utils", - "lib/wasi-framebuffer", + "lib/wasi-experimental-io-devices", "lib/wasi-tests", "lib/emscripten-tests", "lib/middleware-common-tests", @@ -103,7 +103,7 @@ backend-singlepass = [ "wasmer-middleware-common-tests/singlepass", ] wasi = ["wasmer-wasi"] -experimental-framebuffer = ["wasmer-wasi-framebuffer"] +experimental-io-devices = ["wasmer-wasi-experimental-io-devices"] managed = ["backend-singlepass", "wasmer-runtime-core/managed"] [[example]] diff --git a/lib/wasi-framebuffer/Cargo.toml b/lib/wasi-experimental-io-devices/Cargo.toml similarity index 89% rename from lib/wasi-framebuffer/Cargo.toml rename to lib/wasi-experimental-io-devices/Cargo.toml index bbce689d8..6d65df3dc 100644 --- a/lib/wasi-framebuffer/Cargo.toml +++ b/lib/wasi-experimental-io-devices/Cargo.toml @@ -1,5 +1,5 @@ [package] -name = "wasmer-wasi-framebuffer" +name = "wasmer-wasi-experimental-io-devices" version = "0.11.0" authors = ["The Wasmer Engineering Team "] edition = "2018" diff --git a/lib/wasi-framebuffer/README.md b/lib/wasi-experimental-io-devices/README.md similarity index 100% rename from lib/wasi-framebuffer/README.md rename to lib/wasi-experimental-io-devices/README.md diff --git a/lib/wasi-framebuffer/src/lib.rs b/lib/wasi-experimental-io-devices/src/lib.rs similarity index 94% rename from lib/wasi-framebuffer/src/lib.rs rename to lib/wasi-experimental-io-devices/src/lib.rs index 359fb9196..d713a18af 100644 --- a/lib/wasi-framebuffer/src/lib.rs +++ b/lib/wasi-experimental-io-devices/src/lib.rs @@ -1,7 +1,8 @@ use serde::{Deserialize, Serialize}; -use std::collections::{VecDeque, BTreeSet}; +use std::collections::{BTreeSet, VecDeque}; use std::convert::TryInto; use std::io::{Read, Seek, SeekFrom, Write}; +use wasmer_runtime_core::debug; use wasmer_wasi::{ state::{Fd, WasiFile, WasiFs, WasiFsError, ALL_RIGHTS, VIRTUAL_ROOT_FD}, types::*, @@ -20,8 +21,6 @@ std::thread_local! { ); } -use std::borrow::BorrowMut; - pub const MAX_X: u32 = 8192; pub const MAX_Y: u32 = 4320; @@ -163,27 +162,13 @@ impl FrameBufferState { } pub fn draw(&mut self) { - self.window.update_with_buffer(if self.front_buffer { - &self.data_1[..] - } else { - &self.data_2[..] - }, - ); - } - - pub fn get_buffer(&self) -> &[u32] { - if self.front_buffer { - &self.data_1[..] - } else { - &self.data_2[..] - } - } - pub fn get_buffer_mut(&mut self) -> &mut [u32] { - if self.front_buffer { - &mut self.data_1[..] - } else { - &mut self.data_2[..] - } + self.window + .update_with_buffer(if self.front_buffer { + &self.data_1[..] + } else { + &self.data_2[..] + }) + .expect("Internal error! Failed to draw to framebuffer"); } #[inline] @@ -485,7 +470,7 @@ pub fn initialize(fs: &mut WasiFs) -> Result<(), String> { .map_err(|e| format!("fb: Failed to create dev folder {:?}", e))? }; - let fd = fs + let _fd = fs .open_file_at( dev_fd, input_file, @@ -497,9 +482,9 @@ pub fn initialize(fs: &mut WasiFs) -> Result<(), String> { ) .map_err(|e| format!("fb: Failed to init framebuffer {:?}", e))?; - println!("Input open on fd {}", fd); + debug!("Input open on fd {}", _fd); - let fd = fs + let _fd = fs .open_file_at( dev_fd, frame_buffer_file, @@ -511,9 +496,9 @@ pub fn initialize(fs: &mut WasiFs) -> Result<(), String> { ) .map_err(|e| format!("fb: Failed to init framebuffer {:?}", e))?; - println!("Framebuffer open on fd {}", fd); + debug!("Framebuffer open on fd {}", _fd); - let fd = fs + let _fd = fs .open_file_at( fb_fd, resolution_file, @@ -525,9 +510,9 @@ pub fn initialize(fs: &mut WasiFs) -> Result<(), String> { ) .map_err(|e| format!("fb_resolution: Failed to init framebuffer {:?}", e))?; - println!("Framebuffer resolution open on fd {}", fd); + debug!("Framebuffer resolution open on fd {}", _fd); - let fd = fs + let _fd = fs .open_file_at( fb_fd, index_file, @@ -539,7 +524,7 @@ pub fn initialize(fs: &mut WasiFs) -> Result<(), String> { ) .map_err(|e| format!("fb_index_display: Failed to init framebuffer {:?}", e))?; - println!("Framebuffer draw open on fd {}", fd); + debug!("Framebuffer draw open on fd {}", _fd); Ok(()) } diff --git a/lib/wasi-framebuffer/src/util.rs b/lib/wasi-experimental-io-devices/src/util.rs similarity index 98% rename from lib/wasi-framebuffer/src/util.rs rename to lib/wasi-experimental-io-devices/src/util.rs index 0d4f18933..a3e4daf08 100644 --- a/lib/wasi-framebuffer/src/util.rs +++ b/lib/wasi-experimental-io-devices/src/util.rs @@ -37,8 +37,6 @@ pub fn bytes_for_input_event(input_event: InputEvent) -> (u8, [u8; 8], usize) { MouseButton::Right => MOUSE_PRESS_RIGHT, MouseButton::Middle => MOUSE_PRESS_MIDDLE, }; - dbg!(x); - dbg!(y); let x_bytes = x.to_le_bytes(); for i in 0..4 { data[i] = x_bytes[i]; @@ -144,7 +142,7 @@ pub fn map_key_to_bytes(key: Key) -> u8 { Key::NumPadMinus => 109, Key::NumPadDot => 110, Key::NumPadSlash => 111, - + Key::F1 => 112, Key::F2 => 113, Key::F3 => 114, @@ -160,7 +158,7 @@ pub fn map_key_to_bytes(key: Key) -> u8 { Key::NumLock => 144, Key::ScrollLock => 145, - + Key::Semicolon => 186, Key::Equal => 187, Key::Comma => 188, diff --git a/lib/wasi/src/lib.rs b/lib/wasi/src/lib.rs index 062ad0d4a..80c661bb7 100644 --- a/lib/wasi/src/lib.rs +++ b/lib/wasi/src/lib.rs @@ -54,97 +54,6 @@ pub fn generate_import_object( envs: Vec>, preopened_files: Vec, mapped_dirs: Vec<(String, PathBuf)>, -) -> ImportObject { - generate_import_object_for_version( - WasiVersion::Latest, - args, - envs, - preopened_files, - mapped_dirs, - ) -} - -pub fn generate_import_object_from_state( - wasi_state: WasiState, - _version: WasiVersion, -) -> ImportObject { - // THIS IS DEVELOPMENT CODE; DO NOT SHIP - let wasi_state_bytes = wasi_state.freeze().unwrap(); - let state_gen = move || { - fn state_destructor(data: *mut c_void) { - unsafe { - drop(std::rc::Rc::from_raw(data as *mut WasiState)); - } - } - - let wasi_state = Box::new(WasiState::unfreeze(&wasi_state_bytes).unwrap()); - dbg!(&wasi_state); - - ( - Box::into_raw(wasi_state) as *mut c_void, - state_destructor as fn(*mut c_void), - ) - }; - imports! { - // This generates the wasi state. - state_gen, - "wasi_unstable" => { - "args_get" => func!(args_get), - "args_sizes_get" => func!(args_sizes_get), - "clock_res_get" => func!(clock_res_get), - "clock_time_get" => func!(clock_time_get), - "environ_get" => func!(environ_get), - "environ_sizes_get" => func!(environ_sizes_get), - "fd_advise" => func!(fd_advise), - "fd_allocate" => func!(fd_allocate), - "fd_close" => func!(fd_close), - "fd_datasync" => func!(fd_datasync), - "fd_fdstat_get" => func!(fd_fdstat_get), - "fd_fdstat_set_flags" => func!(fd_fdstat_set_flags), - "fd_fdstat_set_rights" => func!(fd_fdstat_set_rights), - "fd_filestat_get" => func!(legacy::snapshot0::fd_filestat_get), - "fd_filestat_set_size" => func!(fd_filestat_set_size), - "fd_filestat_set_times" => func!(fd_filestat_set_times), - "fd_pread" => func!(fd_pread), - "fd_prestat_get" => func!(fd_prestat_get), - "fd_prestat_dir_name" => func!(fd_prestat_dir_name), - "fd_pwrite" => func!(fd_pwrite), - "fd_read" => func!(fd_read), - "fd_readdir" => func!(fd_readdir), - "fd_renumber" => func!(fd_renumber), - "fd_seek" => func!(legacy::snapshot0::fd_seek), - "fd_sync" => func!(fd_sync), - "fd_tell" => func!(fd_tell), - "fd_write" => func!(fd_write), - "path_create_directory" => func!(path_create_directory), - "path_filestat_get" => func!(legacy::snapshot0::path_filestat_get), - "path_filestat_set_times" => func!(path_filestat_set_times), - "path_link" => func!(path_link), - "path_open" => func!(path_open), - "path_readlink" => func!(path_readlink), - "path_remove_directory" => func!(path_remove_directory), - "path_rename" => func!(path_rename), - "path_symlink" => func!(path_symlink), - "path_unlink_file" => func!(path_unlink_file), - "poll_oneoff" => func!(legacy::snapshot0::poll_oneoff), - "proc_exit" => func!(proc_exit), - "proc_raise" => func!(proc_raise), - "random_get" => func!(random_get), - "sched_yield" => func!(sched_yield), - "sock_recv" => func!(sock_recv), - "sock_send" => func!(sock_send), - "sock_shutdown" => func!(sock_shutdown), - }, - } -} - -/* -pub fn generate_import_object_with_fs_setup( - args: Vec>, - envs: Vec>, - preopened_files: Vec, - mapped_dirs: Vec<(String, PathBuf)>, - setup_fs: Option Result<(), String> + Send>>, ) -> ImportObject { let state_gen = move || { // TODO: look into removing all these unnecessary clones @@ -155,12 +64,6 @@ pub fn generate_import_object_with_fs_setup( } let preopened_files = preopened_files.clone(); let mapped_dirs = mapped_dirs.clone(); - //let wasi_builder = create_wasi_instance(); - - let mut fs = WasiFs::new(&preopened_files, &mapped_dirs).unwrap(); - if let Some(sfn) = &setup_fs { - sfn(&mut fs).unwrap(); - } let state = Box::new(WasiState { fs: WasiFs::new(&preopened_files, &mapped_dirs).expect("Could not create WASI FS"), @@ -173,58 +76,41 @@ pub fn generate_import_object_with_fs_setup( state_destructor as fn(*mut c_void), ) }; - imports! { - // This generates the wasi state. - state_gen, - "wasi_snapshot_preview1" => { - "args_get" => func!(args_get), - "args_sizes_get" => func!(args_sizes_get), - "clock_res_get" => func!(clock_res_get), - "clock_time_get" => func!(clock_time_get), - "environ_get" => func!(environ_get), - "environ_sizes_get" => func!(environ_sizes_get), - "fd_advise" => func!(fd_advise), - "fd_allocate" => func!(fd_allocate), - "fd_close" => func!(fd_close), - "fd_datasync" => func!(fd_datasync), - "fd_fdstat_get" => func!(fd_fdstat_get), - "fd_fdstat_set_flags" => func!(fd_fdstat_set_flags), - "fd_fdstat_set_rights" => func!(fd_fdstat_set_rights), - "fd_filestat_get" => func!(fd_filestat_get), - "fd_filestat_set_size" => func!(fd_filestat_set_size), - "fd_filestat_set_times" => func!(fd_filestat_set_times), - "fd_pread" => func!(fd_pread), - "fd_prestat_get" => func!(fd_prestat_get), - "fd_prestat_dir_name" => func!(fd_prestat_dir_name), - "fd_pwrite" => func!(fd_pwrite), - "fd_read" => func!(fd_read), - "fd_readdir" => func!(fd_readdir), - "fd_renumber" => func!(fd_renumber), - "fd_seek" => func!(fd_seek), - "fd_sync" => func!(fd_sync), - "fd_tell" => func!(fd_tell), - "fd_write" => func!(fd_write), - "path_create_directory" => func!(path_create_directory), - "path_filestat_get" => func!(path_filestat_get), - "path_filestat_set_times" => func!(path_filestat_set_times), - "path_link" => func!(path_link), - "path_open" => func!(path_open), - "path_readlink" => func!(path_readlink), - "path_remove_directory" => func!(path_remove_directory), - "path_rename" => func!(path_rename), - "path_symlink" => func!(path_symlink), - "path_unlink_file" => func!(path_unlink_file), - "poll_oneoff" => func!(poll_oneoff), - "proc_exit" => func!(proc_exit), - "proc_raise" => func!(proc_raise), - "random_get" => func!(random_get), - "sched_yield" => func!(sched_yield), - "sock_recv" => func!(sock_recv), - "sock_send" => func!(sock_send), - "sock_shutdown" => func!(sock_shutdown), - }, + + generate_import_object_snapshot1_inner(state_gen) +} + +/// Create an [`ImportObject`] with an existing [`WasiState`]. [`WasiState`] +/// can be constructed from a [`WasiStateBuilder`]. +pub fn generate_import_object_from_state( + wasi_state: WasiState, + version: WasiVersion, +) -> ImportObject { + // HACK(mark): this is really quite nasty and inefficient, a proper fix will + // require substantial changes to the internals of the WasiFS + // copy WasiState by serializing and deserializing + let wasi_state_bytes = wasi_state.freeze().unwrap(); + let state_gen = move || { + fn state_destructor(data: *mut c_void) { + unsafe { + drop(Box::from_raw(data as *mut WasiState)); + } + } + + let wasi_state = Box::new(WasiState::unfreeze(&wasi_state_bytes).unwrap()); + + ( + Box::into_raw(wasi_state) as *mut c_void, + state_destructor as fn(*mut c_void), + ) + }; + match version { + WasiVersion::Snapshot0 => generate_import_object_snapshot0_inner(state_gen), + WasiVersion::Snapshot1 | WasiVersion::Latest => { + generate_import_object_snapshot1_inner(state_gen) + } } -}*/ +} /// Creates a Wasi [`ImportObject`] with [`WasiState`] for the given [`WasiVersion`]. pub fn generate_import_object_for_version( @@ -273,8 +159,15 @@ fn generate_import_object_snapshot0( state_destructor as fn(*mut c_void), ) }; + generate_import_object_snapshot0_inner(state_gen) +} + +/// Combines a state generating function with the import list for legacy WASI +fn generate_import_object_snapshot0_inner(state_gen: F) -> ImportObject +where + F: Fn() -> (*mut c_void, fn(*mut c_void)) + Send + Sync + 'static, +{ imports! { - // This generates the wasi state. state_gen, "wasi_unstable" => { "args_get" => func!(args_get), @@ -325,3 +218,60 @@ fn generate_import_object_snapshot0( }, } } + +/// Combines a state generating function with the import list for snapshot 1 +fn generate_import_object_snapshot1_inner(state_gen: F) -> ImportObject +where + F: Fn() -> (*mut c_void, fn(*mut c_void)) + Send + Sync + 'static, +{ + imports! { + state_gen, + "wasi_snapshot_preview1" => { + "args_get" => func!(args_get), + "args_sizes_get" => func!(args_sizes_get), + "clock_res_get" => func!(clock_res_get), + "clock_time_get" => func!(clock_time_get), + "environ_get" => func!(environ_get), + "environ_sizes_get" => func!(environ_sizes_get), + "fd_advise" => func!(fd_advise), + "fd_allocate" => func!(fd_allocate), + "fd_close" => func!(fd_close), + "fd_datasync" => func!(fd_datasync), + "fd_fdstat_get" => func!(fd_fdstat_get), + "fd_fdstat_set_flags" => func!(fd_fdstat_set_flags), + "fd_fdstat_set_rights" => func!(fd_fdstat_set_rights), + "fd_filestat_get" => func!(fd_filestat_get), + "fd_filestat_set_size" => func!(fd_filestat_set_size), + "fd_filestat_set_times" => func!(fd_filestat_set_times), + "fd_pread" => func!(fd_pread), + "fd_prestat_get" => func!(fd_prestat_get), + "fd_prestat_dir_name" => func!(fd_prestat_dir_name), + "fd_pwrite" => func!(fd_pwrite), + "fd_read" => func!(fd_read), + "fd_readdir" => func!(fd_readdir), + "fd_renumber" => func!(fd_renumber), + "fd_seek" => func!(fd_seek), + "fd_sync" => func!(fd_sync), + "fd_tell" => func!(fd_tell), + "fd_write" => func!(fd_write), + "path_create_directory" => func!(path_create_directory), + "path_filestat_get" => func!(path_filestat_get), + "path_filestat_set_times" => func!(path_filestat_set_times), + "path_link" => func!(path_link), + "path_open" => func!(path_open), + "path_readlink" => func!(path_readlink), + "path_remove_directory" => func!(path_remove_directory), + "path_rename" => func!(path_rename), + "path_symlink" => func!(path_symlink), + "path_unlink_file" => func!(path_unlink_file), + "poll_oneoff" => func!(poll_oneoff), + "proc_exit" => func!(proc_exit), + "proc_raise" => func!(proc_raise), + "random_get" => func!(random_get), + "sched_yield" => func!(sched_yield), + "sock_recv" => func!(sock_recv), + "sock_send" => func!(sock_send), + "sock_shutdown" => func!(sock_shutdown), + }, + } +} diff --git a/src/bin/wasmer.rs b/src/bin/wasmer.rs index d5a9b0865..906288c33 100644 --- a/src/bin/wasmer.rs +++ b/src/bin/wasmer.rs @@ -225,9 +225,10 @@ struct Run { #[structopt(flatten)] features: PrestandardFeatures, - #[cfg(feature = "experimental-framebuffer")] - #[structopt(long = "enable-experimental-framebuffer")] - enable_experimental_framebuffer: bool, + /// Enable non-standard experimental IO devices + #[cfg(feature = "experimental-io-devices")] + #[structopt(long = "enable-experimental-io-devices", hidden = true)] + enable_experimental_io_devices: bool, /// Application arguments #[structopt(name = "--", multiple = true)] @@ -379,10 +380,12 @@ fn execute_wasi( .preopen_dirs(preopened_files) .map_dirs(mapped_dirs); - #[cfg(feature = "experimental-framebuffer")] + #[cfg(feature = "experimental-io-devices")] { - if options.enable_experimental_framebuffer { - wasi_state_builder.setup_fs(std::rc::Rc::new(wasmer_wasi_framebuffer::initialize)); + if options.enable_experimental_io_devices { + wasi_state_builder.setup_fs(std::rc::Rc::new( + wasmer_wasi_experimental_io_devices::initialize, + )); } } let wasi_state = wasi_state_builder.build().map_err(|e| format!("{:?}", e))?;