summaryrefslogtreecommitdiff
path: root/test/lit/help/wasm-as.test
diff options
context:
space:
mode:
authorThomas Lively <tlively@google.com>2024-04-16 10:43:50 -0700
committerGitHub <noreply@github.com>2024-04-16 10:43:50 -0700
commit359d5aa30ca8349fd38e6968350e7ab4280c1cbb (patch)
treec2e32021ae74c2dfa706dc4d4ebd4257d19ad2db /test/lit/help/wasm-as.test
parente29d77848b89846cf3519491fee581b507e3b194 (diff)
downloadbinaryen-359d5aa30ca8349fd38e6968350e7ab4280c1cbb.tar.gz
binaryen-359d5aa30ca8349fd38e6968350e7ab4280c1cbb.tar.bz2
binaryen-359d5aa30ca8349fd38e6968350e7ab4280c1cbb.zip
[Parser] Pop past unreachables where possible (#6489)
We previously would eagerly drop all concretely typed expressions on the stack when pushing an unreachable instruction. This was semantically correct and closely modeled the semantics of unreachable instructions, which implicitly drop the entire stack and start a new polymorphic stack. However, it also meant that the structure of the parsed IR did not match the structure of the folded input, which meant that tests involving unreachable children would not parse as intended, preventing the test from testing the intended behavior. For example, this wat: ```wasm (i32.add (i32.const 0) (unreachable) ) ``` Would previously parse into this IR: ```wasm (drop (i32.const 0) ) (i32.add (unreachable) (unreachable) ) ``` To fix this problem, we need to stop eagerly dropping stack values when encountering an unreachable instruction so we can still pop expressions pushed before the unreachable as direct children of later instructions. In the example above, we need to keep the `i32.const 0` on the stack so it is available to be popped and become a child of the `i32.add`. However, the naive solution of simply popping past unreachables would produce invalid IR in some cases. For example, consider this wat: ```wasm f32.const 0 unreachable i32.add ``` The naive solution would parse this wat into this IR: ```wasm (i32.add (f32.const 0) (unreachable) ) ``` But we do not want to parse an `i32.add` with an `f32`-typed child. Neither do we want to reject this input, since it is a perfectly valid Wasm fragment. In this case, we actually want the old behavior of dropping the `f32.const` and replacing it with another `unreachable` as the first child of the `i32.add`. To both match the input structure where possible and also gracefully fall back to the old behavior of dropping expressions prior to the unreachable, collect constraints on the types of each child for each kind of expression and compare them to the types of available expressions on the stack when an unreachable instruction will be popped. When the constraints are satisfied, pop expressions normally, even after popping the unreachable instruction. Otherwise, drop the instructions that precede the unreachable instruction to ensure we parse valid IR. To collect the constraints, add a new `ChildTyper` utility that calls a different callback for each kind of possible type constraint for each child. In the future, this utility can be used to simplify the validator as well.
Diffstat (limited to 'test/lit/help/wasm-as.test')
0 files changed, 0 insertions, 0 deletions