-
Notifications
You must be signed in to change notification settings - Fork 1.4k
wasmtime-wit-bindgen: Typecheck exports at {Foo}Indices construction #10610
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
crates/component-macro/tests/expanded/worlds-with-types_tracing_async.rs
Outdated
Show resolved
Hide resolved
Having refs to a pair of arcs made it less expensive to create an InstanceType, but tied its to a borrow of the ComponentInstance (transitively the Store) which makes some new typechecking operations which have an AsContextMut impossible. This has no direct benefit in this PR, but it split out of #10610 because it is more easily reviewed in isolation.
020983c
to
1ccb97f
Compare
9b0d640
to
2472422
Compare
I'm a bit concerned about #10616 and the cost implications of having more |
Thanks, I'll explore that now! |
b5d7be5
to
a601180
Compare
I addressed the concerns above and rewrote the description accordingly. |
a601180
to
96ccf12
Compare
Based on #10621
Currently, in bindgen-emitted component wrappers, the existence of export functions is checked at the construction of the {interface-name}Indices struct, but each export function is only finally typechecked on their invocation in {interface-name}::call_{func-name}.
The goal of this PR is to typecheck component exports at the construction of Indices. This is desirable because it gives a type error as early as possible - when using {interface-name}Indices by way of {interface-name}Pre, this can be performed with only an InstancePre, where the creation of an InstancePre requires only a Component and Linker, and typechecks all of the Component's imports. So, really, this is about getting exports on parity with imports.
Closes #9155 . I've worked around this with ugly hacks in embeddings for 2 different employers now and I'm not about to do it for a third.
Addition to Wasmtime
component::types::ComponentFunc
has a new methodtypecheck<Params, Returns>(&self, instance_type: &InstanceType) -> Result<()>
. The underlying typecheck performed here is the exact same one performed inFunc::typed<Params, Returns>(&self, store: impl AsContextMut) -> Result<()>
, except rather than the type information coming out of the store, its provided by the InstanceType.This addition is a pub interfaces but marked
#[doc(hidden)]
to make them "internal", because the prior art was thatInstanceType
and is internal, and there are no other public interfaces for retrievingInstanceType
or typechecking, with the sole exception ofFunc::typed
. I think that we should consider making these documented public interfaces, but I'll leave that to a future PR unless requested.Changes to wasmtime-wit-bindgen
The
resources-import
test case demonstates the extent of the changes: https://github.com/bytecodealliance/wasmtime/pull/10610/files#diff-0b0815115f3addd488fbf1f032466f210b9fcd29ec42f4b4a777e58f80abba16fn new<T>(_instance_pre: InstancePre<T>) -> Result<Self>
. Deduplicating this eliminates both generated code and complexity in the generator._instance_pre.component()
to lookup exports (both their index and their ComponentItem), and_instance_pre.instance_type()
is used to typecheck the export..get_export_index
has been substituted out with.get_export
, and the returnedComponentItem
is checked to be a ComponentItem::ComponentFunc(func), and thenfunc.typecheck
is invoked with the type argument corresponding to theTypedFunc
type parameters.Future work
Each export func is typechecked again in its bindgen
call_{funcname}
function, in which theFunc
member owned by the typed instance{Foo}
struct is cast to aTypedFunc
with the specific type parameters bindgen keeps track of for each func. Since the{Foo}
struct is created from a{Foo}Indices
, we can guarantee that the export funcs have been typechecked against a givenLinker
orStore
, so we could potentially elide the repeated typecheck there, and make an unchecked cast to TypedFunc instead. (TypedFuncs are not stored in the{Foo}
struct at least in part because their type parameters may use&'a ...
which only apply to the site of the call, and not to the storage of that member in{Foo}
. Thefor<'a>
trick only works for trait objects, not concrete types like TypedFunc.)