From 1f99ef837774a82eacd926e734b1ae68b7a01b82 Mon Sep 17 00:00:00 2001 From: Mark McCaskey Date: Thu, 9 May 2019 16:01:36 -0700 Subject: [PATCH 1/6] implement some FS operations for rsign2 --- lib/wasi/src/syscalls/mod.rs | 111 +++++++++++++++++++++++++++++++---- 1 file changed, 101 insertions(+), 10 deletions(-) diff --git a/lib/wasi/src/syscalls/mod.rs b/lib/wasi/src/syscalls/mod.rs index fcd1caaddfe..dcddeedd95a 100644 --- a/lib/wasi/src/syscalls/mod.rs +++ b/lib/wasi/src/syscalls/mod.rs @@ -987,8 +987,60 @@ pub fn path_create_directory( path_len: u32, ) -> __wasi_errno_t { debug!("wasi::path_create_directory"); - // check __WASI_RIGHT_PATH_CREATE_DIRECTORY - unimplemented!() + let memory = ctx.memory(0); + let state = get_wasi_state(ctx); + + let working_dir = wasi_try!(state.fs.fd_map.get(&fd).ok_or(__WASI_EBADF)); + if !has_rights(working_dir.rights, __WASI_RIGHT_PATH_CREATE_DIRECTORY) { + return __WASI_EACCES; + } + let path_cells = wasi_try!(path.deref(memory, 0, path_len)); + let path_string = + wasi_try!( + std::str::from_utf8(unsafe { &*(path_cells as *const [_] as *const [u8]) }) + .map_err(|_| __WASI_EINVAL) + ); + debug!("=> path: {}", &path_string); + + let path = std::path::PathBuf::from(path_string); + let path_vec = wasi_try!(path + .components() + .map(|comp| { + comp.as_os_str() + .to_str() + .map(|inner_str| inner_str.to_string()) + .ok_or(__WASI_EINVAL) + }) + .collect::, __wasi_errno_t>>()); + if path_vec.is_empty() { + return __WASI_EINVAL; + } + + assert!( + path_vec.len() == 1, + "path_create_directory for paths greater than depth 1 has not been implemented" + ); + debug!("Path vec: {:#?}", path_vec); + + let kind = Kind::Dir { + //parent: Some(working_dir.inode), + path: path.clone(), + entries: Default::default(), + }; + let new_inode = state.fs.inodes.insert(InodeVal { + stat: __wasi_filestat_t::default(), + is_preopened: false, + name: path_vec[0].clone(), + kind, + }); + + if let Kind::Dir { entries, .. } = &mut state.fs.inodes[working_dir.inode].kind { + entries.insert(path_vec[0].clone(), new_inode); + } else { + return __WASI_ENOTDIR; + } + + __WASI_ESUCCESS } /// ### `path_filestat_get()` @@ -1023,25 +1075,27 @@ pub fn path_filestat_get( return __WASI_EACCES; } - let path_vec = wasi_try!(::std::str::from_utf8(unsafe { + let path_string = wasi_try!(::std::str::from_utf8(unsafe { &*(wasi_try!(path.deref(memory, 0, path_len)) as *const [_] as *const [u8]) }) - .map_err(|_| __WASI_EINVAL)) - .split('/') - .map(|str| str.to_string()) - .collect::>(); + .map_err(|_| __WASI_EINVAL)); + debug!("=> path: {}", &path_string); + let path_vec = path_string + .split('/') + .map(|str| str.to_string()) + .collect::>(); let buf_cell = wasi_try!(buf.deref(memory)); // find the inode by traversing the path let mut inode = root_dir.inode; - 'outer: for segment in path_vec { + 'outer: for segment in &path_vec[..(path_vec.len() - 1)] { // loop to traverse symlinks // TODO: proper cycle detection let mut sym_count = 0; loop { match &state.fs.inodes[inode].kind { Kind::Dir { entries, .. } => { - if let Some(entry) = entries.get(&segment) { + if let Some(entry) = entries.get(segment) { inode = entry.clone(); continue 'outer; } else { @@ -1062,7 +1116,44 @@ pub fn path_filestat_get( } } - let stat = state.fs.inodes[inode].stat; + let final_inode = match &state.fs.inodes[inode].kind { + Kind::Dir { entries, .. } => { + // TODO: fail earlier if size 0 + let last_segment = path_vec.last().unwrap(); + if entries.contains_key(last_segment) { + entries[last_segment] + } else { + // lazily load it if we can + // TODO: adjust to directory correctly + + // HACK(mark): assumes current directory, cumulative dir should be built up in previous loop + let real_open_file = wasi_try!(std::fs::OpenOptions::new() + .read(true) + .write(true) + .open(&last_segment) + .map_err(|_| __WASI_ENOENT)); + + let new_inode = state.fs.inodes.insert(InodeVal { + stat: __wasi_filestat_t::default(), + is_preopened: false, // is this correct? + name: last_segment.clone(), + kind: Kind::File { + handle: WasiFile::HostFile(real_open_file), + }, + }); + // reborrow to insert entry + if let Kind::Dir { entries, .. } = &mut state.fs.inodes[inode].kind { + entries.insert(last_segment.clone(), new_inode); + } + new_inode + } + } + _ => { + return __WASI_ENOTDIR; + } + }; + + let stat = state.fs.inodes[final_inode].stat; buf_cell.set(stat); From a527154c62166b4b9168572208f4f0f8bc2641de Mon Sep 17 00:00:00 2001 From: Mark McCaskey Date: Fri, 10 May 2019 10:54:36 -0700 Subject: [PATCH 2/6] major improvements to wasi fs calls; include explanation in unimpl!s --- lib/wasi/src/syscalls/mod.rs | 155 ++++++++++++++++++++++++----------- 1 file changed, 108 insertions(+), 47 deletions(-) diff --git a/lib/wasi/src/syscalls/mod.rs b/lib/wasi/src/syscalls/mod.rs index dcddeedd95a..3fce35916dd 100644 --- a/lib/wasi/src/syscalls/mod.rs +++ b/lib/wasi/src/syscalls/mod.rs @@ -279,7 +279,7 @@ pub fn fd_allocate( len: __wasi_filesize_t, ) -> __wasi_errno_t { debug!("wasi::fd_allocate"); - unimplemented!() + unimplemented!("wasi::fd_allocate") } /// ### `fd_close()` @@ -434,7 +434,7 @@ pub fn fd_filestat_set_size( st_size: __wasi_filesize_t, ) -> __wasi_errno_t { debug!("wasi::fd_filestat_set_size"); - unimplemented!() + unimplemented!("wasi::fd_filestat_set_size") } /// ### `fd_filestat_set_times()` @@ -474,14 +474,14 @@ pub fn fd_filestat_set_times( inode.stat.st_atim = st_atim; } else if fst_flags & __WASI_FILESTAT_SET_ATIM_NOW != 0 { // set to current real time - unimplemented!(); + unimplemented!("Set filestat time to the current real time"); } if fst_flags & __WASI_FILESTAT_SET_MTIM != 0 { inode.stat.st_mtim = st_mtim; } else if fst_flags & __WASI_FILESTAT_SET_MTIM_NOW != 0 { // set to current real time - unimplemented!(); + unimplemented!("Set filestat time to the current real time"); } __WASI_ESUCCESS @@ -501,7 +501,7 @@ pub fn fd_pread( let iov_cells = wasi_try!(iovs.deref(memory, 0, iovs_len)); let nread_cell = wasi_try!(nread.deref(memory)); - unimplemented!(); + unimplemented!("wasi::fd_pread"); __WASI_ESUCCESS } @@ -637,7 +637,7 @@ pub fn fd_pwrite( // TODO: verify return __WASI_EISDIR; } - Kind::Symlink { .. } => unimplemented!(), + Kind::Symlink { .. } => unimplemented!("Symlinks in wasi::fd_pwrite"), Kind::Buffer { buffer } => wasi_try!(write_bytes( &mut buffer[(offset as usize)..], memory, @@ -725,7 +725,7 @@ pub fn fd_read( // TODO: verify return __WASI_EISDIR; } - Kind::Symlink { .. } => unimplemented!(), + Kind::Symlink { .. } => unimplemented!("Symlinks in wasi::fd_read"), Kind::Buffer { buffer } => { wasi_try!(read_bytes(&buffer[offset..], memory, iovs_arr_cell)) } @@ -771,7 +771,7 @@ pub fn fd_readdir( if let (Ok(buf_arr_cell), Ok(bufused_cell)) = (buf.deref(memory, 0, buf_len), bufused.deref(memory)) { - unimplemented!() + unimplemented!("wasi::fd_readdir") } else { __WASI_EFAULT } @@ -833,7 +833,7 @@ pub fn fd_seek( // TODO: handle case if fd is a dir? match whence { __WASI_WHENCE_CUR => fd_entry.offset = (fd_entry.offset as i64 + offset) as u64, - __WASI_WHENCE_END => unimplemented!(), + __WASI_WHENCE_END => unimplemented!("__WASI__WHENCE_END in wasi::fd_seek"), __WASI_WHENCE_SET => fd_entry.offset = offset as u64, _ => return __WASI_EINVAL, } @@ -855,7 +855,7 @@ pub fn fd_seek( pub fn fd_sync(ctx: &mut Ctx, fd: __wasi_fd_t) -> __wasi_errno_t { debug!("wasi::fd_sync"); // TODO: check __WASI_RIGHT_FD_SYNC - unimplemented!() + unimplemented!("wasi::fd_sync") } /// ### `fd_tell()` @@ -950,7 +950,7 @@ pub fn fd_write( // TODO: verify return __WASI_EISDIR; } - Kind::Symlink { .. } => unimplemented!(), + Kind::Symlink { .. } => unimplemented!("Symlinks in wasi::fd_write"), Kind::Buffer { buffer } => { wasi_try!(write_bytes(&mut buffer[offset..], memory, iovs_arr_cell)) } @@ -1018,10 +1018,12 @@ pub fn path_create_directory( assert!( path_vec.len() == 1, - "path_create_directory for paths greater than depth 1 has not been implemented" + "path_create_directory for paths greater than depth 1 has not been implemented because our WASI FS abstractions are a work in progress. We apologize for the inconvenience" ); debug!("Path vec: {:#?}", path_vec); + wasi_try!(std::fs::create_dir(&path).map_err(|_| __WASI_EIO)); + let kind = Kind::Dir { //parent: Some(working_dir.inode), path: path.clone(), @@ -1080,12 +1082,19 @@ pub fn path_filestat_get( }) .map_err(|_| __WASI_EINVAL)); debug!("=> path: {}", &path_string); - let path_vec = path_string - .split('/') - .map(|str| str.to_string()) + let path = std::path::PathBuf::from(path_string); + let path_vec = path + .components() + .map(|comp| comp.as_os_str().to_string_lossy().to_string()) .collect::>(); let buf_cell = wasi_try!(buf.deref(memory)); + if path_vec.is_empty() { + return __WASI_EINVAL; + } + let mut cumulative_path = std::path::PathBuf::new(); + + debug!("=> Path vec: {:?}:", &path_vec); // find the inode by traversing the path let mut inode = root_dir.inode; 'outer: for segment in &path_vec[..(path_vec.len() - 1)] { @@ -1095,14 +1104,47 @@ pub fn path_filestat_get( loop { match &state.fs.inodes[inode].kind { Kind::Dir { entries, .. } => { + cumulative_path.push(&segment); if let Some(entry) = entries.get(segment) { + debug!("Entry {:?} found", &segment); inode = entry.clone(); - continue 'outer; } else { - return __WASI_ENOENT; + // lazily load + debug!("Lazily loading entry {:?}", &segment); + debug!("EEE"); + let path_metadata = + wasi_try!(cumulative_path.metadata().map_err(|_| __WASI_ENOENT)); + debug!("DDD"); + if !path_metadata.is_dir() { + // TODO: should this just return invalid arg? + return __WASI_ENOTDIR; + } + debug!("AAA"); + let kind = Kind::Dir { + path: std::path::PathBuf::from(&segment), + entries: Default::default(), + }; + let inode_val = InodeVal::from_file_metadata( + &path_metadata, + segment.clone(), + false, + kind, + ); + let new_inode = state.fs.inodes.insert(inode_val); + let inode_idx = state.fs.inode_counter.get(); + state.fs.inode_counter.replace(inode_idx + 1); + if let Kind::Dir { entries, .. } = &mut state.fs.inodes[inode].kind { + // check that we're not displacing any entries + assert!(entries.insert(segment.clone(), new_inode).is_none()); + state.fs.inodes[new_inode].stat.st_ino = state.fs.inode_counter.get(); + inode = new_inode; + } + debug!("Directory {:#?} lazily loaded", &cumulative_path); } + continue 'outer; } Kind::Symlink { forwarded } => { + // TODO: updated cumulative path sym_count += 1; inode = forwarded.clone(); if sym_count > MAX_SYMLINKS { @@ -1117,30 +1159,48 @@ pub fn path_filestat_get( } let final_inode = match &state.fs.inodes[inode].kind { - Kind::Dir { entries, .. } => { + Kind::Dir { path, entries, .. } => { // TODO: fail earlier if size 0 let last_segment = path_vec.last().unwrap(); + cumulative_path.push(last_segment); + if entries.contains_key(last_segment) { entries[last_segment] } else { // lazily load it if we can - // TODO: adjust to directory correctly - - // HACK(mark): assumes current directory, cumulative dir should be built up in previous loop - let real_open_file = wasi_try!(std::fs::OpenOptions::new() - .read(true) - .write(true) - .open(&last_segment) - .map_err(|_| __WASI_ENOENT)); - - let new_inode = state.fs.inodes.insert(InodeVal { - stat: __wasi_filestat_t::default(), - is_preopened: false, // is this correct? - name: last_segment.clone(), - kind: Kind::File { - handle: WasiFile::HostFile(real_open_file), - }, - }); + if !cumulative_path.exists() { + return __WASI_ENOENT; + } + let final_path_metadata = + wasi_try!(cumulative_path.metadata().map_err(|_| __WASI_EIO)); + let new_inode = if final_path_metadata.is_dir() { + debug!("Opening host directory {:#?}", &cumulative_path); + state.fs.inodes.insert(InodeVal { + stat: __wasi_filestat_t::default(), + is_preopened: false, // is this correct? + name: last_segment.clone(), + kind: Kind::Dir { + path: std::path::PathBuf::from(&last_segment), + entries: Default::default(), + }, + }) + } else { + debug!("Opening host file {:#?}", &cumulative_path); + let real_open_file = wasi_try!(std::fs::OpenOptions::new() + .read(true) + .write(true) + .open(&cumulative_path) + .map_err(|_| __WASI_ENOENT)); + + state.fs.inodes.insert(InodeVal { + stat: __wasi_filestat_t::default(), + is_preopened: false, // is this correct? + name: last_segment.clone(), + kind: Kind::File { + handle: WasiFile::HostFile(real_open_file), + }, + }) + }; // reborrow to insert entry if let Kind::Dir { entries, .. } = &mut state.fs.inodes[inode].kind { entries.insert(last_segment.clone(), new_inode); @@ -1188,7 +1248,7 @@ pub fn path_filestat_set_times( fst_flags: __wasi_fstflags_t, ) -> __wasi_errno_t { debug!("wasi::path_filestat_set_times"); - unimplemented!() + unimplemented!("wasi::path_filestat_set_times") } /// ### `path_link()` @@ -1219,7 +1279,7 @@ pub fn path_link( new_path_len: u32, ) -> __wasi_errno_t { debug!("wasi::path_link"); - unimplemented!() + unimplemented!("wasi::path_link") } /// ### `path_open()` @@ -1312,6 +1372,7 @@ pub fn path_open( match &state.fs.inodes[cur_dir_inode].kind { Kind::Dir { entries, .. } => { if let Some(child) = entries.get(path_segment) { + cumulative_path.push(path_segment); let inode_val = *child; cur_dir_inode = inode_val; } else { @@ -1467,7 +1528,7 @@ pub fn path_readlink( bufused: WasmPtr, ) -> __wasi_errno_t { debug!("wasi::path_readlink"); - unimplemented!() + unimplemented!("wasi::path_readlink") } pub fn path_remove_directory( ctx: &mut Ctx, @@ -1476,7 +1537,7 @@ pub fn path_remove_directory( path_len: u32, ) -> __wasi_errno_t { debug!("wasi::path_remove_directory"); - unimplemented!() + unimplemented!("wasi::path_remove_directory") } pub fn path_rename( ctx: &mut Ctx, @@ -1488,7 +1549,7 @@ pub fn path_rename( new_path_len: u32, ) -> __wasi_errno_t { debug!("wasi::path_rename"); - unimplemented!() + unimplemented!("wasi::path_rename") } pub fn path_symlink( ctx: &mut Ctx, @@ -1499,7 +1560,7 @@ pub fn path_symlink( new_path_len: u32, ) -> __wasi_errno_t { debug!("wasi::path_symlink"); - unimplemented!() + unimplemented!("wasi::path_symlink") } pub fn path_unlink_file( ctx: &mut Ctx, @@ -1508,7 +1569,7 @@ pub fn path_unlink_file( path_len: u32, ) -> __wasi_errno_t { debug!("wasi::path_unlink_file"); - unimplemented!() + unimplemented!("wasi::path_unlink_file") } pub fn poll_oneoff( ctx: &mut Ctx, @@ -1518,7 +1579,7 @@ pub fn poll_oneoff( nevents: WasmPtr, ) -> __wasi_errno_t { debug!("wasi::poll_oneoff"); - unimplemented!() + unimplemented!("wasi::poll_oneoff") } pub fn proc_exit(ctx: &mut Ctx, code: __wasi_exitcode_t) -> Result { debug!("wasi::proc_exit, {}", code); @@ -1526,7 +1587,7 @@ pub fn proc_exit(ctx: &mut Ctx, code: __wasi_exitcode_t) -> Result __wasi_errno_t { debug!("wasi::proc_raise"); - unimplemented!() + unimplemented!("wasi::proc_raise") } /// ### `random_get()` @@ -1569,7 +1630,7 @@ pub fn sock_recv( ro_flags: WasmPtr<__wasi_roflags_t>, ) -> __wasi_errno_t { debug!("wasi::sock_recv"); - unimplemented!() + unimplemented!("wasi::sock_recv") } pub fn sock_send( ctx: &mut Ctx, @@ -1580,9 +1641,9 @@ pub fn sock_send( so_datalen: WasmPtr, ) -> __wasi_errno_t { debug!("wasi::sock_send"); - unimplemented!() + unimplemented!("wasi::sock_send") } pub fn sock_shutdown(ctx: &mut Ctx, sock: __wasi_fd_t, how: __wasi_sdflags_t) -> __wasi_errno_t { debug!("wasi::sock_shutdown"); - unimplemented!() + unimplemented!("wasi::sock_shutdown") } From 02f3349cb143abad8d67ad15017e5d26834eb5f1 Mon Sep 17 00:00:00 2001 From: Mark McCaskey Date: Fri, 10 May 2019 10:58:06 -0700 Subject: [PATCH 3/6] clean up, update changelog --- CHANGELOG.md | 1 + lib/wasi/src/syscalls/mod.rs | 3 --- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b3f8313136f..3e759f960e1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,7 @@ Blocks of changes will separated by version increments. ## **[Unreleased]** +- [#429](https://github.com/wasmerio/wasmer/pull/429) Get wasi::path_filestat_get working for some programs; misc. minor WASI FS improvements - [#413](https://github.com/wasmerio/wasmer/pull/413) Update LLVM backend to use new parser codegen traits ## 0.4.1 - 2018-05-06 diff --git a/lib/wasi/src/syscalls/mod.rs b/lib/wasi/src/syscalls/mod.rs index 3fce35916dd..0389273fc91 100644 --- a/lib/wasi/src/syscalls/mod.rs +++ b/lib/wasi/src/syscalls/mod.rs @@ -1111,15 +1111,12 @@ pub fn path_filestat_get( } else { // lazily load debug!("Lazily loading entry {:?}", &segment); - debug!("EEE"); let path_metadata = wasi_try!(cumulative_path.metadata().map_err(|_| __WASI_ENOENT)); - debug!("DDD"); if !path_metadata.is_dir() { // TODO: should this just return invalid arg? return __WASI_ENOTDIR; } - debug!("AAA"); let kind = Kind::Dir { path: std::path::PathBuf::from(&segment), entries: Default::default(), From 85158ac22ade7538fc7fc98897438234a96b39b7 Mon Sep 17 00:00:00 2001 From: Brandon Fish Date: Thu, 9 May 2019 19:53:23 -0500 Subject: [PATCH 4/6] Add some initial deny for unused_imports and unused_variables Additional unused variable fix on unix Remove unused import on unix Remove unused windows import --- lib/clif-backend/src/lib.rs | 2 ++ lib/emscripten/src/lib.rs | 2 ++ lib/emscripten/src/syscalls/unix.rs | 3 ++- lib/llvm-backend/src/lib.rs | 1 + lib/llvm-backend/src/platform/unix.rs | 2 +- lib/middleware-common/src/call_trace.rs | 2 +- lib/middleware-common/src/lib.rs | 2 ++ lib/runtime-abi/src/lib.rs | 2 ++ lib/runtime-c-api/src/lib.rs | 2 ++ lib/runtime-core/src/codegen.rs | 2 +- lib/runtime-core/src/lib.rs | 1 + lib/runtime/src/lib.rs | 2 ++ lib/singlepass-backend/src/codegen_x64.rs | 4 ++-- lib/singlepass-backend/src/lib.rs | 1 + lib/wasi/src/lib.rs | 2 ++ lib/win-exception-handler/src/exception_handling.rs | 1 - lib/win-exception-handler/src/lib.rs | 2 ++ src/bin/wasmer.rs | 2 ++ src/lib.rs | 2 ++ 19 files changed, 30 insertions(+), 7 deletions(-) diff --git a/lib/clif-backend/src/lib.rs b/lib/clif-backend/src/lib.rs index d09da68125a..639249c346f 100644 --- a/lib/clif-backend/src/lib.rs +++ b/lib/clif-backend/src/lib.rs @@ -1,3 +1,5 @@ +#![deny(unused_imports, unused_variables)] + mod cache; mod func_env; mod libcalls; diff --git a/lib/emscripten/src/lib.rs b/lib/emscripten/src/lib.rs index 54cbad63255..e996fe58b9e 100644 --- a/lib/emscripten/src/lib.rs +++ b/lib/emscripten/src/lib.rs @@ -1,3 +1,5 @@ +#![deny(unused_imports, unused_variables)] + #[macro_use] extern crate wasmer_runtime_core; diff --git a/lib/emscripten/src/syscalls/unix.rs b/lib/emscripten/src/syscalls/unix.rs index a66cf3097d1..ec8b98f3f90 100644 --- a/lib/emscripten/src/syscalls/unix.rs +++ b/lib/emscripten/src/syscalls/unix.rs @@ -1,4 +1,6 @@ use crate::varargs::VarArgs; +#[cfg(target_os = "macos")] +use libc::size_t; /// NOTE: TODO: These syscalls only support wasm_32 for now because they assume offsets are u32 /// Syscall list: https://www.cs.utexas.edu/~bismith/test/syscalls/syscalls32.html use libc::{ @@ -53,7 +55,6 @@ use libc::{ sendto, setpgid, setsockopt, - size_t, sockaddr, socket, socklen_t, diff --git a/lib/llvm-backend/src/lib.rs b/lib/llvm-backend/src/lib.rs index 1d9a030e6ce..c8bc5031845 100644 --- a/lib/llvm-backend/src/lib.rs +++ b/lib/llvm-backend/src/lib.rs @@ -1,3 +1,4 @@ +#![deny(unused_imports, unused_variables)] #![cfg_attr(nightly, feature(unwind_attributes))] mod backend; diff --git a/lib/llvm-backend/src/platform/unix.rs b/lib/llvm-backend/src/platform/unix.rs index 12894f6bc2a..d16384179c1 100644 --- a/lib/llvm-backend/src/platform/unix.rs +++ b/lib/llvm-backend/src/platform/unix.rs @@ -34,7 +34,7 @@ pub unsafe fn visit_fde(addr: *mut u8, size: usize, visitor: extern "C" fn(*mut } #[cfg(not(target_os = "macos"))] -pub unsafe fn visit_fde(addr: *mut u8, size: usize, visitor: extern "C" fn(*mut u8)) { +pub unsafe fn visit_fde(addr: *mut u8, _size: usize, visitor: extern "C" fn(*mut u8)) { visitor(addr); } diff --git a/lib/middleware-common/src/call_trace.rs b/lib/middleware-common/src/call_trace.rs index 3f856eacd81..9c47d7d7bda 100644 --- a/lib/middleware-common/src/call_trace.rs +++ b/lib/middleware-common/src/call_trace.rs @@ -10,7 +10,7 @@ impl FunctionMiddleware for CallTrace { fn feed_event<'a, 'b: 'a>( &mut self, op: Event<'a, 'b>, - module_info: &ModuleInfo, + _module_info: &ModuleInfo, sink: &mut EventSink<'a, 'b>, ) -> Result<(), Self::Error> { match op { diff --git a/lib/middleware-common/src/lib.rs b/lib/middleware-common/src/lib.rs index 10c8dfd37b9..83b1ee35d12 100644 --- a/lib/middleware-common/src/lib.rs +++ b/lib/middleware-common/src/lib.rs @@ -1 +1,3 @@ +#![deny(unused_imports, unused_variables)] + pub mod call_trace; diff --git a/lib/runtime-abi/src/lib.rs b/lib/runtime-abi/src/lib.rs index 2f0ee8c513d..f4b51b1f034 100644 --- a/lib/runtime-abi/src/lib.rs +++ b/lib/runtime-abi/src/lib.rs @@ -1,3 +1,5 @@ +#![deny(unused_imports, unused_variables)] + #[cfg(not(target_os = "windows"))] #[macro_use] extern crate failure; diff --git a/lib/runtime-c-api/src/lib.rs b/lib/runtime-c-api/src/lib.rs index aa6455f6060..6a26d60277f 100644 --- a/lib/runtime-c-api/src/lib.rs +++ b/lib/runtime-c-api/src/lib.rs @@ -1,3 +1,5 @@ +#![deny(unused_imports, unused_variables)] + extern crate wasmer_runtime; extern crate wasmer_runtime_core; diff --git a/lib/runtime-core/src/codegen.rs b/lib/runtime-core/src/codegen.rs index 2ba85863c94..296d1a740e5 100644 --- a/lib/runtime-core/src/codegen.rs +++ b/lib/runtime-core/src/codegen.rs @@ -1,6 +1,6 @@ use crate::{ backend::RunnableModule, - backend::{sys::Memory, Backend, CacheGen, Compiler, CompilerConfig, Token}, + backend::{Backend, CacheGen, Compiler, CompilerConfig, Token}, cache::{Artifact, Error as CacheError}, error::{CompileError, CompileResult}, module::{ModuleInfo, ModuleInner}, diff --git a/lib/runtime-core/src/lib.rs b/lib/runtime-core/src/lib.rs index 46c435db598..2a0cca431b3 100644 --- a/lib/runtime-core/src/lib.rs +++ b/lib/runtime-core/src/lib.rs @@ -1,3 +1,4 @@ +#![deny(unused_imports, unused_variables)] #![cfg_attr(nightly, feature(unwind_attributes))] #[cfg(test)] diff --git a/lib/runtime/src/lib.rs b/lib/runtime/src/lib.rs index 1836bb206be..ba7f4440b17 100644 --- a/lib/runtime/src/lib.rs +++ b/lib/runtime/src/lib.rs @@ -1,3 +1,5 @@ +#![deny(unused_imports, unused_variables)] + //! Wasmer-runtime is a library that makes embedding WebAssembly //! in your application easy, efficient, and safe. //! diff --git a/lib/singlepass-backend/src/codegen_x64.rs b/lib/singlepass-backend/src/codegen_x64.rs index 22687cd9fc6..f7868bc531e 100644 --- a/lib/singlepass-backend/src/codegen_x64.rs +++ b/lib/singlepass-backend/src/codegen_x64.rs @@ -478,7 +478,7 @@ impl ModuleCodeGenerator Ok(()) } - unsafe fn from_cache(artifact: Artifact, _: Token) -> Result { + unsafe fn from_cache(_artifact: Artifact, _: Token) -> Result { Err(CacheError::Unknown( "the singlepass compiler API doesn't support caching yet".to_string(), )) @@ -1409,7 +1409,7 @@ impl FunctionCodeGenerator for X64FunctionCode { Ok(()) } - fn begin_body(&mut self, module_info: &ModuleInfo) -> Result<(), CodegenError> { + fn begin_body(&mut self, _module_info: &ModuleInfo) -> Result<(), CodegenError> { let a = self.assembler.as_mut().unwrap(); a.emit_push(Size::S64, Location::GPR(GPR::RBP)); a.emit_mov(Size::S64, Location::GPR(GPR::RSP), Location::GPR(GPR::RBP)); diff --git a/lib/singlepass-backend/src/lib.rs b/lib/singlepass-backend/src/lib.rs index 08d9774874a..eec02cbfd01 100644 --- a/lib/singlepass-backend/src/lib.rs +++ b/lib/singlepass-backend/src/lib.rs @@ -1,3 +1,4 @@ +#![deny(unused_imports, unused_variables)] #![feature(proc_macro_hygiene)] #[cfg(not(any( diff --git a/lib/wasi/src/lib.rs b/lib/wasi/src/lib.rs index 82de5ad1f70..241cc607c19 100644 --- a/lib/wasi/src/lib.rs +++ b/lib/wasi/src/lib.rs @@ -1,3 +1,5 @@ +#![deny(unused_imports, unused_variables)] + #[macro_use] extern crate log; diff --git a/lib/win-exception-handler/src/exception_handling.rs b/lib/win-exception-handler/src/exception_handling.rs index ea36333ab0c..c448392b0a3 100644 --- a/lib/win-exception-handler/src/exception_handling.rs +++ b/lib/win-exception-handler/src/exception_handling.rs @@ -1,4 +1,3 @@ -use std::ffi::c_void; use std::ptr::NonNull; use wasmer_runtime_core::vm::{Ctx, Func}; diff --git a/lib/win-exception-handler/src/lib.rs b/lib/win-exception-handler/src/lib.rs index bc4a142b5be..dfb95d0e11a 100644 --- a/lib/win-exception-handler/src/lib.rs +++ b/lib/win-exception-handler/src/lib.rs @@ -1,3 +1,5 @@ +#![deny(unused_imports, unused_variables)] + #[cfg(windows)] mod exception_handling; diff --git a/src/bin/wasmer.rs b/src/bin/wasmer.rs index 7760cc3997c..cd36651a55c 100644 --- a/src/bin/wasmer.rs +++ b/src/bin/wasmer.rs @@ -1,3 +1,5 @@ +#![deny(unused_imports, unused_variables)] + extern crate structopt; use std::env; diff --git a/src/lib.rs b/src/lib.rs index 25af8304fe3..9105e278e3b 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,3 +1,5 @@ +#![deny(unused_imports, unused_variables)] + #[macro_use] extern crate wasmer_runtime_core; // extern crate wasmer_emscripten; From a96d5cb975c48111580d88c0b599dad8d4917c5d Mon Sep 17 00:00:00 2001 From: Brandon Fish Date: Sat, 11 May 2019 19:26:17 -0500 Subject: [PATCH 5/6] Fix f32/f64 conversion, add tests, and rename conversion method --- lib/runtime-core/src/typed_func.rs | 8 +-- lib/runtime-core/src/types.rs | 83 +++++++++++++++++++++++++----- 2 files changed, 73 insertions(+), 18 deletions(-) diff --git a/lib/runtime-core/src/typed_func.rs b/lib/runtime-core/src/typed_func.rs index 23a84873822..0a9bc8c2fdb 100644 --- a/lib/runtime-core/src/typed_func.rs +++ b/lib/runtime-core/src/typed_func.rs @@ -247,7 +247,7 @@ impl WasmTypeList for (A,) { type CStruct = S1; type RetArray = [u64; 1]; fn from_ret_array(array: Self::RetArray) -> Self { - (WasmExternType::from_native(NativeWasmType::from_bits( + (WasmExternType::from_native(NativeWasmType::from_binary( array[0], )),) } @@ -274,7 +274,7 @@ impl WasmTypeList for (A,) { ctx: *mut Ctx, ) -> Result { let (a,) = self; - let args = [a.to_native().to_bits()]; + let args = [a.to_native().to_binary()]; let mut rets = Rets::empty_ret_array(); let mut trap = WasmTrapInfo::Unknown; let mut user_error = None; @@ -322,7 +322,7 @@ macro_rules! impl_traits { fn from_ret_array(array: Self::RetArray) -> Self { #[allow(non_snake_case)] let [ $( $x ),* ] = array; - ( $( WasmExternType::from_native(NativeWasmType::from_bits($x)) ),* ) + ( $( WasmExternType::from_native(NativeWasmType::from_binary($x)) ),* ) } fn empty_ret_array() -> Self::RetArray { [0; count_idents!( $( $x ),* )] @@ -344,7 +344,7 @@ macro_rules! impl_traits { unsafe fn call(self, f: NonNull, wasm: Wasm, ctx: *mut Ctx) -> Result { #[allow(unused_parens)] let ( $( $x ),* ) = self; - let args = [ $( $x.to_native().to_bits() ),* ]; + let args = [ $( $x.to_native().to_binary()),* ]; let mut rets = Rets::empty_ret_array(); let mut trap = WasmTrapInfo::Unknown; let mut user_error = None; diff --git a/lib/runtime-core/src/types.rs b/lib/runtime-core/src/types.rs index 23a1c8379c6..975b5cfba36 100644 --- a/lib/runtime-core/src/types.rs +++ b/lib/runtime-core/src/types.rs @@ -76,44 +76,44 @@ where Self: Sized, { const TYPE: Type; - fn from_bits(bits: u64) -> Self; - fn to_bits(self) -> u64; + fn from_binary(bits: u64) -> Self; + fn to_binary(self) -> u64; } unsafe impl NativeWasmType for i32 { const TYPE: Type = Type::I32; - fn from_bits(bits: u64) -> Self { + fn from_binary(bits: u64) -> Self { bits as _ } - fn to_bits(self) -> u64 { + fn to_binary(self) -> u64 { self as _ } } unsafe impl NativeWasmType for i64 { const TYPE: Type = Type::I64; - fn from_bits(bits: u64) -> Self { + fn from_binary(bits: u64) -> Self { bits as _ } - fn to_bits(self) -> u64 { + fn to_binary(self) -> u64 { self as _ } } unsafe impl NativeWasmType for f32 { const TYPE: Type = Type::F32; - fn from_bits(bits: u64) -> Self { - bits as _ + fn from_binary(bits: u64) -> Self { + f32::from_bits(bits as u32) } - fn to_bits(self) -> u64 { - self as _ + fn to_binary(self) -> u64 { + self.to_bits() as _ } } unsafe impl NativeWasmType for f64 { const TYPE: Type = Type::F64; - fn from_bits(bits: u64) -> Self { - bits as _ + fn from_binary(bits: u64) -> Self { + f64::from_bits(bits) } - fn to_bits(self) -> u64 { - self as _ + fn to_binary(self) -> u64 { + self.to_bits() } } @@ -516,3 +516,58 @@ where } } } + +#[cfg(test)] +mod tests { + use crate::types::NativeWasmType; + use crate::types::WasmExternType; + + #[test] + fn test_native_types_round_trip() { + assert_eq!( + 42i32, + i32::from_native(i32::from_binary((42i32).to_native().to_binary())) + ); + + assert_eq!( + -42i32, + i32::from_native(i32::from_binary((-42i32).to_native().to_binary())) + ); + + use std::i64; + let xi64 = i64::MAX; + assert_eq!( + xi64, + i64::from_native(i64::from_binary((xi64).to_native().to_binary())) + ); + let yi64 = i64::MIN; + assert_eq!( + yi64, + i64::from_native(i64::from_binary((yi64).to_native().to_binary())) + ); + + assert_eq!( + 16.5f32, + f32::from_native(f32::from_binary((16.5f32).to_native().to_binary())) + ); + + assert_eq!( + -16.5f32, + f32::from_native(f32::from_binary((-16.5f32).to_native().to_binary())) + ); + + use std::f64; + let xf64: f64 = f64::MAX; + assert_eq!( + xf64, + f64::from_native(f64::from_binary((xf64).to_native().to_binary())) + ); + + let yf64: f64 = f64::MIN; + assert_eq!( + yf64, + f64::from_native(f64::from_binary((yf64).to_native().to_binary())) + ); + } + +} From 2aefa731a66616781f0632d756f1f68c9df831e5 Mon Sep 17 00:00:00 2001 From: Brandon Fish Date: Sun, 12 May 2019 00:33:02 -0500 Subject: [PATCH 6/6] Add deny for unreachable patterns and unused unsafe --- lib/clif-backend/src/lib.rs | 2 +- lib/emscripten/src/lib.rs | 2 +- lib/llvm-backend/src/lib.rs | 2 +- lib/middleware-common/src/lib.rs | 2 +- lib/runtime-abi/src/lib.rs | 2 +- lib/runtime-c-api/src/lib.rs | 2 +- lib/runtime-core/src/codegen.rs | 1 - lib/runtime-core/src/lib.rs | 2 +- lib/runtime/src/lib.rs | 2 +- lib/singlepass-backend/src/codegen_x64.rs | 8 ++++---- lib/singlepass-backend/src/lib.rs | 2 +- lib/wasi/src/lib.rs | 2 +- lib/win-exception-handler/src/lib.rs | 2 +- src/bin/wasmer.rs | 2 +- src/lib.rs | 2 +- 15 files changed, 17 insertions(+), 18 deletions(-) diff --git a/lib/clif-backend/src/lib.rs b/lib/clif-backend/src/lib.rs index 639249c346f..50fbe5dbf4a 100644 --- a/lib/clif-backend/src/lib.rs +++ b/lib/clif-backend/src/lib.rs @@ -1,4 +1,4 @@ -#![deny(unused_imports, unused_variables)] +#![deny(unused_imports, unused_variables, unused_unsafe, unreachable_patterns)] mod cache; mod func_env; diff --git a/lib/emscripten/src/lib.rs b/lib/emscripten/src/lib.rs index e996fe58b9e..6b034051302 100644 --- a/lib/emscripten/src/lib.rs +++ b/lib/emscripten/src/lib.rs @@ -1,4 +1,4 @@ -#![deny(unused_imports, unused_variables)] +#![deny(unused_imports, unused_variables, unused_unsafe, unreachable_patterns)] #[macro_use] extern crate wasmer_runtime_core; diff --git a/lib/llvm-backend/src/lib.rs b/lib/llvm-backend/src/lib.rs index c8bc5031845..6d8816af8a3 100644 --- a/lib/llvm-backend/src/lib.rs +++ b/lib/llvm-backend/src/lib.rs @@ -1,4 +1,4 @@ -#![deny(unused_imports, unused_variables)] +#![deny(unused_imports, unused_variables, unused_unsafe, unreachable_patterns)] #![cfg_attr(nightly, feature(unwind_attributes))] mod backend; diff --git a/lib/middleware-common/src/lib.rs b/lib/middleware-common/src/lib.rs index 83b1ee35d12..e09d9ee03b7 100644 --- a/lib/middleware-common/src/lib.rs +++ b/lib/middleware-common/src/lib.rs @@ -1,3 +1,3 @@ -#![deny(unused_imports, unused_variables)] +#![deny(unused_imports, unused_variables, unused_unsafe, unreachable_patterns)] pub mod call_trace; diff --git a/lib/runtime-abi/src/lib.rs b/lib/runtime-abi/src/lib.rs index f4b51b1f034..d1c9e232646 100644 --- a/lib/runtime-abi/src/lib.rs +++ b/lib/runtime-abi/src/lib.rs @@ -1,4 +1,4 @@ -#![deny(unused_imports, unused_variables)] +#![deny(unused_imports, unused_variables, unused_unsafe, unreachable_patterns)] #[cfg(not(target_os = "windows"))] #[macro_use] diff --git a/lib/runtime-c-api/src/lib.rs b/lib/runtime-c-api/src/lib.rs index 6a26d60277f..f4d4cc2be94 100644 --- a/lib/runtime-c-api/src/lib.rs +++ b/lib/runtime-c-api/src/lib.rs @@ -1,4 +1,4 @@ -#![deny(unused_imports, unused_variables)] +#![deny(unused_imports, unused_variables, unused_unsafe, unreachable_patterns)] extern crate wasmer_runtime; extern crate wasmer_runtime_core; diff --git a/lib/runtime-core/src/codegen.rs b/lib/runtime-core/src/codegen.rs index 296d1a740e5..b61ce58bb88 100644 --- a/lib/runtime-core/src/codegen.rs +++ b/lib/runtime-core/src/codegen.rs @@ -35,7 +35,6 @@ impl fmt::Debug for InternalEvent { InternalEvent::Breakpoint(_) => write!(f, "Breakpoint"), InternalEvent::SetInternal(_) => write!(f, "SetInternal"), InternalEvent::GetInternal(_) => write!(f, "GetInternal"), - _ => panic!("unknown event"), } } } diff --git a/lib/runtime-core/src/lib.rs b/lib/runtime-core/src/lib.rs index 2a0cca431b3..da9144a2b10 100644 --- a/lib/runtime-core/src/lib.rs +++ b/lib/runtime-core/src/lib.rs @@ -1,4 +1,4 @@ -#![deny(unused_imports, unused_variables)] +#![deny(unused_imports, unused_variables, unused_unsafe, unreachable_patterns)] #![cfg_attr(nightly, feature(unwind_attributes))] #[cfg(test)] diff --git a/lib/runtime/src/lib.rs b/lib/runtime/src/lib.rs index ba7f4440b17..bfdf6c9f7aa 100644 --- a/lib/runtime/src/lib.rs +++ b/lib/runtime/src/lib.rs @@ -1,4 +1,4 @@ -#![deny(unused_imports, unused_variables)] +#![deny(unused_imports, unused_variables, unused_unsafe, unreachable_patterns)] //! Wasmer-runtime is a library that makes embedding WebAssembly //! in your application easy, efficient, and safe. diff --git a/lib/singlepass-backend/src/codegen_x64.rs b/lib/singlepass-backend/src/codegen_x64.rs index f7868bc531e..9aa6c9151e2 100644 --- a/lib/singlepass-backend/src/codegen_x64.rs +++ b/lib/singlepass-backend/src/codegen_x64.rs @@ -212,10 +212,10 @@ impl RunnableModule for X64ExecutionContext { user_error: *mut Option>, num_params_plus_one: Option>, ) -> bool { - let rm: &Box = &unsafe { &*(*ctx).module }.runnable_module; - let execution_context = unsafe { - ::std::mem::transmute_copy::<&dyn RunnableModule, &X64ExecutionContext>(&&**rm) - }; + let rm: &Box = &(&*(*ctx).module).runnable_module; + let execution_context = + ::std::mem::transmute_copy::<&dyn RunnableModule, &X64ExecutionContext>(&&**rm); + let args = ::std::slice::from_raw_parts( args, num_params_plus_one.unwrap().as_ptr() as usize - 1, diff --git a/lib/singlepass-backend/src/lib.rs b/lib/singlepass-backend/src/lib.rs index eec02cbfd01..f1011591daf 100644 --- a/lib/singlepass-backend/src/lib.rs +++ b/lib/singlepass-backend/src/lib.rs @@ -1,4 +1,4 @@ -#![deny(unused_imports, unused_variables)] +#![deny(unused_imports, unused_variables, unused_unsafe, unreachable_patterns)] #![feature(proc_macro_hygiene)] #[cfg(not(any( diff --git a/lib/wasi/src/lib.rs b/lib/wasi/src/lib.rs index 241cc607c19..86f9ceaac4a 100644 --- a/lib/wasi/src/lib.rs +++ b/lib/wasi/src/lib.rs @@ -1,4 +1,4 @@ -#![deny(unused_imports, unused_variables)] +#![deny(unused_imports, unused_variables, unused_unsafe, unreachable_patterns)] #[macro_use] extern crate log; diff --git a/lib/win-exception-handler/src/lib.rs b/lib/win-exception-handler/src/lib.rs index dfb95d0e11a..5329e1cc03d 100644 --- a/lib/win-exception-handler/src/lib.rs +++ b/lib/win-exception-handler/src/lib.rs @@ -1,4 +1,4 @@ -#![deny(unused_imports, unused_variables)] +#![deny(unused_imports, unused_variables, unused_unsafe, unreachable_patterns)] #[cfg(windows)] mod exception_handling; diff --git a/src/bin/wasmer.rs b/src/bin/wasmer.rs index cd36651a55c..14386d1b18b 100644 --- a/src/bin/wasmer.rs +++ b/src/bin/wasmer.rs @@ -1,4 +1,4 @@ -#![deny(unused_imports, unused_variables)] +#![deny(unused_imports, unused_variables, unused_unsafe, unreachable_patterns)] extern crate structopt; diff --git a/src/lib.rs b/src/lib.rs index 9105e278e3b..78d6dae28cb 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,4 +1,4 @@ -#![deny(unused_imports, unused_variables)] +#![deny(unused_imports, unused_variables, unused_unsafe, unreachable_patterns)] #[macro_use] extern crate wasmer_runtime_core;