Skip to content

Conversation

@dhil
Copy link
Member

@dhil dhil commented Jan 20, 2025

No description provided.

sunfishcode and others added 23 commits December 6, 2024 15:41
…codealliance#1102)

wit-bindgen already knows to special-case passing strings by reference
and pass them as `&str` instead of naively passing them as `&String` and
requiring callers to have owned `Strings`. Implement this behavior for
type aliases of strings as well, so that in code like this:
```wit
type my-string = string;
foo: func(x: my-string);
```
the argument is `&str` instead of `&MyString` which is effectively
`&String`. And similar for lists.

This comes up in several functions in wasi-http; for example, in the
bindings for the `Fields::append` function, it enables this change:

```diff
@@ -5075,8 +5075,8 @@ pub mod wasi {
                 /// `field-value` are syntactically invalid.
                 pub fn append(
                     &self,
-                    name: &FieldName,
-                    value: &FieldValue,
+                    name: &str,
+                    value: &[u8],
                 ) -> Result<(), HeaderError> {
                     unsafe {
                         #[repr(align(1))]
```

where `FieldName` and `FieldValue` are defined as:
```wit
            pub type FieldKey = _rt::String;
            pub type FieldName = FieldKey;
            pub type FieldValue = _rt::Vec<u8>;
```
Signed-off-by: James Sturtevant <jsturtevant@gmail.com>
…alliance#1106)

Signed-off-by: James Sturtevant <jsturtevant@gmail.com>
)

In the C bindings, prefix exported function names with `exports_` so
that a world that imports and exports the same function can do so
without collisions.

For example, with this WIT:

```wit
package green:blue;

world my-world {
  import purple: func();
  export purple: func();
}
```wit

This fixes a wit-bindgen panic with:

```
duplicate symbols: "name `my_world_purple` already defined"
```
…e#1109)

Signed-off-by: James Sturtevant <jsturtevant@gmail.com>
* Rename generators for clarity

Signed-off-by: James Sturtevant <jsturtevant@gmail.com>

* Move interface generator to own module

Signed-off-by: James Sturtevant <jsturtevant@gmail.com>

* Move function generator to own module

Signed-off-by: James Sturtevant <jsturtevant@gmail.com>

* Move Ident code to own file

Signed-off-by: James Sturtevant <jsturtevant@gmail.com>

* Move World generator code to own file

Signed-off-by: James Sturtevant <jsturtevant@gmail.com>

* Add some comments and alittle clean up

Signed-off-by: James Sturtevant <jsturtevant@gmail.com>

---------

Signed-off-by: James Sturtevant <jsturtevant@gmail.com>
* Minor clean up to files

* use static list instead of regenerating each time

* Clean up

Signed-off-by: James Sturtevant <jsturtevant@gmail.com>

---------

Signed-off-by: James Sturtevant <jsturtevant@gmail.com>
* Fix mismatched tuple ABIs in Rust

This fixes the mistaken assumption that the tuple ABI in Rust is the
same as the component model ABI and generates different code for
lifting/lowering lists.

Closes bytecodealliance#1112

* Attempt a java test

* Add a go test

* Fix java test

* Attempt to write C#
…ance#1082)

* Add support for async/streams/futures to Rust generator

