-
Notifications
You must be signed in to change notification settings - Fork 3
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
Importing type customization information #3
Comments
I like this idea. Making the host info a syntactic element of the type definition nicely solves the problem of having different reflections of the same type. One issue is that if host info imports work the same as other imports, then it will be impossible to determine until instantiation time whether two imported host infos are the same and therefore whether two types that differ only in their host info should be the same. I guess we would have to solve that by treating different host info indices as different at validation and compile time even if they end up the same. But then casts would have to respect that difference as well, so casts couldn't just use the imported host info as the RTT 🤔 |
Just to make sure we're on the same page, we're thinking of a situation like:
$a and $b are identical except for referring to different imported host-info's. I believe the situation is very similar to how I understand full type imports would need to work. Validation will have to assume that different host-info imports are different, because they may be instantiated differently. But instantiation may provide the same host-info for the types, in which cases the types will be equivalent. Any runtime types/casting will be a 1:1 reflection of that. So in the example above, a |
It seems odd that the relation between types at runtime could be different than the relation between them at validation time, but I guess it's probably ok because the validation relation is more conservative. And yeah, I guess full type imports would have to work similarly. @rossberg, I'm curious to hear what you think of this idea. |
This sketch sounds like the notion of "descriptors" that we discussed two years ago, as a way for giving access to what engines do with shapes/maps, including the ability to store "static" fields in them. Shame on me for having had a sketch of that lying around for a long time, but never getting round to thinking through it enough to put it in the Post-MVP doc. The idea roughly is that you can declare
where $d is another type you can either define locally or import. That type has to be declared to be a descriptor, e.g.,
If defined within Wasm, this gives a way to store Wasm fields within the descriptor, like JS engines do to store some constant fields. Where I got a bit stuck with this idea is that as just sketched naively it would be unsound – like I believe your sketch would be as well. Since we want to use descriptors as RTTs for casts, we also must ensure that they are used consistently, each for one specific type only, across modules! Otherwise nothing is preventing anybody from using one descriptor for two totally unrelated types (possibly in different modules), and boom. Preventing that would seem to require that every descriptor also declares which exact type it is a descriptor for(*), creating a cyclic dependency between the two. Maybe that's okay, but it seems a bit unwieldy. And a follow-up complexity then is that descriptor imports also need to specify this, i.e., imports would need non-trivial bounds. (*) Fixing its entire supertype hierarchy as well, since unlike JS, Wasm also has subtyping, which is encoded in the descriptor. @tlively, re your question: type imports act like parameters. As @eqrion says, validation has to assume conservatively that they are different, even though they could be instantiated the same. That is perfectly fine and unsurprising. The same happens in a Java-like language with generic functions containing casts. (Edit: I should have said C#-like instead, since generic casts are of course broken in Java.) |
@rossberg I think the difference here is that the imported 'host-info' here is an addition to the type definition and runtime-type, not a replacement for it. So if you just had a 'host-info', you can't do any casting of objects with it. You'd need to have a 'type' and 'host-info' pair to get the runtime type to do any cast. So two different types with the same host-info would still be two different types. It's just extra metadata on the type for things like field names or prototypes, and is largely opaque to wasm. But on the (off-)topic of using the RTT for extra storage for static fields, I also have a sketch for that where: (1) A type could declare a single field that would exist on their RTT:
(2) The
This would let programs store their class objects (or whatever) in engine's rtt's and access them from a given object by getting the rtt, then the field off of it. I'm not sure if the bit in rtt.canon about equivalent field values is necessary, but it seems like it could be useful for module rtt coordination. |
Here's a sketch proposal that is very similar to type imports, but instead of importing the whole type we are only importing 'host-info' that only defines how the type is reflected in the host.
Goals
Be able to set the prototype of structs and arrays
Be able to attach read or write accessors to structs and arrays
Sketch
Add a new module-field that represents how a type should be reflected when accessed by host code. I don't have a good name yet, so I'll offer a bad one:
host-info
. This is only able to be imported and exported, no way to define locally is provided. The definition is basically opaque to wasm.Allow a type definition to specify an (imported)
host-info
.Extend JS-API with
StructHostInfo
andArrayHostInfo
interfaces that allow specifying prototypes, accessors, etc.Instantiating a module will check that the imported
host-info
is consistent with the type that imports it.Type equality remains structural, but the final imported
host-info
is taken into account. Two instantiated types are equivalent iff theirhost-info
's are structurally equivalent. Hosts are allowed to define equality of theirhost-info
s however makes most sense for them. [1][1] This is important for web engines where shapes/maps are used for casting and also storing prototype/accessor information. Different prototypes means different shapes/maps, and therefore it's very useful for the types to no longer be equivalent for casting.
Example
The text was updated successfully, but these errors were encountered: