-
Notifications
You must be signed in to change notification settings - Fork 40
Asymmetric handling of br_table and br_if with bot type #48
Comments
This is not specific to bottom, it applies to any subtyping. The difference comes from the fact that br_table has (via the labels' blocks) an explicit type annotation for each of its continuations. For br_if there is no separate one for the fall-through case, so the one available is used for both out edges. The same applies to other instructions that "fork" an operand from the stack, such as So in a way, you'd be trading one small difference for a larger inconsistency. |
Would it be possible to define the result type of br_if and br_table not based on the types of the target blocks, but based on the input value that is popped from the stack? This type is always known, so we would not have to do a sub-type calculation. |
That's the alternative I just described, probably a bit obscured. That wouldn't work in all similar cases (esp. select), so would ultimately lead to a more severe inconsistency than the one you're pointing out. Do you have a use case for this? |
Sorry, I should have read your reply more carefully. I don't understand though why the validation rules of I don't have a use case for this. However, the difference between |
The general scheme are instructions with typing rules of the form
This includes
However, this breaks down as soon as there are multiple occurrences of I'm not sure I see the problem with the V8 implementation. Looking at the code, it seems like all you'd have to do is popping the old argument(s) and pushing the refined type(s) at the end of the ExprBrIf case (see also the algorithm in the spec appendix). That may seem unnecessary from the perspective of your particular algorithm, but only when viewing the wider question through that particular lense. |
I have two use-cases for you. Assume you have 3 types A, B, C, with A is a sub-type of B, and B is a sub-type of C. The same function implemented with br_if does not validate.
From a stack point of view, both version should validate. On top of the stack is a value of type A, which can be consumed both as type B and as type C. Another use case is multi-inheritance. Assume types A, B, C, with A being a sub-type of B and C, but B and C are unrelated. Then the following function would not validate with the current proposal, although from a stack point of view it should. This is just a generalization of the current case with the BOT type I guess.
|
Sure, but these are synthetic use cases. I can easily construct analogous examples for the other instructions mentioned before, including From the point of view of the type system, this form of "covariance" is more involved, and it seems undesirable to introduce it in some cases but not the others, which is what we would have to do. So I prefer to stay on the conservative side, until it really proves too limited in practice. |
Thank you for the information. I adjusted my implementation now accordingly. |
`memory.init`, `memory.copy`, `memory.fill`, `table.init`, and `table.copy` should all fail if their ranges are out-of-bounds, even if the count is zero, similar to for active segments. See the discussions here: WebAssembly/design#897, WebAssembly/bulk-memory-operations#11.
With the recent change to introduce the bottom type, the validation rules for
br_table
changed. However,br_if
did not get changed accordingly.Consider the following two functions, the first function uses
br_table
, with one additional block to simulate the fall-through ofbr_if
. The second function usesbr_if
directly.(func (result f32)
(block (result f32)
(block (result i32)
unreachable
br_table 0 1 1
)
f32.convert_i32_u
)
)
(func (result f32)
(block (result f32)
unreachable
br_if 0
f32.convert_i32_u
)
)
The function with
br_table
validates, because the result type of thebr_table
instruction isBOT
. The function withbr_if
, however, does not validate. Forbr_if
the result type of the fall-through case is not considered when its result type is calculated.Should we adjust the validation of br_if to match the validation of br_table?
The text was updated successfully, but these errors were encountered: