-
Notifications
You must be signed in to change notification settings - Fork 73
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
Type reflection and GC types #338
Comments
This sounds like a good direction, but I'm not familiar enough with JS APIs to have a solid picture of the details. What would the |
Thanks for digging into this topic, I think it's definitely useful to start thinking about what this might look like in future. That said, I don't think we should include this in the MVP, just to keep the set of deliverables for the initial proposal minimal. We've managed to get away without type reflection on the existing core spec for years, so it seems unlikely that the GC MVP would suffer greatly from not having such reflection abilities included on day 1. |
Agreed with @ajklein. I think for the no-frills approach the appropriate cause of action for type reflection would be not to add anything complex yet. We should even drop the additions suggested in the funcref proposal. I think all we'd want to add is the "anyref" value type. |
I didn't have a concrete idea for this in mind, but potentially there could be a
Yes, I'm fine with this approach for now as well. I thought it could make sense to add type reflection if it were straightforward to add an AST-based reflection like have in the base type reflection proposal, but that approach seems limiting for the reasons I wrote earlier. In that case, would we want type reflection to return a vague type (like collapsing all of these to |
Is there a forward compatibility story if we approximate to "anyref" now and want to introduce reflection on more refined types in the future? I guess we could add an additional API to access the more complex details of "anyref". I also think it would be strange to allow reflecting on "anyref" without also allowing anyref values to be passed to functions, so this decision seems intertwined with the discussion in #279. |
Yes, we definitely should not "weaken" non-expressible types. If something isn't any/func/externref, you cannot reflect it, i.e., the respective .type functions would throw for now. Everything else would not be forward-compatible. But that is independent from supporting anyref, e.g., it also applies to funcref. |
One thing we should specify is how types defined in the JS API interact with type canonicalization. |
@manoskouk, yes, those are different types, that's a direct consequence of the iso-recursive semantics. As long as the JS API has no syntax for recursive types, it can only create the equivalent of Wasm 2.0 type definitions (which we already reinterpret to be a shorthand for a singleton recursion). IOW, this follows from our chosen Wasm semantics and the fact that the type reflection API really only defines JS syntax for expressing Wasm type ASTs, it doesn't introduce its own type semantics. |
Currently the JS API is proposed to be a "no-frills" approach (#279). One question that hasn't been resolved yet is if and how type reflection should interact with this proposal.
There has been some discussion already about how type reflection could be handled. For example, by extending the current AST to expand to recursive types and other type definitions.
Such an extension should probably be built on what's proposed for typed function references (https://github.com/WebAssembly/function-references/blob/main/proposals/function-references/Overview.md#js-api), which looks like this:
The
DefType
non-terminal hasn't been defined yet for function references either, but for functions, arrays, and struct there could be straightforward ways to define additional AST descriptions for those type definitions (e.g.,{ deftype: DefTypeKind, ...}
and then type-specific fields)However, for recursive types, something more complicated is needed. To describe a reference ValueType that points to a recursive DefType, it's necessary to encode the recursion group. You could use the notion of a projection from the spec and return a DefType like this:
{ deftype: "projection", group: RecursionGroup, index: int }
One downside I see for this approach, though, is that the RecursionGroup here could be quite big if you eagerly represent it as an AST like other types. IIRC there was some discussion that some producers may output modules where all types are in a single big recursion group.
The JS API would also need to do something for
sub
types. Potentially the whole inheritance chain needs to be represented in the AST as well, and you may encounter recursive types along the inheritance chain too.Instead of using an AST-like approach, I wonder if it's better to create an API like
WebAssembly.Type
that would provide an interface over type definitions. The DefType specified above would be an object encoding this API rather than an AST object.Something like this is already mentioned as a possibility for the type imports proposal, which allows type definitions to be exported (even concrete ones) and thus needs a new kind of interface to match other kinds of exports. With an interface like this, the details of recursion groups could be queried on demand as method calls instead of properties. This new interface could also account for type canonicalization (like was suggested in Andreas' comment mentioned earlier).
Anyone have other thoughts on how this should work? Would adding a
WebAssembly.Type
be too large a change for a no-frills JS API? Should this be deferred and type reflection just throw on typed references?The text was updated successfully, but these errors were encountered: