Rename to experimental-io-devices and clean up for release

This commit is contained in:
Mark McCaskey
2019-12-18 14:10:54 -05:00
parent efaae9f12f
commit 4539ef44d0
8 changed files with 133 additions and 197 deletions

4
Cargo.lock generated
View File

@ -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)",

View File

@ -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]]

View File

@ -1,5 +1,5 @@
[package]
name = "wasmer-wasi-framebuffer"
name = "wasmer-wasi-experimental-io-devices"
version = "0.11.0"
authors = ["The Wasmer Engineering Team <engineering@wasmer.io>"]
edition = "2018"

View File

@ -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.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[..]
}
})
.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(())
}

View File

@ -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];

View File

@ -55,38 +55,119 @@ pub fn generate_import_object(
preopened_files: Vec<PathBuf>,
mapped_dirs: Vec<(String, PathBuf)>,
) -> ImportObject {
generate_import_object_for_version(
WasiVersion::Latest,
args,
envs,
preopened_files,
mapped_dirs,
let state_gen = move || {
// TODO: look into removing all these unnecessary clones
fn state_destructor(data: *mut c_void) {
unsafe {
drop(Box::from_raw(data as *mut WasiState));
}
}
let preopened_files = preopened_files.clone();
let mapped_dirs = mapped_dirs.clone();
let state = Box::new(WasiState {
fs: WasiFs::new(&preopened_files, &mapped_dirs).expect("Could not create WASI FS"),
args: args.clone(),
envs: envs.clone(),
});
(
Box::into_raw(state) as *mut c_void,
state_destructor as fn(*mut c_void),
)
};
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,
version: WasiVersion,
) -> ImportObject {
// THIS IS DEVELOPMENT CODE; DO NOT SHIP
// 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(std::rc::Rc::from_raw(data as *mut WasiState));
drop(Box::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),
)
};
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(
version: WasiVersion,
args: Vec<Vec<u8>>,
envs: Vec<Vec<u8>>,
preopened_files: Vec<PathBuf>,
mapped_dirs: Vec<(String, PathBuf)>,
) -> ImportObject {
match version {
WasiVersion::Snapshot0 => {
generate_import_object_snapshot0(args, envs, preopened_files, mapped_dirs)
}
WasiVersion::Snapshot1 | WasiVersion::Latest => {
generate_import_object(args, envs, preopened_files, mapped_dirs)
}
}
}
/// Creates a legacy Wasi [`ImportObject`] with [`WasiState`].
fn generate_import_object_snapshot0(
args: Vec<Vec<u8>>,
envs: Vec<Vec<u8>>,
preopened_files: Vec<PathBuf>,
mapped_dirs: Vec<(String, PathBuf)>,
) -> ImportObject {
let state_gen = move || {
// TODO: look into removing all these unnecessary clones
fn state_destructor(data: *mut c_void) {
unsafe {
drop(Box::from_raw(data as *mut WasiState));
}
}
let preopened_files = preopened_files.clone();
let mapped_dirs = mapped_dirs.clone();
//let wasi_builder = create_wasi_instance();
let state = Box::new(WasiState {
fs: WasiFs::new(&preopened_files, &mapped_dirs).expect("Could not create WASI FS"),
args: args.clone(),
envs: envs.clone(),
});
(
Box::into_raw(state) as *mut c_void,
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<F>(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),
@ -138,43 +219,12 @@ pub fn generate_import_object_from_state(
}
}
/*
pub fn generate_import_object_with_fs_setup(
args: Vec<Vec<u8>>,
envs: Vec<Vec<u8>>,
preopened_files: Vec<PathBuf>,
mapped_dirs: Vec<(String, PathBuf)>,
setup_fs: Option<Arc<dyn Fn(&mut WasiFs) -> Result<(), String> + Send>>,
) -> ImportObject {
let state_gen = move || {
// TODO: look into removing all these unnecessary clones
fn state_destructor(data: *mut c_void) {
unsafe {
drop(Box::from_raw(data as *mut WasiState));
}
}
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"),
args: args.clone(),
envs: envs.clone(),
});
(
Box::into_raw(state) as *mut c_void,
state_destructor as fn(*mut c_void),
)
};
/// Combines a state generating function with the import list for snapshot 1
fn generate_import_object_snapshot1_inner<F>(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_snapshot_preview1" => {
"args_get" => func!(args_get),
@ -224,104 +274,4 @@ pub fn generate_import_object_with_fs_setup(
"sock_shutdown" => func!(sock_shutdown),
},
}
}*/
/// Creates a Wasi [`ImportObject`] with [`WasiState`] for the given [`WasiVersion`].
pub fn generate_import_object_for_version(
version: WasiVersion,
args: Vec<Vec<u8>>,
envs: Vec<Vec<u8>>,
preopened_files: Vec<PathBuf>,
mapped_dirs: Vec<(String, PathBuf)>,
) -> ImportObject {
match version {
WasiVersion::Snapshot0 => {
generate_import_object_snapshot0(args, envs, preopened_files, mapped_dirs)
}
WasiVersion::Snapshot1 | WasiVersion::Latest => {
generate_import_object(args, envs, preopened_files, mapped_dirs)
}
}
}
/// Creates a legacy Wasi [`ImportObject`] with [`WasiState`].
fn generate_import_object_snapshot0(
args: Vec<Vec<u8>>,
envs: Vec<Vec<u8>>,
preopened_files: Vec<PathBuf>,
mapped_dirs: Vec<(String, PathBuf)>,
) -> ImportObject {
let state_gen = move || {
// TODO: look into removing all these unnecessary clones
fn state_destructor(data: *mut c_void) {
unsafe {
drop(Box::from_raw(data as *mut WasiState));
}
}
let preopened_files = preopened_files.clone();
let mapped_dirs = mapped_dirs.clone();
//let wasi_builder = create_wasi_instance();
let state = Box::new(WasiState {
fs: WasiFs::new(&preopened_files, &mapped_dirs).expect("Could not create WASI FS"),
args: args.clone(),
envs: envs.clone(),
});
(
Box::into_raw(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),
},
}
}

View File

@ -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))?;