Browse Source

Import all changes from lucet-wasi

pull/502/head
Jakub Konka 6 years ago
committed by Dan Gohman
parent
commit
b9871648b2
  1. 67
      README.md
  2. 12
      src/host.rs
  3. 1576
      src/hostcalls.rs
  4. 82
      src/memory.rs

67
README.md

@ -8,7 +8,7 @@
[Wasmtime]: https://github.com/CraneStation/wasmtime
[Lucet]: https://github.com/fastly/lucet
[lucet-wasi]: https://github.com/fastly/lucet/tree/master/lucet-wasi
[lucet-wasi-tracker]: https://github.com/fastly/lucet/commit/5d3efb6005391a7c71d585732a5507b00db6bb1e
[lucet-wasi-tracker]: https://github.com/fastly/lucet/commit/40ae1df64536250a2b6ab67e7f167d22f4aa7f94
[WASI API]: https://github.com/CraneStation/wasmtime/blob/master/docs/WASI-api.md
This repo will ultimately serve as a library providing a common implementation of
@ -16,7 +16,7 @@ WASI hostcalls for re-use in any WASI (and potentially non-WASI) runtimes
such as [Wasmtime] and [Lucet].
The library is an adaption of [lucet-wasi] crate from the [Lucet] project, and it is
currently based on [5d3efb6005][lucet-wasi-tracker] git revision.
currently based on [40ae1df][lucet-wasi-tracker] git revision.
Please note that the library requires Rust compiler version at least 1.34.0.
@ -25,28 +25,47 @@ Please note that the library requires Rust compiler version at least 1.34.0.
We support a subset of the [WASI API], though we are working on new hostcalls
on a regular basis. We currently implement:
- `__wasi_args_get`
- `__wasi_args_sizes_get`
- `__wasi_clock_res_get`
- `__wasi_clock_time_get`
- `__wasi_environ_get`
- `__wasi_environ_sizes_get`
- `__wasi_fd_close`
- `__wasi_fd_fdstat_get`
- `__wasi_fd_fdstat_set_flags`
- `__wasi_fd_filestat_get`
- `__wasi_fd_prestat_dir_name`
- `__wasi_fd_prestat_get`
- `__wasi_fd_read`
- `__wasi_fd_seek`
- `__wasi_fd_write`
- `__wasi_path_open`
- `__wasi_path_filestat_get`
- `__wasi_path_create_directory`
- `__wasi_path_unlink_file`
- `__wasi_poll_oneoff`
- `__wasi_proc_exit`
- `__wasi_random_get`
- `args_get`
- `args_sizes_get`
- `clock_res_get`
- `clock_time_get`
- `environ_get`
- `environ_sizes_get`
- `fd_close`
- `fd_datasync`
- `fd_pread`
- `fd_pwrite`
- `fd_read`
- `fd_renumber`
- `fd_seek`
- `fd_tell`
- `fd_fdstat_get`
- `fd_fdstat_set_flags`
- `fd_fdstat_set_rights`
- `fd_sync`
- `fd_write`
- `fd_advise`
- `fd_allocate`
- `path_create_directory`
- `path_link`
- `path_open`
- `fd_readdir`
- `path_readlink`
- `path_rename`
- `fd_filestat_get`
- `fd_filestat_set_times`
- `fd_filestat_set_size`
- `path_filestat_get`
- `path_filestat_set_times`
- `path_symlink`
- `path_unlink_file`
- `path_remove_directory`
- `poll_oneoff`
- `fd_prestat_get`
- `fd_prestat_dir_name`
- `proc_exit`
- `random_get`
- `sched_yield`
This is enough to run basic C and Rust programs, including those that use command-line arguments,
environment variables, stdio, and basic file operations.

12
src/host.rs

