* Prefix component-bindgen-generated-functions with `call_`
This fixes clashes between Rust-native methods and the methods
themselves. For example right now `new` is a Rust-generated function for
constructing the wrapper but this can conflict with a world-exported
function called `new`.
Closes#5585
* Fix types being both shared and owned
This refactors some inherited cruft from the original `wit-bindgen`
repository to be more Wasmtime-specific and fixes a codegen case where
a type was used in both a shared and an owned context.
Closes#5688
This commit fixes a bug in the `bindgen!` macro for components where
previously the `param` and `result` properties weren't properly
calculated depending on the structure of the type and which types were
visited in which order. This is simplified to use a `LiveTypes`
structure from the `wit-parser` crate and relies on that to do necessary
recursion.
* Update WIT tooling used by Wasmtime
This commit updates the WIT tooling, namely the wasm-tools family of
crates, with recent updates. Notably:
* bytecodealliance/wasm-tools#867
* bytecodealliance/wasm-tools#871
This updates index spaces in components and additionally bumps the
minimum required version of the component binary format to be consumed
by Wasmtime (because of the index space changes). Additionally WIT
tooling now fully supports `use`.
Note that WIT tooling doesn't, at this time, fully support packages and
depending on remotely defined WIT packages. Currently WIT still needs to
be vendored in the project. It's hoped that future work with `cargo
component` and possible integration here could make the story about
depending on remotely-defined WIT more ergonomic and streamlined.
* Fix `bindgen!` codegen tests
* Add a test for `use` paths an implement support
* Update to crates.io versions of wasm-tools
* Uncomment codegen tests
* wip
* start trying to write a runtime test
* cut out all the more complex test cases until i get this one working
* add macro parsing for the trappable error type config
* runtime result tests works for an empty and a string error type
* debugging: macro is broken because interfaces dont have names???
* thats how you name interfaces
* record error and variant error work
* show a concrete trap type, remove debug
* delete clap annotations from wit-bindgen crate
these are not used - clap isnt even an optional dep here - but were a holdover from the old home
A mistake was made in the publication of `wit-parser` where a breaking
change was made without bumping its major version, causing build issues
on `main` if `wit-parser` is updated. This commit updates `wit-parser`
to the latest and we'll handle breaking changes better next time.
Closes#5390
* Import Wasmtime support from the `wit-bindgen` repo
This commit imports the `wit-bindgen-gen-host-wasmtime-rust` crate from
the `wit-bindgen` repository into the upstream Wasmtime repository. I've
chosen to not import the full history here since the crate is relatively
small and doesn't have a ton of complexity. While the history of the
crate is quite long the current iteration of the crate's history is
relatively short so there's not a ton of import there anyway. The
thinking is that this can now continue to evolve in-tree.
* Refactor `wasmtime-component-macro` a bit
Make room for a `wit_bindgen` macro to slot in.
* Add initial support for a `bindgen` macro
* Add tests for `wasmtime::component::bindgen!`
* Improve error forgetting `async` feature
* Add end-to-end tests for bindgen
* Add an audit of `unicase`
* Add a license to the test-helpers crate
* Add vet entry for `pulldown-cmark`
* Update publish script with new crate
* Try to fix publish script
* Update audits
* Update lock file
* Leverage Cargo's workspace inheritance feature
This commit is an attempt to reduce the complexity of the Cargo
manifests in this repository with Cargo's workspace-inheritance feature
becoming stable in Rust 1.64.0. This feature allows specifying fields in
the root workspace `Cargo.toml` which are then reused throughout the
workspace. For example this PR shares definitions such as:
* All of the Wasmtime-family of crates now use `version.workspace =
true` to have a single location which defines the version number.
* All crates use `edition.workspace = true` to have one default edition
for the entire workspace.
* Common dependencies are listed in `[workspace.dependencies]` to avoid
typing the same version number in a lot of different places (e.g. the
`wasmparser = "0.89.0"` is now in just one spot.
Currently the workspace-inheritance feature doesn't allow having two
different versions to inherit, so all of the Cranelift-family of crates
still manually specify their version. The inter-crate dependencies,
however, are shared amongst the root workspace.
This feature can be seen as a method of "preprocessing" of sorts for
Cargo manifests. This will help us develop Wasmtime but shouldn't have
any actual impact on the published artifacts -- everything's dependency
lists are still the same.
* Fix wasi-crypto tests
This commit replaces #4869 and represents the actual version bump that
should have happened had I remembered to bump the in-tree version of
Wasmtime to 1.0.0 prior to the branch-cut date. Alas!
* Upgrade wasm-tools crates, namely the component model
This commit pulls in the latest versions of all of the `wasm-tools`
family of crates. There were two major changes that happened in
`wasm-tools` in the meantime:
* bytecodealliance/wasm-tools#697 - this commit introduced a new API for
more efficiently reading binary operators from a wasm binary. The old
`Operator`-based reading was left in place, however, and continues to
be what Wasmtime uses. I hope to update Wasmtime in a future PR to use
this new API, but for now the biggest change is...
* bytecodealliance/wasm-tools#703 - this commit was a major update to
the component model AST. This commit almost entirely deals with the
fallout of this change.
The changes made to the component model were:
1. The `unit` type no longer exists. This was generally a simple change
where the `Unit` case in a few different locations were all removed.
2. The `expected` type was renamed to `result`. This similarly was
relatively lightweight and mostly just a renaming on the surface. I
took this opportunity to rename `val::Result` to `val::ResultVal` and
`types::Result` to `types::ResultType` to avoid clashing with the
standard library types. The `Option`-based types were handled with
this as well.
3. The payload type of `variant` and `result` types are now optional.
This affected many locations that calculate flat type
representations, ABI information, etc. The `#[derive(ComponentType)]`
macro now specifically handles Rust-defined `enum` types which have
no payload to the equivalent in the component model.
4. Functions can now return multiple parameters. This changed the
signature of invoking component functions because the return value is
now bound by `ComponentNamedList` (renamed from `ComponentParams`).
This had a large effect in the tests, fuzz test case generation, etc.
5. Function types with 2-or-more parameters/results must uniquely name
all parameters/results. This mostly affected the text format used
throughout the tests.
I haven't added specifically new tests for multi-return but I changed a
number of tests to use it. Additionally I've updated the fuzzers to all
exercise multi-return as well so I think we should get some good
coverage with that.
* Update version numbers
* Use crates.io
* Fix a compile error on nightly Rust
It looks like Rust nightly has gotten a bit more strict about
attributes-on-expressions and previously accepted code is no longer
accepted. This commit updates the generated code for a macro to a form
which is accepted by rustc.
* Fix a soundness issue with lowering variants
This commit fixes a soundness issue lowering variants in the component
model where host memory could be leaked to the guest module by accident.
In reviewing code recently for `Val::lower` I noticed that the variant
lowering was extending the payload with `ValRaw::u32(0)` to
appropriately fit the size of the variant. In reading this it appeared
incorrect to me due to the fact that it should be `ValRaw::u64(0)` since
up to 64-bits can be read. Additionally this implementation was also
incorrect because the lowered representation of the payload itself was
not possibly zero-extended to 64-bits to accommodate other variants.
It turned out these issues were benign because with the dynamic
surface area to the component model the arguments were all initialized
to 0 anyway. The static version of the API, however, does not initialize
arguments to 0 and I wanted to initially align these two implementations
so I updated the variant implementation of lowering for dynamic values
and removed the zero-ing of arguments.
To test this change I updated the `debug` mode of adapter module
generation to assert that the upper bits of values in wasm are always
zero when the value is casted down (during `stack_get` which only
happens with variants). I then threaded through the `debug` boolean
configuration parameter into the dynamic and static fuzzers.
To my surprise this new assertion tripped even after the fix was
applied. It turns out, though, that there was other leakage of bits
through other means that I was previously unaware of. At the primitive
level lowerings of types like `u32` will have a `Lower` representation
of `ValRaw` and the lowering is simply `dst.write(ValRaw::i32(self))`,
or the equivalent thereof. The problem, that the fuzzers detected, with
this pattern is that the `ValRaw` type is 16-bytes, and
`ValRaw::i32(X)` only initializes the first 4. This meant that all the
lowerings for all primitives were writing up to 12 bytes of garbage from
the host for the wasm module to read.
It turned out that this write of a `ValRaw` was sometimes 16 bytes and
sometimes the appropriate size depending on the number of optimizations
in play. With enough inlining for example `dst.write(ValRaw::i32(self))`
would only write 4 bytes, as expected. In debug mode though without
inlining 16 bytes would be written, including the garbage from the upper
bits.
To solve this issue I ended up taking a somewhat different approach. I
primarily updated the `ValRaw` constructors to simply always extend the
values internally to 64-bits, meaning that the low 8 bytes of a `ValRaw`
is always initialized. This prevents any undefined data from leaking
from the host into a wasm module, and means that values are also
zero-extended even if they're only used in 32-bit contexts outside of a
variant. This felt like the best fix for now, though, in terms of
not really having a performance impact while additionally not requiring
a rewrite of all lowerings.
This solution ended up also neatly removing the "zero out the entire
payload" logic that was previously require. Now after a payload is
lowered only the tail end of the payload, up to the size of the variant,
is zeroed out. This means that each lowered argument is written to at
most once which should hopefully be a small performance boost for
calling into functions as well.
* Optimize flat type representation calculations
Previously calculating the flat type representation would be done
recursively for an entire type tree every time it was visited.
Additionally the flat type representation was entirely built only to be
thrown away if it was too large at the end. This chiefly presented a
source of recursion based on the type structure in the component model
which fuzzing does not like as it reports stack overflows.
This commit overhauls the representation of flat types in Wasmtime by
caching the representation for each type in the compile-time
`ComponentTypesBuilder` structure. This avoids recalculating each time
the flat representation is queried and additionally allows opportunity
to have more short-circuiting to avoid building overly-large vectors.
* Remove duplicate flat count calculation in wasmtime
Roughly share the infrastructure in the `wasmtime-environ` crate, namely
the non-recursive and memoizing nature of the calculation.
* Fix component fuzz build
* Fix example compile
This commit is an effort to reduce the amount of complexity around
managing the size/alignment calculations of types in the canonical ABI.
Previously the logic for the size/alignment of a type was spread out
across a number of locations. While each individual calculation is not
really the most complicated thing in the world having the duplication in
so many places was constantly worrying me.
I've opted in this commit to centralize all of this within the runtime
at least, and now there's only one "duplicate" of this information in
the fuzzing infrastructure which is to some degree less important to
deduplicate. This commit introduces a new `CanonicalAbiInfo` type to
house all abi size/align information for both memory32 and memory64.
This new type is then used pervasively throughout fused adapter
compilation, dynamic `Val` management, and typed functions. This type
was also able to reduce the complexity of the macro-generated code
meaning that even `wasmtime-component-macro` is performing less math
than it was before.
One other major feature of this commit is that this ABI information is
now saved within a `ComponentTypes` structure. This avoids recursive
querying of size/align information frequently and instead effectively
caching it. This was a worry I had for the fused adapter compiler which
frequently sought out size/align information and would recursively
descend each type tree each time. The `fact-valid-module` fuzzer is now
nearly 10x faster in terms of iterations/s which I suspect is due to
this caching.
This addresses #4307.
For the static API we generate 100 arbitrary test cases at build time, each of
which includes 0-5 parameter types, a result type, and a WAT fragment containing
an imported function and an exported function. The exported function calls the
imported function, which is implemented by the host. At runtime, the fuzz test
selects a test case at random and feeds it zero or more sets of arbitrary
parameters and results, checking that values which flow host-to-guest and
guest-to-host make the transition unchanged.
The fuzz test for the dynamic API follows a similar pattern, the only difference
being that test cases are generated at runtime.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
This commit goes through and updates support in the various argument
passing routines to support 0-sized flags. A bit of a degenerate case
but clarified in WebAssembly/component-model#76 as intentional.
* support dynamic function calls in component model
This addresses #4310, introducing a new `component::values::Val` type for
representing component values dynamically, as well as `component::types::Type`
for representing the corresponding interface types. It also adds a `call` method
to `component::func::Func`, which takes a slice of `Val`s as parameters and
returns a `Result<Val>` representing the result.
Note that I've moved `post_return` and `call_raw` from `TypedFunc` to `Func`
since there was nothing specific to `TypedFunc` about them, and I wanted to
reuse them. The code in both is unchanged beyond the trivial tweaks to make
them fit in their new home.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
* order variants and match cases more consistently
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
* implement lift for String, Box<str>, etc.
This also removes the redundant `store` parameter from `Type::load`.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
* implement code review feedback
This fixes a few issues:
- Bad offset calculation when lowering
- Missing variant padding
- Style issues regarding `types::Handle`
- Missed opportunities to reuse `Lift` and `Lower` impls
It also adds forwarding `Lift` impls for `Box<[T]>`, `Vec<T>`, etc.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
* move `new_*` methods to specific `types` structs
Per review feedback, I've moved `Type::new_record` to `Record::new_val` and
added a `Type::unwrap_record` method; likewise for the other kinds of types.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
* make tuple, option, and expected type comparisons recursive
These types should compare as equal across component boundaries as long as their
type parameters are equal.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
* improve error diagnostic in `Type::check`
We now distinguish between more failure cases to provide an informative error
message.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
* address review feedback
- Remove `WasmStr::to_str_from_memory` and `WasmList::get_from_memory`
- add `try_new` methods to various `values` types
- avoid using `ExactSizeIterator::len` where we can't trust it
- fix over-constrained bounds on forwarded `ComponentType` impls
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
* rearrange code per review feedback
- Move functions from `types` to `values` module so we can make certain struct fields private
- Rename `try_new` to just `new`
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
* remove special-case equality test for tuples, options, and expecteds
Instead, I've added a FIXME comment and will open an issue to do recursive
structural equality testing.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
* implement wasmtime::component::flags! per #4308
This is the last macro needed to complete #4308. It supports generating a Rust
type that represents a `flags` component type, analogous to how the [bitflags
crate](https://crates.io/crates/bitflags) operates.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
* wrap `format_flags` output in parens
This ensures we generate non-empty output even when no flags are set. Empty
output for a `Debug` implementation would be confusing.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
* unconditionally derive `Lift` and `Lower` in wasmtime::component::flags!
Per feedback on #4414, we now derive impls for those traits unconditionally,
which simplifies the syntax of the macro.
Also, I happened to notice an alignment bug in `LowerExpander::expand_variant`,
so I fixed that and cleaned up some related code.
Finally, I used @jameysharp's trick to calculate bit masks without looping.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
* fix shift overflow regression in previous commit
Jamey pointed out my mistake: I didn't consider the case when the flag count was
evenly divisible by the representation size. This fixes the problem and adds
test cases to cover it.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
* support enums with more than 256 variants in derive macro
This addresses #4361. Technically, we now support up to 2^32 variants, which is
the maximum for the canonical ABI. In practice, though, the derived code for
enums with even just 2^16 variants takes a prohibitively long time to compile.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
* simplify `LowerExpander::expand_variant` code
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
* support variant, enum, and union derives
This is the second stage of implementing #4308. It adds support for deriving
variant, enum, and union impls for `ComponentType`, `Lift`, and `Lower`. It
also fixes derived record impls for generic `struct`s, which I had intended to
support in my previous commit, but forgot to test.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
* deduplicate component-macro code
Thanks to @jameysharp for the suggestion!
Signed-off-by: Joel Dice <joel.dice@fermyon.com>
The more I read over this again the more I think that these should be
constants to explicitly indicate that we're supposed to be able to
optimize for them. Currently I'm predicting that adding memory64 support
will probably double the surface area of each trait (e.g. `lower32` and
`lower64`) rather than have a parameter passed around. This is in the
hopes that having specialized 32 and 64-bit paths will enable better
optimizations within each path instead of having to check all bounds
everywhere.
Additionally one day I'd like to have `fn load(bytes: &[u8;
Self::SIZE32])` but that doesn't work today in Rust.
This is the first stage of implementing
https://github.com/bytecodealliance/wasmtime/issues/4308, i.e. derive macros for
`ComponentType`, `Lift`, and `Lower` for composite types in the component model.
This stage only covers records; I expect the other composite types will follow a
similar pattern.
It borrows heavily from the work Jamey Sharp did in
https://github.com/bytecodealliance/wasmtime/pull/4217. Thanks for that, and
thanks to both Jamey and Alex Crichton for their excellent review feedback.
Thanks also to Brian for pairing up on the initial draft.
Signed-off-by: Joel Dice <joel.dice@fermyon.com>