Merge branch 'pch/wiggle_flags_bitflags' into pch/wasi_common_cap_std

This commit is contained in:
Pat Hickey
2021-01-11 18:31:43 -08:00
42 changed files with 648 additions and 198 deletions

View File

@@ -81,6 +81,10 @@ macro_rules! declare_function_signatures {
AbiParam::new(I32).uext()
}
fn i64(&self) -> AbiParam {
AbiParam::new(I64)
}
$(
fn $name(&mut self, func: &mut Function) -> ir::SigRef {
let sig = self.$name.unwrap_or_else(|| {
@@ -258,6 +262,70 @@ impl<'module_environment> FuncEnvironment<'module_environment> {
}
}
fn get_memory_atomic_notify(
&mut self,
func: &mut Function,
memory_index: MemoryIndex,
) -> (ir::SigRef, usize, BuiltinFunctionIndex) {
if let Some(defined_memory_index) = self.module.defined_memory_index(memory_index) {
(
self.builtin_function_signatures.memory_atomic_notify(func),
defined_memory_index.index(),
BuiltinFunctionIndex::memory_atomic_notify(),
)
} else {
(
self.builtin_function_signatures
.imported_memory_atomic_notify(func),
memory_index.index(),
BuiltinFunctionIndex::imported_memory_atomic_notify(),
)
}
}
fn get_memory_atomic_wait(
&mut self,
func: &mut Function,
memory_index: MemoryIndex,
ty: ir::Type,
) -> (ir::SigRef, usize, BuiltinFunctionIndex) {
match ty {
I32 => {
if let Some(defined_memory_index) = self.module.defined_memory_index(memory_index) {
(
self.builtin_function_signatures.memory_atomic_wait32(func),
defined_memory_index.index(),
BuiltinFunctionIndex::memory_atomic_wait32(),
)
} else {
(
self.builtin_function_signatures
.imported_memory_atomic_wait32(func),
memory_index.index(),
BuiltinFunctionIndex::imported_memory_atomic_wait32(),
)
}
}
I64 => {
if let Some(defined_memory_index) = self.module.defined_memory_index(memory_index) {
(
self.builtin_function_signatures.memory_atomic_wait64(func),
defined_memory_index.index(),
BuiltinFunctionIndex::memory_atomic_wait64(),
)
} else {
(
self.builtin_function_signatures
.imported_memory_atomic_wait64(func),
memory_index.index(),
BuiltinFunctionIndex::imported_memory_atomic_wait64(),
)
}
}
x => panic!("get_memory_atomic_wait unsupported type: {:?}", x),
}
}
fn get_memory_init_func(&mut self, func: &mut Function) -> (ir::SigRef, BuiltinFunctionIndex) {
(
self.builtin_function_signatures.memory_init(func),
@@ -1368,29 +1436,50 @@ impl<'module_environment> cranelift_wasm::FuncEnvironment for FuncEnvironment<'m
fn translate_atomic_wait(
&mut self,
_pos: FuncCursor,
_index: MemoryIndex,
mut pos: FuncCursor,
memory_index: MemoryIndex,
_heap: ir::Heap,
_addr: ir::Value,
_expected: ir::Value,
_timeout: ir::Value,
addr: ir::Value,
expected: ir::Value,
timeout: ir::Value,
) -> WasmResult<ir::Value> {
Err(WasmError::Unsupported(
"wasm atomics (fn translate_atomic_wait)".to_string(),
))
let implied_ty = pos.func.dfg.value_type(expected);
let (func_sig, memory_index, func_idx) =
self.get_memory_atomic_wait(&mut pos.func, memory_index, implied_ty);
let memory_index_arg = pos.ins().iconst(I32, memory_index as i64);
let (vmctx, func_addr) = self.translate_load_builtin_function_address(&mut pos, func_idx);
let call_inst = pos.ins().call_indirect(
func_sig,
func_addr,
&[vmctx, memory_index_arg, addr, expected, timeout],
);
Ok(*pos.func.dfg.inst_results(call_inst).first().unwrap())
}
fn translate_atomic_notify(
&mut self,
_pos: FuncCursor,
_index: MemoryIndex,
mut pos: FuncCursor,
memory_index: MemoryIndex,
_heap: ir::Heap,
_addr: ir::Value,
_count: ir::Value,
addr: ir::Value,
count: ir::Value,
) -> WasmResult<ir::Value> {
Err(WasmError::Unsupported(
"wasm atomics (fn translate_atomic_notify)".to_string(),
))
let (func_sig, memory_index, func_idx) =
self.get_memory_atomic_notify(&mut pos.func, memory_index);
let memory_index_arg = pos.ins().iconst(I32, memory_index as i64);
let (vmctx, func_addr) = self.translate_load_builtin_function_address(&mut pos, func_idx);
let call_inst =
pos.ins()
.call_indirect(func_sig, func_addr, &[vmctx, memory_index_arg, addr, count]);
Ok(*pos.func.dfg.inst_results(call_inst).first().unwrap())
}
fn translate_loop_header(&mut self, mut pos: FuncCursor) -> WasmResult<()> {

View File

@@ -45,6 +45,18 @@ macro_rules! foreach_builtin_function {
externref_global_get(vmctx, i32) -> (reference);
/// Returns an index for Wasm's `global.get` instruction for `externref`s.
externref_global_set(vmctx, i32, reference) -> ();
/// Returns an index for wasm's `memory.atomic.notify` for locally defined memories.
memory_atomic_notify(vmctx, i32, i32, i32) -> (i32);
/// Returns an index for wasm's `memory.atomic.notify` for imported memories.
imported_memory_atomic_notify(vmctx, i32, i32, i32) -> (i32);
/// Returns an index for wasm's `memory.atomic.wait32` for locally defined memories.
memory_atomic_wait32(vmctx, i32, i32, i32, i64) -> (i32);
/// Returns an index for wasm's `memory.atomic.wait32` for imported memories.
imported_memory_atomic_wait32(vmctx, i32, i32, i32, i64) -> (i32);
/// Returns an index for wasm's `memory.atomic.wait64` for locally defined memories.
memory_atomic_wait64(vmctx, i32, i32, i64, i64) -> (i32);
/// Returns an index for wasm's `memory.atomic.wait64` for imported memories.
imported_memory_atomic_wait64(vmctx, i32, i32, i64, i64) -> (i32);
}
};
}

View File

@@ -21,7 +21,7 @@ iter-enum = "0.2"
itertools = "0.9.0"
memoffset = "0.6.0"
more-asserts = "0.2.1"
smallvec = "1.0.0"
smallvec = "1.6.1"
thiserror = "1.0.9"
typemap = "0.3"
wasmparser = "0.71"

View File

@@ -58,7 +58,7 @@
use crate::externref::VMExternRef;
use crate::table::Table;
use crate::traphandlers::raise_lib_trap;
use crate::traphandlers::{raise_lib_trap, Trap};
use crate::vmcontext::{VMCallerCheckedAnyfunc, VMContext};
use std::mem;
use std::ptr::{self, NonNull};
@@ -496,3 +496,88 @@ pub unsafe extern "C" fn wasmtime_externref_global_set(
let old = mem::replace((*global).as_externref_mut(), externref);
drop(old);
}
#[derive(Debug)]
struct Unimplemented(&'static str);
impl std::error::Error for Unimplemented {}
impl std::fmt::Display for Unimplemented {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::result::Result<(), std::fmt::Error> {
write!(f, "unimplemented: {}", self.0)
}
}
/// Implementation of `memory.atomic.notify` for locally defined memories.
pub unsafe extern "C" fn wasmtime_memory_atomic_notify(
_vmctx: *mut VMContext,
_memory_index: u32,
_addr: u32,
_count: u32,
) -> u32 {
raise_lib_trap(Trap::User(Box::new(Unimplemented(
"wasm atomics (fn wasmtime_memory_atomic_notify) unsupported",
))));
}
/// Implementation of `memory.atomic.notify` for imported memories.
pub unsafe extern "C" fn wasmtime_imported_memory_atomic_notify(
_vmctx: *mut VMContext,
_memory_index: u32,
_addr: u32,
_count: u32,
) -> u32 {
raise_lib_trap(Trap::User(Box::new(Unimplemented(
"wasm atomics (fn wasmtime_imported_memory_atomic_notify) unsupported",
))));
}
/// Implementation of `memory.atomic.wait32` for locally defined memories.
pub unsafe extern "C" fn wasmtime_memory_atomic_wait32(
_vmctx: *mut VMContext,
_memory_index: u32,
_addr: u32,
_expected: u32,
_timeout: u64,
) -> u32 {
raise_lib_trap(Trap::User(Box::new(Unimplemented(
"wasm atomics (fn wasmtime_memory_atomic_wait32) unsupported",
))));
}
/// Implementation of `memory.atomic.wait32` for imported memories.
pub unsafe extern "C" fn wasmtime_imported_memory_atomic_wait32(
_vmctx: *mut VMContext,
_memory_index: u32,
_addr: u32,
_expected: u32,
_timeout: u64,
) -> u32 {
raise_lib_trap(Trap::User(Box::new(Unimplemented(
"wasm atomics (fn wasmtime_imported_memory_atomic_wait32) unsupported",
))));
}
/// Implementation of `memory.atomic.wait64` for locally defined memories.
pub unsafe extern "C" fn wasmtime_memory_atomic_wait64(
_vmctx: *mut VMContext,
_memory_index: u32,
_addr: u32,
_expected: u64,
_timeout: u64,
) -> u32 {
raise_lib_trap(Trap::User(Box::new(Unimplemented(
"wasm atomics (fn wasmtime_memory_atomic_wait32) unsupported",
))));
}
/// Implementation of `memory.atomic.wait32` for imported memories.
pub unsafe extern "C" fn wasmtime_imported_memory_atomic_wait64(
_vmctx: *mut VMContext,
_memory_index: u32,
_addr: u32,
_expected: u64,
_timeout: u64,
) -> u32 {
raise_lib_trap(Trap::User(Box::new(Unimplemented(
"wasm atomics (fn wasmtime_imported_memory_atomic_wait64) unsupported",
))));
}

View File

@@ -600,6 +600,18 @@ impl VMBuiltinFunctionsArray {
wasmtime_table_fill as usize;
ptrs[BuiltinFunctionIndex::table_fill_funcref().index() as usize] =
wasmtime_table_fill as usize;
ptrs[BuiltinFunctionIndex::memory_atomic_notify().index() as usize] =
wasmtime_memory_atomic_notify as usize;
ptrs[BuiltinFunctionIndex::imported_memory_atomic_notify().index() as usize] =
wasmtime_imported_memory_atomic_notify as usize;
ptrs[BuiltinFunctionIndex::memory_atomic_wait32().index() as usize] =
wasmtime_memory_atomic_wait32 as usize;
ptrs[BuiltinFunctionIndex::imported_memory_atomic_wait32().index() as usize] =
wasmtime_imported_memory_atomic_wait32 as usize;
ptrs[BuiltinFunctionIndex::memory_atomic_wait64().index() as usize] =
wasmtime_memory_atomic_wait64 as usize;
ptrs[BuiltinFunctionIndex::imported_memory_atomic_wait64().index() as usize] =
wasmtime_imported_memory_atomic_wait64 as usize;
if cfg!(debug_assertions) {
for i in 0..ptrs.len() {

View File

@@ -78,7 +78,7 @@ impl Entry {
/// `HandleRights` structure is a subset of rights attached to this `Entry`. The check is
/// performed using `Entry::validate_rights` method. If the check fails, `Error::Notcapable`
/// is returned.
pub(crate) fn as_handle(&self, rights: &HandleRights) -> Result<EntryHandle> {
pub(crate) fn as_handle(&self, rights: HandleRights) -> Result<EntryHandle> {
self.validate_rights(rights)?;
Ok(self.handle.get())
}
@@ -87,7 +87,7 @@ impl Entry {
/// rights attached to this `Entry` object are a superset.
///
/// Upon unsuccessful check, `Error::Notcapable` is returned.
pub(crate) fn validate_rights(&self, rights: &HandleRights) -> Result<()> {
pub(crate) fn validate_rights(&self, rights: HandleRights) -> Result<()> {
let this_rights = self.handle.get_rights();
if this_rights.contains(rights) {
Ok(())

View File

@@ -39,8 +39,8 @@ impl HandleRights {
}
/// Checks if `other` is a subset of those rights.
pub fn contains(&self, other: &Self) -> bool {
self.base.contains(&other.base) && self.inheriting.contains(&other.inheriting)
pub fn contains(&self, other: Self) -> bool {
self.base.contains(other.base) && self.inheriting.contains(other.inheriting)
}
/// Returns base rights.
@@ -100,7 +100,7 @@ pub trait Handle {
let file_type = self.get_file_type();
let rights = self.get_rights();
let required_rights = HandleRights::from_base(Rights::FD_SEEK | Rights::FD_TELL);
file_type == Filetype::CharacterDevice && rights.contains(&required_rights)
file_type == Filetype::CharacterDevice && rights.contains(required_rights)
}
// TODO perhaps should be a separate trait?
// FdOps

View File

@@ -11,7 +11,7 @@ pub(crate) use crate::sys::path::{from_host, open_rights};
/// This is a workaround for not having Capsicum support in the OS.
pub(crate) fn get(
entry: &Entry,
required_rights: &HandleRights,
required_rights: HandleRights,
dirflags: Lookupflags,
path: &str,
needs_final_component: bool,
@@ -140,7 +140,7 @@ pub(crate) fn get(
}
continue;
} else if ends_with_slash || dirflags.contains(&Lookupflags::SYMLINK_FOLLOW)
} else if ends_with_slash || dirflags.contains(Lookupflags::SYMLINK_FOLLOW)
{
// if there's a trailing slash, or if `LOOKUP_SYMLINK_FOLLOW` is set, attempt
// symlink expansion

View File

@@ -60,7 +60,7 @@ impl<'a> WasiSnapshotPreview1 for WasiCtx {
let required_rights = HandleRights::from_base(types::Rights::FD_ADVISE);
let entry = self.get_entry(fd)?;
entry
.as_handle(&required_rights)?
.as_handle(required_rights)?
.advise(advice, offset, len)
}
@@ -72,7 +72,7 @@ impl<'a> WasiSnapshotPreview1 for WasiCtx {
) -> Result<()> {
let required_rights = HandleRights::from_base(types::Rights::FD_ALLOCATE);
let entry = self.get_entry(fd)?;
entry.as_handle(&required_rights)?.allocate(offset, len)
entry.as_handle(required_rights)?.allocate(offset, len)
}
fn fd_close(&self, fd: types::Fd) -> Result<()> {
@@ -89,12 +89,12 @@ impl<'a> WasiSnapshotPreview1 for WasiCtx {
fn fd_datasync(&self, fd: types::Fd) -> Result<()> {
let required_rights = HandleRights::from_base(types::Rights::FD_DATASYNC);
let entry = self.get_entry(fd)?;
entry.as_handle(&required_rights)?.datasync()
entry.as_handle(required_rights)?.datasync()
}
fn fd_fdstat_get(&self, fd: types::Fd) -> Result<types::Fdstat> {
let entry = self.get_entry(fd)?;
let file = entry.as_handle(&HandleRights::empty())?;
let file = entry.as_handle(HandleRights::empty())?;
let fs_flags = file.fdstat_get()?;
let rights = entry.get_rights();
let fdstat = types::Fdstat {
@@ -109,7 +109,7 @@ impl<'a> WasiSnapshotPreview1 for WasiCtx {
fn fd_fdstat_set_flags(&self, fd: types::Fd, flags: types::Fdflags) -> Result<()> {
let required_rights = HandleRights::from_base(types::Rights::FD_FDSTAT_SET_FLAGS);
let entry = self.get_entry(fd)?;
entry.as_handle(&required_rights)?.fdstat_set_flags(flags)
entry.as_handle(required_rights)?.fdstat_set_flags(flags)
}
fn fd_fdstat_set_rights(
@@ -120,7 +120,7 @@ impl<'a> WasiSnapshotPreview1 for WasiCtx {
) -> Result<()> {
let rights = HandleRights::new(fs_rights_base, fs_rights_inheriting);
let entry = self.get_entry(fd)?;
if !entry.get_rights().contains(&rights) {
if !entry.get_rights().contains(rights) {
return Err(Error::Notcapable);
}
entry.set_rights(rights);
@@ -130,14 +130,14 @@ impl<'a> WasiSnapshotPreview1 for WasiCtx {
fn fd_filestat_get(&self, fd: types::Fd) -> Result<types::Filestat> {
let required_rights = HandleRights::from_base(types::Rights::FD_FILESTAT_GET);
let entry = self.get_entry(fd)?;
let host_filestat = entry.as_handle(&required_rights)?.filestat_get()?;
let host_filestat = entry.as_handle(required_rights)?.filestat_get()?;
Ok(host_filestat)
}
fn fd_filestat_set_size(&self, fd: types::Fd, size: types::Filesize) -> Result<()> {
let required_rights = HandleRights::from_base(types::Rights::FD_FILESTAT_SET_SIZE);
let entry = self.get_entry(fd)?;
entry.as_handle(&required_rights)?.filestat_set_size(size)
entry.as_handle(required_rights)?.filestat_set_size(size)
}
fn fd_filestat_set_times(
@@ -150,7 +150,7 @@ impl<'a> WasiSnapshotPreview1 for WasiCtx {
let required_rights = HandleRights::from_base(types::Rights::FD_FILESTAT_SET_TIMES);
let entry = self.get_entry(fd)?;
entry
.as_handle(&required_rights)?
.as_handle(required_rights)?
.filestat_set_times(atim, mtim, fst_flags)
}
@@ -180,7 +180,7 @@ impl<'a> WasiSnapshotPreview1 for WasiCtx {
.map(|s| io::IoSliceMut::new(&mut *s))
.collect::<Vec<io::IoSliceMut<'_>>>();
entry
.as_handle(&required_rights)?
.as_handle(required_rights)?
.preadv(&mut buf, offset)?
.try_into()?
};
@@ -255,7 +255,7 @@ impl<'a> WasiSnapshotPreview1 for WasiCtx {
let buf: Vec<io::IoSlice> =
guest_slices.iter().map(|s| io::IoSlice::new(&*s)).collect();
entry
.as_handle(&required_rights)?
.as_handle(required_rights)?
.pwritev(&buf, offset)?
.try_into()?
};
@@ -278,7 +278,7 @@ impl<'a> WasiSnapshotPreview1 for WasiCtx {
.map(|s| io::IoSliceMut::new(&mut *s))
.collect();
entry
.as_handle(&required_rights)?
.as_handle(required_rights)?
.read_vectored(&mut slices)?
.try_into()?
};
@@ -298,7 +298,7 @@ impl<'a> WasiSnapshotPreview1 for WasiCtx {
let mut bufused = 0;
let mut buf = buf.clone();
for pair in entry.as_handle(&required_rights)?.readdir(cookie)? {
for pair in entry.as_handle(required_rights)?.readdir(cookie)? {
let (dirent, name) = pair?;
let dirent_raw = dirent.as_bytes()?;
let dirent_len: types::Size = dirent_raw.len().try_into()?;
@@ -379,21 +379,21 @@ impl<'a> WasiSnapshotPreview1 for WasiCtx {
types::Whence::End => SeekFrom::End(offset),
types::Whence::Set => SeekFrom::Start(offset as u64),
};
let host_newoffset = entry.as_handle(&required_rights)?.seek(pos)?;
let host_newoffset = entry.as_handle(required_rights)?.seek(pos)?;
Ok(host_newoffset)
}
fn fd_sync(&self, fd: types::Fd) -> Result<()> {
let required_rights = HandleRights::from_base(types::Rights::FD_SYNC);
let entry = self.get_entry(fd)?;
entry.as_handle(&required_rights)?.sync()
entry.as_handle(required_rights)?.sync()
}
fn fd_tell(&self, fd: types::Fd) -> Result<types::Filesize> {
let required_rights = HandleRights::from_base(types::Rights::FD_TELL);
let entry = self.get_entry(fd)?;
let host_offset = entry
.as_handle(&required_rights)?
.as_handle(required_rights)?
.seek(SeekFrom::Current(0))?;
Ok(host_offset)
}
@@ -411,7 +411,7 @@ impl<'a> WasiSnapshotPreview1 for WasiCtx {
let slices: Vec<io::IoSlice> =
guest_slices.iter().map(|s| io::IoSlice::new(&*s)).collect();
entry
.as_handle(&required_rights)?
.as_handle(required_rights)?
.write_vectored(&slices)?
.try_into()?
};
@@ -426,7 +426,7 @@ impl<'a> WasiSnapshotPreview1 for WasiCtx {
let path = path.as_str()?;
let (dirfd, path) = path::get(
&entry,
&required_rights,
required_rights,
types::Lookupflags::empty(),
path.deref(),
false,
@@ -443,9 +443,9 @@ impl<'a> WasiSnapshotPreview1 for WasiCtx {
let required_rights = HandleRights::from_base(types::Rights::PATH_FILESTAT_GET);
let entry = self.get_entry(dirfd)?;
let path = path.as_str()?;
let (dirfd, path) = path::get(&entry, &required_rights, flags, path.deref(), false)?;
let (dirfd, path) = path::get(&entry, required_rights, flags, path.deref(), false)?;
let host_filestat =
dirfd.filestat_get_at(&path, flags.contains(&types::Lookupflags::SYMLINK_FOLLOW))?;
dirfd.filestat_get_at(&path, flags.contains(types::Lookupflags::SYMLINK_FOLLOW))?;
Ok(host_filestat)
}
@@ -461,13 +461,13 @@ impl<'a> WasiSnapshotPreview1 for WasiCtx {
let required_rights = HandleRights::from_base(types::Rights::PATH_FILESTAT_SET_TIMES);
let entry = self.get_entry(dirfd)?;
let path = path.as_str()?;
let (dirfd, path) = path::get(&entry, &required_rights, flags, path.deref(), false)?;
let (dirfd, path) = path::get(&entry, required_rights, flags, path.deref(), false)?;
dirfd.filestat_set_times_at(
&path,
atim,
mtim,
fst_flags,
flags.contains(&types::Lookupflags::SYMLINK_FOLLOW),
flags.contains(types::Lookupflags::SYMLINK_FOLLOW),
)?;
Ok(())
}
@@ -487,7 +487,7 @@ impl<'a> WasiSnapshotPreview1 for WasiCtx {
let old_path = old_path.as_str()?;
path::get(
&old_entry,
&required_rights,
required_rights,
types::Lookupflags::empty(),
old_path.deref(),
false,
@@ -500,7 +500,7 @@ impl<'a> WasiSnapshotPreview1 for WasiCtx {
let new_path = new_path.as_str()?;
path::get(
&new_entry,
&required_rights,
required_rights,
types::Lookupflags::empty(),
new_path.deref(),
false,
@@ -510,7 +510,7 @@ impl<'a> WasiSnapshotPreview1 for WasiCtx {
&old_path,
new_dirfd,
&new_path,
old_flags.contains(&types::Lookupflags::SYMLINK_FOLLOW),
old_flags.contains(types::Lookupflags::SYMLINK_FOLLOW),
)
}
@@ -535,7 +535,7 @@ impl<'a> WasiSnapshotPreview1 for WasiCtx {
let path = path.as_str()?;
path::get(
&entry,
&needed_rights,
needed_rights,
dirflags,
path.deref(),
oflags & types::Oflags::CREAT != types::Oflags::empty(),
@@ -581,7 +581,7 @@ impl<'a> WasiSnapshotPreview1 for WasiCtx {
let path = path.as_str()?;
path::get(
&entry,
&required_rights,
required_rights,
types::Lookupflags::empty(),
path.deref(),
false,
@@ -599,7 +599,7 @@ impl<'a> WasiSnapshotPreview1 for WasiCtx {
let path = path.as_str()?;
path::get(
&entry,
&required_rights,
required_rights,
types::Lookupflags::empty(),
path.deref(),
true,
@@ -621,7 +621,7 @@ impl<'a> WasiSnapshotPreview1 for WasiCtx {
let old_path = old_path.as_str()?;
path::get(
&entry,
&required_rights,
required_rights,
types::Lookupflags::empty(),
old_path.deref(),
true,
@@ -633,7 +633,7 @@ impl<'a> WasiSnapshotPreview1 for WasiCtx {
let new_path = new_path.as_str()?;
path::get(
&entry,
&required_rights,
required_rights,
types::Lookupflags::empty(),
new_path.deref(),
true,
@@ -654,7 +654,7 @@ impl<'a> WasiSnapshotPreview1 for WasiCtx {
let new_path = new_path.as_str()?;
path::get(
&entry,
&required_rights,
required_rights,
types::Lookupflags::empty(),
new_path.deref(),
true,
@@ -672,7 +672,7 @@ impl<'a> WasiSnapshotPreview1 for WasiCtx {
let path = path.as_str()?;
path::get(
&entry,
&required_rights,
required_rights,
types::Lookupflags::empty(),
path.deref(),
false,
@@ -815,7 +815,7 @@ impl WasiCtx {
}
};
fd_events.push(sched::FdEventData {
handle: entry.as_handle(&required_rights)?,
handle: entry.as_handle(required_rights)?,
r#type: types::Eventtype::FdRead,
userdata: subscription.userdata,
});
@@ -841,7 +841,7 @@ impl WasiCtx {
}
};
fd_events.push(sched::FdEventData {
handle: entry.as_handle(&required_rights)?,
handle: entry.as_handle(required_rights)?,
r#type: types::Eventtype::FdWrite,
userdata: subscription.userdata,
});

View File

@@ -12,10 +12,10 @@ pub(crate) fn filestat_set_times(
st_mtim: Timestamp,
fst_flags: Fstflags,
) -> Result<()> {
let set_atim = fst_flags.contains(&Fstflags::ATIM);
let set_atim_now = fst_flags.contains(&Fstflags::ATIM_NOW);
let set_mtim = fst_flags.contains(&Fstflags::MTIM);
let set_mtim_now = fst_flags.contains(&Fstflags::MTIM_NOW);
let set_atim = fst_flags.contains(Fstflags::ATIM);
let set_atim_now = fst_flags.contains(Fstflags::ATIM_NOW);
let set_mtim = fst_flags.contains(Fstflags::MTIM);
let set_mtim_now = fst_flags.contains(Fstflags::MTIM_NOW);
if (set_atim && set_atim_now) || (set_mtim && set_mtim_now) {
return Err(Error::Inval);

View File

@@ -147,19 +147,19 @@ impl From<Clockid> for ClockId {
impl From<Fdflags> for OFlags {
fn from(fdflags: Fdflags) -> Self {
let mut nix_flags = Self::empty();
if fdflags.contains(&Fdflags::APPEND) {
if fdflags.contains(Fdflags::APPEND) {
nix_flags.insert(Self::APPEND);
}
if fdflags.contains(&Fdflags::DSYNC) {
if fdflags.contains(Fdflags::DSYNC) {
nix_flags.insert(Self::DSYNC);
}
if fdflags.contains(&Fdflags::NONBLOCK) {
if fdflags.contains(Fdflags::NONBLOCK) {
nix_flags.insert(Self::NONBLOCK);
}
if fdflags.contains(&Fdflags::RSYNC) {
if fdflags.contains(Fdflags::RSYNC) {
nix_flags.insert(O_RSYNC);
}
if fdflags.contains(&Fdflags::SYNC) {
if fdflags.contains(Fdflags::SYNC) {
nix_flags.insert(Self::SYNC);
}
nix_flags
@@ -191,16 +191,16 @@ impl From<OFlags> for Fdflags {
impl From<Oflags> for OFlags {
fn from(oflags: Oflags) -> Self {
let mut nix_flags = Self::empty();
if oflags.contains(&Oflags::CREAT) {
if oflags.contains(Oflags::CREAT) {
nix_flags.insert(Self::CREAT);
}
if oflags.contains(&Oflags::DIRECTORY) {
if oflags.contains(Oflags::DIRECTORY) {
nix_flags.insert(Self::DIRECTORY);
}
if oflags.contains(&Oflags::EXCL) {
if oflags.contains(Oflags::EXCL) {
nix_flags.insert(Self::EXCL);
}
if oflags.contains(&Oflags::TRUNC) {
if oflags.contains(Oflags::TRUNC) {
nix_flags.insert(Self::TRUNC);
}
nix_flags

View File

@@ -239,10 +239,10 @@ pub(crate) fn filestat_set_times_at(
use std::time::{Duration, UNIX_EPOCH};
use yanix::filetime::*;
let set_atim = fst_flags.contains(&Fstflags::ATIM);
let set_atim_now = fst_flags.contains(&Fstflags::ATIM_NOW);
let set_mtim = fst_flags.contains(&Fstflags::MTIM);
let set_mtim_now = fst_flags.contains(&Fstflags::MTIM_NOW);
let set_atim = fst_flags.contains(Fstflags::ATIM);
let set_atim_now = fst_flags.contains(Fstflags::ATIM_NOW);
let set_mtim = fst_flags.contains(Fstflags::MTIM);
let set_mtim_now = fst_flags.contains(Fstflags::MTIM_NOW);
if (set_atim && set_atim_now) || (set_mtim && set_mtim_now) {
return Err(Error::Inval);

View File

@@ -299,7 +299,7 @@ impl Handle for InMemoryFile {
trace!("write_vectored(iovs={:?})", iovs);
let mut data = self.data.borrow_mut();
let append_mode = self.fd_flags.get().contains(&Fdflags::APPEND);
let append_mode = self.fd_flags.get().contains(Fdflags::APPEND);
trace!(" | fd_flags={}", self.fd_flags.get());
// If this file is in append mode, we write to the end.
@@ -353,7 +353,7 @@ impl Handle for InMemoryFile {
oflags: Oflags,
_fd_flags: Fdflags,
) -> Result<Box<dyn Handle>> {
if oflags.contains(&Oflags::DIRECTORY) {
if oflags.contains(Oflags::DIRECTORY) {
tracing::trace!(
"InMemoryFile::openat was passed oflags DIRECTORY, but {:?} is a file.",
path
@@ -652,7 +652,7 @@ impl Handle for VirtualDir {
return Err(Error::Exist);
}
if oflags.contains(&Oflags::DIRECTORY)
if oflags.contains(Oflags::DIRECTORY)
&& e.get().get_file_type() != Filetype::Directory
{
tracing::trace!(
@@ -665,7 +665,7 @@ impl Handle for VirtualDir {
e.get().try_clone().map_err(Into::into)
}
Entry::Vacant(v) => {
if oflags.contains(&Oflags::CREAT) {
if oflags.contains(Oflags::CREAT) {
if self.writable {
// Enforce a hard limit at `u32::MAX - 2` files.
// This is to have a constant limit (rather than target-dependent limit we

View File

@@ -6,7 +6,7 @@ description = "Wasmtime implementation of the wasi-nn API"
documentation = "https://docs.rs/wasmtime-wasi-nn"
license = "Apache-2.0 WITH LLVM-exception"
categories = ["wasm", "computer-vision"]
keywords = ["webassembly", "wasm", "neural network"]
keywords = ["webassembly", "wasm", "neural-network"]
repository = "https://github.com/bytecodealliance/wasmtime"
readme = "README.md"
edition = "2018"

View File

@@ -26,7 +26,7 @@ rustc-demangle = "0.1.16"
cpp_demangle = "0.3.2"
log = "0.4.8"
wat = { version = "1.0.18", optional = true }
smallvec = "1.4.0"
smallvec = "1.6.1"
serde = { version = "1.0.94", features = ["derive"] }
bincode = "1.2.1"
indexmap = "1.6"

View File

@@ -15,6 +15,7 @@ thiserror = "1"
witx = { path = "../wasi-common/WASI/tools/witx", version = "0.8.7", optional = true }
wiggle-macro = { path = "macro", version = "0.22.0" }
tracing = "0.1.15"
bitflags = "1.2"
[badges]
maintenance = { status = "actively-developed" }

View File

@@ -169,7 +169,7 @@ pub fn define_func(
let func_name = &func.name.as_str();
if func.noreturn {
quote!(pub fn #ident(#abi_args) -> Result<#abi_ret, wiggle::Trap> {
quote!(pub fn #ident(#abi_args) -> Result<#abi_ret, #rt::Trap> {
let _span = #rt::tracing::span!(
#rt::tracing::Level::TRACE,
"wiggle abi",
@@ -184,7 +184,7 @@ pub fn define_func(
Err(trap)
})
} else {
quote!(pub fn #ident(#abi_args) -> Result<#abi_ret, wiggle::Trap> {
quote!(pub fn #ident(#abi_args) -> Result<#abi_ret, #rt::Trap> {
let _span = #rt::tracing::span!(
#rt::tracing::Level::TRACE,
"wiggle abi",

View File

@@ -40,7 +40,7 @@ pub fn generate(doc: &witx::Document, names: &Names, errs: &ErrorTransform) -> T
let abi_typename = names.type_ref(&errtype.abi_type(), anon_lifetime());
let user_typename = errtype.typename();
let methodname = names.user_error_conversion_method(&errtype);
quote!(fn #methodname(&self, e: super::#user_typename) -> Result<#abi_typename, wiggle::Trap>;)
quote!(fn #methodname(&self, e: super::#user_typename) -> Result<#abi_typename, #rt::Trap>;)
});
let user_error_conversion = quote! {
pub trait UserErrorConversion {

View File

@@ -69,7 +69,8 @@ pub fn define_module_trait(names: &Names, m: &Module, errxform: &ErrorTransform)
.unwrap_or(quote!(()));
quote!( Result<(#(#rets),*), #err> )
} else {
quote!(wiggle::Trap)
let rt = names.runtime_mod();
quote!(#rt::Trap)
};
if is_anonymous {

View File

@@ -27,102 +27,31 @@ pub(super) fn define_flags(names: &Names, name: &witx::Id, f: &witx::FlagsDataty
}
quote! {
#[repr(transparent)]
#[derive(Copy, Clone, Debug, ::std::hash::Hash, Eq, PartialEq)]
pub struct #ident(#repr);
impl #ident {
#(pub const #names_: #ident = #ident(#values_);)*
#[inline]
pub const fn empty() -> Self {
#ident(0)
}
#[inline]
pub const fn all() -> Self {
#ident(#(#values_)|*)
}
#[inline]
pub fn contains(&self, other: &#ident) -> bool {
!*self & *other == Self::empty()
#rt::bitflags::bitflags! {
pub struct #ident: #repr {
#(const #names_ = #values_;)*
}
}
impl ::std::fmt::Display for #ident {
fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
let mut first = true;
#(
if self.0 & #values_ == #values_ {
if !first {
f.write_str("|")?;
}
first = false;
f.write_fmt(format_args!("{}", stringify!(#names_).to_lowercase()))?;
}
)*
if first {
f.write_str("empty")?;
}
f.write_fmt(format_args!(" ({:#x})", self.0))?;
f.write_str(stringify!(#ident))?;
f.write_str("(")?;
::std::fmt::Debug::fmt(self, f)?;
f.write_str(" (0x")?;
::std::fmt::LowerHex::fmt(&self.bits, f)?;
f.write_str("))")?;
Ok(())
}
}
impl ::std::ops::BitAnd for #ident {
type Output = Self;
fn bitand(self, rhs: Self) -> Self::Output {
#ident(self.0 & rhs.0)
}
}
impl ::std::ops::BitAndAssign for #ident {
fn bitand_assign(&mut self, rhs: Self) {
*self = *self & rhs
}
}
impl ::std::ops::BitOr for #ident {
type Output = Self;
fn bitor(self, rhs: Self) -> Self::Output {
#ident(self.0 | rhs.0)
}
}
impl ::std::ops::BitOrAssign for #ident {
fn bitor_assign(&mut self, rhs: Self) {
*self = *self | rhs
}
}
impl ::std::ops::BitXor for #ident {
type Output = Self;
fn bitxor(self, rhs: Self) -> Self::Output {
#ident(self.0 ^ rhs.0)
}
}
impl ::std::ops::BitXorAssign for #ident {
fn bitxor_assign(&mut self, rhs: Self) {
*self = *self ^ rhs
}
}
impl ::std::ops::Not for #ident {
type Output = Self;
fn not(self) -> Self::Output {
#ident(!self.0)
}
}
impl ::std::convert::TryFrom<#repr> for #ident {
type Error = #rt::GuestError;
fn try_from(value: #repr) -> Result<Self, #rt::GuestError> {
if #repr::from(!#ident::all()) & value != 0 {
Err(#rt::GuestError::InvalidFlagValue(stringify!(#ident)))
} else {
Ok(#ident(value))
Ok(#ident { bits: value })
}
}
}
@@ -136,7 +65,7 @@ pub(super) fn define_flags(names: &Names, name: &witx::Id, f: &witx::FlagsDataty
impl From<#ident> for #repr {
fn from(e: #ident) -> #repr {
e.0
e.bits
}
}

View File

@@ -6,6 +6,7 @@ use std::slice;
use std::str;
use std::sync::Arc;
pub use bitflags;
pub use wiggle_macro::from_witx;
#[cfg(feature = "wiggle_metadata")]

View File

@@ -103,11 +103,11 @@ proptest! {
#[test]
fn flags_fmt() {
let empty = format!("{}", types::CarConfig::empty());
assert_eq!(empty, "empty (0x0)");
assert_eq!(empty, "CarConfig((empty) (0x0))");
let one_flag = format!("{}", types::CarConfig::AWD);
assert_eq!(one_flag, "awd (0x2)");
assert_eq!(one_flag, "CarConfig(AWD (0x2))");
let two_flags = format!("{}", types::CarConfig::AUTOMATIC | types::CarConfig::SUV);
assert_eq!(two_flags, "automatic|suv (0x5)");
assert_eq!(two_flags, "CarConfig(AUTOMATIC | SUV (0x5))");
let all = format!("{}", types::CarConfig::all());
assert_eq!(all, "automatic|awd|suv (0x7)");
assert_eq!(all, "CarConfig(AUTOMATIC | AWD | SUV (0x7))");
}