This adds support for generating bindings which use the [Async
ABI](https://github.com/WebAssembly/component-model/blob/main/design/mvp/Async.md)
along with the [`stream`, `future`, and
`error-context`](WebAssembly/component-model#405) types.

By default, normal synchronous bindings are generated, but the user may opt-in
to async bindings for all or some of the imported and/or exported functions in
the target world and interfaces -- provided the default-enabled `async` feature
is enabled.

In addition, we generate `StreamPayload` and/or `FuturePayload` trait
implementations for any types appearing as the `T` in `stream<T>` or `future<T>`
in the WIT files, respectively.  That enables user code to call `new_stream` or
`new_future` to create `stream`s or `future`s with those payload types, then
write to them, read from them, and/or pass the readable end as a parameter to a
component import or return value of a component export.

Note that I've added new `core::abi::Instruction` enum variants to handle async
lifting and lowering, but they're currently tailored to the Rust generator and
will probably change somewhat as we add support for other languages.

This does not include any new tests; I'll add those in a follow-up commit.

Signed-off-by: Joel Dice <joel.dice@fermyon.com>

add `async: true` case to Rust `codegen_tests`

This ensures that all the codegen test WIT files produce compile-able bindings
with `async: true` (i.e. all imports lowered and all exports lifted using the
async ABI).  That revealed some issues involving resource methods and
constructors, as well as missing stub support, which I've resolved.

Signed-off-by: Joel Dice <joel.dice@fermyon.com>

add codegen tests for futures, streams, and error-contexts

Signed-off-by: Joel Dice <joel.dice@fermyon.com>

remove async_support::poll_future

It was both unsafe to use and intended only for testing (and not even good for
that, it turns out).

Signed-off-by: Joel Dice <joel.dice@fermyon.com>

add stream/future read/write cancellation support

Also, fix some issues with stream/future payload lifting/lowering which I
_thought_ I had already tested but actually hadn't.

Signed-off-by: Joel Dice <joel.dice@fermyon.com>

support callback-less (AKA stackful) async lifts

Signed-off-by: Joel Dice <joel.dice@fermyon.com>

revert incorrect test change in flavorful/wasm.rs

I had thoughtlessly removed test code based on a clippy warning, not realizing
it was testing (at compile time) that the generated types implemented `Debug`.

Signed-off-by: Joel Dice <joel.dice@fermyon.com>

test `async: true` option in Rust codegen tests

I had meant to do this originally, but apparently forgot to actually use the
option.

Signed-off-by: Joel Dice <joel.dice@fermyon.com>

add docs for new `debug` and `async` Rust macro options

Signed-off-by: Joel Dice <joel.dice@fermyon.com>

address `cargo check` lifetime warning

Signed-off-by: Joel Dice <joel.dice@fermyon.com>

minimize use of features based on PR feedback

Signed-off-by: Joel Dice <joel.dice@fermyon.com>

* add comment explaining lack of recursion in `type_id_info`

Signed-off-by: Joel Dice <joel.dice@fermyon.com>

* refactor stream and future support for Rust generator

Per a discussion with Alex, this moves most of the stream and future code into
the `wit-bindgen-rt` crate.  That's where I had intended to put it to begin
with, but ran into orphan rule issues given the trait-based approach I was
using.

The new approach uses dynamic dispatch via a vtable type.  Thus we've traded a
small (theoretical) amount of performance for much better compatibility in cases
of separately-generated bindings (e.g. passing `FutureWriter<T>` between crates
should work fine now), easier debugging, etc.

Signed-off-by: Joel Dice <joel.dice@fermyon.com>

* break `streams_and_futures` into two modules

Signed-off-by: Joel Dice <joel.dice@fermyon.com>

* restore previously-removed feature check in Rust macro

Signed-off-by: Joel Dice <joel.dice@fermyon.com>

---------

Signed-off-by: Joel Dice <joel.dice@fermyon.com>
* Update wasm-tools crates

Bringing then up-to-date with latest

* Fix compile of tests
- The generated lift/lower code for stream/future payloads was not always calculating module paths correctly when generating type names.
- Also, we were moving raw pointers into `async move` blocks and returning them without capturing the pointed-to memory.  This would have been caught by runtime tests, but we don't have those yet since the Wasmtime async PR hasn't been merged yet.  Fortunately, it was easy enough to find and fix when I updated that PR to use the latest wit-bindgen.
- The generated lift/lower code for reading and writing streams needs to return a `Box<dyn Future>` that captures the lifetimes of the parameters.

Signed-off-by: Joel Dice <joel.dice@fermyon.com>
…codealliance#1119)

This commit fixes compatibility of generated code with the Rust 2024
edition coming up next month. The new edition requires that
`#[export_name]` is notably an `unsafe` attribute and is wrapped in
`#[unsafe(export_name = "...")]` so the generated code is updated to do
that. Note that this syntax is allowed on the 2021 edition as of Rust
1.82.0 but is not required, it's only required in the 2024 edition.
…odealliance#1120)

* enable stream/future payload lift/lower for non-Wasm platforms

Previously, we generated no code for non-Wasm platforms; which meant our codegen
tests weren't really testing much as far as streams and futures go.  Now that
the tests actually do something, they uncovered a few issues which I've fixed:

- Invalid code generation when using `duplicate_if_necessary: true`
- Invalid code generation for stream or futures whose payloads contain one or more a streams or futures

For the latter, I mimicked what we do for resources: use interior mutability to
provide `take_handle` methods for `StreamReader` and `FutureReader`.

Signed-off-by: Joel Dice <joel.dice@fermyon.com>

* avoid lowering same values more than once in `StreamVtable::write`

Previously, we would optimistically lower all the values in the input array and
then re-lower the subset which wasn't accepted the first time.  Aside from being
inefficient, that was also incorrect since re-lowering would fail in the cases
of any resource handles, futures, or streams in the payload since we would have
already taken the handles using `take_handle`.

Signed-off-by: Joel Dice <joel.dice@fermyon.com>

---------

Signed-off-by: Joel Dice <joel.dice@fermyon.com>
[automatically-tag-and-release-this-commit]

Co-authored-by: Auto Release Process <auto-release-process@users.noreply.github.com>
…iance#1124)

While testing runtime borrow enforcement in Wasmtime, I discovered that the
guest code generated by `wit-bindgen` was not dropping borrows early enough for
async exports.  Specifically, all borrows need to be dropped before
`task.return` is called, which is what this patch does.

Signed-off-by: Joel Dice <joel.dice@fermyon.com>
Prior to bytecodealliance#1124, we were dropping borrows too late.  That PR fixed that problem,
but dropped borrows too early and didn't allow application code to capture the
borrows in the `Future` it returned.  This patch improves the situation by
dropping borrows as late as possible, but no later.  As a side effect, it
simplfies the code and makes implementing the generated trait(s) much more
ergonomic.

Signed-off-by: Joel Dice <joel.dice@fermyon.com>
…#1126)

This commit adds helpers for new `error-context` canon functions that
are part of the WASI P3 async effort.

Signed-off-by: Victor Adossi <vadossi@cosmonic.com>
Co-authored-by: Joel Dice <joel.dice@fermyon.com>
* c#: Add cli option to generate Result types

Signed-off-by: James Sturtevant <jsturtevant@gmail.com>

* Apply suggestions from code review

Co-authored-by: yowl <scott.waye@hubse.com>
Co-authored-by: Joel Dice <joel.dice@fermyon.com>

* Fix indentation

Signed-off-by: James Sturtevant <jsturtevant@gmail.com>

---------

Signed-off-by: James Sturtevant <jsturtevant@gmail.com>
Co-authored-by: yowl <scott.waye@hubse.com>
Co-authored-by: Joel Dice <joel.dice@fermyon.com>
…liance#1122)

* When calling an import we don't need to copy data to a new structure for cannoncal types. This avoid the extra copy of data in this scenario

Signed-off-by: James Sturtevant <jsturtevant@gmail.com>

* Use a pinned gc handle to get a pointer to the list

Using a span and fixed keyword won't work with variants due to the fact that the external import call requires different types. Nesting of the fixed commands also become unwiedly

Signed-off-by: James Sturtevant <jsturtevant@gmail.com>

* Apply suggestions from code review

Co-authored-by: Joel Dice <joel.dice@fermyon.com>

---------

Signed-off-by: James Sturtevant <jsturtevant@gmail.com>
Co-authored-by: Joel Dice <joel.dice@fermyon.com>
)

This commit introduces a default value for the `--async` option as
used with Rust bindgen.

Signed-off-by: Victor Adossi <vadossi@cosmonic.com>
Previously, we were either dropping the result too early
(e.g. `wit_bindgen_rt::async_support::ErrorContext`) or not at all
(e.g. `String` and `Vec`) due to the lowering code expecting to pass ownership
to the caller, which would later free memory using a post-return function.  But
async exports don't have post-return functions; they use `task.return` instead,
and they should free any memory (and/or drop handles) after `task.return`
returns.  So now we do that!

Signed-off-by: Joel Dice <joel.dice@fermyon.com>
Signed-off-by: James Sturtevant <jsturtevant@gmail.com>
@dhil dhil merged commit a3612b5 into wasmfx:main Jan 20, 2025
24 checks passed
@dhil dhil deleted the wasmfx-merge branch January 20, 2025 11:25
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants