WebAssembly / proposal-type-imports

Proposal for Type Imports & Exports
Other
21 stars 7 forks source link

Clarification on exporting objects referencing type imports #14

Open takikawa opened 3 years ago

takikawa commented 3 years ago

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:

(import "file" "File" (type $File any))
(func $read3 (param $f (ref $File)) (result i32 i32 i32)
 ;; elided
)

If one were to instantiate this module with $File as heap type extern, 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 the call_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)

rossberg commented 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.