This commit fixes a bug where when an out-of-bounds access is detected at compile time, `emit_wasm_store` was failing to free the source register. By the time the address is computed, the register is already allocated, independently if it's used or not, it must be freed.
* Add commentary on advantages/disadvantages of the pooling allocator
Inspired by discussion on #8034
* Add `memory_init_cow` commentary on disadvantages
* Fix doc link
* Show true error reason in `wasmtime serve`
The `wasmtime serve` command prints failed HTTP handling to `stderr`
but, when the reason was due to failure inside the HTTP handler itself,
the printed error message is not descriptive enough. After looking at
long dumps of `guest never invoked `response-outparam::set` method`, I
realized that errors inside the Tokio `task` are never propagated
outwards. This change captures those errors and appends them to the
printed error message.
* review: remove TODO comment
* review: improve doc comment
Co-authored-by: Trevor Elliott <telliott@fastly.com>
* review: add comment about immediate resolution
---------
Co-authored-by: Trevor Elliott <telliott@fastly.com>
* Add CLI flags for instance limits
While experimenting with `wasmtime serve`, I found it helpful to be able
to configure some of the maximum limits of the various objects stored in
the pooling allocator. This change surfaces some new `-O total-*` flags
for controlling these limits from the command line.
* review: prepend flags with `pooling_*`
* update capstone dependency to 0.12.0
this is only used for benchmarking, so the cargo vet is just an exemption which I updated to the latest version.
* winch filetests: fix capstone changes
* Add WinML backend for wasi-nn.
* Log execution time.
* WinML backend supports execution target selection.
ExecutionTarget::Gpu is mapped to LearningModelDeviceKind::DirectX.
* Limit WinML backend on Windows only.
* Move wasi-nn WinML example to new test infra.
* Scale tensor data in test app.
App knows input and target data range, so it's better to let app to
handle scaling.
* Remove old example for wasi-nn WinML backend.
* Update image2tensor link.
* Format code.
* Upgrade image2tensor to 0.3.1.
* Upgrade windows to 0.52.0
* Use tensor data as input for wasi-nn WinML backend test.
To avoid involving too many external dependencies, input image is
converted to tensor data offline.
* Restore trailing new line for Cargo.toml.
* Remove unnecessary features for windows crate.
* Check input tensor types.
Only FP32 is supported right now. Reject other tensor types.
* Rename default model name to model.onnx.
It aligns with openvino backend.
prtest:full
* Run nn_image_classification_winml only when winml is enabled.
* vet: add trusted `windows` crate to lockfile
* Fix wasi-nn tests when both openvino and winml are enabled.
* Add check for WinML availability.
* vet: reapply vet lock
---------
Co-authored-by: Andrew Brown <andrew.brown@intel.com>
This commit fixes an issue when inspecting the types of a component
where if a resource type wasn't substituted through an import it would
end up panicking. The fix here is to add a third kind of resource type
which represents an uninstantiated component as opposed to an
instantiated component or host type.
Closes#8003
When native unwinding information is enabled Wasmtime will use the
`__register_frame` API on Unix platforms to inform the runtime of the
unwinding information generated for wasm modules. This function,
however, has a different interface in libgcc vs libunwind. This means
that we need to detect which is being used and adapt our calls to it
appropriately.
Previously this decision was static. FreeBSD and Linux glibc would
assume libgcc and everything else was assumed to be libunwind. It's
possible to use libgcc on other platforms, however, such as with musl.
The goal of this PR is to make the detection here more robust.
Specifically this PR now probes for a symbol at runtime rather than
relying on a compile-time decision. That way we can see what we got at
runtime and make the decision then.
Closes#7997
* Add a "custom" platform configuration for Wasmtime
This commit leverages adds a new "platform" to Wasmtime to be supported
in the `crates/runtime/src/sys` folder. This joins preexisting platforms
such as Unix and Windows. The goal of this platform is to be an opt-in
way to build Wasmtime for targets that don't have a predefined way to
run.
The new "custom" platform requires `--cfg wasmtime_custom_platform` to
be passed to the Rust compiler, for example by using `RUSTFLAGS`. This
new platform bottoms out in a C API that is intended to be small and
Linux-like. The C API is effectively the interface to virtual memory
that Wasmtime requires. This C API is also available as a header file at
`examples/min-platform/embedding/wasmtime-platform.h` (generated by
`cbindgen`).
The main purpose of this is to make it easier to experiment with porting
Wasmtime to new platforms. By decoupling a platform implementation from
Wasmtime itself it should be possible to run these experiments
out-of-tree. An example of this I've been working on is getting
Wasmtime running on bare-metal with a custom kernel. This support
enables defining the platform interface of the custom kernel's syscalls
outside of Wasmtime.
* Exclude wasmtime-platform.h from formatting
* Include build-wasmtime-target-wasm32 in final job
* Don't force any single toolchain
* Add notes to no_std docs
* Add rust-src to CI
* Review comments
* Change APIs to be fallible
* Only compile the min-platform example on Linux
* Fix compile of min-platform example
* Fix another compile error in the example
This commit is an attempt to make the mistake fixed in #8016 harder to
happen again. This removes the `set_raw` helper entirely from tables and
instead forces all callers to view the table as either a table of
funcrefs or a table of externefs. By forcing that choice outwards
instead of handling it inwards it enables dealing with a typed table in
more contexts which should help naturally do the right thing.
While debugging #7999, we learned of a possible, extremely subtle,
interaction between the design of our ISLE mid-end prelude and matching
rules with a certain structure. Because a `Value` represents an entire
eclass, separate left-hand sides (as in helper rules or if-let clauses)
that match on the value may match against different enodes returned by
the multi-match extractor's iterator. We then may infer some property of
one enode, another property of another enode, and perform a rewrite that
is only valid if both of those matches are on the same enode.
The precise distinction is whether it is a property of the *value* -- e.g.,
nonzero, or even, or within a range -- or a property of the *operation*
and matched subpieces. The former is fine, the latter runs into
trouble. We found that #7719 added a helper that determined whether a
value "was a certain operator" -- actually, had any enode of a certain
operator -- and separately, matched "the operator" and extracted its
opcode and parameters (actually, *any* binary operator). The first half
can match an opcode we support simplifying, and the second half can get
the arguments and `op` and blindly use them in the rewrite.
This PR adds new guidance to avoid complex helpers and be aware of
multi-matching behavior, preferring to write patterns directly (as the
fix in #8005 does) instead. Longer-term, we also have other ideas, e.g.
@jameysharp's suggestion to disallow at-patterns on multi-extractors in
left hand sides to reduce the chance of hitting this footgun.
This logs the resulting values of a call into ISLE's `simplify` constructor, not
just the input value, so we can better debug in the future by tracing how a value
was produced and which value it is a rewrite of.
New output:
Calling into ISLE with original value v2
-> returned from ISLE: v2 -> [v3, v4, v5]
Old output:
Calling into ISLE with original value v2
-> returned from ISLE, generated 3 optimized values
We had two optimization rules which started off like this:
(rule (simplify (ireduce smallty val@(binary_op _ op x y)))
(if-let _ (reducible_modular_op val))
...)
This was intended to check that `x` and `y` came from an instruction
which not only was a binary op but also matched `reducible_modular_op`.
Unfortunately, both `binary_op` and `reducible_modular_op` were
multi-terms.
- So `binary_op` would search the eclass rooted at `val` to find each
instruction that uses a binary operator.
- Then `reducible_modular_op` would search the entire eclass again to
find an instruction which matched its criteria.
Nothing ensured that both searches would find the same instruction.
The reason these rules were written this way was because they had
additional guards (`will_simplify_with_ireduce`) which made them fairly
complex, and it seemed desirable to not have to copy those guards for
every operator where we wanted to apply this optimization.
However, we've decided that checking whether the rule is actually an
improvement is not desirable. In general, that should be the job of the
cost function. Blindly adding equivalent expressions gives us more
opportunities for other rules to fire, and we have global recursion and
growth limits to keep the process from going too wild.
As a result, we can just delete those guards. That allows us to write
the rules in a more straightforward way.
Fixes#7999.
Co-authored-by: Trevor Elliott <telliott@fastly.com>
Co-authored-by: L Pereira <l.pereira@fastly.com>
Co-authored-by: Chris Fallin <chris@cfallin.org>
This commit is an implementation of #7860 for Wasmtime where
`wasmtime::component::Linker` is now "semver aware". This means that it
assumes that hosts are always managing WIT interfaces in a
semver-aare fashion meaning that semver-compatible upgrade exclusively
adds functionality. This neatly fits into the idea of subtyping at the
instance-level where if a binary built against 0.2.0 only requests a
subset of functionality from a runtime that provides 0.2.1, that should
work just fine.
Specifically what this change does is:
* For all names inserted into a `Linker` there might also be a "semver
compatible name" which is registered as well. For example `..@1.0.0`
is also registered as `..@1`.
* Semver-compatible names are only provided for versions without a
prerelease and with either a nonzero major or minor version number.
* When looking up an item in the linker if no exact match is found then
if a semver-compatible-name is available for the lookup key then
that's consulted as well.
This semantically means that if a components imports WASI 0.2.0 then a
runtime which only provides WASI 0.2.1 will be able to instantiate the
component. Furthermore if a component imports WASI 0.2.1 but only
imports the subset of WASI that was available in 0.2.0 then it will be
instantiable in a runtime that only supports 0.2.0.
This implementation is intended to be a crucial part of the evolution to
WASI to make it more seamless to upgrade WASI from both a host and guest
perspective. This no longer requires everyone to upgrade to the same
version all at the same time but instead decouples the upgrade
schedules.
Closes#7860
* winch: Fix bounds checks for dynamic heaps
This commit fixes a fuzz bug in which the current implementation was incorrectly cloberring the index register of a memory access (for addition overflow check) and then using that same clobbered register to perform the memory access. The clobbered register contained the value: `index + offset + access_size`, which resulting in an incorrect access and consequently in an incorrect `HeapOutOfBounds` trap.
This bug is only reproducible when modifying Wasmtime's memory settings, forcing the heap to be treated as `Dynamic`.
Currently in Winch there's no easy way to have specific Wasmtime configurations, so having a filetests for this case is not straightforward. I've opted to add an integration test, in which it's easier to configure Wasmtime.
Note that the `tests/all/winch.rs` file is temporary, and the plan is to execute all the other integration tests with Winch at some point. In the case of `memory.rs`, that will be once Winch supports `memory64` hoping to reduce the amount of code needed in order to integrate Winch.
* Remove unused variable in integration tests
This commit updates Wasmtime to support `global.get` in constant
expressions when located in table initializers and element segments.
Pre-reference-types this never came up because there was no valid
`global.get` that would typecheck. After the reference-types proposal
landed however this became possible but Wasmtime did not support it.
This was surfaced in #6705 when the spec test suite was updated and has
a new test that exercises this functionality.
This commit both updates the spec test suite and additionally adds
support for this new form of element segment and table initialization
expression.
The fact that Wasmtime hasn't supported this until now also means that
we have a gap in our fuzz-testing infrastructure. The `wasm-smith`
generator is being updated in bytecodealliance/wasm-tools#1426 to
generate modules with this particular feature and I've tested that with
that PR fuzzing here eventually generates an error before this PR.
Closes#6705
* Wasmtime: Add a `gc` cargo feature
This controls whether support for `ExternRef` and its associated deferred,
reference-counting garbage collector is enabled at compile time or not. It will
also be used for similarly for Wasmtime's full Wasm GC support as that gets
added.
* Add CI for `gc` Cargo feature
* Cut down on the number of `#[cfg(feature = "gc")]`s outside the implementation of `[VM]ExternRef`
* Fix wasmparser reference types configuration with GC disabled/enabled
* More config fix
* doc cfg
* Make the dummy `VMExternRefActivationsTable` inhabited
* Fix winch tests
* final review bits
* Enable wasmtime's gc cargo feature for the C API
* Enable wasmtime's gc cargo feature from wasmtime-cli-flags
* enable gc cargo feature in a couple other crates
This commit fixes an accidental regression from #7766 where
`infer_native_flags` is called even if a target is explicitly specified
to a `Config`. Now inference only happens if a target isn't specified
meaning that the host is selected.
First of all, it is just a nice separation of concerns.
Second of all, as I design the GC rooting APIs for Wasmtime's upcoming Wasm GC
support, I want this same thing and I'd rather not open code it multiple times.
* Enable compiling the Wasmtime CLI to Wasm
While not the most useful thing to do in the world it's kind of neat to
play around with. This builds on the previous work to exclude the
runtime from the `wasmtime` crate so it's now possible to compile the
Wasmtime CLI's `compile` command, and only the `compile` command, to
wasm itself. This means you can run Wasmtime in Wasmtime!
* Fix warning on wasm
* Fix some feature combos
* Update some CI dependencies
* Update to the latest nightly toolchain
* Update mdbook
* Update QEMU for cross-compiled testing
* Update `cargo nextest` for usage with MIRI
prtest:full
* Remove lots of unnecessary imports
* Downgrade qemu as 8.2.1 seems to segfault
* Remove more imports
* Remove unused winch trait method
* Fix warnings about unused trait methods
* More unused imports
* More unused imports
This is true for anything I've ever encountered historically so I'm not
sure if it's worth having an explicit `compile_error!` here for all
non-enumerated platforms.
* Refactor the prologue and epilogue interface in winch
* Remove the locals reservation from the MacroAssembler's prologue/epilogue
* Update winch tests
* Remove the `WASI` submodule
Historically the `WASI` submodule in this repository was used to pull
the sources of the `*.witx` files for preview1. This has never been used
by the `wasmtime-wasi` crate (which has its own copy in the
`crates/wasi/witx` folder) and was only ever used by `wasi-common`. This
submodule also served as a location for the `witx` crate itself.
Neither of these are really needed any more as the `*.witx` files are
unlikely to ever really change again. This commit removes the submodule
entirely, as well as the `path` dependency on `witx`, and copies the
`*.witx` files in the same manner as the `wasmtime-wasi` crate.
* Updated vet entries for witx
* Remove witx special cases in publish script
* Change how the wasi-common package is built
When emitting a call to __tls_get_offset, the instruction needs to
carry two relocations, a R_390_PLT32DBL targeting __tls_get_offset
and a R_390_TLS_GDCALL targeting the TLS symbol. Specifically, the
system linker expects to see these two relocation in that order.
However, the cranelift backend currently emits the relocations in
reverse order - this unfortunately causes the linker to corrupt
the instruction sequence when performing a TLS relaxation.
To fix this in the backend, I need support in machinst common code
to emit a relocation at some offset to the instruction about to be
emitted (e.g. the relocation should target two bytes into the 6-byte
instruction that will be emitted next). I've added a new routine
add_reloc_at_offset to that effect. This also allowed to simplify
some existing code in the backend.
Also, change the disassembler to print multiple relocations on
a single instruction, if present.
* winch: Overhaul the internal ABI
This change overhauls Winch's ABI. This means that as part of this change, the default ABI now closely resembles Cranelift's ABI, particularly on the treatment of the VMContext. This change also fixes many wrong assumptions about trampolines, which are tied to how the previous ABI operated.
The main motivation behind this change is:
* To make it easier to integrate Winch-generated functions with Wasmtime
* Fix fuzz bugs related to imports
* Solidify the implementation regarding the usage of a pinned register to hold the VMContext value throughout the lifetime of a function.
The previous implementation had the following characteristics, and wrong assumptions):
* Assumed that nternal functions don't receive a caller or callee VMContexts as parameters.
* Worked correctly in the following scenarios:
* `Wasm -> Native`: since we can explicitly load the caller and callee `VMContext`, because we're
calling a native import.
* `(Native, Array) -> Wasm`: because the native signatures define a tuple of `VMContext` as arguments.
* It didn't work in the following scenario:
* `Wasm->Wasm`: When calling imports from another WebAssembly instance (via
direct call or `call_indirect`. The previous implementation wrongly assumes
that there should be a trampoline in this case, but there isn't. The code
was generated by the same compiler, so the same ABI should be used in
both functions, but it doesn't.
This change introduces the following changes, which fix the previous assumptions and bugs:
* All internal functions declare a two extra pointer-sized parameters, which will hold the callee and caller `VMContext`s
* Use a pinned register that will be considered live through the lifetime of the function instead of pinning it at the trampoline level. The pinning explicitlly happens when entering the function body and no other assumptions are made from there on.
* Introduce the concept of special `ContextArgs` for function calls. This enum holds metadata about which context arguments are needed depending on the callee. The previous implementation of introducing register values at arbitrary locations in the value stack conflicts with the stack ordering principle which states that older values must *always* precede newer values. So we can't insert a register, because if a spill happens the order of the values will be wrong.
Finally, given that this change also enables the `imports.wast` test suite, it also includes a fix to `global.{get, set}` instructions which didn't account entirely for imported globals.
Resolved conflicts
Update Winch filetests
* Fix typos
* Use `get_wasm_local` and `get_frame_local` instead of `get_local` and `get_local_unchecked`
* Introduce `MAX_CONTEXT_ARGS` and use it in the trampoline to skip context arguments.
This commit updates the allocation scheme for resources in the component
model to start at 1 instead of 0 when communicating with components.
This is an implementation of WebAssembly/component-model#284.
While this broke a number of tests we have this shouldn't actually break
any components in practice. The broken tests were all overly-precise in
their assertions and error messages and this shouldn't idiomatically
come up in any guest language, so this should not be a practically
breaking change.
This change additionally places an upper limit on the maximum
allocatable index at `1 << 30` which is also specified in the above PR.
* better top matter
* eliminate wasi-common deprecations from wasmtime-wasi
* wasmtime-wasi: preview2 feature always enabled, so just eliminate it
* rename preview1-on-preview2 feature to just preview1
* wasi-http fix
* dep fixes. change some log::debug! to tracing::debug!
* mv preview2 up to root
and `sed -i 's/crate::preview2/crate/g' **/*.rs`
* fix tests too
* fixes throughout wasmtime-wasi-http
* cli: s/wasmtime_wasi::preview2/wasmtime_wasi
* rustfmt
* fix wasi-async example
* fix docs build (needs wasi-common built to compile examples)
* c-api: use wasi-common directly
i guess we didnt build the c-api in CI with deprecation warnings denied
prtest:full
* fix example required-features
* fix examples CMakeLists build
By moving the registration count into the `Arc`, that is pulling the `Arc`
outwards from containing just the `WasmFuncType` to the registration count as
well, and turning it into an atomic, we can manipulate the registration count
without a write lock. Once that is done, we have the following:
* `RegisteredType::root` only needs a read lock, not a write lock.
* `RegisteredType::clone`, which used to need a write lock, doesn't need any
locking anymore.
* `RegisteredType::drop` doesn't need any locking most of the time. The
exception is when this is this drop that moves the refcount to zero, in which
case grabbing a write lock is still necessary to remove the type from the
registry.