Stream: git-wasmtime

Topic: wasmtime / PR #10610 wasmtime-wit-bindgen: Typecheck expo...


view this post on Zulip Wasmtime GitHub notifications bot (Apr 18 2025 at 20:40):

pchickey edited PR #10610.

view this post on Zulip Wasmtime GitHub notifications bot (Apr 18 2025 at 20:53):

pchickey updated PR #10610.

view this post on Zulip Wasmtime GitHub notifications bot (Apr 18 2025 at 21:01):

pchickey edited PR #10610:

Based on #10616.

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 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 :).

<!--
Please make sure you include the following information:

Our development process is documented in the Wasmtime book:
https://docs.wasmtime.dev/contributing-development-process.html

Please ensure all communication follows the code of conduct:
https://github.com/bytecodealliance/wasmtime/blob/main/CODE_OF_CONDUCT.md
-->

view this post on Zulip Wasmtime GitHub notifications bot (Apr 18 2025 at 21:01):

pchickey edited PR #10610:

Based on #10616.

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 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.

<!--
Please make sure you include the following information:

Our development process is documented in the Wasmtime book:
https://docs.wasmtime.dev/contributing-development-process.html

Please ensure all communication follows the code of conduct:
https://github.com/bytecodealliance/wasmtime/blob/main/CODE_OF_CONDUCT.md
-->

view this post on Zulip Wasmtime GitHub notifications bot (Apr 18 2025 at 23:06):

pchickey updated PR #10610.

view this post on Zulip Wasmtime GitHub notifications bot (Apr 18 2025 at 23:15):

pchickey edited PR #10610:

Based on #10616.

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 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.

Additions to Wasmtime

All of these additions are pub interfaces but marked #[doc(hidden)] to make them "internal", because the prior art was that InstanceType and is internal, and there are no other public interfaces for retrieving InstanceType or typechecking, with the sole exception of Func::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

This test case demonstates the extent of the changes: https://github.com/bytecodealliance/wasmtime/pull/10610/files#diff-0b0815115f3addd488fbf1f032466f210b9fcd29ec42f4b4a777e58f80abba16

<!--
Please make sure you include the following information:

Our development process is documented in the Wasmtime book:
https://docs.wasmtime.dev/contributing-development-process.html

Please ensure all communication follows the code of conduct:
https://github.com/bytecodealliance/wasmtime/blob/main/CODE_OF_CONDUCT.md
-->

view this post on Zulip Wasmtime GitHub notifications bot (Apr 18 2025 at 23:22):

pchickey edited PR #10610:

Based on #10616.

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 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.

Additions to Wasmtime

All of these additions are pub interfaces but marked #[doc(hidden)] to make them "internal", because the prior art was that InstanceType and is internal, and there are no other public interfaces for retrieving InstanceType or typechecking, with the sole exception of Func::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

This test case demonstates the extent of the changes: https://github.com/bytecodealliance/wasmtime/pull/10610/files#diff-0b0815115f3addd488fbf1f032466f210b9fcd29ec42f4b4a777e58f80abba16

Future work

Each export func is typechecked again in its bindgen call_{funcname} function, in which the Func member owned by the typed instance {Foo} struct is cast to a TypedFunc 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 given Linker or Store, 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}. The for<'a> trick only works for trait objects, not concrete types like TypedFunc.)

<!--
Please make sure you include the following information:

Our development process is documented in the Wasmtime book:
https://docs.wasmtime.dev/contributing-development-process.html

Please ensure all communication follows the code of conduct:
https://github.com/bytecodealliance/wasmtime/blob/main/CODE_OF_CONDUCT.md
-->

view this post on Zulip Wasmtime GitHub notifications bot (Apr 18 2025 at 23:23):

pchickey has marked PR #10610 as ready for review.

view this post on Zulip Wasmtime GitHub notifications bot (Apr 18 2025 at 23:23):

pchickey requested dicej for a review on PR #10610.

view this post on Zulip Wasmtime GitHub notifications bot (Apr 18 2025 at 23:23):

pchickey requested wasmtime-core-reviewers for a review on PR #10610.

view this post on Zulip Wasmtime GitHub notifications bot (Apr 18 2025 at 23:29):

pchickey edited PR #10610:

Based on #10616.

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.

