Stream: git-wasmtime

Topic: wasmtime / issue #4039 components: Implement the ability ...


view this post on Zulip Wasmtime GitHub notifications bot (Apr 15 2022 at 19:54):

alexcrichton commented on issue #4039:

Note that procedurally this is based on https://github.com/bytecodealliance/wasmtime/pull/4005 so the first few commits aren't relevant to this PR itself. Additionally as with #4005 there are no tests, and this one definitely can't land without tests.

view this post on Zulip Wasmtime GitHub notifications bot (Apr 15 2022 at 20:09):

github-actions[bot] commented on issue #4039:

Subscribe to Label Action

cc @peterhuene

<details>
This issue or pull request has been labeled: "wasmtime:api", "wasmtime:config"

Thus the following users have been cc'd because of the following labels:

To subscribe or unsubscribe from this label, edit the <code>.github/subscribe-to-label.json</code> configuration file.

Learn more.
</details>

view this post on Zulip Wasmtime GitHub notifications bot (Apr 15 2022 at 20:10):

github-actions[bot] commented on issue #4039:

Label Messager: wasmtime:config

It looks like you are changing Wasmtime's configuration options. Make sure to
complete this check list:

[fuzzing-config]: https://github.com/bytecodealliance/wasmtime/blob/ca0e8d0a1d8cefc0496dba2f77a670571d8fdcab/crates/fuzzing/src/generators.rs#L182-L194
[fuzzing-docs]: https://docs.wasmtime.dev/contributing-fuzzing.html


<details>

To modify this label's message, edit the <code>.github/label-messager/wasmtime-config.md</code> file.

To add new label messages or remove existing label messages, edit the
<code>.github/label-messager.json</code> configuration file.

Learn more.

</details>

view this post on Zulip Wasmtime GitHub notifications bot (Apr 19 2022 at 14:02):

alexcrichton commented on issue #4039:

What if there were two ways to go from Value to Cursor?

The reason I haven't gone with something like this is that the idiomatic thing to do is then the slow thing, which I've been trying to avoid. Existence of a Value<T> doesn't lock memory to a particular state or prevent mutations, so validation of a Value<T> must always be re-done.

It's also less-so validation and more just reading all the memory. Even if we were to somehow do ahead-of-time validation it means that when you read something like list<my-enum> that does all the decoding a second time which is also something we should be shooting to avoid for performant cases. Basically I think it's required that we interleave validation and decoding for performance, but to be strictly standards compliant we probably need to figure out how to force those two to happen given any Value<T>

view this post on Zulip Wasmtime GitHub notifications bot (May 20 2022 at 20:58):

alexcrichton commented on issue #4039:

Still needs tests, so nothing new here, but I would like to confirm with other the subtyping store because that may or may not invalidate everything in this PR.

view this post on Zulip Wasmtime GitHub notifications bot (May 24 2022 at 18:14):

alexcrichton commented on issue #4039:

Ok I have written a mess of tests for this which indeed found some issues in the previous code. I've also opened https://github.com/bytecodealliance/wasmtime/issues/4185 to track various items to make sure I don't forget them. Otherwise I think this is probably good to land now.

Currently I have not added support to *.wast for actually invoking component functions. I could do that (inventing some syntax for this along the way) along with statically listing "these are the signatures which can be called" or something like that. I opted to instead use custom embedding tests, but eventually I think it will be more useful to get *.wast support as well (but it's always limited in the sense that the callable signatures must be statically listed internally). If @fitzgen you or others have thoughts on how to improve the tests here I'm happy to change things up as well.

view this post on Zulip Wasmtime GitHub notifications bot (May 24 2022 at 18:40):

alexcrichton commented on issue #4039:

Ah let me write my thoughts on subtyping here as well.

I realized relatively late in the design process for this feature that we did not factor in subtyping when crossing between the host and wasm. The major problem here is that the API designed here is where the host statically asserts the signature of a wasm componet function and then attempts to call it with that signature. Given subtyping, though, one might suspect that subtyping relationships would be respected in this typecheck. Implementation-wise, this is not supported.

For example if a wasm function export takes zero parameters, then the host could declare that it in fact takes 2 parameters. According to the subtyping rules these type signatures are compatible and this function call should be executed. If the parameters were strings though the host would copy in results to the module when calling it when it shouldn't do that.

A naive fix for this issue would be to always lower values in the context of a type. For example the ComponentValue trait would have a type added to the lower method where a value is lowered into a particular type (or stored as one). This means though that all layers of lowering are constantly performing typechecks to see if subtyping conversions are necessary. It's roughly predicted that the cost of this will be prohibitive and as such we wouldn't want to do that.

A much more advanced fix would be to generate trampolines. Compilation of a component would now also involve specifying the interface that an embedder would be using (e.g. the signature it expects for exports and the signatures for the imports). Appropriate trampolines would be generated and the host would call the trampolines which would "do the right thing". The problem with this strategy is that the host loses all flexibility of the layout of host data. Instead now everything has to be in a format that the trampoline understands. Additionally throwing in complexity of things like host destructors makes this much more complex as well.

Overall after talking with Luke the current thinking is to do this:

The (hopeful) idea is that hosts can detect mismatches in type relationships. Hosts ideally have *.wit files or similar describing imports and exports, and that can be used to preprocess a component from a consumer to either verify that the types all line up or whether a second component is needed to perform the subtyping relationship. This component-to-component communication would then handle subtyping via the Cranelift-generated trampolines because type representation is all fixed with the canonical ABI and it's much easier to generate a trampoline.

view this post on Zulip Wasmtime GitHub notifications bot (May 24 2022 at 19:17):

fitzgen commented on issue #4039:

Overall after talking with Luke the current thinking is to do this:

* Do not implement subtyping in host imports/exports. Everything has to have an exact signature match.

* If subtyping is necessary, the component is wrapped in another component which uses the right signatures.

The (hopeful) idea is that hosts can detect mismatches in type relationships. Hosts ideally have *.wit files or similar describing imports and exports, and that can be used to preprocess a component from a consumer to either verify that the types all line up or whether a second component is needed to perform the subtyping relationship. This component-to-component communication would then handle subtyping via the Cranelift-generated trampolines because type representation is all fixed with the canonical ABI and it's much easier to generate a trampoline.

This seems like a very reasonable path for us to go down.


Last updated: Dec 23 2024 at 12:05 UTC