diff options
-rw-r--r-- | src/wasm-validator.h | 115 | ||||
-rw-r--r-- | test/passes/Oz.txt | 1 | ||||
-rw-r--r-- | test/passes/Oz.wast | 1 | ||||
-rw-r--r-- | test/passes/dce.wast | 1 | ||||
-rw-r--r-- | test/passes/local-cse.txt | 1 | ||||
-rw-r--r-- | test/passes/local-cse.wast | 1 | ||||
-rw-r--r-- | test/passes/remove-unused-brs_shrink-level=1.txt | 1 | ||||
-rw-r--r-- | test/passes/remove-unused-brs_shrink-level=1.wast | 1 | ||||
-rw-r--r-- | test/passes/remove-unused-brs_shrink-level=1_ignore-implicit-traps.txt | 1 | ||||
-rw-r--r-- | test/passes/remove-unused-brs_shrink-level=1_ignore-implicit-traps.wast | 1 |
10 files changed, 118 insertions, 6 deletions
diff --git a/src/wasm-validator.h b/src/wasm-validator.h index 4631a63b8..00a35fb24 100644 --- a/src/wasm-validator.h +++ b/src/wasm-validator.h @@ -128,9 +128,18 @@ public: } } } - if (!isConcreteWasmType(curr->type) && curr->list.size() > 0) { - if (isConcreteWasmType(curr->list.back()->type)) { - shouldBeTrue(curr->type == unreachable, curr, "block with no value and a last element with a value must be unreachable"); + 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"); + } + } else { + if (isConcreteWasmType(backType)) { + shouldBeEqual(curr->type, backType, curr, "block with value and last element with value must match types"); + } else { + shouldBeUnequal(backType, none, curr, "block with value must not have last element that is none"); + } } } } @@ -155,7 +164,7 @@ public: } void visitIf(If *curr) { - shouldBeTrue(curr->condition->type == unreachable || curr->condition->type == i32 || curr->condition->type == i64, curr, "if condition must be valid"); + shouldBeTrue(curr->condition->type == unreachable || curr->condition->type == i32, curr, "if condition must be valid"); if (!curr->ifFalse) { shouldBeFalse(isConcreteWasmType(curr->ifTrue->type), curr, "if without else must not return a value in body"); if (curr->condition->type != unreachable) { @@ -284,6 +293,97 @@ public: if (curr->left->type != unreachable && curr->right->type != unreachable) { shouldBeEqual(curr->left->type, curr->right->type, curr, "binary child types must be equal"); } + switch (curr->op) { + case AddInt32: + case SubInt32: + case MulInt32: + case DivSInt32: + case DivUInt32: + case RemSInt32: + case RemUInt32: + case AndInt32: + case OrInt32: + case XorInt32: + case ShlInt32: + case ShrUInt32: + case ShrSInt32: + case RotLInt32: + case RotRInt32: + case EqInt32: + case NeInt32: + case LtSInt32: + case LtUInt32: + case LeSInt32: + case LeUInt32: + case GtSInt32: + case GtUInt32: + case GeSInt32: + case GeUInt32: { + shouldBeEqualOrFirstIsUnreachable(curr->left->type, i32, curr, "i32 op"); + break; + } + case AddInt64: + case SubInt64: + case MulInt64: + case DivSInt64: + case DivUInt64: + case RemSInt64: + case RemUInt64: + case AndInt64: + case OrInt64: + case XorInt64: + case ShlInt64: + case ShrUInt64: + case ShrSInt64: + case RotLInt64: + case RotRInt64: + case EqInt64: + case NeInt64: + case LtSInt64: + case LtUInt64: + case LeSInt64: + case LeUInt64: + case GtSInt64: + case GtUInt64: + case GeSInt64: + case GeUInt64: { + shouldBeEqualOrFirstIsUnreachable(curr->left->type, i64, curr, "i64 op"); + break; + } + case AddFloat32: + case SubFloat32: + case MulFloat32: + case DivFloat32: + case CopySignFloat32: + case MinFloat32: + case MaxFloat32: + case EqFloat32: + case NeFloat32: + case LtFloat32: + case LeFloat32: + case GtFloat32: + case GeFloat32: { + shouldBeEqualOrFirstIsUnreachable(curr->left->type, f32, curr, "f32 op"); + break; + } + case AddFloat64: + case SubFloat64: + case MulFloat64: + case DivFloat64: + case CopySignFloat64: + case MinFloat64: + case MaxFloat64: + case EqFloat64: + case NeFloat64: + case LtFloat64: + case LeFloat64: + case GtFloat64: + case GeFloat64: { + shouldBeEqualOrFirstIsUnreachable(curr->left->type, f64, curr, "f64 op"); + break; + } + default: WASM_UNREACHABLE(); + } } void visitUnary(Unary *curr) { shouldBeUnequal(curr->value->type, none, curr, "unaries must not receive a none as their input"); @@ -322,9 +422,12 @@ public: } break; } - case EqZInt32: + case EqZInt32: { + shouldBeTrue(curr->value->type == i32, curr, "i32.eqz input must be i32"); + break; + } case EqZInt64: { - shouldBeTrue(curr->value->type == i32 || curr->value->type == i64, curr, "eqz input must be i32 or i64"); + shouldBeTrue(curr->value->type == i64, curr, "i64.eqz input must be i64"); break; } case ExtendSInt32: shouldBeEqual(curr->value->type, i32, curr, "extend type must be correct"); break; diff --git a/test/passes/Oz.txt b/test/passes/Oz.txt index fe47b089e..c67106326 100644 --- a/test/passes/Oz.txt +++ b/test/passes/Oz.txt @@ -51,5 +51,6 @@ ) ) ) + (i32.const 0) ) ) diff --git a/test/passes/Oz.wast b/test/passes/Oz.wast index fc465669e..abfd880d5 100644 --- a/test/passes/Oz.wast +++ b/test/passes/Oz.wast @@ -52,6 +52,7 @@ ) ) ) + (i32.const 0) ) ) ) diff --git a/test/passes/dce.wast b/test/passes/dce.wast index b7d903e6b..0bed1e8ff 100644 --- a/test/passes/dce.wast +++ b/test/passes/dce.wast @@ -440,5 +440,6 @@ (i32.const 0) ) (nop) + (i32.const 0) ) ) diff --git a/test/passes/local-cse.txt b/test/passes/local-cse.txt index 9a7f4445e..266008bd4 100644 --- a/test/passes/local-cse.txt +++ b/test/passes/local-cse.txt @@ -178,6 +178,7 @@ ) ) ) + (i32.const 0) ) ) ) diff --git a/test/passes/local-cse.wast b/test/passes/local-cse.wast index b1155ce9d..26a25d236 100644 --- a/test/passes/local-cse.wast +++ b/test/passes/local-cse.wast @@ -158,6 +158,7 @@ ) ) ) + (i32.const 0) ) ) ) diff --git a/test/passes/remove-unused-brs_shrink-level=1.txt b/test/passes/remove-unused-brs_shrink-level=1.txt index 923d45ae9..1f837ab0c 100644 --- a/test/passes/remove-unused-brs_shrink-level=1.txt +++ b/test/passes/remove-unused-brs_shrink-level=1.txt @@ -43,6 +43,7 @@ (i32.const 27) ) ) + (i32.const 0) ) (func $join-br_ifs (type $1) (block $out diff --git a/test/passes/remove-unused-brs_shrink-level=1.wast b/test/passes/remove-unused-brs_shrink-level=1.wast index e48ced178..c0ec7d4cd 100644 --- a/test/passes/remove-unused-brs_shrink-level=1.wast +++ b/test/passes/remove-unused-brs_shrink-level=1.wast @@ -36,6 +36,7 @@ (i32.const 27) ) ) + (i32.const 0) ) (func $join-br_ifs (block $out diff --git a/test/passes/remove-unused-brs_shrink-level=1_ignore-implicit-traps.txt b/test/passes/remove-unused-brs_shrink-level=1_ignore-implicit-traps.txt index a4ba5997d..51c096755 100644 --- a/test/passes/remove-unused-brs_shrink-level=1_ignore-implicit-traps.txt +++ b/test/passes/remove-unused-brs_shrink-level=1_ignore-implicit-traps.txt @@ -43,6 +43,7 @@ (i32.const 1) ) ) + (i32.const 0) ) (func $join-br_ifs (type $1) (block $out diff --git a/test/passes/remove-unused-brs_shrink-level=1_ignore-implicit-traps.wast b/test/passes/remove-unused-brs_shrink-level=1_ignore-implicit-traps.wast index e48ced178..c0ec7d4cd 100644 --- a/test/passes/remove-unused-brs_shrink-level=1_ignore-implicit-traps.wast +++ b/test/passes/remove-unused-brs_shrink-level=1_ignore-implicit-traps.wast @@ -36,6 +36,7 @@ (i32.const 27) ) ) + (i32.const 0) ) (func $join-br_ifs (block $out |