Additions to Wasmtime

All of these additions are pub interfaces but marked #[doc(hidden)] to make them "internal", because the prior art was that InstanceType and is internal, and there are no other public interfaces for retrieving InstanceType or typechecking, with the sole exception of Func::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

This test case demonstates the extent of the changes: https://github.com/bytecodealliance/wasmtime/pull/10610/files#diff-0b0815115f3addd488fbf1f032466f210b9fcd29ec42f4b4a777e58f80abba16

Future work

Each export func is typechecked again in its bindgen call_{funcname} function, in which the Func member owned by the typed instance {Foo} struct is cast to a TypedFunc 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 given Linker or Store, 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}. The for<'a> trick only works for trait objects, not concrete types like TypedFunc.)

<!--
Please make sure you include the following information:

Our development process is documented in the Wasmtime book:
https://docs.wasmtime.dev/contributing-development-process.html

Please ensure all communication follows the code of conduct:
https://github.com/bytecodealliance/wasmtime/blob/main/CODE_OF_CONDUCT.md
-->

view this post on Zulip Wasmtime GitHub notifications bot (Apr 21 2025 at 14:22):

dicej submitted PR review.

view this post on Zulip Wasmtime GitHub notifications bot (Apr 21 2025 at 15:01):

alexcrichton commented on PR #10610:

I'm a bit concerned about https://github.com/bytecodealliance/wasmtime/pull/10616 and the cost implications of having more Arc-clones on lifting/lowering paths, and after reading over this more I've got a possibilty which I forget if we already talked about and/or whether you tried, so let me know if I sound like a broken record. Could the various *Indices constructors take a &InstancePre<T> instead of a &Component? That way we could refactor the internals of InstancePre<T> to hold whatever is necessary to cheaply create the InstanceType<T> I think?

view this post on Zulip Wasmtime GitHub notifications bot (Apr 21 2025 at 15:01):

alexcrichton edited a comment on PR #10610:

I'm a bit concerned about https://github.com/bytecodealliance/wasmtime/pull/10616 and the cost implications of having more Arc-clones on lifting/lowering paths, and after reading over this more I've got a possibilty which I forget if we already talked about and/or whether you tried, so let me know if I sound like a broken record. Could the various *Indices constructors take a &InstancePre<T> instead of a &Component? That way we could refactor the internals of InstancePre<T> to hold whatever is necessary to cheaply create the InstanceType<'_> I think?

view this post on Zulip Wasmtime GitHub notifications bot (Apr 21 2025 at 16:32):

pchickey commented on PR #10610:

Thanks, I'll explore that now!

view this post on Zulip Wasmtime GitHub notifications bot (Apr 21 2025 at 20:41):

pchickey updated PR #10610.

view this post on Zulip Wasmtime GitHub notifications bot (Apr 21 2025 at 21:03):

pchickey updated PR #10610.

view this post on Zulip Wasmtime GitHub notifications bot (Apr 21 2025 at 21:07):

pchickey edited PR #10610.

view this post on Zulip Wasmtime GitHub notifications bot (Apr 21 2025 at 21:09):

pchickey edited PR #10610:

Based on #10616.

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 method typecheck<Params, Returns>(&self, instance_type: &InstanceType) -> Result<()>. The underlying typecheck performed here is the exact same one performed in Func::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 that InstanceType and is internal, and there are no other public interfaces for retrieving InstanceType or typechecking, with the sole exception of Func::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

This test case demonstates the extent of the changes: https://github.com/bytecodealliance/wasmtime/pull/10610/files#diff-0b0815115f3addd488fbf1f032466f210b9fcd29ec42f4b4a777e58f80abba16

Future work

Each export func is typechecked again in its bindgen call_{funcname} function, in which the Func member owned by the typed instance {Foo} struct is cast to a TypedFunc 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 given Linker or Store, 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}. The for<'a> trick only works for trait objects, not concrete types like TypedFunc.)

<!--
Please make sure you include the following information:

Our development process is documented in the Wasmtime book:
https://docs.wasmtime.dev/contributing-development-process.html

Please ensure all communication follows the code of conduct:
https://github.com/bytecodealliance/wasmtime/blob/main/CODE_OF_CONDUCT.md
-->

