rvolosatovs opened issue #7726:
Feature
At present, only simple types can be returned in
component::LinkerInstance::func_new
The following variants of
component::Val
cannot be returned by dynamic functions defined viacomponent::LinkerInstance::func_new
:
- List(List)
- Record(Record)
- Tuple(Tuple)
- Variant(Variant)
- Enum(Enum)
- Option(OptionVal)
- Result(ResultVal)
- Flags(Flags)
The reason for this is the fact that constructors of these values require a type parameter, which cannot be constructed outside the crate. While such type parameter can be extracted from a function signature exported by a component, there is currently no means to access the type for functions imported by the component. At best, implementations may parse the type information using
wit_parser
crate, but there is currently no way to map fromwit_parser
type towasmtime
type.For example:
Enum::new
requirestypes::Enum
value as a parameter, which does not export a constructor or any conversion mechanism. This type can only be returned by wasmtime crate, but functionality to extract this from a component import does not currently appear to exist.Benefit
This would allow dynamically-typed function definitions in the linker returning more that the basic numeric/string types (and resources once https://github.com/bytecodealliance/wasmtime/pull/7688 lands)
Implementation
Perhaps
func_new
function parameter signatures could be updated to take in aVec<Type>
(https://docs.rs/wasmtime/latest/wasmtime/component/types/enum.Type.html) or, perhaps even better signatures could getVec<(Val, Type)>
as a parameter for the result parameter. Note, thatparams
are free from this issue, because the type info is already embedded inVal
passed to the function, which is not the case for results (and there is probably no way to change that)Alternatives
The only alternative seems not supporting dynamically-typed function imports, or only supporting a subset of those, as currently done.
alexcrichton commented on issue #7726:
I might recommend a route such as with https://github.com/bytecodealliance/wasmtime/issues/4593 where we'd flesh out the runtime reflection APIs on the types used in a component to be able to inspect imports/exports and then update
func_new
to taking aFuncType
like its core wasm counterpart as well. The one major tricky part would be runtime construction of types if that's required which is not easy, but if you're using exact types from a component then that should still work ok.
rvolosatovs commented on issue #7726:
I might recommend a route such as with #4593 where we'd flesh out the runtime reflection APIs on the types used in a component to be able to inspect imports/exports and then update
func_new
to taking aFuncType
like its core wasm counterpart as well. The one major tricky part would be runtime construction of types if that's required which is not easy, but if you're using exact types from a component then that should still work ok.Given existing functionality, I don't think this would work without significant changes in
component::types
- that is because at present construction ofVal
requires a component instance to lookupInstanceType
from, e.g. considerOption
, which relies on theHandle
type, which, in turn, requires anInstanceType
: https://github.com/bytecodealliance/wasmtime/blob/f3b5478bfcb759d99b3910b121c644b4c9c572bf/crates/wasmtime/src/component/types.rs#L428-L430. As far as I understand the implementation, at present the only way to produce anInstanceType
is to instantiate the component.
Linker::func_new
is called before instantiation takes place, therefore it's not possible to produce aFuncType
parameter to pass toLinker::func_new
- that would depend on instantiation.
Am I missing something here?For my concrete use case, however, introspecting the
Instance
/InstancePre
types from within thefunc_new
closure implementation is most certainly "good enough" (a handle to it is simply kept in the store). What do you think about this approach? It feels like introspecting onInstance
/InstancePre
level would be a beneficial feature anyway
rvolosatovs edited a comment on issue #7726:
I might recommend a route such as with #4593 where we'd flesh out the runtime reflection APIs on the types used in a component to be able to inspect imports/exports and then update
func_new
to taking aFuncType
like its core wasm counterpart as well. The one major tricky part would be runtime construction of types if that's required which is not easy, but if you're using exact types from a component then that should still work ok.Given existing functionality, I don't think this would work without significant changes in
component::types
- that is because at present construction ofType
requires a component instance to lookupInstanceType
from, e.g. considerOptionType
, which relies on theHandle
type, which, in turn, requires anInstanceType
: https://github.com/bytecodealliance/wasmtime/blob/f3b5478bfcb759d99b3910b121c644b4c9c572bf/crates/wasmtime/src/component/types.rs#L428-L430. As far as I understand the implementation, at present the only way to produce anInstanceType
is to instantiate the component.
Linker::func_new
is called before instantiation takes place, therefore it's not possible to produce aFuncType
parameter to pass toLinker::func_new
- that would depend on instantiation.
Am I missing something here?For my concrete use case, however, introspecting the
Instance
/InstancePre
types from within thefunc_new
closure implementation is most certainly "good enough" (a handle to it is simply kept in the store). What do you think about this approach? It feels like introspecting onInstance
/InstancePre
level would be a beneficial feature anyway
rvolosatovs edited a comment on issue #7726:
I might recommend a route such as with #4593 where we'd flesh out the runtime reflection APIs on the types used in a component to be able to inspect imports/exports and then update
func_new
to taking aFuncType
like its core wasm counterpart as well. The one major tricky part would be runtime construction of types if that's required which is not easy, but if you're using exact types from a component then that should still work ok.Given existing functionality, I don't think this would work without significant changes in
component::types
- that is because at present construction ofType
requires a component instance to lookupInstanceType
from, e.g. considerOptionType
, which relies on theHandle
type, which, in turn, requires anInstanceType
: https://github.com/bytecodealliance/wasmtime/blob/f3b5478bfcb759d99b3910b121c644b4c9c572bf/crates/wasmtime/src/component/types.rs#L428-L430. As far as I understand the implementation, at present the only way to produce anInstanceType
is to instantiate the component.
Linker::func_new
is called before instantiation takes place, therefore it's not possible to produce aFuncType
parameter to pass toLinker::func_new
- that would depend on instantiation.
Am I missing something here?For my concrete use case, however, introspecting the
Instance
types from within thefunc_new
closure implementation is most certainly "good enough" (a handle to it is simply kept in the store). What do you think about this approach? It feels like introspecting onInstance
level would be a beneficial feature anyway
alexcrichton commented on issue #7726:
I think that's reasonable yeah, good point. There's subtelty here around resources and while it's something I believe we can solve you're right it'd require some refactoring. In the long run we're going to want to query the type of and instance in addition to a component anyway, so I think it make sense to go ahead and implement this for instances at this time too.
alexcrichton closed issue #7726:
Feature
At present, only simple types can be returned in
component::LinkerInstance::func_new
The following variants of
component::Val
cannot be returned by dynamic functions defined viacomponent::LinkerInstance::func_new
:
- List(List)
- Record(Record)
- Tuple(Tuple)
- Variant(Variant)
- Enum(Enum)
- Option(OptionVal)
- Result(ResultVal)
- Flags(Flags)
The reason for this is the fact that constructors of these values require a type parameter, which cannot be constructed outside the crate. While such type parameter can be extracted from a function signature exported by a component, there is currently no means to access the type for functions imported by the component. At best, implementations may parse the type information using
wit_parser
crate, but there is currently no way to map fromwit_parser
type towasmtime
type.For example:
Enum::new
requirestypes::Enum
value as a parameter, which does not export a constructor or any conversion mechanism. This type can only be returned by wasmtime crate, but functionality to extract this from a component import does not currently appear to exist.Benefit
This would allow dynamically-typed function definitions in the linker returning more that the basic numeric/string types (and resources once https://github.com/bytecodealliance/wasmtime/pull/7688 lands)
Implementation
Perhaps
func_new
function parameter signatures could be updated to take in aVec<Type>
(https://docs.rs/wasmtime/latest/wasmtime/component/types/enum.Type.html) or, perhaps even better signatures could getVec<(Val, Type)>
as a parameter for the result parameter. Note, thatparams
are free from this issue, because the type info is already embedded inVal
passed to the function, which is not the case for results (and there is probably no way to change that)Alternatives
The only alternative seems not supporting dynamically-typed function imports, or only supporting a subset of those, as currently done.
Last updated: Dec 23 2024 at 12:05 UTC