Open takikawa opened 3 years ago
Yes, a module with type imports is similar to a polymorphic definition, i.e., the instantiation types determine the types of exports.
FWIW, table types don't matter for call_indirect, they are only relevant for validation and don't affect execution. What call_indirect looks at are the precise (runtime) type of the function found and the type annotated. The best mental model perhaps is that a call_indirect is roughly equivalent to a sequence of table.get, rtt.canon, cast (as in the GC proposal), and call_ref, except that it can potentially be optimised better. Thus, type imports only possibly affect the type annotation, i.e., the type produced by the assumed rtt.canon. We could consider disallowing the use of imported types in a call_indirect to avoid the link-time dependency, but that would be rather non-compositional.
My understanding of type imports is that once the module is instantiated and a concrete type is given, the module should act as if its exports had a substitution applied to them of the concrete type for the import. For example, given a function like in the proposal example:
If one were to instantiate this module with
$File
as heap typeextern
, then the type of the$read3
function on export should be[externref] -> [i32 i32 i32]
(and for example type reflection should return a representation of this in JS). Is this a correct understanding of how the proposal works?I think this also means that this substitution has to be executed at instantiation-time for some things, not just delayed through some kind of indirection. For example, if type imports are used to specify a table type for use with
call_indirect
, the concrete type has to be substituted in at instantiation (not just an indirection to look up later) in order to make thecall_indirect
check a pointer comparison. Is this intuition correct?(On the other hand, maybe function wrappers/stubs for JS/host interoperation that are compiled by the engine still need an indirection to get the concrete type for an import if such wrappers are compiled before instantiation-time)