Make funcref not a subtype of anyref #69
Description
(This idea came up after yesterday's discussion about the GC extension. I have tried to describe it here in a self-contained matter, but let me know if there are any terms I forgot to define or motivations I forgot to provide.)
Having funcref
be a subtype of anyref
forces the two to have the same register-level representation. Yet there are good reasons why an engine might want to represent a function reference differently than an arbitrary reference. For example, function references might always be an assembly-code pointer paired with a module-instance pointer, effectively representing the assembly code compiled from a wasm module closed over the global state of the specific instance the function reference was created from. If so, it might make sense for an engine to use a fat pointer for a function reference. But if funcref
is a subtype of anyref
, and if it overall makes sense for arbitrary references to be implemented with normal-width pointers, then that forces function references to be implemented with normal-width pointers as well, causing an otherwise-avoidable additional memory-indirection in every indirect function call.
Regardless of the reason, by making funcref
not a subtype of anyref
, we give engines the flexibility to represent these two types differently (including the option to represent them the same). Instead of subtyping, we could have a convert
instruction that could take a function reference and convert it into an anyref
representation, or more generally could convert between "convertible" types. The only main benefit of subtyping over conversion in a low-level type system is its behavior with respect to variance, such as co/contravariance of function types, but I see no such application for funcref
and anyref
. And in the worst case, we could always making funcref
a subtype of anyref
later if such a compelling need arises.