It's wiggle time! (#1202)
* Use wiggle in place of wig in wasi-common This is a rather massive commit that introduces `wiggle` into the picture. We still use `wig`'s macro in `old` snapshot and to generate `wasmtime-wasi` glue, but everything else is now autogenerated by `wiggle`. In summary, thanks to `wiggle`, we no longer need to worry about serialising and deserialising to and from the guest memory, and all guest (WASI) types are now proper idiomatic Rust types. While we're here, in preparation for the ephemeral snapshot, I went ahead and reorganised the internal structure of the crate. Instead of modules like `hostcalls_impl` or `hostcalls_impl::fs`, the structure now resembles that in ephemeral with modules like `path`, `fd`, etc. Now, I'm not requiring we leave it like this, but I reckon it looks cleaner this way after all. * Fix wig to use new first-class access to caller's mem * Ignore warning in proc_exit for the moment * Group unsafes together in args and environ calls * Simplify pwrite; more unsafe blocks * Simplify fd_read * Bundle up unsafes in fd_readdir * Simplify fd_write * Add comment to path_readlink re zero-len buffers * Simplify unsafes in random_get * Hide GuestPtr<str> to &str in path::get * Rewrite pread and pwrite using SeekFrom and read/write_vectored I've left the implementation of VirtualFs pretty much untouched as I don't feel that comfortable in changing the API too much. Having said that, I reckon `pread` and `pwrite` could be refactored out, and `preadv` and `pwritev` could be entirely rewritten using `seek` and `read_vectored` and `write_vectored`. * Add comment about VirtFs unsafety * Fix all mentions of FdEntry to Entry * Fix warnings on Win * Add aux struct EntryTable responsible for Fds and Entries This commit adds aux struct `EntryTable` which is private to `WasiCtx` and is basically responsible for `Fd` alloc/dealloc as well as storing matching `Entry`s. This struct is entirely private to `WasiCtx` and as such as should remain transparent to `WasiCtx` users. * Remove redundant check for empty buffer in path_readlink * Preserve and rewind file cursor in pread/pwrite * Use GuestPtr<[u8]>::copy_from_slice wherever copying bytes directly * Use GuestPtr<[u8]>::copy_from_slice in fd_readdir * Clean up unsafes around WasiCtx accessors * Fix bugs in args_get and environ_get * Fix conflicts after rebase
This commit is contained in:
@@ -1,5 +1,7 @@
|
||||
use crate::fs::{File, OpenOptions, ReadDir};
|
||||
use crate::{host, hostcalls, wasi, WasiCtx};
|
||||
use crate::wasi::types;
|
||||
use crate::wasi::wasi_snapshot_preview1::WasiSnapshotPreview1;
|
||||
use crate::WasiCtx;
|
||||
#[cfg(unix)]
|
||||
use std::os::unix::ffi::OsStrExt;
|
||||
use std::{io, path::Path};
|
||||
@@ -15,13 +17,13 @@ use std::{io, path::Path};
|
||||
/// Unlike `std::fs`, this API has no `canonicalize`, because absolute paths
|
||||
/// don't interoperate well with the capability-oriented security model.
|
||||
pub struct Dir<'ctx> {
|
||||
ctx: &'ctx mut WasiCtx,
|
||||
fd: wasi::__wasi_fd_t,
|
||||
ctx: &'ctx WasiCtx,
|
||||
fd: types::Fd,
|
||||
}
|
||||
|
||||
impl<'ctx> Dir<'ctx> {
|
||||
/// Constructs a new instance of `Self` from the given raw WASI file descriptor.
|
||||
pub unsafe fn from_raw_wasi_fd(ctx: &'ctx mut WasiCtx, fd: wasi::__wasi_fd_t) -> Self {
|
||||
pub unsafe fn from_raw_wasi_fd(ctx: &'ctx WasiCtx, fd: types::Fd) -> Self {
|
||||
Self { ctx, fd }
|
||||
}
|
||||
|
||||
@@ -37,7 +39,7 @@ impl<'ctx> Dir<'ctx> {
|
||||
/// [`std::fs::File::open`]: https://doc.rust-lang.org/std/fs/struct.File.html#method.open
|
||||
pub fn open_file<P: AsRef<Path>>(&mut self, path: P) -> io::Result<File> {
|
||||
let path = path.as_ref();
|
||||
let mut fd = 0;
|
||||
let mut fd = types::Fd::from(0);
|
||||
|
||||
// TODO: Refactor the hostcalls functions to split out the encoding/decoding
|
||||
// parts from the underlying functionality, so that we can call into the
|
||||
@@ -90,7 +92,7 @@ impl<'ctx> Dir<'ctx> {
|
||||
/// TODO: Not yet implemented. See the comment in `open_file`.
|
||||
pub fn open_dir<P: AsRef<Path>>(&mut self, path: P) -> io::Result<Self> {
|
||||
let path = path.as_ref();
|
||||
let mut fd = 0;
|
||||
let mut fd = types::Fd::from(0);
|
||||
|
||||
// TODO: See the comment in `open_file`.
|
||||
unimplemented!("Dir::open_dir");
|
||||
@@ -122,7 +124,7 @@ impl<'ctx> Dir<'ctx> {
|
||||
/// [`std::fs::File::create`]: https://doc.rust-lang.org/std/fs/struct.File.html#method.create
|
||||
pub fn create_file<P: AsRef<Path>>(&mut self, path: P) -> io::Result<File> {
|
||||
let path = path.as_ref();
|
||||
let mut fd = 0;
|
||||
let mut fd = types::Fd::from(0);
|
||||
|
||||
// TODO: See the comments in `open_file`.
|
||||
//
|
||||
@@ -199,7 +201,7 @@ impl<'ctx> Drop for Dir<'ctx> {
|
||||
// the file descriptor was closed or not, and if we retried (for
|
||||
// something like EINTR), we might close another valid file descriptor
|
||||
// opened after we closed ours.
|
||||
let _ = unsafe { hostcalls::fd_close(self.ctx, &mut [], self.fd) };
|
||||
let _ = self.ctx.fd_close(self.fd);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
use crate::fs::Metadata;
|
||||
use crate::wasi::{self, WasiResult};
|
||||
use crate::{host, hostcalls, hostcalls_impl, WasiCtx};
|
||||
use crate::wasi::wasi_snapshot_preview1::WasiSnapshotPreview1;
|
||||
use crate::wasi::{types, Result};
|
||||
use crate::WasiCtx;
|
||||
use std::io;
|
||||
|
||||
/// A reference to an open file on the filesystem.
|
||||
@@ -16,8 +17,8 @@ use std::io;
|
||||
/// [`Dir::open_file`]: struct.Dir.html#method.open_file
|
||||
/// [`Dir::create_file`]: struct.Dir.html#method.create_file
|
||||
pub struct File<'ctx> {
|
||||
ctx: &'ctx mut WasiCtx,
|
||||
fd: wasi::__wasi_fd_t,
|
||||
ctx: &'ctx WasiCtx,
|
||||
fd: types::Fd,
|
||||
}
|
||||
|
||||
impl<'ctx> File<'ctx> {
|
||||
@@ -26,7 +27,7 @@ impl<'ctx> File<'ctx> {
|
||||
/// This corresponds to [`std::fs::File::from_raw_fd`].
|
||||
///
|
||||
/// [`std::fs::File::from_raw_fd`]: https://doc.rust-lang.org/std/fs/struct.File.html#method.from_raw_fd
|
||||
pub unsafe fn from_raw_wasi_fd(ctx: &'ctx mut WasiCtx, fd: wasi::__wasi_fd_t) -> Self {
|
||||
pub unsafe fn from_raw_wasi_fd(ctx: &'ctx WasiCtx, fd: types::Fd) -> Self {
|
||||
Self { ctx, fd }
|
||||
}
|
||||
|
||||
@@ -35,10 +36,8 @@ impl<'ctx> File<'ctx> {
|
||||
/// This corresponds to [`std::fs::File::sync_all`].
|
||||
///
|
||||
/// [`std::fs::File::sync_all`]: https://doc.rust-lang.org/std/fs/struct.File.html#method.sync_all
|
||||
pub fn sync_all(&self) -> WasiResult<()> {
|
||||
unsafe {
|
||||
hostcalls_impl::fd_sync(self.ctx, &mut [], self.fd)?;
|
||||
}
|
||||
pub fn sync_all(&self) -> Result<()> {
|
||||
self.ctx.fd_sync(self.fd)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -48,10 +47,8 @@ impl<'ctx> File<'ctx> {
|
||||
/// This corresponds to [`std::fs::File::sync_data`].
|
||||
///
|
||||
/// [`std::fs::File::sync_data`]: https://doc.rust-lang.org/std/fs/struct.File.html#method.sync_data
|
||||
pub fn sync_data(&self) -> WasiResult<()> {
|
||||
unsafe {
|
||||
hostcalls_impl::fd_datasync(self.ctx, &mut [], self.fd)?;
|
||||
}
|
||||
pub fn sync_data(&self) -> Result<()> {
|
||||
self.ctx.fd_datasync(self.fd)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -61,10 +58,8 @@ impl<'ctx> File<'ctx> {
|
||||
/// This corresponds to [`std::fs::File::set_len`].
|
||||
///
|
||||
/// [`std::fs::File::set_len`]: https://doc.rust-lang.org/std/fs/struct.File.html#method.set_len
|
||||
pub fn set_len(&self, size: u64) -> WasiResult<()> {
|
||||
unsafe {
|
||||
hostcalls_impl::fd_filestat_set_size(self.ctx, &mut [], self.fd, size)?;
|
||||
}
|
||||
pub fn set_len(&self, size: u64) -> Result<()> {
|
||||
self.ctx.fd_filestat_set_size(self.fd, size)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -73,7 +68,7 @@ impl<'ctx> File<'ctx> {
|
||||
/// This corresponds to [`std::fs::File::metadata`].
|
||||
///
|
||||
/// [`std::fs::File::metadata`]: https://doc.rust-lang.org/std/fs/struct.File.html#method.metadata
|
||||
pub fn metadata(&self) -> WasiResult<Metadata> {
|
||||
pub fn metadata(&self) -> Result<Metadata> {
|
||||
Ok(Metadata {})
|
||||
}
|
||||
}
|
||||
@@ -85,17 +80,18 @@ impl<'ctx> Drop for File<'ctx> {
|
||||
// the file descriptor was closed or not, and if we retried (for
|
||||
// something like EINTR), we might close another valid file descriptor
|
||||
// opened after we closed ours.
|
||||
let _ = unsafe { hostcalls::fd_close(self.ctx, &mut [], self.fd) };
|
||||
let _ = self.ctx.fd_close(self.fd);
|
||||
}
|
||||
}
|
||||
|
||||
impl<'ctx> io::Read for File<'ctx> {
|
||||
/// TODO: Not yet implemented. See the comment in `Dir::open_file`.
|
||||
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
|
||||
let iov = [host::__wasi_iovec_t {
|
||||
buf: buf.as_mut_ptr() as *mut u8,
|
||||
buf_len: buf.len(),
|
||||
}];
|
||||
// TODO
|
||||
// let iov = [types::Iovec {
|
||||
// buf: buf.as_mut_ptr() as *mut u8,
|
||||
// buf_len: buf.len(),
|
||||
// }];
|
||||
let mut nread = 0;
|
||||
|
||||
// TODO: See the comment in `Dir::open_file`.
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
use crate::fs::DirEntry;
|
||||
use crate::{hostcalls, wasi};
|
||||
use crate::wasi::types;
|
||||
|
||||
/// Iterator over the entries in a directory.
|
||||
///
|
||||
@@ -9,12 +9,12 @@ use crate::{hostcalls, wasi};
|
||||
///
|
||||
/// [`std::fs::ReadDir`]: https://doc.rust-lang.org/std/fs/struct.ReadDir.html
|
||||
pub struct ReadDir {
|
||||
fd: wasi::__wasi_fd_t,
|
||||
fd: types::Fd,
|
||||
}
|
||||
|
||||
impl ReadDir {
|
||||
/// Constructs a new instance of `Self` from the given raw WASI file descriptor.
|
||||
pub unsafe fn from_raw_wasi_fd(fd: wasi::__wasi_fd_t) -> Self {
|
||||
pub unsafe fn from_raw_wasi_fd(fd: types::Fd) -> Self {
|
||||
Self { fd }
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user