* wiggle-runtime: add as_raw method for [T]
* add trivial borrow checker back in
* integrate runtime borrow checker with as_raw methods
* handle pointer arith overflow correctly in as_raw, create PtrOverflow error
* runtime: add validation back to GuestType
* generate: impl validate for enums, flags, handles, ints
* oops! make validate its own method on trait GuestTypeTransparent
* fix transparent impls for enum, flag, handle, int
* some structs are transparent. fix tests.
* tests: define byte_slice_strat and friends
* wiggle-tests: i believe my allocator is working now
* some type juggling around memset for ease of use
* make GuestTypeTransparent an unsafe trait
* delete redundant validation of pointer align
* fix doc
* wiggle_test: aha, you cant use sets to track memory areas
* add multi-string test
which exercises the runtime borrow checker against
HostMemory::byte_slice_strat
* oops left debug panic in
* remove redundant (& incorrect, since unchecked) length calc
* redesign validate again, and actually hook to as_raw
* makr all validate impls as inline
this should hopefully allow as_raw's check loop to be unrolled to a
no-op in most cases!
* code review fixes
* Yanix now returns io::Error
This commit may seem somewhat controversial at first, but hear me
out first. Currently, Yanix would return a custom error that's a
wrapper around three other error types returned by various entities
inside Rust's `libstd`. In particular, Yanix's error type would wrap
`io::Error`, `num::TryFromIntError` and `ffi::NulError`. It turns
out that there is a natural conversion between the first and the last
and provided by the standard library, i.e., `From<ffi::NulError> for io::Error`
is provided. So at the surface it may seem that only the first two
wrapped error types are worth keeping.
Digging a little bit deeper into `libstd`, `num::TryFromIntError`
is essentially speaking only a marker that the integral conversion
went wrong. The struct implementing this error stores a unit type,
and nothing more. It therefore seems like a waste to wrap this
particular error when we could unify everything under `io::Error`.
And so, whenever we perform an int conversion, I suggest we simply
remap the error to `io::Error::from_raw_os_error(libc::EOVERFLOW)`
since this carries a comparable amount of information.
As a result of completely discarding `yanix::Error` custom error type,
we are invariably simplifying `yanix` itself, but also allowing
`wasi-common` to simplify in several places as well.
* Adapt wasi-common to changes in yanix
* Add Cargo.lock
* Unwrap try_into's where possible
* Remove unnecessary type annotation
* Fill out CI docs in the contributing section of the book
Figured it'd be good to document at least at a high level what in the
world is happening on all our PR runs.
* Tweak fuzz test comments
* Add support for virtual files (eg, not backed by an OS file).
Virtual files are implemented through trait objects, with a default
implementation that tries to behave like on-disk files, but entirely
backed by in-memory structures.
Co-authored-by: Dan Gohman <sunfish@mozilla.com>
The EVEX encoding format (e.g. in AVX-512) allows addressing 32 registers instead of 16. The FPR register class currently defines 16 registers, `%xmm0`-`%xmm15`; that class is kept as-is with this change. A larger class, FPR32, is added as a super-class of FPR using a larger bank of registers, `%xmm0`-`%xmm31`.
With this change, register banks can now be re-ordered and other components (e.g. unwinding, regalloc) will no longer break. The previous behavior assumed that GPR registers always started at `RegUnit` 0.
Update the documentation for the merger, and also for various changes in
Cranelift. Remove some old obsolete documentation, and convert the remaining
Sphinx files to Markdown. Some of the remaining content is still out of
date, but this is a step forward.
This commit expands the documentation of the `Func` type as well as
updating the Rust embedding tutorial with more recent APIs. I wanted to
also leave space in the Rust tutorial to get more ambitious over time
with what it's documenting, but I stopped around here, curious to see
what others think about it!
This is a rebase of [1]. In the long term, we'll want to simplify these
analysis passes. For now, this is simple and will reduce the number of
instructions processed in certain cases.
[1] https://github.com/bytecodealliance/cranelift/pull/866
* Reuse std::io::Error for raw *nix errno
This commit removes custom `yanix::Errno` and instead (as was
previously suggested) reuses `std::io::Error` to generate and wrap
raw *nix errno value.
* Update wasi-common to use new Yanix error type
This commit updates `wasi-common` to use new way of handling raw
OS error in `yanix`; i.e., via re-use of `std::io::Error` instead
of a custom `Errno` enum.
* Fix formatting
* Unwrap if io::Error created from raw OS error
This commit calls `unwrap` on `err` if that one was created via
`io::Error::last_os_error()`. It also refactors error matching
in several syscalls on the BSD platform (mainly).
This commit removes the two fuzz targets that we imported from cranelift
when cranelift merged in. These have both uncovered a few issues in the
fuzz targets themselves, for example:
* `translate_module` - this doesn't verify the wasm is valid a head of
time and cranelift is known to panic on translating invalid wasm
modules. We also already do a lot of fuzzing of translation of wasm
modules, so this isn't necessarily buying us anything over what we're
already fuzzing.
* `reader_parse_test` - discovered in #1205 we already found some "bugs"
in this but it may not necessarily rise to the level of "needs to be
run on oss-fuzz for us to find more bugs" yet. It looks like this is
still somewhat internal so we can re-enable when we've got folks to
fix the fuzz bugs coming in.
Closes#1205
This commit rewrites the runtime crate to provide safety in the face
of recursive calls to the guest. The basic principle is that
`GuestMemory` is now a trait which dynamically returns the
pointer/length pair. This also has an implicit contract (hence the
`unsafe` trait) that the pointer/length pair point to a valid list of
bytes in host memory "until something is reentrant".
After this changes the various suite of `Guest*` types were rewritten.
`GuestRef` and `GuestRefMut` were both removed since they cannot safely
exist. The `GuestPtrMut` type was removed for simplicity, and the final
`GuestPtr` type subsumes `GuestString` and `GuestArray`. This means
that there's only one guest pointer type, `GuestPtr<'a, T>`, where `'a`
is the borrow into host memory, basically borrowing the `GuestMemory`
trait object itself.
Some core utilities are exposed on `GuestPtr`, but they're all 100%
safe. Unsafety is now entirely contained within a few small locations:
* Implementations of the `GuestType` for primitive types (e.g. `i8`,
`u8`, etc) use `unsafe` to read/write memory. The `unsafe` trait of
`GuestMemory` though should prove that they're safe.
* `GuestPtr<'_, str>` has a method which validates utf-8 contents, and
this requires `unsafe` internally to read all the bytes. This is
guaranteed to be safe however given the contract of `GuestMemory`.
And that's it! Everything else is a bunch of safe combinators all built
up on the various utilities provided by `GuestPtr`. The general idioms
are roughly the same as before, with various tweaks here and there. A
summary of expected idioms are:
* For small values you'd `.read()` or `.write()` very quickly. You'd
pass around the type itself.
* For strings, you'd pass `GuestPtr<'_, str>` down to the point where
it's actually consumed. At that moment you'd either decide to copy it
out (a safe operation) or you'd get a raw view to the string (an
unsafe operation) and assert that you won't call back into wasm while
you're holding that pointer.
* Arrays are similar to strings, passing around `GuestPtr<'_, [T]>`.
Arrays also have a `iter()` method which yields an iterator of
`GuestPtr<'_, T>` for convenience.
Overall there's still a lot of missing documentation on the runtime
crate specifically around the safety of the `GuestMemory` trait as well
as how the utilities/methods are expected to be used. Additionally
there's utilities which aren't currently implemented which would be easy
to implement. For example there's no method to copy out a string or a
slice, although that would be pretty easy to add.
In any case I'm curious to get feedback on this approach and see what
y'all think!
This commit puts context object, i.e., the implementor of the
WASI snapshot, behind a reference `&self` rather than a mutable
reference `&mut self`. As suggested by @alexcrichton, this gives
the implementor the possibility to determine how it handles its
interior mutability.
The current interface of `cranelift-module` requires consumers who want
to be informed about traps to discover that information through
`Module::Product`, which is backend-specific. Since it's advantageous
to manipulate this information in a backend-agnostic way, this patch
changes `Module::define_function{,_bytes}` to return information about
the traps contained in the function being defined.
* Add a wasmtime-specific `wasmtime_wat2wasm` C API
This commit implements a wasmtime-specific C API for converting the text
format to the binary format. An upstream spec issue exists for adding
this to the C API, but in the meantime we can experiment with our own
version of this API and use it in the C# extension, for example!
Closes#1000
* Reorder arguments
* Use wasm_byte_vec_t for input `*.wat`
* Mark wat input as const
* Return an error message and use `fixed`
* Actually include the error message
* Use `fixed` in `Module.cs` as well
Currently, we create an immutable `GuestPtr` from `self` and call
`as_raw` on it which correctly returns `*const u8`. However, since
we're dealing with `GuestPtrMut` I thought it might make more sense
to return `*mut u8` directly instead. This will be needed (and will
save us from silly casts `*const _ as *mut _`) in plugging in
`Iovec<'_>` into `std::io::IoSliceMut` in `fd_read` and `fd_pread` calls.
* Add WASI spec (minus unions)
* Fill in all WASI shims
* Clean up derives and fix noncopy struct write method
This commit does three things:
* it uses the full, current snapshot1 WASI spec as a compilation test
* it fixes noncopy struct write method (which was incorrectly resolved
in certain cases to the inherent method of the `GuestPtrMut` rather
than the interface method `GuestType::write`
* it cleans up derives for structs and unions which should not auto-derive
`PartialEq`, `Eq`, or `Hash` since their members are not guaranteed to
be compatible