Skip to content
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

Generalize the binary shorthand for exact references #9

Closed
wants to merge 1 commit into from

Conversation

tlively
Copy link
Member

@tlively tlively commented Mar 10, 2025

Extend the pattern of using 0x62 ht:absheaptype as a shorthand for
nullable reference types beyond just abstract heaptypes. Instead, use
0x62 ht:heaptype to mean a nullable exact reference for any heap type,
replacing the previous encoding.

Keep the (exact anyref) text shorthand for abstract heap types, but do
not extend it to other heap types since it is generally not as readable
as an explicitly spelled out type.

Extend the pattern of using `0x62 ht:absheaptype` as a shorthand for
nullable reference types beyond just abstract heaptypes. Instead, use
`0x62 ht:heaptype` to mean a nullable exact reference for any heap type,
replacing the previous encoding.

Keep the `(exact anyref)` text shorthand for abstract heap types, but do
not extend it to other heap types since it is generally not as readable
as an explicitly spelled out type.
@tlively
Copy link
Member Author

tlively commented Mar 10, 2025

cc @jakobkummerow

In practice I've found that the (exact anyref) shorthand is not that useful, so I'd be happy to remove it as well. I find that WAT is easier to read when all reference types are either a single keyword (like anyref) or begin with a ref.

@tlively
Copy link
Member Author

tlively commented Mar 10, 2025

cc @rossberg and @eqrion for your thoughts.

@rossberg
Copy link
Member

rossberg commented Mar 11, 2025

Is there reason to assume that nullable exact types are more frequent than non-nullable ones? That is a bit counter-intuitive to me. Otherwise, you'd rather want to shorten the other one.

I'm on board with not supporting the (exact anyref) shorthand.

@tlively
Copy link
Member Author

tlively commented Mar 11, 2025

Is there reason to assume that nullable exact types are more frequent than non-nullable ones? That is a bit counter-intuitive to me. Otherwise, you'd rather want to shorten the other one.

No, I haven't done any measurements. This made sense when it just applied to abstract heap types because we already only have binary shorthands for their nullable references. Reserving the shorter encoding for the more common pattern sounds good to me. I'll add a note in the text reminding us to revisit this later once we have implementations.

@sjrd
Copy link

sjrd commented Mar 12, 2025

IMO, exact any, exact extern, and the like should not even exist. Introducing them

  • has little to no benefit, and
  • will constrain future evolution of Wasm.

One very concrete constraint is that we would never be allowed to add subtypes of externref if we do that. An exact extern today can hold any value of the host (except null) -- and through WasmGC interop, that means any value of Wasm as well. Indeed, there are no subtypes of (ref extern), so every value qualifies. For example, an (exact extern) could hold a JS string. Now imagine that you want to add a subtype of externref for JS strings, let's call it (ref extern-string). That invalidates the fact that a JS string was a valid value of type (exact extern), since now there is a more precise type available, and it must be an (exact extern-string) instead.

For struct types, it's OK. We can reasonably assume that if we ever add new subtypes of struct types, values of such types would be completely new; not values that exist today. For broad types like extern, any and eq, (perhaps even func and exn), we cannot make the same argument.

@tlively
Copy link
Member Author

tlively commented Mar 12, 2025

This is addressed in the overview:

In contrast, any.convert_extern and extern.convert_any never produce exact references. (ref exact any) and (ref exact extern) are uninhabited. Internalized host references and externalized internal references are modeled as having "hidden" subtypes of any and extern, respectively. This preserves our ability to assign them more specific types in the future.

This is intended to apply to every abstract heap type that does not specifically have values. I think the only exceptions are i31, exn, and waitqueue (from shared-everything-threads).

@rossberg
Copy link
Member

I agree that exact abstract types are rather useless. But they are also harmless — both is true because they are uninhabited. We'd only get into trouble if we broke that invariant and introduced an instruction that produces a value of such a type. But I see no reason why we would ever want to, since that's equally useless AFAICS.

@tlively, maybe it's worth spelling out this invariant more explicitly?

So yeah, we could make special cases and disallow exact abstract types. But is it worth the effort?

Btw, I still think calling them "final" fits in better with the existing language...

@sjrd
Copy link

sjrd commented Mar 12, 2025

This is addressed in the overview:

Ah, I had missed that. Indeed, if they are uninhabited, and are guaranteed to stay uninhabited forever, then it's harmless. And if it helps regularity, that's a good motivation not to forbid them.

@tlively
Copy link
Member Author

tlively commented Mar 19, 2025

This is made obsolete by #18.

@tlively tlively closed this Mar 19, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants