diff options
author | Alon Zakai <alonzakai@gmail.com> | 2017-09-05 19:26:19 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-09-05 19:26:19 -0700 |
commit | c0f21e10a1166829afd34c4fb06366d7430802bb (patch) | |
tree | 518bbe8c8746679b3adf678940e52158e77b5ede /src/wasm/wasm-validator.cpp | |
parent | 4f58e1e666cff6f1e61d888279dba42d1be14251 (diff) | |
download | binaryen-c0f21e10a1166829afd34c4fb06366d7430802bb.tar.gz binaryen-c0f21e10a1166829afd34c4fb06366d7430802bb.tar.bz2 binaryen-c0f21e10a1166829afd34c4fb06366d7430802bb.zip |
Return to more structured type rules for block and if (#1148)
* if a block has a concrete final element (or a break with a value), then even if it has an unreachable child, keep it with that concrete type. this means we no longe allow the silly case of a block with an unreachable in the middle and a concrete as the final element while the block is unreachable - after this change, the block would have the type of the final element
* if an if has a concrete element in one arm, make it have that type as a result, even if the if condition is unreachable, to parallel block
* make type rules for brs and switches simpler, ignore whether they are reachable or not. whether they are dead code should not affect how they influence other types in our IR.
Diffstat (limited to 'src/wasm/wasm-validator.cpp')
-rw-r--r-- | src/wasm/wasm-validator.cpp | 20 |
1 files changed, 11 insertions, 9 deletions
diff --git a/src/wasm/wasm-validator.cpp b/src/wasm/wasm-validator.cpp index e30661e8f..877232521 100644 --- a/src/wasm/wasm-validator.cpp +++ b/src/wasm/wasm-validator.cpp @@ -70,9 +70,7 @@ void WasmValidator::visitBlock(Block *curr) { if (curr->list.size() > 0) { auto backType = curr->list.back()->type; if (!isConcreteWasmType(curr->type)) { - if (isConcreteWasmType(backType)) { - shouldBeTrue(curr->type == unreachable, curr, "block with no value and a last element with a value must be unreachable"); - } + shouldBeFalse(isConcreteWasmType(backType), curr, "if block is not returning a value, final element should not flow out a value"); } else { if (isConcreteWasmType(backType)) { shouldBeEqual(curr->type, backType, curr, "block with value and last element with value must match types"); @@ -118,15 +116,19 @@ void WasmValidator::visitIf(If *curr) { shouldBeEqual(curr->ifFalse->type, unreachable, curr, "unreachable if-else must have unreachable false"); } } + if (isConcreteWasmType(curr->ifTrue->type)) { + shouldBeEqual(curr->type, curr->ifTrue->type, curr, "if type must match concrete ifTrue"); + shouldBeEqualOrFirstIsUnreachable(curr->ifFalse->type, curr->ifTrue->type, curr, "other arm must match concrete ifTrue"); + } + if (isConcreteWasmType(curr->ifFalse->type)) { + shouldBeEqual(curr->type, curr->ifFalse->type, curr, "if type must match concrete ifFalse"); + shouldBeEqualOrFirstIsUnreachable(curr->ifTrue->type, curr->ifFalse->type, curr, "other arm must match concrete ifFalse"); + } } } void WasmValidator::noteBreak(Name name, Expression* value, Expression* curr) { - if (!BranchUtils::isBranchTaken(curr)) { - // if not actually taken, just note the name - namedBreakTargets.insert(name); - return; - } + namedBreakTargets.insert(name); WasmType valueType = none; Index arity = 0; if (value) { @@ -548,7 +550,7 @@ void WasmValidator::visitFunction(Function *curr) { if (returnType != unreachable) { shouldBeEqual(curr->result, returnType, curr->body, "function result must match, if function has returns"); } - if (!shouldBeTrue(namedBreakTargets.empty(), curr->body, "all named break targets must exist (even if not taken)") && !quiet) { + if (!shouldBeTrue(namedBreakTargets.empty(), curr->body, "all named break targets must exist") && !quiet) { std::cerr << "(on label " << *namedBreakTargets.begin() << ")\n"; } returnType = unreachable; |