* Add armv7 support to wasi-common
This commit enables `target_pointer_width = 32` compatibility for
`wasi-common` (and by transitivity, any crate found inside, e.g., `yanix`).
I've also added a simplistic (bare minimum) check to our CI to ensure
that `wasi-common` cross-compiles to `armv7-unknown-gnueabihf` fine.
While here, I've done the same for `wasm32-unknown-emscripten`.
* Clean arch-specific impls + reuse libc consts
* Make SeekLoc::from_raw platform independent
* Collapse CI cc jobs into one
To avoid libfuzzer timeouts, limit the total number of API calls we generate in
the `api_calls` fuzz target. We were already limiting the number of exported
function calls we made, and this extends the limit to all API calls.
* Enable the already-passing `bulk-memoryoperations/imports.wast` test
* Implement support for the `memory.init` instruction and passive data
This adds support for passive data segments and the `memory.init` instruction
from the bulk memory operations proposal. Passive data segments are stored on
the Wasm module and then `memory.init` instructions copy their contents into
memory.
* Implement the `data.drop` instruction
This allows wasm modules to deallocate passive data segments that it doesn't
need anymore. We keep track of which segments have not been dropped on an
`Instance` and when dropping them, remove the entry from the instance's hash
map. The module always needs all of the segments for new instantiations.
* Enable final bulk memory operations spec test
This requires special casing an expected error message for an `assert_trap`,
since the expected error message contains the index of an uninitialized table
element, but our trap implementation doesn't save that diagnostic information
and shepherd it out.
* Disallow values to cross stores
Lots of internals in the wasmtime-{jit,runtime} crates are highly
unsafe, so it's up to the `wasmtime` API crate to figure out how to make
it safe. One guarantee we need to provide is that values never cross
between stores. For example you can't take a function in one store and
move it over into a different instance in a different store. This
dynamic check can't be performed at compile time and it's up to
`wasmtime` to do the check itself.
This adds a number of checks, but not all of them, to the codebase for
now. This primarily adds checks around instantiation, globals, and
tables. The main hole in this is functions, where you can pass in
arguments or return values that are not from the right store. For now
though we can't compile modules with `anyref` parameters/returns anyway,
so we should be good. Eventually when that is supported we'll need to
put the guards in place.
Closes#958
* Clarify how values test they come from stores
* Allow null anyref to initialize tables
* Introduce WasiCtxBuilderError error type
`WasiCtxBuilderError` is the `wasi-common` client-facing error type
which is exclusively thrown when building a new `WasiCtx` instance.
As such, building such an instance should not require the client to
understand different WASI errno values as was assumed until now.
This commit is a first step at streamlining error handling in
`wasi-common` and makes way for the `wiggle` crate.
When adding the `WasiCtxBuilderError`, I've had to do two things of
notable importance:
1. I've removed a couple of `ok_or` calls in `WasiCtxBuilder::build`
and replaced them with `unwrap`s, following the same pattern in
different builder methods above. This is fine since we _always_
operate on non-empty `Option`s in `WasiCtxBuilder` thus `unwrap`ing
will never fail. On the other hand, this might be a good opportunity
to rethink the structure of our builder, and how we good remove
the said `Option`s especially since we always populate them with
empty containers to begin with. I understand this is to make
chaining of builder methods easier which take and return `&mut self`
and the same applies to `WasiCtxBuilder::build(&mut self)` method,
but perhaps it would more cleanly signal the intentions if we simply
moved `WasiCtxBuilder` instance around. Food for thought!
2. Methods specific to determining rights of passed around `std::fs::File`
objects when populating `WasiCtx` `FdEntry` entities now return
`io::Error` directly so that we can reuse them in `WasiCtxBuilder` methods
(returning `WasiCtxBuilderError` error type), and in syscalls
(returning WASI errno).
* Return WasiError directly in syscalls
Also, removes `error::Error` type altogether. Now, `io::Error` and
related are automatically converted to their corresponding WASI
errno value encapsulated as `WasiError`.
While here, it made sense to me to move `WasiError` to `wasi` module
which will align itself well with the upcoming changes introduced
by `wiggle`. To different standard `Result` from WASI specific, I've
created a helper alias `WasiResult` also residing in `wasi` module.
* Update wig
* Add from ffi::NulError and pass context to NotADirectory
* Add dummy commit to test CI
* Move filetime module to yanix
I've noticed that we could replace every occurrence of `crate::Result`
in `filetime` mods with `io::Result`, so I thought why not move it
to `yanix` and get rid off a lot of unnecessary code duplication
within `wasi-common`. Now, ideally I'd have our `filetime` modifications
backported to Alex's [`filetime`] crate, but one step at a time
(apologies Alex, I was meant to backport this ages ago, just didn't
find the time yet... :-().
Anyway, this commit does just that; i.e., moves the `filetime` modules
into `yanix` which seems a better fit for this type of code.
[`filetime`]: https://github.com/alexcrichton/filetime
There is one caveat here. On Emscripten, converting between `filetime::Filetime`
and `libc::timespec` appears to be lossy, at least as far as the
types are concerned. Now, `filetime::Filetime`'s seconds field is
`i64` while nanoseconds field is `u32`, while Emscripten's
`libc::timespec` requires both to be `i32` width. This might actually
not be a problem since I don't think it's possible to fill `filetime::Filetime`
struct with values of width wider than `i32` since Emscripten is 32bit
but just to be on the safe side, we do a `TryInto` conversion, log
the error (if any), and return `libc::EOVERFLOW`.
* Run cargo fmt
* Use i64::from instead of as cast
* Winx now returns io::Error
This commit is a spiritual follower of #1242 in the sense that it
adjusts `winx` to also return `io::Error` directly rather than
tossing a custom error type here and there.
* Adapt wasi-common to changes in winx
* Run cargo fmt
* Swap overly big map_err with explicit match
* 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
* 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>
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!
* 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).
* 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
* rename PassiveElemIndex to ElemIndex and same for PassiveDataIndex (#1411)
* rename PassiveDataIndex to DataIndex
* rename PassiveElemIndex to ElemIndex
* Apply renamings to wasmtime as well
* Run rustfmt
Co-authored-by: csmoe <csmoe@msn.com>
Jitdump was using an api consisent v0.04 for target_lexicon instead
of the version v0.10. This updates calls to target_lexicon to be
consistent with v0.10.
This commit changes the C API function `wasm_module_new` to use the Rust API
`Module::from_binary` which performs verification of the module, as per the C
API spec.
This also introduces a `EngineBuilder` type to the C# API that can be used to
construct an `Engine` with the various Wasmtime configuration options. This
is required to get the C# tests passing since they use reference types and
multi-value.
Fixes#859.
* Add a version to a path dependeency for publishing on crates.io.
* Add a README.md for wasmtime-profiling.
* Add versions to the wasmtime-profiling dependencies.
Essentially, table and memory out of bounds errors are no longer link errors,
but traps after linking. This means that the partail writes / inits are visible.
This adds support for the `table.copy` instruction from the bulk memory
proposal. It also supports multiple tables, which were introduced by the
reference types proposal.
Part of #928
* Improve robustness of cache loading/storing
Today wasmtime incorrectly loads compiled compiled modules from the
global cache when toggling settings such as optimizations. For example
if you execute `wasmtime foo.wasm` that will cache globally an
unoptimized version of the wasm module. If you then execute `wasmtime -O
foo.wasm` it would then reload the unoptimized version from cache, not
realizing the compilation settings were different, and use that instead.
This can lead to very surprising behavior naturally!
This commit updates how the cache is managed in an attempt to make it
much more robust against these sorts of issues. This takes a leaf out of
rustc's playbook and models the cache with a function that looks like:
fn load<T: Hash>(
&self,
data: T,
compute: fn(T) -> CacheEntry,
) -> CacheEntry;
The goal here is that it guarantees that all the `data` necessary to
`compute` the result of the cache entry is hashable and stored into the
hash key entry. This was previously open-coded and manually managed
where items were hashed explicitly, but this construction guarantees
that everything reasonable `compute` could use to compile the module is
stored in `data`, which is itself hashable.
This refactoring then resulted in a few workarounds and a few fixes,
including the original issue:
* The `Module` type was split into `Module` and `ModuleLocal` where only
the latter is hashed. The previous hash function for a `Module` left
out items like the `start_func` and didn't hash items like the imports
of the module. Omitting the `start_func` was fine since compilation
didn't actually use it, but omitting imports seemed uncomfortable
because while compilation didn't use the import values it did use the
*number* of imports, which seems like it should then be put into the
cache key. The `ModuleLocal` type now derives `Hash` to guarantee that
all of its contents affect the hash key.
* The `ModuleTranslationState` from `cranelift-wasm` doesn't implement
`Hash` which means that we have a manual wrapper to work around that.
This will be fixed with an upstream implementation, since this state
affects the generated wasm code. Currently this is just a map of
signatures, which is present in `Module` anyway, so we should be good
for the time being.
* Hashing `dyn TargetIsa` was also added, where previously it was not
fully hashed. Previously only the target name was used as part of the
cache key, but crucially the flags of compilation were omitted (for
example the optimization flags). Unfortunately the trait object itself
is not hashable so we still have to manually write a wrapper to hash
it, but we likely want to add upstream some utilities to hash isa
objects into cranelift itself. For now though we can continue to add
hashed fields as necessary.
Overall the goal here was to use the compiler to expose what we're not
hashing, and then make sure we organize data and write the right code to
ensure everything is hashed, and nothing more.
* Update crates/environ/src/module.rs
Co-Authored-By: Peter Huene <peterhuene@protonmail.com>
* Fix lightbeam
* Fix compilation of tests
* Update the expected structure of the cache
* Revert "Update the expected structure of the cache"
This reverts commit 2b53fee426a4e411c313d8c1e424841ba304a9cd.
* Separate the cache dir a bit
* Add a test the cache is busted with opt levels
* rustfmt
Co-authored-by: Peter Huene <peterhuene@protonmail.com>