@ -567,6 +567,18 @@ pub unsafe fn ciovec_to_nix_mut<'a>(
nix::sys::uio::IoVec::from_mut_slice(slice)
}
pub unsafe fn iovec_to_nix<'a>(iovec: &'a __wasi_iovec_t) -> nix::sys::uio::IoVec<&'a [u8]> {
let slice = std::slice::from_raw_parts(iovec.buf as *const u8, iovec.buf_len);
nix::sys::uio::IoVec::from_slice(slice)
}
pub unsafe fn iovec_to_nix_mut<'a>(
iovec: &'a mut __wasi_iovec_t,
) -> nix::sys::uio::IoVec<&'a mut [u8]> {
let slice = std::slice::from_raw_parts_mut(iovec.buf as *mut u8, iovec.buf_len);
nix::sys::uio::IoVec::from_mut_slice(slice)
}
#[cfg(target_os = "linux")]
pub const O_RSYNC: nix::fcntl::OFlag = nix::fcntl::OFlag::O_RSYNC;

1576
src/hostcalls.rs

File diff suppressed because it is too large

82
src/memory.rs

@ -199,6 +199,26 @@ pub fn dec_ciovec_slice(
slice.iter().map(|iov| dec_ciovec(memory, iov)).collect()
}
pub fn dec_iovec(
memory: &[u8],
iovec: &wasm32::__wasi_iovec_t,
) -> Result<host::__wasi_iovec_t, host::__wasi_errno_t> {
let len = dec_usize(iovec.buf_len);
Ok(host::__wasi_iovec_t {
buf: dec_ptr(memory, iovec.buf, len)? as *mut host::void,
buf_len: len,
})
}
pub fn dec_iovec_slice(
memory: &[u8],
ptr: wasm32::uintptr_t,
len: wasm32::size_t,
) -> Result<Vec<host::__wasi_iovec_t>, host::__wasi_errno_t> {
let slice = dec_slice_of::<wasm32::__wasi_iovec_t>(memory, ptr, len)?;
slice.iter().map(|iov| dec_iovec(memory, iov)).collect()
}
dec_enc_scalar!(
__wasi_clockid_t,
dec_clockid,
@ -435,6 +455,14 @@ dec_enc_scalar!(
enc_timestamp_byref
);
pub fn dec_u32(x: u32) -> u32 {
u32::from_le(x)
}
pub fn enc_u32(x: u32) -> u32 {
x.to_le()
}
pub fn dec_usize(size: wasm32::size_t) -> usize {
cast::usize(u32::from_le(size))
}
@ -535,3 +563,57 @@ pub fn enc_event(event: host::__wasi_event_t) -> wasm32::__wasi_event_t {
__bindgen_padding_0: 0,
}
}
dec_enc_scalar!(
__wasi_advice_t,
dec_advice,
dec_advice_byref,
enc_advice,
enc_advice_byref
);
dec_enc_scalar!(
__wasi_fstflags_t,
dec_fstflags,
dec_fstflags_byref,
enc_fstflags,
enc_fstflags_byref
);
dec_enc_scalar!(
__wasi_dircookie_t,
dec_dircookie,
dec_dircookie_byref,
enc_dircookie,
enc_dircookie_byref
);
#[cfg(target_os = "linux")]
pub fn dirent_from_host(
host_entry: &nix::libc::dirent,
) -> Result<wasm32::__wasi_dirent_t, host::__wasi_errno_t> {
let mut entry = unsafe { std::mem::zeroed::<wasm32::__wasi_dirent_t>() };
let d_namlen = unsafe { std::ffi::CStr::from_ptr(host_entry.d_name.as_ptr()) }
.to_bytes()
.len();
if d_namlen > u32::max_value() as usize {
return Err(host::__WASI_EIO);
}
entry.d_ino = enc_inode(host_entry.d_ino);
entry.d_next = enc_dircookie(host_entry.d_off as u64);
entry.d_namlen = enc_u32(d_namlen as u32);
entry.d_type = enc_filetype(host_entry.d_type);
Ok(entry)
}
#[cfg(not(target_os = "linux"))]
pub fn dirent_from_host(
host_entry: &nix::libc::dirent,
) -> Result<wasm32::__wasi_dirent_t, host::__wasi_errno_t> {
let mut entry = unsafe { std::mem::zeroed::<wasm32::__wasi_dirent_t>() };
entry.d_ino = enc_inode(host_entry.d_ino);
entry.d_next = enc_dircookie(host_entry.d_seekoff);
entry.d_namlen = enc_u32(u32::from(host_entry.d_namlen));
entry.d_type = enc_filetype(host_entry.d_type);
Ok(entry)
}

Loading…
Cancel
Save