|
21 | 21 |
|
22 | 22 | namespace wasm {
|
23 | 23 |
|
24 |
| -// For each child, call `noteSubtype` with a pointer to the child and the most |
25 |
| -// specific type that the child must have. |
| 24 | +// CRTP visitor for determining constraints on the types of expression children. |
| 25 | +// For each child of the visited expression, calls a callback with a pointer to |
| 26 | +// the child and information on how the child is constrained. The possible |
| 27 | +// callbacks are: |
| 28 | +// |
| 29 | +// noteSubtype(Expression** childp, Type type) - The child must be a subtype |
| 30 | +// of `type`, which may be a tuple type. For children that must not produce |
| 31 | +// values, this may be `Type::none`. This accounts for most type constraints. |
| 32 | +// |
| 33 | +// noteAnyType(Expression** childp) - The child may have any non-tuple type. |
| 34 | +// Used for the children of polymorphic instructions like `drop` and `select`. |
| 35 | +// |
| 36 | +// noteAnyReference(Expression** childp) - The child may have any reference |
| 37 | +// type. Used for the children of polymorphic reference instructions like |
| 38 | +// `ref.is_null`. |
| 39 | +// |
| 40 | +// noteAnyTupleType(Expression** childp, size_t arity) - The child may have |
| 41 | +// any tuple type with the given arity. Used for the children of polymorphic |
| 42 | +// tuple instructions like `tuple.drop` and `tuple.extract`. |
| 43 | +// |
| 44 | +// Subclasses must additionally implement a callback for getting the type of a |
| 45 | +// branch target. This callback will only be used when the label type is not |
| 46 | +// passed directly as an argument to the branch visitor method (see below). |
| 47 | +// |
| 48 | +// Type getLabelType(Name label) |
| 49 | +// |
| 50 | +// Children with type `unreachable` satisfy all constraints. |
| 51 | +// |
| 52 | +// Constraints are determined using information that would be present in the |
| 53 | +// binary, e.g. type annotation immediates. Many of the visitor methods take |
| 54 | +// optional additional parameter for passing this information directly, and if |
| 55 | +// those parameters are not used, it is an error to use this utility in cases |
| 56 | +// where that information cannot be recovered from the IR. |
| 57 | +// |
| 58 | +// For example, it is an error to visit a `StructSet` expression whose `ref` |
| 59 | +// field is unreachable or null without directly passing the heap type to the |
| 60 | +// visitor because it is not possible for the utility to determine what type the |
| 61 | +// value child should be in that case. |
| 62 | +// |
| 63 | +// Conversely, this utility does not use any information that would not be |
| 64 | +// present in the binary, and in particular it generally does not introspect on |
| 65 | +// the types of children. For example, it does not report the constraint that |
| 66 | +// two non-reference children of `select` must have the same type because that |
| 67 | +// would require inspecting the types of those children. |
26 | 68 | template<typename Subtype> struct ChildTyper : OverriddenVisitor<Subtype> {
|
27 | 69 | Module& wasm;
|
28 | 70 | Function* func;
|
|
0 commit comments