diff --git a/lib/api/src/js/export.rs b/lib/api/src/js/export.rs index 94a887a93..685bb3f2d 100644 --- a/lib/api/src/js/export.rs +++ b/lib/api/src/js/export.rs @@ -1,15 +1,18 @@ use crate::js::error::WasmError; use crate::js::store::{AsStoreMut, AsStoreRef, InternalStoreHandle}; use crate::js::wasm_bindgen_polyfill::Global; +use crate::MemoryView; use js_sys::Function; use js_sys::WebAssembly::{Memory, Table}; use serde::{Deserialize, Serialize}; use std::fmt; -use wasm_bindgen::{JsCast, JsValue}; -use wasmer_types::{ExternType, FunctionType, GlobalType, MemoryType, TableType, Pages, WASM_PAGE_SIZE, StoreSnapshot}; -use crate::MemoryView; -#[cfg(feature="tracing")] +#[cfg(feature = "tracing")] use tracing::trace; +use wasm_bindgen::{JsCast, JsValue}; +use wasmer_types::{ + ExternType, FunctionType, GlobalType, MemoryType, Pages, StoreSnapshot, TableType, + WASM_PAGE_SIZE, +}; pub use wasmer_types::MemoryError; @@ -44,7 +47,7 @@ impl VMMemory { pub fn fork(&self) -> Result { let new_memory = crate::Memory::new_internal(self.ty.clone())?; - #[cfg(feature="tracing")] + #[cfg(feature = "tracing")] trace!("memory copy started"); let src = MemoryView::new_raw(&self.memory); @@ -56,7 +59,8 @@ impl VMMemory { let delta = amount - dst_size; let pages = ((delta - 1) / WASM_PAGE_SIZE) + 1; - let our_js_memory: &crate::js::externals::memory::JSMemory = JsCast::unchecked_from_js_ref(&new_memory); + let our_js_memory: &crate::js::externals::memory::JSMemory = + JsCast::unchecked_from_js_ref(&new_memory); our_js_memory.grow(pages as u32).map_err(|err| { if err.is_instance_of::() { let cur_pages = dst_size; @@ -72,20 +76,17 @@ impl VMMemory { dst = MemoryView::new_raw(&new_memory); } - src.copy_to_memory(amount as u64, &dst) - .map_err(|err| { - wasmer_types::MemoryError::Generic(format!("failed to copy the memory - {}", err)) - })?; + src.copy_to_memory(amount as u64, &dst).map_err(|err| { + wasmer_types::MemoryError::Generic(format!("failed to copy the memory - {}", err)) + })?; - #[cfg(feature="tracing")] + #[cfg(feature = "tracing")] trace!("memory copy finished (size={})", dst.size().bytes().0); - Ok( - Self { - memory: new_memory, - ty: self.ty.clone(), - } - ) + Ok(Self { + memory: new_memory, + ty: self.ty.clone(), + }) } } @@ -103,9 +104,7 @@ impl VMGlobal { /// Saves the global value into the snapshot pub fn save_snapshot(&self, index: usize, snapshot: &mut StoreSnapshot) { if let Some(val) = self.global.as_f64() { - let entry = snapshot.globals - .entry(index as u32) - .or_default(); + let entry = snapshot.globals.entry(index as u32).or_default(); *entry = val as u128; } } diff --git a/lib/api/src/js/externals/function.rs b/lib/api/src/js/externals/function.rs index d75427704..92f1388dd 100644 --- a/lib/api/src/js/externals/function.rs +++ b/lib/api/src/js/externals/function.rs @@ -61,13 +61,9 @@ pub struct Function { pub(crate) handle: StoreHandle, } -impl Into -for StoreHandle -{ +impl Into for StoreHandle { fn into(self) -> Function { - Function { - handle: self - } + Function { handle: self } } } @@ -405,7 +401,10 @@ impl Function { ) -> Result, RuntimeError> { #[allow(unused_unsafe)] let params: Vec<_> = unsafe { - params.iter().map(|a| a.as_raw_value(&store.as_store_ref())).collect() + params + .iter() + .map(|a| a.as_raw_value(&store.as_store_ref())) + .collect() }; let arr = js_sys::Array::new_with_length(params.len() as u32); @@ -428,10 +427,16 @@ impl Function { let store_mut = store.as_store_mut(); if let Some(callback) = store_mut.inner.on_called.take() { match callback(store_mut) { - Ok(wasmer_types::OnCalledAction::InvokeAgain) => { continue; } - Ok(wasmer_types::OnCalledAction::Finish) => { break; } - Ok(wasmer_types::OnCalledAction::Trap(trap)) => { return Err(RuntimeError::user(trap)) }, - Err(trap) => { return Err(RuntimeError::user(trap)) }, + Ok(wasmer_types::OnCalledAction::InvokeAgain) => { + continue; + } + Ok(wasmer_types::OnCalledAction::Finish) => { + break; + } + Ok(wasmer_types::OnCalledAction::Trap(trap)) => { + return Err(RuntimeError::user(trap)) + } + Err(trap) => return Err(RuntimeError::user(trap)), } } break; @@ -1458,4 +1463,4 @@ mod inner { } } */ -} \ No newline at end of file +} diff --git a/lib/api/src/js/externals/memory.rs b/lib/api/src/js/externals/memory.rs index a9e860e00..0dba4bcbe 100644 --- a/lib/api/src/js/externals/memory.rs +++ b/lib/api/src/js/externals/memory.rs @@ -101,13 +101,15 @@ impl Memory { let js_memory = js_sys::WebAssembly::Memory::new(&descriptor) .map_err(|_e| MemoryError::Generic("Error while creating the memory".to_owned()))?; - Ok( - js_memory - ) + Ok(js_memory) } /// Creates a new host `Memory` from provided JavaScript memory. - pub fn new_raw(store: &mut impl AsStoreMut, js_memory: js_sys::WebAssembly::Memory, ty: MemoryType) -> Result { + pub fn new_raw( + store: &mut impl AsStoreMut, + js_memory: js_sys::WebAssembly::Memory, + ty: MemoryType, + ) -> Result { let vm_memory = VMMemory::new(js_memory, ty); Ok(Self::from_vm_export(store, vm_memory)) } @@ -199,8 +201,7 @@ impl Memory { &self, store: &impl AsStoreRef, new_store: &mut impl AsStoreMut, - ) -> Result - { + ) -> Result { // Create the new memory using the parameters of the existing memory let view = self.view(store); let ty = self.ty(store); @@ -218,9 +219,7 @@ impl Memory { // Copy the bytes view.copy_to_memory(amount as u64, &new_view) - .map_err(|err| { - MemoryError::Generic(err.to_string()) - })?; + .map_err(|err| MemoryError::Generic(err.to_string()))?; // Return the new memory Ok(new_memory) diff --git a/lib/api/src/js/externals/memory_view.rs b/lib/api/src/js/externals/memory_view.rs index 782775280..d4eb10e44 100644 --- a/lib/api/src/js/externals/memory_view.rs +++ b/lib/api/src/js/externals/memory_view.rs @@ -27,9 +27,7 @@ pub struct MemoryView<'a> { impl<'a> MemoryView<'a> { pub(crate) fn new(memory: &Memory, store: &impl AsStoreRef) -> Self { - let memory = memory - .handle - .get(store.as_store_ref().objects()); + let memory = memory.handle.get(store.as_store_ref().objects()); Self::new_raw(&memory.memory) } @@ -279,7 +277,7 @@ impl<'a> MemoryView<'a> { self.read(offset, &mut chunk[..sublen])?; new_memory.write(offset, &chunk[..sublen])?; - + offset += sublen as u64; } Ok(()) diff --git a/lib/api/src/js/imports.rs b/lib/api/src/js/imports.rs index a227aa1ab..4ac8dd47a 100644 --- a/lib/api/src/js/imports.rs +++ b/lib/api/src/js/imports.rs @@ -184,27 +184,23 @@ impl Imports { } pub struct ImportsIterator<'a> { - iter: std::collections::hash_map::Iter<'a, (String, String), Extern> + iter: std::collections::hash_map::Iter<'a, (String, String), Extern>, } -impl<'a> ImportsIterator<'a> -{ +impl<'a> ImportsIterator<'a> { fn new(imports: &'a Imports) -> Self { let iter = imports.map.iter(); Self { iter } } } -impl<'a> Iterator -for ImportsIterator<'a> { +impl<'a> Iterator for ImportsIterator<'a> { type Item = (&'a str, &'a str, &'a Extern); fn next(&mut self) -> Option { self.iter .next() - .map(|(k, v)| { - (k.0.as_str(), k.1.as_str(), v) - }) + .map(|(k, v)| (k.0.as_str(), k.1.as_str(), v)) } } diff --git a/lib/api/src/js/instance.rs b/lib/api/src/js/instance.rs index 68b94651a..a10196e3c 100644 --- a/lib/api/src/js/instance.rs +++ b/lib/api/src/js/instance.rs @@ -127,7 +127,11 @@ impl Instance { // If the memory is imported then also export it for backwards compatibility reasons // (many will assume the memory is always exported) - later we can remove this if exports.get_memory("memory").is_err() { - if let Some(memory) = externs.iter().filter(|a| a.ty(store).memory().is_some()).next() { + if let Some(memory) = externs + .iter() + .filter(|a| a.ty(store).memory().is_some()) + .next() + { exports.insert("memory", memory.clone()); } } diff --git a/lib/api/src/js/mod.rs b/lib/api/src/js/mod.rs index c5ef7947d..186892a06 100644 --- a/lib/api/src/js/mod.rs +++ b/lib/api/src/js/mod.rs @@ -73,14 +73,14 @@ pub use crate::js::value::Value as Val; pub mod vm { //! The `vm` module re-exports wasmer-vm types. - + pub use crate::js::export::VMMemory; } pub use wasmer_types::is_wasm; pub use wasmer_types::{ - Bytes, ExportIndex, GlobalInit, LocalFunctionIndex, Pages, ValueType, WASM_MAX_PAGES, - WASM_MIN_PAGES, WASM_PAGE_SIZE, OnCalledAction, StoreSnapshot + Bytes, ExportIndex, GlobalInit, LocalFunctionIndex, OnCalledAction, Pages, StoreSnapshot, + ValueType, WASM_MAX_PAGES, WASM_MIN_PAGES, WASM_PAGE_SIZE, }; #[cfg(feature = "wat")] diff --git a/lib/api/src/js/module.rs b/lib/api/src/js/module.rs index 8f65c3c5a..6f04a5960 100644 --- a/lib/api/src/js/module.rs +++ b/lib/api/src/js/module.rs @@ -14,16 +14,15 @@ use std::borrow::Cow; use std::fmt; use std::io; use std::path::Path; -use bytes::Bytes; #[cfg(feature = "std")] use thiserror::Error; +#[cfg(feature = "tracing")] +use tracing::{debug, warn}; use wasm_bindgen::JsValue; use wasmer_types::{ ExportsIterator, ExternType, FunctionType, GlobalType, ImportsIterator, MemoryType, Mutability, Pages, TableType, Type, }; -#[cfg(feature = "tracing")] -use tracing::{debug, warn}; #[derive(Debug)] #[cfg_attr(feature = "std", derive(Error))] @@ -111,27 +110,23 @@ pub struct Module { raw_bytes: Option, } -pub trait IntoBytes -{ +pub trait IntoBytes { fn into_bytes(self) -> Bytes; } -impl IntoBytes -for Bytes { +impl IntoBytes for Bytes { fn into_bytes(self) -> Bytes { self } } -impl IntoBytes -for Vec { +impl IntoBytes for Vec { fn into_bytes(self) -> Bytes { Bytes::from(self) } } -impl IntoBytes -for &[u8] { +impl IntoBytes for &[u8] { fn into_bytes(self) -> Bytes { Bytes::from(self.to_vec()) } @@ -227,7 +222,10 @@ impl Module { /// Opposed to [`Module::new`], this function is not compatible with /// the WebAssembly text format (if the "wat" feature is enabled for /// this crate). - pub fn from_binary(_store: &impl AsStoreRef, binary: impl IntoBytes) -> Result { + pub fn from_binary( + _store: &impl AsStoreRef, + binary: impl IntoBytes, + ) -> Result { let binary = binary.into_bytes(); // // Self::validate(store, binary)?; @@ -366,7 +364,11 @@ impl Module { import_externs.push(import); } else { #[cfg(feature = "tracing")] - warn!("import not found {}:{}", import_type.module(), import_type.name()); + warn!( + "import not found {}:{}", + import_type.module(), + import_type.name() + ); } // in case the import is not found, the JS Wasm VM will handle // the error for us, so we don't need to handle it @@ -676,8 +678,7 @@ impl Module { /// between threads except via a post_message()) pub fn is_ok(&self) -> bool { let val = JsValue::from(&self.module); - !val.is_undefined() && - !val.is_null() + !val.is_undefined() && !val.is_null() } // /// Get the custom sections of the module given a `name`. diff --git a/lib/api/src/js/store.rs b/lib/api/src/js/store.rs index 5115ecdff..36030941f 100644 --- a/lib/api/src/js/store.rs +++ b/lib/api/src/js/store.rs @@ -6,7 +6,14 @@ use wasmer_types::OnCalledAction; /// wrap the actual context in a box. pub(crate) struct StoreInner { pub(crate) objects: StoreObjects, - pub(crate) on_called: Option Result>>>, + pub(crate) on_called: Option< + Box< + dyn FnOnce( + StoreMut, + ) + -> Result>, + >, + >, } /// The store represents all global state that can be manipulated by @@ -40,7 +47,7 @@ impl Store { pub fn same(_a: &Self, _b: &Self) -> bool { true } - + /// Returns the ID of this store pub fn id(&self) -> StoreId { self.inner.objects.id() @@ -149,11 +156,12 @@ impl<'a> StoreMut<'a> { } /// Sets the unwind callback which will be invoked when the call finishes - pub fn on_called( - &mut self, - callback: F, - ) - where F: FnOnce(StoreMut<'_>) -> Result> + Send + Sync + 'static, + pub fn on_called(&mut self, callback: F) + where + F: FnOnce(StoreMut<'_>) -> Result> + + Send + + Sync + + 'static, { self.inner.on_called.replace(Box::new(callback)); } @@ -328,7 +336,7 @@ mod objects { } ret } - + /// Serializes the mutable things into a snapshot pub fn restore_snapshot(&mut self, snapshot: &wasmer_types::StoreSnapshot) { for (index, global) in self.globals.iter_mut().enumerate() { diff --git a/lib/api/src/js/types.rs b/lib/api/src/js/types.rs index b86eada0c..6b2da9165 100644 --- a/lib/api/src/js/types.rs +++ b/lib/api/src/js/types.rs @@ -57,8 +57,6 @@ impl AsJs for Value { impl AsJs for wasmer_types::RawValue { fn as_jsvalue(&self, _store: &impl AsStoreRef) -> JsValue { - unsafe { - JsValue::from_f64(self.f64) - } + unsafe { JsValue::from_f64(self.f64) } } } diff --git a/lib/api/src/js/value.rs b/lib/api/src/js/value.rs index f6292e1e9..162988cae 100644 --- a/lib/api/src/js/value.rs +++ b/lib/api/src/js/value.rs @@ -2,8 +2,8 @@ use std::convert::TryFrom; use std::fmt; use std::string::{String, ToString}; -use wasmer_types::Type; use wasmer_types::RawValue; +use wasmer_types::Type; //use crate::ExternRef; use crate::js::externals::function::Function; @@ -110,7 +110,7 @@ impl Value { /// Converts the `Value` into a `RawValue`. pub unsafe fn as_raw_value(&self, store: &impl AsStoreRef) -> RawValue { RawValue { - f64: self.as_raw(store) + f64: self.as_raw(store), } } diff --git a/lib/api/src/sys/externals/function.rs b/lib/api/src/sys/externals/function.rs index 774e94c9e..7666b4884 100644 --- a/lib/api/src/sys/externals/function.rs +++ b/lib/api/src/sys/externals/function.rs @@ -41,13 +41,9 @@ pub struct Function { pub(crate) handle: StoreHandle, } -impl Into -for StoreHandle -{ +impl Into for StoreHandle { fn into(self) -> Function { - Function { - handle: self - } + Function { handle: self } } } @@ -424,7 +420,6 @@ impl Function { mut params: Vec, results: &mut [Value], ) -> Result<(), RuntimeError> { - // Call the trampoline. let result = { let mut r; @@ -442,20 +437,23 @@ impl Function { let store_mut = store.as_store_mut(); if let Some(callback) = store_mut.inner.on_called.take() { match callback(store_mut) { - Ok(wasmer_types::OnCalledAction::InvokeAgain) => { continue; } - Ok(wasmer_types::OnCalledAction::Finish) => { break; } - Ok(wasmer_types::OnCalledAction::Trap(trap)) => { return Err(RuntimeError::user(trap)) }, - Err(trap) => { + Ok(wasmer_types::OnCalledAction::InvokeAgain) => { + continue; + } + Ok(wasmer_types::OnCalledAction::Finish) => { + break; + } + Ok(wasmer_types::OnCalledAction::Trap(trap)) => { return Err(RuntimeError::user(trap)) - }, + } + Err(trap) => return Err(RuntimeError::user(trap)), } } break; } r }; - if let Err(error) = result - { + if let Err(error) = result { return Err(RuntimeError::from_trap(error)); } @@ -1349,7 +1347,7 @@ mod inner { let mut store = StoreMut::from_raw(env.raw_store as *mut _); let result = on_host_stack(|| { // println!("func wrapper1"); - panic::catch_unwind(AssertUnwindSafe(|| { + panic::catch_unwind(AssertUnwindSafe(|| { $( let $x = FromToNativeWasmType::from_native(NativeWasmTypeInto::from_abi(&mut store, $x)); )* @@ -1715,4 +1713,4 @@ mod inner { } } */ -} \ No newline at end of file +} diff --git a/lib/api/src/sys/externals/memory.rs b/lib/api/src/sys/externals/memory.rs index b1c19c11e..3ebb790cd 100644 --- a/lib/api/src/sys/externals/memory.rs +++ b/lib/api/src/sys/externals/memory.rs @@ -10,7 +10,7 @@ use std::mem::MaybeUninit; use std::slice; #[cfg(feature = "tracing")] use tracing::warn; -use wasmer_types::{Pages, LinearMemory, WASM_PAGE_SIZE}; +use wasmer_types::{LinearMemory, Pages, WASM_PAGE_SIZE}; use wasmer_vm::{InternalStoreHandle, MemoryError, StoreHandle, VMExtern, VMMemory}; use super::MemoryView; @@ -63,7 +63,7 @@ impl Memory { /// Create a memory object from an existing memory and attaches it to the store pub fn new_from_existing(new_store: &mut impl AsStoreMut, memory: VMMemory) -> Self { Self { - handle: StoreHandle::new(new_store.objects_mut(), memory) + handle: StoreHandle::new(new_store.objects_mut(), memory), } } @@ -138,8 +138,7 @@ impl Memory { &self, store: &impl AsStoreRef, new_store: &mut impl AsStoreMut, - ) -> Result - { + ) -> Result { // Create the new memory using the parameters of the existing memory let view = self.view(store); let ty = self.ty(store); @@ -157,9 +156,7 @@ impl Memory { // Copy the bytes view.copy_to_memory(amount as u64, &new_view) - .map_err(|err| { - MemoryError::Generic(err.to_string()) - })?; + .map_err(|err| MemoryError::Generic(err.to_string()))?; // Return the new memory Ok(new_memory) @@ -184,8 +181,7 @@ impl Memory { /// Attempts to clone this memory (if its clonable) pub fn try_clone(&self, store: &impl AsStoreRef) -> Option { let mem = self.handle.get(store.as_store_ref().objects()); - mem.try_clone() - .map(|mem| mem.into()) + mem.try_clone().map(|mem| mem.into()) } pub(crate) fn to_vm_extern(&self) -> VMExtern { diff --git a/lib/api/src/sys/externals/memory_view.rs b/lib/api/src/sys/externals/memory_view.rs index 16150b6cd..f55aad1dd 100644 --- a/lib/api/src/sys/externals/memory_view.rs +++ b/lib/api/src/sys/externals/memory_view.rs @@ -4,7 +4,7 @@ use std::convert::TryInto; use std::marker::PhantomData; use std::mem::MaybeUninit; use std::slice; -use wasmer_types::{Pages, LinearMemory}; +use wasmer_types::{LinearMemory, Pages}; use super::memory::MemoryBuffer; use super::Memory; @@ -184,7 +184,7 @@ impl<'a> MemoryView<'a> { self.read(offset, &mut chunk[..sublen])?; new_memory.write(offset, &chunk[..sublen])?; - + offset += sublen as u64; } Ok(()) diff --git a/lib/api/src/sys/imports.rs b/lib/api/src/sys/imports.rs index 82d44eb78..ef7f567ca 100644 --- a/lib/api/src/sys/imports.rs +++ b/lib/api/src/sys/imports.rs @@ -1,7 +1,7 @@ //! The import module contains the implementation data structures and helper functions used to //! manipulate and access a wasm module's imports including memories, tables, globals, and //! functions. -use crate::{Exports, Extern, Module, AsStoreMut, Memory}; +use crate::{AsStoreMut, Exports, Extern, Memory, Module}; use std::collections::HashMap; use std::fmt; use wasmer_compiler::LinkError; @@ -114,7 +114,11 @@ impl Imports { /// Imports (any) shared memory into the imports. /// (if the module does not import memory then this function is ignored) - pub fn import_shared_memory(&mut self, module: &Module, store: &mut impl AsStoreMut) -> Option { + pub fn import_shared_memory( + &mut self, + module: &Module, + store: &mut impl AsStoreMut, + ) -> Option { // Determine if shared memory needs to be created and imported let shared_memory = module .imports() @@ -122,16 +126,16 @@ impl Imports { .next() .map(|a| *a.ty()) .map(|ty| { - let style = store - .as_store_ref() - .tunables() - .memory_style(&ty); - VMSharedMemory::new(&ty, &style) - .unwrap() + let style = store.as_store_ref().tunables().memory_style(&ty); + VMSharedMemory::new(&ty, &style).unwrap() }); if let Some(memory) = shared_memory { - self.define("env", "memory", Memory::new_from_existing(store, memory.clone().into())); + self.define( + "env", + "memory", + Memory::new_from_existing(store, memory.clone().into()), + ); Some(memory) } else { None @@ -184,27 +188,23 @@ impl Imports { } pub struct ImportsIterator<'a> { - iter: std::collections::hash_map::Iter<'a, (String, String), Extern> + iter: std::collections::hash_map::Iter<'a, (String, String), Extern>, } -impl<'a> ImportsIterator<'a> -{ +impl<'a> ImportsIterator<'a> { fn new(imports: &'a Imports) -> Self { let iter = imports.map.iter(); Self { iter } } } -impl<'a> Iterator -for ImportsIterator<'a> { +impl<'a> Iterator for ImportsIterator<'a> { type Item = (&'a str, &'a str, &'a Extern); fn next(&mut self) -> Option { self.iter .next() - .map(|(k, v)| { - (k.0.as_str(), k.1.as_str(), v) - }) + .map(|(k, v)| (k.0.as_str(), k.1.as_str(), v)) } } diff --git a/lib/api/src/sys/instance.rs b/lib/api/src/sys/instance.rs index 3cc967530..3fdbd77e9 100644 --- a/lib/api/src/sys/instance.rs +++ b/lib/api/src/sys/instance.rs @@ -115,7 +115,7 @@ impl Instance { module: &Module, imports: &Imports, ) -> Result { - let externs = imports + let externs = imports .imports_for_module(module) .map_err(InstantiationError::Link)?; let mut handle = module.instantiate(store, &externs)?; @@ -128,11 +128,15 @@ impl Instance { (name, extern_) }) .collect::(); - + // If the memory is imported then also export it for backwards compatibility reasons // (many will assume the memory is always exported) - later we can remove this if exports.get_memory("memory").is_err() { - if let Some(memory) = externs.iter().filter(|a| a.ty(store).memory().is_some()).next() { + if let Some(memory) = externs + .iter() + .filter(|a| a.ty(store).memory().is_some()) + .next() + { exports.insert("memory", memory.clone()); } } @@ -177,7 +181,11 @@ impl Instance { // If the memory is imported then also export it for backwards compatibility reasons // (many will assume the memory is always exported) - later we can remove this if exports.get_memory("memory").is_err() { - if let Some(memory) = externs.iter().filter(|a| a.ty(store).memory().is_some()).next() { + if let Some(memory) = externs + .iter() + .filter(|a| a.ty(store).memory().is_some()) + .next() + { exports.insert("memory", memory.clone()); } } diff --git a/lib/api/src/sys/mem_access.rs b/lib/api/src/sys/mem_access.rs index d0e274a83..8bceda732 100644 --- a/lib/api/src/sys/mem_access.rs +++ b/lib/api/src/sys/mem_access.rs @@ -347,7 +347,7 @@ impl<'a, T: ValueType> WasmSlice<'a, T> { ret.set_len(len); } Ok(ret) - } + } } impl<'a, T: ValueType> fmt::Debug for WasmSlice<'a, T> { diff --git a/lib/api/src/sys/mod.rs b/lib/api/src/sys/mod.rs index ef37ee1ad..c810bf817 100644 --- a/lib/api/src/sys/mod.rs +++ b/lib/api/src/sys/mod.rs @@ -42,7 +42,7 @@ pub use wasmer_derive::ValueType; pub use wasmer_types::is_wasm; pub use wasmer_types::{ CpuFeature, ExportType, ExternType, FunctionType, GlobalType, ImportType, MemoryType, - Mutability, TableType, Target, Type, OnCalledAction, StoreSnapshot + Mutability, OnCalledAction, StoreSnapshot, TableType, Target, Type, }; pub use wasmer_types::{ @@ -57,8 +57,8 @@ pub mod vm { //! The `vm` module re-exports wasmer-vm types. pub use wasmer_vm::{ - MemoryError, MemoryStyle, TableStyle, VMExtern, VMMemory, VMMemoryDefinition, VMTable, - VMTableDefinition, VMOwnedMemory, VMSharedMemory + MemoryError, MemoryStyle, TableStyle, VMExtern, VMMemory, VMMemoryDefinition, + VMOwnedMemory, VMSharedMemory, VMTable, VMTableDefinition, }; } diff --git a/lib/api/src/sys/module.rs b/lib/api/src/sys/module.rs index 9a7096f12..d7badd46a 100644 --- a/lib/api/src/sys/module.rs +++ b/lib/api/src/sys/module.rs @@ -2,12 +2,10 @@ use crate::sys::InstantiationError; use crate::AsStoreMut; use crate::AsStoreRef; use bytes::Bytes; -use std::borrow::Cow; use std::fmt; use std::io; use std::path::Path; use std::sync::Arc; -use bytes::Bytes; use thiserror::Error; use wasmer_compiler::Artifact; use wasmer_compiler::ArtifactCreate; @@ -57,34 +55,29 @@ pub struct Module { module_info: Arc, } -pub trait IntoBytes -{ +pub trait IntoBytes { fn into_bytes(self) -> Bytes; } -impl IntoBytes -for Bytes { +impl IntoBytes for Bytes { fn into_bytes(self) -> Bytes { self } } -impl IntoBytes -for Vec { +impl IntoBytes for Vec { fn into_bytes(self) -> Bytes { Bytes::from(self) } } -impl IntoBytes -for &Vec { +impl IntoBytes for &Vec { fn into_bytes(self) -> Bytes { Bytes::from(self.clone()) } } -impl IntoBytes -for &[u8] { +impl IntoBytes for &[u8] { fn into_bytes(self) -> Bytes { Bytes::from(self.to_vec()) } @@ -96,8 +89,7 @@ impl IntoBytes for &[u8; N] { } } -impl IntoBytes -for &str { +impl IntoBytes for &str { fn into_bytes(self) -> Bytes { Bytes::from(self.as_bytes().to_vec()) } @@ -203,7 +195,10 @@ impl Module { /// Opposed to [`Module::new`], this function is not compatible with /// the WebAssembly text format (if the "wat" feature is enabled for /// this crate). - pub fn from_binary(store: &impl AsStoreRef, binary: impl IntoBytes) -> Result { + pub fn from_binary( + store: &impl AsStoreRef, + binary: impl IntoBytes, + ) -> Result { let binary = binary.into_bytes(); Self::validate(store, binary.clone())?; unsafe { Self::from_binary_unchecked(store, binary) } @@ -265,8 +260,7 @@ impl Module { /// # } /// ``` pub fn serialize(&self) -> Result { - self.artifact.serialize() - .map(|bytes| bytes.into()) + self.artifact.serialize().map(|bytes| bytes.into()) } /// Serializes a module into a file that the `Engine` @@ -508,7 +502,6 @@ impl Module { true } - /// Get the custom sections of the module given a `name`. /// /// # Important diff --git a/lib/api/src/sys/native.rs b/lib/api/src/sys/native.rs index f7ec12597..4a7d3a30c 100644 --- a/lib/api/src/sys/native.rs +++ b/lib/api/src/sys/native.rs @@ -7,16 +7,14 @@ //! let add_one = instance.exports.get_function("function_name")?; //! let add_one_native: TypedFunction = add_one.native().unwrap(); //! ``` -use std::marker::PhantomData; use std::cell::Cell; +use std::marker::PhantomData; -use crate::StoreMut; use crate::sys::{ AsStoreMut, FromToNativeWasmType, Function, NativeWasmTypeInto, RuntimeError, WasmTypeList, }; -use wasmer_types::{ - RawValue, OnCalledAction -}; +use crate::StoreMut; +use wasmer_types::{OnCalledAction, RawValue}; /// A WebAssembly function that can be called natively /// (using the Native ABI). diff --git a/lib/api/src/sys/ptr.rs b/lib/api/src/sys/ptr.rs index 8e7935e28..285688b8f 100644 --- a/lib/api/src/sys/ptr.rs +++ b/lib/api/src/sys/ptr.rs @@ -215,7 +215,10 @@ impl WasmPtr { /// This method is safe to call even if the memory is being concurrently /// modified. #[inline] - pub fn read_utf8_string_with_nul(&self, view: &MemoryView) -> Result { + pub fn read_utf8_string_with_nul( + &self, + view: &MemoryView, + ) -> Result { let vec = self.read_until(view, |&byte| byte == 0)?; Ok(String::from_utf8(vec)?) } diff --git a/lib/api/src/sys/store.rs b/lib/api/src/sys/store.rs index eaaeea085..f9aaececd 100644 --- a/lib/api/src/sys/store.rs +++ b/lib/api/src/sys/store.rs @@ -1,10 +1,10 @@ use crate::sys::tunables::BaseTunables; +use derivative::Derivative; use std::fmt; #[cfg(feature = "compiler")] use wasmer_compiler::{Engine, EngineBuilder, Tunables}; use wasmer_types::{OnCalledAction, StoreSnapshot}; -use wasmer_vm::{init_traps, TrapHandler, TrapHandlerFn, StoreId}; -use derivative::Derivative; +use wasmer_vm::{init_traps, StoreId, TrapHandler, TrapHandlerFn}; use wasmer_vm::StoreObjects; @@ -24,11 +24,17 @@ pub(crate) struct StoreInner { #[derivative(Debug = "ignore")] pub(crate) trap_handler: Option>>, #[derivative(Debug = "ignore")] - pub(crate) on_called: Option) -> Result>>>, + pub(crate) on_called: Option< + Box< + dyn FnOnce( + StoreMut<'_>, + ) + -> Result>, + >, + >, } -impl StoreInner -{ +impl StoreInner { // Serializes the mutable things into a snapshot pub fn save_snapshot(&self) -> StoreSnapshot { self.objects.save_snapshot() @@ -324,17 +330,16 @@ impl<'a> StoreMut<'a> { } pub(crate) unsafe fn from_raw(raw: *mut StoreInner) -> Self { - Self { - inner: &mut *raw, - } + Self { inner: &mut *raw } } /// Sets the unwind callback which will be invoked when the call finishes - pub fn on_called( - &mut self, - callback: F, - ) - where F: FnOnce(StoreMut<'_>) -> Result> + Send + Sync + 'static, + pub fn on_called(&mut self, callback: F) + where + F: FnOnce(StoreMut<'_>) -> Result> + + Send + + Sync + + 'static, { self.inner.on_called.replace(Box::new(callback)); } @@ -368,9 +373,7 @@ impl AsStoreRef for StoreMut<'_> { } impl AsStoreMut for StoreMut<'_> { fn as_store_mut(&mut self) -> StoreMut<'_> { - StoreMut { - inner: self.inner, - } + StoreMut { inner: self.inner } } fn objects_mut(&mut self) -> &mut StoreObjects { &mut self.inner.objects diff --git a/lib/api/tests/reference_types.rs b/lib/api/tests/reference_types.rs index c44e4e314..46b86da77 100644 --- a/lib/api/tests/reference_types.rs +++ b/lib/api/tests/reference_types.rs @@ -54,10 +54,7 @@ pub mod reference_types { let call_set_value: &Function = instance.exports.get_function("call_set_value")?; let results: Box<[Value]> = call_set_value.call(&mut store, &[Value::FuncRef(Some(func_to_call))])?; - assert!(env - .as_ref(&store.as_store_ref()) - .0 - .load(Ordering::SeqCst)); + assert!(env.as_ref(&store.as_store_ref()).0.load(Ordering::SeqCst)); assert_eq!(&*results, &[Value::I32(343)]); Ok(()) diff --git a/lib/cli-compiler/src/commands/compile.rs b/lib/cli-compiler/src/commands/compile.rs index fa9928d3f..822b26501 100644 --- a/lib/cli-compiler/src/commands/compile.rs +++ b/lib/cli-compiler/src/commands/compile.rs @@ -104,7 +104,7 @@ impl Compile { &target, memory_styles, table_styles, - None + None, )?; artifact.serialize_to_file(self.output.as_ref())?; eprintln!( diff --git a/lib/cli/src/commands/run/wasi.rs b/lib/cli/src/commands/run/wasi.rs index 4ff31eaa0..05c093db3 100644 --- a/lib/cli/src/commands/run/wasi.rs +++ b/lib/cli/src/commands/run/wasi.rs @@ -1,16 +1,16 @@ use crate::utils::{parse_envvar, parse_mapdir}; use anyhow::Result; -use wasmer_vfs::FileSystem; -use wasmer_wasi::fs::{PassthruFileSystem, RootFileSystemBuilder, TtyFile, SpecialFile}; -use wasmer_wasi::types::__WASI_STDIN_FILENO; use std::collections::HashMap; +use std::path::PathBuf; use std::sync::Arc; use std::{collections::BTreeSet, path::Path}; -use std::path::PathBuf; use wasmer::{AsStoreMut, FunctionEnv, Instance, Module, RuntimeError, Value}; +use wasmer_vfs::FileSystem; +use wasmer_wasi::fs::{PassthruFileSystem, RootFileSystemBuilder, SpecialFile, TtyFile}; +use wasmer_wasi::types::__WASI_STDIN_FILENO; use wasmer_wasi::{ - get_wasi_versions, import_object_for_all_wasi_versions, WasiEnv, WasiError, - WasiState, WasiVersion, is_wasix_module, default_fs_backing, PluggableRuntimeImplementation, + default_fs_backing, get_wasi_versions, import_object_for_all_wasi_versions, is_wasix_module, + PluggableRuntimeImplementation, WasiEnv, WasiError, WasiState, WasiVersion, }; use clap::Parser; @@ -97,7 +97,8 @@ impl Wasi { ) -> Result<(FunctionEnv, Instance)> { let args = args.iter().cloned().map(|arg| arg.into_bytes()); - let map_commands = self.map_commands + let map_commands = self + .map_commands .iter() .map(|map| map.split_once("=").unwrap()) .map(|(a, b)| (a.to_string(), b.to_string())) @@ -113,11 +114,13 @@ impl Wasi { .runtime(&runtime) .map_commands(map_commands.clone()); - if is_wasix_module(module) - { + if is_wasix_module(module) { // If we preopen anything from the host then shallow copy it over let root_fs = RootFileSystemBuilder::new() - .with_tty(Box::new(TtyFile::new(runtime.clone(), Box::new(SpecialFile::new(__WASI_STDIN_FILENO))))) + .with_tty(Box::new(TtyFile::new( + runtime.clone(), + Box::new(SpecialFile::new(__WASI_STDIN_FILENO)), + ))) .build(); if self.mapped_dirs.len() > 0 { let fs_backing: Arc = @@ -125,7 +128,7 @@ impl Wasi { for (src, dst) in self.mapped_dirs.clone() { let src = match src.starts_with("/") { true => src, - false => format!("/{}", src) + false => format!("/{}", src), }; root_fs.mount(PathBuf::from(src), &fs_backing, dst)?; } @@ -155,7 +158,7 @@ impl Wasi { let mut wasi_env = wasi_state_builder.finalize(store)?; let mut import_object = import_object_for_all_wasi_versions(store, &wasi_env.env); import_object.import_shared_memory(module, &mut store); - + let instance = Instance::new(store, module, &import_object)?; wasi_env.initialize(&mut store, &instance)?; Ok((wasi_env.env, instance)) diff --git a/lib/compiler-cranelift/src/compiler.rs b/lib/compiler-cranelift/src/compiler.rs index 13068acab..0a1a189f3 100644 --- a/lib/compiler-cranelift/src/compiler.rs +++ b/lib/compiler-cranelift/src/compiler.rs @@ -55,7 +55,7 @@ impl Compiler for CraneliftCompiler { fn name(&self) -> &str { "cranelift" } - + /// Get the middlewares for this compiler fn get_middlewares(&self) -> &[Arc] { &self.config.middlewares diff --git a/lib/compiler-cranelift/src/func_environ.rs b/lib/compiler-cranelift/src/func_environ.rs index 4cdcc5657..afb6010d4 100644 --- a/lib/compiler-cranelift/src/func_environ.rs +++ b/lib/compiler-cranelift/src/func_environ.rs @@ -973,7 +973,7 @@ impl<'module_environment> BaseFuncEnvironment for FuncEnvironment<'module_enviro }, false, ) - }, + } MemoryStyle::Static { bound, offset_guard_size, diff --git a/lib/compiler-cranelift/src/translator/code_translator.rs b/lib/compiler-cranelift/src/translator/code_translator.rs index d432f0743..e38640fb3 100644 --- a/lib/compiler-cranelift/src/translator/code_translator.rs +++ b/lib/compiler-cranelift/src/translator/code_translator.rs @@ -1073,13 +1073,15 @@ pub fn translate_operator( ) { Ok(res) => { state.push1(res); - }, + } Err(wasmer_types::WasmError::Unsupported(_err)) => { // If multiple threads hit a mutex then the function will fail builder.ins().trap(ir::TrapCode::UnreachableCodeReached); state.reachable = false; - }, - Err(err) => { return Err(err); } + } + Err(err) => { + return Err(err); + } }; } Operator::MemoryAtomicNotify { memarg } => { @@ -1088,18 +1090,19 @@ pub fn translate_operator( let count = state.pop1(); // 32 (fixed) let addr = state.pop1(); // 32 (fixed) let addr = fold_atomic_mem_addr(addr, memarg, I32, builder); - match environ.translate_atomic_notify(builder.cursor(), heap_index, heap, addr, count) - { + match environ.translate_atomic_notify(builder.cursor(), heap_index, heap, addr, count) { Ok(res) => { state.push1(res); - }, + } Err(wasmer_types::WasmError::Unsupported(_err)) => { // Simple return a zero as this function is needed for the __wasi_init_memory function // but the equivalent notify.wait will not be called (as only one thread calls __start) // hence these atomic operations are not needed state.push1(builder.ins().iconst(I32, i64::from(0))); - }, - Err(err) => { return Err(err); } + } + Err(err) => { + return Err(err); + } }; } Operator::I32AtomicLoad { memarg } => { diff --git a/lib/compiler/src/artifact_builders/artifact_builder.rs b/lib/compiler/src/artifact_builders/artifact_builder.rs index 8270d982e..1f569af89 100644 --- a/lib/compiler/src/artifact_builders/artifact_builder.rs +++ b/lib/compiler/src/artifact_builders/artifact_builder.rs @@ -16,8 +16,8 @@ use wasmer_types::MetadataHeader; use wasmer_types::SerializeError; use wasmer_types::{ CompileError, CpuFeature, CustomSection, Dwarf, FunctionIndex, LocalFunctionIndex, MemoryIndex, - MemoryStyle, ModuleInfo, OwnedDataInitializer, Relocation, SectionIndex, SignatureIndex, - TableIndex, TableStyle, Target, Pages, + MemoryStyle, ModuleInfo, OwnedDataInitializer, Pages, Relocation, SectionIndex, SignatureIndex, + TableIndex, TableStyle, Target, }; use wasmer_types::{ CompiledFunctionFrameInfo, FunctionBody, SerializableCompilation, SerializableModule, diff --git a/lib/compiler/src/engine/resolver.rs b/lib/compiler/src/engine/resolver.rs index 8668baeb8..6f8c0a2dc 100644 --- a/lib/compiler/src/engine/resolver.rs +++ b/lib/compiler/src/engine/resolver.rs @@ -4,7 +4,8 @@ use crate::LinkError; use more_asserts::assert_ge; use wasmer_types::entity::{BoxedSlice, EntityRef, PrimaryMap}; use wasmer_types::{ - ExternType, FunctionIndex, ImportError, ImportIndex, MemoryIndex, ModuleInfo, TableIndex, LinearMemory, + ExternType, FunctionIndex, ImportError, ImportIndex, LinearMemory, MemoryIndex, ModuleInfo, + TableIndex, }; use wasmer_vm::{ diff --git a/lib/compiler/src/engine/tunables.rs b/lib/compiler/src/engine/tunables.rs index b9dd376d3..cfe6d4b5b 100644 --- a/lib/compiler/src/engine/tunables.rs +++ b/lib/compiler/src/engine/tunables.rs @@ -3,7 +3,7 @@ use std::ptr::NonNull; use wasmer_types::entity::{EntityRef, PrimaryMap}; use wasmer_types::{ GlobalType, LocalGlobalIndex, LocalMemoryIndex, LocalTableIndex, MemoryIndex, MemoryType, - ModuleInfo, TableIndex, TableType, Pages, + ModuleInfo, Pages, TableIndex, TableType, }; use wasmer_vm::{InternalStoreHandle, MemoryError, StoreObjects}; use wasmer_vm::{MemoryStyle, TableStyle}; diff --git a/lib/compiler/src/translator/environ.rs b/lib/compiler/src/translator/environ.rs index 1615b87bc..fc515a9c7 100644 --- a/lib/compiler/src/translator/environ.rs +++ b/lib/compiler/src/translator/environ.rs @@ -8,13 +8,13 @@ use crate::wasmparser::{Operator, Range, Type}; use std::convert::{TryFrom, TryInto}; use wasmer_types::entity::PrimaryMap; use wasmer_types::FunctionType; +use wasmer_types::WasmResult; use wasmer_types::{ CustomSectionIndex, DataIndex, DataInitializer, DataInitializerLocation, ElemIndex, ExportIndex, FunctionIndex, GlobalIndex, GlobalInit, GlobalType, ImportIndex, LocalFunctionIndex, MemoryIndex, MemoryType, ModuleInfo, SignatureIndex, TableIndex, TableInitializer, TableType, }; -use wasmer_types::WasmResult; /// Contains function data: bytecode and its offset in the module. #[derive(Hash)] diff --git a/lib/derive/src/value_type.rs b/lib/derive/src/value_type.rs index 0280f5ead..ef3d54857 100644 --- a/lib/derive/src/value_type.rs +++ b/lib/derive/src/value_type.rs @@ -1,7 +1,7 @@ use proc_macro2::TokenStream; use proc_macro_error::abort; use quote::quote; -use syn::{Data, DeriveInput, Member, Meta, MetaList, NestedMeta, Field}; +use syn::{Data, DeriveInput, Field, Member, Meta, MetaList, NestedMeta}; /// We can only validate types that have a well defined layout. fn check_repr(input: &DeriveInput) { diff --git a/lib/emscripten/src/lib.rs b/lib/emscripten/src/lib.rs index cbc388d91..33571234e 100644 --- a/lib/emscripten/src/lib.rs +++ b/lib/emscripten/src/lib.rs @@ -23,9 +23,9 @@ use std::f64; use std::path::PathBuf; use std::sync::{Arc, Mutex, RwLock}; use wasmer::{ - imports, namespace, AsStoreMut, ExportError, Exports, Function, FunctionEnv, FunctionEnvMut, - FunctionType, Global, Imports, Instance, Memory, MemoryType, Module, Pages, RuntimeError, - Table, TableType, TypedFunction, Value, WasmPtr, AsStoreRef, + imports, namespace, AsStoreMut, AsStoreRef, ExportError, Exports, Function, FunctionEnv, + FunctionEnvMut, FunctionType, Global, Imports, Instance, Memory, MemoryType, Module, Pages, + RuntimeError, Table, TableType, TypedFunction, Value, WasmPtr, }; use wasmer_types::Type as ValType; @@ -146,11 +146,7 @@ impl EmEnv { *w = funcs; } - pub fn set_data( - &self, - data: &EmscriptenGlobalsData, - mapped_dirs: HashMap, - ) { + pub fn set_data(&self, data: &EmscriptenGlobalsData, mapped_dirs: HashMap) { let mut w = self.data.lock().unwrap(); *w = Some(EmscriptenData::new(data.clone(), mapped_dirs)); } diff --git a/lib/emscripten/src/memory.rs b/lib/emscripten/src/memory.rs index 4294a42cb..36ee1299c 100644 --- a/lib/emscripten/src/memory.rs +++ b/lib/emscripten/src/memory.rs @@ -111,7 +111,7 @@ pub fn sbrk(mut ctx: FunctionEnvMut, increment: i32) -> i32 { total_memory ); drop(dynamictop_ptr); - + if increment > 0 && new_dynamic_top < old_dynamic_top || new_dynamic_top < 0 { abort_on_cannot_grow_memory_old(ctx); return -1; diff --git a/lib/types/src/lib.rs b/lib/types/src/lib.rs index bede70683..7e6687779 100644 --- a/lib/types/src/lib.rs +++ b/lib/types/src/lib.rs @@ -62,6 +62,7 @@ mod libcalls; mod memory; mod module; mod serialize; +mod store; mod table; mod trapcode; mod types; @@ -69,7 +70,6 @@ mod units; mod utils; mod value; mod vmoffsets; -mod store; pub use crate::compilation::target::{ Aarch64Architecture, Architecture, BinaryFormat, CallingConvention, CpuFeature, Endianness, @@ -77,8 +77,8 @@ pub use crate::compilation::target::{ }; pub use crate::serialize::{MetadataHeader, SerializableCompilation, SerializableModule}; pub use error::{ - CompileError, DeserializeError, ImportError, MiddlewareError, ParseCpuFeatureError, - PreInstantiationError, SerializeError, WasmError, WasmResult, MemoryError, + CompileError, DeserializeError, ImportError, MemoryError, MiddlewareError, + ParseCpuFeatureError, PreInstantiationError, SerializeError, WasmError, WasmResult, }; /// The entity module, with common helpers for Rust structures @@ -104,11 +104,9 @@ pub use types::{ pub use value::{RawValue, ValueType}; pub use crate::libcalls::LibCall; -pub use crate::memory::{ - MemoryStyle, MemoryRole, LinearMemory, VMMemoryDefinition, -}; +pub use crate::memory::{LinearMemory, MemoryRole, MemoryStyle, VMMemoryDefinition}; pub use crate::table::TableStyle; -pub use crate::trapcode::{TrapCode, OnCalledAction}; +pub use crate::trapcode::{OnCalledAction, TrapCode}; pub use crate::vmoffsets::{TargetSharedSignatureIndex, VMBuiltinFunctionIndex, VMOffsets}; pub use crate::utils::is_wasm; diff --git a/lib/types/src/memory.rs b/lib/types/src/memory.rs index 55ed2c6a8..728111c64 100644 --- a/lib/types/src/memory.rs +++ b/lib/types/src/memory.rs @@ -1,14 +1,14 @@ use crate::{Pages, ValueType}; +use core::ptr::NonNull; use rkyv::{Archive, Deserialize as RkyvDeserialize, Serialize as RkyvSerialize}; #[cfg(feature = "enable-serde")] use serde::{Deserialize, Serialize}; -use core::ptr::NonNull; use std::convert::{TryFrom, TryInto}; use std::iter::Sum; use std::ops::{Add, AddAssign}; -use super::MemoryType; use super::MemoryError; +use super::MemoryType; /// Implementation styles for WebAssembly linear memory. #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, RkyvSerialize, RkyvDeserialize, Archive)] @@ -135,8 +135,7 @@ unsafe impl MemorySize for Memory64 { /// Represents different roles that a particular region of memory plays #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)] -pub enum MemoryRole -{ +pub enum MemoryRole { /// The region is used for storing data (default) Data, /// The region is used as a stack @@ -147,8 +146,7 @@ pub enum MemoryRole Remote(u64), } -impl Default -for MemoryRole { +impl Default for MemoryRole { fn default() -> Self { MemoryRole::Data } @@ -156,7 +154,8 @@ for MemoryRole { /// Represents memory that is used by the WebAsssembly module pub trait LinearMemory -where Self: std::fmt::Debug + Send +where + Self: std::fmt::Debug + Send, { /// Returns the type for this memory. fn ty(&self) -> MemoryType; @@ -216,10 +215,10 @@ unsafe impl Sync for VMMemoryDefinition {} #[cfg(test)] mod test_vmmemory_definition { use super::VMMemoryDefinition; + use crate::ModuleInfo; use crate::VMOffsets; use memoffset::offset_of; use std::mem::size_of; - use crate::ModuleInfo; #[test] fn check_vmmemory_definition_offsets() { diff --git a/lib/types/src/serialize.rs b/lib/types/src/serialize.rs index 8bf073597..99c36af2c 100644 --- a/lib/types/src/serialize.rs +++ b/lib/types/src/serialize.rs @@ -1,5 +1,5 @@ -use crate::Pages; use crate::entity::PrimaryMap; +use crate::Pages; use crate::{ compilation::target::CpuFeature, CompileModuleInfo, CompiledFunctionFrameInfo, CustomSection, DeserializeError, Dwarf, Features, FunctionBody, FunctionIndex, LocalFunctionIndex, diff --git a/lib/types/src/store.rs b/lib/types/src/store.rs index 4777a9b4d..b9085aee8 100644 --- a/lib/types/src/store.rs +++ b/lib/types/src/store.rs @@ -4,14 +4,12 @@ use std::io::Read; /// Represents a snapshot of parts of the store that mutate /// (such as globals and tables) #[derive(Debug, Default)] -pub struct StoreSnapshot -{ +pub struct StoreSnapshot { /// Global values at the time the snapshot was taken pub globals: HashMap, } -impl StoreSnapshot -{ +impl StoreSnapshot { /// Serializes the snapshot into a set of bytes pub fn serialize(&self) -> Vec { let capacity = 32usize * self.globals.len(); @@ -25,7 +23,7 @@ impl StoreSnapshot } ret } - + /// Deserializes the bytes back into a store snapshot pub fn deserialize(data: &[u8]) -> std::io::Result { let mut ret = StoreSnapshot::default(); @@ -33,7 +31,7 @@ impl StoreSnapshot // Read all the sections let mut reader = data; loop { - let mut ty_arr = [0u8; 4]; + let mut ty_arr = [0u8; 4]; if let Err(err) = reader.read_exact(&mut ty_arr) { if err.kind() == std::io::ErrorKind::UnexpectedEof { break; @@ -62,8 +60,10 @@ impl StoreSnapshot // Set the value in the snapshot ret.globals.insert(key, val); } - }, - _ => { break; } + } + _ => { + break; + } } } diff --git a/lib/types/src/trapcode.rs b/lib/types/src/trapcode.rs index 9572f12c8..134a4b3ce 100644 --- a/lib/types/src/trapcode.rs +++ b/lib/types/src/trapcode.rs @@ -123,8 +123,7 @@ impl FromStr for TrapCode { /// After the stack is unwound via asyncify what /// should the call loop do next #[derive(Debug)] -pub enum OnCalledAction -{ +pub enum OnCalledAction { /// Will call the function again InvokeAgain, /// Will return the result of the invocation diff --git a/lib/vbus/src/lib.rs b/lib/vbus/src/lib.rs index 4ce32b944..8c1572304 100644 --- a/lib/vbus/src/lib.rs +++ b/lib/vbus/src/lib.rs @@ -4,7 +4,7 @@ use std::pin::Pin; use std::task::{Context, Poll}; use thiserror::Error; -use wasmer::{Store, FunctionEnvMut}; +use wasmer::{FunctionEnvMut, Store}; pub use wasmer_vfs::FileDescriptor; pub use wasmer_vfs::StdioMode; use wasmer_vfs::VirtualFile; @@ -28,15 +28,13 @@ impl From for CallDescriptor { } pub trait VirtualBus: fmt::Debug + Send + Sync + 'static -where T: SpawnEnvironmentIntrinsics, - T: std::fmt::Debug + Send + Sync + 'static +where + T: SpawnEnvironmentIntrinsics, + T: std::fmt::Debug + Send + Sync + 'static, { /// Starts a new WAPM sub process fn spawn(&self, env: T) -> SpawnOptions { - SpawnOptions::new( - Box::new(DefaultVirtualBusSpawner::default()), - env - ) + SpawnOptions::new(Box::new(DefaultVirtualBusSpawner::default()), env) } /// Creates a listener thats used to receive BUS commands @@ -47,16 +45,35 @@ where T: SpawnEnvironmentIntrinsics, pub trait VirtualBusSpawner { /// Spawns a new WAPM process by its name - fn spawn<'a>(&self, parent_ctx: Option<&FunctionEnvMut<'a, T>>, name: &str, store: Store, config: SpawnOptionsConfig, fallback: &dyn VirtualBusSpawner) -> Result { - fallback.spawn(parent_ctx, name, store, config, &mut UnsupportedVirtualBusSpawner::default()) + fn spawn<'a>( + &self, + parent_ctx: Option<&FunctionEnvMut<'a, T>>, + name: &str, + store: Store, + config: SpawnOptionsConfig, + fallback: &dyn VirtualBusSpawner, + ) -> Result { + fallback.spawn( + parent_ctx, + name, + store, + config, + &mut UnsupportedVirtualBusSpawner::default(), + ) } } #[derive(Debug, Default)] -pub struct UnsupportedVirtualBusSpawner { } -impl VirtualBusSpawner -for UnsupportedVirtualBusSpawner { - fn spawn<'a>(&self, _parent_ctx: Option<&FunctionEnvMut<'a, T>>, _name: &str, _store: Store, _config: SpawnOptionsConfig, _fallback: &dyn VirtualBusSpawner) -> Result { +pub struct UnsupportedVirtualBusSpawner {} +impl VirtualBusSpawner for UnsupportedVirtualBusSpawner { + fn spawn<'a>( + &self, + _parent_ctx: Option<&FunctionEnvMut<'a, T>>, + _name: &str, + _store: Store, + _config: SpawnOptionsConfig, + _fallback: &dyn VirtualBusSpawner, + ) -> Result { Err(VirtualBusError::Unsupported) } } @@ -84,7 +101,8 @@ pub trait SpawnEnvironmentIntrinsics { } impl SpawnOptionsConfig -where T: SpawnEnvironmentIntrinsics +where + T: SpawnEnvironmentIntrinsics, { pub fn reuse(&self) -> bool { self.reuse @@ -113,7 +131,8 @@ pub struct SpawnOptions { } impl SpawnOptions -where T: SpawnEnvironmentIntrinsics +where + T: SpawnEnvironmentIntrinsics, { pub fn new(spawner: Box>, env: T) -> Self { Self { @@ -137,8 +156,15 @@ where T: SpawnEnvironmentIntrinsics } /// Spawns a new bus instance by its reference name - pub fn spawn<'a>(self, parent_ctx: Option<&FunctionEnvMut<'a, T>>, name: &str, store: Store, fallback: &dyn VirtualBusSpawner) -> Result { - self.spawner.spawn(parent_ctx, name, store, self.conf, fallback) + pub fn spawn<'a>( + self, + parent_ctx: Option<&FunctionEnvMut<'a, T>>, + name: &str, + store: Store, + fallback: &dyn VirtualBusSpawner, + ) -> Result { + self.spawner + .spawn(parent_ctx, name, store, self.conf, fallback) } } @@ -146,31 +172,28 @@ pub struct BusSpawnedProcessJoin { inst: Box, } -impl BusSpawnedProcessJoin -{ +impl BusSpawnedProcessJoin { pub fn new(process: BusSpawnedProcess) -> Self { - Self { - inst: process.inst - } + Self { inst: process.inst } } } -impl Future -for BusSpawnedProcessJoin { +impl Future for BusSpawnedProcessJoin { type Output = Option; fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { let inst = Pin::new(self.inst.as_mut()); match inst.poll_ready(cx) { Poll::Ready(_) => Poll::Ready(self.inst.exit_code()), - Poll::Pending => Poll::Pending + Poll::Pending => Poll::Pending, } } } /// Signal handles...well...they process signals pub trait SignalHandlerAbi -where Self: std::fmt::Debug +where + Self: std::fmt::Debug, { /// Processes a signal fn signal(&self, sig: u8); @@ -190,15 +213,10 @@ pub struct BusSpawnedProcess { pub signaler: Option>, } -impl BusSpawnedProcess -{ +impl BusSpawnedProcess { pub fn exited_process(exit_code: u32) -> Self { Self { - inst: Box::new( - ExitedProcess { - exit_code - } - ), + inst: Box::new(ExitedProcess { exit_code }), stdin: None, stdout: None, stderr: None, @@ -226,19 +244,24 @@ pub trait VirtualBusInvokable: fmt::Debug + Send + Sync + 'static { } #[derive(Debug, Default)] -struct UnsupportedBusInvoker { } +struct UnsupportedBusInvoker {} -impl VirtualBusInvoked -for UnsupportedBusInvoker { +impl VirtualBusInvoked for UnsupportedBusInvoker { #[allow(unused_variables)] - fn poll_invoked(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll>> { + fn poll_invoked( + self: Pin<&mut Self>, + cx: &mut Context<'_>, + ) -> Poll>> { Poll::Ready(Err(VirtualBusError::Unsupported)) } } pub trait VirtualBusInvoked: fmt::Debug + Unpin + 'static { //// Returns once the bus has been invoked (or failed) - fn poll_invoked(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll>>; + fn poll_invoked( + self: Pin<&mut Self>, + cx: &mut Context<'_>, + ) -> Poll>>; } pub trait VirtualBusProcess: @@ -259,20 +282,18 @@ pub trait VirtualBusInvocation: } #[derive(Debug)] -pub struct InstantInvocation -{ +pub struct InstantInvocation { val: Option, err: Option, call: Option>, } -impl InstantInvocation -{ +impl InstantInvocation { pub fn response(format: BusDataFormat, data: Vec) -> Self { Self { val: Some(BusInvocationEvent::Response { format, data }), err: None, - call: None + call: None, } } @@ -280,7 +301,7 @@ impl InstantInvocation Self { val: None, err: Some(err), - call: None + call: None, } } @@ -288,15 +309,16 @@ impl InstantInvocation Self { val: None, err: None, - call: Some(val) + call: Some(val), } } } -impl VirtualBusInvoked -for InstantInvocation -{ - fn poll_invoked(mut self: Pin<&mut Self>, _cx: &mut Context<'_>) -> Poll>> { +impl VirtualBusInvoked for InstantInvocation { + fn poll_invoked( + mut self: Pin<&mut Self>, + _cx: &mut Context<'_>, + ) -> Poll>> { if let Some(err) = self.err.take() { return Poll::Ready(Err(err)); } @@ -308,47 +330,35 @@ for InstantInvocation }))); } match self.call.take() { - Some(val) => { - Poll::Ready(Ok(val)) - }, - None => { - Poll::Ready(Err(VirtualBusError::AlreadyConsumed)) - } + Some(val) => Poll::Ready(Ok(val)), + None => Poll::Ready(Err(VirtualBusError::AlreadyConsumed)), } } } -impl VirtualBusInvocation -for InstantInvocation -{ +impl VirtualBusInvocation for InstantInvocation { fn poll_event(mut self: Pin<&mut Self>, _cx: &mut Context<'_>) -> Poll { match self.val.take() { - Some(val) => { - Poll::Ready(val) - }, - None => { - Poll::Ready(BusInvocationEvent::Fault { fault: VirtualBusError::AlreadyConsumed }) - } + Some(val) => Poll::Ready(val), + None => Poll::Ready(BusInvocationEvent::Fault { + fault: VirtualBusError::AlreadyConsumed, + }), } } } -impl VirtualBusInvokable -for InstantInvocation -{ +impl VirtualBusInvokable for InstantInvocation { fn invoke( &self, _topic_hash: u128, _format: BusDataFormat, _buf: Vec, ) -> Box { - Box::new( - InstantInvocation { - val: None, - err: Some(VirtualBusError::InvalidTopic), - call: None - } - ) + Box::new(InstantInvocation { + val: None, + err: Some(VirtualBusError::InvalidTopic), + call: None, + }) } } @@ -373,8 +383,8 @@ pub enum BusInvocationEvent { /// The service has responded with a fault Fault { /// Fault code that was raised - fault: VirtualBusError - } + fault: VirtualBusError, + }, } pub trait VirtualBusListener: fmt::Debug + Send + Sync + Unpin + 'static { @@ -394,8 +404,7 @@ pub struct BusCallEvent { pub data: Vec, } -pub trait VirtualBusCalled: fmt::Debug + Send + Sync + 'static -{ +pub trait VirtualBusCalled: fmt::Debug + Send + Sync + 'static { /// Polls for new calls to this service fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll; @@ -421,23 +430,20 @@ pub enum BusDataFormat { } #[derive(Debug, Default)] -pub struct DefaultVirtualBus -{ -} +pub struct DefaultVirtualBus {} impl VirtualBus for DefaultVirtualBus -where T: SpawnEnvironmentIntrinsics, - T: std::fmt::Debug + Send + Sync + 'static +where + T: SpawnEnvironmentIntrinsics, + T: std::fmt::Debug + Send + Sync + 'static, { } #[derive(Debug, Default)] -pub struct DefaultVirtualBusSpawner -{ -} +pub struct DefaultVirtualBusSpawner {} -impl VirtualBusSpawner for DefaultVirtualBusSpawner -where T: std::fmt::Debug + Send + Sync + 'static +impl VirtualBusSpawner for DefaultVirtualBusSpawner where + T: std::fmt::Debug + Send + Sync + 'static { } @@ -510,10 +516,8 @@ pub struct ExitedProcess { pub exit_code: u32, } -impl VirtualBusProcess -for ExitedProcess { - fn exit_code(&self) -> Option - { +impl VirtualBusProcess for ExitedProcess { + fn exit_code(&self) -> Option { Some(self.exit_code.clone()) } @@ -522,12 +526,10 @@ for ExitedProcess { } } -impl VirtualBusScope -for ExitedProcess { +impl VirtualBusScope for ExitedProcess { fn poll_finished(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<()> { VirtualBusProcess::poll_ready(self, cx) } } -impl VirtualBusInvokable -for ExitedProcess { } +impl VirtualBusInvokable for ExitedProcess {} diff --git a/lib/vfs/src/host_fs.rs b/lib/vfs/src/host_fs.rs index 511a32e28..74da90995 100644 --- a/lib/vfs/src/host_fs.rs +++ b/lib/vfs/src/host_fs.rs @@ -422,7 +422,7 @@ impl VirtualFile for File { } #[cfg(feature = "sys")] - fn bytes_available(&self) -> Result { + fn bytes_available(&self) -> Result { host_file_bytes_available(self.inner.try_into_filedescriptor()?) } diff --git a/lib/vfs/src/lib.rs b/lib/vfs/src/lib.rs index fcb8520a3..646cb58c0 100644 --- a/lib/vfs/src/lib.rs +++ b/lib/vfs/src/lib.rs @@ -200,8 +200,7 @@ impl OpenOptions { /// This trait relies on your file closing when it goes out of scope via `Drop` //#[cfg_attr(feature = "enable-serde", typetag::serde)] #[async_trait::async_trait] -pub trait VirtualFile: fmt::Debug + Write + Read + Seek + Upcastable -{ +pub trait VirtualFile: fmt::Debug + Write + Read + Seek + Upcastable { /// the last time the file was accessed in nanoseconds as a UNIX timestamp fn last_accessed(&self) -> u64; @@ -249,14 +248,18 @@ pub trait VirtualFile: fmt::Debug + Write + Read + Seek + Upcastable /// Polls for when read data is available again /// Defaults to `None` which means no asynchronous IO support - caller /// must poll `bytes_available_read` instead - fn poll_read_ready(&self, cx: &mut std::task::Context<'_>, register_root_waker: &Arc) -> std::task::Poll> { + fn poll_read_ready( + &self, + cx: &mut std::task::Context<'_>, + register_root_waker: &Arc, + ) -> std::task::Poll> { use std::ops::Deref; match self.bytes_available_read() { Ok(Some(0)) => { let waker = cx.waker().clone(); register_root_waker.deref()(waker); std::task::Poll::Pending - }, + } Ok(Some(a)) => std::task::Poll::Ready(Ok(a)), Ok(None) => std::task::Poll::Ready(Err(FsError::WouldBlock)), Err(err) => std::task::Poll::Ready(Err(err)), @@ -266,14 +269,18 @@ pub trait VirtualFile: fmt::Debug + Write + Read + Seek + Upcastable /// Polls for when the file can be written to again /// Defaults to `None` which means no asynchronous IO support - caller /// must poll `bytes_available_write` instead - fn poll_write_ready(&self, cx: &mut std::task::Context<'_>, register_root_waker: &Arc) -> std::task::Poll> { + fn poll_write_ready( + &self, + cx: &mut std::task::Context<'_>, + register_root_waker: &Arc, + ) -> std::task::Poll> { use std::ops::Deref; match self.bytes_available_write() { Ok(Some(0)) => { let waker = cx.waker().clone(); register_root_waker.deref()(waker); std::task::Poll::Pending - }, + } Ok(Some(a)) => std::task::Poll::Ready(Ok(a)), Ok(None) => std::task::Poll::Ready(Err(FsError::WouldBlock)), Err(err) => std::task::Poll::Ready(Err(err)), @@ -283,15 +290,19 @@ pub trait VirtualFile: fmt::Debug + Write + Read + Seek + Upcastable /// Polls for when the file can be written to again /// Defaults to `None` which means no asynchronous IO support - caller /// must poll `bytes_available_write` instead - fn poll_close_ready(&self, cx: &mut std::task::Context<'_>, register_root_waker: &Arc) -> std::task::Poll<()> { + fn poll_close_ready( + &self, + cx: &mut std::task::Context<'_>, + register_root_waker: &Arc, + ) -> std::task::Poll<()> { use std::ops::Deref; match self.is_open() { true => { let waker = cx.waker().clone(); register_root_waker.deref()(waker); std::task::Poll::Pending - }, - false => std::task::Poll::Ready(()) + } + false => std::task::Poll::Ready(()), } } @@ -322,8 +333,7 @@ pub trait Upcastable { fn upcast_any_box(self: Box) -> Box; } -pub trait ClonableVirtualFile: VirtualFile + Clone { -} +pub trait ClonableVirtualFile: VirtualFile + Clone {} impl Upcastable for T { #[inline] diff --git a/lib/vfs/src/mem_fs/file.rs b/lib/vfs/src/mem_fs/file.rs index 97e1844e3..9f7d4161a 100644 --- a/lib/vfs/src/mem_fs/file.rs +++ b/lib/vfs/src/mem_fs/file.rs @@ -28,9 +28,7 @@ pub(super) struct FileHandle { arc_file: Option>>, } -impl Clone -for FileHandle -{ +impl Clone for FileHandle { fn clone(&self) -> Self { Self { inode: self.inode.clone(), @@ -64,14 +62,13 @@ impl FileHandle { } } - fn lazy_load_arc_file_mut(&mut self) -> Result<&mut dyn VirtualFile> - { + fn lazy_load_arc_file_mut(&mut self) -> Result<&mut dyn VirtualFile> { if self.arc_file.is_none() { let fs = match self.filesystem.inner.read() { Ok(fs) => fs, _ => return Err(FsError::EntryNotFound), }; - + let inode = fs.storage.get(self.inode); match inode { Some(Node::ArcFile { fs, path, .. }) => { @@ -80,20 +77,19 @@ impl FileHandle { .read(self.readable) .write(self.writable) .append(self.append_mode) - .open(path.as_path()) + .open(path.as_path()), ); - }, - _ => return Err(FsError::EntryNotFound) + } + _ => return Err(FsError::EntryNotFound), } } - Ok( - self.arc_file - .as_mut() - .unwrap() - .as_mut() - .map_err(|err| err.clone())? - .as_mut() - ) + Ok(self + .arc_file + .as_mut() + .unwrap() + .as_mut() + .map_err(|err| err.clone())? + .as_mut()) } } @@ -152,28 +148,24 @@ impl VirtualFile for FileHandle { Some(Node::CustomFile { file, .. }) => { let file = file.lock().unwrap(); file.size().try_into().unwrap_or(0) - }, - Some(Node::ArcFile { fs, path, .. }) => { - match self.arc_file.as_ref() { - Some(file) => file - .as_ref() - .map(|file| file.size()) - .unwrap_or(0), - None => fs.new_open_options().read(self.readable).write(self.writable).append(self.append_mode).open(path.as_path()) - .map(|file| file.size()) - .unwrap_or(0), - } + } + Some(Node::ArcFile { fs, path, .. }) => match self.arc_file.as_ref() { + Some(file) => file.as_ref().map(|file| file.size()).unwrap_or(0), + None => fs + .new_open_options() + .read(self.readable) + .write(self.writable) + .append(self.append_mode) + .open(path.as_path()) + .map(|file| file.size()) + .unwrap_or(0), }, _ => 0, } } fn set_len(&mut self, new_size: u64) -> Result<()> { - let mut fs = self - .filesystem - .inner - .write() - .map_err(|_| FsError::Lock)?; + let mut fs = self.filesystem.inner.write().map_err(|_| FsError::Lock)?; let inode = fs.storage.get_mut(self.inode); match inode { @@ -181,20 +173,17 @@ impl VirtualFile for FileHandle { file.buffer .resize(new_size.try_into().map_err(|_| FsError::UnknownError)?, 0); metadata.len = new_size; - }, + } Some(Node::CustomFile { file, metadata, .. }) => { let mut file = file.lock().unwrap(); file.set_len(new_size)?; metadata.len = new_size; - }, - Some(Node::ReadOnlyFile { .. }) => { - return Err(FsError::PermissionDenied) - }, + } + Some(Node::ReadOnlyFile { .. }) => return Err(FsError::PermissionDenied), Some(Node::ArcFile { .. }) => { drop(fs); self.lazy_load_arc_file_mut() .map(|file| file.set_len(new_size))??; - } _ => return Err(FsError::NotAFile), } @@ -205,11 +194,7 @@ impl VirtualFile for FileHandle { fn unlink(&mut self) -> Result<()> { let (inode_of_parent, position, inode_of_file) = { // Read lock. - let fs = self - .filesystem - .inner - .read() - .map_err(|_| FsError::Lock)?; + let fs = self.filesystem.inner.read().map_err(|_| FsError::Lock)?; // The inode of the file. let inode_of_file = self.inode; @@ -228,7 +213,7 @@ impl VirtualFile for FileHandle { None } }) - }, + } _ => None, }) @@ -239,11 +224,7 @@ impl VirtualFile for FileHandle { { // Write lock. - let mut fs = self - .filesystem - .inner - .write() - .map_err(|_| FsError::Lock)?; + let mut fs = self.filesystem.inner.write().map_err(|_| FsError::Lock)?; // Remove the file from the storage. fs.storage.remove(inode_of_file); @@ -256,11 +237,7 @@ impl VirtualFile for FileHandle { } fn bytes_available(&self) -> Result { - let fs = self - .filesystem - .inner - .read() - .map_err(|_| FsError::Lock)?; + let fs = self.filesystem.inner.read().map_err(|_| FsError::Lock)?; let inode = fs.storage.get(self.inode); match inode { @@ -269,17 +246,20 @@ impl VirtualFile for FileHandle { Some(Node::CustomFile { file, .. }) => { let file = file.lock().unwrap(); file.bytes_available() - }, - Some(Node::ArcFile { fs, path, .. }) => { - match self.arc_file.as_ref() { - Some(file) => file - .as_ref() - .map(|file| file.bytes_available()) - .map_err(|err| err.clone())?, - None => fs.new_open_options().read(self.readable).write(self.writable).append(self.append_mode).open(path.as_path()) - .map(|file| file.bytes_available())?, - } } + Some(Node::ArcFile { fs, path, .. }) => match self.arc_file.as_ref() { + Some(file) => file + .as_ref() + .map(|file| file.bytes_available()) + .map_err(|err| err.clone())?, + None => fs + .new_open_options() + .read(self.readable) + .write(self.writable) + .append(self.append_mode) + .open(path.as_path()) + .map(|file| file.bytes_available())?, + }, _ => Err(FsError::NotAFile), } } @@ -289,13 +269,11 @@ impl VirtualFile for FileHandle { } fn get_special_fd(&self) -> Option { - let fs = match self - .filesystem - .inner - .read() - { + let fs = match self.filesystem.inner.read() { Ok(a) => a, - Err(_) => { return None; } + Err(_) => { + return None; + } }; let inode = fs.storage.get(self.inode); @@ -303,18 +281,21 @@ impl VirtualFile for FileHandle { Some(Node::CustomFile { file, .. }) => { let file = file.lock().unwrap(); file.get_special_fd() - }, - Some(Node::ArcFile { fs, path, .. }) => { - match self.arc_file.as_ref() { - Some(file) => file - .as_ref() - .map(|file| file.get_special_fd()) - .unwrap_or(None), - None => fs.new_open_options().read(self.readable).write(self.writable).append(self.append_mode).open(path.as_path()) - .map(|file| file.get_special_fd()) - .unwrap_or(None), - } } + Some(Node::ArcFile { fs, path, .. }) => match self.arc_file.as_ref() { + Some(file) => file + .as_ref() + .map(|file| file.get_special_fd()) + .unwrap_or(None), + None => fs + .new_open_options() + .read(self.readable) + .write(self.writable) + .append(self.append_mode) + .open(path.as_path()) + .map(|file| file.get_special_fd()) + .unwrap_or(None), + }, _ => None, } } @@ -557,16 +538,18 @@ impl Read for FileHandle { let read = file.read(buf)?; self.cursor += read as u64; Ok(read) - }, + } Some(Node::ArcFile { .. }) => { drop(fs); self.lazy_load_arc_file_mut() .map(|file| file.read(buf)) - .map_err(|_| io::Error::new( - io::ErrorKind::NotFound, - format!("inode `{}` doesn't match a file", self.inode), - ))? - }, + .map_err(|_| { + io::Error::new( + io::ErrorKind::NotFound, + format!("inode `{}` doesn't match a file", self.inode), + ) + })? + } _ => { return Err(io::Error::new( io::ErrorKind::NotFound, @@ -602,16 +585,18 @@ impl Read for FileHandle { let read = file.read_to_end(buf)?; self.cursor += read as u64; Ok(read) - }, + } Some(Node::ArcFile { .. }) => { drop(fs); self.lazy_load_arc_file_mut() .map(|file| file.read_to_end(buf)) - .map_err(|_| io::Error::new( - io::ErrorKind::NotFound, - format!("inode `{}` doesn't match a file", self.inode), - ))? - }, + .map_err(|_| { + io::Error::new( + io::ErrorKind::NotFound, + format!("inode `{}` doesn't match a file", self.inode), + ) + })? + } _ => { return Err(io::Error::new( io::ErrorKind::NotFound, @@ -666,16 +651,18 @@ impl Read for FileHandle { file.read_exact(buf)?; self.cursor += buf.len() as u64; Ok(()) - }, + } Some(Node::ArcFile { .. }) => { drop(fs); self.lazy_load_arc_file_mut() .map(|file| file.read_exact(buf)) - .map_err(|_| io::Error::new( - io::ErrorKind::NotFound, - format!("inode `{}` doesn't match a file", self.inode), - ))? - }, + .map_err(|_| { + io::Error::new( + io::ErrorKind::NotFound, + format!("inode `{}` doesn't match a file", self.inode), + ) + })? + } _ => { return Err(io::Error::new( io::ErrorKind::NotFound, @@ -721,16 +708,18 @@ impl Seek for FileHandle { let pos = file.seek(position)?; self.cursor = pos; Ok(pos) - }, + } Some(Node::ArcFile { .. }) => { drop(fs); self.lazy_load_arc_file_mut() .map(|file| file.seek(position)) - .map_err(|_| io::Error::new( - io::ErrorKind::NotFound, - format!("inode `{}` doesn't match a file", self.inode), - ))? - }, + .map_err(|_| { + io::Error::new( + io::ErrorKind::NotFound, + format!("inode `{}` doesn't match a file", self.inode), + ) + })? + } _ => { return Err(io::Error::new( io::ErrorKind::NotFound, @@ -764,12 +753,12 @@ impl Write for FileHandle { let bytes_written = file.write(buf, &mut self.cursor)?; metadata.len = file.len().try_into().unwrap(); bytes_written - }, + } Some(Node::ReadOnlyFile { file, metadata, .. }) => { let bytes_written = file.write(buf, &mut self.cursor)?; metadata.len = file.len().try_into().unwrap(); bytes_written - }, + } Some(Node::CustomFile { file, metadata, .. }) => { let mut file = file.lock().unwrap(); let _ = file.seek(io::SeekFrom::Start(self.cursor as u64)); @@ -777,16 +766,18 @@ impl Write for FileHandle { self.cursor += bytes_written as u64; metadata.len = file.size().try_into().unwrap(); bytes_written - }, + } Some(Node::ArcFile { .. }) => { drop(fs); self.lazy_load_arc_file_mut() .map(|file| file.write(buf)) - .map_err(|_| io::Error::new( - io::ErrorKind::NotFound, - format!("inode `{}` doesn't match a file", self.inode), - ))?? - }, + .map_err(|_| { + io::Error::new( + io::ErrorKind::NotFound, + format!("inode `{}` doesn't match a file", self.inode), + ) + })?? + } _ => { return Err(io::Error::new( io::ErrorKind::NotFound, @@ -810,22 +801,22 @@ impl Write for FileHandle { Some(Node::CustomFile { file, .. }) => { let mut file = file.lock().unwrap(); file.flush() - }, + } Some(Node::ArcFile { .. }) => { drop(fs); self.lazy_load_arc_file_mut() .map(|file| file.flush()) - .map_err(|_| io::Error::new( - io::ErrorKind::NotFound, - format!("inode `{}` doesn't match a file", self.inode), - ))? - }, - _ => { - Err(io::Error::new( - io::ErrorKind::NotFound, - format!("inode `{}` doesn't match a file", self.inode), - )) + .map_err(|_| { + io::Error::new( + io::ErrorKind::NotFound, + format!("inode `{}` doesn't match a file", self.inode), + ) + })? } + _ => Err(io::Error::new( + io::ErrorKind::NotFound, + format!("inode `{}` doesn't match a file", self.inode), + )), } } @@ -1095,9 +1086,7 @@ pub(super) struct File { impl File { pub(super) fn new() -> Self { - Self { - buffer: Vec::new(), - } + Self { buffer: Vec::new() } } pub(super) fn truncate(&mut self) { @@ -1256,9 +1245,7 @@ pub(super) struct ReadOnlyFile { impl ReadOnlyFile { pub(super) fn new(buffer: Cow<'static, [u8]>) -> Self { - Self { - buffer, - } + Self { buffer } } pub(super) fn len(&self) -> usize { diff --git a/lib/vfs/src/mem_fs/file_opener.rs b/lib/vfs/src/mem_fs/file_opener.rs index d4c470930..7b38a4998 100644 --- a/lib/vfs/src/mem_fs/file_opener.rs +++ b/lib/vfs/src/mem_fs/file_opener.rs @@ -1,5 +1,5 @@ -use super::*; use super::filesystem::InodeResolution; +use super::*; use crate::{FileType, FsError, Metadata, OpenOptionsConfig, Result, VirtualFile}; use std::borrow::Cow; use std::io::{self, Seek}; @@ -12,18 +12,12 @@ pub struct FileOpener { pub(super) filesystem: FileSystem, } -impl FileOpener -{ +impl FileOpener { /// Inserts a readonly file into the file system that uses copy-on-write /// (this is required for zero-copy creation of the same file) - pub fn insert_ro_file( - &mut self, - path: &Path, - contents: Cow<'static, [u8]> - ) -> Result<()> { + pub fn insert_ro_file(&mut self, path: &Path, contents: Cow<'static, [u8]>) -> Result<()> { let _ = crate::FileSystem::remove_file(&self.filesystem, path); - let (inode_of_parent, maybe_inode_of_file, name_of_file) = - self.insert_inode(path)?; + let (inode_of_parent, maybe_inode_of_file, name_of_file) = self.insert_inode(path)?; let inode_of_parent = match inode_of_parent { InodeResolution::Found(a) => a, @@ -31,7 +25,7 @@ impl FileOpener return Err(FsError::InvalidInput); } }; - + match maybe_inode_of_file { // The file already exists, then it can not be inserted. Some(_inode_of_file) => return Err(FsError::AlreadyExists), @@ -39,11 +33,7 @@ impl FileOpener // The file doesn't already exist; it's OK to create it if None => { // Write lock. - let mut fs = self - .filesystem - .inner - .write() - .map_err(|_| FsError::Lock)?; + let mut fs = self.filesystem.inner.write().map_err(|_| FsError::Lock)?; let file = ReadOnlyFile::new(contents); @@ -88,10 +78,10 @@ impl FileOpener pub fn insert_arc_file( &mut self, path: PathBuf, - fs: Arc + fs: Arc, ) -> Result<()> { let _ = crate::FileSystem::remove_file(&self.filesystem, path.as_path()); - let (inode_of_parent, maybe_inode_of_file, name_of_file) = + let (inode_of_parent, maybe_inode_of_file, name_of_file) = self.insert_inode(path.as_path())?; let inode_of_parent = match inode_of_parent { @@ -100,7 +90,7 @@ impl FileOpener return Err(FsError::InvalidInput); } }; - + match maybe_inode_of_file { // The file already exists, then it can not be inserted. Some(_inode_of_file) => return Err(FsError::AlreadyExists), @@ -108,11 +98,7 @@ impl FileOpener // The file doesn't already exist; it's OK to create it if None => { // Write lock. - let mut fs_lock = self - .filesystem - .inner - .write() - .map_err(|_| FsError::Lock)?; + let mut fs_lock = self.filesystem.inner.write().map_err(|_| FsError::Lock)?; // Creating the file in the storage. let inode_of_file = fs_lock.storage.vacant_entry().key(); @@ -155,10 +141,10 @@ impl FileOpener pub fn insert_arc_directory( &mut self, path: PathBuf, - fs: Arc + fs: Arc, ) -> Result<()> { let _ = crate::FileSystem::remove_dir(&self.filesystem, path.as_path()); - let (inode_of_parent, maybe_inode_of_file, name_of_file) = + let (inode_of_parent, maybe_inode_of_file, name_of_file) = self.insert_inode(path.as_path())?; let inode_of_parent = match inode_of_parent { @@ -167,7 +153,7 @@ impl FileOpener return Err(FsError::InvalidInput); } }; - + match maybe_inode_of_file { // The file already exists, then it can not be inserted. Some(_inode_of_file) => return Err(FsError::AlreadyExists), @@ -175,11 +161,7 @@ impl FileOpener // The file doesn't already exist; it's OK to create it if None => { // Write lock. - let mut fs_lock = self - .filesystem - .inner - .write() - .map_err(|_| FsError::Lock)?; + let mut fs_lock = self.filesystem.inner.write().map_err(|_| FsError::Lock)?; // Creating the file in the storage. let inode_of_file = fs_lock.storage.vacant_entry().key(); @@ -222,19 +204,19 @@ impl FileOpener pub fn insert_custom_file( &mut self, path: PathBuf, - file: Box + file: Box, ) -> Result<()> { let _ = crate::FileSystem::remove_file(&self.filesystem, path.as_path()); - let (inode_of_parent, maybe_inode_of_file, name_of_file) = + let (inode_of_parent, maybe_inode_of_file, name_of_file) = self.insert_inode(path.as_path())?; - + let inode_of_parent = match inode_of_parent { InodeResolution::Found(a) => a, InodeResolution::Redirect(..) => { return Err(FsError::InvalidInput); } }; - + match maybe_inode_of_file { // The file already exists, then it can not be inserted. Some(_inode_of_file) => return Err(FsError::AlreadyExists), @@ -242,11 +224,7 @@ impl FileOpener // The file doesn't already exist; it's OK to create it if None => { // Write lock. - let mut fs_lock = self - .filesystem - .inner - .write() - .map_err(|_| FsError::Lock)?; + let mut fs_lock = self.filesystem.inner.write().map_err(|_| FsError::Lock)?; // Creating the file in the storage. let inode_of_file = fs_lock.storage.vacant_entry().key(); @@ -288,28 +266,26 @@ impl FileOpener path: &Path, ) -> Result<(InodeResolution, Option, OsString)> { // Read lock. - let fs = self - .filesystem - .inner - .read() - .map_err(|_| FsError::Lock)?; + let fs = self.filesystem.inner.read().map_err(|_| FsError::Lock)?; // Check the path has a parent. - let parent_of_path = path.parent().ok_or({ - FsError::BaseNotDirectory - })?; + let parent_of_path = path.parent().ok_or({ FsError::BaseNotDirectory })?; // Check the file name. let name_of_file = path .file_name() .ok_or(FsError::InvalidInput)? .to_os_string(); - + // Find the parent inode. let inode_of_parent = match fs.inode_of_parent(parent_of_path)? { InodeResolution::Found(a) => a, InodeResolution::Redirect(fs, parent_path) => { - return Ok((InodeResolution::Redirect(fs, parent_path), None, name_of_file)); + return Ok(( + InodeResolution::Redirect(fs, parent_path), + None, + name_of_file, + )); } }; @@ -317,8 +293,12 @@ impl FileOpener let maybe_inode_of_file = fs .as_parent_get_position_and_inode_of_file(inode_of_parent, &name_of_file)? .map(|(_nth, inode)| inode); - - Ok((InodeResolution::Found(inode_of_parent), maybe_inode_of_file, name_of_file)) + + Ok(( + InodeResolution::Found(inode_of_parent), + maybe_inode_of_file, + name_of_file, + )) } } @@ -354,19 +334,19 @@ impl crate::FileOpener for FileOpener { write = false; } - let (inode_of_parent, maybe_inode_of_file, name_of_file) = - self.insert_inode(path)?; - + let (inode_of_parent, maybe_inode_of_file, name_of_file) = self.insert_inode(path)?; + let inode_of_parent = match inode_of_parent { InodeResolution::Found(a) => a, InodeResolution::Redirect(fs, mut parent_path) => { parent_path.push(name_of_file); - return fs.new_open_options() - .options(conf.clone()) - .open(parent_path); + return fs + .new_open_options() + .options(conf.clone()) + .open(parent_path); } }; - + let mut cursor = 0u64; let inode_of_file = match maybe_inode_of_file { // The file already exists, and a _new_ one _must_ be @@ -375,22 +355,15 @@ impl crate::FileOpener for FileOpener { // The file already exists; it's OK. Some(inode_of_file) => { - let inode_of_file = match inode_of_file { InodeResolution::Found(a) => a, InodeResolution::Redirect(fs, path) => { - return fs.new_open_options() - .options(conf.clone()) - .open(path); + return fs.new_open_options().options(conf.clone()).open(path); } }; - + // Write lock. - let mut fs = self - .filesystem - .inner - .write() - .map_err(|_| FsError::Lock)?; + let mut fs = self.filesystem.inner.write().map_err(|_| FsError::Lock)?; let inode = fs.storage.get_mut(inode_of_file); match inode { @@ -408,7 +381,7 @@ impl crate::FileOpener for FileOpener { if append { cursor = file.len() as u64; } - }, + } Some(Node::ReadOnlyFile { metadata, .. }) => { // Update the accessed time. @@ -437,7 +410,9 @@ impl crate::FileOpener for FileOpener { } } - Some(Node::ArcFile { metadata, fs, path, .. }) => { + Some(Node::ArcFile { + metadata, fs, path, .. + }) => { // Update the accessed time. metadata.accessed = time(); @@ -478,11 +453,7 @@ impl crate::FileOpener for FileOpener { // 2. `create` is used with `write` or `append`. None if (create_new || create) && (write || append) => { // Write lock. - let mut fs = self - .filesystem - .inner - .write() - .map_err(|_| FsError::Lock)?; + let mut fs = self.filesystem.inner.write().map_err(|_| FsError::Lock)?; let file = File::new(); @@ -530,7 +501,7 @@ impl crate::FileOpener for FileOpener { read, write || append || truncate, append, - cursor + cursor, ))) } } diff --git a/lib/vfs/src/mem_fs/filesystem.rs b/lib/vfs/src/mem_fs/filesystem.rs index e8a70a410..867a6064c 100644 --- a/lib/vfs/src/mem_fs/filesystem.rs +++ b/lib/vfs/src/mem_fs/filesystem.rs @@ -20,8 +20,7 @@ pub struct FileSystem { pub(super) inner: Arc>, } -impl FileSystem -{ +impl FileSystem { pub fn new_open_options_ext(&self) -> FileOpener { let opener = FileOpener { filesystem: self.clone(), @@ -35,7 +34,11 @@ impl FileSystem let mut remaining = VecDeque::new(); remaining.push_back(PathBuf::from("/")); while let Some(next) = remaining.pop_back() { - if next.file_name().map(|n| n.to_string_lossy().starts_with(".wh.")).unwrap_or(false) { + if next + .file_name() + .map(|n| n.to_string_lossy().starts_with(".wh.")) + .unwrap_or(false) + { let rm = next.to_string_lossy(); let rm = &rm[".wh.".len()..]; let rm = PathBuf::from(rm); @@ -50,7 +53,7 @@ impl FileSystem match sub_dir.file_type() { Ok(t) if t.is_dir() => { remaining.push_back(sub_dir.path()); - }, + } Ok(t) if t.is_file() => { if sub_dir.file_name().to_string_lossy().starts_with(".wh.") { let rm = next.to_string_lossy(); @@ -60,20 +63,24 @@ impl FileSystem let _ = crate::FileSystem::remove_file(self, rm.as_path()); continue; } - let _ = self.new_open_options_ext() - .insert_arc_file(sub_dir.path(), - other.clone()); - }, - _ => { } + let _ = self + .new_open_options_ext() + .insert_arc_file(sub_dir.path(), other.clone()); + } + _ => {} } } } } } - } - pub fn mount(&self, path: PathBuf, other: &Arc, dst: PathBuf) -> Result<()> { + pub fn mount( + &self, + path: PathBuf, + other: &Arc, + dst: PathBuf, + ) -> Result<()> { if crate::FileSystem::read_dir(self, path.as_path()).is_ok() { return Err(FsError::AlreadyExists); } @@ -88,7 +95,7 @@ impl FileSystem // Check the path has a parent. let parent_of_path = path.parent().ok_or(FsError::BaseNotDirectory)?; - + // Check the directory name. let name_of_directory = path .file_name() @@ -163,22 +170,20 @@ impl crate::FileSystem for FileSystem { // Check it's a directory and fetch the immediate children as `DirEntry`. let inode = guard.storage.get(inode_of_directory); let children = match inode { - Some(Node::Directory { children, .. }) => { - children - .iter() - .filter_map(|inode| guard.storage.get(*inode)) - .map(|node| DirEntry { - path: { - let mut entry_path = path.to_path_buf(); - entry_path.push(node.name()); + Some(Node::Directory { children, .. }) => children + .iter() + .filter_map(|inode| guard.storage.get(*inode)) + .map(|node| DirEntry { + path: { + let mut entry_path = path.to_path_buf(); + entry_path.push(node.name()); + + entry_path + }, + metadata: Ok(node.metadata().clone()), + }) + .collect(), - entry_path - }, - metadata: Ok(node.metadata().clone()), - }) - .collect() - }, - Some(Node::ArcDirectory { fs, path, .. }) => { return fs.read_dir(path.as_path()); } @@ -291,11 +296,12 @@ impl crate::FileSystem for FileSystem { // Get the child index to remove in the parent node, in // addition to the inode of the directory to remove. - let (position, inode_of_directory) = guard.as_parent_get_position_and_inode_of_directory( - inode_of_parent, - &name_of_directory, - DirectoryMustBeEmpty::Yes, - )?; + let (position, inode_of_directory) = guard + .as_parent_get_position_and_inode_of_directory( + inode_of_parent, + &name_of_directory, + DirectoryMustBeEmpty::Yes, + )?; (inode_of_parent, position, inode_of_directory) }; @@ -431,14 +437,12 @@ impl crate::FileSystem for FileSystem { // Read lock. let guard = self.inner.read().map_err(|_| FsError::Lock)?; match guard.inode_of(path)? { - InodeResolution::Found(inode) => { - Ok(guard - .storage - .get(inode) - .ok_or(FsError::UnknownError)? - .metadata() - .clone()) - }, + InodeResolution::Found(inode) => Ok(guard + .storage + .get(inode) + .ok_or(FsError::UnknownError)? + .metadata() + .clone()), InodeResolution::Redirect(fs, path) => { drop(guard); fs.metadata(path.as_path()) @@ -525,14 +529,12 @@ pub(super) struct FileSystemInner { } #[derive(Debug)] -pub(super) enum InodeResolution -{ +pub(super) enum InodeResolution { Found(Inode), - Redirect(Arc, PathBuf) + Redirect(Arc, PathBuf), } -impl InodeResolution -{ +impl InodeResolution { #[allow(dead_code)] pub fn unwrap(&self) -> Inode { match self { @@ -563,21 +565,21 @@ impl FileSystemInner { .filter_map(|inode| self.storage.get(*inode)) .find(|node| node.name() == component.as_os_str()) .ok_or(FsError::EntryNotFound)?, - Node::ArcDirectory { fs, path: fs_path, .. } => { + Node::ArcDirectory { + fs, path: fs_path, .. + } => { let mut path = fs_path.clone(); path.push(PathBuf::from(component.as_os_str())); while let Some(component) = components.next() { path.push(PathBuf::from(component.as_os_str())); } - return Ok(InodeResolution::Redirect(fs.clone(), path)) - }, + return Ok(InodeResolution::Redirect(fs.clone(), path)); + } _ => return Err(FsError::BaseNotDirectory), }; } - Ok( - InodeResolution::Found(node.inode()) - ) + Ok(InodeResolution::Found(node.inode())) } /// Get the inode associated to a “parent path”. The returned @@ -589,12 +591,10 @@ impl FileSystemInner { match self.storage.get(inode_of_parent) { Some(Node::Directory { .. }) => Ok(InodeResolution::Found(inode_of_parent)), Some(Node::ArcDirectory { .. }) => Ok(InodeResolution::Found(inode_of_parent)), - _ => { - Err(FsError::BaseNotDirectory) - }, + _ => Err(FsError::BaseNotDirectory), } - }, - InodeResolution::Redirect(fs, path) => { + } + InodeResolution::Redirect(fs, path) => { return Ok(InodeResolution::Redirect(fs, path)); } } @@ -632,15 +632,15 @@ impl FileSystemInner { .ok_or(FsError::InvalidInput) .and_then(identity), // flatten - Some(Node::ArcDirectory { fs, path: fs_path, .. }) => { + Some(Node::ArcDirectory { + fs, path: fs_path, .. + }) => { let mut path = fs_path.clone(); path.push(name_of_directory); Ok((0, InodeResolution::Redirect(fs.clone(), path))) - }, + } - _ => { - Err(FsError::BaseNotDirectory) - }, + _ => Err(FsError::BaseNotDirectory), } } @@ -657,23 +657,26 @@ impl FileSystemInner { .enumerate() .filter_map(|(nth, inode)| self.storage.get(*inode).map(|node| (nth, node))) .find_map(|(nth, node)| match node { - Node::File { inode, name, .. } | - Node::ReadOnlyFile { inode, name, .. } | - Node::CustomFile { inode, name, .. } | - Node::ArcFile { inode, name, .. } - if name.as_os_str() == name_of_file => { + Node::File { inode, name, .. } + | Node::ReadOnlyFile { inode, name, .. } + | Node::CustomFile { inode, name, .. } + | Node::ArcFile { inode, name, .. } + if name.as_os_str() == name_of_file => + { Some(Some((nth, InodeResolution::Found(*inode)))) - }, + } _ => None, }) .or(Some(None)) .ok_or(FsError::InvalidInput), - - Some(Node::ArcDirectory { fs, path: fs_path, .. }) => { + + Some(Node::ArcDirectory { + fs, path: fs_path, .. + }) => { let mut path = fs_path.clone(); path.push(name_of_file); Ok(Some((0, InodeResolution::Redirect(fs.clone(), path)))) - }, + } _ => Err(FsError::BaseNotDirectory), } @@ -693,25 +696,27 @@ impl FileSystemInner { .enumerate() .filter_map(|(nth, inode)| self.storage.get(*inode).map(|node| (nth, node))) .find_map(|(nth, node)| match node { - Node::File { inode, name, .. } | - Node::Directory { inode, name, .. } | - Node::ReadOnlyFile { inode, name, .. } | - Node::CustomFile { inode, name, .. } | - Node::ArcFile { inode, name, .. } + Node::File { inode, name, .. } + | Node::Directory { inode, name, .. } + | Node::ReadOnlyFile { inode, name, .. } + | Node::CustomFile { inode, name, .. } + | Node::ArcFile { inode, name, .. } if name.as_os_str() == name_of => { Some(Some((nth, InodeResolution::Found(*inode)))) - }, + } _ => None, }) .or(Some(None)) .ok_or(FsError::InvalidInput), - - Some(Node::ArcDirectory { fs, path: fs_path, .. }) => { + + Some(Node::ArcDirectory { + fs, path: fs_path, .. + }) => { let mut path = fs_path.clone(); path.push(name_of); Ok(Some((0, InodeResolution::Redirect(fs.clone(), path)))) - }, + } _ => Err(FsError::BaseNotDirectory), } @@ -1600,49 +1605,67 @@ mod test_filesystem { let fs_inner = fs.inner.read().unwrap(); assert_eq!( - fs_inner.canonicalize(path!("/")).map(|(a, b)| (a, b.unwrap())), + fs_inner + .canonicalize(path!("/")) + .map(|(a, b)| (a, b.unwrap())), Ok((path!(buf "/"), ROOT_INODE)), "canonicalizing `/`", ); assert_eq!( - fs_inner.canonicalize(path!("foo")).map(|(a, b)| (a, b.unwrap())), + fs_inner + .canonicalize(path!("foo")) + .map(|(a, b)| (a, b.unwrap())), Err(FsError::InvalidInput), "canonicalizing `foo`", ); assert_eq!( - fs_inner.canonicalize(path!("/././././foo/")).map(|(a, b)| (a, b.unwrap())), + fs_inner + .canonicalize(path!("/././././foo/")) + .map(|(a, b)| (a, b.unwrap())), Ok((path!(buf "/foo"), 1)), "canonicalizing `/././././foo/`", ); assert_eq!( - fs_inner.canonicalize(path!("/foo/bar//")).map(|(a, b)| (a, b.unwrap())), + fs_inner + .canonicalize(path!("/foo/bar//")) + .map(|(a, b)| (a, b.unwrap())), Ok((path!(buf "/foo/bar"), 2)), "canonicalizing `/foo/bar//`", ); assert_eq!( - fs_inner.canonicalize(path!("/foo/bar/../bar")).map(|(a, b)| (a, b.unwrap())), + fs_inner + .canonicalize(path!("/foo/bar/../bar")) + .map(|(a, b)| (a, b.unwrap())), Ok((path!(buf "/foo/bar"), 2)), "canonicalizing `/foo/bar/../bar`", ); assert_eq!( - fs_inner.canonicalize(path!("/foo/bar/../..")).map(|(a, b)| (a, b.unwrap())), + fs_inner + .canonicalize(path!("/foo/bar/../..")) + .map(|(a, b)| (a, b.unwrap())), Ok((path!(buf "/"), ROOT_INODE)), "canonicalizing `/foo/bar/../..`", ); assert_eq!( - fs_inner.canonicalize(path!("/foo/bar/../../..")).map(|(a, b)| (a, b.unwrap())), + fs_inner + .canonicalize(path!("/foo/bar/../../..")) + .map(|(a, b)| (a, b.unwrap())), Err(FsError::InvalidInput), "canonicalizing `/foo/bar/../../..`", ); assert_eq!( - fs_inner.canonicalize(path!("C:/foo/")).map(|(a, b)| (a, b.unwrap())), + fs_inner + .canonicalize(path!("C:/foo/")) + .map(|(a, b)| (a, b.unwrap())), Err(FsError::InvalidInput), "canonicalizing `C:/foo/`", ); assert_eq!( - fs_inner.canonicalize(path!( - "/foo/./../foo/bar/../../foo/bar/./baz/./../baz/qux/../../baz/./qux/hello.txt" - )).map(|(a, b)| (a, b.unwrap())), + fs_inner + .canonicalize(path!( + "/foo/./../foo/bar/../../foo/bar/./baz/./../baz/qux/../../baz/./qux/hello.txt" + )) + .map(|(a, b)| (a, b.unwrap())), Ok((path!(buf "/foo/bar/baz/qux/hello.txt"), 5)), "canonicalizing a crazily stupid path name", ); diff --git a/lib/vfs/src/mem_fs/mod.rs b/lib/vfs/src/mem_fs/mod.rs index b667e24b0..0c06527f3 100644 --- a/lib/vfs/src/mem_fs/mod.rs +++ b/lib/vfs/src/mem_fs/mod.rs @@ -3,13 +3,17 @@ mod file_opener; mod filesystem; mod stdio; -use file::{File, ReadOnlyFile, FileHandle}; +use file::{File, FileHandle, ReadOnlyFile}; pub use file_opener::FileOpener; pub use filesystem::FileSystem; pub use stdio::{Stderr, Stdin, Stdout}; use crate::Metadata; -use std::{ffi::{OsStr, OsString}, sync::{Arc, Mutex}, path::PathBuf}; +use std::{ + ffi::{OsStr, OsString}, + path::PathBuf, + sync::{Arc, Mutex}, +}; type Inode = usize; const ROOT_INODE: Inode = 0; diff --git a/lib/vm/src/export.rs b/lib/vm/src/export.rs index 0bc7c62e8..d9df605e8 100644 --- a/lib/vm/src/export.rs +++ b/lib/vm/src/export.rs @@ -7,9 +7,9 @@ use crate::store::InternalStoreHandle; use crate::table::VMTable; use crate::vmcontext::VMFunctionKind; use crate::{MaybeInstanceOwned, VMCallerCheckedAnyfunc}; +use derivative::Derivative; use std::any::Any; use wasmer_types::FunctionType; -use derivative::Derivative; /// The value of an export passed from one instance to another. pub enum VMExtern { diff --git a/lib/vm/src/extern_ref.rs b/lib/vm/src/extern_ref.rs index ad59e1d18..79f71b876 100644 --- a/lib/vm/src/extern_ref.rs +++ b/lib/vm/src/extern_ref.rs @@ -1,5 +1,5 @@ -use std::any::Any; use derivative::Derivative; +use std::any::Any; use wasmer_types::RawValue; use crate::store::InternalStoreHandle; diff --git a/lib/vm/src/function_env.rs b/lib/vm/src/function_env.rs index 181574f17..f2f8b7284 100644 --- a/lib/vm/src/function_env.rs +++ b/lib/vm/src/function_env.rs @@ -1,5 +1,5 @@ -use std::any::Any; use derivative::Derivative; +use std::any::Any; /// Underlying FunctionEnvironment used by a `VMFunction`. #[derive(Derivative)] diff --git a/lib/vm/src/global.rs b/lib/vm/src/global.rs index d7d062687..a899f7cd6 100644 --- a/lib/vm/src/global.rs +++ b/lib/vm/src/global.rs @@ -1,7 +1,7 @@ use crate::{store::MaybeInstanceOwned, vmcontext::VMGlobalDefinition}; +use derivative::Derivative; use std::{cell::UnsafeCell, ptr::NonNull}; use wasmer_types::{GlobalType, StoreSnapshot}; -use derivative::Derivative; /// A Global instance #[derive(Derivative)] @@ -41,7 +41,7 @@ impl VMGlobal { Self { ty: self.ty, vm_global_definition: MaybeInstanceOwned::Host(Box::new(UnsafeCell::new( - self.vm_global_definition.as_ptr().as_ref().clone() + self.vm_global_definition.as_ptr().as_ref().clone(), ))), } } @@ -49,13 +49,9 @@ impl VMGlobal { /// Saves the global value into the snapshot pub fn save_snapshot(&self, index: usize, snapshot: &mut StoreSnapshot) { - let entry = snapshot.globals - .entry(index as u32) - .or_default(); - - let val = unsafe { - self.vm_global_definition.as_ptr().as_ref().val.u128 - }; + let entry = snapshot.globals.entry(index as u32).or_default(); + + let val = unsafe { self.vm_global_definition.as_ptr().as_ref().val.u128 }; *entry = val; } @@ -63,9 +59,7 @@ impl VMGlobal { pub fn restore_snapshot(&mut self, index: usize, snapshot: &StoreSnapshot) { let index = index as u32; if let Some(entry) = snapshot.globals.get(&index) { - let existing = unsafe { - self.vm_global_definition.as_ptr().as_ref().val.u128 - }; + let existing = unsafe { self.vm_global_definition.as_ptr().as_ref().val.u128 }; if existing != *entry { unsafe { self.vm_global_definition.as_ptr().as_mut().val.u128 = *entry; diff --git a/lib/vm/src/instance/allocator.rs b/lib/vm/src/instance/allocator.rs index e00625f5e..c6ca74193 100644 --- a/lib/vm/src/instance/allocator.rs +++ b/lib/vm/src/instance/allocator.rs @@ -5,8 +5,8 @@ use std::convert::TryFrom; use std::mem; use std::ptr::{self, NonNull}; use wasmer_types::entity::EntityRef; -use wasmer_types::{VMOffsets, VMMemoryDefinition}; use wasmer_types::{LocalMemoryIndex, LocalTableIndex, ModuleInfo}; +use wasmer_types::{VMMemoryDefinition, VMOffsets}; /// This is an intermediate type that manages the raw allocation and /// metadata when creating an [`Instance`]. diff --git a/lib/vm/src/instance/mod.rs b/lib/vm/src/instance/mod.rs index a70a0870e..121480480 100644 --- a/lib/vm/src/instance/mod.rs +++ b/lib/vm/src/instance/mod.rs @@ -14,9 +14,9 @@ use crate::store::{InternalStoreHandle, StoreObjects}; use crate::table::TableElement; use crate::trap::{catch_traps, Trap, TrapCode}; use crate::vmcontext::{ - VMBuiltinFunctionsArray, VMCallerCheckedAnyfunc, VMContext, VMFunctionContext, - VMFunctionImport, VMFunctionKind, VMGlobalDefinition, VMGlobalImport, - VMMemoryImport, VMSharedSignatureIndex, VMTableDefinition, VMTableImport, VMTrampoline, memory_copy, memory_fill, + memory_copy, memory_fill, VMBuiltinFunctionsArray, VMCallerCheckedAnyfunc, VMContext, + VMFunctionContext, VMFunctionImport, VMFunctionKind, VMGlobalDefinition, VMGlobalImport, + VMMemoryImport, VMSharedSignatureIndex, VMTableDefinition, VMTableImport, VMTrampoline, }; use crate::{FunctionBodyPtr, MaybeInstanceOwned, TrapHandlerFn, VMFunctionBody}; use crate::{LinearMemory, VMMemoryDefinition}; @@ -36,9 +36,9 @@ use std::sync::Arc; use wasmer_types::entity::{packed_option::ReservedValue, BoxedSlice, EntityRef, PrimaryMap}; use wasmer_types::{ DataIndex, DataInitializer, ElemIndex, ExportIndex, FunctionIndex, GlobalIndex, GlobalInit, - LocalFunctionIndex, LocalGlobalIndex, LocalMemoryIndex, LocalTableIndex, MemoryIndex, - ModuleInfo, Pages, SignatureIndex, TableIndex, TableInitializer, VMOffsets, LinearMemory, - MemoryError, VMMemoryDefinition + LinearMemory, LocalFunctionIndex, LocalGlobalIndex, LocalMemoryIndex, LocalTableIndex, + MemoryError, MemoryIndex, ModuleInfo, Pages, SignatureIndex, TableIndex, TableInitializer, + VMMemoryDefinition, VMOffsets, }; /// A WebAssembly instance. diff --git a/lib/vm/src/lib.rs b/lib/vm/src/lib.rs index 9b9903c0e..91a3aee9f 100644 --- a/lib/vm/src/lib.rs +++ b/lib/vm/src/lib.rs @@ -46,7 +46,6 @@ pub use crate::global::*; pub use crate::imports::Imports; pub use crate::instance::{InstanceAllocator, InstanceHandle}; pub use crate::memory::{VMMemory, VMOwnedMemory, VMSharedMemory}; -pub use wasmer_types::MemoryError; pub use crate::mmap::Mmap; pub use crate::probestack::PROBESTACK; pub use crate::sig_registry::SignatureRegistry; @@ -57,13 +56,14 @@ pub use crate::table::{TableElement, VMTable}; pub use crate::trap::*; pub use crate::vmcontext::{ VMCallerCheckedAnyfunc, VMContext, VMDynamicFunctionContext, VMFunctionContext, - VMFunctionImport, VMFunctionKind, VMGlobalDefinition, VMGlobalImport, - VMMemoryImport, VMSharedSignatureIndex, VMTableDefinition, VMTableImport, VMTrampoline, + VMFunctionImport, VMFunctionKind, VMGlobalDefinition, VMGlobalImport, VMMemoryImport, + VMSharedSignatureIndex, VMTableDefinition, VMTableImport, VMTrampoline, }; pub use wasmer_types::LibCall; -pub use wasmer_types::{MemoryStyle, VMMemoryDefinition}; +pub use wasmer_types::MemoryError; use wasmer_types::RawValue; pub use wasmer_types::TableStyle; +pub use wasmer_types::{MemoryStyle, VMMemoryDefinition}; pub use wasmer_types::{TargetSharedSignatureIndex, VMBuiltinFunctionIndex, VMOffsets}; #[deprecated( diff --git a/lib/vm/src/memory.rs b/lib/vm/src/memory.rs index 44db6cca8..d66221e6b 100644 --- a/lib/vm/src/memory.rs +++ b/lib/vm/src/memory.rs @@ -10,8 +10,11 @@ use more_asserts::assert_ge; use std::cell::UnsafeCell; use std::convert::TryInto; use std::ptr::NonNull; -use std::sync::{RwLock, Arc}; -use wasmer_types::{Bytes, MemoryStyle, MemoryType, Pages, MemoryError, LinearMemory, VMMemoryDefinition, MemoryRole}; +use std::sync::{Arc, RwLock}; +use wasmer_types::{ + Bytes, LinearMemory, MemoryError, MemoryRole, MemoryStyle, MemoryType, Pages, + VMMemoryDefinition, +}; // Represents a region of memory that plays a particular role #[derive(Debug, Clone)] @@ -37,8 +40,7 @@ struct WasmMmap { vm_memory_definition: MaybeInstanceOwned, } -impl WasmMmap -{ +impl WasmMmap { fn get_vm_memory_definition(&self) -> NonNull { self.vm_memory_definition.as_ptr() } @@ -106,14 +108,12 @@ impl WasmMmap Mmap::accessible_reserved(new_bytes, request_bytes).map_err(MemoryError::Region)?; let copy_len = self.alloc.len() - conf.offset_guard_size; - new_mmap.as_mut_slice()[..copy_len] - .copy_from_slice(&self.alloc.as_slice()[..copy_len]); + new_mmap.as_mut_slice()[..copy_len].copy_from_slice(&self.alloc.as_slice()[..copy_len]); self.alloc = new_mmap; } else if delta_bytes > 0 { // Make the newly allocated pages accessible. - self - .alloc + self.alloc .make_accessible(prev_bytes, delta_bytes) .map_err(MemoryError::Region)?; } @@ -132,18 +132,12 @@ impl WasmMmap } /// Marks a region of the memory for a particular role - pub fn mark_region(&mut self, start: u64, end: u64, role: MemoryRole) - { - self.regions.push(VMMemoryRegion { - start, - end, - role - }); + pub fn mark_region(&mut self, start: u64, end: u64, role: MemoryRole) { + self.regions.push(VMMemoryRegion { start, end, role }); } /// Returns the role of a part of the memory - pub fn region(&self, pointer: u64) -> MemoryRole - { + pub fn region(&self, pointer: u64) -> MemoryRole { for region in self.regions.iter() { if pointer >= region.start && pointer < region.end { return region.role; @@ -154,24 +148,24 @@ impl WasmMmap /// Copies the memory /// (in this case it performs a copy-on-write to save memory) - pub fn fork(&mut self) -> Result - { + pub fn fork(&mut self) -> Result { let mem_length = self.size.bytes().0; - let mut alloc = self.alloc + let mut alloc = self + .alloc .fork(Some(mem_length)) .map_err(|err| MemoryError::Generic(err))?; let base_ptr = alloc.as_mut_ptr(); - Ok( - Self { - vm_memory_definition: MaybeInstanceOwned::Host(Box::new(UnsafeCell::new(VMMemoryDefinition { + Ok(Self { + vm_memory_definition: MaybeInstanceOwned::Host(Box::new(UnsafeCell::new( + VMMemoryDefinition { base: base_ptr, current_length: mem_length, - }))), - alloc, - size: self.size, - regions: self.regions.clone(), - } - ) + }, + ))), + alloc, + size: self.size, + regions: self.regions.clone(), + }) } } @@ -189,8 +183,7 @@ struct VMMemoryConfig { offset_guard_size: usize, } -impl VMMemoryConfig -{ +impl VMMemoryConfig { fn ty(&self, minimum: Pages) -> MemoryType { let mut out = self.memory; out.minimum = minimum; @@ -212,8 +205,8 @@ pub struct VMOwnedMemory { config: VMMemoryConfig, } -unsafe impl Send for VMOwnedMemory { } -unsafe impl Sync for VMOwnedMemory { } +unsafe impl Send for VMOwnedMemory {} +unsafe impl Sync for VMOwnedMemory {} /// A shared linear memory instance. #[derive(Debug, Clone)] @@ -224,8 +217,8 @@ pub struct VMSharedMemory { config: VMMemoryConfig, } -unsafe impl Send for VMSharedMemory { } -unsafe impl Sync for VMSharedMemory { } +unsafe impl Send for VMSharedMemory {} +unsafe impl Sync for VMSharedMemory {} impl VMOwnedMemory { /// Create a new linear memory instance with specified minimum and maximum number of wasm pages. @@ -288,7 +281,7 @@ impl VMOwnedMemory { MemoryStyle::Static { bound, .. } => { assert_ge!(*bound, memory.minimum); *bound - }, + } }; let minimum_bytes = minimum_pages.bytes().0; let request_bytes = minimum_bytes.checked_add(offset_guard_bytes).unwrap(); @@ -318,7 +311,7 @@ impl VMOwnedMemory { alloc, size: memory.minimum, }; - + Ok(Self { mmap: mmap, config: VMMemoryConfig { @@ -326,26 +319,22 @@ impl VMOwnedMemory { offset_guard_size: offset_guard_bytes, memory: *memory, style: style.clone(), - } + }, }) } } -impl VMOwnedMemory -{ +impl VMOwnedMemory { /// Converts this owned memory into shared memory - pub fn to_shared(self) -> VMSharedMemory - { + pub fn to_shared(self) -> VMSharedMemory { VMSharedMemory { mmap: Arc::new(RwLock::new(self.mmap)), - config: self.config + config: self.config, } } } -impl LinearMemory -for VMOwnedMemory -{ +impl LinearMemory for VMOwnedMemory { /// Returns the type for this memory. fn ty(&self) -> MemoryType { let minimum = self.mmap.size(); @@ -382,14 +371,10 @@ for VMOwnedMemory /// Copies this memory to a new memory fn fork(&mut self) -> Result, MemoryError> { - Ok( - Box::new( - Self { - mmap: self.mmap.fork()?, - config: self.config.clone(), - } - ) - ) + Ok(Box::new(Self { + mmap: self.mmap.fork()?, + config: self.config.clone(), + })) } /// Marks a region of the memory for a particular role @@ -403,24 +388,19 @@ for VMOwnedMemory } } -impl Into -for VMOwnedMemory -{ +impl Into for VMOwnedMemory { fn into(self) -> VMMemory { VMMemory(Box::new(self)) } } -impl VMSharedMemory -{ +impl VMSharedMemory { /// Create a new linear memory instance with specified minimum and maximum number of wasm pages. /// /// This creates a `Memory` with owned metadata: this can be used to create a memory /// that will be imported into Wasm modules. pub fn new(memory: &MemoryType, style: &MemoryStyle) -> Result { - Ok( - VMOwnedMemory::new(memory, style)?.to_shared() - ) + Ok(VMOwnedMemory::new(memory, style)?.to_shared()) } /// Create a new linear memory instance with specified minimum and maximum number of wasm pages. @@ -435,15 +415,11 @@ impl VMSharedMemory style: &MemoryStyle, vm_memory_location: NonNull, ) -> Result { - Ok( - VMOwnedMemory::from_definition(memory, style, vm_memory_location)?.to_shared() - ) + Ok(VMOwnedMemory::from_definition(memory, style, vm_memory_location)?.to_shared()) } } -impl LinearMemory -for VMSharedMemory -{ +impl LinearMemory for VMSharedMemory { /// Returns the type for this memory. fn ty(&self) -> MemoryType { let minimum = { @@ -487,16 +463,10 @@ for VMSharedMemory /// Copies this memory to a new memory fn fork(&mut self) -> Result, MemoryError> { let mut guard = self.mmap.write().unwrap(); - Ok( - Box::new( - Self { - mmap: Arc::new(RwLock::new( - guard.fork()? - )), - config: self.config.clone(), - } - ) - ) + Ok(Box::new(Self { + mmap: Arc::new(RwLock::new(guard.fork()?)), + config: self.config.clone(), + })) } /// Marks a region of the memory for a particular role @@ -512,9 +482,7 @@ for VMSharedMemory } } -impl Into -for VMSharedMemory -{ +impl Into for VMSharedMemory { fn into(self) -> VMMemory { VMMemory(Box::new(self)) } @@ -524,17 +492,13 @@ for VMSharedMemory #[derive(Debug)] pub struct VMMemory(pub Box); -impl Into -for Box -{ +impl Into for Box { fn into(self) -> VMMemory { VMMemory(self) } } -impl LinearMemory -for VMMemory -{ +impl LinearMemory for VMMemory { /// Returns the type for this memory. fn ty(&self) -> MemoryType { self.0.ty() @@ -584,21 +548,18 @@ for VMMemory } } -impl VMMemory -{ +impl VMMemory { /// Creates a new linear memory instance of the correct type with specified /// minimum and maximum number of wasm pages. /// /// This creates a `Memory` with owned metadata: this can be used to create a memory /// that will be imported into Wasm modules. pub fn new(memory: &MemoryType, style: &MemoryStyle) -> Result { - Ok( - if memory.shared { - Self(Box::new(VMSharedMemory::new(memory, style)?)) - } else { - Self(Box::new(VMOwnedMemory::new(memory, style)?)) - } - ) + Ok(if memory.shared { + Self(Box::new(VMSharedMemory::new(memory, style)?)) + } else { + Self(Box::new(VMOwnedMemory::new(memory, style)?)) + }) } /// Create a new linear memory instance with specified minimum and maximum number of wasm pages. @@ -613,13 +574,19 @@ impl VMMemory style: &MemoryStyle, vm_memory_location: NonNull, ) -> Result { - Ok( - if memory.shared { - Self(Box::new(VMSharedMemory::from_definition(memory, style, vm_memory_location)?)) - } else { - Self(Box::new(VMOwnedMemory::from_definition(memory, style, vm_memory_location)?)) - } - ) + Ok(if memory.shared { + Self(Box::new(VMSharedMemory::from_definition( + memory, + style, + vm_memory_location, + )?)) + } else { + Self(Box::new(VMOwnedMemory::from_definition( + memory, + style, + vm_memory_location, + )?)) + }) } /// Creates VMMemory from a custom implementation - the following into implementations @@ -628,7 +595,8 @@ impl VMMemory /// - VMSharedMemory -> VMMemory /// - Box -> VMMemory pub fn from_custom(memory: IntoVMMemory) -> VMMemory - where IntoVMMemory: Into + where + IntoVMMemory: Into, { memory.into() } diff --git a/lib/vm/src/mmap.rs b/lib/vm/src/mmap.rs index 5b598bdfe..b547b6640 100644 --- a/lib/vm/src/mmap.rs +++ b/lib/vm/src/mmap.rs @@ -9,7 +9,7 @@ use more_asserts::assert_lt; use std::io; use std::ptr; use std::slice; -#[cfg(feature="tracing")] +#[cfg(feature = "tracing")] use tracing::trace; /// Round `size` up to the nearest multiple of `page_size`. @@ -34,29 +34,24 @@ pub struct Mmap { #[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] pub struct FdGuard(pub i32); -impl Default -for FdGuard -{ +impl Default for FdGuard { fn default() -> Self { Self(-1) } } -impl Clone -for FdGuard -{ +impl Clone for FdGuard { fn clone(&self) -> Self { - unsafe { - FdGuard(libc::dup(self.0)) - } + unsafe { FdGuard(libc::dup(self.0)) } } } -impl Drop -for FdGuard { +impl Drop for FdGuard { fn drop(&mut self) { if self.0 >= 0 { - unsafe { libc::close(self.0); } + unsafe { + libc::close(self.0); + } self.0 = -1; } } @@ -91,7 +86,6 @@ impl Mmap { accessible_size: usize, mapping_size: usize, ) -> Result { - let page_size = region::page::size(); assert_le!(accessible_size, mapping_size); assert_eq!(mapping_size & (page_size - 1), 0); @@ -111,16 +105,23 @@ impl Mmap { libc::tmpfile() }; if file == ptr::null_mut() { - return Err(format!("failed to create temporary file - {}", io::Error::last_os_error())); + return Err(format!( + "failed to create temporary file - {}", + io::Error::last_os_error() + )); } FdGuard(libc::fileno(file)) }; // First we initialize it with zeros if mapping_size > (u32::MAX as usize) { - unsafe { libc::ftruncate64(fd.0, mapping_size as i64); } + unsafe { + libc::ftruncate64(fd.0, mapping_size as i64); + } } else { - unsafe { libc::ftruncate(fd.0, mapping_size as i64); } + unsafe { + libc::ftruncate(fd.0, mapping_size as i64); + } } // Compute the flags @@ -321,15 +322,16 @@ impl Mmap { /// Copies the memory to a new swap file (using copy-on-write if available) #[cfg(not(target_os = "windows"))] - pub fn fork(&mut self, hint_used: Option) -> Result - { + pub fn fork(&mut self, hint_used: Option) -> Result { // Empty memory is an edge case if self.len == 0 { return Ok(Self::new()); } // First we sync all the data to the backing file - unsafe { libc::fdatasync(self.fd.0); } + unsafe { + libc::fdatasync(self.fd.0); + } // Open a new temporary file (which is used for swapping for the forked memory) let fd = unsafe { @@ -339,22 +341,26 @@ impl Mmap { libc::tmpfile() }; if file == ptr::null_mut() { - return Err(format!("failed to create temporary file - {}", io::Error::last_os_error())); + return Err(format!( + "failed to create temporary file - {}", + io::Error::last_os_error() + )); } FdGuard(libc::fileno(file)) }; // Attempt to do a shallow copy (needs a backing file system that supports it) unsafe { - if libc::ioctl(fd.0, 0x94, 9, self.fd.0) != 0 // FICLONE + if libc::ioctl(fd.0, 0x94, 9, self.fd.0) != 0 + // FICLONE { - #[cfg(feature="tracing")] + #[cfg(feature = "tracing")] trace!("memory copy started"); // Determine host much to copy let len = match hint_used { Some(a) => a, - None => self.len + None => self.len, }; // The shallow copy failed so we have to do it the hard way @@ -362,10 +368,13 @@ impl Mmap { let mut off_out: libc::off64_t = 0; let ret = libc::copy_file_range(self.fd.0, &mut off_in, fd.0, &mut off_out, len, 0); if ret < 0 { - return Err(format!("failed to copy temporary file data - {}", io::Error::last_os_error())); + return Err(format!( + "failed to copy temporary file data - {}", + io::Error::last_os_error() + )); } - #[cfg(feature="tracing")] + #[cfg(feature = "tracing")] trace!("memory copy finished (size={})", len); } } @@ -388,29 +397,26 @@ impl Mmap { return Err(io::Error::last_os_error().to_string()); } - Ok( - Self { - ptr: ptr as usize, - len: self.len, - fd, - } - ) + Ok(Self { + ptr: ptr as usize, + len: self.len, + fd, + }) } /// Copies the memory to a new swap file (using copy-on-write if available) #[cfg(target_os = "windows")] - pub fn fork(&mut self, hint_used: Option) -> Result - { + pub fn fork(&mut self, hint_used: Option) -> Result { // Create a new memory which we will copy to let new_mmap = Self::with_at_least(self.len)?; - #[cfg(feature="tracing")] + #[cfg(feature = "tracing")] trace!("memory copy started"); // Determine host much to copy let len = match hint_used { Some(a) => a, - None => self.len + None => self.len, }; // Copy the data to the new memory @@ -420,11 +426,9 @@ impl Mmap { std::ptr::copy_nonoverlapping(src, dst, len); } - #[cfg(feature="tracing")] + #[cfg(feature = "tracing")] trace!("memory copy finished (size={})", len); - Ok( - new_mmap - ) + Ok(new_mmap) } } diff --git a/lib/vm/src/store.rs b/lib/vm/src/store.rs index e75f1673e..4648d0e5e 100644 --- a/lib/vm/src/store.rs +++ b/lib/vm/src/store.rs @@ -295,9 +295,9 @@ impl MaybeInstanceOwned { } } -impl std::fmt::Debug -for MaybeInstanceOwned -where T: std::fmt::Debug +impl std::fmt::Debug for MaybeInstanceOwned +where + T: std::fmt::Debug, { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match self { @@ -305,7 +305,7 @@ where T: std::fmt::Debug write!(f, "host(")?; p.as_ref().fmt(f)?; write!(f, ")") - }, + } MaybeInstanceOwned::Instance(p) => { write!(f, "instance(")?; unsafe { p.as_ref().fmt(f)? }; diff --git a/lib/vm/src/table.rs b/lib/vm/src/table.rs index 40e38fa35..00c2555c2 100644 --- a/lib/vm/src/table.rs +++ b/lib/vm/src/table.rs @@ -10,11 +10,11 @@ use crate::vmcontext::VMTableDefinition; use crate::Trap; use crate::VMExternRef; use crate::VMFuncRef; +use derivative::Derivative; use std::cell::UnsafeCell; use std::convert::TryFrom; use std::fmt; use std::ptr::NonNull; -use derivative::Derivative; use wasmer_types::TableStyle; use wasmer_types::{TableType, TrapCode, Type as ValType}; @@ -315,9 +315,7 @@ impl VMTable { pub fn copy_on_write(&self) -> Result { let mut ret = Self::new(&self.table, &self.style)?; ret.copy(self, 0, 0, self.size()) - .map_err(|trap| { - format!("failed to copy the table - {:?}", trap) - })?; + .map_err(|trap| format!("failed to copy the table - {:?}", trap))?; Ok(ret) } diff --git a/lib/vm/src/trap/mod.rs b/lib/vm/src/trap/mod.rs index 1f6e30238..afa81642a 100644 --- a/lib/vm/src/trap/mod.rs +++ b/lib/vm/src/trap/mod.rs @@ -14,4 +14,4 @@ pub use traphandlers::{ TrapHandler, TrapHandlerFn, }; pub use traphandlers::{init_traps, resume_panic}; -pub use wasmer_types::TrapCode; \ No newline at end of file +pub use wasmer_types::TrapCode; diff --git a/lib/vm/src/trap/traphandlers.rs b/lib/vm/src/trap/traphandlers.rs index 7b7708e81..2899b5d18 100644 --- a/lib/vm/src/trap/traphandlers.rs +++ b/lib/vm/src/trap/traphandlers.rs @@ -1052,4 +1052,4 @@ pub fn lazy_per_thread_init() -> Result<(), Trap> { } } } -} \ No newline at end of file +} diff --git a/lib/vm/src/vmcontext.rs b/lib/vm/src/vmcontext.rs index ba3b4d967..9d209c7a8 100644 --- a/lib/vm/src/vmcontext.rs +++ b/lib/vm/src/vmcontext.rs @@ -313,7 +313,12 @@ mod test_vmglobal_import { /// # Safety /// The memory is not copied atomically and is not synchronized: it's the /// caller's responsibility to synchronize. -pub(crate) unsafe fn memory_copy(mem: &VMMemoryDefinition, dst: u32, src: u32, len: u32) -> Result<(), Trap> { +pub(crate) unsafe fn memory_copy( + mem: &VMMemoryDefinition, + dst: u32, + src: u32, + len: u32, +) -> Result<(), Trap> { // https://webassembly.github.io/reference-types/core/exec/instructions.html#exec-memory-copy if src .checked_add(len) @@ -347,7 +352,12 @@ pub(crate) unsafe fn memory_copy(mem: &VMMemoryDefinition, dst: u32, src: u32, l /// # Safety /// The memory is not filled atomically and is not synchronized: it's the /// caller's responsibility to synchronize. -pub(crate) unsafe fn memory_fill(mem: &VMMemoryDefinition, dst: u32, val: u32, len: u32) -> Result<(), Trap> { +pub(crate) unsafe fn memory_fill( + mem: &VMMemoryDefinition, + dst: u32, + val: u32, + len: u32, +) -> Result<(), Trap> { if dst .checked_add(len) .map_or(true, |m| usize::try_from(m).unwrap() > mem.current_length) diff --git a/lib/vnet/src/lib.rs b/lib/vnet/src/lib.rs index 46ffa0bb5..d514b314f 100644 --- a/lib/vnet/src/lib.rs +++ b/lib/vnet/src/lib.rs @@ -38,8 +38,7 @@ pub struct IpRoute { /// An implementation of virtual networking #[async_trait::async_trait] #[allow(unused_variables)] -pub trait VirtualNetworking: fmt::Debug + Send + Sync + 'static -{ +pub trait VirtualNetworking: fmt::Debug + Send + Sync + 'static { /// Establishes a web socket connection /// (note: this does not use the virtual sockets and is standalone /// functionality that works without the network being connected) @@ -151,7 +150,7 @@ pub trait VirtualNetworking: fmt::Debug + Send + Sync + 'static ) -> Result> { Err(NetworkError::Unsupported) } - + /// Opens a UDP socket that listens on a specific IP and Port combination /// Multiple servers (processes or threads) can bind to the same port if they each set /// the reuse-port and-or reuse-addr flags @@ -247,7 +246,10 @@ pub trait VirtualTcpListener: fmt::Debug + Send + Sync + 'static { fn peek(&mut self) -> Result; /// Polls the socket for when there is data to be received - fn poll_accept_ready(&mut self, cx: &mut std::task::Context<'_>) -> std::task::Poll>; + fn poll_accept_ready( + &mut self, + cx: &mut std::task::Context<'_>, + ) -> std::task::Poll>; /// Sets the accept timeout fn set_timeout(&mut self, timeout: Option) -> Result<()>; @@ -292,10 +294,16 @@ pub trait VirtualSocket: fmt::Debug + Send + Sync + 'static { fn status(&self) -> Result; /// Polls the socket for when there is data to be received - fn poll_read_ready(&mut self, cx: &mut std::task::Context<'_>) -> std::task::Poll>; + fn poll_read_ready( + &mut self, + cx: &mut std::task::Context<'_>, + ) -> std::task::Poll>; /// Polls the socket for when the backpressure allows for writing to the socket - fn poll_write_ready(&mut self, cx: &mut std::task::Context<'_>) -> std::task::Poll>; + fn poll_write_ready( + &mut self, + cx: &mut std::task::Context<'_>, + ) -> std::task::Poll>; } #[derive(Debug, Copy, Clone, PartialEq, Eq)] @@ -330,10 +338,16 @@ pub trait VirtualWebSocket: fmt::Debug + Send + Sync + 'static { fn try_recv(&mut self) -> Result>; /// Polls the socket for when there is data to be received - fn poll_read_ready(&mut self, cx: &mut std::task::Context<'_>) -> std::task::Poll>; + fn poll_read_ready( + &mut self, + cx: &mut std::task::Context<'_>, + ) -> std::task::Poll>; /// Polls the socket for when the backpressure allows for writing to the socket - fn poll_write_ready(&mut self, cx: &mut std::task::Context<'_>) -> std::task::Poll>; + fn poll_write_ready( + &mut self, + cx: &mut std::task::Context<'_>, + ) -> std::task::Poll>; } /// Connected sockets have a persistent connection to a remote peer @@ -543,8 +557,7 @@ pub trait VirtualUdpSocket: pub struct UnsupportedVirtualNetworking {} #[async_trait::async_trait] -impl VirtualNetworking for UnsupportedVirtualNetworking { -} +impl VirtualNetworking for UnsupportedVirtualNetworking {} #[derive(Error, Copy, Clone, Debug, PartialEq, Eq)] pub enum NetworkError { diff --git a/lib/wasi-local-networking/src/lib.rs b/lib/wasi-local-networking/src/lib.rs index 8aa6db2bb..c70f7a927 100644 --- a/lib/wasi-local-networking/src/lib.rs +++ b/lib/wasi-local-networking/src/lib.rs @@ -1,13 +1,13 @@ #![allow(unused_variables)] use bytes::Bytes; -use tokio::io::{AsyncRead, AsyncWriteExt}; use std::future::Future; use std::net::{IpAddr, Ipv4Addr, Ipv6Addr, Shutdown, SocketAddr}; use std::pin::Pin; use std::ptr; use std::sync::Mutex; -use std::task::{RawWakerVTable, RawWaker, Waker, Context, Poll}; +use std::task::{Context, Poll, RawWaker, RawWakerVTable, Waker}; use std::time::Duration; +use tokio::io::{AsyncRead, AsyncWriteExt}; #[allow(unused_imports, dead_code)] use tracing::{debug, error, info, trace, warn}; #[allow(unused_imports)] @@ -57,7 +57,7 @@ impl VirtualNetworking for LocalNetworking { Ok(Box::new(LocalUdpSocket { socket: LocalUdpSocketMode::Async(socket), addr, - nonblocking: false + nonblocking: false, })) } @@ -68,13 +68,9 @@ impl VirtualNetworking for LocalNetworking { timeout: Option, ) -> Result> { let stream = if let Some(timeout) = timeout { - match tokio::time::timeout(timeout, tokio::net::TcpStream::connect(&peer)) - .await - { + match tokio::time::timeout(timeout, tokio::net::TcpStream::connect(&peer)).await { Ok(a) => a, - Err(err) => { - Err(Into::::into(std::io::ErrorKind::TimedOut)) - } + Err(err) => Err(Into::::into(std::io::ErrorKind::TimedOut)), } } else { tokio::net::TcpStream::connect(peer).await @@ -89,7 +85,7 @@ impl VirtualNetworking for LocalNetworking { write_timeout: None, linger_timeout: None, nonblocking: false, - shutdown: None + shutdown: None, })) } @@ -128,41 +124,36 @@ impl VirtualTcpListener for LocalTcpListener { if nonblocking { let waker = unsafe { Waker::from_raw(RawWaker::new(ptr::null(), &NOOP_WAKER_VTABLE)) }; let mut cx = Context::from_waker(&waker); - return match self.stream + return match self + .stream .poll_accept(&mut cx) .map_err(io_err_into_net_error) { - Poll::Ready(Ok((sock, addr))) => { - Ok( - ( - Box::new(LocalTcpStream { - stream: sock, - addr, - connect_timeout: None, - read_timeout: None, - write_timeout: None, - linger_timeout: None, - nonblocking, - shutdown: None - }), - addr, - ) - ) - }, + Poll::Ready(Ok((sock, addr))) => Ok(( + Box::new(LocalTcpStream { + stream: sock, + addr, + connect_timeout: None, + read_timeout: None, + write_timeout: None, + linger_timeout: None, + nonblocking, + shutdown: None, + }), + addr, + )), Poll::Ready(Err(err)) => Err(err), - Poll::Pending => Err(NetworkError::WouldBlock) + Poll::Pending => Err(NetworkError::WouldBlock), }; } let timeout = self.timeout.clone(); let work = async move { match timeout { - Some(timeout) => { - tokio::time::timeout(timeout, self.stream.accept()) - .await - .map_err(|_| Into::::into(std::io::ErrorKind::WouldBlock))? - }, - None => self.stream.accept().await + Some(timeout) => tokio::time::timeout(timeout, self.stream.accept()) + .await + .map_err(|_| Into::::into(std::io::ErrorKind::WouldBlock))?, + None => self.stream.accept().await, } }; @@ -178,7 +169,7 @@ impl VirtualTcpListener for LocalTcpListener { write_timeout: None, linger_timeout: None, nonblocking, - shutdown: None + shutdown: None, }), addr, ) @@ -209,15 +200,13 @@ impl VirtualTcpListener for LocalTcpListener { write_timeout: None, linger_timeout: None, nonblocking: self.nonblocking, - shutdown: None + shutdown: None, }), addr, )); Ok(backlog.len()) - }, - Poll::Ready(Err(err)) => { - Err(io_err_into_net_error(err)) } + Poll::Ready(Err(err)) => Err(io_err_into_net_error(err)), Poll::Pending => { let backlog = self.backlog.lock().unwrap(); Ok(backlog.len()) @@ -225,7 +214,10 @@ impl VirtualTcpListener for LocalTcpListener { } } - fn poll_accept_ready(&mut self, cx: &mut std::task::Context<'_>) -> std::task::Poll> { + fn poll_accept_ready( + &mut self, + cx: &mut std::task::Context<'_>, + ) -> std::task::Poll> { self.stream .poll_accept(cx) .map_err(io_err_into_net_error) @@ -240,11 +232,11 @@ impl VirtualTcpListener for LocalTcpListener { write_timeout: None, linger_timeout: None, nonblocking: self.nonblocking, - shutdown: None + shutdown: None, }), addr, )); - backlog.len() + backlog.len() }) } @@ -264,11 +256,16 @@ impl VirtualTcpListener for LocalTcpListener { } fn set_ttl(&mut self, ttl: u8) -> Result<()> { - self.stream.set_ttl(ttl as u32).map_err(io_err_into_net_error) + self.stream + .set_ttl(ttl as u32) + .map_err(io_err_into_net_error) } fn ttl(&self) -> Result { - self.stream.ttl().map(|ttl| ttl as u8).map_err(io_err_into_net_error) + self.stream + .ttl() + .map(|ttl| ttl as u8) + .map_err(io_err_into_net_error) } fn set_nonblocking(&mut self, nonblocking: bool) -> Result<()> { @@ -299,20 +296,18 @@ impl VirtualTcpSocket for LocalTcpStream { match ty { TimeType::ReadTimeout => { self.read_timeout = timeout.clone(); - }, + } TimeType::WriteTimeout => { self.write_timeout = timeout.clone(); - }, + } TimeType::ConnectTimeout => { self.connect_timeout = timeout; } #[cfg(feature = "wasix")] TimeType::Linger => { self.linger_timeout = timeout.clone(); - }, - _ => { - return Err(NetworkError::InvalidInput) - }, + } + _ => return Err(NetworkError::InvalidInput), } Ok(()) } @@ -344,7 +339,9 @@ impl VirtualTcpSocket for LocalTcpStream { } fn set_nodelay(&mut self, nodelay: bool) -> Result<()> { - self.stream.set_nodelay(nodelay).map_err(io_err_into_net_error) + self.stream + .set_nodelay(nodelay) + .map_err(io_err_into_net_error) } fn nodelay(&self) -> Result { @@ -400,19 +397,15 @@ impl VirtualConnectedSocket for LocalTcpStream { let timeout = self.write_timeout.clone(); let work = async move { match timeout { - Some(timeout) => { - tokio::time::timeout(timeout, self.stream.write_all(&data[..])) - .await - .map_err(|_| Into::::into(std::io::ErrorKind::WouldBlock))? - }, - None => self.stream.write_all(&data[..]).await + Some(timeout) => tokio::time::timeout(timeout, self.stream.write_all(&data[..])) + .await + .map_err(|_| Into::::into(std::io::ErrorKind::WouldBlock))?, + None => self.stream.write_all(&data[..]).await, } .map(|_| data.len()) }; - let amt = work - .await - .map_err(io_err_into_net_error)?; + let amt = work.await.map_err(io_err_into_net_error)?; if amt == 0 { if nonblocking { return Err(NetworkError::WouldBlock); @@ -435,25 +428,23 @@ impl VirtualConnectedSocket for LocalTcpStream { let timeout = self.write_timeout.clone(); let work = async move { match timeout { - Some(timeout) => { - tokio::time::timeout(timeout, self.stream.flush()) - .await - .map_err(|_| Into::::into(std::io::ErrorKind::WouldBlock))? - }, - None => self.stream.flush().await + Some(timeout) => tokio::time::timeout(timeout, self.stream.flush()) + .await + .map_err(|_| Into::::into(std::io::ErrorKind::WouldBlock))?, + None => self.stream.flush().await, } }; - work - .await - .map_err(io_err_into_net_error) + work.await.map_err(io_err_into_net_error) } async fn recv(&mut self) -> Result { use tokio::io::AsyncReadExt; let max_buf_size = 8192; let mut buf = Vec::with_capacity(max_buf_size); - unsafe { buf.set_len(max_buf_size); } + unsafe { + buf.set_len(max_buf_size); + } let nonblocking = self.nonblocking; if nonblocking { @@ -464,7 +455,9 @@ impl VirtualConnectedSocket for LocalTcpStream { return match stream.poll_read(&mut cx, &mut read_buf) { Poll::Ready(Ok(read)) => { let read = read_buf.remaining(); - unsafe { buf.set_len(read); } + unsafe { + buf.set_len(read); + } if read == 0 { return Err(NetworkError::WouldBlock); } @@ -473,35 +466,29 @@ impl VirtualConnectedSocket for LocalTcpStream { data: buf, truncated: read == max_buf_size, }) - }, - Poll::Ready(Err(err)) => { - Err(io_err_into_net_error(err)) - }, - Poll::Pending => { - Err(NetworkError::WouldBlock) } + Poll::Ready(Err(err)) => Err(io_err_into_net_error(err)), + Poll::Pending => Err(NetworkError::WouldBlock), }; } let timeout = self.write_timeout.clone(); let work = async move { match timeout { - Some(timeout) => { - tokio::time::timeout(timeout, self.stream.read(&mut buf[..])) - .await - .map_err(|_| Into::::into(std::io::ErrorKind::WouldBlock))? - }, - None => self.stream.read(&mut buf[..]).await + Some(timeout) => tokio::time::timeout(timeout, self.stream.read(&mut buf[..])) + .await + .map_err(|_| Into::::into(std::io::ErrorKind::WouldBlock))?, + None => self.stream.read(&mut buf[..]).await, } .map(|read| { - unsafe { buf.set_len(read); } + unsafe { + buf.set_len(read); + } Bytes::from(buf) }) }; - let buf = work - .await - .map_err(io_err_into_net_error)?; + let buf = work.await.map_err(io_err_into_net_error)?; if buf.is_empty() { if nonblocking { return Err(NetworkError::WouldBlock); @@ -518,7 +505,9 @@ impl VirtualConnectedSocket for LocalTcpStream { fn try_recv(&mut self) -> Result> { let max_buf_size = 8192; let mut buf = Vec::with_capacity(max_buf_size); - unsafe { buf.set_len(max_buf_size); } + unsafe { + buf.set_len(max_buf_size); + } let waker = unsafe { Waker::from_raw(RawWaker::new(ptr::null(), &NOOP_WAKER_VTABLE)) }; let mut cx = Context::from_waker(&waker); @@ -527,7 +516,9 @@ impl VirtualConnectedSocket for LocalTcpStream { match stream.poll_read(&mut cx, &mut read_buf) { Poll::Ready(Ok(read)) => { let read = read_buf.remaining(); - unsafe { buf.set_len(read); } + unsafe { + buf.set_len(read); + } if read == 0 { return Err(NetworkError::WouldBlock); } @@ -536,20 +527,18 @@ impl VirtualConnectedSocket for LocalTcpStream { data: buf, truncated: read == max_buf_size, })) - }, - Poll::Ready(Err(err)) => { - Err(io_err_into_net_error(err)) - }, - Poll::Pending => { - Ok(None) } + Poll::Ready(Err(err)) => Err(io_err_into_net_error(err)), + Poll::Pending => Ok(None), } } async fn peek(&mut self) -> Result { let max_buf_size = 8192; let mut buf = Vec::with_capacity(max_buf_size); - unsafe { buf.set_len(max_buf_size); } + unsafe { + buf.set_len(max_buf_size); + } if self.nonblocking { let waker = unsafe { Waker::from_raw(RawWaker::new(ptr::null(), &NOOP_WAKER_VTABLE)) }; @@ -558,7 +547,9 @@ impl VirtualConnectedSocket for LocalTcpStream { let mut read_buf = tokio::io::ReadBuf::new(&mut buf); return match stream.poll_peek(&mut cx, &mut read_buf) { Poll::Ready(Ok(read)) => { - unsafe { buf.set_len(read); } + unsafe { + buf.set_len(read); + } if read == 0 { return Err(NetworkError::WouldBlock); } @@ -567,41 +558,35 @@ impl VirtualConnectedSocket for LocalTcpStream { data: buf, truncated: read == max_buf_size, }) - }, - Poll::Ready(Err(err)) => { - Err(io_err_into_net_error(err)) - }, - Poll::Pending => { - Err(NetworkError::WouldBlock) } + Poll::Ready(Err(err)) => Err(io_err_into_net_error(err)), + Poll::Pending => Err(NetworkError::WouldBlock), }; } let timeout = self.write_timeout.clone(); let work = async move { match timeout { - Some(timeout) => { - tokio::time::timeout(timeout, self.stream.peek(&mut buf[..])) - .await - .map_err(|_| Into::::into(std::io::ErrorKind::WouldBlock))? - }, - None => self.stream.peek(&mut buf[..]).await + Some(timeout) => tokio::time::timeout(timeout, self.stream.peek(&mut buf[..])) + .await + .map_err(|_| Into::::into(std::io::ErrorKind::WouldBlock))?, + None => self.stream.peek(&mut buf[..]).await, } .map(|read| { - unsafe { buf.set_len(read); } + unsafe { + buf.set_len(read); + } Bytes::from(buf) }) }; - let buf = work - .await - .map_err(io_err_into_net_error)?; + let buf = work.await.map_err(io_err_into_net_error)?; if buf.len() == 0 { return Err(NetworkError::BrokenPipe); } Ok(SocketReceive { truncated: buf.len() == max_buf_size, - data: buf, + data: buf, }) } } @@ -633,16 +618,20 @@ impl VirtualSocket for LocalTcpStream { Ok(SocketStatus::Opened) } - fn poll_read_ready(&mut self, cx: &mut std::task::Context<'_>) -> std::task::Poll> - { + fn poll_read_ready( + &mut self, + cx: &mut std::task::Context<'_>, + ) -> std::task::Poll> { self.stream .poll_read_ready(cx) .map_ok(|a| 8192usize) .map_err(io_err_into_net_error) } - fn poll_write_ready(&mut self, cx: &mut std::task::Context<'_>) -> std::task::Poll> - { + fn poll_write_ready( + &mut self, + cx: &mut std::task::Context<'_>, + ) -> std::task::Poll> { self.stream .poll_write_ready(cx) .map_ok(|a| 8192usize) @@ -653,12 +642,13 @@ impl VirtualSocket for LocalTcpStream { struct LocalTcpStreamReadReady<'a> { stream: &'a mut tokio::net::TcpStream, } -impl<'a> Future -for LocalTcpStreamReadReady<'a> -{ +impl<'a> Future for LocalTcpStreamReadReady<'a> { type Output = Result; - fn poll(self: std::pin::Pin<&mut Self>, cx: &mut std::task::Context<'_>) -> std::task::Poll { + fn poll( + self: std::pin::Pin<&mut Self>, + cx: &mut std::task::Context<'_>, + ) -> std::task::Poll { self.stream .poll_read_ready(cx) .map_err(io_err_into_net_error) @@ -669,12 +659,13 @@ for LocalTcpStreamReadReady<'a> struct LocalTcpStreamWriteReady<'a> { stream: &'a mut tokio::net::TcpStream, } -impl<'a> Future -for LocalTcpStreamWriteReady<'a> -{ +impl<'a> Future for LocalTcpStreamWriteReady<'a> { type Output = Result; - fn poll(self: std::pin::Pin<&mut Self>, cx: &mut std::task::Context<'_>) -> std::task::Poll { + fn poll( + self: std::pin::Pin<&mut Self>, + cx: &mut std::task::Context<'_>, + ) -> std::task::Poll { self.stream .poll_write_ready(cx) .map_err(io_err_into_net_error) @@ -687,18 +678,17 @@ pub struct LocalUdpSocket { socket: LocalUdpSocketMode, #[allow(dead_code)] addr: SocketAddr, - nonblocking: bool + nonblocking: bool, } #[derive(Debug)] enum LocalUdpSocketMode { Blocking(std::net::UdpSocket), Async(tokio::net::UdpSocket), - Uninitialized + Uninitialized, } -impl LocalUdpSocketMode -{ +impl LocalUdpSocketMode { fn as_blocking_mut(&mut self) -> std::io::Result<&mut std::net::UdpSocket> { match self { Self::Blocking(a) => Ok(a), @@ -712,10 +702,10 @@ impl LocalUdpSocketMode std::mem::swap(self, &mut listener); match self { Self::Blocking(a) => Ok(a), - _ => unreachable!() + _ => unreachable!(), } - }, - Self::Uninitialized => unreachable!() + } + Self::Uninitialized => unreachable!(), } } @@ -732,10 +722,10 @@ impl LocalUdpSocketMode std::mem::swap(self, &mut listener); match self { Self::Async(a) => Ok(a), - _ => unreachable!() + _ => unreachable!(), } - }, - Self::Uninitialized => unreachable!() + } + Self::Uninitialized => unreachable!(), } } } @@ -753,9 +743,13 @@ impl VirtualUdpSocket for LocalUdpSocket { fn set_broadcast(&mut self, broadcast: bool) -> Result<()> { match &mut self.socket { - LocalUdpSocketMode::Blocking(a) => a.set_broadcast(broadcast).map_err(io_err_into_net_error), - LocalUdpSocketMode::Async(a) => a.set_broadcast(broadcast).map_err(io_err_into_net_error), - LocalUdpSocketMode::Uninitialized => unreachable!() + LocalUdpSocketMode::Blocking(a) => { + a.set_broadcast(broadcast).map_err(io_err_into_net_error) + } + LocalUdpSocketMode::Async(a) => { + a.set_broadcast(broadcast).map_err(io_err_into_net_error) + } + LocalUdpSocketMode::Uninitialized => unreachable!(), } } @@ -763,15 +757,19 @@ impl VirtualUdpSocket for LocalUdpSocket { match &self.socket { LocalUdpSocketMode::Blocking(a) => a.broadcast().map_err(io_err_into_net_error), LocalUdpSocketMode::Async(a) => a.broadcast().map_err(io_err_into_net_error), - LocalUdpSocketMode::Uninitialized => unreachable!() + LocalUdpSocketMode::Uninitialized => unreachable!(), } } fn set_multicast_loop_v4(&mut self, val: bool) -> Result<()> { match &mut self.socket { - LocalUdpSocketMode::Blocking(a) => a.set_multicast_loop_v4(val).map_err(io_err_into_net_error), - LocalUdpSocketMode::Async(a) => a.set_multicast_loop_v4(val).map_err(io_err_into_net_error), - LocalUdpSocketMode::Uninitialized => unreachable!() + LocalUdpSocketMode::Blocking(a) => { + a.set_multicast_loop_v4(val).map_err(io_err_into_net_error) + } + LocalUdpSocketMode::Async(a) => { + a.set_multicast_loop_v4(val).map_err(io_err_into_net_error) + } + LocalUdpSocketMode::Uninitialized => unreachable!(), } } @@ -779,15 +777,19 @@ impl VirtualUdpSocket for LocalUdpSocket { match &self.socket { LocalUdpSocketMode::Blocking(a) => a.multicast_loop_v4().map_err(io_err_into_net_error), LocalUdpSocketMode::Async(a) => a.multicast_loop_v4().map_err(io_err_into_net_error), - LocalUdpSocketMode::Uninitialized => unreachable!() + LocalUdpSocketMode::Uninitialized => unreachable!(), } } fn set_multicast_loop_v6(&mut self, val: bool) -> Result<()> { match &mut self.socket { - LocalUdpSocketMode::Blocking(a) => a.set_multicast_loop_v6(val).map_err(io_err_into_net_error), - LocalUdpSocketMode::Async(a) => a.set_multicast_loop_v6(val).map_err(io_err_into_net_error), - LocalUdpSocketMode::Uninitialized => unreachable!() + LocalUdpSocketMode::Blocking(a) => { + a.set_multicast_loop_v6(val).map_err(io_err_into_net_error) + } + LocalUdpSocketMode::Async(a) => { + a.set_multicast_loop_v6(val).map_err(io_err_into_net_error) + } + LocalUdpSocketMode::Uninitialized => unreachable!(), } } @@ -795,15 +797,19 @@ impl VirtualUdpSocket for LocalUdpSocket { match &self.socket { LocalUdpSocketMode::Blocking(a) => a.multicast_loop_v6().map_err(io_err_into_net_error), LocalUdpSocketMode::Async(a) => a.multicast_loop_v6().map_err(io_err_into_net_error), - LocalUdpSocketMode::Uninitialized => unreachable!() + LocalUdpSocketMode::Uninitialized => unreachable!(), } } fn set_multicast_ttl_v4(&mut self, ttl: u32) -> Result<()> { match &mut self.socket { - LocalUdpSocketMode::Blocking(a) => a.set_multicast_ttl_v4(ttl).map_err(io_err_into_net_error), - LocalUdpSocketMode::Async(a) => a.set_multicast_ttl_v4(ttl).map_err(io_err_into_net_error), - LocalUdpSocketMode::Uninitialized => unreachable!() + LocalUdpSocketMode::Blocking(a) => { + a.set_multicast_ttl_v4(ttl).map_err(io_err_into_net_error) + } + LocalUdpSocketMode::Async(a) => { + a.set_multicast_ttl_v4(ttl).map_err(io_err_into_net_error) + } + LocalUdpSocketMode::Uninitialized => unreachable!(), } } @@ -811,47 +817,65 @@ impl VirtualUdpSocket for LocalUdpSocket { match &self.socket { LocalUdpSocketMode::Blocking(a) => a.multicast_ttl_v4().map_err(io_err_into_net_error), LocalUdpSocketMode::Async(a) => a.multicast_ttl_v4().map_err(io_err_into_net_error), - LocalUdpSocketMode::Uninitialized => unreachable!() + LocalUdpSocketMode::Uninitialized => unreachable!(), } } fn join_multicast_v4(&mut self, multiaddr: Ipv4Addr, iface: Ipv4Addr) -> Result<()> { match &mut self.socket { - LocalUdpSocketMode::Blocking(a) => a.join_multicast_v4(&multiaddr, &iface).map_err(io_err_into_net_error), - LocalUdpSocketMode::Async(a) => a.join_multicast_v4(multiaddr, iface).map_err(io_err_into_net_error), - LocalUdpSocketMode::Uninitialized => unreachable!() + LocalUdpSocketMode::Blocking(a) => a + .join_multicast_v4(&multiaddr, &iface) + .map_err(io_err_into_net_error), + LocalUdpSocketMode::Async(a) => a + .join_multicast_v4(multiaddr, iface) + .map_err(io_err_into_net_error), + LocalUdpSocketMode::Uninitialized => unreachable!(), } } fn leave_multicast_v4(&mut self, multiaddr: Ipv4Addr, iface: Ipv4Addr) -> Result<()> { match &mut self.socket { - LocalUdpSocketMode::Blocking(a) => a.leave_multicast_v4(&multiaddr, &iface).map_err(io_err_into_net_error), - LocalUdpSocketMode::Async(a) => a.leave_multicast_v4(multiaddr, iface).map_err(io_err_into_net_error), - LocalUdpSocketMode::Uninitialized => unreachable!() + LocalUdpSocketMode::Blocking(a) => a + .leave_multicast_v4(&multiaddr, &iface) + .map_err(io_err_into_net_error), + LocalUdpSocketMode::Async(a) => a + .leave_multicast_v4(multiaddr, iface) + .map_err(io_err_into_net_error), + LocalUdpSocketMode::Uninitialized => unreachable!(), } } fn join_multicast_v6(&mut self, multiaddr: Ipv6Addr, iface: u32) -> Result<()> { match &mut self.socket { - LocalUdpSocketMode::Blocking(a) => a.join_multicast_v6(&multiaddr, iface).map_err(io_err_into_net_error), - LocalUdpSocketMode::Async(a) => a.join_multicast_v6(&multiaddr, iface).map_err(io_err_into_net_error), - LocalUdpSocketMode::Uninitialized => unreachable!() + LocalUdpSocketMode::Blocking(a) => a + .join_multicast_v6(&multiaddr, iface) + .map_err(io_err_into_net_error), + LocalUdpSocketMode::Async(a) => a + .join_multicast_v6(&multiaddr, iface) + .map_err(io_err_into_net_error), + LocalUdpSocketMode::Uninitialized => unreachable!(), } } fn leave_multicast_v6(&mut self, multiaddr: Ipv6Addr, iface: u32) -> Result<()> { match &mut self.socket { - LocalUdpSocketMode::Blocking(a) => a.leave_multicast_v6(&multiaddr, iface).map_err(io_err_into_net_error), - LocalUdpSocketMode::Async(a) => a.leave_multicast_v6(&multiaddr, iface).map_err(io_err_into_net_error), - LocalUdpSocketMode::Uninitialized => unreachable!() + LocalUdpSocketMode::Blocking(a) => a + .leave_multicast_v6(&multiaddr, iface) + .map_err(io_err_into_net_error), + LocalUdpSocketMode::Async(a) => a + .leave_multicast_v6(&multiaddr, iface) + .map_err(io_err_into_net_error), + LocalUdpSocketMode::Uninitialized => unreachable!(), } } fn addr_peer(&self) -> Result> { match &self.socket { - LocalUdpSocketMode::Blocking(a) => a.peer_addr().map(Some).map_err(io_err_into_net_error), + LocalUdpSocketMode::Blocking(a) => { + a.peer_addr().map(Some).map_err(io_err_into_net_error) + } LocalUdpSocketMode::Async(a) => a.peer_addr().map(Some).map_err(io_err_into_net_error), - LocalUdpSocketMode::Uninitialized => unreachable!() + LocalUdpSocketMode::Uninitialized => unreachable!(), } } } @@ -867,7 +891,8 @@ impl VirtualConnectedSocket for LocalUdpSocket { } async fn send(&mut self, data: Bytes) -> Result { - let amt = self.socket + let amt = self + .socket .as_async_mut() .map_err(io_err_into_net_error)? .send(&data[..]) @@ -890,15 +915,20 @@ impl VirtualConnectedSocket for LocalUdpSocket { async fn recv(&mut self) -> Result { let buf_size = 8192; let mut buf = Vec::with_capacity(buf_size); - unsafe { buf.set_len(buf_size); } + unsafe { + buf.set_len(buf_size); + } - let read = self.socket + let read = self + .socket .as_async_mut() .map_err(io_err_into_net_error)? .recv(&mut buf[..]) .await .map_err(io_err_into_net_error)?; - unsafe { buf.set_len(read); } + unsafe { + buf.set_len(read); + } if read == 0 { if self.nonblocking { return Err(NetworkError::WouldBlock); @@ -916,10 +946,17 @@ impl VirtualConnectedSocket for LocalUdpSocket { fn try_recv(&mut self) -> Result> { let buf_size = 8192; let mut buf = Vec::with_capacity(buf_size); - unsafe { buf.set_len(buf_size); } + unsafe { + buf.set_len(buf_size); + } - let socket = self.socket.as_blocking_mut().map_err(io_err_into_net_error)?; - socket.set_nonblocking(true).map_err(io_err_into_net_error)?; + let socket = self + .socket + .as_blocking_mut() + .map_err(io_err_into_net_error)?; + socket + .set_nonblocking(true) + .map_err(io_err_into_net_error)?; let read = socket.recv(&mut buf[..]); let _ = socket.set_nonblocking(self.nonblocking); @@ -928,13 +965,17 @@ impl VirtualConnectedSocket for LocalUdpSocket { return Ok(None); } Ok(a) => Ok(a), - Err(err) if err.kind() == std::io::ErrorKind::TimedOut || - err.kind() == std::io::ErrorKind::WouldBlock => { + Err(err) + if err.kind() == std::io::ErrorKind::TimedOut + || err.kind() == std::io::ErrorKind::WouldBlock => + { return Ok(None); - }, - Err(err) => Err(io_err_into_net_error(err)) + } + Err(err) => Err(io_err_into_net_error(err)), }?; - unsafe { buf.set_len(read); } + unsafe { + buf.set_len(read); + } let buf = Bytes::from(buf); Ok(Some(SocketReceive { @@ -946,14 +987,19 @@ impl VirtualConnectedSocket for LocalUdpSocket { async fn peek(&mut self) -> Result { let buf_size = 8192; let mut buf = Vec::with_capacity(buf_size); - unsafe { buf.set_len(buf_size); } + unsafe { + buf.set_len(buf_size); + } - let read = self.socket + let read = self + .socket .as_blocking_mut() .map_err(io_err_into_net_error)? .peek(&mut buf[..]) .map_err(io_err_into_net_error)?; - unsafe { buf.set_len(read); } + unsafe { + buf.set_len(read); + } if read == 0 { if self.nonblocking { return Err(NetworkError::WouldBlock); @@ -973,7 +1019,8 @@ impl VirtualConnectedSocket for LocalUdpSocket { #[async_trait::async_trait] impl VirtualConnectionlessSocket for LocalUdpSocket { async fn send_to(&mut self, data: Bytes, addr: SocketAddr) -> Result { - let amt = self.socket + let amt = self + .socket .as_async_mut() .map_err(io_err_into_net_error)? .send_to(&data[..], addr) @@ -992,26 +1039,37 @@ impl VirtualConnectionlessSocket for LocalUdpSocket { fn try_recv_from(&mut self) -> Result> { let buf_size = 8192; let mut buf = Vec::with_capacity(buf_size); - unsafe { buf.set_len(buf_size); } + unsafe { + buf.set_len(buf_size); + } - let socket = self.socket.as_blocking_mut().map_err(io_err_into_net_error)?; - socket.set_nonblocking(true).map_err(io_err_into_net_error)?; + let socket = self + .socket + .as_blocking_mut() + .map_err(io_err_into_net_error)?; + socket + .set_nonblocking(true) + .map_err(io_err_into_net_error)?; let read = socket.recv_from(&mut buf[..]); let _ = socket.set_nonblocking(self.nonblocking); let (read, peer) = match read { - Ok((0, _))=> { + Ok((0, _)) => { return Ok(None); } Ok((a, b)) => Ok((a, b)), - Err(err) if err.kind() == std::io::ErrorKind::TimedOut || - err.kind() == std::io::ErrorKind::WouldBlock => { + Err(err) + if err.kind() == std::io::ErrorKind::TimedOut + || err.kind() == std::io::ErrorKind::WouldBlock => + { return Ok(None); - }, - Err(err) => Err(io_err_into_net_error(err)) + } + Err(err) => Err(io_err_into_net_error(err)), }?; - unsafe { buf.set_len(read); } - + unsafe { + buf.set_len(read); + } + let buf = Bytes::from(buf); Ok(Some(SocketReceiveFrom { data: buf, @@ -1023,7 +1081,9 @@ impl VirtualConnectionlessSocket for LocalUdpSocket { async fn recv_from(&mut self) -> Result { let buf_size = 8192; let mut buf = Vec::with_capacity(buf_size); - unsafe { buf.set_len(buf_size); } + unsafe { + buf.set_len(buf_size); + } let (read, peer) = self .socket @@ -1032,7 +1092,9 @@ impl VirtualConnectionlessSocket for LocalUdpSocket { .recv_from(&mut buf[..]) .await .map_err(io_err_into_net_error)?; - unsafe { buf.set_len(read); } + unsafe { + buf.set_len(read); + } if read == 0 { if self.nonblocking { return Err(NetworkError::WouldBlock); @@ -1051,7 +1113,9 @@ impl VirtualConnectionlessSocket for LocalUdpSocket { fn peek_from(&mut self) -> Result { let buf_size = 8192; let mut buf = Vec::with_capacity(buf_size); - unsafe { buf.set_len(buf_size); } + unsafe { + buf.set_len(buf_size); + } let (read, peer) = self .socket @@ -1059,7 +1123,9 @@ impl VirtualConnectionlessSocket for LocalUdpSocket { .map_err(io_err_into_net_error)? .peek_from(&mut buf[..]) .map_err(io_err_into_net_error)?; - unsafe { buf.set_len(read); } + unsafe { + buf.set_len(read); + } if read == 0 { if self.nonblocking { return Err(NetworkError::WouldBlock); @@ -1082,7 +1148,7 @@ impl VirtualSocket for LocalUdpSocket { match &mut self.socket { LocalUdpSocketMode::Blocking(a) => a.set_ttl(ttl).map_err(io_err_into_net_error), LocalUdpSocketMode::Async(a) => a.set_ttl(ttl).map_err(io_err_into_net_error), - LocalUdpSocketMode::Uninitialized => unreachable!() + LocalUdpSocketMode::Uninitialized => unreachable!(), } } @@ -1104,7 +1170,7 @@ impl VirtualSocket for LocalUdpSocket { match &self.socket { LocalUdpSocketMode::Blocking(a) => a.ttl().map_err(io_err_into_net_error), LocalUdpSocketMode::Async(a) => a.ttl().map_err(io_err_into_net_error), - LocalUdpSocketMode::Uninitialized => unreachable!() + LocalUdpSocketMode::Uninitialized => unreachable!(), } } @@ -1112,7 +1178,7 @@ impl VirtualSocket for LocalUdpSocket { match &self.socket { LocalUdpSocketMode::Blocking(a) => a.local_addr().map_err(io_err_into_net_error), LocalUdpSocketMode::Async(a) => a.local_addr().map_err(io_err_into_net_error), - LocalUdpSocketMode::Uninitialized => unreachable!() + LocalUdpSocketMode::Uninitialized => unreachable!(), } } @@ -1120,23 +1186,22 @@ impl VirtualSocket for LocalUdpSocket { Ok(SocketStatus::Opened) } - fn poll_read_ready(&mut self, cx: &mut std::task::Context<'_>) -> std::task::Poll> - { - let socket = self.socket - .as_async_mut() - .map_err(io_err_into_net_error)?; + fn poll_read_ready( + &mut self, + cx: &mut std::task::Context<'_>, + ) -> std::task::Poll> { + let socket = self.socket.as_async_mut().map_err(io_err_into_net_error)?; socket .poll_recv_ready(cx) .map_ok(|a| 8192usize) .map_err(io_err_into_net_error) - } - fn poll_write_ready(&mut self, cx: &mut std::task::Context<'_>) -> std::task::Poll> - { - let socket = self.socket - .as_async_mut() - .map_err(io_err_into_net_error)?; + fn poll_write_ready( + &mut self, + cx: &mut std::task::Context<'_>, + ) -> std::task::Poll> { + let socket = self.socket.as_async_mut().map_err(io_err_into_net_error)?; socket .poll_send_ready(cx) .map_ok(|a| 8192usize) @@ -1147,12 +1212,13 @@ impl VirtualSocket for LocalUdpSocket { struct LocalUdpSocketReadReady<'a> { socket: &'a mut tokio::net::UdpSocket, } -impl<'a> Future -for LocalUdpSocketReadReady<'a> -{ +impl<'a> Future for LocalUdpSocketReadReady<'a> { type Output = Result; - fn poll(self: std::pin::Pin<&mut Self>, cx: &mut std::task::Context<'_>) -> std::task::Poll { + fn poll( + self: std::pin::Pin<&mut Self>, + cx: &mut std::task::Context<'_>, + ) -> std::task::Poll { self.socket .poll_recv_ready(cx) .map_err(io_err_into_net_error) @@ -1163,12 +1229,13 @@ for LocalUdpSocketReadReady<'a> struct LocalUdpSocketWriteReady<'a> { socket: &'a mut tokio::net::UdpSocket, } -impl<'a> Future -for LocalUdpSocketWriteReady<'a> -{ +impl<'a> Future for LocalUdpSocketWriteReady<'a> { type Output = Result; - fn poll(self: std::pin::Pin<&mut Self>, cx: &mut std::task::Context<'_>) -> std::task::Poll { + fn poll( + self: std::pin::Pin<&mut Self>, + cx: &mut std::task::Context<'_>, + ) -> std::task::Poll { self.socket .poll_send_ready(cx) .map_err(io_err_into_net_error) diff --git a/lib/wasi-types/src/asyncify.rs b/lib/wasi-types/src/asyncify.rs index 6b0b63a57..4a3669ea0 100644 --- a/lib/wasi-types/src/asyncify.rs +++ b/lib/wasi-types/src/asyncify.rs @@ -3,7 +3,9 @@ use wasmer_derive::ValueType; #[derive(Debug, Copy, Clone, PartialEq, Eq, ValueType)] #[repr(C)] pub struct __wasi_asyncify_t -where O: wasmer_types::ValueType { +where + O: wasmer_types::ValueType, +{ pub start: O, pub end: O, } diff --git a/lib/wasi-types/src/lib.rs b/lib/wasi-types/src/lib.rs index 89d95f590..e95d9eb1f 100644 --- a/lib/wasi-types/src/lib.rs +++ b/lib/wasi-types/src/lib.rs @@ -12,6 +12,7 @@ fn fail_if_wit_files_arent_up_to_date() { extern crate wasmer_types as wasmer; mod advice; +mod asyncify; mod bus; mod directory; mod error; @@ -23,10 +24,10 @@ mod signal; mod subscription; mod time; mod versions; -mod asyncify; pub use crate::time::*; pub use advice::*; +pub use asyncify::*; pub use bus::*; pub use directory::*; pub use error::*; @@ -37,7 +38,6 @@ pub use net::*; pub use signal::*; pub use subscription::*; pub use versions::*; -pub use asyncify::*; pub type __wasi_exitcode_t = u32; diff --git a/lib/wasi/src/bin_factory/binary_package.rs b/lib/wasi/src/bin_factory/binary_package.rs index a03343ade..8e8fa2031 100644 --- a/lib/wasi/src/bin_factory/binary_package.rs +++ b/lib/wasi/src/bin_factory/binary_package.rs @@ -1,16 +1,14 @@ use std::{ - sync::{ - Arc, Mutex, RwLock - }, any::Any, borrow::Cow, - collections::HashMap + collections::HashMap, + sync::{Arc, Mutex, RwLock}, }; +use crate::{fs::TmpFileSystem, syscalls::platform_clock_time_get}; use derivative::*; use wasmer_vfs::FileSystem; use wasmer_wasi_types::__WASI_CLOCK_MONOTONIC; -use crate::{fs::TmpFileSystem, syscalls::platform_clock_time_get}; use super::hash_of_binary; @@ -30,19 +28,24 @@ impl BinaryPackageCommand { name, ownership: None, hash: None, - atom + atom, } } - pub unsafe fn new_with_ownership<'a, T>(name: String, atom: Cow<'a, [u8]>, ownership: Arc) -> Self - where T: 'static + pub unsafe fn new_with_ownership<'a, T>( + name: String, + atom: Cow<'a, [u8]>, + ownership: Arc, + ) -> Self + where + T: 'static, { let ownership: Arc = ownership; let mut ret = Self::new(name, std::mem::transmute(atom)); ret.ownership = Some(std::mem::transmute(ownership)); ret } - + pub fn hash(&mut self) -> &str { if self.hash.is_none() { self.hash = Some(hash_of_binary(self.atom.as_ref())); @@ -55,7 +58,7 @@ impl BinaryPackageCommand { #[derive(Derivative, Clone)] #[derivative(Debug)] pub struct BinaryPackage { - pub package_name: Cow<'static, str>, + pub package_name: Cow<'static, str>, pub when_cached: u128, pub ownership: Option>, #[derivative(Debug = "ignore")] @@ -78,7 +81,7 @@ impl BinaryPackage { let now = platform_clock_time_get(__WASI_CLOCK_MONOTONIC, 1_000_000).unwrap() as u128; let (package_name, version) = match package_name.split_once("@") { Some((a, b)) => (a.to_string(), b.to_string()), - None => (package_name.to_string(), "1.0.0".to_string()) + None => (package_name.to_string(), "1.0.0".to_string()), }; Self { package_name: package_name.into(), @@ -99,15 +102,20 @@ impl BinaryPackage { } } - pub unsafe fn new_with_ownership<'a, T>(package_name: &str, entry: Cow<'a, [u8]>, ownership: Arc) -> Self - where T: 'static + pub unsafe fn new_with_ownership<'a, T>( + package_name: &str, + entry: Cow<'a, [u8]>, + ownership: Arc, + ) -> Self + where + T: 'static, { let ownership: Arc = ownership; let mut ret = Self::new(package_name, std::mem::transmute(entry)); ret.ownership = Some(std::mem::transmute(ownership)); ret } - + pub fn hash(&self) -> String { let mut hash = self.hash.lock().unwrap(); if hash.is_none() { diff --git a/lib/wasi/src/bin_factory/cached_modules.rs b/lib/wasi/src/bin_factory/cached_modules.rs index 652b5d836..434a83430 100644 --- a/lib/wasi/src/bin_factory/cached_modules.rs +++ b/lib/wasi/src/bin_factory/cached_modules.rs @@ -1,20 +1,15 @@ -use std::sync::RwLock; -use std::{ - collections::HashMap, - cell::RefCell, - ops::DerefMut, - path::PathBuf, -}; use derivative::*; +use std::sync::RwLock; +use std::{cell::RefCell, collections::HashMap, ops::DerefMut, path::PathBuf}; use bytes::Bytes; -use wasmer::{Module, AsStoreRef}; #[cfg(feature = "sys")] use wasmer::Engine; +use wasmer::{AsStoreRef, Module}; use wasmer_wasi_types::__WASI_CLOCK_MONOTONIC; -use crate::{WasiRuntimeImplementation, VirtualTaskManager}; use crate::syscalls::platform_clock_time_get; +use crate::{VirtualTaskManager, WasiRuntimeImplementation}; use super::BinaryPackage; @@ -35,23 +30,20 @@ pub struct CachedCompiledModules { pub(crate) engine: Engine, } -impl Default -for CachedCompiledModules { +impl Default for CachedCompiledModules { fn default() -> Self { CachedCompiledModules::new(None, None) } } thread_local! { - static THREAD_LOCAL_CACHED_MODULES: std::cell::RefCell> + static THREAD_LOCAL_CACHED_MODULES: std::cell::RefCell> = RefCell::new(HashMap::new()); } -impl CachedCompiledModules -{ +impl CachedCompiledModules { #[cfg(feature = "sys")] - fn new_engine() -> wasmer::Engine - { + fn new_engine() -> wasmer::Engine { // Build the features list let mut features = wasmer::Features::new(); features.threads(true); @@ -65,8 +57,8 @@ impl CachedCompiledModules { let compiler = wasmer_compiler_cranelift::Cranelift::default(); return wasmer_compiler::EngineBuilder::new(compiler) - .set_features(Some(features)) - .engine(); + .set_features(Some(features)) + .engine(); } #[cfg(all(not(feature = "compiler-cranelift"), feature = "compiler-llvm"))] { @@ -75,32 +67,47 @@ impl CachedCompiledModules .set_features(Some(features)) .engine(); } - #[cfg(all(not(feature = "compiler-cranelift"), not(feature = "compiler-singlepass"), feature = "compiler-llvm"))] + #[cfg(all( + not(feature = "compiler-cranelift"), + not(feature = "compiler-singlepass"), + feature = "compiler-llvm" + ))] { let compiler = wasmer_compiler_singlepass::Singlepass::default(); return wasmer_compiler::EngineBuilder::new(compiler) .set_features(Some(features)) .engine(); } - #[cfg(all(not(feature = "compiler-cranelift"), not(feature = "compiler-singlepass"), not(feature = "compiler-llvm")))] + #[cfg(all( + not(feature = "compiler-cranelift"), + not(feature = "compiler-singlepass"), + not(feature = "compiler-llvm") + ))] panic!("wasmer not built with a compiler") } - pub fn new(cache_compile_dir: Option, cache_webc_dir: Option) -> CachedCompiledModules { - let cache_compile_dir = shellexpand::tilde(cache_compile_dir - .as_ref() - .map(|a| a.as_str()) - .unwrap_or_else(|| DEFAULT_COMPILED_PATH)) - .to_string(); + pub fn new( + cache_compile_dir: Option, + cache_webc_dir: Option, + ) -> CachedCompiledModules { + let cache_compile_dir = shellexpand::tilde( + cache_compile_dir + .as_ref() + .map(|a| a.as_str()) + .unwrap_or_else(|| DEFAULT_COMPILED_PATH), + ) + .to_string(); let _ = std::fs::create_dir_all(PathBuf::from(cache_compile_dir.clone())); - let cache_webc_dir = shellexpand::tilde(cache_webc_dir - .as_ref() - .map(|a| a.as_str()) - .unwrap_or_else(|| DEFAULT_WEBC_PATH)) - .to_string(); + let cache_webc_dir = shellexpand::tilde( + cache_webc_dir + .as_ref() + .map(|a| a.as_str()) + .unwrap_or_else(|| DEFAULT_WEBC_PATH), + ) + .to_string(); let _ = std::fs::create_dir_all(PathBuf::from(cache_webc_dir.clone())); - + #[cfg(feature = "sys")] let engine = Self::new_engine(); @@ -111,27 +118,30 @@ impl CachedCompiledModules cache_webc: RwLock::new(HashMap::default()), cache_webc_dir, #[cfg(feature = "sys")] - engine + engine, } } #[cfg(feature = "sys")] - pub fn new_store(&self) -> wasmer::Store - { + pub fn new_store(&self) -> wasmer::Store { let engine = self.engine.clone(); wasmer::Store::new(engine) } #[cfg(not(feature = "sys"))] - pub fn new_store(&self) -> wasmer::Store - { + pub fn new_store(&self) -> wasmer::Store { wasmer::Store::default() } - pub fn get_webc(&self, webc: &str, runtime: &dyn WasiRuntimeImplementation, tasks: &dyn VirtualTaskManager) -> Option { + pub fn get_webc( + &self, + webc: &str, + runtime: &dyn WasiRuntimeImplementation, + tasks: &dyn VirtualTaskManager, + ) -> Option { let name = webc.to_string(); let now = platform_clock_time_get(__WASI_CLOCK_MONOTONIC, 1_000_000).unwrap() as u128; - + // Fast path { let cache = self.cache_webc.read().unwrap(); @@ -153,12 +163,14 @@ impl CachedCompiledModules return Some(data.clone()); } } - + // Now try for the WebC - let wapm_name = name.split_once(":").map(|a| a.0).unwrap_or_else(|| name.as_str()); + let wapm_name = name + .split_once(":") + .map(|a| a.0) + .unwrap_or_else(|| name.as_str()); let cache_webc_dir = self.cache_webc_dir.as_str(); - if let Some(data) = crate::wapm::fetch_webc(cache_webc_dir, wapm_name, runtime, tasks) - { + if let Some(data) = crate::wapm::fetch_webc(cache_webc_dir, wapm_name, runtime, tasks) { // If the package is the same then don't replace it // as we don't want to duplicate the memory usage if let Some(existing) = cache.get_mut(&name) { @@ -175,9 +187,14 @@ impl CachedCompiledModules None } - pub fn get_compiled_module(&self, store: &impl AsStoreRef, data_hash: &str, compiler: &str) -> Option { + pub fn get_compiled_module( + &self, + store: &impl AsStoreRef, + data_hash: &str, + compiler: &str, + ) -> Option { let key = format!("{}-{}", data_hash, compiler); - + // fastest path { let module = THREAD_LOCAL_CACHED_MODULES.with(|cache| { @@ -203,16 +220,15 @@ impl CachedCompiledModules } // slow path - let path = std::path::Path::new(self.cache_compile_dir.as_str()).join(format!("{}.bin", key).as_str()); + let path = std::path::Path::new(self.cache_compile_dir.as_str()) + .join(format!("{}.bin", key).as_str()); if let Ok(data) = std::fs::read(path) { let mut decoder = weezl::decode::Decoder::new(weezl::BitOrder::Msb, 8); if let Ok(data) = decoder.decode(&data[..]) { let module_bytes = Bytes::from(data); // Load the module - let module = unsafe { Module::deserialize(store, &module_bytes[..]) - .unwrap() - }; + let module = unsafe { Module::deserialize(store, &module_bytes[..]).unwrap() }; #[cfg(feature = "sys")] { @@ -233,7 +249,7 @@ impl CachedCompiledModules pub fn set_compiled_module(&self, data_hash: &str, compiler: &str, module: &Module) { let key = format!("{}-{}", data_hash, compiler); - + // Add the module to the local thread cache THREAD_LOCAL_CACHED_MODULES.with(|cache| { let mut cache = cache.borrow_mut(); @@ -247,11 +263,12 @@ impl CachedCompiledModules let mut cache = self.cached_modules.write().unwrap(); cache.insert(key.clone(), module.clone()); } - + // We should also attempt to store it in the cache directory let compiled_bytes = module.serialize().unwrap(); - let path = std::path::Path::new(self.cache_compile_dir.as_str()).join(format!("{}.bin", key).as_str()); + let path = std::path::Path::new(self.cache_compile_dir.as_str()) + .join(format!("{}.bin", key).as_str()); let _ = std::fs::create_dir_all(path.parent().unwrap().clone()); let mut encoder = weezl::encode::Encoder::new(weezl::BitOrder::Msb, 8); if let Ok(compiled_bytes) = encoder.encode(&compiled_bytes[..]) { diff --git a/lib/wasi/src/bin_factory/exec.rs b/lib/wasi/src/bin_factory/exec.rs index d14cb4c23..a86986f19 100644 --- a/lib/wasi/src/bin_factory/exec.rs +++ b/lib/wasi/src/bin_factory/exec.rs @@ -1,24 +1,24 @@ -use wasmer::{Store, Module, Memory, Instance, FunctionEnvMut}; -use wasmer_vbus::{ - VirtualBusSpawner, - VirtualBusError, - SpawnOptionsConfig, - BusSpawnedProcess, VirtualBusProcess, VirtualBusScope, VirtualBusInvokable -}; -use wasmer_wasi_types::__WASI_ENOEXEC; use std::{ + ops::DerefMut, pin::Pin, - task::{ - Context, - Poll - }, sync::{Mutex, Arc}, ops::DerefMut + sync::{Arc, Mutex}, + task::{Context, Poll}, }; use tokio::sync::mpsc; use tracing::*; +use wasmer::{FunctionEnvMut, Instance, Memory, Module, Store}; +use wasmer_vbus::{ + BusSpawnedProcess, SpawnOptionsConfig, VirtualBusError, VirtualBusInvokable, VirtualBusProcess, + VirtualBusScope, VirtualBusSpawner, +}; +use wasmer_wasi_types::__WASI_ENOEXEC; -use crate::{WasiEnv, WasiFunctionEnv, import_object_for_all_wasi_versions, WasiError, WasiRuntimeImplementation, SpawnedMemory}; use super::{BinFactory, BinaryPackage, CachedCompiledModules}; use crate::runtime::SpawnType; +use crate::{ + import_object_for_all_wasi_versions, SpawnedMemory, WasiEnv, WasiError, WasiFunctionEnv, + WasiRuntimeImplementation, +}; pub fn spawn_exec( binary: BinaryPackage, @@ -26,32 +26,27 @@ pub fn spawn_exec( store: Store, config: SpawnOptionsConfig, runtime: &Arc, - compiled_modules: &CachedCompiledModules -) -> wasmer_vbus::Result -{ + compiled_modules: &CachedCompiledModules, +) -> wasmer_vbus::Result { // Load the module #[cfg(feature = "sys")] let compiler = store.engine().name(); #[cfg(not(feature = "sys"))] let compiler = "generic"; - let module = compiled_modules.get_compiled_module( - &store, - binary.hash().as_str(), - compiler - ); + let module = compiled_modules.get_compiled_module(&store, binary.hash().as_str(), compiler); let module = match module { Some(a) => a, None => { - let module = Module::new(&store, &binary.entry[..]) - .map_err(|err| { - error!("failed to compile module [{}, len={}] - {}", name, binary.entry.len(), err); - VirtualBusError::CompileError - })?; - compiled_modules.set_compiled_module( - binary.hash().as_str(), - compiler, - &module - ); + let module = Module::new(&store, &binary.entry[..]).map_err(|err| { + error!( + "failed to compile module [{}, len={}] - {}", + name, + binary.entry.len(), + err + ); + VirtualBusError::CompileError + })?; + compiled_modules.set_compiled_module(binary.hash().as_str(), compiler, &module); module } }; @@ -67,9 +62,8 @@ pub fn spawn_exec_module( module: Module, store: Store, config: SpawnOptionsConfig, - runtime: &Arc -) -> wasmer_vbus::Result -{ + runtime: &Arc, +) -> wasmer_vbus::Result { // Create a new task manager let tasks = runtime.new_task_manager(); @@ -81,146 +75,138 @@ pub fn spawn_exec_module( let (exit_code_tx, exit_code_rx) = mpsc::unbounded_channel(); { // Determine if shared memory needs to be created and imported - let shared_memory = module - .imports() - .memories() - .next() - .map(|a| *a.ty()); + let shared_memory = module.imports().memories().next().map(|a| *a.ty()); // Determine if we are going to create memory and import it or just rely on self creation of memory let memory_spawn = match shared_memory { Some(ty) => { #[cfg(feature = "sys")] - let style = store - .tunables() - .memory_style(&ty); + let style = store.tunables().memory_style(&ty); SpawnType::CreateWithType(SpawnedMemory { ty, #[cfg(feature = "sys")] - style + style, }) - }, + } None => SpawnType::Create, }; // Create a thread that will run this process let runtime = runtime.clone(); let tasks_outer = tasks.clone(); - tasks_outer.task_wasm(Box::new(move |mut store, module, memory| - { - // Create the WasiFunctionEnv - let mut wasi_env = config.env().clone(); - wasi_env.runtime = runtime; - wasi_env.tasks = tasks; - let mut wasi_env = WasiFunctionEnv::new(&mut store, wasi_env); + tasks_outer + .task_wasm( + Box::new(move |mut store, module, memory| { + // Create the WasiFunctionEnv + let mut wasi_env = config.env().clone(); + wasi_env.runtime = runtime; + wasi_env.tasks = tasks; + let mut wasi_env = WasiFunctionEnv::new(&mut store, wasi_env); - // Let's instantiate the module with the imports. - let mut import_object = import_object_for_all_wasi_versions(&mut store, &wasi_env.env); - if let Some(memory) = memory { - import_object.define("env", "memory", Memory::new_from_existing(&mut store, memory)); - } - let instance = match Instance::new(&mut store, &module, &import_object) { - Ok(a) => a, - Err(err) => { - error!("wasi[{}]::wasm instantiate error ({})", pid, err); + // Let's instantiate the module with the imports. + let mut import_object = + import_object_for_all_wasi_versions(&mut store, &wasi_env.env); + if let Some(memory) = memory { + import_object.define( + "env", + "memory", + Memory::new_from_existing(&mut store, memory), + ); + } + let instance = match Instance::new(&mut store, &module, &import_object) { + Ok(a) => a, + Err(err) => { + error!("wasi[{}]::wasm instantiate error ({})", pid, err); + return; + } + }; + + // Initialize the WASI environment + if let Err(err) = wasi_env.initialize(&mut store, &instance) { + error!("wasi[{}]::wasi initialize error ({})", pid, err); return; } - }; - // Initialize the WASI environment - if let Err(err) = wasi_env.initialize(&mut store, &instance) { - error!("wasi[{}]::wasi initialize error ({})", pid, err); - return; - } - - // If this module exports an _initialize function, run that first. - if let Ok(initialize) = instance.exports.get_function("_initialize") { - if let Err(e) = initialize.call(&mut store, &[]) { - let code = match e.downcast::() { - Ok(WasiError::Exit(code)) => code, - Ok(WasiError::UnknownWasiVersion) => { - debug!("wasi[{}]::exec-failed: unknown wasi version", pid); - __WASI_ENOEXEC as u32 - } - Err(err) => { - debug!("wasi[{}]::exec-failed: runtime error - {}", pid, err); - 9999u32 - }, - }; - let _ = exit_code_tx.send(code); - return; - } - } - - // Let's call the `_start` function, which is our `main` function in Rust. - let start = instance - .exports - .get_function("_start") - .ok(); - - // If there is a start function - debug!("wasi[{}]::called main()", pid); - let ret = if let Some(start) = start { - match start.call(&mut store, &[]) { - Ok(_) => 0, - Err(e) => { - match e.downcast::() { + // If this module exports an _initialize function, run that first. + if let Ok(initialize) = instance.exports.get_function("_initialize") { + if let Err(e) = initialize.call(&mut store, &[]) { + let code = match e.downcast::() { Ok(WasiError::Exit(code)) => code, Ok(WasiError::UnknownWasiVersion) => { debug!("wasi[{}]::exec-failed: unknown wasi version", pid); - __WASI_ENOEXEC as u32 + __WASI_ENOEXEC as u32 } Err(err) => { debug!("wasi[{}]::exec-failed: runtime error - {}", pid, err); 9999u32 - }, - } - }, + } + }; + let _ = exit_code_tx.send(code); + return; + } } - } else { - debug!("wasi[{}]::exec-failed: missing _start function", pid); - __WASI_ENOEXEC as u32 - }; - debug!("wasi[{}]::main() has exited with {}", pid, ret); - // Send the result - let _ = exit_code_tx.send(ret); - drop(exit_code_tx); - } - ), store, module, memory_spawn) - .map_err(|err| { - error!("wasi[{}]::failed to launch module - {}", pid, err); - VirtualBusError::UnknownError - })? + // Let's call the `_start` function, which is our `main` function in Rust. + let start = instance.exports.get_function("_start").ok(); + + // If there is a start function + debug!("wasi[{}]::called main()", pid); + let ret = if let Some(start) = start { + match start.call(&mut store, &[]) { + Ok(_) => 0, + Err(e) => match e.downcast::() { + Ok(WasiError::Exit(code)) => code, + Ok(WasiError::UnknownWasiVersion) => { + debug!("wasi[{}]::exec-failed: unknown wasi version", pid); + __WASI_ENOEXEC as u32 + } + Err(err) => { + debug!("wasi[{}]::exec-failed: runtime error - {}", pid, err); + 9999u32 + } + }, + } + } else { + debug!("wasi[{}]::exec-failed: missing _start function", pid); + __WASI_ENOEXEC as u32 + }; + debug!("wasi[{}]::main() has exited with {}", pid, ret); + + // Send the result + let _ = exit_code_tx.send(ret); + drop(exit_code_tx); + }), + store, + module, + memory_spawn, + ) + .map_err(|err| { + error!("wasi[{}]::failed to launch module - {}", pid, err); + VirtualBusError::UnknownError + })? }; - let inst = Box::new( - SpawnedProcess { - exit_code: Mutex::new(None), - exit_code_rx: Mutex::new(exit_code_rx), - } - ); - Ok( - BusSpawnedProcess { - inst, - stdin: None, - stdout: None, - stderr: None, - signaler: Some(signaler), - } - ) + let inst = Box::new(SpawnedProcess { + exit_code: Mutex::new(None), + exit_code_rx: Mutex::new(exit_code_rx), + }); + Ok(BusSpawnedProcess { + inst, + stdin: None, + stdout: None, + stderr: None, + signaler: Some(signaler), + }) } -impl VirtualBusSpawner -for BinFactory -{ +impl VirtualBusSpawner for BinFactory { fn spawn<'a>( &self, parent_ctx: Option<&FunctionEnvMut<'a, WasiEnv>>, name: &str, store: Store, config: SpawnOptionsConfig, - _fallback: &dyn VirtualBusSpawner + _fallback: &dyn VirtualBusSpawner, ) -> wasmer_vbus::Result { if config.remote_instance().is_some() { return Err(VirtualBusError::Unsupported); @@ -238,9 +224,7 @@ for BinFactory } // Find the binary (or die trying) and make the spawn type - let binary = self - .get_binary(name) - .ok_or(VirtualBusError::NotFound)?; + let binary = self.get_binary(name).ok_or(VirtualBusError::NotFound)?; spawn_exec(binary, name, store, config, &self.runtime, &self.cache) } } @@ -251,10 +235,8 @@ pub(crate) struct SpawnedProcess { pub exit_code_rx: Mutex>, } -impl VirtualBusProcess -for SpawnedProcess { - fn exit_code(&self) -> Option - { +impl VirtualBusProcess for SpawnedProcess { + fn exit_code(&self) -> Option { let mut exit_code = self.exit_code.lock().unwrap(); if let Some(exit_code) = exit_code.as_ref() { return Some(exit_code.clone()); @@ -264,13 +246,13 @@ for SpawnedProcess { Ok(code) => { exit_code.replace(code); Some(code) - }, + } Err(mpsc::error::TryRecvError::Disconnected) => { let code = 9999; exit_code.replace(code); Some(code) } - _ => None + _ => None, } } @@ -291,18 +273,16 @@ for SpawnedProcess { exit_code.replace(code); } Poll::Ready(()) - }, - Poll::Pending => Poll::Pending + } + Poll::Pending => Poll::Pending, } } } -impl VirtualBusScope -for SpawnedProcess { +impl VirtualBusScope for SpawnedProcess { fn poll_finished(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<()> { VirtualBusProcess::poll_ready(self, cx) } } -impl VirtualBusInvokable -for SpawnedProcess { } +impl VirtualBusInvokable for SpawnedProcess {} diff --git a/lib/wasi/src/bin_factory/mod.rs b/lib/wasi/src/bin_factory/mod.rs index edc8f76b3..3ebb13685 100644 --- a/lib/wasi/src/bin_factory/mod.rs +++ b/lib/wasi/src/bin_factory/mod.rs @@ -1,12 +1,9 @@ -use std::{ - sync::{ - Arc, RwLock, - }, - ops::{ - Deref - }, collections::HashMap, -}; use derivative::Derivative; +use std::{ + collections::HashMap, + ops::Deref, + sync::{Arc, RwLock}, +}; mod binary_package; mod cached_modules; @@ -20,11 +17,7 @@ pub(crate) use exec::SpawnedProcess; use sha2::*; -use crate::{ - WasiState, - WasiRuntimeImplementation, - builtins::BuiltIns -}; +use crate::{builtins::BuiltIns, WasiRuntimeImplementation, WasiState}; #[derive(Derivative, Clone)] pub struct BinFactory { @@ -46,7 +39,7 @@ impl BinFactory { builtins: BuiltIns::new(runtime.clone(), compiled_modules.clone()), runtime, cache: compiled_modules, - local: Arc::new(RwLock::new(HashMap::new())) + local: Arc::new(RwLock::new(HashMap::new())), } } @@ -77,18 +70,18 @@ impl BinFactory { if let Some(data) = cache.get(&name) { return data.clone(); } - + // Check the filesystem for the file if name.starts_with("/") { - if let Ok(mut file) = self.state + if let Ok(mut file) = self + .state .fs_new_open_options() .read(true) .open(name.clone()) { // Read the file let mut data = Vec::with_capacity(file.size() as usize); - if let Ok(_) = file.read_to_end(&mut data) - { + if let Ok(_) = file.read_to_end(&mut data) { let package_name = name.split("/").last().unwrap_or_else(|| name.as_str()); let data = BinaryPackage::new(package_name, data.into()); cache.insert(name, Some(data.clone())); diff --git a/lib/wasi/src/builtins/cmd_wasmer.rs b/lib/wasi/src/builtins/cmd_wasmer.rs index 526952877..74a560381 100644 --- a/lib/wasi/src/builtins/cmd_wasmer.rs +++ b/lib/wasi/src/builtins/cmd_wasmer.rs @@ -1,25 +1,12 @@ +use std::{ops::Deref, sync::Arc}; use wasmer::{FunctionEnvMut, Store}; -use wasmer_vbus::{ - SpawnOptionsConfig, - BusSpawnedProcess -}; +use wasmer_vbus::{BusSpawnedProcess, SpawnOptionsConfig}; use wasmer_wasi_types::__WASI_ENOENT; -use std::{ - ops::Deref, - sync::{ - Arc, - }, -}; use crate::{ - WasiEnv, + bin_factory::{spawn_exec, BinaryPackage, CachedCompiledModules}, syscalls::stderr_write, - WasiRuntimeImplementation, - bin_factory::{ - BinaryPackage, - CachedCompiledModules, - spawn_exec - }, VirtualTaskManager, + VirtualTaskManager, WasiEnv, WasiRuntimeImplementation, }; const HELP: &'static str = r#"USAGE: @@ -49,16 +36,27 @@ pub struct CmdWasmer { } impl CmdWasmer { - pub fn new(runtime: Arc, compiled_modules: Arc) -> Self { + pub fn new( + runtime: Arc, + compiled_modules: Arc, + ) -> Self { Self { runtime, - cache: compiled_modules + cache: compiled_modules, } } } -impl CmdWasmer{ - fn run<'a>(&self, parent_ctx: &FunctionEnvMut<'a, WasiEnv>, name: &str, store: Store, mut config: SpawnOptionsConfig, what: Option, mut args: Vec) -> wasmer_vbus::Result { +impl CmdWasmer { + fn run<'a>( + &self, + parent_ctx: &FunctionEnvMut<'a, WasiEnv>, + name: &str, + store: Store, + mut config: SpawnOptionsConfig, + what: Option, + mut args: Vec, + ) -> wasmer_vbus::Result { if let Some(what) = what { // Set the arguments of the environment by replacing the state let mut state = config.env().state.fork(); @@ -68,13 +66,15 @@ impl CmdWasmer{ // Get the binary let tasks = parent_ctx.data().tasks(); - if let Some(binary) = self.get(what.clone(), tasks) - { + if let Some(binary) = self.get(what.clone(), tasks) { // Now run the module spawn_exec(binary, name, store, config, &self.runtime, &self.cache) } else { - let _ = stderr_write(parent_ctx, format!("package not found - {}\r\n", what).as_bytes()); - Ok(BusSpawnedProcess::exited_process(__WASI_ENOENT as u32)) + let _ = stderr_write( + parent_ctx, + format!("package not found - {}\r\n", what).as_bytes(), + ); + Ok(BusSpawnedProcess::exited_process(__WASI_ENOENT as u32)) } } else { let _ = stderr_write(parent_ctx, HELP_RUN.as_bytes()); @@ -82,20 +82,20 @@ impl CmdWasmer{ } } - pub fn get(&self, name: String, tasks: &dyn VirtualTaskManager) -> Option - { - self.cache.get_webc( - name.as_str(), - self.runtime.deref(), - tasks, - ) + pub fn get(&self, name: String, tasks: &dyn VirtualTaskManager) -> Option { + self.cache + .get_webc(name.as_str(), self.runtime.deref(), tasks) } } -impl BuiltInCommand -for CmdWasmer { - fn exec<'a>(&self, parent_ctx: &FunctionEnvMut<'a, WasiEnv>, name: &str, store: Store, config: SpawnOptionsConfig) -> wasmer_vbus::Result - { +impl BuiltInCommand for CmdWasmer { + fn exec<'a>( + &self, + parent_ctx: &FunctionEnvMut<'a, WasiEnv>, + name: &str, + store: Store, + config: SpawnOptionsConfig, + ) -> wasmer_vbus::Result { // Read the command we want to run let mut args = config.env().state.args.iter().map(|a| a.as_str()); let _alias = args.next(); @@ -107,12 +107,11 @@ for CmdWasmer { let what = args.next().map(|a| a.to_string()); let args = args.map(|a| a.to_string()).collect(); self.run(parent_ctx, name, store, config, what, args) - }, - Some("--help") | - None => { + } + Some("--help") | None => { let _ = stderr_write(parent_ctx, HELP.as_bytes()); Ok(BusSpawnedProcess::exited_process(0)) - }, + } Some(what) => { let what = Some(what.to_string()); let args = args.map(|a| a.to_string()).collect(); @@ -120,4 +119,4 @@ for CmdWasmer { } } } -} \ No newline at end of file +} diff --git a/lib/wasi/src/builtins/mod.rs b/lib/wasi/src/builtins/mod.rs index 2265e1599..8954b2a76 100644 --- a/lib/wasi/src/builtins/mod.rs +++ b/lib/wasi/src/builtins/mod.rs @@ -1,18 +1,25 @@ -use std::{ - collections::HashMap, - sync::Arc -}; +use std::{collections::HashMap, sync::Arc}; use wasmer::{FunctionEnvMut, Store}; -use wasmer_vbus::{SpawnOptionsConfig, BusSpawnedProcess}; +use wasmer_vbus::{BusSpawnedProcess, SpawnOptionsConfig}; use wasmer_wasi_types::__WASI_ENOENT; -use crate::{WasiEnv, syscalls::stderr_write, bin_factory::CachedCompiledModules, WasiRuntimeImplementation}; +use crate::{ + bin_factory::CachedCompiledModules, syscalls::stderr_write, WasiEnv, WasiRuntimeImplementation, +}; mod cmd_wasmer; pub trait BuiltInCommand -where Self: std::fmt::Debug { - fn exec<'a>(&self, parent_ctx: &FunctionEnvMut<'a, WasiEnv>, name: &str, store: Store, config: SpawnOptionsConfig) -> wasmer_vbus::Result; +where + Self: std::fmt::Debug, +{ + fn exec<'a>( + &self, + parent_ctx: &FunctionEnvMut<'a, WasiEnv>, + name: &str, + store: Store, + config: SpawnOptionsConfig, + ) -> wasmer_vbus::Result; } #[derive(Debug, Clone)] @@ -22,36 +29,43 @@ pub struct BuiltIns { } impl BuiltIns { - pub(crate) fn new(runtime: Arc, compiled_modules: Arc) -> Self { - let cmd_wasmer = cmd_wasmer::CmdWasmer::new( - runtime.clone(), - compiled_modules.clone()); - let mut commands: HashMap> - = HashMap::new(); - commands.insert("/bin/wasmer".to_string(), Arc::new( - cmd_wasmer.clone()) - ); + pub(crate) fn new( + runtime: Arc, + compiled_modules: Arc, + ) -> Self { + let cmd_wasmer = cmd_wasmer::CmdWasmer::new(runtime.clone(), compiled_modules.clone()); + let mut commands: HashMap> = + HashMap::new(); + commands.insert("/bin/wasmer".to_string(), Arc::new(cmd_wasmer.clone())); Self { commands, - cmd_wasmer + cmd_wasmer, } } } -impl BuiltIns -{ +impl BuiltIns { pub fn exists(&self, name: &str) -> bool { let name = name.to_string(); self.commands.contains_key(&name) } - pub fn exec<'a>(&self, parent_ctx: &FunctionEnvMut<'a, WasiEnv>, name: &str, store: Store, config: SpawnOptionsConfig) -> wasmer_vbus::Result { + pub fn exec<'a>( + &self, + parent_ctx: &FunctionEnvMut<'a, WasiEnv>, + name: &str, + store: Store, + config: SpawnOptionsConfig, + ) -> wasmer_vbus::Result { let name = name.to_string(); if let Some(cmd) = self.commands.get(&name) { cmd.exec(parent_ctx, name.as_str(), store, config) } else { - let _ = stderr_write(parent_ctx, format!("wasm command unknown - {}\r\n", name).as_bytes()); + let _ = stderr_write( + parent_ctx, + format!("wasm command unknown - {}\r\n", name).as_bytes(), + ); Ok(BusSpawnedProcess::exited_process(__WASI_ENOENT as u32)) } } diff --git a/lib/wasi/src/fs/arc_file.rs b/lib/wasi/src/fs/arc_file.rs index fe571c95f..a8a45e080 100644 --- a/lib/wasi/src/fs/arc_file.rs +++ b/lib/wasi/src/fs/arc_file.rs @@ -1,29 +1,22 @@ -use std::{ - io::{ - self, - * - }, - sync::{ - Arc, - Mutex - } -}; use derivative::Derivative; +use std::{ + io::{self, *}, + sync::{Arc, Mutex}, +}; use wasmer_vbus::FileDescriptor; -use wasmer_vfs::{VirtualFile, ClonableVirtualFile}; +use wasmer_vfs::{ClonableVirtualFile, VirtualFile}; #[derive(Derivative, Clone)] #[derivative(Debug)] pub struct ArcFile { #[derivative(Debug = "ignore")] - inner: Arc>> + inner: Arc>>, } -impl ArcFile -{ +impl ArcFile { pub fn new(inner: Box) -> Self { Self { - inner: Arc::new(Mutex::new(inner)) + inner: Arc::new(Mutex::new(inner)), } } } @@ -54,7 +47,7 @@ impl Read for ArcFile { impl VirtualFile for ArcFile { fn last_accessed(&self) -> u64 { - let inner = self.inner.lock().unwrap(); + let inner = self.inner.lock().unwrap(); inner.last_accessed() } fn last_modified(&self) -> u64 { diff --git a/lib/wasi/src/fs/arc_fs.rs b/lib/wasi/src/fs/arc_fs.rs index 42e6b53fe..450c6ae84 100644 --- a/lib/wasi/src/fs/arc_fs.rs +++ b/lib/wasi/src/fs/arc_fs.rs @@ -12,9 +12,7 @@ pub struct ArcFileSystem { impl ArcFileSystem { pub fn new(inner: Arc) -> Self { - Self { - fs: inner, - } + Self { fs: inner } } } diff --git a/lib/wasi/src/fs/builder.rs b/lib/wasi/src/fs/builder.rs index a35739b39..6216c96da 100644 --- a/lib/wasi/src/fs/builder.rs +++ b/lib/wasi/src/fs/builder.rs @@ -1,16 +1,12 @@ use std::path::{Path, PathBuf}; use tracing::*; use wasmer_vfs::{FileSystem, VirtualFile}; -use wasmer_wasi_types::{__WASI_STDIN_FILENO, __WASI_STDOUT_FILENO, __WASI_STDERR_FILENO}; +use wasmer_wasi_types::{__WASI_STDERR_FILENO, __WASI_STDIN_FILENO, __WASI_STDOUT_FILENO}; +use super::{NullFile, SpecialFile}; use super::{TmpFileSystem, ZeroFile}; -use super::{ - NullFile, - SpecialFile -}; -pub struct RootFileSystemBuilder -{ +pub struct RootFileSystemBuilder { default_root_dirs: bool, default_dev_files: bool, add_wasmer_command: bool, @@ -20,8 +16,7 @@ pub struct RootFileSystemBuilder tty: Option>, } -impl RootFileSystemBuilder -{ +impl RootFileSystemBuilder { pub fn new() -> Self { Self { default_root_dirs: true, @@ -33,7 +28,7 @@ impl RootFileSystemBuilder tty: None, } } - + pub fn with_stdin(mut self, file: Box) -> Self { self.stdin.replace(file); self @@ -62,37 +57,44 @@ impl RootFileSystemBuilder pub fn build(self) -> TmpFileSystem { let tmp = TmpFileSystem::new(); if self.default_root_dirs { - for root_dir in vec![ - "/.app", - "/.private", - "/bin", - "/dev", - "/etc", - "/tmp" - ] { + for root_dir in vec!["/.app", "/.private", "/bin", "/dev", "/etc", "/tmp"] { if let Err(err) = tmp.create_dir(&Path::new(root_dir)) { debug!("failed to create dir [{}] - {}", root_dir, err); } } } if self.add_wasmer_command { - let _ = tmp.new_open_options_ext() + let _ = tmp + .new_open_options_ext() .insert_custom_file(PathBuf::from("/bin/wasmer"), Box::new(NullFile::default())); } if self.default_dev_files { - let _ = tmp.new_open_options_ext() + let _ = tmp + .new_open_options_ext() .insert_custom_file(PathBuf::from("/dev/null"), Box::new(NullFile::default())); - let _ = tmp.new_open_options_ext() + let _ = tmp + .new_open_options_ext() .insert_custom_file(PathBuf::from("/dev/zero"), Box::new(ZeroFile::default())); - let _ = tmp.new_open_options_ext() - .insert_custom_file(PathBuf::from("/dev/stdin"), self.stdin.unwrap_or_else(|| Box::new(SpecialFile::new(__WASI_STDIN_FILENO)))); - let _ = tmp.new_open_options_ext() - .insert_custom_file(PathBuf::from("/dev/stdout"), self.stdout.unwrap_or_else(|| Box::new(SpecialFile::new(__WASI_STDOUT_FILENO)))); - let _ = tmp.new_open_options_ext() - .insert_custom_file(PathBuf::from("/dev/stderr"), self.stderr.unwrap_or_else(|| Box::new(SpecialFile::new(__WASI_STDERR_FILENO)))); - let _ = tmp.new_open_options_ext() - .insert_custom_file(PathBuf::from("/dev/tty"), self.tty.unwrap_or_else(|| Box::new(NullFile::default()))); + let _ = tmp.new_open_options_ext().insert_custom_file( + PathBuf::from("/dev/stdin"), + self.stdin + .unwrap_or_else(|| Box::new(SpecialFile::new(__WASI_STDIN_FILENO))), + ); + let _ = tmp.new_open_options_ext().insert_custom_file( + PathBuf::from("/dev/stdout"), + self.stdout + .unwrap_or_else(|| Box::new(SpecialFile::new(__WASI_STDOUT_FILENO))), + ); + let _ = tmp.new_open_options_ext().insert_custom_file( + PathBuf::from("/dev/stderr"), + self.stderr + .unwrap_or_else(|| Box::new(SpecialFile::new(__WASI_STDERR_FILENO))), + ); + let _ = tmp.new_open_options_ext().insert_custom_file( + PathBuf::from("/dev/tty"), + self.tty.unwrap_or_else(|| Box::new(NullFile::default())), + ); } tmp } -} \ No newline at end of file +} diff --git a/lib/wasi/src/fs/delegate_file.rs b/lib/wasi/src/fs/delegate_file.rs index 4be41f9dc..d4b0072cf 100644 --- a/lib/wasi/src/fs/delegate_file.rs +++ b/lib/wasi/src/fs/delegate_file.rs @@ -1,5 +1,8 @@ -use std::{io::{self, *}, sync::{Arc, RwLock}}; use derivative::Derivative; +use std::{ + io::{self, *}, + sync::{Arc, RwLock}, +}; use wasmer_vbus::FileDescriptor; use wasmer_vfs::VirtualFile; @@ -22,15 +25,20 @@ pub struct DelegateFile { inner: Arc>, } -impl DelegateFile -{ - pub fn with_seek(&self, func: impl Fn(SeekFrom) -> io::Result + Send + Sync + 'static) -> &Self { +impl DelegateFile { + pub fn with_seek( + &self, + func: impl Fn(SeekFrom) -> io::Result + Send + Sync + 'static, + ) -> &Self { let mut inner = self.inner.write().unwrap(); inner.seek.replace(Box::new(func)); self } - pub fn with_write(&self, func: impl Fn(&[u8]) -> io::Result + Send + Sync + 'static) -> &Self { + pub fn with_write( + &self, + func: impl Fn(&[u8]) -> io::Result + Send + Sync + 'static, + ) -> &Self { let mut inner = self.inner.write().unwrap(); inner.write.replace(Box::new(func)); self @@ -42,7 +50,10 @@ impl DelegateFile self } - pub fn with_read(&self, func: impl Fn(&mut [u8]) -> io::Result + Send + Sync + 'static) -> &Self { + pub fn with_read( + &self, + func: impl Fn(&mut [u8]) -> io::Result + Send + Sync + 'static, + ) -> &Self { let mut inner = self.inner.write().unwrap(); inner.read.replace(Box::new(func)); self @@ -54,33 +65,38 @@ impl DelegateFile self } - pub fn with_set_len(&self, func: impl Fn(u64) -> wasmer_vfs::Result<()> + Send + Sync + 'static) -> &Self { + pub fn with_set_len( + &self, + func: impl Fn(u64) -> wasmer_vfs::Result<()> + Send + Sync + 'static, + ) -> &Self { let mut inner = self.inner.write().unwrap(); inner.set_len.replace(Box::new(func)); self } - pub fn with_unlink(&self, func: impl Fn() -> wasmer_vfs::Result<()> + Send + Sync + 'static) -> &Self { + pub fn with_unlink( + &self, + func: impl Fn() -> wasmer_vfs::Result<()> + Send + Sync + 'static, + ) -> &Self { let mut inner = self.inner.write().unwrap(); inner.unlink.replace(Box::new(func)); self } - pub fn with_bytes_available(&self, func: impl Fn() -> wasmer_vfs::Result + Send + Sync + 'static) -> &Self { + pub fn with_bytes_available( + &self, + func: impl Fn() -> wasmer_vfs::Result + Send + Sync + 'static, + ) -> &Self { let mut inner = self.inner.write().unwrap(); inner.bytes_available.replace(Box::new(func)); self } } -impl Default -for DelegateFile -{ +impl Default for DelegateFile { fn default() -> Self { Self { - inner: Arc::new(RwLock::new( - DelegateFileInner::default() - )) + inner: Arc::new(RwLock::new(DelegateFileInner::default())), } } } @@ -88,32 +104,28 @@ for DelegateFile impl Seek for DelegateFile { fn seek(&mut self, pos: SeekFrom) -> io::Result { let inner = self.inner.read().unwrap(); - inner.seek.as_ref() - .map(|seek| seek(pos)) - .unwrap_or(Ok(0)) + inner.seek.as_ref().map(|seek| seek(pos)).unwrap_or(Ok(0)) } } impl Write for DelegateFile { fn write(&mut self, buf: &[u8]) -> io::Result { let inner = self.inner.read().unwrap(); - inner.write.as_ref() + inner + .write + .as_ref() .map(|write| write(buf)) .unwrap_or(Ok(buf.len())) } fn flush(&mut self) -> io::Result<()> { let inner = self.inner.read().unwrap(); - inner.flush.as_ref() - .map(|flush| flush()) - .unwrap_or(Ok(())) + inner.flush.as_ref().map(|flush| flush()).unwrap_or(Ok(())) } } impl Read for DelegateFile { fn read(&mut self, buf: &mut [u8]) -> io::Result { let inner = self.inner.read().unwrap(); - inner.read.as_ref() - .map(|read| read(buf)) - .unwrap_or(Ok(0)) + inner.read.as_ref().map(|read| read(buf)).unwrap_or(Ok(0)) } } @@ -129,29 +141,33 @@ impl VirtualFile for DelegateFile { } fn size(&self) -> u64 { let inner = self.inner.read().unwrap(); - inner.size.as_ref() - .map(|size| size()) - .unwrap_or(0) + inner.size.as_ref().map(|size| size()).unwrap_or(0) } fn set_len(&mut self, new_size: u64) -> wasmer_vfs::Result<()> { let inner = self.inner.read().unwrap(); - inner.set_len.as_ref() + inner + .set_len + .as_ref() .map(|set_len| set_len(new_size)) .unwrap_or(Ok(())) } fn unlink(&mut self) -> wasmer_vfs::Result<()> { let inner = self.inner.read().unwrap(); - inner.unlink.as_ref() + inner + .unlink + .as_ref() .map(|unlink| unlink()) .unwrap_or(Ok(())) } fn bytes_available(&self) -> wasmer_vfs::Result { let inner = self.inner.read().unwrap(); - inner.bytes_available.as_ref() + inner + .bytes_available + .as_ref() .map(|bytes_available| bytes_available()) .unwrap_or(Ok(0)) } fn get_fd(&self) -> Option { None } -} \ No newline at end of file +} diff --git a/lib/wasi/src/fs/empty_fs.rs b/lib/wasi/src/fs/empty_fs.rs index b0ec57d57..23d352693 100644 --- a/lib/wasi/src/fs/empty_fs.rs +++ b/lib/wasi/src/fs/empty_fs.rs @@ -5,8 +5,7 @@ use tracing::{debug, error, info, trace, warn}; use wasmer_vfs::*; #[derive(Debug, Default)] -pub struct EmptyFileSystem { -} +pub struct EmptyFileSystem {} #[allow(unused_variables)] impl FileSystem for EmptyFileSystem { @@ -43,9 +42,7 @@ impl FileSystem for EmptyFileSystem { } } -impl FileOpener -for EmptyFileSystem -{ +impl FileOpener for EmptyFileSystem { #[allow(unused_variables)] fn open( &mut self, @@ -54,4 +51,4 @@ for EmptyFileSystem ) -> Result> { Err(FsError::EntryNotFound) } -} \ No newline at end of file +} diff --git a/lib/wasi/src/fs/mod.rs b/lib/wasi/src/fs/mod.rs index 0feb48756..b21781902 100644 --- a/lib/wasi/src/fs/mod.rs +++ b/lib/wasi/src/fs/mod.rs @@ -1,25 +1,25 @@ -mod builder; -mod tmp_fs; -mod union_fs; -mod passthru_fs; -mod arc_fs; mod arc_file; -mod null_file; +mod arc_fs; +mod builder; mod delegate_file; -mod special_file; mod empty_fs; +mod null_file; +mod passthru_fs; +mod special_file; +mod tmp_fs; mod tty_file; +mod union_fs; mod zero_file; -pub use builder::*; -pub use tmp_fs::*; -pub use union_fs::*; -pub use passthru_fs::*; -pub use arc_fs::*; pub use arc_file::*; -pub use null_file::*; +pub use arc_fs::*; +pub use builder::*; pub use delegate_file::*; -pub use special_file::*; pub use empty_fs::*; +pub use null_file::*; +pub use passthru_fs::*; +pub use special_file::*; +pub use tmp_fs::*; pub use tty_file::*; -pub use zero_file::*; \ No newline at end of file +pub use union_fs::*; +pub use zero_file::*; diff --git a/lib/wasi/src/fs/null_file.rs b/lib/wasi/src/fs/null_file.rs index dda151fab..e19b2f914 100644 --- a/lib/wasi/src/fs/null_file.rs +++ b/lib/wasi/src/fs/null_file.rs @@ -1,7 +1,7 @@ use std::io::{self, *}; use wasmer_vbus::FileDescriptor; -use wasmer_vfs::{VirtualFile, ClonableVirtualFile}; +use wasmer_vfs::{ClonableVirtualFile, VirtualFile}; #[derive(Debug, Clone, Default)] pub struct NullFile {} @@ -53,4 +53,4 @@ impl VirtualFile for NullFile { } } -impl ClonableVirtualFile for NullFile {} \ No newline at end of file +impl ClonableVirtualFile for NullFile {} diff --git a/lib/wasi/src/fs/passthru_fs.rs b/lib/wasi/src/fs/passthru_fs.rs index 785229708..a4c14cbdd 100644 --- a/lib/wasi/src/fs/passthru_fs.rs +++ b/lib/wasi/src/fs/passthru_fs.rs @@ -11,9 +11,7 @@ pub struct PassthruFileSystem { impl PassthruFileSystem { pub fn new(inner: Box) -> Self { - Self { - fs: inner, - } + Self { fs: inner } } } diff --git a/lib/wasi/src/fs/special_file.rs b/lib/wasi/src/fs/special_file.rs index 4cd5c2720..795db1d54 100644 --- a/lib/wasi/src/fs/special_file.rs +++ b/lib/wasi/src/fs/special_file.rs @@ -6,14 +6,12 @@ use wasmer_wasi_types::__wasi_fd_t; #[derive(Debug)] pub struct SpecialFile { - fd: __wasi_fd_t + fd: __wasi_fd_t, } impl SpecialFile { pub fn new(fd: __wasi_fd_t) -> Self { - Self { - fd - } + Self { fd } } } @@ -61,8 +59,8 @@ impl VirtualFile for SpecialFile { } fn get_special_fd(&self) -> Option { Some(self.fd) - } + } fn get_fd(&self) -> Option { None } -} \ No newline at end of file +} diff --git a/lib/wasi/src/fs/tmp_fs.rs b/lib/wasi/src/fs/tmp_fs.rs index 03d0e2546..d60854bcc 100644 --- a/lib/wasi/src/fs/tmp_fs.rs +++ b/lib/wasi/src/fs/tmp_fs.rs @@ -12,10 +12,10 @@ use std::sync::Mutex; #[allow(unused_imports, dead_code)] use tracing::{debug, error, info, trace, warn}; +use crate::{types as wasi_types, WasiFile, WasiFsError}; use wasmer_vfs::mem_fs; use wasmer_vfs::Result as FsResult; use wasmer_vfs::*; -use crate::{types as wasi_types, WasiFile, WasiFsError}; #[derive(Debug, Clone)] pub struct TmpFileSystem { @@ -37,7 +37,12 @@ impl TmpFileSystem { self.fs.union(other) } - pub fn mount(&self, src_path: PathBuf, other: &Arc, dst_path: PathBuf) -> Result<()> { + pub fn mount( + &self, + src_path: PathBuf, + other: &Arc, + dst_path: PathBuf, + ) -> Result<()> { self.fs.mount(src_path, other, dst_path) } } diff --git a/lib/wasi/src/fs/tty_file.rs b/lib/wasi/src/fs/tty_file.rs index 9236ed2f2..74fd881e7 100644 --- a/lib/wasi/src/fs/tty_file.rs +++ b/lib/wasi/src/fs/tty_file.rs @@ -1,9 +1,6 @@ use std::{ - io::{ - self, - * - }, - sync::Arc + io::{self, *}, + sync::Arc, }; use wasmer_vbus::FileDescriptor; use wasmer_vfs::VirtualFile; @@ -11,16 +8,15 @@ use wasmer_vfs::VirtualFile; #[derive(Debug)] pub struct TtyFile { runtime: Arc, - stdin: Box + stdin: Box, } -impl TtyFile -{ - pub fn new(runtime: Arc, stdin: Box) -> Self { - Self { - runtime, - stdin - } +impl TtyFile { + pub fn new( + runtime: Arc, + stdin: Box, + ) -> Self { + Self { runtime, stdin } } } diff --git a/lib/wasi/src/fs/union_fs.rs b/lib/wasi/src/fs/union_fs.rs index 202e10206..c7145d6ec 100644 --- a/lib/wasi/src/fs/union_fs.rs +++ b/lib/wasi/src/fs/union_fs.rs @@ -1,6 +1,5 @@ #![allow(dead_code)] #![allow(unused)] -use wasmer_vfs::*; use std::borrow::Cow; use std::ops::Add; use std::path::{Path, PathBuf}; @@ -10,6 +9,7 @@ use std::sync::Mutex; use std::sync::Weak; #[allow(unused_imports, dead_code)] use tracing::{debug, error, info, trace, warn}; +use wasmer_vfs::*; #[derive(Debug)] pub struct MountPoint { @@ -87,9 +87,7 @@ pub struct UnionFileSystem { impl UnionFileSystem { pub fn new() -> UnionFileSystem { - UnionFileSystem { - mounts: Vec::new(), - } + UnionFileSystem { mounts: Vec::new() } } pub fn clear(&mut self) { @@ -254,13 +252,16 @@ impl FileSystem for UnionFileSystem { if to.starts_with("/") == false { to = format!("/{}", to); } - match mount.fs.rename(Path::new(from.as_ref()), Path::new(to.as_str())) { + match mount + .fs + .rename(Path::new(from.as_ref()), Path::new(to.as_str())) + { Ok(ret) => { trace!("rename ok"); return Ok(ret); } Err(err) => { - trace!("rename error (from={}, to={}) - {}", from, to, err); + trace!("rename error (from={}, to={}) - {}", from, to, err); ret_error = err; } } @@ -417,12 +418,7 @@ impl FileOpener for UnionFileOpener { } } for (path, mount) in filter_mounts(&self.mounts, path.as_ref()) { - match mount - .fs - .new_open_options() - .options(conf.clone()) - .open(path) - { + match mount.fs.new_open_options().options(conf.clone()).open(path) { Ok(ret) => return Ok(ret), Err(err) if ret_err == FsError::EntryNotFound => { ret_err = err; diff --git a/lib/wasi/src/lib.rs b/lib/wasi/src/lib.rs index 46bdd9bd9..92a05f066 100644 --- a/lib/wasi/src/lib.rs +++ b/lib/wasi/src/lib.rs @@ -15,8 +15,12 @@ #[cfg(all(not(feature = "sys"), not(feature = "js")))] compile_error!("At least the `sys` or the `js` feature must be enabled. Please, pick one."); -#[cfg(feature="compiler")] -#[cfg(not(any(feature = "compiler-cranelift", feature = "compiler-llvm", feature = "compiler-singlepass")))] +#[cfg(feature = "compiler")] +#[cfg(not(any( + feature = "compiler-cranelift", + feature = "compiler-llvm", + feature = "compiler-singlepass" +)))] compile_error!("Either feature \"compiler_cranelift\", \"compiler_singlepass\" or \"compiler_llvm\" must be enabled when using \"compiler\"."); #[cfg(all(feature = "sys", feature = "js"))] @@ -34,19 +38,19 @@ compile_error!( #[macro_use] mod macros; -pub mod runtime; -mod state; -mod syscalls; -mod utils; -pub mod fs; -#[cfg(feature = "os")] -pub mod wapm; #[cfg(feature = "os")] pub mod bin_factory; #[cfg(feature = "os")] pub mod builtins; +pub mod fs; #[cfg(feature = "os")] pub mod os; +pub mod runtime; +mod state; +mod syscalls; +mod utils; +#[cfg(feature = "os")] +pub mod wapm; #[cfg(feature = "compiler")] pub use wasmer_compiler; @@ -58,9 +62,9 @@ pub use wasmer_compiler_llvm; pub use wasmer_compiler_singlepass; pub use crate::state::{ - Fd, Pipe, WasiFs, WasiInodes, WasiState, WasiStateBuilder, - WasiThreadId, WasiThreadHandle, WasiProcessId, WasiControlPlane, WasiThread, WasiProcess, WasiPipe, - WasiStateCreationError, ALL_RIGHTS, VIRTUAL_ROOT_FD, default_fs_backing + default_fs_backing, Fd, Pipe, WasiControlPlane, WasiFs, WasiInodes, WasiPipe, WasiProcess, + WasiProcessId, WasiState, WasiStateBuilder, WasiStateCreationError, WasiThread, + WasiThreadHandle, WasiThreadId, ALL_RIGHTS, VIRTUAL_ROOT_FD, }; pub use crate::syscalls::types; pub use crate::utils::{ @@ -69,29 +73,31 @@ pub use crate::utils::{ #[cfg(feature = "os")] use bin_factory::BinFactory; #[allow(unused_imports)] -use bytes::{BytesMut, Bytes}; +use bytes::{Bytes, BytesMut}; use derivative::Derivative; use syscalls::platform_clock_time_get; -use tracing::{trace, warn, error}; +use tracing::{error, trace, warn}; use wasmer_vbus::SpawnEnvironmentIntrinsics; -pub use wasmer_vbus::{DefaultVirtualBus, VirtualBus, BusSpawnedProcessJoin}; +pub use wasmer_vbus::{BusSpawnedProcessJoin, DefaultVirtualBus, VirtualBus}; #[deprecated(since = "2.1.0", note = "Please use `wasmer_vfs::FsError`")] pub use wasmer_vfs::FsError as WasiFsError; #[deprecated(since = "2.1.0", note = "Please use `wasmer_vfs::VirtualFile`")] pub use wasmer_vfs::VirtualFile as WasiFile; pub use wasmer_vfs::{FsError, VirtualFile}; pub use wasmer_vnet::{UnsupportedVirtualNetworking, VirtualNetworking}; -use wasmer_wasi_types::{__WASI_CLOCK_MONOTONIC, __WASI_SIGKILL, __WASI_SIGQUIT, __WASI_SIGINT, __WASI_EINTR}; +use wasmer_wasi_types::{ + __WASI_CLOCK_MONOTONIC, __WASI_EINTR, __WASI_SIGINT, __WASI_SIGKILL, __WASI_SIGQUIT, +}; // re-exports needed for OS #[cfg(feature = "os")] +pub use wasmer; +#[cfg(feature = "os")] +pub use wasmer_vbus; +#[cfg(feature = "os")] pub use wasmer_vfs; #[cfg(feature = "os")] pub use wasmer_vnet; -#[cfg(feature = "os")] -pub use wasmer_vbus; -#[cfg(feature = "os")] -pub use wasmer; use std::cell::RefCell; use std::ops::Deref; @@ -99,14 +105,15 @@ use std::sync::atomic::{AtomicU32, Ordering}; use thiserror::Error; use tracing::trace; use wasmer::{ - imports, namespace, AsStoreMut, Exports, Function, FunctionEnv, Imports, Memory, Memory32, - MemoryAccessError, MemorySize, Module, TypedFunction, Memory64, MemoryView, AsStoreRef, Instance, ExportError, Global, Value, Store, + imports, namespace, AsStoreMut, AsStoreRef, ExportError, Exports, Function, FunctionEnv, + Global, Imports, Instance, Memory, Memory32, Memory64, MemoryAccessError, MemorySize, + MemoryView, Module, Store, TypedFunction, Value, }; use wasmer_wasi_types::wasi::{BusErrno, Errno, Snapshot0Clockid}; pub use runtime::{ - PluggableRuntimeImplementation, WasiRuntimeImplementation, WasiThreadError, WasiTtyState, - WebSocketAbi, VirtualTaskManager, SpawnedMemory + PluggableRuntimeImplementation, SpawnedMemory, VirtualTaskManager, WasiRuntimeImplementation, + WasiThreadError, WasiTtyState, WebSocketAbi, }; use std::sync::{Arc, RwLockReadGuard, RwLockWriteGuard}; use std::time::Duration; @@ -149,8 +156,7 @@ impl From for u32 { #[derive(Derivative, Clone)] #[derivative(Debug)] -pub struct WasiEnvInner -{ +pub struct WasiEnvInner { /// Represents a reference to the memory memory: Memory, /// Represents the module that is being used (this is NOT send/sync) @@ -223,27 +229,61 @@ pub struct WasiEnvInner asyncify_get_state: Option>, } -impl WasiEnvInner -{ - pub fn new(module: Module, memory: Memory, store: &impl AsStoreRef, instance: &Instance) -> Self - { +impl WasiEnvInner { + pub fn new( + module: Module, + memory: Memory, + store: &impl AsStoreRef, + instance: &Instance, + ) -> Self { WasiEnvInner { module, memory, exports: instance.exports.clone(), - stack_pointer: instance.exports.get_global("__stack_pointer").map(|a| a.clone()).ok(), + stack_pointer: instance + .exports + .get_global("__stack_pointer") + .map(|a| a.clone()) + .ok(), start: instance.exports.get_typed_function(store, "_start").ok(), - initialize: instance.exports.get_typed_function(store, "_initialize").ok(), - thread_spawn: instance.exports.get_typed_function(store, "_start_thread").ok(), + initialize: instance + .exports + .get_typed_function(store, "_initialize") + .ok(), + thread_spawn: instance + .exports + .get_typed_function(store, "_start_thread") + .ok(), react: instance.exports.get_typed_function(store, "_react").ok(), - signal: instance.exports.get_typed_function(store, "__wasm_signal").ok(), + signal: instance + .exports + .get_typed_function(store, "__wasm_signal") + .ok(), signal_set: false, - asyncify_start_unwind: instance.exports.get_typed_function(store, "asyncify_start_unwind").ok(), - asyncify_stop_unwind: instance.exports.get_typed_function(store, "asyncify_stop_unwind").ok(), - asyncify_start_rewind: instance.exports.get_typed_function(store, "asyncify_start_rewind").ok(), - asyncify_stop_rewind: instance.exports.get_typed_function(store, "asyncify_stop_rewind").ok(), - asyncify_get_state: instance.exports.get_typed_function(store, "asyncify_get_state").ok(), - thread_local_destroy: instance.exports.get_typed_function(store, "_thread_local_destroy").ok(), + asyncify_start_unwind: instance + .exports + .get_typed_function(store, "asyncify_start_unwind") + .ok(), + asyncify_stop_unwind: instance + .exports + .get_typed_function(store, "asyncify_stop_unwind") + .ok(), + asyncify_start_rewind: instance + .exports + .get_typed_function(store, "asyncify_start_rewind") + .ok(), + asyncify_stop_rewind: instance + .exports + .get_typed_function(store, "asyncify_stop_rewind") + .ok(), + asyncify_get_state: instance + .exports + .get_typed_function(store, "asyncify_get_state") + .ok(), + thread_local_destroy: instance + .exports + .get_typed_function(store, "_thread_local_destroy") + .ok(), } } } @@ -251,8 +291,8 @@ impl WasiEnvInner /// The code itself makes safe use of the struct so multiple threads don't access /// it (without this the JS code prevents the reference to the module from being stored /// which is needed for the multithreading mode) -unsafe impl Send for WasiEnvInner { } -unsafe impl Sync for WasiEnvInner { } +unsafe impl Send for WasiEnvInner {} +unsafe impl Sync for WasiEnvInner {} /// The default stack size for WASIX pub const DEFAULT_STACK_SIZE: u64 = 1_048_576u64; @@ -279,9 +319,7 @@ pub struct WasiVFork { /// The environment provided to the WASI imports. #[derive(Derivative, Clone)] #[derivative(Debug)] -pub struct WasiEnv -where -{ +pub struct WasiEnv { /// Represents the process this environment is attached to pub process: WasiProcess, /// Represents the thread this environment is attached to @@ -301,27 +339,26 @@ where pub bin_factory: BinFactory, /// Inner functions and references that are loaded before the environment starts pub inner: Option, - /// List of the handles that are owned by this context + /// List of the handles that are owned by this context /// (this can be used to ensure that threads own themselves or others) pub owned_handles: Vec, /// Implementation of the WASI runtime. pub runtime: Arc, /// Task manager used to spawn threads and manage the ASYNC runtime - pub tasks: Arc + pub tasks: Arc, } impl WasiEnv { /// Forking the WasiState is used when either fork or vfork is called - pub fn fork(&self) -> (Self, WasiThreadHandle) - { - let process = self.process.compute.new_process(); + pub fn fork(&self) -> (Self, WasiThreadHandle) { + let process = self.process.compute.new_process(); let handle = process.new_thread(); - + let thread = handle.as_thread(); thread.copy_stack_from(&self.thread); - + let state = Arc::new(self.state.fork()); - + #[cfg(feature = "os")] let bin_factory = { let mut bin_factory = self.bin_factory.clone(); @@ -344,7 +381,7 @@ impl WasiEnv { runtime: self.runtime.clone(), tasks: self.tasks.clone(), }, - handle + handle, ) } @@ -366,29 +403,45 @@ lazy_static::lazy_static! { /// Returns the current thread ID pub fn current_caller_id() -> WasiCallingId { - CALLER_ID.with(|f| { - let mut caller_id = f.borrow_mut(); - if *caller_id == 0 { - *caller_id = CALLER_ID_SEED.fetch_add(1, Ordering::AcqRel); - } - *caller_id - }).into() + CALLER_ID + .with(|f| { + let mut caller_id = f.borrow_mut(); + if *caller_id == 0 { + *caller_id = CALLER_ID_SEED.fetch_add(1, Ordering::AcqRel); + } + *caller_id + }) + .into() } impl WasiEnv { - pub fn new(state: WasiState, #[cfg(feature = "os")] compiled_modules: Arc, process: WasiProcess, thread: WasiThreadHandle) -> Self { + pub fn new( + state: WasiState, + #[cfg(feature = "os")] compiled_modules: Arc, + process: WasiProcess, + thread: WasiThreadHandle, + ) -> Self { let state = Arc::new(state); let runtime = Arc::new(PluggableRuntimeImplementation::default()); - Self::new_ext(state, #[cfg(feature = "os")] compiled_modules, process, thread, runtime) + Self::new_ext( + state, + #[cfg(feature = "os")] + compiled_modules, + process, + thread, + runtime, + ) } - pub fn new_ext(state: Arc, #[cfg(feature = "os")] compiled_modules: Arc, process: WasiProcess, thread: WasiThreadHandle, runtime: Arc) -> Self { + pub fn new_ext( + state: Arc, + #[cfg(feature = "os")] compiled_modules: Arc, + process: WasiProcess, + thread: WasiThreadHandle, + runtime: Arc, + ) -> Self { #[cfg(feature = "os")] - let bin_factory = BinFactory::new( - state.clone(), - compiled_modules, - runtime.clone() - ); + let bin_factory = BinFactory::new(state.clone(), compiled_modules, runtime.clone()); let tasks = runtime.new_task_manager(); let mut ret = Self { process, @@ -402,12 +455,12 @@ impl WasiEnv { runtime, tasks, #[cfg(feature = "os")] - bin_factory + bin_factory, }; ret.owned_handles.push(thread); ret } - + /// Returns a copy of the current runtime implementation for this environment pub fn runtime<'a>(&'a self) -> &'a (dyn WasiRuntimeImplementation) { self.runtime.deref() @@ -419,7 +472,7 @@ impl WasiEnv { } /// Overrides the runtime implementation for this environment - pub fn set_runtime(&mut self, runtime: R) + pub fn set_runtime(&mut self, runtime: R) where R: WasiRuntimeImplementation + Send + Sync + 'static, { @@ -432,17 +485,13 @@ impl WasiEnv { } /// Porcesses any signals that are batched up - pub fn process_signals(&self, store: &mut impl AsStoreMut) -> Result<(), WasiError> - { + pub fn process_signals(&self, store: &mut impl AsStoreMut) -> Result<(), WasiError> { // If a signal handler has never been set then we need to handle signals // differently if self.inner().signal_set == false { let signals = self.thread.pop_signals(); for sig in signals { - if sig == __WASI_SIGINT || - sig == __WASI_SIGQUIT || - sig == __WASI_SIGKILL - { + if sig == __WASI_SIGINT || sig == __WASI_SIGQUIT || sig == __WASI_SIGKILL { return Err(WasiError::Exit(__WASI_EINTR as u32)); } else { trace!("wasi[{}]::signal-ignored: {}", self.pid(), sig); @@ -461,7 +510,8 @@ impl WasiEnv { let mut any = false; let inner = self.process.inner.read().unwrap(); if inner.signal_intervals.is_empty() == false { - now = platform_clock_time_get(__WASI_CLOCK_MONOTONIC, 1_000_000).unwrap() as u128; + now = + platform_clock_time_get(__WASI_CLOCK_MONOTONIC, 1_000_000).unwrap() as u128; for signal in inner.signal_intervals.values() { let elapsed = now - signal.last_signal; if elapsed >= signal.interval.as_nanos() { @@ -491,7 +541,11 @@ impl WasiEnv { return Err(err); } Err(err) => { - warn!("wasi[{}]::signal handler runtime error - {}", self.pid(), err); + warn!( + "wasi[{}]::signal handler runtime error - {}", + self.pid(), + err + ); return Err(WasiError::Exit(1)); } } @@ -502,8 +556,7 @@ impl WasiEnv { } // Yields execution - pub fn yield_now_with_signals(&self, store: &mut impl AsStoreMut) -> Result<(), WasiError> - { + pub fn yield_now_with_signals(&self, store: &mut impl AsStoreMut) -> Result<(), WasiError> { self.process_signals(store)?; self.yield_now() } @@ -519,14 +572,14 @@ impl WasiEnv { let tasks = self.tasks.clone(); self.tasks.block_on(Box::pin(async move { tasks.sleep_now(current_caller_id(), 0); - })); + })); Ok(()) } - + // Sleeps for a period of time pub fn sleep(&self, store: &mut impl AsStoreMut, duration: Duration) -> Result<(), WasiError> { let mut signaler = self.thread.signals.1.subscribe(); - + let tasks = self.tasks.clone(); let (tx_signaller, mut rx_signaller) = tokio::sync::mpsc::unbounded_channel(); self.tasks.block_on(Box::pin(async move { @@ -559,17 +612,19 @@ impl WasiEnv { /// Providers safe access to the initialized part of WasiEnv /// (it must be initialized before it can be used) pub fn inner(&self) -> &WasiEnvInner { - self.inner.as_ref() + self.inner + .as_ref() .expect("You must initialize the WasiEnv before using it") } /// Providers safe access to the initialized part of WasiEnv /// (it must be initialized before it can be used) pub fn inner_mut(&mut self) -> &mut WasiEnvInner { - self.inner.as_mut() + self.inner + .as_mut() .expect("You must initialize the WasiEnv before using it") } - + /// Providers safe access to the memory /// (it must be initialized before it can be used) pub fn memory_view<'a>(&'a self, store: &'a impl AsStoreRef) -> MemoryView<'a> { @@ -592,8 +647,12 @@ impl WasiEnv { pub fn state(&self) -> &WasiState { &self.state } - - pub(crate) fn get_memory_and_wasi_state<'a>(&'a self, store: &'a impl AsStoreRef, _mem_index: u32) -> (MemoryView<'a>, &WasiState) { + + pub(crate) fn get_memory_and_wasi_state<'a>( + &'a self, + store: &'a impl AsStoreRef, + _mem_index: u32, + ) -> (MemoryView<'a>, &WasiState) { let memory = self.memory_view(store); let state = self.state.deref(); (memory, state) @@ -623,9 +682,13 @@ impl WasiEnv { #[cfg(feature = "os")] pub fn uses<'a, I>(&self, uses: I) -> Result<(), WasiStateCreationError> - where I: IntoIterator + where + I: IntoIterator, { - use std::{collections::{VecDeque, HashMap}, borrow::Cow}; + use std::{ + borrow::Cow, + collections::{HashMap, VecDeque}, + }; // Load all the containers that we inherit from #[allow(unused_imports)] use std::path::Path; @@ -638,18 +701,25 @@ impl WasiEnv { let mut use_packages = uses.into_iter().collect::>(); while let Some(use_package) = use_packages.pop_back() { - if let Some(package) = self.bin_factory.builtins.cmd_wasmer.get(use_package.clone(), self.tasks.deref()) + if let Some(package) = self + .bin_factory + .builtins + .cmd_wasmer + .get(use_package.clone(), self.tasks.deref()) { // If its already been added make sure the version is correct let package_name = package.package_name.to_string(); if let Some(version) = already.get(&package_name) { if version.as_ref() != package.version.as_ref() { - return Err(WasiStateCreationError::WasiInheritError(format!("webc package version conflict for {} - {} vs {}", use_package, version, package.version))); + return Err(WasiStateCreationError::WasiInheritError(format!( + "webc package version conflict for {} - {} vs {}", + use_package, version, package.version + ))); } continue; } already.insert(package_name, package.version.clone()); - + // Add the additional dependencies for dependency in package.uses.clone() { use_packages.push_back(dependency); @@ -672,21 +742,32 @@ impl WasiEnv { .new_open_options_ext() .insert_ro_file(path, command.atom.clone()) { - tracing::debug!("failed to add package [{}] command [{}] - {}", use_package, command.name, err); + tracing::debug!( + "failed to add package [{}] command [{}] - {}", + use_package, + command.name, + err + ); continue; } // Add the binary package to the bin factory (zero copy the atom) let mut package = package.clone(); package.entry = command.atom.clone(); - self.bin_factory.set_binary(path.as_os_str().to_string_lossy().as_ref(), package); + self.bin_factory + .set_binary(path.as_os_str().to_string_lossy().as_ref(), package); } } } else { - return Err(WasiStateCreationError::WasiInheritError(format!("failed to add package as the file system is not sandboxed"))); + return Err(WasiStateCreationError::WasiInheritError(format!( + "failed to add package as the file system is not sandboxed" + ))); } } else { - return Err(WasiStateCreationError::WasiInheritError(format!("failed to fetch webc package for {}", use_package))); + return Err(WasiStateCreationError::WasiInheritError(format!( + "failed to fetch webc package for {}", + use_package + ))); } } Ok(()) @@ -694,8 +775,10 @@ impl WasiEnv { #[cfg(feature = "os")] #[cfg(feature = "sys")] - pub fn map_commands(&self, map_commands: std::collections::HashMap) -> Result<(), WasiStateCreationError> - { + pub fn map_commands( + &self, + map_commands: std::collections::HashMap, + ) -> Result<(), WasiStateCreationError> { // Load all the mapped atoms #[allow(unused_imports)] use std::path::Path; @@ -707,21 +790,21 @@ impl WasiEnv { #[cfg(feature = "sys")] for (command, target) in map_commands.iter() { // Read the file - let file = std::fs::read(target) - .map_err(|err| { - WasiStateCreationError::WasiInheritError(format!("failed to read local binary [{}] - {}", target.as_os_str().to_string_lossy(), err)) - })?; + let file = std::fs::read(target).map_err(|err| { + WasiStateCreationError::WasiInheritError(format!( + "failed to read local binary [{}] - {}", + target.as_os_str().to_string_lossy(), + err + )) + })?; let file: std::borrow::Cow<'static, [u8]> = file.into(); - + if let WasiFsRoot::Sandbox(root_fs) = &self.state.fs.root_fs { let _ = root_fs.create_dir(Path::new("/bin")); - + let path = format!("/bin/{}", command); let path = Path::new(path.as_str()); - if let Err(err) = root_fs - .new_open_options_ext() - .insert_ro_file(path, file) - { + if let Err(err) = root_fs.new_open_options_ext().insert_ro_file(path, file) { tracing::debug!("failed to add atom command [{}] - {}", command, err); continue; } @@ -734,9 +817,7 @@ impl WasiEnv { } } -impl SpawnEnvironmentIntrinsics -for WasiEnv -{ +impl SpawnEnvironmentIntrinsics for WasiEnv { fn args(&self) -> &Vec { &self.state.args } @@ -804,16 +885,18 @@ impl WasiFunctionEnv { /// Gets a mutable- reference to the host state in this context. pub fn data_mut<'a>(&'a mut self, store: &'a mut impl AsStoreMut) -> &'a mut WasiEnv { - self.env - .as_mut(store) + self.env.as_mut(store) } /// Initializes the WasiEnv using the instance exports /// (this must be executed before attempting to use it) /// (as the stores can not by themselves be passed between threads we can store the module /// in a thread-local variables and use it later - for multithreading) - pub fn initialize(&mut self, store: &mut impl AsStoreMut, instance: &Instance) -> Result<(), ExportError> - { + pub fn initialize( + &mut self, + store: &mut impl AsStoreMut, + instance: &Instance, + ) -> Result<(), ExportError> { // List all the exports and imports for ns in instance.module().exports() { //trace!("module::export - {} ({:?})", ns.name(), ns.ty()); @@ -830,19 +913,50 @@ impl WasiFunctionEnv { memory, module: instance.module().clone(), exports: instance.exports.clone(), - stack_pointer: instance.exports.get_global("__stack_pointer").map(|a| a.clone()).ok(), + stack_pointer: instance + .exports + .get_global("__stack_pointer") + .map(|a| a.clone()) + .ok(), start: instance.exports.get_typed_function(store, "_start").ok(), - initialize: instance.exports.get_typed_function(store, "_initialize").ok(), - thread_spawn: instance.exports.get_typed_function(store, "_start_thread").ok(), + initialize: instance + .exports + .get_typed_function(store, "_initialize") + .ok(), + thread_spawn: instance + .exports + .get_typed_function(store, "_start_thread") + .ok(), react: instance.exports.get_typed_function(store, "_react").ok(), - signal: instance.exports.get_typed_function(&store, "__wasm_signal").ok(), + signal: instance + .exports + .get_typed_function(&store, "__wasm_signal") + .ok(), signal_set: false, - asyncify_start_unwind: instance.exports.get_typed_function(store, "asyncify_start_unwind").ok(), - asyncify_stop_unwind: instance.exports.get_typed_function(store, "asyncify_stop_unwind").ok(), - asyncify_start_rewind: instance.exports.get_typed_function(store, "asyncify_start_rewind").ok(), - asyncify_stop_rewind: instance.exports.get_typed_function(store, "asyncify_stop_rewind").ok(), - asyncify_get_state: instance.exports.get_typed_function(store, "asyncify_get_state").ok(), - thread_local_destroy: instance.exports.get_typed_function(store, "_thread_local_destroy").ok(), + asyncify_start_unwind: instance + .exports + .get_typed_function(store, "asyncify_start_unwind") + .ok(), + asyncify_stop_unwind: instance + .exports + .get_typed_function(store, "asyncify_stop_unwind") + .ok(), + asyncify_start_rewind: instance + .exports + .get_typed_function(store, "asyncify_start_rewind") + .ok(), + asyncify_stop_rewind: instance + .exports + .get_typed_function(store, "asyncify_stop_rewind") + .ok(), + asyncify_get_state: instance + .exports + .get_typed_function(store, "asyncify_get_state") + .ok(), + thread_local_destroy: instance + .exports + .get_typed_function(store, "_thread_local_destroy") + .ok(), }; let env = self.data_mut(store); @@ -858,7 +972,7 @@ impl WasiFunctionEnv { match stack_pointer.get(store) { Value::I32(a) => a as u64, Value::I64(a) => a as u64, - _ => DEFAULT_STACK_SIZE + _ => DEFAULT_STACK_SIZE, } } else { DEFAULT_STACK_SIZE @@ -917,7 +1031,10 @@ impl WasiFunctionEnv { } pub fn cleanup(&self, store: &mut Store) { - trace!("wasi[{}]:: cleaning up local thread variables", self.data(store).pid()); + trace!( + "wasi[{}]:: cleaning up local thread variables", + self.data(store).pid() + ); // Destroy all the local thread variables that were allocated for this thread let to_local_destroy = { @@ -935,7 +1052,13 @@ impl WasiFunctionEnv { to_local_destroy }; if to_local_destroy.len() > 0 { - if let Some(thread_local_destroy) = self.data(store).inner().thread_local_destroy.as_ref().map(|a| a.clone()) { + if let Some(thread_local_destroy) = self + .data(store) + .inner() + .thread_local_destroy + .as_ref() + .map(|a| a.clone()) + { for (user_data, val) in to_local_destroy { let user_data_low: u32 = (user_data & 0xFFFFFFFF) as u32; let user_data_high: u32 = (user_data >> 32) as u32; @@ -943,15 +1066,24 @@ impl WasiFunctionEnv { let val_low: u32 = (val & 0xFFFFFFFF) as u32; let val_high: u32 = (val >> 32) as u32; - let _ = thread_local_destroy.call(store, user_data_low as i32, user_data_high as i32, val_low as i32, val_high as i32); + let _ = thread_local_destroy.call( + store, + user_data_low as i32, + user_data_high as i32, + val_low as i32, + val_high as i32, + ); } } } // If this is the main thread then also close all the files if self.data(store).thread.is_main() { - trace!("wasi[{}]:: cleaning up open file handles", self.data(store).pid()); - + trace!( + "wasi[{}]:: cleaning up open file handles", + self.data(store).pid() + ); + let inodes = self.data(store).state.inodes.read().unwrap(); self.data(store).state.fs.close_all(inodes.deref()); } @@ -1083,11 +1215,7 @@ fn wasi_snapshot_preview1_exports( namespace } -fn wasix_exports_32( - mut store: &mut impl AsStoreMut, - env: &FunctionEnv, -) -> Exports -{ +fn wasix_exports_32(mut store: &mut impl AsStoreMut, env: &FunctionEnv) -> Exports { use syscalls::*; let namespace = namespace! { "args_get" => Function::new_typed_with_env(&mut store, env, args_get::), @@ -1222,11 +1350,7 @@ fn wasix_exports_32( namespace } -fn wasix_exports_64( - mut store: &mut impl AsStoreMut, - env: &FunctionEnv, -) -> Exports -{ +fn wasix_exports_64(mut store: &mut impl AsStoreMut, env: &FunctionEnv) -> Exports { use syscalls::*; let namespace = namespace! { "args_get" => Function::new_typed_with_env(&mut store, env, args_get::), diff --git a/lib/wasi/src/macros.rs b/lib/wasi/src/macros.rs index 0d819b3b5..9018a2626 100644 --- a/lib/wasi/src/macros.rs +++ b/lib/wasi/src/macros.rs @@ -6,9 +6,7 @@ macro_rules! wasi_try { ($expr:expr) => {{ let res: Result<_, crate::syscalls::types::wasi::Errno> = $expr; match res { - Ok(val) => { - val - } + Ok(val) => val, Err(err) => { tracing::debug!("wasi::wasi_try::err: {:?}", err); return err; @@ -23,9 +21,7 @@ macro_rules! wasi_try_ok { ($expr:expr) => {{ let res: Result<_, crate::syscalls::types::wasi::Errno> = $expr; match res { - Ok(val) => { - val - } + Ok(val) => val, Err(err) => { tracing::debug!("wasi::wasi_try_ok::err: {:?}", err); return Ok(err); @@ -36,9 +32,7 @@ macro_rules! wasi_try_ok { ($expr:expr, $thread:expr) => {{ let res: Result<_, crate::syscalls::types::wasi::Errno> = $expr; match res { - Ok(val) => { - val - } + Ok(val) => val, Err(err) => { if err == crate::syscalls::types::wasi::Errno::Intr { $thread.yield_now()?; @@ -56,9 +50,7 @@ macro_rules! wasi_try_bus { ($expr:expr) => {{ let res: Result<_, crate::syscalls::types::wasi::BusErrno> = $expr; match res { - Ok(val) => { - val - } + Ok(val) => val, Err(err) => { tracing::debug!("wasi::wasi_try_bus::err: {:?}", err); return err; diff --git a/lib/wasi/src/os/cconst.rs b/lib/wasi/src/os/cconst.rs index 9bec0625d..cb96a9537 100644 --- a/lib/wasi/src/os/cconst.rs +++ b/lib/wasi/src/os/cconst.rs @@ -69,7 +69,7 @@ impl ConsoleConst { pub const COL_LIGHT_CYAN: &'static str = "\x1B[1;36m"; pub const COL_LIGHT_GRAY: &'static str = "\x1B[0;37m"; pub const COL_WHITE: &'static str = "\x1B[1;37m"; - + pub const WELCOME_LARGE: &'static str = include_str!("txt/welcome_large.txt"); pub const WELCOME_MEDIUM: &'static str = include_str!("txt/welcome_medium.txt"); pub const WELCOME_SMALL: &'static str = include_str!("txt/welcome_small.txt"); diff --git a/lib/wasi/src/os/console.rs b/lib/wasi/src/os/console.rs index c4163ee8e..a08bec436 100644 --- a/lib/wasi/src/os/console.rs +++ b/lib/wasi/src/os/console.rs @@ -1,40 +1,40 @@ #![allow(unused_imports)] #![allow(dead_code)] -use std::collections::HashMap; -use std::ops::{Deref, DerefMut}; -use std::io::Write; -use std::path::Path; -use std::sync::Arc; -use std::sync::Mutex; -use std::sync::atomic::AtomicBool; use derivative::*; use linked_hash_set::LinkedHashSet; +use std::collections::HashMap; +use std::io::Write; +use std::ops::{Deref, DerefMut}; +use std::path::Path; +use std::sync::atomic::AtomicBool; +use std::sync::Arc; +use std::sync::Mutex; use tokio::sync::mpsc; use tokio::sync::RwLock; #[allow(unused_imports, dead_code)] use tracing::{debug, error, info, trace, warn}; #[cfg(feature = "sys")] use wasmer::Engine; -use wasmer_vbus::{SpawnOptionsConfig, BusSpawnedProcess}; +use wasmer_vbus::{BusSpawnedProcess, SpawnOptionsConfig}; use wasmer_vfs::FileSystem; -use crate::{WasiControlPlane, WasiEnv, WasiProcess, WasiState}; -use crate::WasiRuntimeImplementation; +use crate::bin_factory::spawn_exec; use crate::bin_factory::BinFactory; use crate::bin_factory::CachedCompiledModules; -use crate::bin_factory::spawn_exec; -use crate::WasiPipe; -use crate::runtime::RuntimeStdout; use crate::runtime::RuntimeStderr; +use crate::runtime::RuntimeStdout; +use crate::WasiPipe; +use crate::WasiRuntimeImplementation; +use crate::{WasiControlPlane, WasiEnv, WasiProcess, WasiState}; +use super::cconst::ConsoleConst; use super::common::*; use super::posix_err; -use super::cconst::ConsoleConst; //pub const DEFAULT_BOOT_WEBC: &'static str = "sharrattj/bash"; pub const DEFAULT_BOOT_WEBC: &'static str = "sharrattj/dash"; //pub const DEFAULT_BOOT_USES: [&'static str; 2] = [ "sharrattj/coreutils", "sharrattj/catsay" ]; -pub const DEFAULT_BOOT_USES: [&'static str; 0] = [ ]; +pub const DEFAULT_BOOT_USES: [&'static str; 0] = []; #[derive(Derivative)] #[derivative(Debug)] @@ -59,8 +59,14 @@ impl Console { runtime: Arc, compiled_modules: Arc, ) -> Self { - let mut uses = DEFAULT_BOOT_USES.iter().map(|a| a.to_string()).collect::>(); - let prog = DEFAULT_BOOT_WEBC.split_once(" ").map(|a| a.1).unwrap_or(DEFAULT_BOOT_WEBC); + let mut uses = DEFAULT_BOOT_USES + .iter() + .map(|a| a.to_string()) + .collect::>(); + let prog = DEFAULT_BOOT_WEBC + .split_once(" ") + .map(|a| a.1) + .unwrap_or(DEFAULT_BOOT_WEBC); uses.insert(prog.to_string()); Self { boot_cmd: DEFAULT_BOOT_WEBC.to_string(), @@ -123,25 +129,23 @@ impl Console { self } - pub fn run(&mut self) -> wasmer_vbus::Result - { + pub fn run(&mut self) -> wasmer_vbus::Result { // Extract the program name from the arguments let empty_args: Vec<&[u8]> = Vec::new(); let (webc, prog, args) = match self.boot_cmd.split_once(" ") { - Some((webc, args)) => { - ( - webc, - webc.split_once("/").map(|a| a.1).unwrap_or(webc), - args.split(" ").map(|a| a.as_bytes()).collect::>() - ) - }, - None => { - ( - self.boot_cmd.as_str(), - self.boot_cmd.split_once("/").map(|a| a.1).unwrap_or(self.boot_cmd.as_str()), - empty_args - ) - } + Some((webc, args)) => ( + webc, + webc.split_once("/").map(|a| a.1).unwrap_or(webc), + args.split(" ").map(|a| a.as_bytes()).collect::>(), + ), + None => ( + self.boot_cmd.as_str(), + self.boot_cmd + .split_once("/") + .map(|a| a.1) + .unwrap_or(self.boot_cmd.as_str()), + empty_args, + ), }; let envs = self.env.clone(); @@ -185,16 +189,16 @@ impl Console { self.compiled_modules.clone(), process, thread, - self.runtime.clone() + self.runtime.clone(), ); - + // Find the binary - if let Some(binary) = self.compiled_modules.get_webc(webc, self.runtime.deref(), env.tasks.deref()) + if let Some(binary) = + self.compiled_modules + .get_webc(webc, self.runtime.deref(), env.tasks.deref()) { if let Err(err) = env.uses(self.uses.clone()) { - let _ = self.runtime.stderr( - format!("{}\r\n", err).as_bytes() - ); + let _ = self.runtime.stderr(format!("{}\r\n", err).as_bytes()); return Err(wasmer_vbus::VirtualBusError::BadRequest); } @@ -213,15 +217,16 @@ impl Console { store, config, &self.runtime, - self.compiled_modules.as_ref() - ).unwrap(); + self.compiled_modules.as_ref(), + ) + .unwrap(); // Return the process Ok(process) } else { - let _ = self.runtime.stderr( - format!("package not found [{}]\r\n", self.boot_cmd).as_bytes() - ); + let _ = self + .runtime + .stderr(format!("package not found [{}]\r\n", self.boot_cmd).as_bytes()); Err(wasmer_vbus::VirtualBusError::NotFound) } } diff --git a/lib/wasi/src/os/mod.rs b/lib/wasi/src/os/mod.rs index 9782f7021..52fcfe880 100644 --- a/lib/wasi/src/os/mod.rs +++ b/lib/wasi/src/os/mod.rs @@ -1,8 +1,8 @@ -mod tty; -pub mod posix_err; -pub mod common; pub mod cconst; +pub mod common; mod console; +pub mod posix_err; +mod tty; +pub use console::*; pub use tty::*; -pub use console::*; \ No newline at end of file diff --git a/lib/wasi/src/os/tty.rs b/lib/wasi/src/os/tty.rs index ff285afa2..850997e42 100644 --- a/lib/wasi/src/os/tty.rs +++ b/lib/wasi/src/os/tty.rs @@ -1,14 +1,14 @@ -use std::{sync::{Mutex, Arc}, io::Write}; use derivative::*; +use std::{ + io::Write, + sync::{Arc, Mutex}, +}; -use wasmer_vfs::VirtualFile; use wasmer_vbus::SignalHandlerAbi; +use wasmer_vfs::VirtualFile; use wasmer_wasi_types::__WASI_CLOCK_MONOTONIC; -use crate::{ - types::__WASI_SIGINT, - syscalls::platform_clock_time_get -}; +use crate::{syscalls::platform_clock_time_get, types::__WASI_SIGINT}; const TTY_MOBILE_PAUSE: u128 = std::time::Duration::from_millis(200).as_nanos(); @@ -25,13 +25,9 @@ pub struct ConsoleRect { pub rows: u32, } -impl Default -for ConsoleRect { +impl Default for ConsoleRect { fn default() -> Self { - Self { - cols: 80, - rows: 25 - } + Self { cols: 80, rows: 25 } } } @@ -45,22 +41,18 @@ pub struct TtyOptionsInner { #[derive(Debug, Clone)] pub struct TtyOptions { - inner: Arc> + inner: Arc>, } -impl Default -for TtyOptions { +impl Default for TtyOptions { fn default() -> Self { Self { inner: Arc::new(Mutex::new(TtyOptionsInner { echo: true, line_buffering: true, line_feeds: true, - rect: ConsoleRect { - cols: 80, - rows: 25 - } - })) + rect: ConsoleRect { cols: 80, rows: 25 }, + })), } } } @@ -134,7 +126,7 @@ impl Tty { stdin: Box, stdout: Box, is_mobile: bool, - options: TtyOptions + options: TtyOptions, ) -> Self { Self { stdin, @@ -143,7 +135,7 @@ impl Tty { last: None, options, is_mobile, - line: String::new() + line: String::new(), } } @@ -164,7 +156,8 @@ impl Tty { // Due to a nasty bug in xterm.js on Android mobile it sends the keys you press // twice in a row with a short interval between - this hack will avoid that bug if self.is_mobile { - let now = platform_clock_time_get(__WASI_CLOCK_MONOTONIC, 1_000_000).unwrap() as u128; + let now = + platform_clock_time_get(__WASI_CLOCK_MONOTONIC, 1_000_000).unwrap() as u128; if let Some((what, when)) = self.last.as_ref() { if what.as_str() == data && now - *when < TTY_MOBILE_PAUSE { self.last = None; @@ -176,14 +169,11 @@ impl Tty { self.on_data(data.as_bytes()) } - InputEvent::Raw(data) => { - self.on_data(&data[..]) - } + InputEvent::Raw(data) => self.on_data(&data[..]), } } - fn on_enter(&mut self, _data: &str) - { + fn on_enter(&mut self, _data: &str) { // Add a line feed on the end and take the line let mut data = self.line.clone(); self.line.clear(); @@ -202,8 +192,7 @@ impl Tty { let _ = self.stdin.write(data.as_bytes()); } - fn on_ctrl_c(&mut self, _data: &str) - { + fn on_ctrl_c(&mut self, _data: &str) { if let Some(signaler) = self.signaler.as_ref() { signaler.signal(__WASI_SIGINT); @@ -211,7 +200,7 @@ impl Tty { let options = self.options.inner.lock().unwrap(); (options.echo, options.line_buffering) }; - + self.line.clear(); if echo { self.stdout("\n".as_bytes()); @@ -220,15 +209,14 @@ impl Tty { } } - fn on_backspace(&mut self, _data: &str) - { + fn on_backspace(&mut self, _data: &str) { // Remove a character (if there are none left we are done) if self.line.is_empty() { return; } let len = self.line.len(); - self.line = (&self.line[..len-1]).to_string(); - + self.line = (&self.line[..len - 1]).to_string(); + // If echo is on then write the backspace { let options = self.options.inner.lock().unwrap(); @@ -239,96 +227,51 @@ impl Tty { } } - fn on_tab(&mut self, _data: &str) - { - } + fn on_tab(&mut self, _data: &str) {} - fn on_cursor_left(&mut self, _data: &str) - { - } + fn on_cursor_left(&mut self, _data: &str) {} - fn on_cursor_right(&mut self, _data: &str) - { - } + fn on_cursor_right(&mut self, _data: &str) {} - fn on_cursor_up(&mut self, _data: &str) - { - } + fn on_cursor_up(&mut self, _data: &str) {} - fn on_cursor_down(&mut self, _data: &str) - { - } + fn on_cursor_down(&mut self, _data: &str) {} - fn on_home(&mut self, _data: &str) - { - } + fn on_home(&mut self, _data: &str) {} - fn on_end(&mut self, _data: &str) - { - } + fn on_end(&mut self, _data: &str) {} - fn on_ctrl_l(&mut self, _data: &str) - { - } + fn on_ctrl_l(&mut self, _data: &str) {} - fn on_page_up(&mut self, _data: &str) - { - } + fn on_page_up(&mut self, _data: &str) {} - fn on_page_down(&mut self, _data: &str) - { - } + fn on_page_down(&mut self, _data: &str) {} - fn on_f1(&mut self, _data: &str) - { - } + fn on_f1(&mut self, _data: &str) {} - fn on_f2(&mut self, _data: &str) - { - } + fn on_f2(&mut self, _data: &str) {} - fn on_f3(&mut self, _data: &str) - { - } + fn on_f3(&mut self, _data: &str) {} - fn on_f4(&mut self, _data: &str) - { - } + fn on_f4(&mut self, _data: &str) {} - fn on_f5(&mut self, _data: &str) - { - } + fn on_f5(&mut self, _data: &str) {} - fn on_f6(&mut self, _data: &str) - { - } + fn on_f6(&mut self, _data: &str) {} - fn on_f7(&mut self, _data: &str) - { - } + fn on_f7(&mut self, _data: &str) {} - fn on_f8(&mut self, _data: &str) - { - } + fn on_f8(&mut self, _data: &str) {} - fn on_f9(&mut self, _data: &str) - { - } + fn on_f9(&mut self, _data: &str) {} - fn on_f10(&mut self, _data: &str) - { - } + fn on_f10(&mut self, _data: &str) {} - fn on_f11(&mut self, _data: &str) - { - } + fn on_f11(&mut self, _data: &str) {} - fn on_f12(&mut self, _data: &str) - { - } + fn on_f12(&mut self, _data: &str) {} - fn on_data(&mut self, data: &[u8]) - { + fn on_data(&mut self, data: &[u8]) { // If we are line buffering then we need to check for some special cases let options = self.options.inner.lock().unwrap(); if options.line_buffering { @@ -386,4 +329,4 @@ impl Tty { fn stdout(&mut self, data: &[u8]) { let _ = self.stdout.write(&data[..]); } -} \ No newline at end of file +} diff --git a/lib/wasi/src/runtime/mod.rs b/lib/wasi/src/runtime/mod.rs index 5bd41994d..069b8cc6c 100644 --- a/lib/wasi/src/runtime/mod.rs +++ b/lib/wasi/src/runtime/mod.rs @@ -1,18 +1,18 @@ +use derivative::Derivative; +use std::future::Future; use std::io::Write; +use std::pin::Pin; use std::sync::{Arc, Mutex}; use std::task::Waker; use std::{fmt, io}; -use std::future::Future; -use std::pin::Pin; use thiserror::Error; -use wasmer::{Module, Store, MemoryType}; +use tracing::*; use wasmer::vm::VMMemory; +use wasmer::{MemoryType, Module, Store}; #[cfg(feature = "sys")] use wasmer_types::MemoryStyle; use wasmer_vbus::{DefaultVirtualBus, VirtualBus}; use wasmer_vnet::VirtualNetworking; -use derivative::Derivative; -use tracing::*; use crate::{WasiCallingId, WasiEnv}; @@ -29,9 +29,7 @@ pub mod term; #[cfg(feature = "termios")] pub use term::*; -use tokio::runtime::{ - Builder, Runtime -}; +use tokio::runtime::{Builder, Runtime}; #[derive(Error, Debug)] pub enum WasiThreadError { @@ -71,8 +69,7 @@ pub struct WasiTtyState { pub line_feeds: bool, } -impl Default -for WasiTtyState { +impl Default for WasiTtyState { fn default() -> Self { Self { rows: 80, @@ -90,8 +87,7 @@ for WasiTtyState { } #[derive(Debug)] -pub struct SpawnedMemory -{ +pub struct SpawnedMemory { pub ty: MemoryType, #[cfg(feature = "sys")] pub style: MemoryStyle, @@ -122,12 +118,15 @@ pub struct ReqwestResponse { /// An implementation of task management #[allow(unused_variables)] -pub trait VirtualTaskManager: fmt::Debug + Send + Sync + 'static -{ +pub trait VirtualTaskManager: fmt::Debug + Send + Sync + 'static { /// Invokes whenever a WASM thread goes idle. In some runtimes (like singlethreaded /// execution environments) they will need to do asynchronous work whenever the main /// thread goes idle and this is the place to hook for that. - fn sleep_now(&self, _id: WasiCallingId, ms: u128) -> Pin + Send + Sync + 'static>>; + fn sleep_now( + &self, + _id: WasiCallingId, + ms: u128, + ) -> Pin + Send + Sync + 'static>>; /// Starts an asynchronous task that will run on a shared worker pool /// This task must not block the execution or it could cause a deadlock @@ -139,10 +138,7 @@ pub trait VirtualTaskManager: fmt::Debug + Send + Sync + 'static ) -> Result<(), WasiThreadError>; /// Starts an asynchronous task on the local thread (by running it in a runtime) - fn block_on( - &self, - task: Pin>>, - ); + fn block_on(&self, task: Pin>>); /// Starts an asynchronous task will will run on a dedicated thread /// pulled from the worker pool that has a stateful thread local variable @@ -200,7 +196,7 @@ pub trait VirtualTaskManager: fmt::Debug + Send + Sync + 'static } /// Waits for a periodic period (if there is anyone waiting on it) - fn wait_for_root_waker(&self) -> Pin + Send + Sync + 'static>> { + fn wait_for_root_waker(&self) -> Pin + Send + Sync + 'static>> { let (has_wakers, mut new_wakers) = { let periodic_wakers = self.periodic_wakers(); let guard = periodic_wakers.lock().unwrap(); @@ -226,7 +222,8 @@ pub trait VirtualTaskManager: fmt::Debug + Send + Sync + 'static /// unimplemented. #[allow(unused_variables)] pub trait WasiRuntimeImplementation -where Self: fmt::Debug + Sync, +where + Self: fmt::Debug + Sync, { /// For WASI runtimes that support it they can implement a message BUS implementation /// which allows runtimes to pass serialized messages between each other similar to @@ -251,8 +248,7 @@ where Self: fmt::Debug + Sync, /// Sets the TTY state #[cfg(not(feature = "host-termios"))] - fn tty_set(&self, _tty_state: WasiTtyState) { - } + fn tty_set(&self, _tty_state: WasiTtyState) {} #[cfg(feature = "host-termios")] fn tty_get(&self) -> WasiTtyState { @@ -263,7 +259,7 @@ where Self: fmt::Debug + Sync, if let Ok(termios) = termios::Termios::from_fd(0) { echo = (termios.c_lflag & termios::ECHO) != 0; line_buffered = (termios.c_lflag & termios::ICANON) != 0; - line_feeds = (termios.c_lflag & termios::ONLCR) != 0; + line_feeds = (termios.c_lflag & termios::ONLCR) != 0; } if let Some((w, h)) = term_size::dimensions() { @@ -350,40 +346,35 @@ where Self: fmt::Debug + Sync, debug!("failed to convert method ({}) - {}", method, err); __WASI_EIO as u32 })?; - + let client = reqwest::ClientBuilder::default().build().map_err(|err| { debug!("failed to build reqwest client - {}", err); __WASI_EIO as u32 })?; - + let mut builder = client.request(method, url.as_str()); for (header, val) in headers { - if let Ok(header) = - reqwest::header::HeaderName::from_bytes(header.as_bytes()) - { + if let Ok(header) = reqwest::header::HeaderName::from_bytes(header.as_bytes()) { builder = builder.header(header, val); } else { debug!("failed to parse header - {}", header); } } - + if let Some(data) = data { builder = builder.body(reqwest::Body::from(data)); } - + let request = builder.build().map_err(|err| { debug!("failed to convert request (url={}) - {}", url.as_str(), err); __WASI_EIO as u32 })?; - - let response = client.execute(request) - .await - .map_err(|err| - { + + let response = client.execute(request).await.map_err(|err| { debug!("failed to execute reqest - {}", err); __WASI_EIO as u32 })?; - + let status = response.status().as_u16(); let status_text = response.status().as_str().to_string(); let data = response.bytes().await.map_err(|err| { @@ -391,7 +382,7 @@ where Self: fmt::Debug + Sync, __WASI_EIO as u32 })?; let data = data.to_vec(); - + Ok(ReqwestResponse { pos: 0usize, ok: true, @@ -405,11 +396,10 @@ where Self: fmt::Debug + Sync, }; let (tx, rx) = std::sync::mpsc::channel(); - tasks - .block_on(Box::pin(async move { - let ret = work.await; - let _ = tx.send(ret); - })); + tasks.block_on(Box::pin(async move { + let ret = work.await; + let _ = tx.send(ret); + })); rx.try_recv().map_err(|_| __WASI_EIO)? } @@ -426,17 +416,17 @@ where Self: fmt::Debug + Sync, fn web_socket(&self, url: &str) -> Result, String> { let url = url.to_string(); let (tx_done, rx_done) = mpsc::unbounded_channel(); - self.task_shared(Box::new(move || + self.task_shared(Box::new(move || { Box::pin(async move { - let ret = move || async move { - Box::new(TerminalWebSocket::new(url.as_str())).await - }; + let ret = + move || async move { Box::new(TerminalWebSocket::new(url.as_str())).await }; let ret = ret().await; let _ = tx_done.send(ret); }) - )); + })); tokio::task::block_in_place(move || { - rx_done.blocking_recv() + rx_done + .blocking_recv() .ok_or("failed to create web socket".to_string()) }) } @@ -482,14 +472,12 @@ where Self: fmt::Debug + Sync, #[derive(Derivative)] #[derivative(Debug)] -pub struct PluggableRuntimeImplementation -{ +pub struct PluggableRuntimeImplementation { pub bus: Arc + Send + Sync + 'static>, pub networking: Arc, } -impl PluggableRuntimeImplementation -{ +impl PluggableRuntimeImplementation { pub fn set_bus_implementation(&mut self, bus: I) where I: VirtualBus + Sync, @@ -505,9 +493,7 @@ impl PluggableRuntimeImplementation } } -impl Default -for PluggableRuntimeImplementation -{ +impl Default for PluggableRuntimeImplementation { fn default() -> Self { Self { #[cfg(not(feature = "host-vnet"))] @@ -526,42 +512,38 @@ pub struct DefaultTaskManager { runtime: std::sync::Arc, /// List of periodic wakers to wake (this is used by IO subsystems) /// that do not support async operations - periodic_wakers: Arc, tokio::sync::broadcast::Sender<()>)>> + periodic_wakers: Arc, tokio::sync::broadcast::Sender<()>)>>, } -impl Default -for DefaultTaskManager { +impl Default for DefaultTaskManager { fn default() -> Self { - let runtime: std::sync::Arc - = std::sync::Arc::new(Builder::new_current_thread() - .enable_all() - .build() - .unwrap() - ); + let runtime: std::sync::Arc = + std::sync::Arc::new(Builder::new_current_thread().enable_all().build().unwrap()); let (tx, _) = tokio::sync::broadcast::channel(100); Self { runtime, - periodic_wakers: Arc::new(Mutex::new((Vec::new(), tx))) + periodic_wakers: Arc::new(Mutex::new((Vec::new(), tx))), } } } #[allow(unused_variables)] #[cfg(not(feature = "sys-thread"))] -impl VirtualTaskManager -for DefaultTaskManager -{ +impl VirtualTaskManager for DefaultTaskManager { /// Invokes whenever a WASM thread goes idle. In some runtimes (like singlethreaded /// execution environments) they will need to do asynchronous work whenever the main /// thread goes idle and this is the place to hook for that. - fn sleep_now(&self, id: WasiCallingId, ms: u128) -> Pin + Send + Sync + 'static>> { + fn sleep_now( + &self, + id: WasiCallingId, + ms: u128, + ) -> Pin + Send + Sync + 'static>> { if ms == 0 { std::thread::yield_now(); } else { std::thread::sleep(std::time::Duration::from_millis(ms as u64)); } - Box::pin(async move { - }) + Box::pin(async move {}) } /// Starts an asynchronous task that will run on a shared worker pool @@ -576,11 +558,7 @@ for DefaultTaskManager } /// Starts an asynchronous task on the local thread (by running it in a runtime) - fn block_on( - &self, - task: Pin>>, - ) - { + fn block_on(&self, task: Pin>>) { let _guard = self.runtime.enter(); self.runtime.block_on(async move { task.await; @@ -632,13 +610,15 @@ for DefaultTaskManager } #[cfg(feature = "sys-thread")] -impl VirtualTaskManager -for DefaultTaskManager -{ +impl VirtualTaskManager for DefaultTaskManager { /// Invokes whenever a WASM thread goes idle. In some runtimes (like singlethreaded /// execution environments) they will need to do asynchronous work whenever the main /// thread goes idle and this is the place to hook for that. - fn sleep_now(&self, _id: WasiCallingId, ms: u128) -> Pin + Send + Sync + 'static>> { + fn sleep_now( + &self, + _id: WasiCallingId, + ms: u128, + ) -> Pin + Send + Sync + 'static>> { Box::pin(async move { if ms == 0 { tokio::task::yield_now().await; @@ -665,11 +645,7 @@ for DefaultTaskManager } /// Starts an asynchronous task on the local thread (by running it in a runtime) - fn block_on( - &self, - task: Pin>>, - ) - { + fn block_on(&self, task: Pin>>) { let _guard = self.runtime.enter(); self.runtime.block_on(async move { task.await; @@ -689,20 +665,18 @@ for DefaultTaskManager use wasmer::vm::VMSharedMemory; let memory: Option = match spawn_type { - SpawnType::CreateWithType(mem) => { - Some( - VMSharedMemory::new(&mem.ty, &mem.style) - .map_err(|err| { - error!("failed to create memory - {}", err); - }) - .unwrap() - .into() - ) - }, + SpawnType::CreateWithType(mem) => Some( + VMSharedMemory::new(&mem.ty, &mem.style) + .map_err(|err| { + error!("failed to create memory - {}", err); + }) + .unwrap() + .into(), + ), SpawnType::NewThread(mem) => Some(mem), SpawnType::Create => None, }; - + std::thread::spawn(move || { // Invoke the callback task(store, module, memory); @@ -742,11 +716,9 @@ for DefaultTaskManager /// in a stable way (ideally we should aim for this number /// of background threads) fn thread_parallelism(&self) -> Result { - Ok( - std::thread::available_parallelism() - .map(|a| usize::from(a)) - .unwrap_or(8) - ) + Ok(std::thread::available_parallelism() + .map(|a| usize::from(a)) + .unwrap_or(8)) } /// Returns a reference to the periodic wakers used by this task manager @@ -755,9 +727,7 @@ for DefaultTaskManager } } -impl WasiRuntimeImplementation -for PluggableRuntimeImplementation -{ +impl WasiRuntimeImplementation for PluggableRuntimeImplementation { fn bus<'a>(&'a self) -> Arc + Send + Sync + 'static> { self.bus.clone() } diff --git a/lib/wasi/src/runtime/stdio.rs b/lib/wasi/src/runtime/stdio.rs index 7b478b41a..c8417e3bb 100644 --- a/lib/wasi/src/runtime/stdio.rs +++ b/lib/wasi/src/runtime/stdio.rs @@ -1,5 +1,5 @@ +use std::io::{self, Read, Seek, Write}; use std::sync::Arc; -use std::io::{self, Read, Write, Seek}; #[derive(Debug)] pub struct RuntimeStdout { @@ -8,9 +8,7 @@ pub struct RuntimeStdout { impl RuntimeStdout { pub fn new(runtime: Arc) -> Self { - Self { - runtime - } + Self { runtime } } } @@ -95,9 +93,7 @@ pub struct RuntimeStderr { impl RuntimeStderr { pub fn new(runtime: Arc) -> Self { - Self { - runtime - } + Self { runtime } } } diff --git a/lib/wasi/src/runtime/term.rs b/lib/wasi/src/runtime/term.rs index e1fb9b5ca..9ab951284 100644 --- a/lib/wasi/src/runtime/term.rs +++ b/lib/wasi/src/runtime/term.rs @@ -2,7 +2,8 @@ #[cfg(unix)] use { libc::{ - c_int, tcsetattr, termios, ECHO, ECHOE, ECHONL, ICANON, ICRNL, IEXTEN, ISIG, IXON, OPOST, TCSANOW, + c_int, tcsetattr, termios, ECHO, ECHOE, ECHONL, ICANON, ICRNL, IEXTEN, ISIG, IXON, OPOST, + TCSANOW, }, std::mem, std::os::unix::io::AsRawFd, @@ -68,7 +69,7 @@ pub fn set_mode_no_line_feeds() -> std::fs::File { let mut termios = unsafe { termios.assume_init() }; termios.c_lflag &= !ICANON; - + unsafe { tcsetattr(fd, TCSANOW, &termios) }; tty } @@ -83,7 +84,7 @@ pub fn set_mode_line_feeds() -> std::fs::File { let mut termios = unsafe { termios.assume_init() }; termios.c_lflag |= ICANON; - + unsafe { tcsetattr(fd, TCSANOW, &termios) }; tty } @@ -98,7 +99,7 @@ pub fn set_mode_no_line_feeds() -> std::fs::File { let mut termios = unsafe { termios.assume_init() }; termios.c_lflag &= !ONLCR; - + unsafe { tcsetattr(fd, TCSANOW, &termios) }; tty } @@ -113,7 +114,7 @@ pub fn set_mode_line_feeds() -> std::fs::File { let mut termios = unsafe { termios.assume_init() }; termios.c_lflag |= ONLCR; - + unsafe { tcsetattr(fd, TCSANOW, &termios) }; tty } diff --git a/lib/wasi/src/runtime/ws.rs b/lib/wasi/src/runtime/ws.rs index 86af35fc1..85a52c3f4 100644 --- a/lib/wasi/src/runtime/ws.rs +++ b/lib/wasi/src/runtime/ws.rs @@ -10,7 +10,11 @@ pub trait WebSocketAbi { fn set_onclose(&mut self, callback: Box); - fn set_onmessage(&mut self, callback: Box) + Send + 'static>, runtime: &dyn WasiRuntimeImplementation); + fn set_onmessage( + &mut self, + callback: Box) + Send + 'static>, + runtime: &dyn WasiRuntimeImplementation, + ); #[cfg(feature = "async_ws")] async fn send(&mut self, data: Vec) -> Result<(), String>; diff --git a/lib/wasi/src/state/builder.rs b/lib/wasi/src/state/builder.rs index b71418e7d..4c85cb814 100644 --- a/lib/wasi/src/state/builder.rs +++ b/lib/wasi/src/state/builder.rs @@ -3,9 +3,11 @@ #[cfg(feature = "os")] use crate::bin_factory::CachedCompiledModules; use crate::fs::{ArcFile, TmpFileSystem}; -use crate::state::{WasiFs, WasiState, WasiFsRoot}; +use crate::state::{WasiFs, WasiFsRoot, WasiState}; use crate::syscalls::types::{__WASI_STDERR_FILENO, __WASI_STDIN_FILENO, __WASI_STDOUT_FILENO}; -use crate::{WasiEnv, WasiFunctionEnv, WasiInodes, WasiControlPlane, PluggableRuntimeImplementation}; +use crate::{ + PluggableRuntimeImplementation, WasiControlPlane, WasiEnv, WasiFunctionEnv, WasiInodes, +}; use generational_arena::Arena; use rand::Rng; use std::collections::HashMap; @@ -128,8 +130,10 @@ impl WasiStateBuilder { Key: AsRef<[u8]>, Value: AsRef<[u8]>, { - self.envs - .push((String::from_utf8_lossy(key.as_ref()).to_string(), value.as_ref().to_vec())); + self.envs.push(( + String::from_utf8_lossy(key.as_ref()).to_string(), + value.as_ref().to_vec(), + )); self } @@ -141,7 +145,8 @@ impl WasiStateBuilder { where Arg: AsRef<[u8]>, { - self.args.push(String::from_utf8_lossy(arg.as_ref()).to_string()); + self.args + .push(String::from_utf8_lossy(arg.as_ref()).to_string()); self } @@ -192,7 +197,8 @@ impl WasiStateBuilder { Target: AsRef, { let path_buf = PathBuf::from(target.as_ref().to_string()); - self.map_commands.insert(name.as_ref().to_string(), path_buf); + self.map_commands + .insert(name.as_ref().to_string(), path_buf); self } @@ -206,7 +212,8 @@ impl WasiStateBuilder { { map_commands.into_iter().for_each(|(name, target)| { let path_buf = PathBuf::from(target.as_ref().to_string()); - self.map_commands.insert(name.as_ref().to_string(), path_buf); + self.map_commands + .insert(name.as_ref().to_string(), path_buf); }); self } @@ -434,9 +441,7 @@ impl WasiStateBuilder { for arg in self.args.iter() { for b in arg.as_bytes().iter() { if *b == 0 { - return Err(WasiStateCreationError::ArgumentContainsNulByte( - arg.clone(), - )); + return Err(WasiStateCreationError::ArgumentContainsNulByte(arg.clone())); } } } @@ -458,10 +463,7 @@ impl WasiStateBuilder { }) { Some(InvalidCharacter::Nul) => { return Err(WasiStateCreationError::EnvironmentVariableFormatError( - format!( - "found nul byte in env var key \"{}\" (key=value)", - env_key - ), + format!("found nul byte in env var key \"{}\" (key=value)", env_key), )) } @@ -487,25 +489,26 @@ impl WasiStateBuilder { } } - // Get a reference to the runtime - let runtime = self.runtime_override.clone().unwrap_or_else( || { - Arc::new(PluggableRuntimeImplementation::default()) - }); + // Get a reference to the runtime + let runtime = self + .runtime_override + .clone() + .unwrap_or_else(|| Arc::new(PluggableRuntimeImplementation::default())); // Determine the STDIN - let stdin: Box = self.stdin_override + let stdin: Box = self + .stdin_override .take() .map(|a| Box::new(ArcFile::new(a))) - .unwrap_or_else(|| { - Box::new(ArcFile::new(Box::new(super::Stdin::default()))) - }); + .unwrap_or_else(|| Box::new(ArcFile::new(Box::new(super::Stdin::default())))); // If we are running WASIX then we start a full sandbox FS // otherwise we drop through to a default file system - let fs_backing = self.fs_override + let fs_backing = self + .fs_override .take() .unwrap_or_else(|| WasiFsRoot::Sandbox(Arc::new(TmpFileSystem::new()))); - + // self.preopens are checked in [`PreopenDirBuilder::build`] let inodes = RwLock::new(crate::state::WasiInodes { arena: Arena::new(), @@ -519,10 +522,10 @@ impl WasiStateBuilder { inodes.deref_mut(), &self.preopens, &self.vfs_preopens, - fs_backing + fs_backing, ) .map_err(WasiStateCreationError::WasiFsCreationError)?; - + // set up the file system, overriding base files and calling the setup function wasi_fs .swap_file(inodes.deref(), __WASI_STDIN_FILENO, stdin) @@ -620,7 +623,7 @@ impl WasiStateBuilder { self.compiled_modules.clone(), process, thread, - runtime + runtime, ); #[cfg(feature = "os")] diff --git a/lib/wasi/src/state/guard.rs b/lib/wasi/src/state/guard.rs index 32fd81332..722fcd226 100644 --- a/lib/wasi/src/state/guard.rs +++ b/lib/wasi/src/state/guard.rs @@ -5,8 +5,11 @@ use crate::VirtualTaskManager; use super::*; use std::{ + future::Future, io::{Read, Seek}, - sync::RwLockReadGuard, future::Future, pin::Pin, task::Poll, + pin::Pin, + sync::RwLockReadGuard, + task::Poll, }; pub(crate) enum InodeValFilePollGuardMode { @@ -15,9 +18,9 @@ pub(crate) enum InodeValFilePollGuardMode { immediate: bool, waker: Mutex>, counter: Arc, - wakers: Arc>>> + wakers: Arc>>>, }, - Socket(InodeSocket) + Socket(InodeSocket), } pub(crate) struct InodeValFilePollGuard { @@ -27,14 +30,26 @@ pub(crate) struct InodeValFilePollGuard { pub(crate) tasks: Arc, } impl<'a> InodeValFilePollGuard { - pub(crate) fn new(fd: u32, guard: &Kind, subscriptions: HashMap, tasks: Arc) -> Option { + pub(crate) fn new( + fd: u32, + guard: &Kind, + subscriptions: HashMap, + tasks: Arc, + ) -> Option { let mode = match guard.deref() { - Kind::EventNotifications { counter, wakers, immediate, .. } => { + Kind::EventNotifications { + counter, + wakers, + immediate, + .. + } => { let (tx, rx) = tokio::sync::mpsc::unbounded_channel(); let immediate = { let mut wakers = wakers.lock().unwrap(); wakers.push_back(tx); - immediate.compare_exchange(true, false, Ordering::AcqRel, Ordering::Relaxed).is_ok() + immediate + .compare_exchange(true, false, Ordering::AcqRel, Ordering::Relaxed) + .is_ok() }; InodeValFilePollGuardMode::EventNotifications { immediate, @@ -42,7 +57,7 @@ impl<'a> InodeValFilePollGuard { counter: counter.clone(), wakers: wakers.clone(), } - }, + } Kind::Socket { socket } => InodeValFilePollGuardMode::Socket(socket.clone()), Kind::File { handle, .. } => { if let Some(handle) = handle { @@ -50,29 +65,27 @@ impl<'a> InodeValFilePollGuard { } else { return None; } - }, + } _ => { return None; } }; - Some( - Self { - fd, - mode, - subscriptions, - tasks - } - ) + Some(Self { + fd, + mode, + subscriptions, + tasks, + }) } } -impl std::fmt::Debug -for InodeValFilePollGuard -{ +impl std::fmt::Debug for InodeValFilePollGuard { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { match &self.mode { InodeValFilePollGuardMode::File(..) => write!(f, "guard-file"), - InodeValFilePollGuardMode::EventNotifications { .. } => write!(f, "guard-notifications"), + InodeValFilePollGuardMode::EventNotifications { .. } => { + write!(f, "guard-notifications") + } InodeValFilePollGuardMode::Socket(socket) => { let socket = socket.inner.read().unwrap(); match socket.kind { @@ -82,7 +95,7 @@ for InodeValFilePollGuard InodeSocketKind::Raw(..) => write!(f, "guard-raw-socket"), InodeSocketKind::HttpRequest(..) => write!(f, "guard-http-request"), InodeSocketKind::WebSocket(..) => write!(f, "guard-web-socket"), - _ => write!(f, "guard-socket") + _ => write!(f, "guard-socket"), } } } @@ -95,17 +108,14 @@ impl InodeValFilePollGuard { InodeValFilePollGuardMode::File(file) => { let guard = file.read().unwrap(); guard.bytes_available_read() - }, - InodeValFilePollGuardMode::EventNotifications { counter, .. } => { - Ok( - Some(counter.load(std::sync::atomic::Ordering::Acquire) as usize) - ) - }, - InodeValFilePollGuardMode::Socket(socket) => { - socket.peek() - .map(|a| Some(a)) - .map_err(fs_error_from_wasi_err) } + InodeValFilePollGuardMode::EventNotifications { counter, .. } => Ok(Some( + counter.load(std::sync::atomic::Ordering::Acquire) as usize, + )), + InodeValFilePollGuardMode::Socket(socket) => socket + .peek() + .map(|a| Some(a)) + .map_err(fs_error_from_wasi_err), } } @@ -114,13 +124,11 @@ impl InodeValFilePollGuard { InodeValFilePollGuardMode::File(file) => { let guard = file.read().unwrap(); guard.bytes_available_write() - }, + } InodeValFilePollGuardMode::EventNotifications { wakers, .. } => { let wakers = wakers.lock().unwrap(); - Ok( - Some(wakers.len()) - ) - }, + Ok(Some(wakers.len())) + } InodeValFilePollGuardMode::Socket(socket) => { if socket.can_write() { Ok(Some(4096)) @@ -131,16 +139,14 @@ impl InodeValFilePollGuard { } } - pub fn is_open(&self) -> bool{ + pub fn is_open(&self) -> bool { match &self.mode { InodeValFilePollGuardMode::File(file) => { let guard = file.read().unwrap(); guard.is_open() - }, - InodeValFilePollGuardMode::EventNotifications { .. } | - InodeValFilePollGuardMode::Socket(..) => { - true } + InodeValFilePollGuardMode::EventNotifications { .. } + | InodeValFilePollGuardMode::Socket(..) => true, } } @@ -163,9 +169,7 @@ impl<'a> InodeValFilePollGuardJoin<'a> { } } } -impl<'a> Future -for InodeValFilePollGuardJoin<'a> -{ +impl<'a> Future for InodeValFilePollGuardJoin<'a> { type Output = Vec<__wasi_event_t>; fn poll(self: Pin<&mut Self>, cx: &mut std::task::Context<'_>) -> Poll { @@ -174,21 +178,23 @@ for InodeValFilePollGuardJoin<'a> let mut has_close = None; let mut has_hangup = false; - let register_root_waker = self.tasks - .register_root_waker(); + let register_root_waker = self.tasks.register_root_waker(); let mut ret = Vec::new(); for (set, s) in self.subscriptions.iter() { for in_event in iterate_poll_events(*set) { match in_event { - PollEvent::PollIn => { has_read = Some(s.clone()); }, - PollEvent::PollOut => { has_write = Some(s.clone()); }, + PollEvent::PollIn => { + has_read = Some(s.clone()); + } + PollEvent::PollOut => { + has_write = Some(s.clone()); + } PollEvent::PollHangUp => { has_hangup = true; has_close = Some(s.clone()); } - PollEvent::PollError | - PollEvent::PollInvalid => { + PollEvent::PollError | PollEvent::PollInvalid => { if has_hangup == false { has_close = Some(s.clone()); } @@ -201,35 +207,28 @@ for InodeValFilePollGuardJoin<'a> InodeValFilePollGuardMode::File(file) => { let guard = file.read().unwrap(); guard.poll_close_ready(cx, ®ister_root_waker).is_ready() - }, - InodeValFilePollGuardMode::EventNotifications { .. } => { - false - }, + } + InodeValFilePollGuardMode::EventNotifications { .. } => false, InodeValFilePollGuardMode::Socket(socket) => { let inner = socket.inner.read().unwrap(); if let InodeSocketKind::Closed = inner.kind { true } else { - if has_read.is_some() || has_write.is_some() - { + if has_read.is_some() || has_write.is_some() { // this will be handled in the read/write poll instead false } else { // we do a read poll which will error out if its closed match socket.poll_read_ready(cx) { - Poll::Ready(Err(NetworkError::ConnectionAborted)) | - Poll::Ready(Err(NetworkError::ConnectionRefused)) | - Poll::Ready(Err(NetworkError::ConnectionReset)) | - Poll::Ready(Err(NetworkError::BrokenPipe)) | - Poll::Ready(Err(NetworkError::NotConnected)) | - Poll::Ready(Err(NetworkError::UnexpectedEof)) => { - true - }, - _ => { - false - } + Poll::Ready(Err(NetworkError::ConnectionAborted)) + | Poll::Ready(Err(NetworkError::ConnectionRefused)) + | Poll::Ready(Err(NetworkError::ConnectionReset)) + | Poll::Ready(Err(NetworkError::BrokenPipe)) + | Poll::Ready(Err(NetworkError::NotConnected)) + | Poll::Ready(Err(NetworkError::UnexpectedEof)) => true, + _ => false, } - } + } } } }; @@ -244,7 +243,9 @@ for InodeValFilePollGuardJoin<'a> nbytes: 0, flags: if has_hangup { __WASI_EVENT_FD_READWRITE_HANGUP - } else { 0 }, + } else { + 0 + }, }, } }, @@ -256,8 +257,13 @@ for InodeValFilePollGuardJoin<'a> InodeValFilePollGuardMode::File(file) => { let guard = file.read().unwrap(); guard.poll_read_ready(cx, ®ister_root_waker) - }, - InodeValFilePollGuardMode::EventNotifications { waker, counter, immediate, .. } => { + } + InodeValFilePollGuardMode::EventNotifications { + waker, + counter, + immediate, + .. + } => { if *immediate { let cnt = counter.load(Ordering::Acquire); Poll::Ready(Ok(cnt as usize)) @@ -270,21 +276,20 @@ for InodeValFilePollGuardJoin<'a> Ok(cnt as usize) }) } - }, - InodeValFilePollGuardMode::Socket(socket) => { - socket.poll_read_ready(cx) - .map_err(net_error_into_io_err) - .map_err(Into::::into) } + InodeValFilePollGuardMode::Socket(socket) => socket + .poll_read_ready(cx) + .map_err(net_error_into_io_err) + .map_err(Into::::into), }; if let Some(s) = has_close.as_ref() { poll_result = match poll_result { - Poll::Ready(Err(FsError::ConnectionAborted)) | - Poll::Ready(Err(FsError::ConnectionRefused)) | - Poll::Ready(Err(FsError::ConnectionReset)) | - Poll::Ready(Err(FsError::BrokenPipe)) | - Poll::Ready(Err(FsError::NotConnected)) | - Poll::Ready(Err(FsError::UnexpectedEof)) => { + Poll::Ready(Err(FsError::ConnectionAborted)) + | Poll::Ready(Err(FsError::ConnectionRefused)) + | Poll::Ready(Err(FsError::ConnectionReset)) + | Poll::Ready(Err(FsError::BrokenPipe)) + | Poll::Ready(Err(FsError::NotConnected)) + | Poll::Ready(Err(FsError::UnexpectedEof)) => { ret.push(__wasi_event_t { userdata: s.user_data, error: __WASI_ESUCCESS, @@ -295,20 +300,25 @@ for InodeValFilePollGuardJoin<'a> nbytes: 0, flags: if has_hangup { __WASI_EVENT_FD_READWRITE_HANGUP - } else { 0 }, + } else { + 0 + }, }, } }, }); Poll::Pending } - a => a + a => a, }; } if let Poll::Ready(bytes_available) = poll_result { ret.push(__wasi_event_t { userdata: s.user_data, - error: bytes_available.clone().map(|_| __WASI_ESUCCESS).unwrap_or_else(fs_error_into_wasi_err), + error: bytes_available + .clone() + .map(|_| __WASI_ESUCCESS) + .unwrap_or_else(fs_error_into_wasi_err), type_: s.event_type.raw_tag(), u: { __wasi_event_u { @@ -326,8 +336,13 @@ for InodeValFilePollGuardJoin<'a> InodeValFilePollGuardMode::File(file) => { let guard = file.read().unwrap(); guard.poll_write_ready(cx, ®ister_root_waker) - }, - InodeValFilePollGuardMode::EventNotifications { waker, counter, immediate, .. } => { + } + InodeValFilePollGuardMode::EventNotifications { + waker, + counter, + immediate, + .. + } => { if *immediate { let cnt = counter.load(Ordering::Acquire); Poll::Ready(Ok(cnt as usize)) @@ -340,21 +355,20 @@ for InodeValFilePollGuardJoin<'a> Ok(cnt as usize) }) } - }, - InodeValFilePollGuardMode::Socket(socket) => { - socket.poll_write_ready(cx) - .map_err(net_error_into_io_err) - .map_err(Into::::into) } + InodeValFilePollGuardMode::Socket(socket) => socket + .poll_write_ready(cx) + .map_err(net_error_into_io_err) + .map_err(Into::::into), }; if let Some(s) = has_close.as_ref() { poll_result = match poll_result { - Poll::Ready(Err(FsError::ConnectionAborted)) | - Poll::Ready(Err(FsError::ConnectionRefused)) | - Poll::Ready(Err(FsError::ConnectionReset)) | - Poll::Ready(Err(FsError::BrokenPipe)) | - Poll::Ready(Err(FsError::NotConnected)) | - Poll::Ready(Err(FsError::UnexpectedEof)) => { + Poll::Ready(Err(FsError::ConnectionAborted)) + | Poll::Ready(Err(FsError::ConnectionRefused)) + | Poll::Ready(Err(FsError::ConnectionReset)) + | Poll::Ready(Err(FsError::BrokenPipe)) + | Poll::Ready(Err(FsError::NotConnected)) + | Poll::Ready(Err(FsError::UnexpectedEof)) => { ret.push(__wasi_event_t { userdata: s.user_data, error: __WASI_ESUCCESS, @@ -365,20 +379,25 @@ for InodeValFilePollGuardJoin<'a> nbytes: 0, flags: if has_hangup { __WASI_EVENT_FD_READWRITE_HANGUP - } else { 0 }, + } else { + 0 + }, }, } }, }); Poll::Pending } - a => a + a => a, }; } if let Poll::Ready(bytes_available) = poll_result { ret.push(__wasi_event_t { userdata: s.user_data, - error: bytes_available.clone().map(|_| __WASI_ESUCCESS).unwrap_or_else(fs_error_into_wasi_err), + error: bytes_available + .clone() + .map(|_| __WASI_ESUCCESS) + .unwrap_or_else(fs_error_into_wasi_err), type_: s.event_type.raw_tag(), u: { __wasi_event_u { @@ -411,13 +430,18 @@ impl InodeValFileReadGuard { let guard = file.read().unwrap(); Self { file: file.clone(), - guard: unsafe { std::mem::transmute(guard) } + guard: unsafe { std::mem::transmute(guard) }, } } } impl InodeValFileReadGuard { - pub fn into_poll_guard(self, fd: u32, subscriptions: HashMap, tasks: Arc) -> InodeValFilePollGuard { + pub fn into_poll_guard( + self, + fd: u32, + subscriptions: HashMap, + tasks: Arc, + ) -> InodeValFilePollGuard { InodeValFilePollGuard { fd, subscriptions, @@ -446,10 +470,13 @@ impl InodeValFileWriteGuard { let guard = file.write().unwrap(); Self { file: file.clone(), - guard: unsafe { std::mem::transmute(guard) } + guard: unsafe { std::mem::transmute(guard) }, } } - pub(crate) fn swap(&mut self, mut file: Box) -> Box { + pub(crate) fn swap( + &mut self, + mut file: Box, + ) -> Box { std::mem::swap(self.guard.deref_mut(), &mut file); file } @@ -494,10 +521,7 @@ impl WasiStateFileGuard { } } - pub fn lock_read( - &self, - inodes: &RwLockReadGuard, - ) -> Option { + pub fn lock_read(&self, inodes: &RwLockReadGuard) -> Option { let guard = inodes.arena[self.inode].read(); if let Kind::File { handle, .. } = guard.deref() { if let Some(handle) = handle.as_ref() { @@ -655,7 +679,7 @@ impl Write for WasiStateFileGuard { fn write(&mut self, buf: &[u8]) -> std::io::Result { let inodes = self.inodes.read().unwrap(); let mut guard = self.lock_write(&inodes); - if let Some(file) = guard.as_mut () { + if let Some(file) = guard.as_mut() { file.write(buf) } else { Err(std::io::ErrorKind::Unsupported.into()) diff --git a/lib/wasi/src/state/mod.rs b/lib/wasi/src/state/mod.rs index b6a74384e..dc06e12da 100644 --- a/lib/wasi/src/state/mod.rs +++ b/lib/wasi/src/state/mod.rs @@ -17,27 +17,27 @@ mod builder; mod guard; +mod parking; mod pipe; mod socket; -mod types; mod thread; -mod parking; +mod types; pub use self::builder::*; pub use self::guard::*; +pub use self::guard::*; +pub use self::parking::*; pub use self::pipe::*; pub use self::socket::*; -pub use self::types::*; -pub use self::guard::*; pub use self::thread::*; -pub use self::parking::*; -use crate::WasiCallingId; -use crate::WasiFunctionEnv; -use crate::WasiRuntimeImplementation; +pub use self::types::*; #[cfg(feature = "os")] use crate::bin_factory::BinaryPackage; use crate::syscalls::types::*; use crate::utils::map_io_err; +use crate::WasiCallingId; +use crate::WasiFunctionEnv; +use crate::WasiRuntimeImplementation; use cooked_waker::ViaRawPointer; use cooked_waker::Wake; use cooked_waker::WakeRef; @@ -46,18 +46,14 @@ use generational_arena::Arena; pub use generational_arena::Index as Inode; #[cfg(feature = "enable-serde")] use serde::{Deserialize, Serialize}; -use wasmer::Store; -use wasmer_vbus::VirtualBusCalled; -use wasmer_vbus::VirtualBusInvocation; -use wasmer_vfs::FileOpener; use std::borrow::Cow; use std::cell::RefCell; use std::collections::HashMap; use std::collections::HashSet; use std::collections::VecDeque; +use std::sync::Arc; use std::sync::Condvar; use std::sync::MutexGuard; -use std::sync::Arc; use std::task::Waker; use std::time::Duration; use std::{ @@ -71,6 +67,10 @@ use std::{ }, }; use tracing::{debug, trace}; +use wasmer::Store; +use wasmer_vbus::VirtualBusCalled; +use wasmer_vbus::VirtualBusInvocation; +use wasmer_vfs::FileOpener; use wasmer_vfs::{FileSystem, FsError, OpenOptions, VirtualFile}; @@ -327,7 +327,7 @@ impl WasiInodes { if let Some(handle) = handle { Ok(InodeValFileReadGuard::new(handle)) } else { - Err(FsError::NotAFile) + Err(FsError::NotAFile) } } else { // Our public API should ensure that this is not possible @@ -351,7 +351,7 @@ impl WasiInodes { if let Some(handle) = handle { Ok(InodeValFileWriteGuard::new(handle)) } else { - Err(FsError::NotAFile) + Err(FsError::NotAFile) } } else { // Our public API should ensure that this is not possible @@ -367,58 +367,56 @@ impl WasiInodes { #[derive(Debug, Clone)] pub enum WasiFsRoot { Sandbox(Arc), - Backing(Arc>) + Backing(Arc>), } -impl FileSystem -for WasiFsRoot -{ +impl FileSystem for WasiFsRoot { fn read_dir(&self, path: &Path) -> wasmer_vfs::Result { match self { WasiFsRoot::Sandbox(fs) => fs.read_dir(path), - WasiFsRoot::Backing(fs) => fs.read_dir(path) + WasiFsRoot::Backing(fs) => fs.read_dir(path), } } fn create_dir(&self, path: &Path) -> wasmer_vfs::Result<()> { match self { WasiFsRoot::Sandbox(fs) => fs.create_dir(path), - WasiFsRoot::Backing(fs) => fs.create_dir(path) + WasiFsRoot::Backing(fs) => fs.create_dir(path), } } fn remove_dir(&self, path: &Path) -> wasmer_vfs::Result<()> { match self { WasiFsRoot::Sandbox(fs) => fs.remove_dir(path), - WasiFsRoot::Backing(fs) => fs.remove_dir(path) + WasiFsRoot::Backing(fs) => fs.remove_dir(path), } } fn rename(&self, from: &Path, to: &Path) -> wasmer_vfs::Result<()> { match self { WasiFsRoot::Sandbox(fs) => fs.rename(from, to), - WasiFsRoot::Backing(fs) => fs.rename(from, to) + WasiFsRoot::Backing(fs) => fs.rename(from, to), } } fn metadata(&self, path: &Path) -> wasmer_vfs::Result { match self { WasiFsRoot::Sandbox(fs) => fs.metadata(path), - WasiFsRoot::Backing(fs) => fs.metadata(path) + WasiFsRoot::Backing(fs) => fs.metadata(path), } } fn symlink_metadata(&self, path: &Path) -> wasmer_vfs::Result { match self { WasiFsRoot::Sandbox(fs) => fs.symlink_metadata(path), - WasiFsRoot::Backing(fs) => fs.symlink_metadata(path) + WasiFsRoot::Backing(fs) => fs.symlink_metadata(path), } } fn remove_file(&self, path: &Path) -> wasmer_vfs::Result<()> { match self { WasiFsRoot::Sandbox(fs) => fs.remove_file(path), - WasiFsRoot::Backing(fs) => fs.remove_file(path) + WasiFsRoot::Backing(fs) => fs.remove_file(path), } } fn new_open_options(&self) -> OpenOptions { match self { WasiFsRoot::Sandbox(fs) => fs.new_open_options(), - WasiFsRoot::Backing(fs) => fs.new_open_options() + WasiFsRoot::Backing(fs) => fs.new_open_options(), } } } @@ -441,11 +439,9 @@ pub struct WasiFs { pub has_unioned: Arc>>, } -impl WasiFs -{ +impl WasiFs { /// Forking the WasiState is used when either fork or vfork is called - pub fn fork(&self) -> Self - { + pub fn fork(&self) -> Self { let fd_map = self.fd_map.read().unwrap().clone(); for fd in fd_map.values() { fd.ref_cnt.fetch_add(1, Ordering::Relaxed); @@ -459,16 +455,14 @@ impl WasiFs current_dir: Mutex::new(self.current_dir.lock().unwrap().clone()), is_wasix: AtomicBool::new(self.is_wasix.load(Ordering::Acquire)), root_fs: self.root_fs.clone(), - has_unioned: Arc::new(Mutex::new(HashSet::new())) + has_unioned: Arc::new(Mutex::new(HashSet::new())), } } /// Closes all the file handles pub fn close_all(&self, inodes: &WasiInodes) { let mut guard = self.fd_map.write().unwrap(); - let fds = { - guard.iter().map(|a| *a.0).collect::>() - }; + let fds = { guard.iter().map(|a| *a.0).collect::>() }; for fd in fds { _ = self.close_fd_ext(inodes, &mut guard, fd); @@ -493,7 +487,7 @@ impl WasiFs if let Some(fs) = binary.webc_fs.clone() { sandbox_fs.union(&fs); - } + } } true } @@ -554,12 +548,9 @@ impl WasiFs { inodes: &mut WasiInodes, preopens: &[PreopenedDir], vfs_preopens: &[String], - fs_backing: WasiFsRoot + fs_backing: WasiFsRoot, ) -> Result { - let (wasi_fs, root_inode) = Self::new_init( - fs_backing, - inodes - )?; + let (wasi_fs, root_inode) = Self::new_init(fs_backing, inodes)?; for preopen_name in vfs_preopens { let kind = Kind::Dir { @@ -732,8 +723,7 @@ impl WasiFs { } /// Converts a relative path into an absolute path - pub(crate) fn relative_path_to_absolute(&self, mut path: String) -> String - { + pub(crate) fn relative_path_to_absolute(&self, mut path: String) -> String { if path.starts_with("./") { let current_dir = self.current_dir.lock().unwrap(); path = format!("{}{}", current_dir.as_str(), &path[1..]); @@ -744,10 +734,7 @@ impl WasiFs { /// Private helper function to init the filesystem, called in `new` and /// `new_with_preopen` - fn new_init( - fs_backing: WasiFsRoot, - inodes: &mut WasiInodes, - ) -> Result<(Self, Inode), String> { + fn new_init(fs_backing: WasiFsRoot, inodes: &mut WasiInodes) -> Result<(Self, Inode), String> { debug!("Initializing WASI filesystem"); let wasi_fs = Self { @@ -759,7 +746,7 @@ impl WasiFs { current_dir: Mutex::new("/".to_string()), is_wasix: AtomicBool::new(false), root_fs: fs_backing, - has_unioned: Arc::new(Mutex::new(HashSet::new())) + has_unioned: Arc::new(Mutex::new(HashSet::new())), }; wasi_fs.create_stdin(inodes); wasi_fs.create_stdout(inodes); @@ -1128,7 +1115,8 @@ impl WasiFs { cd.push(component); cd }; - let metadata = self.root_fs + let metadata = self + .root_fs .symlink_metadata(&file) .ok() .ok_or(Errno::Noent)?; @@ -1593,7 +1581,7 @@ impl WasiFs { } => { let mut file = file.write().unwrap(); file.flush().map_err(|_| __WASI_EIO)? - }, + } // TODO: verify this behavior Kind::Dir { .. } => return Err(Errno::Isdir), Kind::Symlink { .. } => unimplemented!("WasiFs::flush Kind::Symlink"), @@ -1654,7 +1642,7 @@ impl WasiFs { rights_inheriting: Rights, flags: Fdflags, open_flags: u16, - inode: Inode + inode: Inode, ) -> Result<__wasi_fd_t, __wasi_errno_t> { let idx = self.next_fd.fetch_add(1, Ordering::AcqRel); self.create_fd_ext(rights, rights_inheriting, flags, open_flags, inode, idx)?; @@ -1668,7 +1656,7 @@ impl WasiFs { flags: __wasi_fdflags_t, open_flags: u16, inode: Inode, - idx: __wasi_fd_t + idx: __wasi_fd_t, ) -> Result<(), __wasi_errno_t> { self.fd_map.write().unwrap().insert( idx, @@ -1819,14 +1807,16 @@ impl WasiFs { st_mtim: wf.last_modified(), st_ctim: wf.created_time(), - ..Filestat::default() - }) + ..__wasi_filestat_t::default() + }); } - None => self.root_fs + None => self + .root_fs .metadata(path) .map_err(fs_error_into_wasi_err)?, }, - Kind::Dir { path, .. } => self.root_fs + Kind::Dir { path, .. } => self + .root_fs .metadata(path) .map_err(fs_error_into_wasi_err)?, Kind::Symlink { @@ -1885,9 +1875,7 @@ impl WasiFs { fd_map: &mut RwLockWriteGuard>, fd: __wasi_fd_t, ) -> Result<(), __wasi_errno_t> { - - let pfd = fd_map.get(&fd) - .ok_or(__WASI_EBADF)?; + let pfd = fd_map.get(&fd).ok_or(__WASI_EBADF)?; if pfd.ref_cnt.fetch_sub(1, Ordering::AcqRel) > 1 { trace!("closing file descriptor({}) - ref-cnt", fd); fd_map.remove(&fd); @@ -1970,19 +1958,22 @@ impl WasiState { &self, path: P, ) -> Result { - self.fs.root_fs + self.fs + .root_fs .read_dir(path.as_ref()) .map_err(fs_error_into_wasi_err) } pub(crate) fn fs_create_dir>(&self, path: P) -> Result<(), __wasi_errno_t> { - self.fs.root_fs + self.fs + .root_fs .create_dir(path.as_ref()) .map_err(fs_error_into_wasi_err) } pub(crate) fn fs_remove_dir>(&self, path: P) -> Result<(), __wasi_errno_t> { - self.fs.root_fs + self.fs + .root_fs .remove_dir(path.as_ref()) .map_err(fs_error_into_wasi_err) } @@ -1992,36 +1983,31 @@ impl WasiState { from: P, to: Q, ) -> Result<(), __wasi_errno_t> { - self.fs.root_fs + self.fs + .root_fs .rename(from.as_ref(), to.as_ref()) .map_err(fs_error_into_wasi_err) } pub(crate) fn fs_remove_file>(&self, path: P) -> Result<(), __wasi_errno_t> { - self.fs.root_fs + self.fs + .root_fs .remove_file(path.as_ref()) .map_err(fs_error_into_wasi_err) } pub(crate) fn fs_new_open_options(&self) -> OpenOptions { - OpenOptions::new( - Box::new( - WasiStateOpener { - root_fs: self.fs.root_fs.clone(), - } - ) - ) + OpenOptions::new(Box::new(WasiStateOpener { + root_fs: self.fs.root_fs.clone(), + })) } } -struct WasiStateOpener -{ - root_fs: WasiFsRoot +struct WasiStateOpener { + root_fs: WasiFsRoot, } -impl FileOpener -for WasiStateOpener -{ +impl FileOpener for WasiStateOpener { fn open( &mut self, path: &Path, @@ -2041,8 +2027,8 @@ pub(crate) struct WasiThreadContext { /// The code itself makes safe use of the struct so multiple threads don't access /// it (without this the JS code prevents the reference to the module from being stored /// which is needed for the multithreading mode) -unsafe impl Send for WasiThreadContext { } -unsafe impl Sync for WasiThreadContext { } +unsafe impl Send for WasiThreadContext {} +unsafe impl Sync for WasiThreadContext {} /// Structures used for the threading and sub-processes /// @@ -2066,18 +2052,16 @@ pub struct WasiFutex { } #[derive(Debug)] -pub struct WasiBusCall -{ +pub struct WasiBusCall { pub bid: WasiProcessId, pub invocation: Box, } /// Protected area of the BUS state #[derive(Debug, Default)] -pub struct WasiBusProtectedState -{ +pub struct WasiBusProtectedState { pub call_seed: u64, - pub called: HashMap>, + pub called: HashMap>, pub calls: HashMap, } @@ -2085,14 +2069,12 @@ pub struct WasiBusProtectedState /// this process. BUS calls are the equivalent of RPC's with support /// for all the major serializers #[derive(Debug, Default)] -pub struct WasiBusState -{ +pub struct WasiBusState { protected: Mutex, poll_waker: WasiParkingLot, } -impl WasiBusState -{ +impl WasiBusState { /// Gets a reference to the waker that can be used for /// asynchronous calls pub fn get_poll_waker(&self) -> Waker { @@ -2158,7 +2140,7 @@ pub struct WasiState { pub args: Vec, pub envs: Vec>, pub preopen: Vec, - pub(crate) runtime: Arc + pub(crate) runtime: Arc, } impl WasiState { @@ -2233,16 +2215,15 @@ impl WasiState { fd: WasiFd, ) -> Result>, FsError> { let ret = WasiStateFileGuard::new(self, fd)?.map(|a| { - let ret = Box::new(a); - let ret: Box = ret; - ret - }); + let ret = Box::new(a); + let ret: Box = ret; + ret + }); Ok(ret) } /// Forking the WasiState is used when either fork or vfork is called - pub fn fork(&self) -> Self - { + pub fn fork(&self) -> Self { WasiState { fs: self.fs.fork(), secret: self.secret.clone(), @@ -2276,13 +2257,11 @@ pub fn virtual_file_type_to_wasi_file_type(file_type: wasmer_vfs::FileType) -> F pub struct WasiDummyWaker; impl WakeRef for WasiDummyWaker { - fn wake_by_ref(&self) { - } + fn wake_by_ref(&self) {} } impl Wake for WasiDummyWaker { - fn wake(self) { - } + fn wake(self) {} } unsafe impl ViaRawPointer for WasiDummyWaker { diff --git a/lib/wasi/src/state/parking.rs b/lib/wasi/src/state/parking.rs index bb25f5d8f..aebf63566 100644 --- a/lib/wasi/src/state/parking.rs +++ b/lib/wasi/src/state/parking.rs @@ -1,51 +1,37 @@ use std::{ + sync::{Arc, Condvar, Mutex}, task::Waker, - sync::{ - Mutex, - Arc, - Condvar - }, - time::Duration + time::Duration, }; /// Represents a waker that can be used to put a thread to /// sleep while it waits for an event to occur #[derive(Debug)] -pub struct WasiParkingLot -{ +pub struct WasiParkingLot { waker: Waker, run: Arc<(Mutex, Condvar)>, } -impl Default -for WasiParkingLot -{ - fn default() -> Self - { - Self::new(true) +impl Default for WasiParkingLot { + fn default() -> Self { + Self::new(true) } } -impl WasiParkingLot -{ +impl WasiParkingLot { /// Creates a new parking lot with a specific value - pub fn new(initial_val: bool) -> Self - { + pub fn new(initial_val: bool) -> Self { let run = Arc::new((Mutex::new(initial_val), Condvar::default())); let waker = { let run = run.clone(); - waker_fn::waker_fn(move || - { + waker_fn::waker_fn(move || { let mut guard = run.0.lock().unwrap(); *guard = true; run.1.notify_one(); }) }; - Self { - waker, - run, - } + Self { waker, run } } /// Gets a reference to the waker that can be used for @@ -79,4 +65,4 @@ impl WasiParkingLot } } } -} \ No newline at end of file +} diff --git a/lib/wasi/src/state/pipe.rs b/lib/wasi/src/state/pipe.rs index 00844fb18..98590db73 100644 --- a/lib/wasi/src/state/pipe.rs +++ b/lib/wasi/src/state/pipe.rs @@ -1,17 +1,15 @@ use crate::syscalls::types::*; use crate::syscalls::{read_bytes, write_bytes}; use bytes::{Buf, Bytes}; -use wasmer_vfs::VirtualFile; use std::convert::TryInto; -use std::io::{Read, Write, Seek}; +use std::io::{Read, Seek, Write}; use std::ops::DerefMut; use std::sync::mpsc::{self, TryRecvError}; use std::sync::Mutex; use std::time::Duration; use wasmer::WasmSlice; use wasmer::{MemorySize, MemoryView}; -use wasmer_vfs::{FsError, VirtualFile}; -use wasmer_wasi_types::wasi::Errno; +use wasmer_vfs::VirtualFile; #[derive(Debug)] pub struct WasiPipe { @@ -306,7 +304,7 @@ impl WasiPipe { let mut read_buffer = self.read_buffer.lock().unwrap(); read_buffer.take(); } - } + } } impl Write for WasiPipe { @@ -375,9 +373,7 @@ impl Seek for WasiPipe { } } -impl VirtualFile -for WasiPipe -{ +impl VirtualFile for WasiPipe { /// the last time the file was accessed in nanoseconds as a UNIX timestamp fn last_accessed(&self) -> u64 { 0 diff --git a/lib/wasi/src/state/socket.rs b/lib/wasi/src/state/socket.rs index 7a9e5f8a9..a5b0ebb1c 100644 --- a/lib/wasi/src/state/socket.rs +++ b/lib/wasi/src/state/socket.rs @@ -5,7 +5,7 @@ use std::future::Future; use std::mem::transmute; use std::net::{IpAddr, Ipv4Addr, Ipv6Addr, SocketAddr}; use std::pin::Pin; -use std::sync::{Mutex, Arc, RwLock}; +use std::sync::{Arc, Mutex, RwLock}; use std::time::Duration; #[allow(unused_imports)] use tracing::{debug, error, info, warn}; @@ -164,7 +164,7 @@ impl InodeSocket { read_buffer: None, read_addr: None, silence_write_ready: false, - })) + })), } } @@ -214,7 +214,9 @@ impl InodeSocket { .bind_udp(addr, *reuse_port, *reuse_addr) .await .map_err(net_error_into_wasi_err)?; - socket.set_nonblocking(*nonblocking).map_err(net_error_into_wasi_err)?; + socket + .set_nonblocking(*nonblocking) + .map_err(net_error_into_wasi_err)?; Some(InodeSocket::new(InodeSocketKind::UdpSocket(socket))) } _ => return Err(Errno::Inval), @@ -254,7 +256,9 @@ impl InodeSocket { tracing::warn!("wasi[?]::sock_listen - failed - {}", err); net_error_into_wasi_err(err) })?; - socket.set_nonblocking(*nonblocking).map_err(net_error_into_wasi_err)?; + socket + .set_nonblocking(*nonblocking) + .map_err(net_error_into_wasi_err)?; if let Some(accept_timeout) = accept_timeout { socket .set_timeout(Some(*accept_timeout)) @@ -264,17 +268,17 @@ impl InodeSocket { } _ => { tracing::warn!("wasi[?]::sock_listen - failed - not supported(1)"); - return Err(__WASI_ENOTSUP) - }, + return Err(__WASI_ENOTSUP); + } }), InodeSocketKind::Closed => { tracing::warn!("wasi[?]::sock_listen - failed - socket closed"); Err(__WASI_EIO) - }, + } _ => { tracing::warn!("wasi[?]::sock_listen - failed - not supported(2)"); Err(__WASI_ENOTSUP) - }, + } } } @@ -285,12 +289,9 @@ impl InodeSocket { let mut inner = self.inner.write().unwrap(); let (sock, addr) = match &mut inner.kind { InodeSocketKind::TcpListener(sock) => { - let (child, addr) = sock - .accept() - .await - .map_err(net_error_into_wasi_err)?; + let (child, addr) = sock.accept().await.map_err(net_error_into_wasi_err)?; Ok((child, addr)) - }, + } InodeSocketKind::PreSocket { .. } => Err(__WASI_ENOTCONN), InodeSocketKind::Closed => Err(__WASI_EIO), _ => Err(__WASI_ENOTSUP), @@ -456,11 +457,7 @@ impl InodeSocket { }) } - pub fn set_opt_flag( - &self, - option: WasiSocketOption, - val: bool, - ) -> Result<(), __wasi_errno_t> { + pub fn set_opt_flag(&self, option: WasiSocketOption, val: bool) -> Result<(), __wasi_errno_t> { let mut inner = self.inner.write().unwrap(); match &mut inner.kind { InodeSocketKind::PreSocket { @@ -605,10 +602,7 @@ impl InodeSocket { } } - pub fn set_linger( - &self, - linger: Option, - ) -> Result<(), __wasi_errno_t> { + pub fn set_linger(&self, linger: Option) -> Result<(), __wasi_errno_t> { let mut inner = self.inner.write().unwrap(); match &mut inner.kind { InodeSocketKind::TcpStream(sock) => { @@ -620,67 +614,56 @@ impl InodeSocket { } } - pub fn nonblocking( - &self, - ) -> Result { + pub fn nonblocking(&self) -> Result { let inner = self.inner.read().unwrap(); - Ok( - match &inner.kind { - InodeSocketKind::TcpStream(sock) => { - sock.nonblocking().map_err(net_error_into_wasi_err)? - } - InodeSocketKind::TcpListener(sock, ..) => { - sock.nonblocking().map_err(net_error_into_wasi_err)? - } - InodeSocketKind::UdpSocket(sock, ..) => { - sock.nonblocking().map_err(net_error_into_wasi_err)? - } - InodeSocketKind::Raw(sock, ..) => { - sock.nonblocking().map_err(net_error_into_wasi_err)? - } - InodeSocketKind::Icmp(sock, ..) => { - sock.nonblocking().map_err(net_error_into_wasi_err)? - } - InodeSocketKind::PreSocket { nonblocking, .. } => { - *nonblocking - } - _ => { - return Err(__WASI_ENOTSUP); - }, + Ok(match &inner.kind { + InodeSocketKind::TcpStream(sock) => { + sock.nonblocking().map_err(net_error_into_wasi_err)? } - ) + InodeSocketKind::TcpListener(sock, ..) => { + sock.nonblocking().map_err(net_error_into_wasi_err)? + } + InodeSocketKind::UdpSocket(sock, ..) => { + sock.nonblocking().map_err(net_error_into_wasi_err)? + } + InodeSocketKind::Raw(sock, ..) => { + sock.nonblocking().map_err(net_error_into_wasi_err)? + } + InodeSocketKind::Icmp(sock, ..) => { + sock.nonblocking().map_err(net_error_into_wasi_err)? + } + InodeSocketKind::PreSocket { nonblocking, .. } => *nonblocking, + _ => { + return Err(__WASI_ENOTSUP); + } + }) } - pub fn set_nonblocking( - &self, - val: bool, - ) -> Result<(), __wasi_errno_t> { + pub fn set_nonblocking(&self, val: bool) -> Result<(), __wasi_errno_t> { let mut inner = self.inner.write().unwrap(); - Ok( - match &mut inner.kind { - InodeSocketKind::TcpStream(sock) => { - sock.set_nonblocking(val).map_err(net_error_into_wasi_err)? - } - InodeSocketKind::TcpListener(sock, ..) => { - sock.set_nonblocking(val).map_err(net_error_into_wasi_err)? - } - InodeSocketKind::UdpSocket(sock, ..) => { - sock.set_nonblocking(val).map_err(net_error_into_wasi_err)? - } - InodeSocketKind::Raw(sock, ..) => { - sock.set_nonblocking(val).map_err(net_error_into_wasi_err)? - } - InodeSocketKind::Icmp(sock, ..) => { - sock.set_nonblocking(val).map_err(net_error_into_wasi_err)? - } - InodeSocketKind::PreSocket { nonblocking, .. } => { - (*nonblocking) = val; - } - _ => { - return Err(__WASI_ENOTSUP); - }, + Ok(match &mut inner.kind { + InodeSocketKind::TcpStream(sock) => { + sock.set_nonblocking(val).map_err(net_error_into_wasi_err)? } - ) + InodeSocketKind::TcpListener(sock, ..) => { + sock.set_nonblocking(val).map_err(net_error_into_wasi_err)? + } + InodeSocketKind::UdpSocket(sock, ..) => { + sock.set_nonblocking(val).map_err(net_error_into_wasi_err)? + } + InodeSocketKind::Raw(sock, ..) => { + sock.set_nonblocking(val).map_err(net_error_into_wasi_err)? + } + InodeSocketKind::Icmp(sock, ..) => { + sock.set_nonblocking(val).map_err(net_error_into_wasi_err)? + } + InodeSocketKind::PreSocket { nonblocking, .. } => { + (*nonblocking) = val; + } + _ => { + return Err(__WASI_ENOTSUP); + } + }) } pub fn linger(&self) -> Result, __wasi_errno_t> { @@ -875,13 +858,10 @@ impl InodeSocket { } } - pub async fn send( - &self, - buf: Vec, - ) -> Result { + pub async fn send(&self, buf: Vec) -> Result { let buf_len = buf.len(); let mut inner = self.inner.write().unwrap(); - + let ret = match &mut inner.kind { InodeSocketKind::HttpRequest(sock, ty) => { let sock = sock.get_mut().unwrap(); @@ -903,18 +883,21 @@ impl InodeSocket { .await .map(|_| buf_len) .map_err(net_error_into_wasi_err), - InodeSocketKind::Raw(sock) => { - sock.send(Bytes::from(buf)).await.map_err(net_error_into_wasi_err) - } - InodeSocketKind::TcpStream(sock) => { - sock.send(Bytes::from(buf)).await.map_err(net_error_into_wasi_err) - } - InodeSocketKind::UdpSocket(sock) => { - sock.send(Bytes::from(buf)).await.map_err(net_error_into_wasi_err) - } - InodeSocketKind::PreSocket { .. } => Err(Errno::Notconn), - InodeSocketKind::Closed => Err(Errno::Io), - _ => Err(Errno::Notsup), + InodeSocketKind::Raw(sock) => sock + .send(Bytes::from(buf)) + .await + .map_err(net_error_into_wasi_err), + InodeSocketKind::TcpStream(sock) => sock + .send(Bytes::from(buf)) + .await + .map_err(net_error_into_wasi_err), + InodeSocketKind::UdpSocket(sock) => sock + .send(Bytes::from(buf)) + .await + .map_err(net_error_into_wasi_err), + InodeSocketKind::PreSocket { .. } => Err(__WASI_ENOTCONN), + InodeSocketKind::Closed => Err(__WASI_EIO), + _ => Err(__WASI_ENOTSUP), } .map(|_| buf_len)?; @@ -931,7 +914,7 @@ impl InodeSocket { ) -> Result { let buf_len = buf.len(); let mut inner = self.inner.write().unwrap(); - + let ret = match &mut inner.kind { InodeSocketKind::Icmp(sock) => sock .send_to(Bytes::from(buf), addr) @@ -953,9 +936,7 @@ impl InodeSocket { Ok(ret) } - pub fn peek( - &self, - ) -> Result { + pub fn peek(&self) -> Result { let mut inner = self.inner.write().unwrap(); if let Some(buf) = inner.read_buffer.as_ref() { if buf.len() > 0 { @@ -971,11 +952,13 @@ impl InodeSocket { return Err(__WASI_EIO); } let response = sock.response.as_ref().unwrap(); - + use std::sync::mpsc::TryRecvError; match response.try_recv() { Ok(a) => Bytes::from(a), - Err(TryRecvError::Disconnected) => { return Err(__WASI_EIO); } + Err(TryRecvError::Disconnected) => { + return Err(__WASI_EIO); + } Err(TryRecvError::Empty) => { return Ok(0); } @@ -990,12 +973,14 @@ impl InodeSocket { use std::sync::mpsc::TryRecvError; let headers = match headers.try_recv() { Ok(a) => a, - Err(TryRecvError::Disconnected) => { return Err(__WASI_EIO); } + Err(TryRecvError::Disconnected) => { + return Err(__WASI_EIO); + } Err(TryRecvError::Empty) => { return Ok(0); } }; - + let headers = format!("{}: {}", headers.0, headers.1); Bytes::from(headers.as_bytes().to_vec()) } @@ -1007,28 +992,36 @@ impl InodeSocket { InodeSocketKind::WebSocket(sock) => { let read = match sock.try_recv().map_err(net_error_into_wasi_err)? { Some(a) => a, - None => { return Ok(0); } + None => { + return Ok(0); + } }; read.data } InodeSocketKind::Raw(sock) => { let read = match sock.try_recv().map_err(net_error_into_wasi_err)? { Some(a) => a, - None => { return Ok(0); } + None => { + return Ok(0); + } }; read.data } InodeSocketKind::TcpStream(sock) => { let read = match sock.try_recv().map_err(net_error_into_wasi_err)? { Some(a) => a, - None => { return Ok(0); } + None => { + return Ok(0); + } }; read.data } InodeSocketKind::UdpSocket(sock) => { let read = match sock.try_recv().map_err(net_error_into_wasi_err)? { Some(a) => a, - None => { return Ok(0); } + None => { + return Ok(0); + } }; read.data } @@ -1048,10 +1041,7 @@ impl InodeSocket { } } - pub async fn recv( - &self, - max_size: usize, - ) -> Result { + pub async fn recv(&self, max_size: usize) -> Result { let mut inner = self.inner.write().unwrap(); loop { let is_tcp = if let InodeSocketKind::TcpStream(..) = &inner.kind { @@ -1125,9 +1115,7 @@ impl InodeSocket { } } - pub async fn peek_from( - &self, - ) -> Result { + pub async fn peek_from(&self) -> Result { let mut inner = self.inner.write().unwrap(); if let Some(buf) = inner.read_buffer.as_ref() { if buf.len() > 0 { @@ -1138,13 +1126,17 @@ impl InodeSocket { InodeSocketKind::Icmp(sock) => { match sock.try_recv_from().map_err(net_error_into_wasi_err)? { Some(a) => a, - None => { return Ok(0); } + None => { + return Ok(0); + } } - }, + } InodeSocketKind::UdpSocket(sock) => { match sock.try_recv_from().map_err(net_error_into_wasi_err)? { Some(a) => a, - None => { return Ok(0); } + None => { + return Ok(0); + } } } InodeSocketKind::PreSocket { .. } => return Err(__WASI_ENOTCONN), @@ -1160,10 +1152,7 @@ impl InodeSocket { } } - pub async fn recv_from( - &self, - max_size: usize - ) -> Result<(Bytes, SocketAddr), __wasi_errno_t> { + pub async fn recv_from(&self, max_size: usize) -> Result<(Bytes, SocketAddr), __wasi_errno_t> { let mut inner = self.inner.write().unwrap(); loop { let is_tcp = if let InodeSocketKind::TcpStream(..) = &inner.kind { @@ -1190,10 +1179,10 @@ impl InodeSocket { let rcv = match &mut inner.kind { InodeSocketKind::Icmp(sock) => { sock.recv_from().await.map_err(net_error_into_wasi_err)? - }, + } InodeSocketKind::UdpSocket(sock) => { sock.recv_from().await.map_err(net_error_into_wasi_err)? - }, + } InodeSocketKind::PreSocket { .. } => return Err(__WASI_ENOTCONN), InodeSocketKind::Closed => return Err(__WASI_EIO), _ => return Err(__WASI_ENOTSUP), @@ -1240,88 +1229,62 @@ impl InodeSocket { match &mut guard.kind { InodeSocketKind::TcpListener(socket) => { socket.peek().ok().map(|a| a > 0).unwrap_or_default() - }, - InodeSocketKind::TcpStream(..) | - InodeSocketKind::UdpSocket(..) | - InodeSocketKind::Raw(..) | - InodeSocketKind::WebSocket(..) => { - true - }, - _ => { - false } + InodeSocketKind::TcpStream(..) + | InodeSocketKind::UdpSocket(..) + | InodeSocketKind::Raw(..) + | InodeSocketKind::WebSocket(..) => true, + _ => false, } } else { false } } - pub fn poll_read_ready(&self, cx: &mut std::task::Context<'_>) -> std::task::Poll> { + pub fn poll_read_ready( + &self, + cx: &mut std::task::Context<'_>, + ) -> std::task::Poll> { let mut inner = self.inner.write().unwrap(); match &mut inner.kind { - InodeSocketKind::TcpListener(socket) => { - socket.poll_accept_ready(cx) - }, - InodeSocketKind::TcpStream(socket) => { - socket.poll_read_ready(cx) - } - InodeSocketKind::UdpSocket(socket) => { - socket.poll_read_ready(cx) - } - InodeSocketKind::Raw(socket) => { - socket.poll_read_ready(cx) - } - InodeSocketKind::WebSocket(socket) => { - socket.poll_read_ready(cx) - }, - InodeSocketKind::Icmp(socket) => { - socket.poll_read_ready(cx) - }, - InodeSocketKind::PreSocket{ .. } => { + InodeSocketKind::TcpListener(socket) => socket.poll_accept_ready(cx), + InodeSocketKind::TcpStream(socket) => socket.poll_read_ready(cx), + InodeSocketKind::UdpSocket(socket) => socket.poll_read_ready(cx), + InodeSocketKind::Raw(socket) => socket.poll_read_ready(cx), + InodeSocketKind::WebSocket(socket) => socket.poll_read_ready(cx), + InodeSocketKind::Icmp(socket) => socket.poll_read_ready(cx), + InodeSocketKind::PreSocket { .. } => { std::task::Poll::Ready(Err(wasmer_vnet::NetworkError::IOError)) - }, - InodeSocketKind::HttpRequest(..) => { - std::task::Poll::Pending - }, + } + InodeSocketKind::HttpRequest(..) => std::task::Poll::Pending, InodeSocketKind::Closed => { std::task::Poll::Ready(Err(wasmer_vnet::NetworkError::ConnectionAborted)) - }, + } } } - pub fn poll_write_ready(&self, cx: &mut std::task::Context<'_>) -> std::task::Poll> { + pub fn poll_write_ready( + &self, + cx: &mut std::task::Context<'_>, + ) -> std::task::Poll> { let mut inner = self.inner.write().unwrap(); if inner.silence_write_ready { return std::task::Poll::Pending; } let ret = match &mut inner.kind { - InodeSocketKind::TcpListener(_) => { - std::task::Poll::Pending - }, - InodeSocketKind::TcpStream(socket) => { - socket.poll_write_ready(cx) - } - InodeSocketKind::UdpSocket(socket) => { - socket.poll_write_ready(cx) - } - InodeSocketKind::Raw(socket) => { - socket.poll_write_ready(cx) - } - InodeSocketKind::WebSocket(socket) => { - socket.poll_write_ready(cx) - }, - InodeSocketKind::Icmp(socket) => { - socket.poll_write_ready(cx) - }, - InodeSocketKind::PreSocket{ .. } => { + InodeSocketKind::TcpListener(_) => std::task::Poll::Pending, + InodeSocketKind::TcpStream(socket) => socket.poll_write_ready(cx), + InodeSocketKind::UdpSocket(socket) => socket.poll_write_ready(cx), + InodeSocketKind::Raw(socket) => socket.poll_write_ready(cx), + InodeSocketKind::WebSocket(socket) => socket.poll_write_ready(cx), + InodeSocketKind::Icmp(socket) => socket.poll_write_ready(cx), + InodeSocketKind::PreSocket { .. } => { std::task::Poll::Ready(Err(wasmer_vnet::NetworkError::IOError)) - }, - InodeSocketKind::HttpRequest(..) => { - std::task::Poll::Pending - }, + } + InodeSocketKind::HttpRequest(..) => std::task::Poll::Pending, InodeSocketKind::Closed => { std::task::Poll::Ready(Err(wasmer_vnet::NetworkError::ConnectionAborted)) - }, + } }; if ret.is_ready() { // TODO - This will suppress the write ready notifications @@ -1332,12 +1295,13 @@ impl InodeSocket { } #[derive(Default)] -struct IndefinitePoll { -} -impl Future -for IndefinitePoll { +struct IndefinitePoll {} +impl Future for IndefinitePoll { type Output = (); - fn poll(self: Pin<&mut Self>, _cx: &mut std::task::Context<'_>) -> std::task::Poll { + fn poll( + self: Pin<&mut Self>, + _cx: &mut std::task::Context<'_>, + ) -> std::task::Poll { std::task::Poll::Pending } } diff --git a/lib/wasi/src/state/thread.rs b/lib/wasi/src/state/thread.rs index 89b60cc4f..2fd426649 100644 --- a/lib/wasi/src/state/thread.rs +++ b/lib/wasi/src/state/thread.rs @@ -1,16 +1,20 @@ use std::{ + borrow::Cow, + collections::{HashMap, HashSet}, + ops::{Deref, DerefMut}, sync::{ - Mutex, - Arc, - Condvar, RwLock, atomic::{AtomicU32, Ordering}, RwLockWriteGuard, RwLockReadGuard + atomic::{AtomicU32, Ordering}, + Arc, Condvar, Mutex, RwLock, RwLockReadGuard, RwLockWriteGuard, }, - time::Duration, collections::{HashMap, HashSet}, borrow::Cow, ops::{Deref, DerefMut} + time::Duration, }; -use bytes::{BytesMut, Bytes}; +use bytes::{Bytes, BytesMut}; use tracing::log::trace; use wasmer_vbus::{BusSpawnedProcess, SignalHandlerAbi}; -use wasmer_wasi_types::{__wasi_signal_t, __wasi_exitcode_t, __WASI_CLOCK_MONOTONIC, __wasi_errno_t, __WASI_ECHILD}; +use wasmer_wasi_types::{ + __wasi_errno_t, __wasi_exitcode_t, __wasi_signal_t, __WASI_CLOCK_MONOTONIC, __WASI_ECHILD, +}; use crate::syscalls::platform_clock_time_get; @@ -41,8 +45,7 @@ impl From for u32 { } } -impl std::fmt::Display -for WasiThreadId { +impl std::fmt::Display for WasiThreadId { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { write!(f, "{}", self.0) } @@ -50,16 +53,14 @@ for WasiThreadId { /// Represents a linked list of stack snapshots #[derive(Debug, Clone)] -struct ThreadSnapshot -{ +struct ThreadSnapshot { call_stack: Bytes, store_data: Bytes, } /// Represents a linked list of stack snapshots #[derive(Debug, Clone, Default)] -struct ThreadStack -{ +struct ThreadStack { memory_stack: Vec, memory_stack_corrected: Vec, snapshots: HashMap, @@ -69,18 +70,19 @@ struct ThreadStack /// Represents a running thread which allows a joiner to /// wait for the thread to exit #[derive(Debug, Clone)] -pub struct WasiThread -{ +pub struct WasiThread { pub(crate) is_main: bool, pub(crate) pid: WasiProcessId, pub(crate) id: WasiThreadId, finished: Arc<(Mutex>, Condvar)>, - pub(crate) signals: Arc<(Mutex>, tokio::sync::broadcast::Sender<()>)>, + pub(crate) signals: Arc<( + Mutex>, + tokio::sync::broadcast::Sender<()>, + )>, stack: Arc>, } -impl WasiThread -{ +impl WasiThread { /// Returns the process ID pub fn pid(&self) -> WasiProcessId { self.pid @@ -150,19 +152,34 @@ impl WasiThread } /// Adds a stack snapshot and removes dead ones - pub fn add_snapshot(&self, mut memory_stack: &[u8], memory_stack_corrected: &[u8], hash: u128, rewind_stack: &[u8], store_data: &[u8]) { + pub fn add_snapshot( + &self, + mut memory_stack: &[u8], + memory_stack_corrected: &[u8], + hash: u128, + rewind_stack: &[u8], + store_data: &[u8], + ) { // Lock the stack let mut stack = self.stack.lock().unwrap(); let mut pstack = stack.deref_mut(); loop { // First we validate if the stack is no longer valid let memory_stack_before = pstack.memory_stack.len(); - let memory_stack_after= memory_stack.len(); - if memory_stack_before > memory_stack_after || - ( - pstack.memory_stack.iter().zip(memory_stack.iter()).any(|(a, b)| *a == *b) == false && - pstack.memory_stack_corrected.iter().zip(memory_stack.iter()).any(|(a, b)| *a == *b) == false - ) + let memory_stack_after = memory_stack.len(); + if memory_stack_before > memory_stack_after + || (pstack + .memory_stack + .iter() + .zip(memory_stack.iter()) + .any(|(a, b)| *a == *b) + == false + && pstack + .memory_stack_corrected + .iter() + .zip(memory_stack.iter()) + .any(|(a, b)| *a == *b) + == false) { // The stacks have changed so need to start again at this segment let mut new_stack = ThreadStack::default(); @@ -178,7 +195,11 @@ impl WasiThread } while let Some(disowned) = disown { for hash in disowned.snapshots.keys() { - tracing::trace!("wasi[{}]::stack has been forgotten (hash={})", self.pid, hash); + tracing::trace!( + "wasi[{}]::stack has been forgotten (hash={})", + self.pid, + hash + ); } disown = disowned.next; } @@ -201,10 +222,13 @@ impl WasiThread } // Add the call stack - pstack.snapshots.insert(hash, ThreadSnapshot { - call_stack: BytesMut::from(rewind_stack).freeze(), - store_data: BytesMut::from(store_data).freeze(), - }); + pstack.snapshots.insert( + hash, + ThreadSnapshot { + call_stack: BytesMut::from(rewind_stack).freeze(), + store_data: BytesMut::from(store_data).freeze(), + }, + ); } /// Gets a snapshot that was previously addedf @@ -216,7 +240,11 @@ impl WasiThread loop { memory_stack.extend(pstack.memory_stack_corrected.iter()); if let Some(snapshot) = pstack.snapshots.get(&hash) { - return Some((memory_stack, snapshot.call_stack.clone(), snapshot.store_data.clone())); + return Some(( + memory_stack, + snapshot.call_stack.clone(), + snapshot.store_data.clone(), + )); } if let Some(next) = pstack.next.as_ref() { pstack = next.deref(); @@ -255,8 +283,7 @@ impl WasiThreadHandle { } } -impl Drop -for WasiThreadHandle { +impl Drop for WasiThreadHandle { fn drop(&mut self) { // We do this so we track when the last handle goes out of scope if let Some(id) = Arc::get_mut(&mut self.id) { @@ -264,13 +291,12 @@ for WasiThreadHandle { if let Some(ctrl) = inner.threads.remove(id) { ctrl.terminate(0); } - inner.thread_count -= 1; + inner.thread_count -= 1; } } } -impl std::ops::Deref -for WasiThreadHandle { +impl std::ops::Deref for WasiThreadHandle { type Target = WasiThread; fn deref(&self) -> &Self::Target { @@ -278,8 +304,7 @@ for WasiThreadHandle { } } -impl std::ops::DerefMut -for WasiThreadHandle { +impl std::ops::DerefMut for WasiThreadHandle { fn deref_mut(&mut self) -> &mut Self::Target { &mut self.thread } @@ -317,16 +342,14 @@ impl Into for WasiProcessId { } } -impl std::fmt::Display -for WasiProcessId { +impl std::fmt::Display for WasiProcessId { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { write!(f, "{}", self.0) } } #[derive(Debug)] -pub struct WasiSignalInterval -{ +pub struct WasiSignalInterval { /// Signal that will be raised pub signal: u8, /// Time between the signals @@ -338,8 +361,7 @@ pub struct WasiSignalInterval } #[derive(Debug)] -pub struct WasiProcessInner -{ +pub struct WasiProcessInner { /// The threads that make up this process pub threads: HashMap, /// Number of threads running for this process @@ -362,8 +384,7 @@ pub struct WasiProcessInner /// Represents a process running within the compute state #[derive(Debug, Clone)] -pub struct WasiProcess -{ +pub struct WasiProcess { /// Unique ID of this process pub(crate) pid: WasiProcessId, /// ID of the parent process @@ -388,20 +409,18 @@ impl WasiProcessWait { pub fn new(process: &WasiProcess) -> Self { process.waiting.fetch_add(1, Ordering::AcqRel); Self { - waiting: process.waiting.clone() + waiting: process.waiting.clone(), } } } -impl Drop -for WasiProcessWait { +impl Drop for WasiProcessWait { fn drop(&mut self) { self.waiting.fetch_sub(1, Ordering::AcqRel); } } -impl WasiProcess -{ +impl WasiProcess { /// Gets the process ID of this process pub fn pid(&self) -> WasiProcessId { self.pid @@ -442,11 +461,11 @@ impl WasiProcess is_main, finished, signals: Arc::new((Mutex::new(Vec::new()), tx_signals)), - stack: Arc::new(Mutex::new(ThreadStack::default())) + stack: Arc::new(Mutex::new(ThreadStack::default())), }; inner.threads.insert(id, ctrl.clone()); inner.thread_count += 1; - + WasiThreadHandle { id: Arc::new(id), thread: ctrl, @@ -459,14 +478,19 @@ impl WasiProcess let inner = self.inner.read().unwrap(); inner.threads.get(tid).map(|a| a.clone()) } - + /// Signals a particular thread in the process pub fn signal_thread(&self, tid: &WasiThreadId, signal: __wasi_signal_t) { let inner = self.inner.read().unwrap(); if let Some(thread) = inner.threads.get(tid) { thread.signal(signal); } else { - trace!("wasi[{}]::lost-signal(tid={}, sig={})", self.pid(), tid.0, signal); + trace!( + "wasi[{}]::lost-signal(tid={}, sig={})", + self.pid(), + tid.0, + signal + ); } } @@ -488,25 +512,31 @@ impl WasiProcess } /// Signals one of the threads every interval - pub fn signal_interval(&self, signal: __wasi_signal_t, interval: Option, repeat: bool) { + pub fn signal_interval( + &self, + signal: __wasi_signal_t, + interval: Option, + repeat: bool, + ) { let mut inner = self.inner.write().unwrap(); let interval = match interval { None => { inner.signal_intervals.remove(&signal); return; - }, + } Some(a) => a, }; let now = platform_clock_time_get(__WASI_CLOCK_MONOTONIC, 1_000_000).unwrap() as u128; - inner.signal_intervals.insert(signal, + inner.signal_intervals.insert( + signal, WasiSignalInterval { signal, interval, last_signal: now, - repeat - } + repeat, + }, ); } @@ -550,7 +580,7 @@ impl WasiProcess let mut children = self.children.write().unwrap(); children.retain(|a| *a != pid); exit_code = a; - }, + } None => { return None; } @@ -561,7 +591,10 @@ impl WasiProcess } /// Waits for all the children to be finished - pub fn join_any_child(&mut self, timeout: Duration) -> Result, __wasi_errno_t> { + pub fn join_any_child( + &mut self, + timeout: Duration, + ) -> Result, __wasi_errno_t> { let _guard = WasiProcessWait::new(self); let children: Vec<_> = { let children = self.children.read().unwrap(); @@ -576,7 +609,7 @@ impl WasiProcess let pid = process.pid(); let mut children = self.children.write().unwrap(); children.retain(|a| *a != pid); - return Ok(Some((pid, exit_code))) + return Ok(Some((pid, exit_code))); } } } @@ -603,16 +636,14 @@ impl WasiProcess } } -impl SignalHandlerAbi -for WasiProcess { +impl SignalHandlerAbi for WasiProcess { fn signal(&self, sig: __wasi_signal_t) { self.signal_process(sig) } } #[derive(Debug, Clone)] -pub struct WasiControlPlane -{ +pub struct WasiControlPlane { /// The processes running on this machine pub(crate) processes: Arc>>, /// Seed used to generate process ID's @@ -621,9 +652,7 @@ pub struct WasiControlPlane pub(crate) reserved: Arc>>, } -impl Default -for WasiControlPlane -{ +impl Default for WasiControlPlane { fn default() -> Self { Self { processes: Default::default(), @@ -633,8 +662,7 @@ for WasiControlPlane } } -impl WasiControlPlane -{ +impl WasiControlPlane { /// Reserves a PID and returns it pub fn reserve_pid(&self) -> WasiProcessId { let mut pid: WasiProcessId; @@ -648,7 +676,7 @@ impl WasiControlPlane } guard.insert(pid); } - + { let guard = self.processes.read().unwrap(); if guard.contains_key(&pid) == false { @@ -680,11 +708,11 @@ impl WasiControlPlane thread_local_seed: Default::default(), signal_intervals: Default::default(), bus_processes: Default::default(), - bus_process_reuse: Default::default() + bus_process_reuse: Default::default(), })), children: Arc::new(RwLock::new(Default::default())), finished: Arc::new((Mutex::new(None), Condvar::default())), - waiting: Arc::new(AtomicU32::new(0)) + waiting: Arc::new(AtomicU32::new(0)), }; { let mut guard = self.processes.write().unwrap(); diff --git a/lib/wasi/src/state/types.rs b/lib/wasi/src/state/types.rs index d99c01b7e..dfcefd4a2 100644 --- a/lib/wasi/src/state/types.rs +++ b/lib/wasi/src/state/types.rs @@ -1,7 +1,7 @@ /// types for use in the WASI filesystem #[cfg(feature = "enable-serde")] use serde::{Deserialize, Serialize}; -#[cfg(all(unix, feature = "sys-poll", not(feature="os")))] +#[cfg(all(unix, feature = "sys-poll", not(feature = "os")))] use std::convert::TryInto; use std::{ collections::VecDeque, @@ -11,16 +11,12 @@ use std::{ }; use wasmer_vbus::VirtualBusError; +#[cfg(all(not(feature = "mem-fs"), not(feature = "host-fs")))] +pub use crate::{fs::NullFile as Stderr, fs::NullFile as Stdin, fs::NullFile as Stdout}; #[cfg(feature = "host-fs")] pub use wasmer_vfs::host_fs::{Stderr, Stdin, Stdout}; #[cfg(all(feature = "mem-fs", not(feature = "host-fs")))] pub use wasmer_vfs::mem_fs::{Stderr, Stdin, Stdout}; -#[cfg(all(not(feature = "mem-fs"), not(feature = "host-fs")))] -pub use crate::{ - fs::NullFile as Stderr, - fs::NullFile as Stdin, - fs::NullFile as Stdout, -}; use wasmer_vfs::{FsError, VirtualFile}; use wasmer_vnet::NetworkError; @@ -240,7 +236,7 @@ pub fn iterate_poll_events(pes: PollEventSet) -> PollEventIter { PollEventIter { pes, i: 0 } } -#[cfg(all(unix, feature = "sys-poll", not(feature="os")))] +#[cfg(all(unix, feature = "sys-poll", not(feature = "os")))] fn poll_event_set_to_platform_poll_events(mut pes: PollEventSet) -> i16 { let mut out = 0; for i in 0..16 { @@ -257,7 +253,7 @@ fn poll_event_set_to_platform_poll_events(mut pes: PollEventSet) -> i16 { out } -#[cfg(all(unix, feature = "sys-poll", not(feature="os")))] +#[cfg(all(unix, feature = "sys-poll", not(feature = "os")))] fn platform_poll_events_to_pollevent_set(mut num: i16) -> PollEventSet { let mut peb = PollEventBuilder::new(); for i in 0..16 { @@ -290,7 +286,7 @@ impl PollEventBuilder { } } -#[cfg(all(unix, feature = "sys-poll", not(feature="os")))] +#[cfg(all(unix, feature = "sys-poll", not(feature = "os")))] pub(crate) fn poll( selfs: &[&(dyn VirtualFile + Send + Sync + 'static)], events: &[PollEventSet], @@ -330,14 +326,13 @@ pub(crate) fn poll( Ok(result.try_into().unwrap()) } -#[cfg(any(not(unix), not(feature = "sys-poll"), feature="os"))] +#[cfg(any(not(unix), not(feature = "sys-poll"), feature = "os"))] pub(crate) fn poll( files: &[super::InodeValFilePollGuard], events: &[PollEventSet], seen_events: &mut [PollEventSet], timeout: Duration, ) -> Result { - if !(files.len() == events.len() && events.len() == seen_events.len()) { tracing::debug!("the slice length of 'files', 'events' and 'seen_events' must be the same (files={}, events={}, seen_events={})", files.len(), events.len(), seen_events.len()); return Err(FsError::InvalidInput); @@ -364,10 +359,8 @@ pub(crate) fn poll( match event { PollEvent::PollIn => { if can_read.is_none() { - can_read = Some( - file.bytes_available_read()? - .map(|s| s > 0) - .unwrap_or(false)); + can_read = + Some(file.bytes_available_read()?.map(|s| s > 0).unwrap_or(false)); } if can_read.unwrap_or_default() { tracing::debug!("poll_evt can_read=true file={:?}", file); @@ -376,19 +369,18 @@ pub(crate) fn poll( } PollEvent::PollOut => { if can_write.is_none() { - can_write = Some(file - .bytes_available_write()? - .map(|s| s > 0) - .unwrap_or(false)); + can_write = Some( + file.bytes_available_write()? + .map(|s| s > 0) + .unwrap_or(false), + ); } if can_write.unwrap_or_default() { tracing::debug!("poll_evt can_write=true file={:?}", file); builder = builder.add(PollEvent::PollOut); } } - PollEvent::PollHangUp | - PollEvent::PollInvalid | - PollEvent::PollError => { + PollEvent::PollHangUp | PollEvent::PollInvalid | PollEvent::PollError => { if is_closed.is_none() { is_closed = Some(file.is_open() == false); } diff --git a/lib/wasi/src/syscalls/mod.rs b/lib/wasi/src/syscalls/mod.rs index ee27e56f2..2afc0faeb 100644 --- a/lib/wasi/src/syscalls/mod.rs +++ b/lib/wasi/src/syscalls/mod.rs @@ -23,21 +23,16 @@ use self::types::*; #[cfg(feature = "os")] use crate::bin_factory::spawn_exec_module; use crate::runtime::SpawnType; -use crate::state::{WasiProcessWait, read_ip_port, write_ip_port}; use crate::state::{ - bus_error_into_wasi_err, - wasi_error_into_bus_err, - InodeHttpSocketType, - WasiThreadContext, - WasiThreadId, - WasiProcessId, - WasiFutex, - WasiBusCall, - WasiParkingLot, - WasiDummyWaker + bus_error_into_wasi_err, wasi_error_into_bus_err, InodeHttpSocketType, WasiBusCall, + WasiDummyWaker, WasiFutex, WasiParkingLot, WasiProcessId, WasiThreadContext, WasiThreadId, }; +use crate::state::{read_ip_port, write_ip_port, WasiProcessWait}; use crate::utils::map_io_err; -use crate::{WasiEnvInner, import_object_for_all_wasi_versions, WasiFunctionEnv, current_caller_id, DEFAULT_STACK_SIZE, WasiVFork, WasiRuntimeImplementation, VirtualTaskManager, WasiThread}; +use crate::{ + current_caller_id, import_object_for_all_wasi_versions, VirtualTaskManager, WasiEnvInner, + WasiFunctionEnv, WasiRuntimeImplementation, WasiThread, WasiVFork, DEFAULT_STACK_SIZE, +}; use crate::{ mem_error_to_wasi, state::{ @@ -50,11 +45,10 @@ use crate::{ use bytes::{Bytes, BytesMut}; use cooked_waker::IntoWaker; use sha2::Sha256; -use wasmer::vm::VMMemory; use std::borrow::{Borrow, Cow}; use std::cell::RefCell; -use std::collections::{HashSet, HashMap}; use std::collections::hash_map::Entry; +use std::collections::{HashMap, HashSet}; use std::convert::{Infallible, TryInto}; use std::io::{self, Read, Seek, Write}; use std::mem::transmute; @@ -63,22 +57,27 @@ use std::num::NonZeroU64; use std::ops::{Deref, DerefMut}; use std::path::Path; use std::pin::Pin; -use std::sync::atomic::{AtomicU64, AtomicU32, AtomicBool}; +use std::sync::atomic::{AtomicBool, AtomicU32, AtomicU64}; use std::sync::{atomic::Ordering, Mutex}; use std::sync::{mpsc, Arc, Condvar}; -use std::task::{Poll, Context}; +use std::task::{Context, Poll}; use std::thread::LocalKey; use std::time::Duration; use tracing::{debug, error, trace, warn}; +use wasmer::vm::VMMemory; use wasmer::{ - AsStoreMut, FunctionEnvMut, Memory, Memory32, Memory64, MemorySize, RuntimeError, Value, - WasmPtr, WasmSlice, FunctionEnv, Instance, Module, Extern, MemoryView, TypedFunction, Store, Pages, Global, AsStoreRef, - MemoryAccessError, OnCalledAction, MemoryError, Function, StoreSnapshot + AsStoreMut, AsStoreRef, Extern, Function, FunctionEnv, FunctionEnvMut, Global, Instance, + Memory, Memory32, Memory64, MemoryAccessError, MemoryError, MemorySize, MemoryView, Module, + OnCalledAction, Pages, RuntimeError, Store, StoreSnapshot, TypedFunction, Value, WasmPtr, + WasmSlice, }; -use wasmer_vbus::{FileDescriptor, StdioMode, BusDataFormat, BusInvocationEvent, BusSpawnedProcess, VirtualBusError, SignalHandlerAbi, SpawnOptionsConfig}; -use wasmer_vfs::{FsError, VirtualFile, FileSystem}; -use wasmer_vnet::{SocketHttpRequest, StreamSecurity}; use wasmer_types::LinearMemory; +use wasmer_vbus::{ + BusDataFormat, BusInvocationEvent, BusSpawnedProcess, FileDescriptor, SignalHandlerAbi, + SpawnOptionsConfig, StdioMode, VirtualBusError, +}; +use wasmer_vfs::{FileSystem, FsError, VirtualFile}; +use wasmer_vnet::{SocketHttpRequest, StreamSecurity}; #[cfg(any( target_os = "freebsd", @@ -150,7 +149,7 @@ pub(crate) fn read_bytes( let to_read = from_offset::(iov_inner.buf_len)?; raw_bytes.resize(to_read, 0); let has_read = reader.read(&mut raw_bytes).map_err(map_io_err)?; - + let buf = WasmPtr::::new(iov_inner.buf) .slice(memory, iov_inner.buf_len) .map_err(mem_error_to_wasi)?; @@ -169,10 +168,7 @@ fn has_rights(rights_set: __wasi_rights_t, rights_check_set: __wasi_rights_t) -> } /// Writes data to the stderr -pub fn stderr_write( - ctx: &FunctionEnvMut<'_, WasiEnv>, - buf: &[u8] -) -> Result<(), __wasi_errno_t> { +pub fn stderr_write(ctx: &FunctionEnvMut<'_, WasiEnv>, buf: &[u8]) -> Result<(), __wasi_errno_t> { let env = ctx.data(); let (memory, state, inodes) = env.get_memory_and_wasi_state_and_inodes_mut(ctx, 0); @@ -192,7 +188,7 @@ fn __sock_actor( where T: 'static, F: FnOnce(crate::state::InodeSocket) -> Fut + 'static, - Fut: std::future::Future> + Fut: std::future::Future>, { let env = ctx.data(); let (_, state, inodes) = env.get_memory_and_wasi_state_and_inodes(&ctx, 0); @@ -215,10 +211,8 @@ where drop(guard); // Block on the work and process process - __asyncify(tasks, &env.thread, None, async move { - actor(socket).await - })? - }, + __asyncify(tasks, &env.thread, None, async move { actor(socket).await })? + } _ => { return Err(Errno::Notsock); } @@ -236,16 +230,18 @@ fn __asyncify( ) -> Result where T: 'static, - Fut: std::future::Future> + 'static + Fut: std::future::Future> + 'static, { let mut signaler = thread.signals.1.subscribe(); // Create the timeout - let timeout = { - let tasks_inner= tasks.clone(); + let timeout = { + let tasks_inner = tasks.clone(); async move { if let Some(timeout) = timeout { - tasks_inner.sleep_now(current_caller_id(), timeout.as_millis()).await + tasks_inner + .sleep_now(current_caller_id(), timeout.as_millis()) + .await } else { InfiniteSleep::default().await } @@ -253,42 +249,37 @@ where }; // Block on the work and process process - let tasks_inner= tasks.clone(); + let tasks_inner = tasks.clone(); let (tx_ret, mut rx_ret) = tokio::sync::mpsc::unbounded_channel(); - tasks.block_on( - Box::pin(async move { - tokio::select! { - // The main work we are doing - ret = work => { - let _ = tx_ret.send(ret); - }, - // If a signaller is triggered then we interrupt the main process - _ = signaler.recv() => { - let _ = tx_ret.send(Err(__WASI_EINTR)); - }, - // Optional timeout - _ = timeout => { - let _ = tx_ret.send(Err(__WASI_ETIMEDOUT)); - }, - // Periodically wake every 10 milliseconds for synchronously IO - // (but only if someone is currently registered for it) - _ = async move { - loop { - tasks_inner.wait_for_root_waker().await; - tasks_inner.wake_root_wakers(); - } - } => { } - } - - }) - ); - rx_ret - .try_recv() - .unwrap_or(Err(__WASI_EINTR)) + tasks.block_on(Box::pin(async move { + tokio::select! { + // The main work we are doing + ret = work => { + let _ = tx_ret.send(ret); + }, + // If a signaller is triggered then we interrupt the main process + _ = signaler.recv() => { + let _ = tx_ret.send(Err(__WASI_EINTR)); + }, + // Optional timeout + _ = timeout => { + let _ = tx_ret.send(Err(__WASI_ETIMEDOUT)); + }, + // Periodically wake every 10 milliseconds for synchronously IO + // (but only if someone is currently registered for it) + _ = async move { + loop { + tasks_inner.wait_for_root_waker().await; + tasks_inner.wake_root_wakers(); + } + } => { } + } + })); + rx_ret.try_recv().unwrap_or(Err(__WASI_EINTR)) } #[derive(Default)] -struct InfiniteSleep { } +struct InfiniteSleep {} impl std::future::Future for InfiniteSleep { type Output = (); fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { @@ -305,7 +296,7 @@ fn __sock_actor_mut( where T: 'static, F: FnOnce(crate::state::InodeSocket) -> Fut + 'static, - Fut: std::future::Future> + Fut: std::future::Future>, { let env = ctx.data(); let (_, state, inodes) = env.get_memory_and_wasi_state_and_inodes(&ctx, 0); @@ -326,10 +317,8 @@ where let socket = socket.clone(); drop(guard); - __asyncify(tasks, &env.thread, None, async move { - actor(socket).await - }) - }, + __asyncify(tasks, &env.thread, None, async move { actor(socket).await }) + } _ => { return Err(__WASI_ENOTSOCK); } @@ -344,15 +333,20 @@ fn __sock_upgrade( ) -> Result<(), __wasi_errno_t> where F: FnOnce(crate::state::InodeSocket) -> Fut + 'static, - Fut: std::future::Future, __wasi_errno_t>> - + Fut: std::future::Future, __wasi_errno_t>>, { let env = ctx.data(); let (_, state, inodes) = env.get_memory_and_wasi_state_and_inodes(&ctx, 0); let fd_entry = state.fs.get_fd(sock)?; if rights != 0 && !has_rights(fd_entry.rights, rights) { - tracing::warn!("wasi[{}:{}]::sock_upgrade(fd={}, rights={}) - failed - no access rights to upgrade", ctx.data().pid(), ctx.data().tid(), sock, rights); + tracing::warn!( + "wasi[{}:{}]::sock_upgrade(fd={}, rights={}) - failed - no access rights to upgrade", + ctx.data().pid(), + ctx.data().tid(), + sock, + rights + ); return Err(__WASI_EACCES); } @@ -365,12 +359,10 @@ where Kind::Socket { socket } => { let socket = socket.clone(); drop(guard); - + let new_socket = { // Block on the work and process process - __asyncify(tasks, &env.thread, None, async move { - actor(socket).await - })? + __asyncify(tasks, &env.thread, None, async move { actor(socket).await })? }; if let Some(mut new_socket) = new_socket { @@ -378,16 +370,28 @@ where match guard.deref_mut() { Kind::Socket { socket } => { std::mem::swap(socket, &mut new_socket); - }, + } _ => { - tracing::warn!("wasi[{}:{}]::sock_upgrade(fd={}, rights={}) - failed - not a socket", ctx.data().pid(), ctx.data().tid(), sock, rights); + tracing::warn!( + "wasi[{}:{}]::sock_upgrade(fd={}, rights={}) - failed - not a socket", + ctx.data().pid(), + ctx.data().tid(), + sock, + rights + ); return Err(__WASI_ENOTSOCK); } } } } _ => { - tracing::warn!("wasi[{}:{}]::sock_upgrade(fd={}, rights={}) - failed - not a socket", ctx.data().pid(), ctx.data().tid(), sock, rights); + tracing::warn!( + "wasi[{}:{}]::sock_upgrade(fd={}, rights={}) - failed - not a socket", + ctx.data().pid(), + ctx.data().tid(), + sock, + rights + ); return Err(__WASI_ENOTSOCK); } } @@ -478,7 +482,11 @@ pub fn args_sizes_get( argc: WasmPtr, argv_buf_size: WasmPtr, ) -> __wasi_errno_t { - debug!("wasi[{}:{}]::args_sizes_get", ctx.data().pid(), ctx.data().tid()); + debug!( + "wasi[{}:{}]::args_sizes_get", + ctx.data().pid(), + ctx.data().tid() + ); let env = ctx.data(); let (memory, mut state) = env.get_memory_and_wasi_state(&ctx, 0); @@ -510,7 +518,11 @@ pub fn clock_res_get( clock_id: __wasi_clockid_t, resolution: WasmPtr<__wasi_timestamp_t, M>, ) -> __wasi_errno_t { - trace!("wasi[{}:{}]::clock_res_get", ctx.data().pid(), ctx.data().tid()); + trace!( + "wasi[{}:{}]::clock_res_get", + ctx.data().pid(), + ctx.data().tid() + ); let env = ctx.data(); let memory = env.memory_view(&ctx); @@ -584,7 +596,8 @@ pub fn clock_time_set( ) -> __wasi_errno_t { trace!( "wasi::clock_time_set clock_id: {}, time: {}", - clock_id, time + clock_id, + time ); let env = ctx.data(); let memory = env.memory_view(&ctx); @@ -595,7 +608,7 @@ pub fn clock_time_set( let t_target = time as i64; let t_offset = t_target - t_now; - + let mut guard = env.state.clock_offset.lock().unwrap(); guard.insert(clock_id, t_offset); @@ -617,7 +630,8 @@ pub fn environ_get( ) -> __wasi_errno_t { trace!( "wasi::environ_get. Environ: {:?}, environ_buf: {:?}", - environ, environ_buf + environ, + environ_buf ); let env = ctx.data(); let (memory, mut state) = env.get_memory_and_wasi_state(&ctx, 0); @@ -638,7 +652,11 @@ pub fn environ_sizes_get( environ_count: WasmPtr, environ_buf_size: WasmPtr, ) -> __wasi_errno_t { - trace!("wasi[{}:{}]::environ_sizes_get", ctx.data().pid(), ctx.data().tid()); + trace!( + "wasi[{}:{}]::environ_sizes_get", + ctx.data().pid(), + ctx.data().tid() + ); let env = ctx.data(); let (memory, mut state) = env.get_memory_and_wasi_state(&ctx, 0); @@ -679,7 +697,12 @@ pub fn fd_advise( len: __wasi_filesize_t, advice: __wasi_advice_t, ) -> __wasi_errno_t { - debug!("wasi[{}:{}]::fd_advise: fd={}", ctx.data().pid(), ctx.data().tid(), fd); + debug!( + "wasi[{}:{}]::fd_advise: fd={}", + ctx.data().pid(), + ctx.data().tid(), + fd + ); // this is used for our own benefit, so just returning success is a valid // implementation for now @@ -701,7 +724,11 @@ pub fn fd_allocate( offset: __wasi_filesize_t, len: __wasi_filesize_t, ) -> __wasi_errno_t { - debug!("wasi[{}:{}]::fd_allocate", ctx.data().pid(), ctx.data().tid()); + debug!( + "wasi[{}:{}]::fd_allocate", + ctx.data().pid(), + ctx.data().tid() + ); let env = ctx.data(); let (_, mut state, inodes) = env.get_memory_and_wasi_state_and_inodes(&ctx, 0); let fd_entry = wasi_try!(state.fs.get_fd(fd)); @@ -749,11 +776,16 @@ pub fn fd_allocate( /// - `Errno::Badf` /// If `fd` is invalid or not open pub fn fd_close(ctx: FunctionEnvMut<'_, WasiEnv>, fd: __wasi_fd_t) -> __wasi_errno_t { - debug!("wasi[{}:{}]::fd_close: fd={}", ctx.data().pid(), ctx.data().tid(), fd); + debug!( + "wasi[{}:{}]::fd_close: fd={}", + ctx.data().pid(), + ctx.data().tid(), + fd + ); let env = ctx.data(); let (_, mut state, inodes) = env.get_memory_and_wasi_state_and_inodes(&ctx, 0); - let fd_entry = wasi_try!(state.fs.get_fd(fd)); + let fd_entry = wasi_try!(state.fs.get_fd(fd)); wasi_try!(state.fs.close_fd(inodes.deref(), fd)); Errno::Success @@ -765,7 +797,11 @@ pub fn fd_close(ctx: FunctionEnvMut<'_, WasiEnv>, fd: __wasi_fd_t) -> __wasi_err /// - `Fd fd` /// The file descriptor to sync pub fn fd_datasync(ctx: FunctionEnvMut<'_, WasiEnv>, fd: __wasi_fd_t) -> __wasi_errno_t { - debug!("wasi[{}:{}]::fd_datasync", ctx.data().pid(), ctx.data().tid()); + debug!( + "wasi[{}:{}]::fd_datasync", + ctx.data().pid(), + ctx.data().tid() + ); let env = ctx.data(); let (_, mut state, inodes) = env.get_memory_and_wasi_state_and_inodes(&ctx, 0); let fd_entry = wasi_try!(state.fs.get_fd(fd)); @@ -794,7 +830,9 @@ pub fn fd_fdstat_get( buf_ptr: WasmPtr, ) -> Errno { debug!( - "wasi[{}:{}]::fd_fdstat_get: fd={}, buf_ptr={}", ctx.data().pid(), ctx.data().tid(), + "wasi[{}:{}]::fd_fdstat_get: fd={}, buf_ptr={}", + ctx.data().pid(), + ctx.data().tid(), fd, buf_ptr.offset() ); @@ -821,7 +859,13 @@ pub fn fd_fdstat_set_flags( fd: __wasi_fd_t, flags: __wasi_fdflags_t, ) -> __wasi_errno_t { - debug!("wasi[{}:{}]::fd_fdstat_set_flags (fd={}, flags={})", ctx.data().pid(), ctx.data().tid(), fd, flags); + debug!( + "wasi[{}:{}]::fd_fdstat_set_flags (fd={}, flags={})", + ctx.data().pid(), + ctx.data().tid(), + fd, + flags + ); let env = ctx.data(); let (_, mut state, inodes) = env.get_memory_and_wasi_state_and_inodes(&ctx, 0); let mut fd_map = state.fs.fd_map.write().unwrap(); @@ -829,7 +873,13 @@ pub fn fd_fdstat_set_flags( let inode = fd_entry.inode; if !has_rights(fd_entry.rights, __WASI_RIGHT_FD_FDSTAT_SET_FLAGS) { - debug!("wasi[{}:{}]::fd_fdstat_set_flags (fd={}, flags={}) - access denied", ctx.data().pid(), ctx.data().tid(), fd, flags); + debug!( + "wasi[{}:{}]::fd_fdstat_set_flags (fd={}, flags={}) - access denied", + ctx.data().pid(), + ctx.data().tid(), + fd, + flags + ); return __WASI_EACCES; } @@ -838,10 +888,16 @@ pub fn fd_fdstat_set_flags( match guard.deref_mut() { Kind::Socket { socket } => { let nonblocking = (flags & __WASI_FDFLAG_NONBLOCK) != 0; - debug!("wasi[{}:{}]::socket(fd={}) nonblocking={}", ctx.data().pid(), ctx.data().tid(), fd, nonblocking); + debug!( + "wasi[{}:{}]::socket(fd={}) nonblocking={}", + ctx.data().pid(), + ctx.data().tid(), + fd, + nonblocking + ); socket.set_nonblocking(nonblocking); - }, - _ => { } + } + _ => {} } } @@ -864,7 +920,11 @@ pub fn fd_fdstat_set_rights( fs_rights_base: __wasi_rights_t, fs_rights_inheriting: __wasi_rights_t, ) -> __wasi_errno_t { - debug!("wasi[{}:{}]::fd_fdstat_set_rights", ctx.data().pid(), ctx.data().tid()); + debug!( + "wasi[{}:{}]::fd_fdstat_set_rights", + ctx.data().pid(), + ctx.data().tid() + ); let env = ctx.data(); let (_, mut state) = env.get_memory_and_wasi_state(&ctx, 0); let mut fd_map = state.fs.fd_map.write().unwrap(); @@ -912,7 +972,11 @@ pub(crate) fn fd_filestat_get_internal( fd: __wasi_fd_t, buf: WasmPtr<__wasi_filestat_t, M>, ) -> __wasi_errno_t { - debug!("wasi[{}:{}]::fd_filestat_get", ctx.data().pid(), ctx.data().tid()); + debug!( + "wasi[{}:{}]::fd_filestat_get", + ctx.data().pid(), + ctx.data().tid() + ); let env = ctx.data(); let (memory, mut state, inodes) = env.get_memory_and_wasi_state_and_inodes(&ctx, 0); let fd_entry = wasi_try!(state.fs.get_fd(fd)); @@ -940,7 +1004,11 @@ pub fn fd_filestat_set_size( fd: __wasi_fd_t, st_size: __wasi_filesize_t, ) -> __wasi_errno_t { - debug!("wasi[{}:{}]::fd_filestat_set_size", ctx.data().pid(), ctx.data().tid()); + debug!( + "wasi[{}:{}]::fd_filestat_set_size", + ctx.data().pid(), + ctx.data().tid() + ); let env = ctx.data(); let (_, mut state, inodes) = env.get_memory_and_wasi_state_and_inodes(&ctx, 0); let fd_entry = wasi_try!(state.fs.get_fd(fd)); @@ -992,7 +1060,11 @@ pub fn fd_filestat_set_times( st_mtim: __wasi_timestamp_t, fst_flags: __wasi_fstflags_t, ) -> __wasi_errno_t { - debug!("wasi[{}:{}]::fd_filestat_set_times", ctx.data().pid(), ctx.data().tid()); + debug!( + "wasi[{}:{}]::fd_filestat_set_times", + ctx.data().pid(), + ctx.data().tid() + ); let env = ctx.data(); let (_, mut state, inodes) = env.get_memory_and_wasi_state_and_inodes(&ctx, 0); let fd_entry = wasi_try!(state.fs.get_fd(fd)); @@ -1054,7 +1126,13 @@ pub fn fd_pread( offset: Filesize, nread: WasmPtr, ) -> Result<__wasi_errno_t, WasiError> { - trace!("wasi[{}:{}]::fd_pread: fd={}, offset={}", ctx.data().pid(), ctx.data().tid(), fd, offset); + trace!( + "wasi[{}:{}]::fd_pread: fd={}, offset={}", + ctx.data().pid(), + ctx.data().tid(), + fd, + offset + ); let env = ctx.data(); let (memory, mut state, inodes) = env.get_memory_and_wasi_state_and_inodes(&ctx, 0); @@ -1101,43 +1179,42 @@ pub fn fd_pread( } Kind::Socket { socket } => { let mut memory = env.memory_view(&ctx); - + let mut max_size = 0usize; for iovs in iovs_arr.iter() { let iovs = wasi_try_mem_ok!(iovs.read()); - let buf_len: usize = wasi_try_ok!(iovs.buf_len.try_into().map_err(|_| __WASI_EOVERFLOW)); + let buf_len: usize = + wasi_try_ok!(iovs.buf_len.try_into().map_err(|_| __WASI_EOVERFLOW)); max_size += buf_len; } let socket = socket.clone(); - let data = wasi_try_ok!( - __asyncify( - env.tasks.clone(), - &env.thread, - None, - async move { - socket.recv(max_size).await - } - ) - ); + let data = wasi_try_ok!(__asyncify( + env.tasks.clone(), + &env.thread, + None, + async move { socket.recv(max_size).await } + )); let data_len = data.len(); let mut reader = &data[..]; - let bytes_read = wasi_try_ok!( - read_bytes(reader, &memory, iovs_arr).map(|_| data_len) - ); + let bytes_read = + wasi_try_ok!(read_bytes(reader, &memory, iovs_arr).map(|_| data_len)); bytes_read } Kind::Pipe { pipe } => { let mut a; loop { - a = wasi_try_ok!(match pipe.recv(&memory, iovs_arr, Duration::from_millis(5)) { - Err(err) if err == __WASI_ETIMEDOUT => { - env.yield_now()?; - continue; + a = wasi_try_ok!( + match pipe.recv(&memory, iovs_arr, Duration::from_millis(5)) { + Err(err) if err == __WASI_ETIMEDOUT => { + env.yield_now()?; + continue; + } + a => a, }, - a => a - }, env); + env + ); break; } a @@ -1173,18 +1250,24 @@ pub fn fd_prestat_get( fd: __wasi_fd_t, buf: WasmPtr<__wasi_prestat_t, M>, ) -> __wasi_errno_t { - trace!("wasi[{}:{}]::fd_prestat_get: fd={}", ctx.data().pid(), ctx.data().tid(), fd); + trace!( + "wasi[{}:{}]::fd_prestat_get: fd={}", + ctx.data().pid(), + ctx.data().tid(), + fd + ); let env = ctx.data(); let (memory, mut state, inodes) = env.get_memory_and_wasi_state_and_inodes(&ctx, 0); let prestat_ptr = buf.deref(&memory); - wasi_try_mem!(prestat_ptr.write(wasi_try!( - state.fs.prestat_fd(inodes.deref(), fd) - .map_err(|code| { + wasi_try_mem!( + prestat_ptr.write(wasi_try!(state.fs.prestat_fd(inodes.deref(), fd).map_err( + |code| { debug!("fd_prestat_get failed (fd={}) - errno={}", fd, code); code - }) - ))); + } + ))) + ); Errno::Success } @@ -1197,7 +1280,8 @@ pub fn fd_prestat_dir_name( ) -> Errno { trace!( "wasi[{}:{}]::fd_prestat_dir_name: fd={}, path_len={}", - ctx.data().pid(), ctx.data().tid(), + ctx.data().pid(), + ctx.data().tid(), fd, path_len ); @@ -1316,21 +1400,18 @@ pub fn fd_pwrite( .filter_map(|a| a.read().ok()) .map(|a| a.buf_len) .sum(); - let buf_len: usize = wasi_try_ok!(buf_len.try_into().map_err(|_| __WASI_EINVAL)); + let buf_len: usize = + wasi_try_ok!(buf_len.try_into().map_err(|_| __WASI_EINVAL)); let mut buf = Vec::with_capacity(buf_len); wasi_try_ok!(write_bytes(&mut buf, &memory, iovs_arr)); let socket = socket.clone(); - wasi_try_ok!( - __asyncify( - env.tasks.clone(), - &env.thread, - None, - async move { - socket.send(buf).await - } - ) - ) + wasi_try_ok!(__asyncify( + env.tasks.clone(), + &env.thread, + None, + async move { socket.send(buf).await } + )) } Kind::Pipe { pipe } => { wasi_try_ok!(pipe.send(&memory, iovs_arr), env) @@ -1378,7 +1459,12 @@ pub fn fd_read( iovs_len: M::Offset, nread: WasmPtr, ) -> Result<__wasi_errno_t, WasiError> { - trace!("wasi[{}:{}]::fd_read: fd={}", ctx.data().pid(), ctx.data().tid(), fd); + trace!( + "wasi[{}:{}]::fd_read: fd={}", + ctx.data().pid(), + ctx.data().tid(), + fd + ); ctx.data().clone().process_signals(&mut ctx)?; @@ -1393,7 +1479,7 @@ pub fn fd_read( __WASI_STDERR_FILENO => return Ok(__WASI_EINVAL), _ => false, }; - + let fd_entry = wasi_try_ok!(state.fs.get_fd(fd)); let bytes_read = { let inodes = inodes.read().unwrap(); @@ -1442,31 +1528,27 @@ pub fn fd_read( Kind::Socket { socket } => { let mut memory = env.memory_view(&ctx); let iovs_arr = wasi_try_mem_ok!(iovs.slice(&memory, iovs_len)); - + let mut max_size = 0usize; for iovs in iovs_arr.iter() { let iovs = wasi_try_mem_ok!(iovs.read()); - let buf_len: usize = wasi_try_ok!(iovs.buf_len.try_into().map_err(|_| __WASI_EOVERFLOW)); + let buf_len: usize = + wasi_try_ok!(iovs.buf_len.try_into().map_err(|_| __WASI_EOVERFLOW)); max_size += buf_len; } let socket = socket.clone(); - let data = wasi_try_ok!( - __asyncify( - env.tasks.clone(), - &env.thread, - None, - async move { - socket.recv(max_size).await - } - ) - ); + let data = wasi_try_ok!(__asyncify( + env.tasks.clone(), + &env.thread, + None, + async move { socket.recv(max_size).await } + )); let data_len = data.len(); let mut reader = &data[..]; - let bytes_read = wasi_try_ok!( - read_bytes(reader, &memory, iovs_arr - ).map(|_| data_len)); + let bytes_read = + wasi_try_ok!(read_bytes(reader, &memory, iovs_arr).map(|_| data_len)); bytes_read } Kind::Pipe { pipe } => { @@ -1474,14 +1556,17 @@ pub fn fd_read( loop { let mut memory = env.memory_view(&ctx); let iovs_arr = wasi_try_mem_ok!(iovs.slice(&memory, iovs_len)); - a = wasi_try_ok!(match pipe.recv(&memory, iovs_arr, Duration::from_millis(50)) { - Err(err) if err == __WASI_ETIMEDOUT => { - env.clone().process_signals(&mut ctx)?; - env = ctx.data(); - continue; + a = wasi_try_ok!( + match pipe.recv(&memory, iovs_arr, Duration::from_millis(50)) { + Err(err) if err == __WASI_ETIMEDOUT => { + env.clone().process_signals(&mut ctx)?; + env = ctx.data(); + continue; + } + a => a, }, - a => a - }, env); + env + ); break; } a @@ -1514,21 +1599,13 @@ pub fn fd_read( if val > 0 { let new_val = if is_semaphore { val - 1 } else { 0 }; if counter - .compare_exchange( - val, - new_val, - Ordering::AcqRel, - Ordering::Acquire, - ) + .compare_exchange(val, new_val, Ordering::AcqRel, Ordering::Acquire) .is_ok() { let mut memory = env.memory_view(&ctx); let reader = val.to_ne_bytes(); let iovs_arr = wasi_try_mem_ok!(iovs.slice(&memory, iovs_len)); - ret = wasi_try_ok!( - read_bytes(&reader[..], &memory, iovs_arr), - env - ); + ret = wasi_try_ok!(read_bytes(&reader[..], &memory, iovs_arr), env); break; } else { continue; @@ -1562,15 +1639,22 @@ pub fn fd_read( // reborrow let mut fd_map = state.fs.fd_map.write().unwrap(); let fd_entry = wasi_try_ok!(fd_map.get_mut(&fd).ok_or(__WASI_EBADF)); - fd_entry.offset.fetch_add(bytes_read as u64, Ordering::AcqRel); + fd_entry + .offset + .fetch_add(bytes_read as u64, Ordering::AcqRel); } bytes_read }; let bytes_read: M::Offset = wasi_try_ok!(bytes_read.try_into().map_err(|_| __WASI_EOVERFLOW)); - trace!("wasi[{}:{}]::fd_read: bytes_read={}", ctx.data().pid(), ctx.data().tid(), bytes_read); - + trace!( + "wasi[{}:{}]::fd_read: bytes_read={}", + ctx.data().pid(), + ctx.data().tid(), + bytes_read + ); + let env = ctx.data(); let memory = env.memory_view(&ctx); let nread_ref = nread.deref(&memory); @@ -1602,7 +1686,11 @@ pub fn fd_readdir( cookie: Dircookie, bufused: WasmPtr, ) -> __wasi_errno_t { - trace!("wasi[{}:{}]::fd_readdir", ctx.data().pid(), ctx.data().tid()); + trace!( + "wasi[{}:{}]::fd_readdir", + ctx.data().pid(), + ctx.data().tid() + ); let env = ctx.data(); let (memory, mut state, inodes) = env.get_memory_and_wasi_state_and_inodes(&ctx, 0); // TODO: figure out how this is supposed to work; @@ -1732,7 +1820,13 @@ pub fn fd_renumber( from: __wasi_fd_t, to: __wasi_fd_t, ) -> __wasi_errno_t { - debug!("wasi[{}:{}]::fd_renumber(from={}, to={})", ctx.data().pid(), ctx.data().tid(), from, to); + debug!( + "wasi[{}:{}]::fd_renumber(from={}, to={})", + ctx.data().pid(), + ctx.data().tid(), + from, + to + ); if from == to { return __WASI_ESUCCESS; @@ -1761,7 +1855,7 @@ pub fn fd_renumber( } } fd_map.insert(to, new_fd_entry); - + __WASI_ESUCCESS } @@ -1806,19 +1900,25 @@ pub fn fd_event( counter: Arc::new(AtomicU64::new(initial_val)), is_semaphore: flags & EVENT_FD_FLAGS_SEMAPHORE != 0, wakers: Default::default(), - immediate: Arc::new(AtomicBool::new(false)) + immediate: Arc::new(AtomicBool::new(false)), }; - let inode = state.fs.create_inode_with_default_stat( - inodes.deref_mut(), - kind, - false, - "event".into(), - ); - let rights = __WASI_RIGHT_FD_READ | __WASI_RIGHT_FD_WRITE | __WASI_RIGHT_POLL_FD_READWRITE | __WASI_RIGHT_FD_FDSTAT_SET_FLAGS; + let inode = + state + .fs + .create_inode_with_default_stat(inodes.deref_mut(), kind, false, "event".into()); + let rights = __WASI_RIGHT_FD_READ + | __WASI_RIGHT_FD_WRITE + | __WASI_RIGHT_POLL_FD_READWRITE + | __WASI_RIGHT_FD_FDSTAT_SET_FLAGS; let fd = wasi_try!(state.fs.create_fd(rights, rights, 0, 0, inode)); - debug!("wasi[{}:{}]::fd_event - event notifications created (fd={})", ctx.data().pid(), ctx.data().tid(), fd); + debug!( + "wasi[{}:{}]::fd_event - event notifications created (fd={})", + ctx.data().pid(), + ctx.data().tid(), + fd + ); wasi_try_mem!(ret_fd.write(&memory, fd)); Errno::Success @@ -1843,7 +1943,13 @@ pub fn fd_seek( whence: __wasi_whence_t, newoffset: WasmPtr<__wasi_filesize_t, M>, ) -> Result<__wasi_errno_t, WasiError> { - trace!("wasi[{}:{}]::fd_seek: fd={}, offset={}", ctx.data().pid(), ctx.data().tid(), fd, offset); + trace!( + "wasi[{}:{}]::fd_seek: fd={}, offset={}", + ctx.data().pid(), + ctx.data().tid(), + fd, + offset + ); let env = ctx.data(); let (memory, mut state, inodes) = env.get_memory_and_wasi_state_and_inodes(&ctx, 0); let new_offset_ref = newoffset.deref(&memory); @@ -1861,7 +1967,9 @@ pub fn fd_seek( if offset > 0 { fd_entry.offset.fetch_add(offset as u64, Ordering::AcqRel) } else if offset < 0 { - fd_entry.offset.fetch_sub(offset.abs() as u64, Ordering::AcqRel) + fd_entry + .offset + .fetch_sub(offset.abs() as u64, Ordering::AcqRel) } else { fd_entry.offset.load(Ordering::Acquire) } @@ -1882,7 +1990,9 @@ pub fn fd_seek( drop(guard); let mut fd_map = state.fs.fd_map.write().unwrap(); let fd_entry = wasi_try_ok!(fd_map.get_mut(&fd).ok_or(__WASI_EBADF)); - fd_entry.offset.store((end as i64 + offset) as u64, Ordering::Release); + fd_entry + .offset + .store((end as i64 + offset) as u64, Ordering::Release); } else { return Ok(Errno::Inval); } @@ -2015,7 +2125,12 @@ pub fn fd_write( iovs_len: M::Offset, nwritten: WasmPtr, ) -> Result<__wasi_errno_t, WasiError> { - trace!("wasi[{}:{}]::fd_write: fd={}", ctx.data().pid(), ctx.data().tid(), fd); + trace!( + "wasi[{}:{}]::fd_write: fd={}", + ctx.data().pid(), + ctx.data().tid(), + fd + ); let env = ctx.data(); let (memory, mut state, inodes) = env.get_memory_and_wasi_state_and_inodes(&ctx, 0); let iovs_arr = wasi_try_mem_ok!(iovs.slice(&memory, iovs_len)); @@ -2030,7 +2145,7 @@ pub fn fd_write( _ => false, }; - let bytes_written ={ + let bytes_written = { if is_stdio == false { if !has_rights(fd_entry.rights, __WASI_RIGHT_FD_WRITE) { return Ok(__WASI_EACCES); @@ -2066,21 +2181,18 @@ pub fn fd_write( .filter_map(|a| a.read().ok()) .map(|a| a.buf_len) .sum(); - let buf_len: usize = wasi_try_ok!(buf_len.try_into().map_err(|_| __WASI_EINVAL)); + let buf_len: usize = + wasi_try_ok!(buf_len.try_into().map_err(|_| __WASI_EINVAL)); let mut buf = Vec::with_capacity(buf_len); wasi_try_ok!(write_bytes(&mut buf, &memory, iovs_arr)); let socket = socket.clone(); - wasi_try_ok!( - __asyncify( - env.tasks.clone(), - &env.thread, - None, - async move { - socket.send(buf).await - } - ) - ) + wasi_try_ok!(__asyncify( + env.tasks.clone(), + &env.thread, + None, + async move { socket.send(buf).await } + )) } Kind::Pipe { pipe } => { wasi_try_ok!(pipe.send(&memory, iovs_arr), env) @@ -2090,11 +2202,13 @@ pub fn fd_write( return Ok(__WASI_EISDIR); } Kind::EventNotifications { - counter, wakers, immediate, .. + counter, + wakers, + immediate, + .. } => { let mut val = 0u64.to_ne_bytes(); - let written = - wasi_try_ok!(write_bytes(&mut val[..], &memory, iovs_arr)); + let written = wasi_try_ok!(write_bytes(&mut val[..], &memory, iovs_arr)); if written != val.len() { return Ok(__WASI_EINVAL); } @@ -2113,10 +2227,7 @@ pub fn fd_write( } Kind::Symlink { .. } => unimplemented!("Symlinks in wasi::fd_write"), Kind::Buffer { buffer } => { - wasi_try_ok!( - write_bytes(&mut buffer[offset..], &memory, iovs_arr), - env - ) + wasi_try_ok!(write_bytes(&mut buffer[offset..], &memory, iovs_arr), env) } } }; @@ -2126,7 +2237,9 @@ pub fn fd_write( { let mut fd_map = state.fs.fd_map.write().unwrap(); let fd_entry = wasi_try_ok!(fd_map.get_mut(&fd).ok_or(__WASI_EBADF)); - fd_entry.offset.fetch_add(bytes_written as u64, Ordering::AcqRel); + fd_entry + .offset + .fetch_add(bytes_written as u64, Ordering::AcqRel); } // we set teh size but we don't return any errors if it fails as @@ -2181,7 +2294,13 @@ pub fn fd_pipe( let rights = super::state::all_socket_rights(); let fd1 = wasi_try!(state.fs.create_fd(rights, rights, 0, 0, inode1)); let fd2 = wasi_try!(state.fs.create_fd(rights, rights, 0, 0, inode2)); - trace!("wasi[{}:{}]::fd_pipe (fd1={}, fd2={})", ctx.data().pid(), ctx.data().tid(), fd1, fd2); + trace!( + "wasi[{}:{}]::fd_pipe (fd1={}, fd2={})", + ctx.data().pid(), + ctx.data().tid(), + fd1, + fd2 + ); wasi_try_mem!(ro_fd1.write(&memory, fd1)); wasi_try_mem!(ro_fd2.write(&memory, fd2)); @@ -2208,7 +2327,11 @@ pub fn path_create_directory( path: WasmPtr, path_len: M::Offset, ) -> __wasi_errno_t { - debug!("wasi[{}:{}]::path_create_directory", ctx.data().pid(), ctx.data().tid()); + debug!( + "wasi[{}:{}]::path_create_directory", + ctx.data().pid(), + ctx.data().tid() + ); let env = ctx.data(); let (memory, state, mut inodes) = env.get_memory_and_wasi_state_and_inodes_mut(&ctx, 0); @@ -2224,11 +2347,16 @@ pub fn path_create_directory( } let mut path_string = unsafe { get_input_str!(&memory, path, path_len) }; debug!("=> fd: {}, path: {}", fd, &path_string); - + // Convert relative paths into absolute paths if path_string.starts_with("./") { path_string = ctx.data().state.fs.relative_path_to_absolute(path_string); - trace!("wasi[{}:{}]::rel_to_abs (name={}))", ctx.data().pid(), ctx.data().tid(), path_string); + trace!( + "wasi[{}:{}]::rel_to_abs (name={}))", + ctx.data().pid(), + ctx.data().tid(), + path_string + ); } let path = std::path::PathBuf::from(&path_string); @@ -2348,12 +2476,23 @@ pub fn path_filestat_get( let (memory, mut state, mut inodes) = env.get_memory_and_wasi_state_and_inodes_mut(&ctx, 0); let mut path_string = unsafe { get_input_str!(&memory, path, path_len) }; - debug!("wasi[{}:{}]::path_filestat_get (fd={}, path={})", ctx.data().pid(), ctx.data().tid(), fd, path_string); + debug!( + "wasi[{}:{}]::path_filestat_get (fd={}, path={})", + ctx.data().pid(), + ctx.data().tid(), + fd, + path_string + ); // Convert relative paths into absolute paths if path_string.starts_with("./") { path_string = ctx.data().state.fs.relative_path_to_absolute(path_string); - trace!("wasi[{}:{}]::rel_to_abs (name={}))", ctx.data().pid(), ctx.data().tid(), path_string); + trace!( + "wasi[{}:{}]::rel_to_abs (name={}))", + ctx.data().pid(), + ctx.data().tid(), + path_string + ); } let stat = wasi_try!(path_filestat_get_internal( @@ -2397,7 +2536,7 @@ pub fn path_filestat_get_internal( if !root_dir.rights.contains(Rights::PATH_FILESTAT_GET) { return Err(Errno::Access); } - + let file_inode = state.fs.get_inode_at_path( inodes, fd, @@ -2439,7 +2578,11 @@ pub fn path_filestat_set_times( st_mtim: __wasi_timestamp_t, fst_flags: __wasi_fstflags_t, ) -> __wasi_errno_t { - debug!("wasi[{}:{}]::path_filestat_set_times", ctx.data().pid(), ctx.data().tid()); + debug!( + "wasi[{}:{}]::path_filestat_set_times", + ctx.data().pid(), + ctx.data().tid() + ); let env = ctx.data(); let (memory, mut state, mut inodes) = env.get_memory_and_wasi_state_and_inodes_mut(&ctx, 0); let fd_entry = wasi_try!(state.fs.get_fd(fd)); @@ -2459,7 +2602,12 @@ pub fn path_filestat_set_times( // Convert relative paths into absolute paths if path_string.starts_with("./") { path_string = ctx.data().state.fs.relative_path_to_absolute(path_string); - trace!("wasi[{}:{}]::rel_to_abs (name={}))", ctx.data().pid(), ctx.data().tid(), path_string); + trace!( + "wasi[{}:{}]::rel_to_abs (name={}))", + ctx.data().pid(), + ctx.data().tid(), + path_string + ); } let file_inode = wasi_try!(state.fs.get_inode_at_path( @@ -2657,7 +2805,12 @@ pub fn path_open( // Convert relative paths into absolute paths if path_string.starts_with("./") { path_string = ctx.data().state.fs.relative_path_to_absolute(path_string); - trace!("wasi[{}:{}]::rel_to_abs (name={}))", ctx.data().pid(), ctx.data().tid(), path_string); + trace!( + "wasi[{}:{}]::rel_to_abs (name={}))", + ctx.data().pid(), + ctx.data().tid(), + path_string + ); } let path_arg = std::path::PathBuf::from(&path_string); @@ -2767,12 +2920,10 @@ pub fn path_open( if minimum_rights.truncate { open_flags |= Fd::TRUNCATE; } - *handle = Some( - Arc::new(std::sync::RwLock::new( - wasi_try!(open_options.open(&path).map_err(fs_error_into_wasi_err)) - )) - ); - + *handle = Some(Arc::new(std::sync::RwLock::new(wasi_try!(open_options + .open(&path) + .map_err(fs_error_into_wasi_err))))); + if let Some(handle) = handle { let handle = handle.read().unwrap(); if let Some(special_fd) = handle.get_special_fd() { @@ -2911,7 +3062,12 @@ pub fn path_open( )); wasi_try_mem!(fd_ref.write(out_fd)); - debug!("wasi[{}:{}]::path_open returning fd {}", ctx.data().pid(), ctx.data().tid(), out_fd); + debug!( + "wasi[{}:{}]::path_open returning fd {}", + ctx.data().pid(), + ctx.data().tid(), + out_fd + ); Errno::Success } @@ -2941,7 +3097,11 @@ pub fn path_readlink( buf_len: M::Offset, buf_used: WasmPtr, ) -> __wasi_errno_t { - debug!("wasi[{}:{}]::path_readlink", ctx.data().pid(), ctx.data().tid()); + debug!( + "wasi[{}:{}]::path_readlink", + ctx.data().pid(), + ctx.data().tid() + ); let env = ctx.data(); let (memory, mut state, mut inodes) = env.get_memory_and_wasi_state_and_inodes_mut(&ctx, 0); @@ -2954,7 +3114,12 @@ pub fn path_readlink( // Convert relative paths into absolute paths if path_str.starts_with("./") { path_str = ctx.data().state.fs.relative_path_to_absolute(path_str); - trace!("wasi[{}:{}]::rel_to_abs (name={}))", ctx.data().pid(), ctx.data().tid(), path_str); + trace!( + "wasi[{}:{}]::rel_to_abs (name={}))", + ctx.data().pid(), + ctx.data().tid(), + path_str + ); } let inode = wasi_try!(state @@ -2973,8 +3138,7 @@ pub fn path_readlink( } let bytes: Vec<_> = bytes.collect(); - let out = - wasi_try_mem!(buf.slice(&memory, wasi_try!(to_offset::(bytes.len())))); + let out = wasi_try_mem!(buf.slice(&memory, wasi_try!(to_offset::(bytes.len())))); wasi_try_mem!(out.write_slice(&bytes)); // should we null terminate this? @@ -2997,7 +3161,11 @@ pub fn path_remove_directory( path_len: M::Offset, ) -> Errno { // TODO check if fd is a dir, ensure it's within sandbox, etc. - debug!("wasi[{}:{}]::path_remove_directory", ctx.data().pid(), ctx.data().tid()); + debug!( + "wasi[{}:{}]::path_remove_directory", + ctx.data().pid(), + ctx.data().tid() + ); let env = ctx.data(); let (memory, mut state, mut inodes) = env.get_memory_and_wasi_state_and_inodes_mut(&ctx, 0); @@ -3007,7 +3175,12 @@ pub fn path_remove_directory( // Convert relative paths into absolute paths if path_str.starts_with("./") { path_str = ctx.data().state.fs.relative_path_to_absolute(path_str); - trace!("wasi[{}:{}]::rel_to_abs (name={}))", ctx.data().pid(), ctx.data().tid(), path_str); + trace!( + "wasi[{}:{}]::rel_to_abs (name={}))", + ctx.data().pid(), + ctx.data().tid(), + path_str + ); } let inode = wasi_try!(state @@ -3269,7 +3442,11 @@ pub fn path_symlink( new_path: WasmPtr, new_path_len: M::Offset, ) -> __wasi_errno_t { - debug!("wasi[{}:{}]::path_symlink", ctx.data().pid(), ctx.data().tid()); + debug!( + "wasi[{}:{}]::path_symlink", + ctx.data().pid(), + ctx.data().tid() + ); let env = ctx.data(); let (memory, mut state, mut inodes) = env.get_memory_and_wasi_state_and_inodes_mut(&ctx, 0); let mut old_path_str = unsafe { get_input_str!(&memory, old_path, old_path_len) }; @@ -3374,7 +3551,11 @@ pub fn path_unlink_file( path: WasmPtr, path_len: M::Offset, ) -> __wasi_errno_t { - debug!("wasi[{}:{}]::path_unlink_file", ctx.data().pid(), ctx.data().tid()); + debug!( + "wasi[{}:{}]::path_unlink_file", + ctx.data().pid(), + ctx.data().tid() + ); let env = ctx.data(); let (memory, mut state, mut inodes) = env.get_memory_and_wasi_state_and_inodes_mut(&ctx, 0); @@ -3388,7 +3569,12 @@ pub fn path_unlink_file( // Convert relative paths into absolute paths if path_str.starts_with("./") { path_str = ctx.data().state.fs.relative_path_to_absolute(path_str); - trace!("wasi[{}:{}]::rel_to_abs (name={}))", ctx.data().pid(), ctx.data().tid(), path_str); + trace!( + "wasi[{}:{}]::rel_to_abs (name={}))", + ctx.data().pid(), + ctx.data().tid(), + path_str + ); } let inode = wasi_try!(state @@ -3494,10 +3680,14 @@ pub fn poll_oneoff( nsubscriptions: M::Offset, nevents: WasmPtr, ) -> Result<__wasi_errno_t, WasiError> { - let pid = ctx.data().pid(); let tid = ctx.data().tid(); - trace!("wasi[{}:{}]::poll_oneoff (nsubscriptions={})", pid, tid, nsubscriptions); + trace!( + "wasi[{}:{}]::poll_oneoff (nsubscriptions={})", + pid, + tid, + nsubscriptions + ); // These are used when we capture what clocks (timeouts) are being // subscribed too @@ -3566,10 +3756,15 @@ pub fn poll_oneoff( // If there is a timeout we need to use the runtime to measure this // otherwise we just process all the events and wait on them indefinately if let Some(time_to_sleep) = time_to_sleep.as_ref() { - tracing::trace!("wasi[{}:{}]::poll_oneoff wait_for_timeout={}", pid, tid, time_to_sleep.as_millis()); + tracing::trace!( + "wasi[{}:{}]::poll_oneoff wait_for_timeout={}", + pid, + tid, + time_to_sleep.as_millis() + ); } let time_to_sleep = time_to_sleep; - + let mut events_seen: u32 = 0; // Build the async function we will block on @@ -3587,32 +3782,26 @@ pub fn poll_oneoff( let mut fd_guards = vec![]; #[allow(clippy::significant_drop_in_scrutinee)] - let fds = { + let fds = { for (fd, in_events) in subscriptions { let wasi_file_ref = match fd { __WASI_STDERR_FILENO => { - wasi_try_ok!( - inodes - .stderr(&state.fs.fd_map) - .map(|g| g.into_poll_guard(fd, in_events, tasks.clone())) - .map_err(fs_error_into_wasi_err) - ) + wasi_try_ok!(inodes + .stderr(&state.fs.fd_map) + .map(|g| g.into_poll_guard(fd, in_events, tasks.clone())) + .map_err(fs_error_into_wasi_err)) } __WASI_STDIN_FILENO => { - wasi_try_ok!( - inodes - .stdin(&state.fs.fd_map) - .map(|g| g.into_poll_guard(fd, in_events, tasks.clone())) - .map_err(fs_error_into_wasi_err) - ) + wasi_try_ok!(inodes + .stdin(&state.fs.fd_map) + .map(|g| g.into_poll_guard(fd, in_events, tasks.clone())) + .map_err(fs_error_into_wasi_err)) } __WASI_STDOUT_FILENO => { - wasi_try_ok!( - inodes - .stdout(&state.fs.fd_map) - .map(|g| g.into_poll_guard(fd, in_events, tasks.clone())) - .map_err(fs_error_into_wasi_err) - ) + wasi_try_ok!(inodes + .stdout(&state.fs.fd_map) + .map(|g| g.into_poll_guard(fd, in_events, tasks.clone())) + .map_err(fs_error_into_wasi_err)) } _ => { let fd_entry = wasi_try_ok!(state.fs.get_fd(fd)); @@ -3623,7 +3812,12 @@ pub fn poll_oneoff( { let guard = inodes.arena[inode].read(); - if let Some(guard) = crate::state::InodeValFilePollGuard::new(fd, guard.deref(), in_events, tasks.clone()) { + if let Some(guard) = crate::state::InodeValFilePollGuard::new( + fd, + guard.deref(), + in_events, + tasks.clone(), + ) { guard } else { return Ok(Errno::Badf); @@ -3631,17 +3825,22 @@ pub fn poll_oneoff( } } }; - tracing::trace!("wasi[{}:{}]::poll_oneoff wait_for_fd={} type={:?}", pid, tid, fd, wasi_file_ref); + tracing::trace!( + "wasi[{}:{}]::poll_oneoff wait_for_fd={} type={:?}", + pid, + tid, + fd, + wasi_file_ref + ); fd_guards.push(wasi_file_ref); } - + fd_guards }; - + // Build all the async calls we need for all the files let mut polls = Vec::new(); - for guard in fds - { + for guard in fds { // Combine all the events together let mut peb = PollEventBuilder::new(); for (in_events, _) in guard.subscriptions.iter() { @@ -3661,10 +3860,14 @@ pub fn poll_oneoff( // that we can give to the caller let evts = guard.wait().await; for evt in evts { - tracing::trace!("wasi[{}:{}]::poll_oneoff (fd_triggered={}, type={})", pid, tid, guard.fd, evt.type_); - triggered_events_tx - .send(evt) - .unwrap(); + tracing::trace!( + "wasi[{}:{}]::poll_oneoff (fd_triggered={}, type={})", + pid, + tid, + guard.fd, + evt.type_ + ); + triggered_events_tx.send(evt).unwrap(); } }); polls.push(poll); @@ -3686,14 +3889,9 @@ pub fn poll_oneoff( // Block on the work and process process let env = ctx.data(); - let mut ret = __asyncify( - env.tasks.clone(), - &env.thread, - time_to_sleep, - async move { - work.await - } - ); + let mut ret = __asyncify(env.tasks.clone(), &env.thread, time_to_sleep, async move { + work.await + }); // If its a timeout then return an event for it if let Err(__WASI_ETIMEDOUT) = ret { @@ -3701,8 +3899,8 @@ pub fn poll_oneoff( // The timeout has triggerred so lets add that event for (clock_info, userdata) in clock_subs { - triggered_events_tx.send( - __wasi_event_t { + triggered_events_tx + .send(__wasi_event_t { userdata, error: __WASI_ESUCCESS, type_: __WASI_EVENTTYPE_CLOCK, @@ -3714,8 +3912,8 @@ pub fn poll_oneoff( }, } }, - } - ).unwrap(); + }) + .unwrap(); } ret = Ok(__WASI_ESUCCESS); } @@ -3727,7 +3925,7 @@ pub fn poll_oneoff( ret = Ok(__WASI_ESUCCESS); } let ret = wasi_try_ok!(ret); - + // Process all the events that were triggered let mut env = ctx.data(); let memory = env.memory_view(&ctx); @@ -3739,7 +3937,13 @@ pub fn poll_oneoff( let events_seen: M::Offset = wasi_try_ok!(events_seen.try_into().map_err(|_| __WASI_EOVERFLOW)); let out_ptr = nevents.deref(&memory); wasi_try_mem_ok!(out_ptr.write(events_seen)); - tracing::trace!("wasi[{}:{}]::poll_oneoff ret={} seen={}", pid, tid, ret, events_seen); + tracing::trace!( + "wasi[{}:{}]::poll_oneoff ret={} seen={}", + pid, + tid, + ret, + events_seen + ); Ok(ret) } @@ -3754,14 +3958,18 @@ pub fn proc_exit( mut ctx: FunctionEnvMut<'_, WasiEnv>, code: __wasi_exitcode_t, ) -> Result<(), WasiError> { - debug!("wasi[{}:{}]::proc_exit (code={})", ctx.data().pid(), ctx.data().tid(), code); - + debug!( + "wasi[{}:{}]::proc_exit (code={})", + ctx.data().pid(), + ctx.data().tid(), + code + ); + // Set the exit code for this process ctx.data().thread.terminate(code as u32); // If we are in a vfork we need to return to the point we left off - if let Some(mut vfork) = ctx.data_mut().vfork.take() - { + if let Some(mut vfork) = ctx.data_mut().vfork.take() { // Restore the WasiEnv to the point when we vforked std::mem::swap(&mut vfork.env.inner, &mut ctx.data_mut().inner); std::mem::swap(vfork.env.as_mut(), ctx.data_mut()); @@ -3778,15 +3986,14 @@ pub fn proc_exit( // If the return value offset is within the memory stack then we need // to update it here rather than in the real memory let pid_offset: u64 = vfork.pid_offset.into(); - if pid_offset >= wasi_env.stack_start && pid_offset < wasi_env.stack_base - { + if pid_offset >= wasi_env.stack_start && pid_offset < wasi_env.stack_base { // Make sure its within the "active" part of the memory stack let offset = wasi_env.stack_base - pid_offset; if offset as usize > memory_stack.len() { warn!("wasi[{}:{}]::vfork failed - the return value (pid) is outside of the active part of the memory stack ({} vs {})", ctx.data().pid(), ctx.data().tid(), offset, memory_stack.len()); return Err(WasiError::Exit(__WASI_EFAULT as u32)); } - + // Update the memory stack with the new PID let val_bytes = pid.raw().to_ne_bytes(); let pstart = memory_stack.len() - offset as usize; @@ -3799,10 +4006,14 @@ pub fn proc_exit( } // Jump back to the vfork point and current on execution - unwind::(ctx, move |mut ctx, _, _| - { + unwind::(ctx, move |mut ctx, _, _| { // Now rewind the previous stack and carry on from where we did the vfork - match rewind::(ctx, memory_stack.freeze(), rewind_stack.freeze(), store_data) { + match rewind::( + ctx, + memory_stack.freeze(), + rewind_stack.freeze(), + store_data, + ) { __WASI_ESUCCESS => OnCalledAction::InvokeAgain, err => { warn!("fork failed - could not rewind the stack - errno={}", err); @@ -3827,14 +4038,20 @@ pub fn proc_exit( pub fn thread_signal( mut ctx: FunctionEnvMut<'_, WasiEnv>, tid: __wasi_tid_t, - sig: __wasi_signal_t + sig: __wasi_signal_t, ) -> Result<__wasi_errno_t, WasiError> { - debug!("wasi[{}:{}]::thread_signal(tid={}, sig={})", ctx.data().pid(), ctx.data().tid(), tid, sig); + debug!( + "wasi[{}:{}]::thread_signal(tid={}, sig={})", + ctx.data().pid(), + ctx.data().tid(), + tid, + sig + ); { let tid: WasiThreadId = tid.into(); ctx.data().process.signal_thread(&tid, sig); } - + let env = ctx.data(); env.clone().yield_now_with_signals(&mut ctx)?; @@ -3845,9 +4062,15 @@ pub fn thread_signal( pub fn thread_signal( mut ctx: FunctionEnvMut<'_, WasiEnv>, tid: __wasi_tid_t, - sig: __wasi_signal_t + sig: __wasi_signal_t, ) -> Result<__wasi_errno_t, WasiError> { - warn!("wasi[{}:{}]::thread_signal(tid={}, sig={}) are not supported without the 'os' feature", ctx.data().pid(), ctx.data().tid(), tid, sig); + warn!( + "wasi[{}:{}]::thread_signal(tid={}, sig={}) are not supported without the 'os' feature", + ctx.data().pid(), + ctx.data().tid(), + tid, + sig + ); Ok(__WASI_ENOTSUP) } @@ -3859,9 +4082,14 @@ pub fn thread_signal( /// Signal to be raised for this process pub fn proc_raise( mut ctx: FunctionEnvMut<'_, WasiEnv>, - sig: __wasi_signal_t + sig: __wasi_signal_t, ) -> Result<__wasi_errno_t, WasiError> { - debug!("wasi[{}:{}]::proc_raise (sig={})", ctx.data().pid(), ctx.data().tid(), sig); + debug!( + "wasi[{}:{}]::proc_raise (sig={})", + ctx.data().pid(), + ctx.data().tid(), + sig + ); let env = ctx.data(); env.process.signal_process(sig); env.clone().yield_now_with_signals(&mut ctx)?; @@ -3880,15 +4108,20 @@ pub fn proc_raise_interval( interval: __wasi_timestamp_t, repeat: __wasi_bool_t, ) -> Result<__wasi_errno_t, WasiError> { - debug!("wasi[{}:{}]::proc_raise_interval (sig={})", ctx.data().pid(), ctx.data().tid(), sig); + debug!( + "wasi[{}:{}]::proc_raise_interval (sig={})", + ctx.data().pid(), + ctx.data().tid(), + sig + ); let env = ctx.data(); let interval = match interval { 0 => None, - a => Some(Duration::from_millis(a)) + a => Some(Duration::from_millis(a)), }; let repeat = match repeat { __WASI_BOOL_TRUE => true, - _ => false + _ => false, }; env.process.signal_interval(sig, interval, repeat); env.clone().yield_now_with_signals(&mut ctx)?; @@ -3898,31 +4131,22 @@ pub fn proc_raise_interval( /// ### `sched_yield()` /// Yields execution of the thread -pub fn sched_yield( - mut ctx: FunctionEnvMut<'_, WasiEnv> -) -> Result<__wasi_errno_t, WasiError> { +pub fn sched_yield(mut ctx: FunctionEnvMut<'_, WasiEnv>) -> Result<__wasi_errno_t, WasiError> { //trace!("wasi[{}:{}]::sched_yield", ctx.data().pid(), ctx.data().tid()); let env = ctx.data(); env.clone().yield_now_with_signals(&mut ctx)?; Ok(__WASI_ESUCCESS) } -fn get_stack_base( - mut ctx: &mut FunctionEnvMut<'_, WasiEnv>, -) -> u64 { +fn get_stack_base(mut ctx: &mut FunctionEnvMut<'_, WasiEnv>) -> u64 { ctx.data().stack_base } -fn get_stack_start( - mut ctx: &mut FunctionEnvMut<'_, WasiEnv>, -) -> u64 { +fn get_stack_start(mut ctx: &mut FunctionEnvMut<'_, WasiEnv>) -> u64 { ctx.data().stack_start } -fn get_memory_stack_pointer( - ctx: &mut FunctionEnvMut<'_, WasiEnv>, -) -> Result -{ +fn get_memory_stack_pointer(ctx: &mut FunctionEnvMut<'_, WasiEnv>) -> Result { // Get the current value of the stack pointer (which we will use // to save all of the stack) let stack_base = get_stack_base(ctx); @@ -3930,18 +4154,17 @@ fn get_memory_stack_pointer( match stack_pointer.get(ctx) { Value::I32(a) => a as u64, Value::I64(a) => a as u64, - _ => stack_base + _ => stack_base, } } else { - return Err(format!("failed to save stack: not exported __stack_pointer global")); + return Err(format!( + "failed to save stack: not exported __stack_pointer global" + )); }; Ok(stack_pointer) } -fn get_memory_stack_offset( - ctx: &mut FunctionEnvMut<'_, WasiEnv>, -) -> Result -{ +fn get_memory_stack_offset(ctx: &mut FunctionEnvMut<'_, WasiEnv>) -> Result { let stack_base = get_stack_base(ctx); let stack_pointer = get_memory_stack_pointer(ctx)?; Ok(stack_base - stack_pointer) @@ -3950,8 +4173,7 @@ fn get_memory_stack_offset( fn set_memory_stack_offset( ctx: &mut FunctionEnvMut<'_, WasiEnv>, offset: u64, -) -> Result<(), String> -{ +) -> Result<(), String> { // Sets the stack pointer let stack_base = get_stack_base(ctx); let stack_pointer = stack_base - offset; @@ -3959,16 +4181,20 @@ fn set_memory_stack_offset( match stack_pointer_ptr.get(ctx) { Value::I32(_) => { stack_pointer_ptr.set(ctx, Value::I32(stack_pointer as i32)); - }, + } Value::I64(_) => { stack_pointer_ptr.set(ctx, Value::I64(stack_pointer as i64)); - }, + } _ => { - return Err(format!("failed to save stack: __stack_pointer global is of an unknown type")); + return Err(format!( + "failed to save stack: __stack_pointer global is of an unknown type" + )); } } } else { - return Err(format!("failed to save stack: not exported __stack_pointer global")); + return Err(format!( + "failed to save stack: not exported __stack_pointer global" + )); } Ok(()) } @@ -3984,55 +4210,61 @@ fn get_memory_stack( match stack_pointer.get(ctx) { Value::I32(a) => a as u64, Value::I64(a) => a as u64, - _ => stack_base + _ => stack_base, } } else { - return Err(format!("failed to save stack: not exported __stack_pointer global")); + return Err(format!( + "failed to save stack: not exported __stack_pointer global" + )); }; let env = ctx.data(); let memory = env.memory_view(&ctx); let stack_offset = env.stack_base - stack_pointer; // Read the memory stack into a vector - let memory_stack_ptr = WasmPtr::::new(stack_pointer.try_into().map_err(|_| { - format!("failed to save stack: stack pointer overflow") - })?); - - memory_stack_ptr.slice(&memory, stack_offset.try_into().map_err(|_| { - format!("failed to save stack: stack pointer overflow") - })?) - .and_then(|memory_stack| { - memory_stack.read_to_bytes() - }) - .map_err(|err| { - format!("failed to read stack: {}", err) - }) + let memory_stack_ptr = WasmPtr::::new( + stack_pointer + .try_into() + .map_err(|_| format!("failed to save stack: stack pointer overflow"))?, + ); + + memory_stack_ptr + .slice( + &memory, + stack_offset + .try_into() + .map_err(|_| format!("failed to save stack: stack pointer overflow"))?, + ) + .and_then(|memory_stack| memory_stack.read_to_bytes()) + .map_err(|err| format!("failed to read stack: {}", err)) } #[allow(dead_code)] fn set_memory_stack( mut ctx: &mut FunctionEnvMut<'_, WasiEnv>, - stack: Bytes + stack: Bytes, ) -> Result<(), String> { // First we restore the memory stack let stack_base = get_stack_base(ctx); let stack_offset = stack.len() as u64; let stack_pointer = stack_base - stack_offset; - let stack_ptr = WasmPtr::::new(stack_pointer.try_into().map_err(|_| { - format!("failed to restore stack: stack pointer overflow") - })?); + let stack_ptr = WasmPtr::::new( + stack_pointer + .try_into() + .map_err(|_| format!("failed to restore stack: stack pointer overflow"))?, + ); let env = ctx.data(); let memory = env.memory_view(&ctx); - stack_ptr.slice(&memory, stack_offset.try_into().map_err(|_| { - format!("failed to restore stack: stack pointer overflow") - })?) - .and_then(|memory_stack| { - memory_stack.write_slice(&stack[..]) - }) - .map_err(|err| { - format!("failed to write stack: {}", err) - })?; + stack_ptr + .slice( + &memory, + stack_offset + .try_into() + .map_err(|_| format!("failed to restore stack: stack pointer overflow"))?, + ) + .and_then(|memory_stack| memory_stack.write_slice(&stack[..])) + .map_err(|err| format!("failed to write stack: {}", err))?; // Set the stack pointer itself and return set_memory_stack_offset(ctx, stack_offset)?; @@ -4044,7 +4276,11 @@ fn unwind( mut ctx: FunctionEnvMut<'_, WasiEnv>, callback: F, ) -> Result<__wasi_errno_t, WasiError> -where F: FnOnce(FunctionEnvMut<'_, WasiEnv>, BytesMut, BytesMut) -> OnCalledAction + Send + Sync + 'static, +where + F: FnOnce(FunctionEnvMut<'_, WasiEnv>, BytesMut, BytesMut) -> OnCalledAction + + Send + + Sync + + 'static, { // Get the current stack pointer (this will be used to determine the // upper limit of stack space remaining to unwind into) @@ -4055,25 +4291,26 @@ where F: FnOnce(FunctionEnvMut<'_, WasiEnv>, BytesMut, BytesMut) -> OnCalledActi return Err(WasiError::Exit(__WASI_EFAULT as __wasi_exitcode_t)); } }; - + // Perform a check to see if we have enough room let env = ctx.data(); let memory = env.memory_view(&ctx); - + // Write the addresses to the start of the stack space - let unwind_pointer: u64 = wasi_try_ok!(env.stack_start.try_into().map_err(|_| __WASI_EOVERFLOW)); - let unwind_data_start = unwind_pointer + (std::mem::size_of::<__wasi_asyncify_t>() as u64); + let unwind_pointer: u64 = + wasi_try_ok!(env.stack_start.try_into().map_err(|_| __WASI_EOVERFLOW)); + let unwind_data_start = + unwind_pointer + (std::mem::size_of::<__wasi_asyncify_t>() as u64); let unwind_data = __wasi_asyncify_t:: { start: wasi_try_ok!(unwind_data_start.try_into().map_err(|_| __WASI_EOVERFLOW)), end: wasi_try_ok!(env.stack_base.try_into().map_err(|_| __WASI_EOVERFLOW)), }; - let unwind_data_ptr: WasmPtr<__wasi_asyncify_t, M> = WasmPtr::new( - wasi_try_ok!(unwind_pointer.try_into().map_err(|_| __WASI_EOVERFLOW)) - ); - wasi_try_mem_ok!( - unwind_data_ptr.write(&memory, unwind_data) - ); - + let unwind_data_ptr: WasmPtr<__wasi_asyncify_t, M> = + WasmPtr::new(wasi_try_ok!(unwind_pointer + .try_into() + .map_err(|_| __WASI_EOVERFLOW))); + wasi_try_mem_ok!(unwind_data_ptr.write(&memory, unwind_data)); + // Invoke the callback that will prepare to unwind // We need to start unwinding the stack let asyncify_data = wasi_try_ok!(unwind_pointer.try_into().map_err(|_| __WASI_EOVERFLOW)); @@ -4089,33 +4326,50 @@ where F: FnOnce(FunctionEnvMut<'_, WasiEnv>, BytesMut, BytesMut) -> OnCalledActi let unwind_stack_begin: u64 = unwind_data.start.into(); let unwind_space = env.stack_base - env.stack_start; let func = ctx.as_ref(); - trace!("wasi[{}:{}]::unwinding (memory_stack_size={} unwind_space={})", ctx.data().pid(), ctx.data().tid(), memory_stack.len(), unwind_space); + trace!( + "wasi[{}:{}]::unwinding (memory_stack_size={} unwind_space={})", + ctx.data().pid(), + ctx.data().tid(), + memory_stack.len(), + unwind_space + ); ctx.as_store_mut().on_called(move |mut store| { let mut ctx = func.into_mut(&mut store); let env = ctx.data(); let memory = env.memory_view(&ctx); let unwind_data_ptr: WasmPtr<__wasi_asyncify_t, M> = WasmPtr::new( - unwind_pointer.try_into().map_err(|_| __WASI_EOVERFLOW).unwrap() + unwind_pointer + .try_into() + .map_err(|_| __WASI_EOVERFLOW) + .unwrap(), ); let unwind_data_result = unwind_data_ptr.read(&memory).unwrap(); let unwind_stack_finish: u64 = unwind_data_result.start.into(); let unwind_size = unwind_stack_finish - unwind_stack_begin; - trace!("wasi[{}:{}]::unwound (memory_stack_size={} unwind_size={})", ctx.data().pid(), ctx.data().tid(), memory_stack.len(), unwind_size); - + trace!( + "wasi[{}:{}]::unwound (memory_stack_size={} unwind_size={})", + ctx.data().pid(), + ctx.data().tid(), + memory_stack.len(), + unwind_size + ); + // Read the memory stack into a vector - let unwind_stack_ptr = WasmPtr::::new(unwind_stack_begin.try_into().map_err(|_| { - format!("failed to save stack: stack pointer overflow") - })?); - let unwind_stack = unwind_stack_ptr.slice(&memory, unwind_size.try_into().map_err(|_| { - format!("failed to save stack: stack pointer overflow") - })?) - .and_then(|memory_stack| { - memory_stack.read_to_bytes() - }) - .map_err(|err| { - format!("failed to read stack: {}", err) - })?; + let unwind_stack_ptr = WasmPtr::::new( + unwind_stack_begin + .try_into() + .map_err(|_| format!("failed to save stack: stack pointer overflow"))?, + ); + let unwind_stack = unwind_stack_ptr + .slice( + &memory, + unwind_size + .try_into() + .map_err(|_| format!("failed to save stack: stack pointer overflow"))?, + ) + .and_then(|memory_stack| memory_stack.read_to_bytes()) + .map_err(|err| format!("failed to read stack: {}", err))?; // Notify asyncify that we are no longer unwinding if let Some(asyncify_stop_unwind) = env.inner().asyncify_stop_unwind.clone() { @@ -4125,9 +4379,7 @@ where F: FnOnce(FunctionEnvMut<'_, WasiEnv>, BytesMut, BytesMut) -> OnCalledActi return Ok(OnCalledAction::Finish); } - Ok( - callback(ctx, memory_stack, unwind_stack) - ) + Ok(callback(ctx, memory_stack, unwind_stack)) }); // We need to exit the function so that it can unwind and then invoke the callback @@ -4140,9 +4392,15 @@ fn rewind( memory_stack: Bytes, rewind_stack: Bytes, store_data: Bytes, -) -> __wasi_errno_t -{ - trace!("wasi[{}:{}]::rewinding (memory_stack_size={}, rewind_size={}, store_data={})", ctx.data().pid(), ctx.data().tid(), memory_stack.len(), rewind_stack.len(), store_data.len()); +) -> __wasi_errno_t { + trace!( + "wasi[{}:{}]::rewinding (memory_stack_size={}, rewind_size={}, store_data={})", + ctx.data().pid(), + ctx.data().tid(), + memory_stack.len(), + rewind_stack.len(), + store_data.len() + ); // Store the memory stack so that it can be restored later super::REWIND.with(|cell| cell.replace(Some(memory_stack))); @@ -4161,30 +4419,37 @@ fn rewind( // Write the addresses to the start of the stack space let rewind_pointer: u64 = wasi_try!(env.stack_start.try_into().map_err(|_| __WASI_EOVERFLOW)); - let rewind_data_start = rewind_pointer + (std::mem::size_of::<__wasi_asyncify_t>() as u64); + let rewind_data_start = + rewind_pointer + (std::mem::size_of::<__wasi_asyncify_t>() as u64); let rewind_data_end = rewind_data_start + (rewind_stack.len() as u64); if rewind_data_end > env.stack_base { - warn!("attempting to rewind a stack bigger than the allocated stack space ({} > {})", rewind_data_end, env.stack_base); + warn!( + "attempting to rewind a stack bigger than the allocated stack space ({} > {})", + rewind_data_end, env.stack_base + ); return __WASI_EOVERFLOW; } let rewind_data = __wasi_asyncify_t:: { start: wasi_try!(rewind_data_end.try_into().map_err(|_| __WASI_EOVERFLOW)), end: wasi_try!(env.stack_base.try_into().map_err(|_| __WASI_EOVERFLOW)), }; - let rewind_data_ptr: WasmPtr<__wasi_asyncify_t, M> = WasmPtr::new( - wasi_try!(rewind_pointer.try_into().map_err(|_| __WASI_EOVERFLOW)) - ); - wasi_try_mem!( - rewind_data_ptr.write(&memory, rewind_data) - ); + let rewind_data_ptr: WasmPtr<__wasi_asyncify_t, M> = + WasmPtr::new(wasi_try!(rewind_pointer + .try_into() + .map_err(|_| __WASI_EOVERFLOW))); + wasi_try_mem!(rewind_data_ptr.write(&memory, rewind_data)); // Copy the data to the address - let rewind_stack_ptr = WasmPtr::::new(wasi_try!(rewind_data_start.try_into().map_err(|_| __WASI_EOVERFLOW))); - wasi_try_mem!(rewind_stack_ptr.slice(&memory, wasi_try!(rewind_stack.len().try_into().map_err(|_| __WASI_EOVERFLOW))) - .and_then(|stack| { - stack.write_slice(&rewind_stack[..]) - })); - + let rewind_stack_ptr = WasmPtr::::new(wasi_try!(rewind_data_start + .try_into() + .map_err(|_| __WASI_EOVERFLOW))); + wasi_try_mem!(rewind_stack_ptr + .slice( + &memory, + wasi_try!(rewind_stack.len().try_into().map_err(|_| __WASI_EOVERFLOW)) + ) + .and_then(|stack| { stack.write_slice(&rewind_stack[..]) })); + // Invoke the callback that will prepare to rewind let asyncify_data = wasi_try!(rewind_pointer.try_into().map_err(|_| __WASI_EOVERFLOW)); if let Some(asyncify_start_rewind) = env.inner().asyncify_start_rewind.clone() { @@ -4193,16 +4458,13 @@ fn rewind( warn!("failed to rewind the stack because the asyncify_start_rewind export is missing"); return __WASI_EFAULT; } - + __WASI_ESUCCESS } -fn handle_rewind( - ctx: &mut FunctionEnvMut<'_, WasiEnv>, -) -> bool { +fn handle_rewind(ctx: &mut FunctionEnvMut<'_, WasiEnv>) -> bool { // If the stack has been restored - if let Some(memory_stack) = super::REWIND.with(|cell| cell.borrow_mut().take()) - { + if let Some(memory_stack) = super::REWIND.with(|cell| cell.borrow_mut().take()) { // Notify asyncify that we are no longer rewinding let env = ctx.data(); if let Some(asyncify_stop_rewind) = env.inner().asyncify_stop_rewind.clone() { @@ -4224,28 +4486,32 @@ pub fn stack_checkpoint( mut ctx: FunctionEnvMut<'_, WasiEnv>, snapshot_ptr: WasmPtr<__wasi_stack_snaphost_t, M>, ret_val: WasmPtr<__wasi_longsize_t, M>, -) -> Result<__wasi_errno_t, WasiError> -{ +) -> Result<__wasi_errno_t, WasiError> { // If we were just restored then we need to return the value instead if handle_rewind::(&mut ctx) { let env = ctx.data(); let memory = env.memory_view(&ctx); - let ret_val = wasi_try_mem_ok!( - ret_val.read(&memory) + let ret_val = wasi_try_mem_ok!(ret_val.read(&memory)); + trace!( + "wasi[{}:{}]::stack_checkpoint - restored - (ret={})", + ctx.data().pid(), + ctx.data().tid(), + ret_val ); - trace!("wasi[{}:{}]::stack_checkpoint - restored - (ret={})", ctx.data().pid(), ctx.data().tid(), ret_val); return Ok(__WASI_ESUCCESS); } - trace!("wasi[{}:{}]::stack_checkpoint - capturing", ctx.data().pid(), ctx.data().tid()); + trace!( + "wasi[{}:{}]::stack_checkpoint - capturing", + ctx.data().pid(), + ctx.data().tid() + ); // Set the return value that we will give back to // indicate we are a normal function call that has not yet // been restored let env = ctx.data(); let memory = env.memory_view(&ctx); - wasi_try_mem_ok!( - ret_val.write(&memory, 0) - ); + wasi_try_mem_ok!(ret_val.write(&memory, 0)); // Pass some offsets to the unwind function let ret_offset = ret_val.offset(); @@ -4254,18 +4520,17 @@ pub fn stack_checkpoint( // We clear the target memory location before we grab the stack so that // it correctly hashes - if let Err(err) = snapshot_ptr.write(&memory, - __wasi_stack_snaphost_t { - hash: 0, - user: 0, - }) - { - warn!("wasi[{}:{}]::failed to write to stack snapshot return variable - {}", env.pid(), env.tid(), err); + if let Err(err) = snapshot_ptr.write(&memory, __wasi_stack_snaphost_t { hash: 0, user: 0 }) { + warn!( + "wasi[{}:{}]::failed to write to stack snapshot return variable - {}", + env.pid(), + env.tid(), + err + ); } // Perform the unwind action - unwind::(ctx, move |mut ctx, mut memory_stack, rewind_stack| - { + unwind::(ctx, move |mut ctx, mut memory_stack, rewind_stack| { // Grab all the globals and serialize them let env = ctx.data(); let store_data = ctx.as_store_ref().save_snapshot().serialize(); @@ -4277,7 +4542,7 @@ pub fn stack_checkpoint( // and security so that the stack can not be used to attempt to break // out of the sandbox let hash = { - use sha2::{Sha256, Digest}; + use sha2::{Digest, Sha256}; let mut hasher = Sha256::new(); hasher.update(&secret[..]); hasher.update(&memory_stack[..]); @@ -4309,8 +4574,7 @@ pub fn stack_checkpoint( let mut memory_stack_corrected = memory_stack.clone(); { let snapshot_offset: u64 = snapshot_offset.into(); - if snapshot_offset >= env.stack_start && snapshot_offset < env.stack_base - { + if snapshot_offset >= env.stack_start && snapshot_offset < env.stack_base { // Make sure its within the "active" part of the memory stack // (note - the area being written to might not go past the memory pointer) let offset = env.stack_base - snapshot_offset; @@ -4326,33 +4590,52 @@ pub fn stack_checkpoint( } } } - + /// Add a snapshot to the stack ctx.data().thread.add_snapshot( &memory_stack[..], &memory_stack_corrected[..], hash, &rewind_stack[..], - &store_data[..] + &store_data[..], + ); + trace!( + "wasi[{}:{}]::stack_recorded (hash={}, user={})", + ctx.data().pid(), + ctx.data().tid(), + snapshot.hash, + snapshot.user ); - trace!("wasi[{}:{}]::stack_recorded (hash={}, user={})", ctx.data().pid(), ctx.data().tid(), snapshot.hash, snapshot.user); // Save the stack snapshot let env = ctx.data(); let memory = env.memory_view(&ctx); let snapshot_ptr: WasmPtr<__wasi_stack_snaphost_t, M> = WasmPtr::new(snapshot_offset); if let Err(err) = snapshot_ptr.write(&memory, snapshot) { - warn!("wasi[{}:{}]::failed checkpoint - could not save stack snapshot - {}", env.pid(), env.tid(), err); + warn!( + "wasi[{}:{}]::failed checkpoint - could not save stack snapshot - {}", + env.pid(), + env.tid(), + err + ); return OnCalledAction::Trap(Box::new(WasiError::Exit(__WASI_EFAULT as u32))); } // Rewind the stack and carry on let pid = ctx.data().pid(); let tid = ctx.data().tid(); - match rewind::(ctx, memory_stack_corrected.freeze(), rewind_stack.freeze(), store_data) { + match rewind::( + ctx, + memory_stack_corrected.freeze(), + rewind_stack.freeze(), + store_data, + ) { __WASI_ESUCCESS => OnCalledAction::InvokeAgain, err => { - warn!("wasi[{}:{}]::failed checkpoint - could not rewind the stack - errno={}", pid, tid, err); + warn!( + "wasi[{}:{}]::failed checkpoint - could not rewind the stack - errno={}", + pid, tid, err + ); OnCalledAction::Trap(Box::new(WasiError::Exit(err as u32))) } } @@ -4376,30 +4659,41 @@ pub fn stack_restore( let memory = env.memory_view(&ctx); let snapshot = match snapshot_ptr.read(&memory) { Ok(a) => { - trace!("wasi[{}:{}]::stack_restore (with_ret={}, hash={}, user={})", ctx.data().pid(), ctx.data().tid(), val, a.hash, a.user); + trace!( + "wasi[{}:{}]::stack_restore (with_ret={}, hash={}, user={})", + ctx.data().pid(), + ctx.data().tid(), + val, + a.hash, + a.user + ); a - }, + } Err(err) => { - warn!("wasi[{}:{}]::stack_restore - failed to read stack snapshot - {}", ctx.data().pid(), ctx.data().tid(), err); + warn!( + "wasi[{}:{}]::stack_restore - failed to read stack snapshot - {}", + ctx.data().pid(), + ctx.data().tid(), + err + ); return Err(WasiError::Exit(128)); } }; - + // Perform the unwind action - unwind::(ctx, move |mut ctx, _, _| - { + unwind::(ctx, move |mut ctx, _, _| { // Let the stack (or fail trying!) let env = ctx.data(); - if let Some((mut memory_stack, rewind_stack, store_data)) = env.thread.get_snapshot(snapshot.hash) - { + if let Some((mut memory_stack, rewind_stack, store_data)) = + env.thread.get_snapshot(snapshot.hash) + { let env = ctx.data(); let memory = env.memory_view(&ctx); - + // If the return value offset is within the memory stack then we need // to update it here rather than in the real memory let ret_val_offset = snapshot.user; - if ret_val_offset >= env.stack_start && ret_val_offset < env.stack_base - { + if ret_val_offset >= env.stack_start && ret_val_offset < env.stack_base { // Make sure its within the "active" part of the memory stack let val_bytes = val.to_ne_bytes(); let offset = env.stack_base - ret_val_offset; @@ -4415,17 +4709,20 @@ pub fn stack_restore( pbytes.clone_from_slice(&val_bytes); } } else { - let err = snapshot.user + let err = snapshot + .user .try_into() .map_err(|_| __WASI_EOVERFLOW) .map(|a| WasmPtr::<__wasi_longsize_t, M>::new(a)) - .map(|a| a.write(&memory, val) - .map(|_| __WASI_ESUCCESS) - .unwrap_or(__WASI_EFAULT)) + .map(|a| { + a.write(&memory, val) + .map(|_| __WASI_ESUCCESS) + .unwrap_or(__WASI_EFAULT) + }) .unwrap_or_else(|a| a); if err != __WASI_ESUCCESS { warn!("wasi[{}:{}]::snapshot stack restore failed - the return value can not be written too - {}", env.pid(), env.tid(), err); - return OnCalledAction::Trap(Box::new(WasiError::Exit(__WASI_EFAULT as u32))); + return OnCalledAction::Trap(Box::new(WasiError::Exit(__WASI_EFAULT as u32))); } } @@ -4436,7 +4733,10 @@ pub fn stack_restore( match rewind::(ctx, memory_stack.freeze(), rewind_stack, store_data) { __WASI_ESUCCESS => OnCalledAction::InvokeAgain, err => { - warn!("wasi[{}:{}]::failed to rewind the stack - errno={}", pid, tid, err); + warn!( + "wasi[{}:{}]::failed to rewind the stack - errno={}", + pid, tid, err + ); OnCalledAction::Trap(Box::new(WasiError::Exit(__WASI_EFAULT as u32))) } } @@ -4464,7 +4764,13 @@ pub fn proc_signal( pid: __wasi_pid_t, sig: __wasi_signal_t, ) -> Result<__wasi_errno_t, WasiError> { - trace!("wasi[{}:{}]::proc_signal(pid={}, sig={})", ctx.data().pid(), ctx.data().tid(), pid, sig); + trace!( + "wasi[{}:{}]::proc_signal(pid={}, sig={})", + ctx.data().pid(), + ctx.data().tid(), + pid, + sig + ); let process = { let pid: WasiProcessId = pid.into(); @@ -4473,7 +4779,7 @@ pub fn proc_signal( if let Some(process) = process { process.signal_process(sig); } - + let env = ctx.data(); env.clone().yield_now_with_signals(&mut ctx)?; @@ -4486,7 +4792,13 @@ pub fn proc_signal( pid: __wasi_pid_t, sig: __wasi_signal_t, ) -> Result<__wasi_errno_t, WasiError> { - warn!("wasi[{}:{}]::proc_signal(pid={}, sig={}) is not supported without 'os' feature", ctx.data().pid(), ctx.data().tid(), pid, sig); + warn!( + "wasi[{}:{}]::proc_signal(pid={}, sig={}) is not supported without 'os' feature", + ctx.data().pid(), + ctx.data().tid(), + pid, + sig + ); Ok(__WASI_ENOTSUP) } @@ -4502,7 +4814,12 @@ pub fn random_get( buf: WasmPtr, buf_len: M::Offset, ) -> __wasi_errno_t { - trace!("wasi[{}:{}]::random_get(buf_len={})", ctx.data().pid(), ctx.data().tid(), buf_len); + trace!( + "wasi[{}:{}]::random_get(buf_len={})", + ctx.data().pid(), + ctx.data().tid(), + buf_len + ); let env = ctx.data(); let memory = env.memory_view(&ctx); let buf_len64: u64 = buf_len.into(); @@ -4566,7 +4883,14 @@ pub fn tty_set( _ => return __WASI_EINVAL, }; let line_feeds = true; - debug!("wasi[{}:{}]::tty_set(echo={}, line_buffered={}, line_feeds={})", ctx.data().pid(), ctx.data().tid(), echo, line_buffered, line_feeds); + debug!( + "wasi[{}:{}]::tty_set(echo={}, line_buffered={}, line_feeds={})", + ctx.data().pid(), + ctx.data().tid(), + echo, + line_buffered, + line_feeds + ); let state = super::runtime::WasiTtyState { cols: state.cols, @@ -4590,7 +4914,7 @@ pub fn tty_set( }, echo, line_buffered, - line_feeds + line_feeds, }; env.runtime.tty_set(state); @@ -4614,7 +4938,12 @@ pub fn getcwd( let (_, cur_dir) = wasi_try!(state .fs .get_current_dir(inodes.deref_mut(), crate::VIRTUAL_ROOT_FD,)); - trace!("wasi[{}:{}]::getcwd(current_dir={})", ctx.data().pid(), ctx.data().tid(), cur_dir); + trace!( + "wasi[{}:{}]::getcwd(current_dir={})", + ctx.data().pid(), + ctx.data().tid(), + cur_dir + ); let max_path_len = wasi_try_mem!(path_len.read(&memory)); let path_slice = wasi_try_mem!(path.slice(&memory, max_path_len)); @@ -4652,7 +4981,12 @@ pub fn chdir( let env = ctx.data(); let (memory, mut state) = env.get_memory_and_wasi_state(&ctx, 0); let path = unsafe { get_input_str!(&memory, path, path_len) }; - debug!("wasi[{}:{}]::chdir [{}]", ctx.data().pid(), ctx.data().tid(), path); + debug!( + "wasi[{}:{}]::chdir [{}]", + ctx.data().pid(), + ctx.data().tid(), + path + ); // Check if the directory exists if state.fs.root_fs.read_dir(Path::new(path.as_str())).is_err() { @@ -4665,9 +4999,9 @@ pub fn chdir( /// ### `callback_spawn()` /// Sets the callback to invoke upon spawning of new threads -/// +/// /// ### Parameters -/// +/// /// * `name` - Name of the function that will be invoked pub fn callback_thread( mut ctx: FunctionEnvMut<'_, WasiEnv>, @@ -4677,10 +5011,14 @@ pub fn callback_thread( let env = ctx.data(); let memory = env.memory_view(&ctx); let name = unsafe { name.read_utf8_string(&memory, name_len)? }; - debug!("wasi[{}:{}]::callback_spawn (name={})", ctx.data().pid(), ctx.data().tid(), name); + debug!( + "wasi[{}:{}]::callback_spawn (name={})", + ctx.data().pid(), + ctx.data().tid(), + name + ); - let funct = env.inner().exports - .get_typed_function(&ctx, &name).ok(); + let funct = env.inner().exports.get_typed_function(&ctx, &name).ok(); ctx.data_mut().inner_mut().thread_spawn = funct; Ok(()) @@ -4688,9 +5026,9 @@ pub fn callback_thread( /// ### `callback_signal()` /// Sets the callback to invoke signals -/// +/// /// ### Parameters -/// +/// /// * `name` - Name of the function that will be invoked pub fn callback_signal( mut ctx: FunctionEnvMut<'_, WasiEnv>, @@ -4703,15 +5041,23 @@ pub fn callback_signal( match name.read_utf8_string(&memory, name_len) { Ok(a) => a, Err(err) => { - warn!("failed to access memory that holds the name of the signal callback: {}", err); + warn!( + "failed to access memory that holds the name of the signal callback: {}", + err + ); return Ok(()); } } }; - - let funct = env.inner().exports - .get_typed_function(&ctx, &name).ok(); - trace!("wasi[{}:{}]::callback_signal (name={}, found={})", ctx.data().pid(), ctx.data().tid(), name, funct.is_some()); + + let funct = env.inner().exports.get_typed_function(&ctx, &name).ok(); + trace!( + "wasi[{}:{}]::callback_signal (name={}, found={})", + ctx.data().pid(), + ctx.data().tid(), + name, + funct.is_some() + ); { let inner = ctx.data_mut().inner_mut(); @@ -4727,9 +5073,9 @@ pub fn callback_signal( /// ### `callback_reactor()` /// Sets the callback to invoke for reactors -/// +/// /// ### Parameters -/// +/// /// * `name` - Name of the function that will be invoked pub fn callback_reactor( mut ctx: FunctionEnvMut<'_, WasiEnv>, @@ -4739,10 +5085,14 @@ pub fn callback_reactor( let env = ctx.data(); let memory = env.memory_view(&ctx); let name = unsafe { name.read_utf8_string(&memory, name_len)? }; - debug!("wasi[{}:{}]::callback_reactor (name={})", ctx.data().pid(), ctx.data().tid(), name); + debug!( + "wasi[{}:{}]::callback_reactor (name={})", + ctx.data().pid(), + ctx.data().tid(), + name + ); - let funct = env.inner().exports - .get_typed_function(&ctx, &name).ok(); + let funct = env.inner().exports.get_typed_function(&ctx, &name).ok(); ctx.data_mut().inner_mut().react = funct; Ok(()) @@ -4750,9 +5100,9 @@ pub fn callback_reactor( /// ### `callback_thread_local_destroy()` /// Sets the callback to invoke for the destruction of thread local variables -/// +/// /// ### Parameters -/// +/// /// * `name` - Name of the function that will be invoked pub fn callback_thread_local_destroy( mut ctx: FunctionEnvMut<'_, WasiEnv>, @@ -4762,10 +5112,14 @@ pub fn callback_thread_local_destroy( let env = ctx.data(); let memory = env.memory_view(&ctx); let name = unsafe { name.read_utf8_string(&memory, name_len)? }; - debug!("wasi[{}:{}]::callback_thread_local_destroy (name={})", ctx.data().pid(), ctx.data().tid(), name); + debug!( + "wasi[{}:{}]::callback_thread_local_destroy (name={})", + ctx.data().pid(), + ctx.data().tid(), + name + ); - let funct = env.inner().exports - .get_typed_function(&ctx, &name).ok(); + let funct = env.inner().exports.get_typed_function(&ctx, &name).ok(); ctx.data_mut().inner_mut().thread_local_destroy = funct; Ok(()) @@ -4797,8 +5151,16 @@ pub fn thread_spawn( reactor: __wasi_bool_t, ret_tid: WasmPtr<__wasi_tid_t, M>, ) -> __wasi_errno_t { - debug!("wasi[{}:{}]::thread_spawn (reactor={}, thread_id={}, stack_base={}, caller_id={})", ctx.data().pid(), ctx.data().tid(), reactor, ctx.data().thread.tid().raw(), stack_base, current_caller_id().raw()); - + debug!( + "wasi[{}:{}]::thread_spawn (reactor={}, thread_id={}, stack_base={}, caller_id={})", + ctx.data().pid(), + ctx.data().tid(), + reactor, + ctx.data().thread.tid().raw(), + stack_base, + current_caller_id().raw() + ); + // Now we use the environment and memory references let env = ctx.data(); let memory = env.memory_view(&ctx); @@ -4811,15 +5173,10 @@ pub fn thread_spawn( // We need a copy of the process memory and a packaged store in order to // launch threads and reactors - let thread_memory = wasi_try!( - ctx.data() - .memory() - .try_clone(&ctx) - .ok_or_else(|| { - error!("thread failed - the memory could not be cloned"); - __WASI_ENOTCAPABLE - }) - ); + let thread_memory = wasi_try!(ctx.data().memory().try_clone(&ctx).ok_or_else(|| { + error!("thread failed - the memory could not be cloned"); + __WASI_ENOTCAPABLE + })); #[cfg(feature = "compiler")] let engine = ctx.as_store_ref().engine().clone(); @@ -4835,8 +5192,7 @@ pub fn thread_spawn( let state = env.state.clone(); let wasi_env = env.clone(); let thread = thread_handle.as_thread(); - move |mut store: Store, module: Module, memory: VMMemory| - { + move |mut store: Store, module: Module, memory: VMMemory| { // We need to reconstruct some things let module = module.clone(); let memory = Memory::new_from_existing(&mut store, memory); @@ -4852,7 +5208,7 @@ pub fn thread_spawn( let mut import_object = import_object_for_all_wasi_versions(&mut store, &ctx.env); import_object.define("env", "memory", memory.clone()); - + let instance = match Instance::new(&mut store, &module, &import_object) { Ok(a) => a, Err(err) => { @@ -4860,22 +5216,23 @@ pub fn thread_spawn( return Err(__WASI_ENOEXEC as u32); } }; - + // Set the current thread ID - ctx.data_mut(&mut store).inner = Some( - WasiEnvInner::new(module, memory, &store, &instance) + ctx.data_mut(&mut store).inner = + Some(WasiEnvInner::new(module, memory, &store, &instance)); + trace!( + "threading: new context created for thread_id = {}", + thread.tid().raw() ); - trace!("threading: new context created for thread_id = {}", thread.tid().raw()); Ok(WasiThreadContext { ctx, - store: RefCell::new(store) + store: RefCell::new(store), }) } }; // This function calls into the module - let call_module = move |ctx: &WasiFunctionEnv, store: &mut Store| - { + let call_module = move |ctx: &WasiFunctionEnv, store: &mut Store| { // We either call the reactor callback or the thread spawn callback //trace!("threading: invoking thread callback (reactor={})", reactor); let spawn = match reactor { @@ -4896,10 +5253,9 @@ pub fn thread_spawn( ret = __WASI_ENOEXEC; } //trace!("threading: thread callback finished (reactor={}, ret={})", reactor, ret); - + // If we are NOT a reactor then we will only run once and need to clean up - if reactor == __WASI_BOOL_FALSE - { + if reactor == __WASI_BOOL_FALSE { // Clean up the environment ctx.cleanup(store); } @@ -4909,11 +5265,10 @@ pub fn thread_spawn( }; // This next function gets a context for the local thread and then - // calls into the process + // calls into the process let mut execute_module = { let state = env.state.clone(); - move |store: &mut Option, module: Module, memory: &mut Option| - { + move |store: &mut Option, module: Module, memory: &mut Option| { // We capture the thread handle here, it is used to notify // anyone that is interested when this thread has terminated let _captured_handle = Box::new(&mut thread_handle); @@ -4930,28 +5285,34 @@ pub fn thread_spawn( let guard = state.threading.read().unwrap(); guard.thread_ctx.get(&caller_id).map(|a| a.clone()) }; - if let Some(thread) = thread - { + if let Some(thread) = thread { let mut store = thread.store.borrow_mut(); let ret = call_module(&thread.ctx, store.deref_mut()); return ret; } // Otherwise we need to create a new context under a write lock - debug!("encountered a new caller (ref={}) - creating WASM execution context...", caller_id.raw()); + debug!( + "encountered a new caller (ref={}) - creating WASM execution context...", + caller_id.raw() + ); // We can only create the context once per thread let memory = match memory.take() { Some(m) => m, None => { - debug!("thread failed - memory can only be consumed once per context creation"); + debug!( + "thread failed - memory can only be consumed once per context creation" + ); return __WASI_ENOEXEC as u32; } }; let store = match store.take() { Some(s) => s, None => { - debug!("thread failed - store can only be consumed once per context creation"); + debug!( + "thread failed - store can only be consumed once per context creation" + ); return __WASI_ENOEXEC as u32; } }; @@ -4976,7 +5337,7 @@ pub fn thread_spawn( __WASI_BOOL_TRUE => { warn!("thread failed - reactors are not currently supported"); return __WASI_ENOTCAPABLE; - }, + } __WASI_BOOL_FALSE => { // If the process does not export a thread spawn function then obviously // we can't spawn a background thread @@ -4989,7 +5350,8 @@ pub fn thread_spawn( trace!("threading: spawning background thread"); let thread_module = env.inner().module.clone(); wasi_try!(tasks - .task_wasm(Box::new(move |store, module, thread_memory| { + .task_wasm( + Box::new(move |store, module, thread_memory| { let mut thread_memory = thread_memory; let mut store = Some(store); execute_module(&mut store, module, &mut thread_memory); @@ -5001,15 +5363,14 @@ pub fn thread_spawn( .map_err(|err| { let err: __wasi_errno_t = err.into(); err - }) - ); - }, + })); + } _ => { warn!("thread failed - invalid reactor parameter value"); return __WASI_ENOTCAPABLE; } } - + // Success let memory = ctx.data().memory_view(&ctx); wasi_try_mem!(ret_tid.write(&memory, thread_id)); @@ -5030,7 +5391,12 @@ pub fn thread_local_create( user_data: u64, ret_key: WasmPtr<__wasi_tl_key_t, M>, ) -> __wasi_errno_t { - trace!("wasi[{}:{}]::thread_local_create (user_data={})", ctx.data().pid(), ctx.data().tid(), user_data); + trace!( + "wasi[{}:{}]::thread_local_create (user_data={})", + ctx.data().pid(), + ctx.data().tid(), + user_data + ); let env = ctx.data(); let key = { @@ -5040,7 +5406,7 @@ pub fn thread_local_create( inner.thread_local_user_data.insert(key, user_data); key }; - + let memory = env.memory_view(&ctx); wasi_try_mem!(ret_key.write(&memory, key)); __WASI_ESUCCESS @@ -5056,14 +5422,26 @@ pub fn thread_local_create( /// * `key` - Thread key that was previously created pub fn thread_local_destroy( mut ctx: FunctionEnvMut<'_, WasiEnv>, - key: __wasi_tl_key_t + key: __wasi_tl_key_t, ) -> __wasi_errno_t { - trace!("wasi[{}:{}]::thread_local_destroy (key={})", ctx.data().pid(), ctx.data().tid(), key); + trace!( + "wasi[{}:{}]::thread_local_destroy (key={})", + ctx.data().pid(), + ctx.data().tid(), + key + ); let process = ctx.data().process.clone(); let mut inner = process.write(); if let Some(user_data) = inner.thread_local_user_data.remove(&key) { - if let Some(thread_local_destroy) = ctx.data().inner().thread_local_destroy.as_ref().map(|a| a.clone()) { - inner.thread_local + if let Some(thread_local_destroy) = ctx + .data() + .inner() + .thread_local_destroy + .as_ref() + .map(|a| a.clone()) + { + inner + .thread_local .iter() .filter(|((_, k), _)| *k == key) .for_each(|((_, _), val)| { @@ -5073,7 +5451,13 @@ pub fn thread_local_destroy( let val_low: u32 = (val & 0xFFFFFFFF) as u32; let val_high: u32 = (val >> 32) as u32; - let _ = thread_local_destroy.call(&mut ctx, user_data_low as i32, user_data_high as i32, val_low as i32, val_high as i32); + let _ = thread_local_destroy.call( + &mut ctx, + user_data_low as i32, + user_data_high as i32, + val_low as i32, + val_high as i32, + ); }); } } @@ -5091,7 +5475,7 @@ pub fn thread_local_destroy( pub fn thread_local_set( ctx: FunctionEnvMut<'_, WasiEnv>, key: __wasi_tl_key_t, - val: __wasi_tl_val_t + val: __wasi_tl_val_t, ) -> __wasi_errno_t { //trace!("wasi[{}:{}]::thread_local_set (key={}, val={})", ctx.data().pid(), ctx.data().tid(), key, val); let env = ctx.data(); @@ -5119,7 +5503,10 @@ pub fn thread_local_get( let val = { let current_thread = ctx.data().thread.tid(); let guard = env.process.read(); - guard.thread_local.get(&(current_thread, key)).map(|a| a.clone()) + guard + .thread_local + .get(&(current_thread, key)) + .map(|a| a.clone()) }; let val = val.unwrap_or_default(); let memory = env.memory_view(&ctx); @@ -5172,7 +5559,12 @@ pub fn thread_join( ctx: FunctionEnvMut<'_, WasiEnv>, tid: __wasi_tid_t, ) -> Result<__wasi_errno_t, WasiError> { - debug!("wasi[{}:{}]::thread_join(tid={})", ctx.data().pid(), ctx.data().tid(), tid); + debug!( + "wasi[{}:{}]::thread_join(tid={})", + ctx.data().pid(), + ctx.data().tid(), + tid + ); let env = ctx.data(); let tid: WasiThreadId = tid.into(); @@ -5197,7 +5589,11 @@ pub fn thread_parallelism( ctx: FunctionEnvMut<'_, WasiEnv>, ret_parallelism: WasmPtr, ) -> __wasi_errno_t { - debug!("wasi[{}:{}]::thread_parallelism", ctx.data().pid(), ctx.data().tid()); + debug!( + "wasi[{}:{}]::thread_parallelism", + ctx.data().pid(), + ctx.data().tid() + ); let env = ctx.data(); let parallelism = wasi_try!(env.tasks().thread_parallelism().map_err(|err| { @@ -5226,7 +5622,12 @@ pub fn futex_wait( timeout: WasmPtr<__wasi_option_timestamp_t, M>, ret_woken: WasmPtr<__wasi_bool_t, M>, ) -> Result<__wasi_errno_t, WasiError> { - trace!("wasi[{}:{}]::futex_wait(offset={})", ctx.data().pid(), ctx.data().tid(), futex_ptr.offset()); + trace!( + "wasi[{}:{}]::futex_wait(offset={})", + ctx.data().pid(), + ctx.data().tid(), + futex_ptr.offset() + ); let env = ctx.data(); let state = env.state.deref(); @@ -5237,13 +5638,11 @@ pub fn futex_wait( use std::collections::hash_map::Entry; let mut guard = state.futexs.lock().unwrap(); match guard.entry(pointer) { - Entry::Occupied(entry) => { - entry.get().clone() - }, + Entry::Occupied(entry) => entry.get().clone(), Entry::Vacant(entry) => { let futex = WasiFutex { refcnt: Arc::new(AtomicU32::new(1)), - inner: Arc::new((Mutex::new(()), Condvar::new())) + inner: Arc::new((Mutex::new(()), Condvar::new())), }; entry.insert(futex.clone()); futex @@ -5267,7 +5666,11 @@ pub fn futex_wait( } } - let result = futex.inner.1.wait_timeout(futex_lock, Duration::from_millis(50)).unwrap(); + let result = futex + .inner + .1 + .wait_timeout(futex_lock, Duration::from_millis(50)) + .unwrap(); if result.1.timed_out() { yielded = env.yield_now(); if yielded.is_err() { @@ -5281,7 +5684,8 @@ pub fn futex_wait( // Drop the reference count to the futex (and remove it if the refcnt hits zero) { let mut guard = state.futexs.lock().unwrap(); - if guard.get(&pointer) + if guard + .get(&pointer) .map(|futex| futex.refcnt.fetch_sub(1, Ordering::AcqRel) == 1) .unwrap_or(false) { @@ -5307,11 +5711,16 @@ pub fn futex_wake( futex: WasmPtr, ret_woken: WasmPtr<__wasi_bool_t, M>, ) -> __wasi_errno_t { - trace!("wasi[{}:{}]::futex_wake(offset={})", ctx.data().pid(), ctx.data().tid(), futex.offset()); + trace!( + "wasi[{}:{}]::futex_wake(offset={})", + ctx.data().pid(), + ctx.data().tid(), + futex.offset() + ); let env = ctx.data(); let memory = env.memory_view(&ctx); let state = env.state.deref(); - + let pointer: u64 = wasi_try!(futex.offset().try_into().map_err(|_| __WASI_EOVERFLOW)); let mut woken = false; @@ -5320,7 +5729,11 @@ pub fn futex_wake( futex.inner.1.notify_one(); woken = true; } else { - trace!("wasi[{}:{}]::futex_wake - nothing waiting!", ctx.data().pid(), ctx.data().tid()); + trace!( + "wasi[{}:{}]::futex_wake - nothing waiting!", + ctx.data().pid(), + ctx.data().tid() + ); } let woken = match woken { @@ -5328,7 +5741,7 @@ pub fn futex_wake( true => __WASI_BOOL_TRUE, }; wasi_try_mem!(ret_woken.write(&memory, woken)); - + __WASI_ESUCCESS } @@ -5342,7 +5755,12 @@ pub fn futex_wake_all( futex: WasmPtr, ret_woken: WasmPtr<__wasi_bool_t, M>, ) -> __wasi_errno_t { - trace!("wasi[{}:{}]::futex_wake_all(offset={})", ctx.data().pid(), ctx.data().tid(), futex.offset()); + trace!( + "wasi[{}:{}]::futex_wake_all(offset={})", + ctx.data().pid(), + ctx.data().tid(), + futex.offset() + ); let env = ctx.data(); let memory = env.memory_view(&ctx); let state = env.state.deref(); @@ -5361,7 +5779,7 @@ pub fn futex_wake_all( true => __WASI_BOOL_TRUE, }; wasi_try_mem!(ret_woken.write(&memory, woken)); - + __WASI_ESUCCESS } @@ -5393,7 +5811,7 @@ pub fn proc_parent( let pid: WasiProcessId = pid.into(); if pid == env.process.pid() { let memory = env.memory_view(&ctx); - wasi_try_mem!(ret_parent.write(&memory, env.process.ppid().raw() as __wasi_pid_t)); + wasi_try_mem!(ret_parent.write(&memory, env.process.ppid().raw() as __wasi_pid_t)); } else { let compute = env.process.control_plane(); if let Some(process) = compute.get_process(pid) { @@ -5419,13 +5837,16 @@ pub fn thread_exit( ctx: FunctionEnvMut<'_, WasiEnv>, exitcode: __wasi_exitcode_t, ) -> Result<(), WasiError> { - debug!("wasi[{}:{}]::thread_exit", ctx.data().pid(), ctx.data().tid()); + debug!( + "wasi[{}:{}]::thread_exit", + ctx.data().pid(), + ctx.data().tid() + ); Err(WasiError::Exit(exitcode)) } // Function to prepare the WASI environment -fn _prepare_wasi(wasi_env: &mut WasiEnv, args: Option>) -{ +fn _prepare_wasi(wasi_env: &mut WasiEnv, args: Option>) { // Swap out the arguments with the new ones if let Some(args) = args { let mut wasi_state = wasi_env.state.fork(); @@ -5440,13 +5861,14 @@ fn _prepare_wasi(wasi_env: &mut WasiEnv, args: Option>) preopen_fds.iter().map(|a| *a).collect::>() }; let mut fd_map = wasi_env.state.fs.fd_map.read().unwrap(); - fd_map.keys().filter_map(|a| { - match *a { + fd_map + .keys() + .filter_map(|a| match *a { a if a <= __WASI_STDERR_FILENO => None, a if preopen_fds.contains(&a) => None, - a => Some(a) - } - }).collect::>() + a => Some(a), + }) + .collect::>() }; // Now close all these files @@ -5461,7 +5883,7 @@ fn conv_bus_err_to_exit_code(err: VirtualBusError) -> u32 { VirtualBusError::AccessDenied => -1i32 as u32, VirtualBusError::NotFound => -2i32 as u32, VirtualBusError::Unsupported => -22i32 as u32, - VirtualBusError::BadRequest | _ => -8i32 as u32 + VirtualBusError::BadRequest | _ => -8i32 as u32, } } @@ -5476,21 +5898,39 @@ pub fn proc_fork( pid_ptr: WasmPtr<__wasi_pid_t, M>, ) -> Result<__wasi_errno_t, WasiError> { // If we were just restored then we need to return the value instead - let fork_op = if copy_memory == __WASI_BOOL_TRUE { "fork" } else { "vfork" }; + let fork_op = if copy_memory == __WASI_BOOL_TRUE { + "fork" + } else { + "vfork" + }; if handle_rewind::(&mut ctx) { let env = ctx.data(); let memory = env.memory_view(&ctx); - let ret_pid = wasi_try_mem_ok!( - pid_ptr.read(&memory) - ); + let ret_pid = wasi_try_mem_ok!(pid_ptr.read(&memory)); if ret_pid == 0 { - trace!("wasi[{}:{}]::proc_{} - entering child", ctx.data().pid(), ctx.data().tid(), fork_op); + trace!( + "wasi[{}:{}]::proc_{} - entering child", + ctx.data().pid(), + ctx.data().tid(), + fork_op + ); } else { - trace!("wasi[{}:{}]::proc_{} - entering parent(child={})", ctx.data().pid(), ctx.data().tid(), fork_op, ret_pid); + trace!( + "wasi[{}:{}]::proc_{} - entering parent(child={})", + ctx.data().pid(), + ctx.data().tid(), + fork_op, + ret_pid + ); } return Ok(__WASI_ESUCCESS); } - trace!("wasi[{}:{}]::proc_{} - capturing", ctx.data().pid(), ctx.data().tid(), fork_op); + trace!( + "wasi[{}:{}]::proc_{} - capturing", + ctx.data().pid(), + ctx.data().tid(), + fork_op + ); // Fork the environment which will copy all the open file handlers // and associate a new context but otherwise shares things like the @@ -5498,7 +5938,7 @@ pub fn proc_fork( // in the parent process context let (mut child_env, mut child_handle) = ctx.data().fork(); let child_pid = child_env.process.pid(); - + // We write a zero to the PID before we capture the stack // so that this is what will be returned to the child { @@ -5507,23 +5947,19 @@ pub fn proc_fork( } let env = ctx.data(); let memory = env.memory_view(&ctx); - wasi_try_mem_ok!( - pid_ptr.write(&memory, 0) - ); - + wasi_try_mem_ok!(pid_ptr.write(&memory, 0)); + // Pass some offsets to the unwind function let pid_offset = pid_ptr.offset(); - + // If we are not copying the memory then we act like a `vfork` // instead which will pretend to be the new process for a period // of time until `proc_exec` is called at which point the fork // actually occurs - if copy_memory == __WASI_BOOL_FALSE - { + if copy_memory == __WASI_BOOL_FALSE { // Perform the unwind action let pid_offset: u64 = pid_offset.into(); - return unwind::(ctx, move |mut ctx, mut memory_stack, rewind_stack| - { + return unwind::(ctx, move |mut ctx, mut memory_stack, rewind_stack| { // Grab all the globals and serialize them let store_data = ctx.as_store_ref().save_snapshot().serialize(); let store_data = Bytes::from(store_data); @@ -5541,14 +5977,22 @@ pub fn proc_fork( handle: child_handle, pid_offset, }); - + // Carry on as if the fork had taken place (which basically means // it prevents to be the new process with the old one suspended) // Rewind the stack and carry on - match rewind::(ctx, memory_stack.freeze(), rewind_stack.freeze(), store_data) { + match rewind::( + ctx, + memory_stack.freeze(), + rewind_stack.freeze(), + store_data, + ) { __WASI_ESUCCESS => OnCalledAction::InvokeAgain, err => { - warn!("{} failed - could not rewind the stack - errno={}", fork_op, err); + warn!( + "{} failed - could not rewind the stack - errno={}", + fork_op, err + ); OnCalledAction::Trap(Box::new(WasiError::Exit(__WASI_EFAULT as u32))) } } @@ -5560,8 +6004,7 @@ pub fn proc_fork( let bin_factory = env.bin_factory.clone(); // Perform the unwind action - unwind::(ctx, move |mut ctx, mut memory_stack, rewind_stack| - { + unwind::(ctx, move |mut ctx, mut memory_stack, rewind_stack| { // Grab all the globals and serialize them let store_data = ctx.as_store_ref().save_snapshot().serialize(); let store_data = Bytes::from(store_data); @@ -5572,18 +6015,25 @@ pub fn proc_fork( .memory() .try_clone(&ctx) .ok_or_else(|| { - error!("wasi[{}:{}]::{} failed - the memory could not be cloned", ctx.data().pid(), ctx.data().tid(), fork_op); + error!( + "wasi[{}:{}]::{} failed - the memory could not be cloned", + ctx.data().pid(), + ctx.data().tid(), + fork_op + ); MemoryError::Generic(format!("the memory could not be cloned")) }) - .and_then(|mut memory| - memory.fork() - ) + .and_then(|mut memory| memory.fork()) { - Ok(memory) => { - memory.into() - }, + Ok(memory) => memory.into(), Err(err) => { - warn!("wasi[{}:{}]::{} failed - could not fork the memory - {}", ctx.data().pid(), ctx.data().tid(), fork_op, err); + warn!( + "wasi[{}:{}]::{} failed - could not fork the memory - {}", + ctx.data().pid(), + ctx.data().tid(), + fork_op, + err + ); return OnCalledAction::Trap(Box::new(WasiError::Exit(__WASI_EFAULT as u32))); } }; @@ -5597,7 +6047,7 @@ pub fn proc_fork( let mut fork_store = Store::new(engine); #[cfg(not(feature = "compiler"))] let mut fork_store = Store::default(); - + // Now we use the environment and memory references let runtime = child_env.runtime.clone(); let tasks = child_env.tasks.clone(); @@ -5614,7 +6064,7 @@ pub fn proc_fork( let runtime = runtime.clone(); let tasks = tasks.clone(); let tasks_outer = tasks.clone(); - tasks_outer.task_wasm(Box::new(move |mut store, module, memory| + tasks_outer.task_wasm(Box::new(move |mut store, module, memory| { // Create the WasiFunctionEnv let pid = child_env.pid(); @@ -5622,7 +6072,7 @@ pub fn proc_fork( child_env.runtime = runtime.clone(); child_env.tasks = tasks.clone(); let mut ctx = WasiFunctionEnv::new(&mut store, child_env); - + // Let's instantiate the module with the imports. let mut import_object = import_object_for_all_wasi_versions(&mut store, &ctx.env); let memory = if let Some(memory) = memory { @@ -5689,21 +6139,26 @@ pub fn proc_fork( // Add the process to the environment state let process = BusSpawnedProcess { - inst: Box::new( - crate::bin_factory::SpawnedProcess { - exit_code: Mutex::new(None), - exit_code_rx: Mutex::new(exit_code_rx), - } - ), + inst: Box::new(crate::bin_factory::SpawnedProcess { + exit_code: Mutex::new(None), + exit_code_rx: Mutex::new(exit_code_rx), + }), stdin: None, stdout: None, stderr: None, signaler: Some(signaler), - }; + }; { - trace!("wasi[{}:{}]::spawned sub-process (pid={})", ctx.data().pid(), ctx.data().tid(), child_pid.raw()); + trace!( + "wasi[{}:{}]::spawned sub-process (pid={})", + ctx.data().pid(), + ctx.data().tid(), + child_pid.raw() + ); let mut inner = ctx.data().process.write(); - inner.bus_processes.insert(child_pid.into(), Box::new(process)); + inner + .bus_processes + .insert(child_pid.into(), Box::new(process)); } // ------------------------------------------------------- @@ -5730,7 +6185,7 @@ pub fn proc_fork( let mut import_object = import_object_for_all_wasi_versions(&mut store, &ctx.env); import_object.define("env", "memory", memory.clone()); - + let instance = match Instance::new(&mut store, &module, &import_object) { Ok(a) => a, Err(err) => { @@ -5738,7 +6193,7 @@ pub fn proc_fork( return Err(__WASI_ENOEXEC as u32); } }; - + // Set the current thread ID ctx.data_mut(&mut store).inner = Some( WasiEnvInner::new(module, memory, &store, &instance) @@ -5790,7 +6245,7 @@ pub fn proc_fork( }; // This next function gets a context for the local thread and then - // calls into the process + // calls into the process let mut execute_module = { let state = child_env.state.clone(); move |store: &mut Option, module: Module, memory: &mut Option| @@ -5874,15 +6329,14 @@ pub fn proc_fork( // If the return value offset is within the memory stack then we need // to update it here rather than in the real memory let pid_offset: u64 = pid_offset.into(); - if pid_offset >= env.stack_start && pid_offset < env.stack_base - { + if pid_offset >= env.stack_start && pid_offset < env.stack_base { // Make sure its within the "active" part of the memory stack let offset = env.stack_base - pid_offset; if offset as usize > memory_stack.len() { warn!("{} failed - the return value (pid) is outside of the active part of the memory stack ({} vs {})", fork_op, offset, memory_stack.len()); return OnCalledAction::Trap(Box::new(WasiError::Exit(__WASI_EFAULT as u32))); } - + // Update the memory stack with the new PID let val_bytes = child_pid.raw().to_ne_bytes(); let pstart = memory_stack.len() - offset as usize; @@ -5895,10 +6349,18 @@ pub fn proc_fork( } // Rewind the stack and carry on - match rewind::(ctx, memory_stack.freeze(), rewind_stack.freeze(), store_data) { + match rewind::( + ctx, + memory_stack.freeze(), + rewind_stack.freeze(), + store_data, + ) { __WASI_ESUCCESS => OnCalledAction::InvokeAgain, err => { - warn!("{} failed - could not rewind the stack - errno={}", fork_op, err); + warn!( + "{} failed - could not rewind the stack - errno={}", + fork_op, err + ); OnCalledAction::Trap(Box::new(WasiError::Exit(__WASI_EFAULT as u32))) } } @@ -5911,7 +6373,11 @@ pub fn proc_fork( mut copy_memory: __wasi_bool_t, pid_ptr: WasmPtr<__wasi_pid_t, M>, ) -> Result<__wasi_errno_t, WasiError> { - warn!("wasi[{}:{}]::proc_fork - not supported without 'os' feature", ctx.data().pid(), ctx.data().tid()); + warn!( + "wasi[{}:{}]::proc_fork - not supported without 'os' feature", + ctx.data().pid(), + ctx.data().tid() + ); Ok(__WASI_ENOTSUP) } @@ -5939,29 +6405,44 @@ pub fn proc_exec( warn!("failed to execve as the name could not be read - {}", err); WasiError::Exit(__WASI_EFAULT as __wasi_exitcode_t) })?; - trace!("wasi[{}:{}]::proc_exec (name={})", ctx.data().pid(), ctx.data().tid(), name); + trace!( + "wasi[{}:{}]::proc_exec (name={})", + ctx.data().pid(), + ctx.data().tid(), + name + ); let args = args.read_utf8_string(&memory, args_len).map_err(|err| { warn!("failed to execve as the args could not be read - {}", err); WasiError::Exit(__WASI_EFAULT as __wasi_exitcode_t) })?; - let args: Vec<_> = args.split(&['\n', '\r']).map(|a| a.to_string()).filter(|a| a.len() > 0).collect(); + let args: Vec<_> = args + .split(&['\n', '\r']) + .map(|a| a.to_string()) + .filter(|a| a.len() > 0) + .collect(); // Convert relative paths into absolute paths if name.starts_with("./") { name = ctx.data().state.fs.relative_path_to_absolute(name); - trace!("wasi[{}:{}]::rel_to_abs (name={}))", ctx.data().pid(), ctx.data().tid(), name); + trace!( + "wasi[{}:{}]::rel_to_abs (name={}))", + ctx.data().pid(), + ctx.data().tid(), + name + ); } - + // Convert the preopen directories let preopen = ctx.data().state.preopen.clone(); // Get the current working directory let (_, cur_dir) = { - let (memory, state, mut inodes) = ctx.data().get_memory_and_wasi_state_and_inodes_mut(&ctx, 0); + let (memory, state, mut inodes) = + ctx.data().get_memory_and_wasi_state_and_inodes_mut(&ctx, 0); match state .fs - .get_current_dir(inodes.deref_mut(), crate::VIRTUAL_ROOT_FD,) + .get_current_dir(inodes.deref_mut(), crate::VIRTUAL_ROOT_FD) { Ok(a) => a, Err(err) => { @@ -5981,8 +6462,7 @@ pub fn proc_exec( // If we are in a vfork we need to first spawn a subprocess of this type // with the forked WasiEnv, then do a longjmp back to the vfork point. - if let Some(mut vfork) = ctx.data_mut().vfork.take() - { + if let Some(mut vfork) = ctx.data_mut().vfork.take() { // We will need the child pid later let child_pid = ctx.data().process.pid(); @@ -5992,40 +6472,63 @@ pub fn proc_exec( let mut wasi_env = *vfork.env; wasi_env.owned_handles.push(vfork.handle); _prepare_wasi(&mut wasi_env, Some(args)); - + // Recrod the stack offsets before we give up ownership of the wasi_env let stack_base = wasi_env.stack_base; let stack_start = wasi_env.stack_start; - + // Spawn a new process with this current execution environment let mut err_exit_code = -2i32 as u32; let bus = ctx.data().bus(); let mut process = bus .spawn(wasi_env) - .spawn(Some(&ctx), name.as_str(), new_store, &ctx.data().bin_factory) + .spawn( + Some(&ctx), + name.as_str(), + new_store, + &ctx.data().bin_factory, + ) .map_err(|err| { err_exit_code = conv_bus_err_to_exit_code(err); - warn!("failed to execve as the process could not be spawned (vfork) - {}", err); - let _ = stderr_write(&ctx, format!("wasm execute failed [{}] - {}\n", name.as_str(), err).as_bytes()); + warn!( + "failed to execve as the process could not be spawned (vfork) - {}", + err + ); + let _ = stderr_write( + &ctx, + format!("wasm execute failed [{}] - {}\n", name.as_str(), err).as_bytes(), + ); err }) .ok(); - + // If no process was created then we create a dummy one so that an // exit code can be processed let process = match process { Some(a) => a, None => { - debug!("wasi[{}:{}]::process failed with (err={})", ctx.data().pid(), ctx.data().tid(), err_exit_code); + debug!( + "wasi[{}:{}]::process failed with (err={})", + ctx.data().pid(), + ctx.data().tid(), + err_exit_code + ); BusSpawnedProcess::exited_process(err_exit_code) } }; - + // Add the process to the environment state { - trace!("wasi[{}:{}]::spawned sub-process (pid={})", ctx.data().pid(), ctx.data().tid(), child_pid.raw()); + trace!( + "wasi[{}:{}]::spawned sub-process (pid={})", + ctx.data().pid(), + ctx.data().tid(), + child_pid.raw() + ); let mut inner = ctx.data().process.write(); - inner.bus_processes.insert(child_pid.into(), Box::new(process)); + inner + .bus_processes + .insert(child_pid.into(), Box::new(process)); } let mut memory_stack = vfork.memory_stack; @@ -6035,13 +6538,12 @@ pub fn proc_exec( // If the return value offset is within the memory stack then we need // to update it here rather than in the real memory let pid_offset: u64 = vfork.pid_offset.into(); - if pid_offset >= stack_start && pid_offset < stack_base - { + if pid_offset >= stack_start && pid_offset < stack_base { // Make sure its within the "active" part of the memory stack let offset = stack_base - pid_offset; if offset as usize > memory_stack.len() { warn!("vfork failed - the return value (pid) is outside of the active part of the memory stack ({} vs {})", offset, memory_stack.len()); - } else { + } else { // Update the memory stack with the new PID let val_bytes = child_pid.raw().to_ne_bytes(); let pstart = memory_stack.len() - offset as usize; @@ -6054,10 +6556,14 @@ pub fn proc_exec( } // Jump back to the vfork point and current on execution - unwind::(ctx, move |mut ctx, _, _| - { + unwind::(ctx, move |mut ctx, _, _| { // Rewind the stack - match rewind::(ctx, memory_stack.freeze(), rewind_stack.freeze(), store_data) { + match rewind::( + ctx, + memory_stack.freeze(), + rewind_stack.freeze(), + store_data, + ) { __WASI_ESUCCESS => OnCalledAction::InvokeAgain, err => { warn!("fork failed - could not rewind the stack - errno={}", err); @@ -6067,47 +6573,49 @@ pub fn proc_exec( })?; return Ok(()); } - // Otherwise we need to unwind the stack to get out of the current executing // callstack, steal the memory/WasiEnv and switch it over to a new thread // on the new module - else - { + else { // We need to unwind out of this process and launch a new process in its place - unwind::(ctx, move |mut ctx, _, _| - { + unwind::(ctx, move |mut ctx, _, _| { // Grab a reference to the bus let bus = ctx.data().bus().clone(); // Prepare the environment let mut wasi_env = ctx.data_mut().clone(); _prepare_wasi(&mut wasi_env, Some(args)); - + // Get a reference to the runtime let bin_factory = ctx.data().bin_factory.clone(); let tasks = wasi_env.tasks.clone(); // Create the process and drop the context - let builder = ctx.data().bus() - .spawn(wasi_env); - + let builder = ctx.data().bus().spawn(wasi_env); + // Spawn a new process with this current execution environment //let pid = wasi_env.process.pid(); - match builder.spawn(Some(&ctx), name.as_str(), new_store, &bin_factory) - { + match builder.spawn(Some(&ctx), name.as_str(), new_store, &bin_factory) { Ok(mut process) => { // Wait for the sub-process to exit itself - then we will exit loop { tasks.sleep_now(current_caller_id(), 5); if let Some(exit_code) = process.inst.exit_code() { - return OnCalledAction::Trap(Box::new(WasiError::Exit(exit_code as crate::syscalls::types::__wasi_exitcode_t))); + return OnCalledAction::Trap(Box::new(WasiError::Exit( + exit_code as crate::syscalls::types::__wasi_exitcode_t, + ))); } } } Err(err) => { - warn!("failed to execve as the process could not be spawned (fork) - {}", err); + warn!( + "failed to execve as the process could not be spawned (fork) - {}", + err + ); let exit_code = conv_bus_err_to_exit_code(err); - OnCalledAction::Trap(Box::new(WasiError::Exit(__WASI_ENOEXEC as crate::syscalls::types::__wasi_exitcode_t))) + OnCalledAction::Trap(Box::new(WasiError::Exit( + __WASI_ENOEXEC as crate::syscalls::types::__wasi_exitcode_t, + ))) } } })?; @@ -6124,8 +6632,12 @@ pub fn proc_exec( _name_len: M::Offset, _args: WasmPtr, _args_len: M::Offset, -) -> Result<(), WasiError> { - warn!("wasi[{}:{}]::exec is not supported in this build", ctx.data().pid(), ctx.data().tid()); +) -> Result<(), WasiError> { + warn!( + "wasi[{}:{}]::exec is not supported in this build", + ctx.data().pid(), + ctx.data().tid() + ); Err(WasiError::Exit(__WASI_ENOTSUP as __wasi_exitcode_t)) } @@ -6171,14 +6683,27 @@ pub fn proc_spawn( let args = unsafe { get_input_str_bus!(&memory, args, args_len) }; let preopen = unsafe { get_input_str_bus!(&memory, preopen, preopen_len) }; let working_dir = unsafe { get_input_str_bus!(&memory, working_dir, working_dir_len) }; - debug!("wasi[{}:{}]::process_spawn (name={})", ctx.data().pid(), ctx.data().tid(), name); + debug!( + "wasi[{}:{}]::process_spawn (name={})", + ctx.data().pid(), + ctx.data().tid(), + name + ); if chroot == __WASI_BOOL_TRUE { - warn!("wasi[{}:{}]::chroot is not currently supported", ctx.data().pid(), ctx.data().tid()); + warn!( + "wasi[{}:{}]::chroot is not currently supported", + ctx.data().pid(), + ctx.data().tid() + ); return __BUS_EUNSUPPORTED; } - let args: Vec<_> = args.split(&['\n', '\r']).map(|a| a.to_string()).filter(|a| a.len() > 0).collect(); + let args: Vec<_> = args + .split(&['\n', '\r']) + .map(|a| a.to_string()) + .filter(|a| a.len() > 0) + .collect(); let preopen: Vec<_> = preopen .split(&['\n', '\r']) @@ -6194,7 +6719,7 @@ pub fn proc_spawn( Some(working_dir), stdin, stdout, - stderr + stderr, ) { Ok(a) => a, Err(err) => { @@ -6218,8 +6743,7 @@ pub fn proc_spawn_internal( stdin: __wasi_stdiomode_t, stdout: __wasi_stdiomode_t, stderr: __wasi_stdiomode_t, -) -> Result<(__wasi_bus_handles_t, FunctionEnvMut<'_, WasiEnv>), __bus_errno_t> -{ +) -> Result<(__wasi_bus_handles_t, FunctionEnvMut<'_, WasiEnv>), __bus_errno_t> { let env = ctx.data(); // Build a new store that will be passed to the thread @@ -6246,7 +6770,12 @@ pub fn proc_spawn_internal( if let Some(preopen) = preopen { if preopen.is_empty() == false { for preopen in preopen { - warn!("wasi[{}:{}]::preopens are not yet supported for spawned processes [{}]", ctx.data().pid(), ctx.data().tid(), preopen); + warn!( + "wasi[{}:{}]::preopens are not yet supported for spawned processes [{}]", + ctx.data().pid(), + ctx.data().tid(), + preopen + ); } return Err(__BUS_EUNSUPPORTED); } @@ -6259,9 +6788,11 @@ pub fn proc_spawn_internal( // Replace the STDIO let (stdin, stdout, stderr) = { - let (_, child_state, mut child_inodes) = child_env.get_memory_and_wasi_state_and_inodes_mut(&new_store, 0); - let mut conv_stdio_mode = |mode: __wasi_stdiomode_t, fd: __wasi_fd_t| -> Result<__wasi_option_fd_t, __bus_errno_t> - { + let (_, child_state, mut child_inodes) = + child_env.get_memory_and_wasi_state_and_inodes_mut(&new_store, 0); + let mut conv_stdio_mode = |mode: __wasi_stdiomode_t, + fd: __wasi_fd_t| + -> Result<__wasi_option_fd_t, __bus_errno_t> { match mode { __WASI_STDIO_MODE_PIPED => { let (pipe1, pipe2) = WasiPipe::new(); @@ -6279,34 +6810,38 @@ pub fn proc_spawn_internal( ); let rights = super::state::all_socket_rights(); - let pipe = ctx.data().state.fs.create_fd(rights, rights, 0, 0, inode1)?; - child_state.fs.create_fd_ext(rights, rights, 0, 0, inode2, fd)?; - - trace!("wasi[{}:{}]::fd_pipe (fd1={}, fd2={})", ctx.data().pid(), ctx.data().tid(), pipe, fd); - Ok( - __wasi_option_fd_t { - tag: __WASI_OPTION_SOME, - fd: pipe - } - ) - }, - __WASI_STDIO_MODE_INHERIT => { - Ok( - __wasi_option_fd_t { - tag: __WASI_OPTION_NONE, - fd: u32::MAX - } - ) - }, + let pipe = ctx + .data() + .state + .fs + .create_fd(rights, rights, 0, 0, inode1)?; + child_state + .fs + .create_fd_ext(rights, rights, 0, 0, inode2, fd)?; + + trace!( + "wasi[{}:{}]::fd_pipe (fd1={}, fd2={})", + ctx.data().pid(), + ctx.data().tid(), + pipe, + fd + ); + Ok(__wasi_option_fd_t { + tag: __WASI_OPTION_SOME, + fd: pipe, + }) + } + __WASI_STDIO_MODE_INHERIT => Ok(__wasi_option_fd_t { + tag: __WASI_OPTION_NONE, + fd: u32::MAX, + }), __WASI_STDIO_MODE_LOG | __WASI_STDIO_MODE_NULL | _ => { child_state.fs.close_fd(child_inodes.deref(), fd); - Ok( - __wasi_option_fd_t { - tag: __WASI_OPTION_NONE, - fd: u32::MAX - } - ) - }, + Ok(__wasi_option_fd_t { + tag: __WASI_OPTION_NONE, + fd: u32::MAX, + }) + } } }; let stdin = conv_stdio_mode(stdin, 0)?; @@ -6319,9 +6854,14 @@ pub fn proc_spawn_internal( let bus = env.runtime.bus(); let mut process = bus .spawn(child_env) - .spawn(Some(&ctx), name.as_str(), new_store, &ctx.data().bin_factory) + .spawn( + Some(&ctx), + name.as_str(), + new_store, + &ctx.data().bin_factory, + ) .map_err(bus_error_into_wasi_err)?; - + // Add the process to the environment state let pid = env.process.pid(); { @@ -6364,9 +6904,12 @@ pub fn proc_spawn_internal( _stdin: __wasi_stdiomode_t, _stdout: __wasi_stdiomode_t, _stderr: __wasi_stdiomode_t, -) -> Result<(__wasi_bus_handles_t, FunctionEnvMut<'_, WasiEnv>), __bus_errno_t> -{ - warn!("wasi[{}:{}]::spawn is not currently supported", ctx.data().pid(), ctx.data().tid()); +) -> Result<(__wasi_bus_handles_t, FunctionEnvMut<'_, WasiEnv>), __bus_errno_t> { + warn!( + "wasi[{}:{}]::spawn is not currently supported", + ctx.data().pid(), + ctx.data().tid() + ); Err(__BUS_EUNSUPPORTED) } @@ -6384,17 +6927,28 @@ pub fn proc_join( let env = ctx.data(); let memory = env.memory_view(&ctx); let pid = wasi_try_mem_ok!(pid_ptr.read(&memory)); - trace!("wasi[{}:{}]::proc_join (pid={})", ctx.data().pid(), ctx.data().tid(), pid); + trace!( + "wasi[{}:{}]::proc_join (pid={})", + ctx.data().pid(), + ctx.data().tid(), + pid + ); // If the ID is maximum then it means wait for all the children if pid == u32::MAX { let _guard = WasiProcessWait::new(&ctx.data().process); loop { - ctx.data().clone().sleep(&mut ctx, std::time::Duration::from_millis(5))?; + ctx.data() + .clone() + .sleep(&mut ctx, std::time::Duration::from_millis(5))?; { let children = ctx.data().process.children.read().unwrap(); if children.is_empty() { - trace!("wasi[{}:{}]::no children", ctx.data().pid(), ctx.data().tid()); + trace!( + "wasi[{}:{}]::no children", + ctx.data().pid(), + ctx.data().tid() + ); let env = ctx.data(); let memory = env.memory_view(&ctx); wasi_try_mem_ok!(pid_ptr.write(&memory, -1i32 as __wasi_pid_t)); @@ -6402,8 +6956,18 @@ pub fn proc_join( return Ok(__WASI_ECHILD); } } - if let Some((pid, exit_code)) = wasi_try_ok!(ctx.data_mut().process.join_any_child(Duration::from_millis(0))) { - trace!("wasi[{}:{}]::child ({}) exited with {}", ctx.data().pid(), ctx.data().tid(), pid, exit_code); + if let Some((pid, exit_code)) = wasi_try_ok!(ctx + .data_mut() + .process + .join_any_child(Duration::from_millis(0))) + { + trace!( + "wasi[{}:{}]::child ({}) exited with {}", + ctx.data().pid(), + ctx.data().tid(), + pid, + exit_code + ); let env = ctx.data(); let memory = env.memory_view(&ctx); wasi_try_mem_ok!(pid_ptr.write(&memory, pid.raw() as __wasi_pid_t)); @@ -6416,7 +6980,11 @@ pub fn proc_join( // Otherwise we wait for the specific PID let env = ctx.data(); let pid: WasiProcessId = pid.into(); - let process = env.process.control_plane().get_process(pid).map(|a| a.clone()); + let process = env + .process + .control_plane() + .get_process(pid) + .map(|a| a.clone()); if let Some(process) = process { loop { env.yield_now()?; @@ -6435,7 +7003,10 @@ pub fn proc_join( children.retain(|a| *a != pid); Ok(__WASI_ESUCCESS) } else { - debug!("process already terminated or not registered (pid={})", pid.raw()); + debug!( + "process already terminated or not registered (pid={})", + pid.raw() + ); let memory = env.memory_view(&ctx); wasi_try_mem_ok!(pid_ptr.write(&memory, pid.raw() as __wasi_pid_t)); wasi_try_mem_ok!(exit_code_ptr.write(&memory, __WASI_ECHILD as u32)); @@ -6467,7 +7038,13 @@ pub fn bus_open_local( let memory = env.memory_view(&ctx); let name = unsafe { get_input_str_bus_ok!(&memory, name, name_len) }; let reuse = reuse == __WASI_BOOL_TRUE; - debug!("wasi[{}:{}]::bus_open_local (name={}, reuse={})", ctx.data().pid(), ctx.data().tid(), name, reuse); + debug!( + "wasi[{}:{}]::bus_open_local (name={}, reuse={})", + ctx.data().pid(), + ctx.data().tid(), + name, + reuse + ); bus_open_internal(ctx, name, reuse, None, None, ret_bid) } @@ -6565,7 +7142,12 @@ fn bus_open_internal( /// /// * `bid` - Handle of the bus process handle to be closed pub fn bus_close(ctx: FunctionEnvMut<'_, WasiEnv>, bid: __wasi_bid_t) -> __bus_errno_t { - trace!("wasi[{}:{}]::bus_close (bid={})", ctx.data().pid(), ctx.data().tid(), bid); + trace!( + "wasi[{}:{}]::bus_close (bid={})", + ctx.data().pid(), + ctx.data().tid(), + bid + ); let bid: WasiProcessId = bid.into(); let env = ctx.data(); @@ -6604,29 +7186,25 @@ pub fn bus_call( let memory = env.memory_view(&ctx); let topic_hash = wasi_try_mem_bus_ok!(topic_hash.read(&memory)); let buf_slice = wasi_try_mem_bus_ok!(buf.slice(&memory, buf_len)); - trace!( - "wasi::bus_call (bid={}, buf_len={})", - bid, - buf_len - ); + trace!("wasi::bus_call (bid={}, buf_len={})", bid, buf_len); // Get the process that we'll invoke this call for let mut guard = env.process.read(); let bid: WasiProcessId = bid.into(); - let process = if let Some(process) = { - guard.bus_processes.get(&bid) - } { process } else { + let process = if let Some(process) = { guard.bus_processes.get(&bid) } { + process + } else { return Ok(__BUS_EBADHANDLE); }; // Invoke the bus process let format = wasi_try_bus_ok!(conv_bus_format_from(format)); - + // Check if the process has finished if let Some(code) = process.inst.exit_code() { debug!("process has already exited (code = {})", code); return Ok(__BUS_EABORTED); - } + } // Invoke the call let buf = wasi_try_mem_bus_ok!(buf_slice.read_to_vec()); @@ -6643,9 +7221,8 @@ pub fn bus_call( let pinned_invoked = Pin::new(invoked.deref_mut()); match pinned_invoked.poll_invoked(&mut cx) { Poll::Ready(i) => { - invocation = wasi_try_bus_ok!(i - .map_err(bus_error_into_wasi_err)); - }, + invocation = wasi_try_bus_ok!(i.map_err(bus_error_into_wasi_err)); + } Poll::Pending => { // Slow path (will put the thread to sleep) let parking = WasiParkingLot::default(); @@ -6655,16 +7232,15 @@ pub fn bus_call( let pinned_invoked = Pin::new(invoked.deref_mut()); match pinned_invoked.poll_invoked(&mut cx) { Poll::Ready(i) => { - invocation = wasi_try_bus_ok!(i - .map_err(bus_error_into_wasi_err)); + invocation = wasi_try_bus_ok!(i.map_err(bus_error_into_wasi_err)); break; - }, + } Poll::Pending => { env.yield_now()?; parking.wait(Duration::from_millis(5)); } } - } + } } } } @@ -6674,10 +7250,7 @@ pub fn bus_call( let mut guard = env.state.bus.protected(); guard.call_seed += 1; let cid = guard.call_seed; - guard.calls.insert(cid, WasiBusCall { - bid, - invocation - }); + guard.calls.insert(cid, WasiBusCall { bid, invocation }); cid }; @@ -6716,19 +7289,14 @@ pub fn bus_subcall( let memory = env.memory_view(&ctx); let topic_hash = wasi_try_mem_bus_ok!(topic_hash.read(&memory)); let buf_slice = wasi_try_mem_bus_ok!(buf.slice(&memory, buf_len)); - trace!( - "wasi::bus_subcall (parent={}, buf_len={})", - parent, - buf_len - ); + trace!("wasi::bus_subcall (parent={}, buf_len={})", parent, buf_len); let format = wasi_try_bus_ok!(conv_bus_format_from(format)); let buf = wasi_try_mem_bus_ok!(buf_slice.read_to_vec()); // Get the parent call that we'll invoke this call for let mut guard = env.state.bus.protected(); - if let Some(parent) = guard.calls.get(&parent) - { + if let Some(parent) = guard.calls.get(&parent) { let bid = parent.bid.clone(); // Invoke the sub-call in the existing parent call @@ -6745,9 +7313,8 @@ pub fn bus_subcall( let pinned_invoked = Pin::new(invoked.deref_mut()); match pinned_invoked.poll_invoked(&mut cx) { Poll::Ready(i) => { - invocation = wasi_try_bus_ok!(i - .map_err(bus_error_into_wasi_err)); - }, + invocation = wasi_try_bus_ok!(i.map_err(bus_error_into_wasi_err)); + } Poll::Pending => { // Slow path (will put the thread to sleep) let parking = WasiParkingLot::default(); @@ -6757,10 +7324,9 @@ pub fn bus_subcall( let pinned_invoked = Pin::new(invoked.deref_mut()); match pinned_invoked.poll_invoked(&mut cx) { Poll::Ready(i) => { - invocation = wasi_try_bus_ok!(i - .map_err(bus_error_into_wasi_err)); + invocation = wasi_try_bus_ok!(i.map_err(bus_error_into_wasi_err)); break; - }, + } Poll::Pending => { env.yield_now()?; parking.wait(Duration::from_millis(5)); @@ -6770,16 +7336,13 @@ pub fn bus_subcall( } } } - + // Add the call and return the ID let cid = { let mut guard = env.state.bus.protected(); guard.call_seed += 1; let cid = guard.call_seed; - guard.calls.insert(cid, WasiBusCall { - bid, - invocation - }); + guard.calls.insert(cid, WasiBusCall { bid, invocation }); cid }; @@ -6809,17 +7372,17 @@ fn conv_bus_format(format: BusDataFormat) -> __wasi_busdataformat_t { } fn conv_bus_format_from(format: __wasi_busdataformat_t) -> Result { - Ok( - match format { - __WASI_BUS_DATA_FORMAT_RAW => BusDataFormat::Raw, - __WASI_BUS_DATA_FORMAT_BINCODE => BusDataFormat::Bincode, - __WASI_BUS_DATA_FORMAT_MESSAGE_PACK => BusDataFormat::MessagePack, - __WASI_BUS_DATA_FORMAT_JSON => BusDataFormat::Json, - __WASI_BUS_DATA_FORMAT_YAML => BusDataFormat::Yaml, - __WASI_BUS_DATA_FORMAT_XML => BusDataFormat::Xml, - _ => { return Err(__BUS_EDES); } + Ok(match format { + __WASI_BUS_DATA_FORMAT_RAW => BusDataFormat::Raw, + __WASI_BUS_DATA_FORMAT_BINCODE => BusDataFormat::Bincode, + __WASI_BUS_DATA_FORMAT_MESSAGE_PACK => BusDataFormat::MessagePack, + __WASI_BUS_DATA_FORMAT_JSON => BusDataFormat::Json, + __WASI_BUS_DATA_FORMAT_YAML => BusDataFormat::Yaml, + __WASI_BUS_DATA_FORMAT_XML => BusDataFormat::Xml, + _ => { + return Err(__BUS_EDES); } - ) + }) } /// Polls for any outstanding events from a particular @@ -6847,16 +7410,20 @@ pub fn bus_poll( let env = ctx.data(); let bus = env.runtime.bus(); let memory = env.memory_view(&ctx); - trace!("wasi[{}:{}]::bus_poll (timeout={})", ctx.data().pid(), ctx.data().tid(), timeout); + trace!( + "wasi[{}:{}]::bus_poll (timeout={})", + ctx.data().pid(), + ctx.data().tid(), + timeout + ); // Lets start by processing events for calls that are already running let mut nevents = M::ZERO; let events = wasi_try_mem_bus_ok!(events.slice(&memory, maxevents)); - + let state = env.state.clone(); let start = platform_clock_time_get(__WASI_CLOCK_MONOTONIC, 1_000_000).unwrap() as u128; - loop - { + loop { // The waker will wake this thread should any work arrive // or need further processing (i.e. async operation) let waker = state.bus.get_poll_waker(); @@ -6880,10 +7447,10 @@ pub fn bus_poll( { // The waker will trigger the reactors when work arrives from the BUS let mut guard = env.state.bus.protected(); - + // Function that hashes the topic using SHA256 let hash_topic = |topic: Cow<'static, str>| -> __wasi_hash_t { - use sha2::{Sha256, Digest}; + use sha2::{Digest, Sha256}; let mut hasher = Sha256::new(); hasher.update(&topic.bytes().collect::>()); let hash: [u8; 16] = hasher.finalize()[..16].try_into().unwrap(); @@ -6903,14 +7470,19 @@ pub fn bus_poll( "bus".into(), ); let rights = super::state::bus_read_rights(); - wasi_try_bus!(state.fs.create_fd(rights, rights, 0, 0, inode) + wasi_try_bus!(state + .fs + .create_fd(rights, rights, 0, 0, inode) .map_err(|err| { - debug!("failed to create file descriptor for BUS event buffer - {}", err); + debug!( + "failed to create file descriptor for BUS event buffer - {}", + err + ); __BUS_EALLOC })) } }; - + // Grab all the events we can from all the existing calls up to the limit of // maximum events that the user requested if nevents < maxevents { @@ -6926,20 +7498,26 @@ pub fn bus_poll( // If the process that is hosting the call is finished then so is the call if exited_bids.contains(&call.bid) { drop_calls.push(*key); - trace!("wasi[{}:{}]::bus_poll (aborted, cid={})", ctx.data().pid(), ctx.data().tid(), cid); + trace!( + "wasi[{}:{}]::bus_poll (aborted, cid={})", + ctx.data().pid(), + ctx.data().tid(), + cid + ); let evt = unsafe { std::mem::transmute(__wasi_busevent_t2 { tag: __WASI_BUS_EVENT_TYPE_FAULT, u: __wasi_busevent_u { fault: __wasi_busevent_fault_t { cid, - err: __BUS_EABORTED - } - } + err: __BUS_EABORTED, + }, + }, }) }; - - let nevents64: u64 = wasi_try_bus_ok!(nevents.try_into().map_err(|_| __BUS_EINTERNAL)); + + let nevents64: u64 = + wasi_try_bus_ok!(nevents.try_into().map_err(|_| __BUS_EINTERNAL)); wasi_try_mem_bus_ok!(events.write(nevents64, evt)); nevents += M::ONE; @@ -6951,15 +7529,18 @@ pub fn bus_poll( let mut finished = false; let call = Pin::new(call.invocation.as_mut()); match call.poll_event(&mut cx) { - Poll::Ready(evt) => - { + Poll::Ready(evt) => { let evt = match evt { - BusInvocationEvent::Callback { topic_hash, format, data } => { + BusInvocationEvent::Callback { + topic_hash, + format, + data, + } => { let sub_cid = { call_seed += 1; call_seed }; - + trace!("wasi[{}:{}]::bus_poll (callback, parent={}, cid={}, topic={})", ctx.data().pid(), ctx.data().tid(), cid, sub_cid, topic_hash); __wasi_busevent_t2 { tag: __WASI_BUS_EVENT_TYPE_CALL, @@ -6972,16 +7553,22 @@ pub fn bus_poll( cid: sub_cid, format: conv_bus_format(format), topic_hash, - fd: buf_to_fd(data), - } - } + fd: buf_to_fd(data), + }, + }, } - }, + } BusInvocationEvent::Response { format, data } => { drop_calls.push(*key); finished = true; - trace!("wasi[{}:{}]::bus_poll (response, cid={}, len={})", ctx.data().pid(), ctx.data().tid(), cid, data.len()); + trace!( + "wasi[{}:{}]::bus_poll (response, cid={}, len={})", + ctx.data().pid(), + ctx.data().tid(), + cid, + data.len() + ); __wasi_busevent_t2 { tag: __WASI_BUS_EVENT_TYPE_RESULT, u: __wasi_busevent_u { @@ -6989,31 +7576,37 @@ pub fn bus_poll( format: conv_bus_format(format), cid, fd: buf_to_fd(data), - } - } + }, + }, } - }, + } BusInvocationEvent::Fault { fault } => { drop_calls.push(*key); finished = true; - trace!("wasi[{}:{}]::bus_poll (fault, cid={}, err={})", ctx.data().pid(), ctx.data().tid(), cid, fault); + trace!( + "wasi[{}:{}]::bus_poll (fault, cid={}, err={})", + ctx.data().pid(), + ctx.data().tid(), + cid, + fault + ); __wasi_busevent_t2 { tag: __WASI_BUS_EVENT_TYPE_FAULT, u: __wasi_busevent_u { fault: __wasi_busevent_fault_t { cid, - err: bus_error_into_wasi_err(fault) - } - } + err: bus_error_into_wasi_err(fault), + }, + }, } } }; - let evt = unsafe { - std::mem::transmute(evt) - }; - - let nevents64: u64 = wasi_try_bus_ok!(nevents.try_into().map_err(|_| __BUS_EINTERNAL)); + let evt = unsafe { std::mem::transmute(evt) }; + + let nevents64: u64 = wasi_try_bus_ok!(nevents + .try_into() + .map_err(|_| __BUS_EINTERNAL)); wasi_try_mem_bus_ok!(events.write(nevents64, evt)); nevents += M::ONE; @@ -7021,8 +7614,10 @@ pub fn bus_poll( if finished { break; } - }, - Poll::Pending => { break; } + } + Poll::Pending => { + break; + } } } } @@ -7064,18 +7659,20 @@ pub fn bus_poll( format: conv_bus_format(event.format), topic_hash: event.topic_hash, fd: buf_to_fd(event.data), - } - } + }, + }, }; - let event = unsafe { - std::mem::transmute(event) - }; - - let nevents64: u64 = wasi_try_bus_ok!(nevents.try_into().map_err(|_| __BUS_EINTERNAL)); + let event = unsafe { std::mem::transmute(event) }; + + let nevents64: u64 = wasi_try_bus_ok!(nevents + .try_into() + .map_err(|_| __BUS_EINTERNAL)); wasi_try_mem_bus_ok!(events.write(nevents64, event)); nevents += M::ONE; - }, - Poll::Pending => { break; } + } + Poll::Pending => { + break; + } }; } if nevents >= maxevents { @@ -7089,14 +7686,11 @@ pub fn bus_poll( } } - while nevents < maxevents - { + while nevents < maxevents { // Check the listener (if none exists then one is created) let event = { let bus = env.runtime.bus(); - let listener = wasi_try_bus_ok!(bus - .listen() - .map_err(bus_error_into_wasi_err)); + let listener = wasi_try_bus_ok!(bus.listen().map_err(bus_error_into_wasi_err)); let listener = Pin::new(listener.deref()); listener.poll(&mut cx) }; @@ -7104,7 +7698,6 @@ pub fn bus_poll( // Process the event returned by the listener or exit the poll loop let event = match event { Poll::Ready(event) => { - // Register the call let sub_cid = { guard.call_seed += 1; @@ -7125,17 +7718,18 @@ pub fn bus_poll( format: conv_bus_format(event.format), topic_hash: event.topic_hash, fd: buf_to_fd(event.data), - } - } + }, + }, } - }, - Poll::Pending => { break; } + } + Poll::Pending => { + break; + } }; - let event = unsafe { - std::mem::transmute(event) - }; - - let nevents64: u64 = wasi_try_bus_ok!(nevents.try_into().map_err(|_| __BUS_EINTERNAL)); + let event = unsafe { std::mem::transmute(event) }; + + let nevents64: u64 = + wasi_try_bus_ok!(nevents.try_into().map_err(|_| __BUS_EINTERNAL)); wasi_try_mem_bus_ok!(events.write(nevents64, event)); nevents += M::ONE; } @@ -7145,7 +7739,7 @@ pub fn bus_poll( if nevents >= M::ONE { break; } - + // Every 100 milliseconds we check if the thread needs to terminate (via `env.yield_now`) // otherwise the loop will break if the BUS futex is triggered or a timeout is reached loop { @@ -7153,7 +7747,11 @@ pub fn bus_poll( let now = platform_clock_time_get(__WASI_CLOCK_MONOTONIC, 1_000_000).unwrap() as u128; let delta = now.checked_sub(start).unwrap_or(0) as __wasi_timestamp_t; if delta >= timeout { - trace!("wasi[{}:{}]::bus_poll (timeout)", ctx.data().pid(), ctx.data().tid()); + trace!( + "wasi[{}:{}]::bus_poll (timeout)", + ctx.data().pid(), + ctx.data().tid() + ); wasi_try_mem_bus_ok!(ret_nevents.write(&memory, nevents)); return Ok(__BUS_ESUCCESS); } @@ -7170,9 +7768,18 @@ pub fn bus_poll( } } if nevents > M::ZERO { - trace!("wasi[{}:{}]::bus_poll (return nevents={})", ctx.data().pid(), ctx.data().tid(), nevents); + trace!( + "wasi[{}:{}]::bus_poll (return nevents={})", + ctx.data().pid(), + ctx.data().tid(), + nevents + ); } else { - trace!("wasi[{}:{}]::bus_poll (idle - no events)", ctx.data().pid(), ctx.data().tid()); + trace!( + "wasi[{}:{}]::bus_poll (idle - no events)", + ctx.data().pid(), + ctx.data().tid() + ); } wasi_try_mem_bus_ok!(ret_nevents.write(&memory, nevents)); @@ -7187,7 +7794,12 @@ pub fn bus_poll( maxevents: M::Offset, ret_nevents: WasmPtr, ) -> Result<__bus_errno_t, WasiError> { - trace!("wasi[{}:{}]::bus_poll (timeout={}) is not supported without 'os' feature", ctx.data().pid(), ctx.data().tid(), timeout); + trace!( + "wasi[{}:{}]::bus_poll (timeout={}) is not supported without 'os' feature", + ctx.data().pid(), + ctx.data().tid(), + timeout + ); Ok(__BUS_EUNSUPPORTED) } @@ -7240,14 +7852,16 @@ pub fn call_reply( /// /// * `cid` - Handle of the call to raise a fault on /// * `fault` - Fault to be raised on the bus -pub fn call_fault( - ctx: FunctionEnvMut<'_, WasiEnv>, - cid: __wasi_cid_t, - fault: __bus_errno_t) -{ +pub fn call_fault(ctx: FunctionEnvMut<'_, WasiEnv>, cid: __wasi_cid_t, fault: __bus_errno_t) { let env = ctx.data(); let bus = env.runtime.bus(); - debug!("wasi[{}:{}]::call_fault (cid={}, fault={})", ctx.data().pid(), ctx.data().tid(), cid, fault); + debug!( + "wasi[{}:{}]::call_fault (cid={}, fault={})", + ctx.data().pid(), + ctx.data().tid(), + cid, + fault + ); let mut guard = env.state.bus.protected(); guard.calls.remove(&cid); @@ -7263,13 +7877,15 @@ pub fn call_fault( /// ## Parameters /// /// * `cid` - Handle of the bus call handle to be dropped -pub fn call_close( - ctx: FunctionEnvMut<'_, WasiEnv>, - cid: __wasi_cid_t -) { +pub fn call_close(ctx: FunctionEnvMut<'_, WasiEnv>, cid: __wasi_cid_t) { let env = ctx.data(); let bus = env.runtime.bus(); - trace!("wasi[{}:{}]::call_close (cid={})", ctx.data().pid(), ctx.data().tid(), cid); + trace!( + "wasi[{}:{}]::call_close (cid={})", + ctx.data().pid(), + ctx.data().tid(), + cid + ); let mut guard = env.state.bus.protected(); guard.calls.remove(&cid); @@ -7292,23 +7908,22 @@ pub fn ws_connect( url_len: M::Offset, ret_sock: WasmPtr<__wasi_fd_t, M>, ) -> __wasi_errno_t { - debug!("wasi[{}:{}]::ws_connect", ctx.data().pid(), ctx.data().tid()); + debug!( + "wasi[{}:{}]::ws_connect", + ctx.data().pid(), + ctx.data().tid() + ); let env = ctx.data(); let memory = env.memory_view(&ctx); let url = unsafe { get_input_str!(&memory, url, url_len) }; let net = env.net(); let tasks = env.tasks.clone(); - let socket = wasi_try!( - __asyncify( - tasks, - &env.thread, - None, - async move { - net.ws_connect(url.as_str()).await.map_err(net_error_into_wasi_err) - } - ) - ); + let socket = wasi_try!(__asyncify(tasks, &env.thread, None, async move { + net.ws_connect(url.as_str()) + .await + .map_err(net_error_into_wasi_err) + })); let (memory, state, mut inodes) = env.get_memory_and_wasi_state_and_inodes_mut(&ctx, 0); @@ -7316,16 +7931,12 @@ pub fn ws_connect( socket: InodeSocket::new(InodeSocketKind::WebSocket(socket)), }; - let inode = state.fs.create_inode_with_default_stat( - inodes.deref_mut(), - kind, - false, - "socket".into(), - ); - let rights = Rights::all_socket(); - let fd = wasi_try!(state - .fs - .create_fd(rights, rights, Fdflags::empty(), 0, inode)); + let inode = + state + .fs + .create_inode_with_default_stat(inodes.deref_mut(), kind, false, "socket".into()); + let rights = super::state::all_socket_rights(); + let fd = wasi_try!(state.fs.create_fd(rights, rights, 0, 0, inode)); wasi_try_mem!(ret_sock.write(&memory, fd)); @@ -7359,7 +7970,11 @@ pub fn http_request( gzip: __wasi_bool_t, ret_handles: WasmPtr<__wasi_http_handles_t, M>, ) -> __wasi_errno_t { - debug!("wasi[{}:{}]::http_request", ctx.data().pid(), ctx.data().tid()); + debug!( + "wasi[{}:{}]::http_request", + ctx.data().pid(), + ctx.data().tid() + ); let env = ctx.data(); let memory = env.memory_view(&ctx); let url = unsafe { get_input_str!(&memory, url, url_len) }; @@ -7374,16 +7989,11 @@ pub fn http_request( let net = env.net(); let tasks = env.tasks.clone(); - let socket = wasi_try!( - __asyncify( - tasks, - &env.thread, - None, - async move { - net.http_request(url.as_str(), method.as_str(), headers.as_str(), gzip).await.map_err(net_error_into_wasi_err) - } - ) - ); + let socket = wasi_try!(__asyncify(tasks, &env.thread, None, async move { + net.http_request(url.as_str(), method.as_str(), headers.as_str(), gzip) + .await + .map_err(net_error_into_wasi_err) + })); let socket_req = SocketHttpRequest { request: socket.request, response: None, @@ -7474,7 +8084,11 @@ pub fn http_status( sock: __wasi_fd_t, status: WasmPtr<__wasi_http_status_t, M>, ) -> __wasi_errno_t { - debug!("wasi[{}:{}]::http_status", ctx.data().pid(), ctx.data().tid()); + debug!( + "wasi[{}:{}]::http_status", + ctx.data().pid(), + ctx.data().tid() + ); let env = ctx.data(); let memory = env.memory_view(&ctx); @@ -7516,7 +8130,11 @@ pub fn port_bridge( token_len: M::Offset, security: __wasi_streamsecurity_t, ) -> __wasi_errno_t { - debug!("wasi[{}:{}]::port_bridge", ctx.data().pid(), ctx.data().tid()); + debug!( + "wasi[{}:{}]::port_bridge", + ctx.data().pid(), + ctx.data().tid() + ); let env = ctx.data(); let memory = env.memory_view(&ctx); let network = unsafe { get_input_str!(&memory, network, network_len) }; @@ -7539,7 +8157,11 @@ pub fn port_bridge( /// ### `port_unbridge()` /// Disconnects from a remote network pub fn port_unbridge(ctx: FunctionEnvMut<'_, WasiEnv>) -> __wasi_errno_t { - debug!("wasi[{}:{}]::port_unbridge", ctx.data().pid(), ctx.data().tid()); + debug!( + "wasi[{}:{}]::port_unbridge", + ctx.data().pid(), + ctx.data().tid() + ); let env = ctx.data(); wasi_try!(env.net().unbridge().map_err(net_error_into_wasi_err)); Errno::Success @@ -7548,20 +8170,17 @@ pub fn port_unbridge(ctx: FunctionEnvMut<'_, WasiEnv>) -> __wasi_errno_t { /// ### `port_dhcp_acquire()` /// Acquires a set of IP addresses using DHCP pub fn port_dhcp_acquire(ctx: FunctionEnvMut<'_, WasiEnv>) -> __wasi_errno_t { - debug!("wasi[{}:{}]::port_dhcp_acquire", ctx.data().pid(), ctx.data().tid()); + debug!( + "wasi[{}:{}]::port_dhcp_acquire", + ctx.data().pid(), + ctx.data().tid() + ); let env = ctx.data(); let net = env.net(); let tasks = env.tasks.clone(); - wasi_try!( - __asyncify( - tasks, - &env.thread, - None, - async move { - net.dhcp_acquire().await.map_err(net_error_into_wasi_err) - } - ) - ); + wasi_try!(__asyncify(tasks, &env.thread, None, async move { + net.dhcp_acquire().await.map_err(net_error_into_wasi_err) + })); __WASI_ESUCCESS } @@ -7575,7 +8194,11 @@ pub fn port_addr_add( ctx: FunctionEnvMut<'_, WasiEnv>, ip: WasmPtr<__wasi_cidr_t, M>, ) -> __wasi_errno_t { - debug!("wasi[{}:{}]::port_addr_add", ctx.data().pid(), ctx.data().tid()); + debug!( + "wasi[{}:{}]::port_addr_add", + ctx.data().pid(), + ctx.data().tid() + ); let env = ctx.data(); let memory = env.memory_view(&ctx); let cidr = wasi_try!(super::state::read_cidr(&memory, ip)); @@ -7596,7 +8219,11 @@ pub fn port_addr_remove( ctx: FunctionEnvMut<'_, WasiEnv>, ip: WasmPtr<__wasi_addr_t, M>, ) -> __wasi_errno_t { - debug!("wasi[{}:{}]::port_addr_remove", ctx.data().pid(), ctx.data().tid()); + debug!( + "wasi[{}:{}]::port_addr_remove", + ctx.data().pid(), + ctx.data().tid() + ); let env = ctx.data(); let memory = env.memory_view(&ctx); let ip = wasi_try!(super::state::read_ip(&memory, ip)); @@ -7607,7 +8234,11 @@ pub fn port_addr_remove( /// ### `port_addr_clear()` /// Clears all the addresses on the local port pub fn port_addr_clear(ctx: FunctionEnvMut<'_, WasiEnv>) -> __wasi_errno_t { - debug!("wasi[{}:{}]::port_addr_clear", ctx.data().pid(), ctx.data().tid()); + debug!( + "wasi[{}:{}]::port_addr_clear", + ctx.data().pid(), + ctx.data().tid() + ); let env = ctx.data(); wasi_try!(env.net().ip_clear().map_err(net_error_into_wasi_err)); Errno::Success @@ -7646,7 +8277,11 @@ pub fn port_addr_list( addrs: WasmPtr<__wasi_cidr_t, M>, naddrs: WasmPtr, ) -> __wasi_errno_t { - debug!("wasi[{}:{}]::port_addr_list", ctx.data().pid(), ctx.data().tid()); + debug!( + "wasi[{}:{}]::port_addr_list", + ctx.data().pid(), + ctx.data().tid() + ); let env = ctx.data(); let memory = env.memory_view(&ctx); let max_addrs = wasi_try_mem!(naddrs.read(&memory)); @@ -7680,7 +8315,11 @@ pub fn port_gateway_set( ctx: FunctionEnvMut<'_, WasiEnv>, ip: WasmPtr<__wasi_addr_t, M>, ) -> __wasi_errno_t { - debug!("wasi[{}:{}]::port_gateway_set", ctx.data().pid(), ctx.data().tid()); + debug!( + "wasi[{}:{}]::port_gateway_set", + ctx.data().pid(), + ctx.data().tid() + ); let env = ctx.data(); let memory = env.memory_view(&ctx); let ip = wasi_try!(super::state::read_ip(&memory, ip)); @@ -7698,7 +8337,11 @@ pub fn port_route_add( preferred_until: WasmPtr<__wasi_option_timestamp_t, M>, expires_at: WasmPtr<__wasi_option_timestamp_t, M>, ) -> __wasi_errno_t { - debug!("wasi[{}:{}]::port_route_add", ctx.data().pid(), ctx.data().tid()); + debug!( + "wasi[{}:{}]::port_route_add", + ctx.data().pid(), + ctx.data().tid() + ); let env = ctx.data(); let memory = env.memory_view(&ctx); let cidr = wasi_try!(super::state::read_cidr(&memory, cidr)); @@ -7729,7 +8372,11 @@ pub fn port_route_remove( ctx: FunctionEnvMut<'_, WasiEnv>, ip: WasmPtr<__wasi_addr_t, M>, ) -> __wasi_errno_t { - debug!("wasi[{}:{}]::port_route_remove", ctx.data().pid(), ctx.data().tid()); + debug!( + "wasi[{}:{}]::port_route_remove", + ctx.data().pid(), + ctx.data().tid() + ); let env = ctx.data(); let memory = env.memory_view(&ctx); let ip = wasi_try!(super::state::read_ip(&memory, ip)); @@ -7740,7 +8387,11 @@ pub fn port_route_remove( /// ### `port_route_clear()` /// Clears all the routes in the local port pub fn port_route_clear(ctx: FunctionEnvMut<'_, WasiEnv>) -> __wasi_errno_t { - debug!("wasi[{}:{}]::port_route_clear", ctx.data().pid(), ctx.data().tid()); + debug!( + "wasi[{}:{}]::port_route_clear", + ctx.data().pid(), + ctx.data().tid() + ); let env = ctx.data(); wasi_try!(env.net().route_clear().map_err(net_error_into_wasi_err)); Errno::Success @@ -7760,15 +8411,18 @@ pub fn port_route_list( routes: WasmPtr, nroutes: WasmPtr, ) -> __wasi_errno_t { - debug!("wasi[{}:{}]::port_route_list", ctx.data().pid(), ctx.data().tid()); + debug!( + "wasi[{}:{}]::port_route_list", + ctx.data().pid(), + ctx.data().tid() + ); let env = ctx.data(); let memory = env.memory_view(&ctx); let nroutes = nroutes.deref(&memory); let max_routes: usize = wasi_try!(wasi_try_mem!(nroutes.read()) .try_into() .map_err(|_| __WASI_EINVAL)); - let ref_routes = - wasi_try_mem!(routes.slice(&memory, wasi_try!(to_offset::(max_routes)))); + let ref_routes = wasi_try_mem!(routes.slice(&memory, wasi_try!(to_offset::(max_routes)))); let routes = wasi_try!(env.net().route_list().map_err(net_error_into_wasi_err)); @@ -7802,7 +8456,12 @@ pub fn sock_shutdown( sock: __wasi_fd_t, how: __wasi_sdflags_t, ) -> __wasi_errno_t { - debug!("wasi[{}:{}]::sock_shutdown (fd={})", ctx.data().pid(), ctx.data().tid(), sock); + debug!( + "wasi[{}:{}]::sock_shutdown (fd={})", + ctx.data().pid(), + ctx.data().tid(), + sock + ); let both = __WASI_SHUT_RD | __WASI_SHUT_WR; let how = match how { @@ -7816,9 +8475,7 @@ pub fn sock_shutdown( &ctx, sock, __WASI_RIGHT_SOCK_SHUTDOWN, - move |socket| async move { - socket.shutdown(how).await - } + move |socket| async move { socket.shutdown(how).await } )); Errno::Success @@ -7831,9 +8488,16 @@ pub fn sock_status( sock: __wasi_fd_t, ret_status: WasmPtr<__wasi_sockstatus_t, M>, ) -> __wasi_errno_t { - debug!("wasi[{}:{}]::sock_status (fd={})", ctx.data().pid(), ctx.data().tid(), sock); + debug!( + "wasi[{}:{}]::sock_status (fd={})", + ctx.data().pid(), + ctx.data().tid(), + sock + ); - let status = wasi_try!(__sock_actor(&ctx, sock, 0, move |socket| async move { socket.status() })); + let status = wasi_try!(__sock_actor(&ctx, sock, 0, move |socket| async move { + socket.status() + })); use super::state::WasiSocketStatus; let status = match status { @@ -7866,7 +8530,12 @@ pub fn sock_addr_local( sock: WasiFd, ret_addr: WasmPtr<__wasi_addr_port_t, M>, ) -> __wasi_errno_t { - debug!("wasi[{}:{}]::sock_addr_local (fd={})", ctx.data().pid(), ctx.data().tid(), sock); + debug!( + "wasi[{}:{}]::sock_addr_local (fd={})", + ctx.data().pid(), + ctx.data().tid(), + sock + ); let addr = wasi_try!(__sock_actor(&ctx, sock, 0, move |socket| async move { socket.addr_local() @@ -7897,10 +8566,17 @@ pub fn sock_addr_peer( sock: WasiFd, ro_addr: WasmPtr<__wasi_addr_port_t, M>, ) -> __wasi_errno_t { - debug!("wasi[{}:{}]::sock_addr_peer (fd={})", ctx.data().pid(), ctx.data().tid(), sock); + debug!( + "wasi[{}:{}]::sock_addr_peer (fd={})", + ctx.data().pid(), + ctx.data().tid(), + sock + ); let env = ctx.data(); - let addr = wasi_try!(__sock_actor(&ctx, sock, 0, move |socket| async move { socket.addr_peer() })); + let addr = wasi_try!(__sock_actor(&ctx, sock, 0, move |socket| async move { + socket.addr_peer() + })); let memory = env.memory_view(&ctx); wasi_try!(super::state::write_ip_port( &memory, @@ -7964,16 +8640,12 @@ pub fn sock_open( _ => return Errno::Notsup, }; - let inode = state.fs.create_inode_with_default_stat( - inodes.deref_mut(), - kind, - false, - "socket".into(), - ); - let rights = Rights::all_socket(); - let fd = wasi_try!(state - .fs - .create_fd(rights, rights, Fdflags::empty(), 0, inode)); + let inode = + state + .fs + .create_inode_with_default_stat(inodes.deref_mut(), kind, false, "socket".into()); + let rights = super::state::all_socket_rights(); + let fd = wasi_try!(state.fs.create_fd(rights, rights, 0, 0, inode)); wasi_try_mem!(ro_sock.write(&memory, fd)); @@ -7995,7 +8667,14 @@ pub fn sock_set_opt_flag( opt: __wasi_sockoption_t, flag: __wasi_bool_t, ) -> __wasi_errno_t { - debug!("wasi[{}:{}]::sock_set_opt_flag(fd={}, ty={}, flag={})", ctx.data().pid(), ctx.data().tid(), sock, opt, flag); + debug!( + "wasi[{}:{}]::sock_set_opt_flag(fd={}, ty={}, flag={})", + ctx.data().pid(), + ctx.data().tid(), + sock, + opt, + flag + ); let flag = match flag { Bool::False => false, @@ -8004,7 +8683,7 @@ pub fn sock_set_opt_flag( }; let option: super::state::WasiSocketOption = opt.into(); - wasi_try!(__sock_actor_mut(&ctx, sock, 0, move |socket| async move { + wasi_try!(__sock_actor_mut(&ctx, sock, 0, move |socket| async move { socket.set_opt_flag(option, flag) })); Errno::Success @@ -8024,7 +8703,13 @@ pub fn sock_get_opt_flag( opt: __wasi_sockoption_t, ret_flag: WasmPtr<__wasi_bool_t, M>, ) -> __wasi_errno_t { - debug!("wasi[{}:{}]::sock_get_opt_flag(fd={}, ty={})", ctx.data().pid(), ctx.data().tid(), sock, opt); + debug!( + "wasi[{}:{}]::sock_get_opt_flag(fd={}, ty={})", + ctx.data().pid(), + ctx.data().tid(), + sock, + opt + ); let env = ctx.data(); let memory = env.memory_view(&ctx); @@ -8056,7 +8741,13 @@ pub fn sock_set_opt_time( opt: __wasi_sockoption_t, time: WasmPtr<__wasi_option_timestamp_t, M>, ) -> __wasi_errno_t { - debug!("wasi[{}:{}]::sock_set_opt_time(fd={}, ty={})", ctx.data().pid(), ctx.data().tid(), sock, opt); + debug!( + "wasi[{}:{}]::sock_set_opt_time(fd={}, ty={})", + ctx.data().pid(), + ctx.data().tid(), + sock, + opt + ); let env = ctx.data(); let memory = env.memory_view(&ctx); @@ -8077,7 +8768,7 @@ pub fn sock_set_opt_time( }; let option: super::state::WasiSocketOption = opt.into(); - wasi_try!(__sock_actor_mut(&ctx, sock, 0, move |socket| async move { + wasi_try!(__sock_actor_mut(&ctx, sock, 0, move |socket| async move { socket.set_opt_time(ty, time) })); Errno::Success @@ -8096,7 +8787,13 @@ pub fn sock_get_opt_time( opt: __wasi_sockoption_t, ret_time: WasmPtr<__wasi_option_timestamp_t, M>, ) -> __wasi_errno_t { - debug!("wasi[{}:{}]::sock_get_opt_time(fd={}, ty={})", ctx.data().pid(), ctx.data().tid(), sock, opt); + debug!( + "wasi[{}:{}]::sock_get_opt_time(fd={}, ty={})", + ctx.data().pid(), + ctx.data().tid(), + sock, + opt + ); let env = ctx.data(); let memory = env.memory_view(&ctx); @@ -8143,7 +8840,13 @@ pub fn sock_set_opt_size( opt: __wasi_sockoption_t, size: __wasi_filesize_t, ) -> __wasi_errno_t { - debug!("wasi[{}:{}]::sock_set_opt_size(fd={}, ty={})", ctx.data().pid(), ctx.data().tid(), sock, opt); + debug!( + "wasi[{}:{}]::sock_set_opt_size(fd={}, ty={})", + ctx.data().pid(), + ctx.data().tid(), + sock, + opt + ); let ty = match opt { Sockoption::RecvTimeout => wasmer_vnet::TimeType::ReadTimeout, @@ -8181,7 +8884,13 @@ pub fn sock_get_opt_size( opt: __wasi_sockoption_t, ret_size: WasmPtr<__wasi_filesize_t, M>, ) -> __wasi_errno_t { - debug!("wasi[{}:{}]::sock_get_opt_size(fd={}, ty={})", ctx.data().pid(), ctx.data().tid(), sock, opt); + debug!( + "wasi[{}:{}]::sock_get_opt_size(fd={}, ty={})", + ctx.data().pid(), + ctx.data().tid(), + sock, + opt + ); let env = ctx.data(); let memory = env.memory_view(&ctx); @@ -8213,7 +8922,12 @@ pub fn sock_join_multicast_v4( multiaddr: WasmPtr<__wasi_addr_ip4_t, M>, iface: WasmPtr<__wasi_addr_ip4_t, M>, ) -> __wasi_errno_t { - debug!("wasi[{}:{}]::sock_join_multicast_v4 (fd={})", ctx.data().pid(), ctx.data().tid(), sock); + debug!( + "wasi[{}:{}]::sock_join_multicast_v4 (fd={})", + ctx.data().pid(), + ctx.data().tid(), + sock + ); let env = ctx.data(); let memory = env.memory_view(&ctx); @@ -8239,7 +8953,12 @@ pub fn sock_leave_multicast_v4( multiaddr: WasmPtr<__wasi_addr_ip4_t, M>, iface: WasmPtr<__wasi_addr_ip4_t, M>, ) -> __wasi_errno_t { - debug!("wasi[{}:{}]::sock_leave_multicast_v4 (fd={})", ctx.data().pid(), ctx.data().tid(), sock); + debug!( + "wasi[{}:{}]::sock_leave_multicast_v4 (fd={})", + ctx.data().pid(), + ctx.data().tid(), + sock + ); let env = ctx.data(); let memory = env.memory_view(&ctx); @@ -8265,7 +8984,12 @@ pub fn sock_join_multicast_v6( multiaddr: WasmPtr<__wasi_addr_ip6_t, M>, iface: u32, ) -> __wasi_errno_t { - debug!("wasi[{}:{}]::sock_join_multicast_v6 (fd={})", ctx.data().pid(), ctx.data().tid(), sock); + debug!( + "wasi[{}:{}]::sock_join_multicast_v6 (fd={})", + ctx.data().pid(), + ctx.data().tid(), + sock + ); let env = ctx.data(); let memory = env.memory_view(&ctx); @@ -8290,7 +9014,12 @@ pub fn sock_leave_multicast_v6( multiaddr: WasmPtr<__wasi_addr_ip6_t, M>, iface: u32, ) -> __wasi_errno_t { - debug!("wasi[{}:{}]::sock_leave_multicast_v6 (fd={})", ctx.data().pid(), ctx.data().tid(), sock); + debug!( + "wasi[{}:{}]::sock_leave_multicast_v6 (fd={})", + ctx.data().pid(), + ctx.data().tid(), + sock + ); let env = ctx.data(); let memory = env.memory_view(&ctx); @@ -8314,7 +9043,12 @@ pub fn sock_bind( sock: WasiFd, addr: WasmPtr<__wasi_addr_port_t, M>, ) -> __wasi_errno_t { - debug!("wasi[{}:{}]::sock_bind (fd={})", ctx.data().pid(), ctx.data().tid(), sock); + debug!( + "wasi[{}:{}]::sock_bind (fd={})", + ctx.data().pid(), + ctx.data().tid(), + sock + ); let env = ctx.data(); let memory = env.memory_view(&ctx); @@ -8325,9 +9059,7 @@ pub fn sock_bind( &ctx, sock, __WASI_RIGHT_SOCK_BIND, - move |socket| async move { - socket.bind(net, addr).await - } + move |socket| async move { socket.bind(net, addr).await } )); __WASI_ESUCCESS } @@ -8349,7 +9081,12 @@ pub fn sock_listen( sock: WasiFd, backlog: M::Offset, ) -> __wasi_errno_t { - debug!("wasi[{}:{}]::sock_listen (fd={})", ctx.data().pid(), ctx.data().tid(), sock); + debug!( + "wasi[{}:{}]::sock_listen (fd={})", + ctx.data().pid(), + ctx.data().tid(), + sock + ); let env = ctx.data(); let net = env.net(); @@ -8358,9 +9095,7 @@ pub fn sock_listen( &ctx, sock, __WASI_RIGHT_SOCK_BIND, - move |socket| async move { - socket.listen(net, backlog).await - } + move |socket| async move { socket.listen(net, backlog).await } )); __WASI_ESUCCESS } @@ -8384,48 +9119,66 @@ pub fn sock_accept( ro_fd: WasmPtr<__wasi_fd_t, M>, ro_addr: WasmPtr<__wasi_addr_port_t, M>, ) -> Result<__wasi_errno_t, WasiError> { - debug!("wasi[{}:{}]::sock_accept (fd={})", ctx.data().pid(), ctx.data().tid(), sock); + debug!( + "wasi[{}:{}]::sock_accept (fd={})", + ctx.data().pid(), + ctx.data().tid(), + sock + ); let mut env = ctx.data(); let (child, addr) = { let mut ret; let (_, state) = env.get_memory_and_wasi_state(&ctx, 0); - let nonblocking = wasi_try_ok!(__sock_actor(&ctx, sock, __WASI_RIGHT_SOCK_ACCEPT, move |socket| async move { - socket.nonblocking() - })); + let nonblocking = wasi_try_ok!(__sock_actor( + &ctx, + sock, + __WASI_RIGHT_SOCK_ACCEPT, + move |socket| async move { socket.nonblocking() } + )); loop { - wasi_try_ok!( - match __sock_actor(&ctx, sock, __WASI_RIGHT_SOCK_ACCEPT, move |socket| async move { + wasi_try_ok!(match __sock_actor( + &ctx, + sock, + __WASI_RIGHT_SOCK_ACCEPT, + move |socket| async move { socket.set_nonblocking(true); let ret = socket.accept(fd_flags).await; socket.set_nonblocking(nonblocking); ret - }) - { - Ok(a) => { - ret = a; - break; - } - Err(__WASI_ETIMEDOUT) => { - if nonblocking { - trace!("wasi[{}:{}]::sock_accept - (ret=EAGAIN)", ctx.data().pid(), ctx.data().tid()); - return Ok(__WASI_EAGAIN); - } - env.yield_now()?; - continue; - } - Err(__WASI_EAGAIN) => { - if nonblocking { - trace!("wasi[{}:{}]::sock_accept - (ret=EAGAIN)", ctx.data().pid(), ctx.data().tid()); - return Ok(__WASI_EAGAIN); - } - env.clone().sleep(&mut ctx, Duration::from_millis(5))?; - env = ctx.data(); - continue; - } - Err(err) => Err(err), } - ); + ) { + Ok(a) => { + ret = a; + break; + } + Err(__WASI_ETIMEDOUT) => { + if nonblocking { + trace!( + "wasi[{}:{}]::sock_accept - (ret=EAGAIN)", + ctx.data().pid(), + ctx.data().tid() + ); + return Ok(__WASI_EAGAIN); + } + env.yield_now()?; + continue; + } + Err(__WASI_EAGAIN) => { + if nonblocking { + trace!( + "wasi[{}:{}]::sock_accept - (ret=EAGAIN)", + ctx.data().pid(), + ctx.data().tid() + ); + return Ok(__WASI_EAGAIN); + } + env.clone().sleep(&mut ctx, Duration::from_millis(5))?; + env = ctx.data(); + continue; + } + Err(err) => Err(err), + }); } ret }; @@ -8435,19 +9188,22 @@ pub fn sock_accept( let kind = Kind::Socket { socket: InodeSocket::new(InodeSocketKind::TcpStream(child)), }; - let inode = state.fs.create_inode_with_default_stat( - inodes.deref_mut(), - kind, - false, - "socket".into(), - ); + let inode = + state + .fs + .create_inode_with_default_stat(inodes.deref_mut(), kind, false, "socket".into()); let rights = Rights::all_socket(); let fd = wasi_try_ok!(state .fs .create_fd(rights, rights, Fdflags::empty(), 0, inode)); - debug!("wasi[{}:{}]::sock_accept (ret=ESUCCESS, peer={})", ctx.data().pid(), ctx.data().tid(), fd); + debug!( + "wasi[{}:{}]::sock_accept (ret=ESUCCESS, peer={})", + ctx.data().pid(), + ctx.data().tid(), + fd + ); wasi_try_mem_ok!(ro_fd.write(&memory, fd)); wasi_try_ok!(super::state::write_ip_port( @@ -8477,7 +9233,12 @@ pub fn sock_connect( sock: __wasi_fd_t, addr: WasmPtr<__wasi_addr_port_t, M>, ) -> __wasi_errno_t { - debug!("wasi[{}:{}]::sock_connect (fd={})", ctx.data().pid(), ctx.data().tid(), sock); + debug!( + "wasi[{}:{}]::sock_connect (fd={})", + ctx.data().pid(), + ctx.data().tid(), + sock + ); let env = ctx.data(); let net = env.net(); @@ -8488,9 +9249,7 @@ pub fn sock_connect( &ctx, sock, __WASI_RIGHT_SOCK_CONNECT, - move |socket| async move { - socket.connect(net, addr).await - } + move |socket| async move { socket.connect(net, addr).await } )); __WASI_ESUCCESS } @@ -8517,7 +9276,12 @@ pub fn sock_recv( ro_data_len: WasmPtr, ro_flags: WasmPtr<__wasi_roflags_t, M>, ) -> Result<__wasi_errno_t, WasiError> { - debug!("wasi[{}:{}]::sock_recv (fd={})", ctx.data().pid(), ctx.data().tid(), sock); + debug!( + "wasi[{}:{}]::sock_recv (fd={})", + ctx.data().pid(), + ctx.data().tid(), + sock + ); let env = ctx.data(); let memory = env.memory_view(&ctx); @@ -8534,9 +9298,7 @@ pub fn sock_recv( &ctx, sock, __WASI_RIGHT_SOCK_RECV, - move |socket| async move { - socket.recv(max_size).await - } + move |socket| async move { socket.recv(max_size).await } )); let data_len = data.len(); let mut reader = &data[..]; @@ -8572,7 +9334,12 @@ pub fn sock_recv_from( ro_flags: WasmPtr, ro_addr: WasmPtr<__wasi_addr_port_t, M>, ) -> Result<__wasi_errno_t, WasiError> { - debug!("wasi[{}:{}]::sock_recv_from (fd={})", ctx.data().pid(), ctx.data().tid(), sock); + debug!( + "wasi[{}:{}]::sock_recv_from (fd={})", + ctx.data().pid(), + ctx.data().tid(), + sock + ); let env = ctx.data(); let memory = env.memory_view(&ctx); @@ -8589,12 +9356,9 @@ pub fn sock_recv_from( &ctx, sock, __WASI_RIGHT_SOCK_RECV_FROM, - move |socket| async move - { - socket.recv_from(max_size).await - } + move |socket| async move { socket.recv_from(max_size).await } )); - + wasi_try_ok!(write_ip_port(&memory, ro_addr, peer.ip(), peer.port())); let data_len = data.len(); @@ -8629,7 +9393,12 @@ pub fn sock_send( _si_flags: SiFlags, ret_data_len: WasmPtr, ) -> Result<__wasi_errno_t, WasiError> { - debug!("wasi[{}:{}]::sock_send (fd={})", ctx.data().pid(), ctx.data().tid(), sock); + debug!( + "wasi[{}:{}]::sock_send (fd={})", + ctx.data().pid(), + ctx.data().tid(), + sock + ); let env = ctx.data(); let runtime = env.runtime.clone(); @@ -8638,10 +9407,10 @@ pub fn sock_send( let iovs_arr = wasi_try_mem_ok!(si_data.slice(&memory, si_data_len)); let buf_len: M::Offset = iovs_arr - .iter() - .filter_map(|a| a.read().ok()) - .map(|a| a.buf_len) - .sum(); + .iter() + .filter_map(|a| a.read().ok()) + .map(|a| a.buf_len) + .sum(); let buf_len: usize = wasi_try_ok!(buf_len.try_into().map_err(|_| __WASI_EINVAL)); let mut buf = Vec::with_capacity(buf_len); wasi_try_ok!(write_bytes(&mut buf, &memory, iovs_arr)); @@ -8650,9 +9419,7 @@ pub fn sock_send( &ctx, sock, __WASI_RIGHT_SOCK_SEND, - move |socket| async move { - socket.send(buf).await - } + move |socket| async move { socket.send(buf).await } )); let bytes_written: M::Offset = @@ -8685,17 +9452,22 @@ pub fn sock_send_to( addr: WasmPtr<__wasi_addr_port_t, M>, ret_data_len: WasmPtr, ) -> Result<__wasi_errno_t, WasiError> { - debug!("wasi[{}:{}]::sock_send_to (fd={})", ctx.data().pid(), ctx.data().tid(), sock); + debug!( + "wasi[{}:{}]::sock_send_to (fd={})", + ctx.data().pid(), + ctx.data().tid(), + sock + ); let env = ctx.data(); let memory = env.memory_view(&ctx); let iovs_arr = wasi_try_mem_ok!(si_data.slice(&memory, si_data_len)); let buf_len: M::Offset = iovs_arr - .iter() - .filter_map(|a| a.read().ok()) - .map(|a| a.buf_len) - .sum(); + .iter() + .filter_map(|a| a.read().ok()) + .map(|a| a.buf_len) + .sum(); let buf_len: usize = wasi_try_ok!(buf_len.try_into().map_err(|_| __WASI_EINVAL)); let mut buf = Vec::with_capacity(buf_len); wasi_try_ok!(write_bytes(&mut buf, &memory, iovs_arr)); @@ -8707,9 +9479,7 @@ pub fn sock_send_to( &ctx, sock, __WASI_RIGHT_SOCK_SEND_TO, - move |socket| async move { - socket.send_to::(buf, addr).await - } + move |socket| async move { socket.send_to::(buf, addr).await } )); let bytes_written: M::Offset = @@ -8739,7 +9509,13 @@ pub fn sock_send_file( mut count: __wasi_filesize_t, ret_sent: WasmPtr<__wasi_filesize_t, M>, ) -> Result<__wasi_errno_t, WasiError> { - debug!("wasi[{}:{}]::send_file (fd={}, file_fd={})", ctx.data().pid(), ctx.data().tid(), sock, in_fd); + debug!( + "wasi[{}:{}]::send_file (fd={}, file_fd={})", + ctx.data().pid(), + ctx.data().tid(), + sock, + in_fd + ); let env = ctx.data(); let net = env.net(); let tasks = env.tasks.clone(); @@ -8802,16 +9578,10 @@ pub fn sock_send_file( let socket = socket.clone(); let tasks = tasks.clone(); let max_size = buf.len(); - let data = wasi_try_ok!( - __asyncify( - tasks, - &env.thread, - None, - async move { - socket.recv(max_size).await - } - ) - ); + let data = + wasi_try_ok!(__asyncify(tasks, &env.thread, None, async move { + socket.recv(max_size).await + })); buf.copy_from_slice(&data[..]); data.len() } @@ -8835,7 +9605,9 @@ pub fn sock_send_file( // reborrow let mut fd_map = state.fs.fd_map.write().unwrap(); let fd_entry = wasi_try_ok!(fd_map.get_mut(&in_fd).ok_or(__WASI_EBADF)); - fd_entry.offset.fetch_add(bytes_read as u64, Ordering::AcqRel); + fd_entry + .offset + .fetch_add(bytes_read as u64, Ordering::AcqRel); bytes_read } @@ -8847,9 +9619,7 @@ pub fn sock_send_file( &ctx, sock, __WASI_RIGHT_SOCK_SEND, - move |socket| async move { - socket.send(buf).await - } + move |socket| async move { socket.send(buf).await } )); total_written += bytes_written as u64; } @@ -8892,22 +9662,22 @@ pub fn resolve( let host_str = unsafe { get_input_str!(&memory, host, host_len) }; let addrs = wasi_try_mem!(addrs.slice(&memory, wasi_try!(to_offset::(naddrs)))); - debug!("wasi[{}:{}]::resolve (host={})", ctx.data().pid(), ctx.data().tid(), host_str); + debug!( + "wasi[{}:{}]::resolve (host={})", + ctx.data().pid(), + ctx.data().tid(), + host_str + ); let port = if port > 0 { Some(port) } else { None }; let net = env.net(); let tasks = env.tasks.clone(); - let found_ips = wasi_try!( - __asyncify( - tasks, - &env.thread, - None, - async move { - net.resolve(host_str.as_str(), port, None).await.map_err(net_error_into_wasi_err) - } - ) - ); + let found_ips = wasi_try!(__asyncify(tasks, &env.thread, None, async move { + net.resolve(host_str.as_str(), port, None) + .await + .map_err(net_error_into_wasi_err) + })); let mut idx = 0; for found_ip in found_ips.iter().take(naddrs) { diff --git a/lib/wasi/src/wapm/manifest.rs b/lib/wasi/src/wapm/manifest.rs index 8600f8e88..fadc3ce85 100644 --- a/lib/wasi/src/wapm/manifest.rs +++ b/lib/wasi/src/wapm/manifest.rs @@ -1,8 +1,8 @@ -use serde::*; use semver::Version; -use std::path::PathBuf; -use std::fmt; +use serde::*; use std::collections::HashMap; +use std::fmt; +use std::path::PathBuf; /// The name of the manifest file. This is hard-coded for now. pub static MANIFEST_FILE_NAME: &str = "wapm.toml"; @@ -184,4 +184,4 @@ pub struct Manifest { /// store the directory path of the manifest file for use later accessing relative path fields #[serde(skip)] pub base_directory_path: PathBuf, -} \ No newline at end of file +} diff --git a/lib/wasi/src/wapm/mod.rs b/lib/wasi/src/wapm/mod.rs index b86fe74a3..49ce5df24 100644 --- a/lib/wasi/src/wapm/mod.rs +++ b/lib/wasi/src/wapm/mod.rs @@ -1,40 +1,39 @@ -use std::{ - sync::Arc, - ops::Deref, - path::PathBuf, -}; -use webc::{FsEntryType, WebC, Annotation, UrlOrManifest}; -use webc_vfs::VirtualFileSystem; +use std::{ops::Deref, path::PathBuf, sync::Arc}; use tracing::*; +use webc::{Annotation, FsEntryType, UrlOrManifest, WebC}; +use webc_vfs::VirtualFileSystem; #[allow(unused_imports)] use tracing::{error, warn}; use crate::{ - runtime::{ - ReqwestOptions - }, - bin_factory::{BinaryPackage, BinaryPackageCommand}, WasiRuntimeImplementation, VirtualTaskManager + bin_factory::{BinaryPackage, BinaryPackageCommand}, + runtime::ReqwestOptions, + VirtualTaskManager, WasiRuntimeImplementation, }; -mod pirita; #[cfg(feature = "wapm-tar")] mod manifest; +mod pirita; use pirita::*; -pub(crate) fn fetch_webc(cache_dir: &str, webc: &str, runtime: &dyn WasiRuntimeImplementation, tasks: &dyn VirtualTaskManager) -> Option { +pub(crate) fn fetch_webc( + cache_dir: &str, + webc: &str, + runtime: &dyn WasiRuntimeImplementation, + tasks: &dyn VirtualTaskManager, +) -> Option { let name = webc.split_once(":").map(|a| a.0).unwrap_or_else(|| webc); let (name, version) = match name.split_once("@") { Some((name, version)) => (name, Some(version)), - None => (name, None) + None => (name, None), }; let url_query = match version { Some(version) => WAPM_WEBC_QUERY_SPECIFIC - .replace(WAPM_WEBC_QUERY_TAG, name.replace("\"", "'").as_str()) - .replace(WAPM_WEBC_VERSION_TAG, version.replace("\"", "'").as_str()), - None => WAPM_WEBC_QUERY_LAST - .replace(WAPM_WEBC_QUERY_TAG,name.replace("\"", "'").as_str()) + .replace(WAPM_WEBC_QUERY_TAG, name.replace("\"", "'").as_str()) + .replace(WAPM_WEBC_VERSION_TAG, version.replace("\"", "'").as_str()), + None => WAPM_WEBC_QUERY_LAST.replace(WAPM_WEBC_QUERY_TAG, name.replace("\"", "'").as_str()), }; let url = format!( "{}{}", @@ -51,34 +50,65 @@ pub(crate) fn fetch_webc(cache_dir: &str, webc: &str, runtime: &dyn WasiRuntimeI match serde_json::from_slice::<'_, WapmWebQuery>(data.as_ref()) { Ok(query) => { if let Some(package) = query.data.get_package_version { - if let Some(pirita_download_url) = package.distribution.pirita_download_url { - let mut ret = download_webc(cache_dir, name, pirita_download_url, runtime, tasks)?; + if let Some(pirita_download_url) = + package.distribution.pirita_download_url + { + let mut ret = download_webc( + cache_dir, + name, + pirita_download_url, + runtime, + tasks, + )?; ret.version = package.version.into(); return Some(ret); } else { - warn!("package ({}) has no pirita download URL: {}", webc, String::from_utf8_lossy(data.as_ref())); + warn!( + "package ({}) has no pirita download URL: {}", + webc, + String::from_utf8_lossy(data.as_ref()) + ); } } else if let Some(package) = query.data.get_package { - if let Some(pirita_download_url) = package.last_version.distribution.pirita_download_url { - let mut ret = download_webc(cache_dir, name, pirita_download_url, runtime, tasks)?; + if let Some(pirita_download_url) = + package.last_version.distribution.pirita_download_url + { + let mut ret = download_webc( + cache_dir, + name, + pirita_download_url, + runtime, + tasks, + )?; ret.version = package.last_version.version.into(); return Some(ret); } else { - warn!("package ({}) has no pirita download URL: {}", webc, String::from_utf8_lossy(data.as_ref())); + warn!( + "package ({}) has no pirita download URL: {}", + webc, + String::from_utf8_lossy(data.as_ref()) + ); } } else { - warn!("failed to parse WAPM package ({}): {}", name, String::from_utf8_lossy(data.as_ref())); + warn!( + "failed to parse WAPM package ({}): {}", + name, + String::from_utf8_lossy(data.as_ref()) + ); } - }, + } Err(err) => { warn!("failed to deserialize WAPM response: {}", err); } } } } else { - warn!("failed to contact WAPM: http_code={}, http_response={}", wapm.status, wapm.status_text); + warn!( + "failed to contact WAPM: http_code={}, http_response={}", + wapm.status, wapm.status_text + ); } - }, + } Err(code) => { warn!("failed to contact WAPM: http_code={}", code); } @@ -86,9 +116,18 @@ pub(crate) fn fetch_webc(cache_dir: &str, webc: &str, runtime: &dyn WasiRuntimeI None } -fn download_webc(cache_dir: &str, name: &str, pirita_download_url: String, runtime: &dyn WasiRuntimeImplementation, tasks: &dyn VirtualTaskManager) -> Option -{ - let mut name_comps = pirita_download_url.split("/").collect::>().into_iter().rev(); +fn download_webc( + cache_dir: &str, + name: &str, + pirita_download_url: String, + runtime: &dyn WasiRuntimeImplementation, + tasks: &dyn VirtualTaskManager, +) -> Option { + let mut name_comps = pirita_download_url + .split("/") + .collect::>() + .into_iter() + .rev(); let mut name = name_comps.next().unwrap_or_else(|| name); let mut name_store; for _ in 0..2 { @@ -110,11 +149,9 @@ fn download_webc(cache_dir: &str, name: &str, pirita_download_url: String, runti #[cfg(feature = "sys")] if path.exists() { match webc::WebCMmap::parse(path.clone(), &options) { - Ok(webc) => { - unsafe { - let webc = Arc::new(webc); - return parse_webc(webc.as_webc_ref(), webc.clone()); - } + Ok(webc) => unsafe { + let webc = Arc::new(webc); + return parse_webc(webc.as_webc_ref(), webc.clone()); }, Err(err) => { warn!("failed to parse WebC: {}", err); @@ -123,11 +160,9 @@ fn download_webc(cache_dir: &str, name: &str, pirita_download_url: String, runti } if let Ok(data) = std::fs::read(path) { match webc::WebCOwned::parse(data, &options) { - Ok(webc) => { - unsafe { - let webc = Arc::new(webc); - return parse_webc(webc.as_webc_ref(), webc.clone()); - } + Ok(webc) => unsafe { + let webc = Arc::new(webc); + return parse_webc(webc.as_webc_ref(), webc.clone()); }, Err(err) => { warn!("failed to parse WebC: {}", err); @@ -144,22 +179,32 @@ fn download_webc(cache_dir: &str, name: &str, pirita_download_url: String, runti let mut temp_path = path.clone(); let rand_128: u128 = rand::random(); - temp_path = PathBuf::from(format!("{}.{}.temp", temp_path.as_os_str().to_string_lossy(), rand_128)); + temp_path = PathBuf::from(format!( + "{}.{}.temp", + temp_path.as_os_str().to_string_lossy(), + rand_128 + )); if let Err(err) = std::fs::write(temp_path.as_path(), &data[..]) { - debug!("failed to write webc cache file [{}] - {}", temp_path.as_path().to_string_lossy(), err); + debug!( + "failed to write webc cache file [{}] - {}", + temp_path.as_path().to_string_lossy(), + err + ); } if let Err(err) = std::fs::rename(temp_path.as_path(), path.as_path()) { - debug!("failed to rename webc cache file [{}] - {}", temp_path.as_path().to_string_lossy(), err); + debug!( + "failed to rename webc cache file [{}] - {}", + temp_path.as_path().to_string_lossy(), + err + ); } #[cfg(feature = "sys")] match webc::WebCMmap::parse(path, &options) { - Ok(webc) => { - unsafe { - let webc = Arc::new(webc); - return parse_webc(webc.as_webc_ref(), webc.clone()); - } + Ok(webc) => unsafe { + let webc = Arc::new(webc); + return parse_webc(webc.as_webc_ref(), webc.clone()); }, Err(err) => { warn!("failed to parse WebC: {}", err); @@ -167,11 +212,9 @@ fn download_webc(cache_dir: &str, name: &str, pirita_download_url: String, runti } match webc::WebCOwned::parse(data, &options) { - Ok(webc) => { - unsafe { - let webc = Arc::new(webc); - return parse_webc(webc.as_webc_ref(), webc.clone()); - } + Ok(webc) => unsafe { + let webc = Arc::new(webc); + return parse_webc(webc.as_webc_ref(), webc.clone()); }, Err(err) => { warn!("failed to parse WebC: {}", err); @@ -182,7 +225,11 @@ fn download_webc(cache_dir: &str, name: &str, pirita_download_url: String, runti None } -fn download_miss(download_url: &str, runtime: &dyn WasiRuntimeImplementation, tasks: &dyn VirtualTaskManager) -> Option> { +fn download_miss( + download_url: &str, + runtime: &dyn WasiRuntimeImplementation, + tasks: &dyn VirtualTaskManager, +) -> Option> { let mut options = ReqwestOptions::default(); options.gzip = true; @@ -194,9 +241,12 @@ fn download_miss(download_url: &str, runtime: &dyn WasiRuntimeImplementation, ta if wapm.status == 200 { return wapm.data; } else { - warn!("failed to download package: http_code={}, http_response={}", wapm.status, wapm.status_text); + warn!( + "failed to download package: http_code={}, http_response={}", + wapm.status, wapm.status_text + ); } - }, + } Err(code) => { warn!("failed to download package: http_code={}", code); } @@ -205,17 +255,17 @@ fn download_miss(download_url: &str, runtime: &dyn WasiRuntimeImplementation, ta } unsafe fn parse_webc<'a, 'b, T>(webc: webc::WebC<'a>, ownership: Arc) -> Option -where T: std::fmt::Debug + Send + Sync + 'static, - T: Deref> +where + T: std::fmt::Debug + Send + Sync + 'static, + T: Deref>, { let package_name = webc.get_package_name(); - let mut pck = webc.manifest.entrypoint + let mut pck = webc + .manifest + .entrypoint .iter() - .filter_map(|entry| { - webc.manifest.commands.get(entry) - .map(|a| (a, entry)) - }) + .filter_map(|entry| webc.manifest.commands.get(entry).map(|a| (a, entry))) .filter_map(|(cmd, entry)| { let api = if cmd.runner.starts_with("https://webc.org/runner/emscripten") { "emscripten" @@ -228,18 +278,20 @@ where T: std::fmt::Debug + Send + Sync + 'static, match webc.get_atom_name_for_command(api, entry.as_str()) { Ok(a) => Some(a), Err(err) => { - warn!("failed to find atom name for entry command({}) - {}", entry.as_str(), err); + warn!( + "failed to find atom name for entry command({}) - {}", + entry.as_str(), + err + ); None } } }) - .filter_map(|atom| { - match webc.get_atom(&package_name, atom.as_str()) { - Ok(a) => Some(a), - Err(err) => { - warn!("failed to find atom for atom name({}) - {}", atom, err); - None - } + .filter_map(|atom| match webc.get_atom(&package_name, atom.as_str()) { + Ok(a) => Some(a), + Err(err) => { + warn!("failed to find atom for atom name({}) - {}", atom, err); + None } }) .map(|atom| { @@ -248,17 +300,12 @@ where T: std::fmt::Debug + Send + Sync + 'static, .next(); if let Some(pck) = pck.as_mut() { - // Add all the dependencies for uses in webc.manifest.use_map.values() { let uses = match uses { UrlOrManifest::Url(url) => Some(url.path().to_string()), - UrlOrManifest::Manifest(manifest) => { - manifest.origin.as_ref().map(|a| a.clone()) - }, - UrlOrManifest::RegistryDependentUrl(url) => { - Some(url.clone()) - }, + UrlOrManifest::Manifest(manifest) => manifest.origin.as_ref().map(|a| a.clone()), + UrlOrManifest::RegistryDependentUrl(url) => Some(url.clone()), }; if let Some(uses) = uses { pck.uses.push(uses); @@ -267,7 +314,9 @@ where T: std::fmt::Debug + Send + Sync + 'static, // Set the version of this package if let Some(Annotation::Map(wapm)) = webc.manifest.package.get("wapm") { - if let Some(Annotation::Text(version)) = wapm.get(&Annotation::Text("version".to_string())) { + if let Some(Annotation::Text(version)) = + wapm.get(&Annotation::Text("version".to_string())) + { pck.version = version.clone().into(); } } else if let Some(Annotation::Text(version)) = webc.manifest.package.get("version") { @@ -290,43 +339,51 @@ where T: std::fmt::Debug + Send + Sync + 'static, }) .collect::>(); - pck.webc_fs = Some(Arc::new(VirtualFileSystem::init(ownership.clone(), &package_name))); + pck.webc_fs = Some(Arc::new(VirtualFileSystem::init( + ownership.clone(), + &package_name, + ))); pck.webc_top_level_dirs = top_level_dirs; let root_package = webc.get_package_name(); for (command, action) in webc.get_metadata().commands.iter() { if let Some(Annotation::Map(annotations)) = action.annotations.get("wasi") { - let mut atom = None; let mut package = root_package.clone(); for (k, v) in annotations { match (k, v) { (Annotation::Text(k), Annotation::Text(v)) if k == "atom" => { atom = Some(v.clone()); - }, + } (Annotation::Text(k), Annotation::Text(v)) if k == "package" => { package = v.clone(); - }, - _ => { } + } + _ => {} } } - + // Load the atom as a command if let Some(atom_name) = atom { match webc.get_atom(package.as_str(), atom_name.as_str()) { Ok(atom) => { - trace!("added atom (name={}, size={}) for command [{}]", atom_name, atom.len(), command); - let mut commands = pck.commands.write().unwrap(); - commands.push( - BinaryPackageCommand::new_with_ownership( - command.clone(), - atom.into(), - ownership.clone() - ) + trace!( + "added atom (name={}, size={}) for command [{}]", + atom_name, + atom.len(), + command ); + let mut commands = pck.commands.write().unwrap(); + commands.push(BinaryPackageCommand::new_with_ownership( + command.clone(), + atom.into(), + ownership.clone(), + )); } Err(err) => { - warn!("Failed to find atom [{}].[{}] - {}", package, atom_name, err); + warn!( + "Failed to find atom [{}].[{}] - {}", + package, atom_name, err + ); } } } diff --git a/lib/wasi/src/wapm/pirita.rs b/lib/wasi/src/wapm/pirita.rs index aacedad0d..0ef5343d6 100644 --- a/lib/wasi/src/wapm/pirita.rs +++ b/lib/wasi/src/wapm/pirita.rs @@ -52,13 +52,13 @@ pub struct WapmWebQueryGetPackageVersion { #[serde(rename = "version")] pub version: String, #[serde(rename = "distribution")] - pub distribution: WapmWebQueryGetPackageLastVersionDistribution + pub distribution: WapmWebQueryGetPackageLastVersionDistribution, } #[derive(Debug, Serialize, Deserialize, Clone)] pub struct WapmWebQueryGetPackage { #[serde(rename = "lastVersion")] - pub last_version: WapmWebQueryGetPackageVersion + pub last_version: WapmWebQueryGetPackageVersion, } #[derive(Debug, Serialize, Deserialize, Clone)] @@ -66,11 +66,11 @@ pub struct WapmWebQueryData { #[serde(rename = "getPackage")] pub get_package: Option, #[serde(rename = "getPackageVersion")] - pub get_package_version: Option + pub get_package_version: Option, } #[derive(Debug, Serialize, Deserialize, Clone)] pub struct WapmWebQuery { #[serde(rename = "data")] pub data: WapmWebQueryData, -} \ No newline at end of file +} diff --git a/lib/wasi/tests/catsay.rs b/lib/wasi/tests/catsay.rs index 4d4901840..3c0e11ae7 100644 --- a/lib/wasi/tests/catsay.rs +++ b/lib/wasi/tests/catsay.rs @@ -1,13 +1,16 @@ #![cfg(feature = "sys")] #![cfg(target_os = "linux")] -use std::{io::{Read, Write}, time::Duration}; +use std::{ + io::{Read, Write}, + time::Duration, +}; #[allow(unused_imports)] use tracing::{debug, info, metadata::LevelFilter}; #[cfg(feature = "sys")] use tracing_subscriber::fmt::SubscriberBuilder; -use wasmer::{Instance, Module, Store, Cranelift, EngineBuilder}; -use wasmer_wasi::{Pipe, WasiState, import_object_for_all_wasi_versions, WasiError}; +use wasmer::{Cranelift, EngineBuilder, Instance, Module, Store}; +use wasmer_wasi::{import_object_for_all_wasi_versions, Pipe, WasiError, WasiState}; #[cfg(feature = "sys")] mod sys { @@ -27,7 +30,6 @@ mod js { } fn test_catsay() { - info!("Creating engine"); let compiler = Cranelift::default(); let engine = EngineBuilder::new(compiler.clone()); @@ -47,10 +49,9 @@ fn test_catsay() { #[cfg(feature = "sys")] SubscriberBuilder::default() - .with_max_level(LevelFilter::TRACE) - .init(); + .with_max_level(LevelFilter::TRACE) + .init(); - let engine = store.engine().clone(); for _ in 0..10 { let module = module.clone(); @@ -69,14 +70,13 @@ fn test_catsay() { } } -fn run_test(mut store: Store, module: Module) -{ +fn run_test(mut store: Store, module: Module) { // Create the `WasiEnv`. let mut stdout = Pipe::new(); let mut wasi_state_builder = WasiState::new("catsay"); let mut stdin_pipe = Pipe::new(); - + let mut wasi_env = wasi_state_builder .stdin(Box::new(stdin_pipe.clone())) .stdout(Box::new(stdout.clone())) @@ -86,28 +86,26 @@ fn run_test(mut store: Store, module: Module) // Start a thread that will dump STDOUT to info #[cfg(feature = "sys")] - std::thread::spawn(move || { - loop { - let mut buf = [0u8; 8192]; - if let Ok(amt) = stdout.read(&mut buf[..]) { - if amt > 0 { - let msg = String::from_utf8_lossy(&buf[0..amt]); - for line in msg.lines() { - info!("{}", line); - } - } else { - std::thread::sleep(Duration::from_millis(1)); + std::thread::spawn(move || loop { + let mut buf = [0u8; 8192]; + if let Ok(amt) = stdout.read(&mut buf[..]) { + if amt > 0 { + let msg = String::from_utf8_lossy(&buf[0..amt]); + for line in msg.lines() { + info!("{}", line); } } else { - break; + std::thread::sleep(Duration::from_millis(1)); } + } else { + break; } }); // Write some text to catsay stdin stdin_pipe.write_all("hi there".as_bytes()).unwrap(); drop(stdin_pipe); - + // Generate an `ImportObject`. let mut import_object = import_object_for_all_wasi_versions(&mut store, &wasi_env.env); import_object.import_shared_memory(&module, &mut store); @@ -121,9 +119,13 @@ fn run_test(mut store: Store, module: Module) let ret = start.call(&mut store, &[]); if let Err(e) = ret { match e.downcast::() { - Ok(WasiError::Exit(0)) => { } + Ok(WasiError::Exit(0)) => {} Ok(WasiError::Exit(code)) => { - assert!(false, "The call should have returned Err(WasiError::Exit(0)) but returned {}", code); + assert!( + false, + "The call should have returned Err(WasiError::Exit(0)) but returned {}", + code + ); } Ok(WasiError::UnknownWasiVersion) => { assert!(false, "The call should have returned Err(WasiError::Exit(0)) but returned UnknownWasiVersion"); diff --git a/lib/wasi/tests/condvar.rs b/lib/wasi/tests/condvar.rs index c3a986376..1334f257f 100644 --- a/lib/wasi/tests/condvar.rs +++ b/lib/wasi/tests/condvar.rs @@ -6,8 +6,8 @@ use std::{io::Read, time::Duration}; use tracing::{debug, info, metadata::LevelFilter}; #[cfg(feature = "sys")] use tracing_subscriber::fmt::SubscriberBuilder; -use wasmer::{Instance, Module, Store, Features, Cranelift, EngineBuilder}; -use wasmer_wasi::{Pipe, WasiState, import_object_for_all_wasi_versions, WasiError}; +use wasmer::{Cranelift, EngineBuilder, Features, Instance, Module, Store}; +use wasmer_wasi::{import_object_for_all_wasi_versions, Pipe, WasiError, WasiState}; #[cfg(feature = "sys")] mod sys { @@ -28,13 +28,11 @@ mod js { fn test_condvar() { let mut features = Features::new(); - features - .threads(true); + features.threads(true); info!("Creating engine"); let compiler = Cranelift::default(); - let engine = EngineBuilder::new(compiler) - .set_features(Some(features)); + let engine = EngineBuilder::new(compiler).set_features(Some(features)); let store = Store::new(engine); @@ -50,18 +48,17 @@ fn test_condvar() { #[cfg(feature = "sys")] SubscriberBuilder::default() - .with_max_level(LevelFilter::TRACE) - .init(); + .with_max_level(LevelFilter::TRACE) + .init(); run_test(store, module); } -fn run_test(mut store: Store, module: Module) -{ +fn run_test(mut store: Store, module: Module) { // Create the `WasiEnv`. let mut stdout = Pipe::new(); let mut wasi_state_builder = WasiState::new("multi-threading"); - + let mut wasi_env = wasi_state_builder .stdout(Box::new(stdout.clone())) .stderr(Box::new(stdout.clone())) @@ -70,24 +67,22 @@ fn run_test(mut store: Store, module: Module) // Start a thread that will dump STDOUT to info #[cfg(feature = "sys")] - std::thread::spawn(move || { - loop { - let mut buf = [0u8; 8192]; - if let Ok(amt) = stdout.read(&mut buf[..]) { - if amt > 0 { - let msg = String::from_utf8_lossy(&buf[0..amt]); - for line in msg.lines() { - info!("{}", line); - } - } else { - std::thread::sleep(Duration::from_millis(1)); + std::thread::spawn(move || loop { + let mut buf = [0u8; 8192]; + if let Ok(amt) = stdout.read(&mut buf[..]) { + if amt > 0 { + let msg = String::from_utf8_lossy(&buf[0..amt]); + for line in msg.lines() { + info!("{}", line); } } else { - break; + std::thread::sleep(Duration::from_millis(1)); } + } else { + break; } }); - + // Generate an `ImportObject`. let mut import_object = import_object_for_all_wasi_versions(&mut store, &wasi_env.env); import_object.import_shared_memory(&module, &mut store); @@ -101,9 +96,12 @@ fn run_test(mut store: Store, module: Module) let ret = start.call(&mut store, &[]); if let Err(e) = ret { match e.downcast::() { - Ok(WasiError::Exit(0)) => { } + Ok(WasiError::Exit(0)) => {} _ => { - assert!(false, "The call should have returned Err(WasiError::Exit(0))"); + assert!( + false, + "The call should have returned Err(WasiError::Exit(0))" + ); } } } diff --git a/lib/wasi/tests/coreutils.rs b/lib/wasi/tests/coreutils.rs index 883dca43b..c37c14773 100644 --- a/lib/wasi/tests/coreutils.rs +++ b/lib/wasi/tests/coreutils.rs @@ -6,8 +6,8 @@ use std::io::Read; use tracing::{debug, info, metadata::LevelFilter}; #[cfg(feature = "sys")] use tracing_subscriber::fmt::SubscriberBuilder; -use wasmer::{Instance, Module, Store, Features, Cranelift, EngineBuilder}; -use wasmer_wasi::{Pipe, WasiState, import_object_for_all_wasi_versions, WasiError}; +use wasmer::{Cranelift, EngineBuilder, Features, Instance, Module, Store}; +use wasmer_wasi::{import_object_for_all_wasi_versions, Pipe, WasiError, WasiState}; #[cfg(feature = "sys")] mod sys { @@ -28,8 +28,7 @@ mod js { fn test_coreutils() { let mut features = Features::new(); - features - .threads(true); + features.threads(true); info!("Creating engine"); let compiler = Cranelift::default(); @@ -51,12 +50,11 @@ fn test_coreutils() { #[cfg(feature = "sys")] SubscriberBuilder::default() - .with_max_level(LevelFilter::DEBUG) - .init(); + .with_max_level(LevelFilter::DEBUG) + .init(); // We do it many times (to make sure the compiled modules are reusable) - for n in 0..2 - { + for n in 0..2 { let store = Store::new(engine.clone()); let module = module.clone(); @@ -66,14 +64,12 @@ fn test_coreutils() { } } -fn run_test(mut store: Store, module: Module) -{ +fn run_test(mut store: Store, module: Module) { // Create the `WasiEnv`. let mut stdout = Pipe::new(); let mut wasi_state_builder = WasiState::new("echo"); - wasi_state_builder - .args(&["apple"]); - + wasi_state_builder.args(&["apple"]); + let mut wasi_env = wasi_state_builder .stdout(Box::new(stdout.clone())) .finalize(&mut store) @@ -92,9 +88,12 @@ fn run_test(mut store: Store, module: Module) let ret = start.call(&mut store, &[]); if let Err(e) = ret { match e.downcast::() { - Ok(WasiError::Exit(0)) => { } + Ok(WasiError::Exit(0)) => {} _ => { - assert!(false, "The call should have returned Err(WasiError::Exit(0))"); + assert!( + false, + "The call should have returned Err(WasiError::Exit(0))" + ); } } } diff --git a/lib/wasi/tests/multi-threading.rs b/lib/wasi/tests/multi-threading.rs index 8a4e1f6a8..ad9abc65e 100644 --- a/lib/wasi/tests/multi-threading.rs +++ b/lib/wasi/tests/multi-threading.rs @@ -6,8 +6,8 @@ use std::{io::Read, time::Duration}; use tracing::{debug, info, metadata::LevelFilter}; #[cfg(feature = "sys")] use tracing_subscriber::fmt::SubscriberBuilder; -use wasmer::{Instance, Module, Store, Features, Cranelift, EngineBuilder}; -use wasmer_wasi::{Pipe, WasiState, import_object_for_all_wasi_versions, WasiError}; +use wasmer::{Cranelift, EngineBuilder, Features, Instance, Module, Store}; +use wasmer_wasi::{import_object_for_all_wasi_versions, Pipe, WasiError, WasiState}; mod sys { #[test] @@ -18,8 +18,7 @@ mod sys { fn test_multithreading() { let mut features = Features::new(); - features - .threads(true); + features.threads(true); info!("Creating engine"); let compiler = Cranelift::default(); @@ -41,12 +40,11 @@ fn test_multithreading() { #[cfg(feature = "sys")] SubscriberBuilder::default() - .with_max_level(LevelFilter::TRACE) - .init(); + .with_max_level(LevelFilter::TRACE) + .init(); // We do it many times (to make sure the compiled modules are reusable) - for n in 0..2 - { + for n in 0..2 { let store = Store::new(engine.clone()); let module = module.clone(); @@ -55,12 +53,11 @@ fn test_multithreading() { } } -fn run_test(mut store: Store, module: Module) -{ +fn run_test(mut store: Store, module: Module) { // Create the `WasiEnv`. let mut stdout = Pipe::new(); let mut wasi_state_builder = WasiState::new("multi-threading"); - + let mut wasi_env = wasi_state_builder .stdout(Box::new(stdout.clone())) .stderr(Box::new(stdout.clone())) @@ -69,24 +66,22 @@ fn run_test(mut store: Store, module: Module) // Start a thread that will dump STDOUT to info #[cfg(feature = "sys")] - std::thread::spawn(move || { - loop { - let mut buf = [0u8; 8192]; - if let Ok(amt) = stdout.read(&mut buf[..]) { - if amt > 0 { - let msg = String::from_utf8_lossy(&buf[0..amt]); - for line in msg.lines() { - info!("{}", line); - } - } else { - std::thread::sleep(Duration::from_millis(1)); + std::thread::spawn(move || loop { + let mut buf = [0u8; 8192]; + if let Ok(amt) = stdout.read(&mut buf[..]) { + if amt > 0 { + let msg = String::from_utf8_lossy(&buf[0..amt]); + for line in msg.lines() { + info!("{}", line); } } else { - break; + std::thread::sleep(Duration::from_millis(1)); } + } else { + break; } }); - + // Generate an `ImportObject`. let mut import_object = import_object_for_all_wasi_versions(&mut store, &wasi_env.env); import_object.import_shared_memory(&module, &mut store); @@ -100,9 +95,12 @@ fn run_test(mut store: Store, module: Module) let ret = start.call(&mut store, &[]); if let Err(e) = ret { match e.downcast::() { - Ok(WasiError::Exit(0)) => { } + Ok(WasiError::Exit(0)) => {} _ => { - assert!(false, "The call should have returned Err(WasiError::Exit(0))"); + assert!( + false, + "The call should have returned Err(WasiError::Exit(0))" + ); } } } diff --git a/tests/lib/wast/src/wasi_wast.rs b/tests/lib/wast/src/wasi_wast.rs index 7b7bdf7e1..1fdceb8c1 100644 --- a/tests/lib/wast/src/wasi_wast.rs +++ b/tests/lib/wast/src/wasi_wast.rs @@ -91,7 +91,7 @@ impl<'a> WasiTest<'a> { let wasi_env = env.data(&store); let start = instance.exports.get_function("_start")?; - + if let Some(stdin) = &self.stdin { let state = wasi_env.state(); let mut wasi_stdin = state.stdin().unwrap().unwrap();