view this post on Zulip Wasmtime GitHub notifications bot (Apr 21 2025 at 21:18):

alexcrichton submitted PR review.

view this post on Zulip Wasmtime GitHub notifications bot (Apr 21 2025 at 21:23):

pchickey edited PR #10610:

Based on #10616.

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 method typecheck<Params, Returns>(&self, instance_type: &InstanceType) -> Result<()>. The underlying typecheck performed here is the exact same one performed in Func::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 that InstanceType and is internal, and there are no other public interfaces for retrieving InstanceType or typechecking, with the sole exception of Func::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-0b0815115f3addd488fbf1f032466f210b9fcd29ec42f4b4a777e58f80abba16

Future work

Each export func is typechecked again in its bindgen call_{funcname} function, in which the Func member owned by the typed instance {Foo} struct is cast to a TypedFunc 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 given Linker or Store, 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}. The for<'a> trick only works for trait objects, not concrete types like TypedFunc.)

<!--
Please make sure you include the following information:

Our development process is documented in the Wasmtime book:
https://docs.wasmtime.dev/contributing-development-process.html

Please ensure all communication follows the code of conduct:
https://github.com/bytecodealliance/wasmtime/blob/main/CODE_OF_CONDUCT.md
-->

view this post on Zulip Wasmtime GitHub notifications bot (Apr 21 2025 at 21:23):

pchickey edited PR #10610:

Based on #10616.

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 method typecheck<Params, Returns>(&self, instance_type: &InstanceType) -> Result<()>. The underlying typecheck performed here is the exact same one performed in Func::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 that InstanceType and is internal, and there are no other public interfaces for retrieving InstanceType or typechecking, with the sole exception of Func::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-0b0815115f3addd488fbf1f032466f210b9fcd29ec42f4b4a777e58f80abba16

Future work

Each export func is typechecked again in its bindgen call_{funcname} function, in which the Func member owned by the typed instance {Foo} struct is cast to a TypedFunc 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 given Linker or Store, 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}. The for<'a> trick only works for trait objects, not concrete types like TypedFunc.)

<!--
Please make sure you include the following information:

Our development process is documented in the Wasmtime book:
https://docs.wasmtime.dev/contributing-development-process.html

Please ensure all communication follows the code of conduct:
https://github.com/bytecodealliance/wasmtime/blob/main/CODE_OF_CONDUCT.md
-->

view this post on Zulip Wasmtime GitHub notifications bot (Apr 21 2025 at 21:23):

pchickey edited PR #10610:

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 method typecheck<Params, Returns>(&self, instance_type: &InstanceType) -> Result<()>. The underlying typecheck performed here is the exact same one performed in Func::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 that InstanceType and is internal, and there are no other public interfaces for retrieving InstanceType or typechecking, with the sole exception of Func::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-0b0815115f3addd488fbf1f032466f210b9fcd29ec42f4b4a777e58f80abba16

Future work

Each export func is typechecked again in its bindgen call_{funcname} function, in which the Func member owned by the typed instance {Foo} struct is cast to a TypedFunc 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 given Linker or Store, 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}. The for<'a> trick only works for trait objects, not concrete types like TypedFunc.)

<!--
Please make sure you include the following information:

Our development process is documented in the Wasmtime book:
https://docs.wasmtime.dev/contributing-development-process.html

Please ensure all communication follows the code of conduct:
https://github.com/bytecodealliance/wasmtime/blob/main/CODE_OF_CONDUCT.md
-->

view this post on Zulip Wasmtime GitHub notifications bot (Apr 21 2025 at 21:24):

pchickey commented on PR #10610:

I addressed the concerns above and rewrote the description accordingly.

view this post on Zulip Wasmtime GitHub notifications bot (Apr 21 2025 at 21:38):

pchickey edited PR #10610.

view this post on Zulip Wasmtime GitHub notifications bot (Apr 21 2025 at 21:40):

pchickey updated PR #10610.

view this post on Zulip Wasmtime GitHub notifications bot (Apr 21 2025 at 21:40):

pchickey has enabled auto merge for PR #10610.

view this post on Zulip Wasmtime GitHub notifications bot (Apr 21 2025 at 22:16):

pchickey merged PR #10610.


Last updated: Dec 06 2025 at 07:03 UTC