Remove duplication in wasi-common for snapshot_0 (#2444)

This commit deletes the old `snapshot_0` implementation of wasi-common,
along with the `wig` crate that was used to generate bindings for it.
This then reimplements `snapshot_0` in terms of
`wasi_snapshot_preview1`. There were very few changes between the two
snapshots:

* The `nlink` field of `FileStat` was increased from 32 to 64 bits.
* The `set` field of `whence` was reordered.
* Clock subscriptions in polling dropped their redundant userdata field.

This makes all of the syscalls relatively straightforward to simply
delegate to the next snapshot's implementation. Some trickery happens to
avoid extra cost when dealing with iovecs, but since the memory layout
of iovecs remained the same this should still work.

Now that `snapshot_0` is using wiggle we simply have a trait to
implement, and that's implemented for the same `WasiCtx` that has the
`wasi_snapshot_preview1` trait implemented for it as well. While this
theoretically means that you could share the file descriptor table
between the two snapshots that's not supported in the generated bindings
just yet. A separate `WasiCtx` will be created for each WASI module.
This commit is contained in:
Alex Crichton
2020-11-30 12:27:49 -06:00
committed by GitHub
parent d413b907b4
commit efe7f37542
58 changed files with 1071 additions and 6874 deletions

View File

@@ -1 +1,2 @@
pub mod wasi_snapshot_preview1;
pub mod wasi_unstable;

View File

@@ -680,6 +680,69 @@ impl<'a> WasiSnapshotPreview1 for WasiCtx {
subscriptions.push(sub);
}
let events = self.poll_oneoff_impl(&subscriptions)?;
let nevents = events.len().try_into()?;
let out_events = out.as_array(nevents);
for (event, event_ptr) in events.into_iter().zip(out_events.iter()) {
let event_ptr = event_ptr?;
event_ptr.write(event)?;
}
trace!(nevents = nevents);
Ok(nevents)
}
fn proc_exit(&self, _rval: types::Exitcode) -> std::result::Result<(), ()> {
// proc_exit is special in that it's expected to unwind the stack, which
// typically requires runtime-specific logic.
unimplemented!("runtimes are expected to override this implementation")
}
fn proc_raise(&self, _sig: types::Signal) -> Result<()> {
unimplemented!("proc_raise")
}
fn sched_yield(&self) -> Result<()> {
std::thread::yield_now();
Ok(())
}
fn random_get(&self, buf: &GuestPtr<u8>, buf_len: types::Size) -> Result<()> {
let mut slice = buf.as_array(buf_len).as_slice_mut()?;
getrandom::getrandom(&mut *slice)?;
Ok(())
}
fn sock_recv(
&self,
_fd: types::Fd,
_ri_data: &types::IovecArray<'_>,
_ri_flags: types::Riflags,
) -> Result<(types::Size, types::Roflags)> {
unimplemented!("sock_recv")
}
fn sock_send(
&self,
_fd: types::Fd,
_si_data: &types::CiovecArray<'_>,
_si_flags: types::Siflags,
) -> Result<types::Size> {
unimplemented!("sock_send")
}
fn sock_shutdown(&self, _fd: types::Fd, _how: types::Sdflags) -> Result<()> {
unimplemented!("sock_shutdown")
}
}
impl WasiCtx {
pub(crate) fn poll_oneoff_impl(
&self,
subscriptions: &[types::Subscription],
) -> Result<Vec<types::Event>> {
let mut events = Vec::new();
let mut timeout: Option<sched::ClockEventData> = None;
let mut fd_events = Vec::new();
@@ -691,7 +754,7 @@ impl<'a> WasiSnapshotPreview1 for WasiCtx {
}
for subscription in subscriptions {
match subscription.u {
match &subscription.u {
types::SubscriptionU::Clock(clock) => {
let delay = clock::to_relative_ns_delay(&clock)?;
debug!(
@@ -771,59 +834,6 @@ impl<'a> WasiSnapshotPreview1 for WasiCtx {
// if no events have been passed. Such situation may occur if all provided
// events have been filtered out as errors in the code above.
poll::oneoff(timeout, fd_events, &mut events)?;
let nevents = events.len().try_into()?;
let out_events = out.as_array(nevents);
for (event, event_ptr) in events.into_iter().zip(out_events.iter()) {
let event_ptr = event_ptr?;
event_ptr.write(event)?;
}
trace!(nevents = nevents);
Ok(nevents)
}
fn proc_exit(&self, _rval: types::Exitcode) -> std::result::Result<(), ()> {
// proc_exit is special in that it's expected to unwind the stack, which
// typically requires runtime-specific logic.
unimplemented!("runtimes are expected to override this implementation")
}
fn proc_raise(&self, _sig: types::Signal) -> Result<()> {
unimplemented!("proc_raise")
}
fn sched_yield(&self) -> Result<()> {
std::thread::yield_now();
Ok(())
}
fn random_get(&self, buf: &GuestPtr<u8>, buf_len: types::Size) -> Result<()> {
let mut slice = buf.as_array(buf_len).as_slice_mut()?;
getrandom::getrandom(&mut *slice)?;
Ok(())
}
fn sock_recv(
&self,
_fd: types::Fd,
_ri_data: &types::IovecArray<'_>,
_ri_flags: types::Riflags,
) -> Result<(types::Size, types::Roflags)> {
unimplemented!("sock_recv")
}
fn sock_send(
&self,
_fd: types::Fd,
_si_data: &types::CiovecArray<'_>,
_si_flags: types::Siflags,
) -> Result<types::Size> {
unimplemented!("sock_send")
}
fn sock_shutdown(&self, _fd: types::Fd, _how: types::Sdflags) -> Result<()> {
unimplemented!("sock_shutdown")
Ok(events)
}
}

View File

@@ -0,0 +1,938 @@
use crate::wasi::{types as types_new, wasi_snapshot_preview1::WasiSnapshotPreview1};
use crate::{Error, WasiCtx};
use std::convert::{TryFrom, TryInto};
use types::*;
wiggle::from_witx!({
witx: ["$WASI_ROOT/phases/old/snapshot_0/witx/wasi_unstable.witx"],
ctx: WasiCtx,
errors: { errno => Error },
});
impl wiggle::GuestErrorType for Errno {
fn success() -> Self {
Self::Success
}
}
impl types::GuestErrorConversion for WasiCtx {
fn into_errno(&self, e: wiggle::GuestError) -> Errno {
tracing::debug!("Guest error: {:?}", e);
e.into()
}
}
impl types::UserErrorConversion for WasiCtx {
fn errno_from_error(&self, e: Error) -> Result<Errno, String> {
tracing::debug!("Error: {:?}", e);
Ok(e.into())
}
}
impl From<Error> for Errno {
fn from(e: Error) -> Errno {
types_new::Errno::from(e).into()
}
}
impl From<wiggle::GuestError> for Errno {
fn from(err: wiggle::GuestError) -> Self {
types_new::Errno::from(err).into()
}
}
impl wasi_unstable::WasiUnstable for WasiCtx {
fn args_get<'a>(
&self,
argv: &wiggle::GuestPtr<'a, wiggle::GuestPtr<'a, u8>>,
argv_buf: &wiggle::GuestPtr<'a, u8>,
) -> Result<(), Error> {
WasiSnapshotPreview1::args_get(self, argv, argv_buf)
}
fn args_sizes_get(&self) -> Result<(Size, Size), Error> {
WasiSnapshotPreview1::args_sizes_get(self)
}
fn environ_get<'a>(
&self,
environ: &wiggle::GuestPtr<'a, wiggle::GuestPtr<'a, u8>>,
environ_buf: &wiggle::GuestPtr<'a, u8>,
) -> Result<(), Error> {
WasiSnapshotPreview1::environ_get(self, environ, environ_buf)
}
fn environ_sizes_get(&self) -> Result<(Size, Size), Error> {
WasiSnapshotPreview1::environ_sizes_get(self)
}
fn clock_res_get(&self, id: Clockid) -> Result<Timestamp, Error> {
WasiSnapshotPreview1::clock_res_get(self, id.into())
}
fn clock_time_get(&self, id: Clockid, precision: Timestamp) -> Result<Timestamp, Error> {
WasiSnapshotPreview1::clock_time_get(self, id.into(), precision)
}
fn fd_advise(
&self,
fd: Fd,
offset: Filesize,
len: Filesize,
advice: Advice,
) -> Result<(), Error> {
WasiSnapshotPreview1::fd_advise(self, fd.into(), offset, len, advice.into())
}
fn fd_allocate(&self, fd: Fd, offset: Filesize, len: Filesize) -> Result<(), Error> {
WasiSnapshotPreview1::fd_allocate(self, fd.into(), offset, len)
}
fn fd_close(&self, fd: Fd) -> Result<(), Error> {
WasiSnapshotPreview1::fd_close(self, fd.into())
}
fn fd_datasync(&self, fd: Fd) -> Result<(), Error> {
WasiSnapshotPreview1::fd_datasync(self, fd.into())
}
fn fd_fdstat_get(&self, fd: Fd) -> Result<Fdstat, Error> {
WasiSnapshotPreview1::fd_fdstat_get(self, fd.into()).map(|s| s.into())
}
fn fd_fdstat_set_flags(&self, fd: Fd, flags: Fdflags) -> Result<(), Error> {
WasiSnapshotPreview1::fd_fdstat_set_flags(self, fd.into(), flags.into())
}
fn fd_fdstat_set_rights(
&self,
fd: Fd,
fs_rights_base: Rights,
fs_rights_inheriting: Rights,
) -> Result<(), Error> {
WasiSnapshotPreview1::fd_fdstat_set_rights(
self,
fd.into(),
fs_rights_base.into(),
fs_rights_inheriting.into(),
)
}
fn fd_filestat_get(&self, fd: Fd) -> Result<Filestat, Error> {
WasiSnapshotPreview1::fd_filestat_get(self, fd.into()).and_then(|e| e.try_into())
}
fn fd_filestat_set_size(&self, fd: Fd, size: Filesize) -> Result<(), Error> {
WasiSnapshotPreview1::fd_filestat_set_size(self, fd.into(), size)
}
fn fd_filestat_set_times(
&self,
fd: Fd,
atim: Timestamp,
mtim: Timestamp,
fst_flags: Fstflags,
) -> Result<(), Error> {
WasiSnapshotPreview1::fd_filestat_set_times(self, fd.into(), atim, mtim, fst_flags.into())
}
fn fd_pread<'a>(&self, fd: Fd, iovs: &IovecArray<'a>, offset: Filesize) -> Result<Size, Error> {
WasiSnapshotPreview1::fd_pread(self, fd.into(), &cvt_iovec(iovs), offset)
}
fn fd_prestat_get(&self, fd: Fd) -> Result<Prestat, Error> {
WasiSnapshotPreview1::fd_prestat_get(self, fd.into()).map(|e| e.into())
}
fn fd_prestat_dir_name<'a>(
&self,
fd: Fd,
path: &wiggle::GuestPtr<'a, u8>,
path_len: Size,
) -> Result<(), Error> {
WasiSnapshotPreview1::fd_prestat_dir_name(self, fd.into(), path, path_len)
}
fn fd_pwrite<'a>(
&self,
fd: Fd,
iovs: &CiovecArray<'a>,
offset: Filesize,
) -> Result<Size, Error> {
WasiSnapshotPreview1::fd_pwrite(self, fd.into(), &cvt_ciovec(iovs), offset)
}
fn fd_read<'a>(&self, fd: Fd, iovs: &IovecArray<'a>) -> Result<Size, Error> {
WasiSnapshotPreview1::fd_read(self, fd.into(), &cvt_iovec(iovs))
}
fn fd_readdir<'a>(
&self,
fd: Fd,
buf: &wiggle::GuestPtr<'a, u8>,
buf_len: Size,
cookie: Dircookie,
) -> Result<Size, Error> {
WasiSnapshotPreview1::fd_readdir(self, fd.into(), buf, buf_len, cookie)
}
fn fd_renumber(&self, from: Fd, to: Fd) -> Result<(), Error> {
WasiSnapshotPreview1::fd_renumber(self, from.into(), to.into())
}
fn fd_seek(&self, fd: Fd, offset: Filedelta, whence: Whence) -> Result<Filesize, Error> {
WasiSnapshotPreview1::fd_seek(self, fd.into(), offset, whence.into())
}
fn fd_sync(&self, fd: Fd) -> Result<(), Error> {
WasiSnapshotPreview1::fd_sync(self, fd.into())
}
fn fd_tell(&self, fd: Fd) -> Result<Filesize, Error> {
WasiSnapshotPreview1::fd_tell(self, fd.into())
}
fn fd_write<'a>(&self, fd: Fd, iovs: &CiovecArray<'a>) -> Result<Size, Error> {
WasiSnapshotPreview1::fd_write(self, fd.into(), &cvt_ciovec(iovs))
}
fn path_create_directory<'a>(
&self,
fd: Fd,
path: &wiggle::GuestPtr<'a, str>,
) -> Result<(), Error> {
WasiSnapshotPreview1::path_create_directory(self, fd.into(), path)
}
fn path_filestat_get<'a>(
&self,
fd: Fd,
flags: Lookupflags,
path: &wiggle::GuestPtr<'a, str>,
) -> Result<Filestat, Error> {
WasiSnapshotPreview1::path_filestat_get(self, fd.into(), flags.into(), path)
.and_then(|e| e.try_into())
}
fn path_filestat_set_times<'a>(
&self,
fd: Fd,
flags: Lookupflags,
path: &wiggle::GuestPtr<'a, str>,
atim: Timestamp,
mtim: Timestamp,
fst_flags: Fstflags,
) -> Result<(), Error> {
WasiSnapshotPreview1::path_filestat_set_times(
self,
fd.into(),
flags.into(),
path,
atim,
mtim,
fst_flags.into(),
)
}
fn path_link<'a>(
&self,
old_fd: Fd,
old_flags: Lookupflags,
old_path: &wiggle::GuestPtr<'a, str>,
new_fd: Fd,
new_path: &wiggle::GuestPtr<'a, str>,
) -> Result<(), Error> {
WasiSnapshotPreview1::path_link(
self,
old_fd.into(),
old_flags.into(),
old_path,
new_fd.into(),
new_path,
)
}
fn path_open<'a>(
&self,
fd: Fd,
dirflags: Lookupflags,
path: &wiggle::GuestPtr<'a, str>,
oflags: Oflags,
fs_rights_base: Rights,
fs_rights_inheriting: Rights,
fdflags: Fdflags,
) -> Result<Fd, Error> {
WasiSnapshotPreview1::path_open(
self,
fd.into(),
dirflags.into(),
path,
oflags.into(),
fs_rights_base.into(),
fs_rights_inheriting.into(),
fdflags.into(),
)
.map(|e| e.into())
}
fn path_readlink<'a>(
&self,
fd: Fd,
path: &wiggle::GuestPtr<'a, str>,
buf: &wiggle::GuestPtr<'a, u8>,
buf_len: Size,
) -> Result<Size, Error> {
WasiSnapshotPreview1::path_readlink(self, fd.into(), path, buf, buf_len)
}
fn path_remove_directory<'a>(
&self,
fd: Fd,
path: &wiggle::GuestPtr<'a, str>,
) -> Result<(), Error> {
WasiSnapshotPreview1::path_remove_directory(self, fd.into(), path)
}
fn path_rename<'a>(
&self,
fd: Fd,
old_path: &wiggle::GuestPtr<'a, str>,
new_fd: Fd,
new_path: &wiggle::GuestPtr<'a, str>,
) -> Result<(), Error> {
WasiSnapshotPreview1::path_rename(self, fd.into(), old_path, new_fd.into(), new_path)
}
fn path_symlink<'a>(
&self,
old_path: &wiggle::GuestPtr<'a, str>,
fd: Fd,
new_path: &wiggle::GuestPtr<'a, str>,
) -> Result<(), Error> {
WasiSnapshotPreview1::path_symlink(self, old_path, fd.into(), new_path)
}
fn path_unlink_file<'a>(&self, fd: Fd, path: &wiggle::GuestPtr<'a, str>) -> Result<(), Error> {
WasiSnapshotPreview1::path_unlink_file(self, fd.into(), path)
}
fn poll_oneoff<'a>(
&self,
in_: &wiggle::GuestPtr<'a, Subscription>,
out: &wiggle::GuestPtr<'a, Event>,
nsubscriptions: Size,
) -> Result<Size, Error> {
if u64::from(nsubscriptions) > types::Filesize::max_value() {
return Err(Error::Inval);
}
let mut subscriptions = Vec::new();
let subs = in_.as_array(nsubscriptions);
for sub_ptr in subs.iter() {
let sub_ptr = sub_ptr?;
let sub: types::Subscription = sub_ptr.read()?;
subscriptions.push(sub.into());
}
let events = self.poll_oneoff_impl(&subscriptions)?;
let nevents = events.len().try_into()?;
let out_events = out.as_array(nevents);
for (event, event_ptr) in events.into_iter().zip(out_events.iter()) {
let event_ptr = event_ptr?;
event_ptr.write(event.into())?;
}
Ok(nevents)
}
fn proc_exit(&self, rval: Exitcode) -> Result<(), ()> {
WasiSnapshotPreview1::proc_exit(self, rval)
}
fn proc_raise(&self, sig: Signal) -> Result<(), Error> {
WasiSnapshotPreview1::proc_raise(self, sig.into())
}
fn sched_yield(&self) -> Result<(), Error> {
WasiSnapshotPreview1::sched_yield(self)
}
fn random_get<'a>(&self, buf: &wiggle::GuestPtr<'a, u8>, buf_len: Size) -> Result<(), Error> {
WasiSnapshotPreview1::random_get(self, buf, buf_len)
}
fn sock_recv<'a>(
&self,
fd: Fd,
ri_data: &IovecArray<'a>,
ri_flags: Riflags,
) -> Result<(Size, Roflags), Error> {
WasiSnapshotPreview1::sock_recv(self, fd.into(), &cvt_iovec(ri_data), ri_flags.into())
.map(|(s, f)| (s, f.into()))
}
fn sock_send<'a>(
&self,
fd: Fd,
si_data: &CiovecArray<'a>,
si_flags: Siflags,
) -> Result<Size, Error> {
WasiSnapshotPreview1::sock_send(self, fd.into(), &cvt_ciovec(si_data), si_flags.into())
}
fn sock_shutdown(&self, fd: Fd, how: Sdflags) -> Result<(), Error> {
WasiSnapshotPreview1::sock_shutdown(self, fd.into(), how.into())
}
}
impl From<Clockid> for types_new::Clockid {
fn from(id: Clockid) -> types_new::Clockid {
match id {
Clockid::Realtime => types_new::Clockid::Realtime,
Clockid::Monotonic => types_new::Clockid::Monotonic,
Clockid::ProcessCputimeId => types_new::Clockid::ProcessCputimeId,
Clockid::ThreadCputimeId => types_new::Clockid::ThreadCputimeId,
}
}
}
impl From<Fd> for types_new::Fd {
fn from(fd: Fd) -> types_new::Fd {
types_new::Fd::from(u32::from(fd))
}
}
impl From<types_new::Fd> for Fd {
fn from(fd: types_new::Fd) -> Fd {
Fd::from(u32::from(fd))
}
}
impl From<Advice> for types_new::Advice {
fn from(e: Advice) -> types_new::Advice {
match e {
Advice::Normal => types_new::Advice::Normal,
Advice::Sequential => types_new::Advice::Sequential,
Advice::Random => types_new::Advice::Random,
Advice::Willneed => types_new::Advice::Willneed,
Advice::Dontneed => types_new::Advice::Dontneed,
Advice::Noreuse => types_new::Advice::Noreuse,
}
}
}
impl From<types_new::Fdstat> for Fdstat {
fn from(e: types_new::Fdstat) -> Fdstat {
Fdstat {
fs_filetype: e.fs_filetype.into(),
fs_flags: e.fs_flags.into(),
fs_rights_base: e.fs_rights_base.into(),
fs_rights_inheriting: e.fs_rights_inheriting.into(),
}
}
}
fn assert_rights_same() {
macro_rules! assert_same {
($($id:ident)*) => ({$(
assert_eq!(u64::from(Rights::$id), u64::from(types_new::Rights::$id));
)*});
}
assert_same! {
FD_DATASYNC
FD_READ
FD_SEEK
FD_FDSTAT_SET_FLAGS
FD_SYNC
FD_TELL
FD_WRITE
FD_ADVISE
FD_ALLOCATE
PATH_CREATE_DIRECTORY
PATH_CREATE_FILE
PATH_LINK_SOURCE
PATH_LINK_TARGET
PATH_OPEN
FD_READDIR
PATH_READLINK
PATH_RENAME_SOURCE
PATH_RENAME_TARGET
PATH_FILESTAT_GET
PATH_FILESTAT_SET_TIMES
PATH_FILESTAT_SET_SIZE
FD_FILESTAT_GET
FD_FILESTAT_SET_SIZE
FD_FILESTAT_SET_TIMES
PATH_SYMLINK
PATH_REMOVE_DIRECTORY
PATH_UNLINK_FILE
POLL_FD_READWRITE
SOCK_SHUTDOWN
}
}
impl From<Rights> for types_new::Rights {
fn from(e: Rights) -> types_new::Rights {
assert_rights_same();
u64::from(e).try_into().unwrap()
}
}
impl From<types_new::Rights> for Rights {
fn from(e: types_new::Rights) -> Rights {
assert_rights_same();
u64::from(e).try_into().unwrap()
}
}
impl From<Filetype> for types_new::Filetype {
fn from(e: Filetype) -> types_new::Filetype {
match e {
Filetype::Unknown => types_new::Filetype::Unknown,
Filetype::BlockDevice => types_new::Filetype::BlockDevice,
Filetype::CharacterDevice => types_new::Filetype::CharacterDevice,
Filetype::Directory => types_new::Filetype::Directory,
Filetype::RegularFile => types_new::Filetype::RegularFile,
Filetype::SocketDgram => types_new::Filetype::SocketDgram,
Filetype::SocketStream => types_new::Filetype::SocketStream,
Filetype::SymbolicLink => types_new::Filetype::SymbolicLink,
}
}
}
impl From<types_new::Filetype> for Filetype {
fn from(e: types_new::Filetype) -> Filetype {
match e {
types_new::Filetype::Unknown => Filetype::Unknown,
types_new::Filetype::BlockDevice => Filetype::BlockDevice,
types_new::Filetype::CharacterDevice => Filetype::CharacterDevice,
types_new::Filetype::Directory => Filetype::Directory,
types_new::Filetype::RegularFile => Filetype::RegularFile,
types_new::Filetype::SocketDgram => Filetype::SocketDgram,
types_new::Filetype::SocketStream => Filetype::SocketStream,
types_new::Filetype::SymbolicLink => Filetype::SymbolicLink,
}
}
}
fn assert_fdflags_same() {
macro_rules! assert_same {
($($id:ident)*) => ({$(
assert_eq!(u16::from(Fdflags::$id), u16::from(types_new::Fdflags::$id));
)*});
}
assert_same! {
APPEND
DSYNC
NONBLOCK
RSYNC
SYNC
}
}
impl From<Fdflags> for types_new::Fdflags {
fn from(e: Fdflags) -> types_new::Fdflags {
assert_fdflags_same();
u16::from(e).try_into().unwrap()
}
}
impl From<types_new::Fdflags> for Fdflags {
fn from(e: types_new::Fdflags) -> Fdflags {
assert_fdflags_same();
u16::from(e).try_into().unwrap()
}
}
impl TryFrom<types_new::Filestat> for Filestat {
type Error = Error;
fn try_from(e: types_new::Filestat) -> Result<Filestat, Error> {
Ok(Filestat {
dev: e.dev,
ino: e.ino,
filetype: e.filetype.into(),
// wasi_snapshot_preview1 has a 64-bit nlink field but we have a
// 32-bit field, so we need to perform a fallible conversion.
nlink: e.nlink.try_into()?,
size: e.size,
atim: e.atim,
mtim: e.mtim,
ctim: e.ctim,
})
}
}
fn assert_fstflags_same() {
macro_rules! assert_same {
($($id:ident)*) => ({$(
assert_eq!(u16::from(Fstflags::$id), u16::from(types_new::Fstflags::$id));
)*});
}
assert_same! {
ATIM
ATIM_NOW
MTIM
MTIM_NOW
}
}
impl From<Fstflags> for types_new::Fstflags {
fn from(e: Fstflags) -> types_new::Fstflags {
assert_fstflags_same();
u16::from(e).try_into().unwrap()
}
}
impl From<types_new::Fstflags> for Fstflags {
fn from(e: types_new::Fstflags) -> Fstflags {
assert_fstflags_same();
u16::from(e).try_into().unwrap()
}
}
impl From<types_new::Prestat> for Prestat {
fn from(e: types_new::Prestat) -> Prestat {
match e {
types_new::Prestat::Dir(d) => Prestat::Dir(d.into()),
}
}
}
impl From<types_new::PrestatDir> for PrestatDir {
fn from(e: types_new::PrestatDir) -> PrestatDir {
PrestatDir {
pr_name_len: e.pr_name_len,
}
}
}
impl From<Whence> for types_new::Whence {
fn from(e: Whence) -> types_new::Whence {
match e {
Whence::Set => types_new::Whence::Set,
Whence::Cur => types_new::Whence::Cur,
Whence::End => types_new::Whence::End,
}
}
}
fn assert_lookupflags_same() {
macro_rules! assert_same {
($($id:ident)*) => ({$(
assert_eq!(u32::from(Lookupflags::$id), u32::from(types_new::Lookupflags::$id));
)*});
}
assert_same! {
SYMLINK_FOLLOW
}
}
impl From<Lookupflags> for types_new::Lookupflags {
fn from(e: Lookupflags) -> types_new::Lookupflags {
assert_lookupflags_same();
u32::from(e).try_into().unwrap()
}
}
fn assert_oflags_same() {
macro_rules! assert_same {
($($id:ident)*) => ({$(
assert_eq!(u16::from(Oflags::$id), u16::from(types_new::Oflags::$id));
)*});
}
assert_same! {
CREAT
DIRECTORY
EXCL
TRUNC
}
}
impl From<Oflags> for types_new::Oflags {
fn from(e: Oflags) -> types_new::Oflags {
assert_oflags_same();
u16::from(e).try_into().unwrap()
}
}
fn assert_sdflags_same() {
macro_rules! assert_same {
($($id:ident)*) => ({$(
assert_eq!(u8::from(Sdflags::$id), u8::from(types_new::Sdflags::$id));
)*});
}
assert_same! {
RD WR
}
}
impl From<Sdflags> for types_new::Sdflags {
fn from(e: Sdflags) -> types_new::Sdflags {
assert_sdflags_same();
u8::from(e).try_into().unwrap()
}
}
impl From<Signal> for types_new::Signal {
fn from(e: Signal) -> types_new::Signal {
match e {
Signal::None => types_new::Signal::None,
Signal::Hup => types_new::Signal::Hup,
Signal::Int => types_new::Signal::Int,
Signal::Quit => types_new::Signal::Quit,
Signal::Ill => types_new::Signal::Ill,
Signal::Trap => types_new::Signal::Trap,
Signal::Abrt => types_new::Signal::Abrt,
Signal::Bus => types_new::Signal::Bus,
Signal::Fpe => types_new::Signal::Fpe,
Signal::Kill => types_new::Signal::Kill,
Signal::Usr1 => types_new::Signal::Usr1,
Signal::Segv => types_new::Signal::Segv,
Signal::Usr2 => types_new::Signal::Usr2,
Signal::Pipe => types_new::Signal::Pipe,
Signal::Alrm => types_new::Signal::Alrm,
Signal::Term => types_new::Signal::Term,
Signal::Chld => types_new::Signal::Chld,
Signal::Cont => types_new::Signal::Cont,
Signal::Stop => types_new::Signal::Stop,
Signal::Tstp => types_new::Signal::Tstp,
Signal::Ttin => types_new::Signal::Ttin,
Signal::Ttou => types_new::Signal::Ttou,
Signal::Urg => types_new::Signal::Urg,
Signal::Xcpu => types_new::Signal::Xcpu,
Signal::Xfsz => types_new::Signal::Xfsz,
Signal::Vtalrm => types_new::Signal::Vtalrm,
Signal::Prof => types_new::Signal::Prof,
Signal::Winch => types_new::Signal::Winch,
Signal::Poll => types_new::Signal::Poll,
Signal::Pwr => types_new::Signal::Pwr,
Signal::Sys => types_new::Signal::Sys,
}
}
}
// For `wasi_unstable` and `wasi_snapshot_preview1` the memory layout of these
// two types was manually verified. It should be fine to effectively cast
// between the two types and get the same behavior.
fn cvt_iovec<'a>(e: &IovecArray<'a>) -> types_new::IovecArray<'a> {
wiggle::GuestPtr::new(e.mem(), (e.offset_base(), e.len()))
}
fn cvt_ciovec<'a>(e: &CiovecArray<'a>) -> types_new::CiovecArray<'a> {
wiggle::GuestPtr::new(e.mem(), (e.offset_base(), e.len()))
}
fn assert_riflags_same() {
macro_rules! assert_same {
($($id:ident)*) => ({$(
assert_eq!(u16::from(Riflags::$id), u16::from(types_new::Riflags::$id));
)*});
}
assert_same! {
RECV_PEEK
RECV_WAITALL
}
}
impl From<Riflags> for types_new::Riflags {
fn from(e: Riflags) -> types_new::Riflags {
assert_riflags_same();
u16::from(e).try_into().unwrap()
}
}
fn assert_roflags_same() {
macro_rules! assert_same {
($($id:ident)*) => ({$(
assert_eq!(u16::from(Roflags::$id), u16::from(types_new::Roflags::$id));
)*});
}
assert_same! {
RECV_DATA_TRUNCATED
}
}
impl From<types_new::Roflags> for Roflags {
fn from(e: types_new::Roflags) -> Roflags {
assert_roflags_same();
u16::from(e).try_into().unwrap()
}
}
impl From<Subscription> for types_new::Subscription {
fn from(e: Subscription) -> types_new::Subscription {
types_new::Subscription {
userdata: e.userdata,
u: e.u.into(),
}
}
}
impl From<SubscriptionU> for types_new::SubscriptionU {
fn from(e: SubscriptionU) -> types_new::SubscriptionU {
match e {
SubscriptionU::Clock(c) => {
types_new::SubscriptionU::Clock(types_new::SubscriptionClock {
id: c.id.into(),
timeout: c.timeout,
precision: c.precision,
flags: c.flags.into(),
})
}
SubscriptionU::FdRead(c) => {
types_new::SubscriptionU::FdRead(types_new::SubscriptionFdReadwrite {
file_descriptor: c.file_descriptor.into(),
})
}
SubscriptionU::FdWrite(c) => {
types_new::SubscriptionU::FdWrite(types_new::SubscriptionFdReadwrite {
file_descriptor: c.file_descriptor.into(),
})
}
}
}
}
impl From<Subclockflags> for types_new::Subclockflags {
fn from(e: Subclockflags) -> types_new::Subclockflags {
macro_rules! assert_same {
($($id:ident)*) => ({$(
assert_eq!(u16::from(Subclockflags::$id), u16::from(types_new::Subclockflags::$id));
)*});
}
assert_same! {
SUBSCRIPTION_CLOCK_ABSTIME
}
u16::from(e).try_into().unwrap()
}
}
impl From<types_new::Event> for Event {
fn from(e: types_new::Event) -> Event {
Event {
userdata: e.userdata,
error: e.error.into(),
type_: e.type_.into(),
fd_readwrite: e.fd_readwrite.into(),
}
}
}
impl From<types_new::Errno> for Errno {
fn from(e: types_new::Errno) -> Errno {
match e {
types_new::Errno::Success => Errno::Success,
types_new::Errno::TooBig => Errno::TooBig,
types_new::Errno::Acces => Errno::Acces,
types_new::Errno::Addrinuse => Errno::Addrinuse,
types_new::Errno::Addrnotavail => Errno::Addrnotavail,
types_new::Errno::Afnosupport => Errno::Afnosupport,
types_new::Errno::Again => Errno::Again,
types_new::Errno::Already => Errno::Already,
types_new::Errno::Badf => Errno::Badf,
types_new::Errno::Badmsg => Errno::Badmsg,
types_new::Errno::Busy => Errno::Busy,
types_new::Errno::Canceled => Errno::Canceled,
types_new::Errno::Child => Errno::Child,
types_new::Errno::Connaborted => Errno::Connaborted,
types_new::Errno::Connrefused => Errno::Connrefused,
types_new::Errno::Connreset => Errno::Connreset,
types_new::Errno::Deadlk => Errno::Deadlk,
types_new::Errno::Destaddrreq => Errno::Destaddrreq,
types_new::Errno::Dom => Errno::Dom,
types_new::Errno::Dquot => Errno::Dquot,
types_new::Errno::Exist => Errno::Exist,
types_new::Errno::Fault => Errno::Fault,
types_new::Errno::Fbig => Errno::Fbig,
types_new::Errno::Hostunreach => Errno::Hostunreach,
types_new::Errno::Idrm => Errno::Idrm,
types_new::Errno::Ilseq => Errno::Ilseq,
types_new::Errno::Inprogress => Errno::Inprogress,
types_new::Errno::Intr => Errno::Intr,
types_new::Errno::Inval => Errno::Inval,
types_new::Errno::Io => Errno::Io,
types_new::Errno::Isconn => Errno::Isconn,
types_new::Errno::Isdir => Errno::Isdir,
types_new::Errno::Loop => Errno::Loop,
types_new::Errno::Mfile => Errno::Mfile,
types_new::Errno::Mlink => Errno::Mlink,
types_new::Errno::Msgsize => Errno::Msgsize,
types_new::Errno::Multihop => Errno::Multihop,
types_new::Errno::Nametoolong => Errno::Nametoolong,
types_new::Errno::Netdown => Errno::Netdown,
types_new::Errno::Netreset => Errno::Netreset,
types_new::Errno::Netunreach => Errno::Netunreach,
types_new::Errno::Nfile => Errno::Nfile,
types_new::Errno::Nobufs => Errno::Nobufs,
types_new::Errno::Nodev => Errno::Nodev,
types_new::Errno::Noent => Errno::Noent,
types_new::Errno::Noexec => Errno::Noexec,
types_new::Errno::Nolck => Errno::Nolck,
types_new::Errno::Nolink => Errno::Nolink,
types_new::Errno::Nomem => Errno::Nomem,
types_new::Errno::Nomsg => Errno::Nomsg,
types_new::Errno::Noprotoopt => Errno::Noprotoopt,
types_new::Errno::Nospc => Errno::Nospc,
types_new::Errno::Nosys => Errno::Nosys,
types_new::Errno::Notconn => Errno::Notconn,
types_new::Errno::Notdir => Errno::Notdir,
types_new::Errno::Notempty => Errno::Notempty,
types_new::Errno::Notrecoverable => Errno::Notrecoverable,
types_new::Errno::Notsock => Errno::Notsock,
types_new::Errno::Notsup => Errno::Notsup,
types_new::Errno::Notty => Errno::Notty,
types_new::Errno::Nxio => Errno::Nxio,
types_new::Errno::Overflow => Errno::Overflow,
types_new::Errno::Ownerdead => Errno::Ownerdead,
types_new::Errno::Perm => Errno::Perm,
types_new::Errno::Pipe => Errno::Pipe,
types_new::Errno::Proto => Errno::Proto,
types_new::Errno::Protonosupport => Errno::Protonosupport,
types_new::Errno::Prototype => Errno::Prototype,
types_new::Errno::Range => Errno::Range,
types_new::Errno::Rofs => Errno::Rofs,
types_new::Errno::Spipe => Errno::Spipe,
types_new::Errno::Srch => Errno::Srch,
types_new::Errno::Stale => Errno::Stale,
types_new::Errno::Timedout => Errno::Timedout,
types_new::Errno::Txtbsy => Errno::Txtbsy,
types_new::Errno::Xdev => Errno::Xdev,
types_new::Errno::Notcapable => Errno::Notcapable,
}
}
}
impl From<types_new::Eventtype> for Eventtype {
fn from(e: types_new::Eventtype) -> Eventtype {
match e {
types_new::Eventtype::Clock => Eventtype::Clock,
types_new::Eventtype::FdRead => Eventtype::FdRead,
types_new::Eventtype::FdWrite => Eventtype::FdWrite,
}
}
}
impl From<types_new::EventFdReadwrite> for EventFdReadwrite {
fn from(e: types_new::EventFdReadwrite) -> EventFdReadwrite {
EventFdReadwrite {
nbytes: e.nbytes,
flags: e.flags.into(),
}
}
}
impl From<types_new::Eventrwflags> for Eventrwflags {
fn from(e: types_new::Eventrwflags) -> Eventrwflags {
macro_rules! assert_same {
($($id:ident)*) => ({$(
assert_eq!(u16::from(Eventrwflags::$id), u16::from(types_new::Eventrwflags::$id));
)*});
}
assert_same! {
FD_READWRITE_HANGUP
}
u16::from(e).try_into().unwrap()
}
}