diff options
-rw-r--r-- | src/wasm-s-parser.h | 3 | ||||
-rw-r--r-- | src/wasm-validator.h | 36 | ||||
-rw-r--r-- | test/example/c-api-kitchen-sink.c | 2 | ||||
-rw-r--r-- | test/example/c-api-kitchen-sink.txt | 6 | ||||
-rw-r--r-- | test/example/c-api-kitchen-sink.txt.txt | 2 | ||||
-rw-r--r-- | test/passes/duplicate-function-elimination.txt | 44 | ||||
-rw-r--r-- | test/passes/duplicate-function-elimination.wast | 48 |
7 files changed, 85 insertions, 56 deletions
diff --git a/src/wasm-s-parser.h b/src/wasm-s-parser.h index 3d57c5ada..9abdea744 100644 --- a/src/wasm-s-parser.h +++ b/src/wasm-s-parser.h @@ -1402,9 +1402,10 @@ private: } void parseData(Element& s) { + if (!hasMemory) throw ParseException("data but no memory"); Index i = 1; Expression* offset; - if (s[i]->isList()) { + if (i < s.size() && s[i]->isList()) { // there is an init expression offset = parseExpression(s[i++]); } else { diff --git a/src/wasm-validator.h b/src/wasm-validator.h index 92ae24688..58a30f9a3 100644 --- a/src/wasm-validator.h +++ b/src/wasm-validator.h @@ -197,11 +197,11 @@ public: } } void visitLoad(Load *curr) { - validateAlignment(curr->align); + validateAlignment(curr->align, curr->type, curr->bytes); shouldBeEqualOrFirstIsUnreachable(curr->ptr->type, i32, curr, "load pointer type must be i32"); } void visitStore(Store *curr) { - validateAlignment(curr->align); + validateAlignment(curr->align, curr->type, curr->bytes); shouldBeEqualOrFirstIsUnreachable(curr->ptr->type, i32, curr, "store pointer type must be i32"); shouldBeUnequal(curr->value->type, none, curr, "store value type must not be none"); shouldBeEqualOrFirstIsUnreachable(curr->value->type, curr->valueType, curr, "store value type must match"); @@ -351,12 +351,26 @@ public: } bool isConstant(Expression* curr) { - return curr->is<Const>(); + return curr->is<Const>() || curr->is<GetGlobal>(); } void visitMemory(Memory *curr) { shouldBeFalse(curr->initial > curr->max, "memory", "memory max >= initial"); shouldBeTrue(curr->max <= Memory::kMaxSize, "memory", "max memory must be <= 4GB"); + Index mustBeGreaterOrEqual = 0; + for (auto& segment : curr->segments) { + if (!shouldBeEqual(segment.offset->type, i32, segment.offset, "segment offset should be i32")) continue; + shouldBeTrue(isConstant(segment.offset), segment.offset, "segment offset should be constant"); + Index size = segment.data.size(); + shouldBeTrue(size <= curr->initial * Memory::kPageSize, segment.data.size(), "segment size should fit in memory"); + if (segment.offset->is<Const>()) { + Index start = segment.offset->cast<Const>()->value.geti32(); + Index end = start + size; + shouldBeTrue(end <= curr->initial * Memory::kPageSize, segment.data.size(), "segment size should fit in memory"); + shouldBeTrue(start >= mustBeGreaterOrEqual, segment.data.size(), "segment size should fit in memory"); + mustBeGreaterOrEqual = end; + } + } } void visitTable(Table* curr) { for (auto& segment : curr->segments) { @@ -476,7 +490,7 @@ private: return true; } - void validateAlignment(size_t align) { + void validateAlignment(size_t align, WasmType type, Index bytes) { switch (align) { case 1: case 2: @@ -488,6 +502,20 @@ private: break; } } + shouldBeTrue(align <= bytes, align, "alignment must not exceed natural"); + switch (type) { + case i32: + case f32: { + shouldBeTrue(align <= 4, align, "alignment must not exceed natural"); + break; + } + case i64: + case f64: { + shouldBeTrue(align <= 8, align, "alignment must not exceed natural"); + break; + } + default: {} + } } }; diff --git a/test/example/c-api-kitchen-sink.c b/test/example/c-api-kitchen-sink.c index f60b62785..77e7f0b05 100644 --- a/test/example/c-api-kitchen-sink.c +++ b/test/example/c-api-kitchen-sink.c @@ -209,7 +209,7 @@ void test_core() { BinaryenSetLocal(module, 0, makeInt32(module, 101)), BinaryenDrop(module, BinaryenTeeLocal(module, 0, makeInt32(module, 102))), BinaryenLoad(module, 4, 0, 0, 0, BinaryenInt32(), makeInt32(module, 1)), - BinaryenLoad(module, 1, 1, 2, 4, BinaryenInt64(), makeInt32(module, 8)), + BinaryenLoad(module, 2, 1, 2, 1, BinaryenInt64(), makeInt32(module, 8)), BinaryenLoad(module, 4, 0, 0, 0, BinaryenFloat32(), makeInt32(module, 2)), BinaryenLoad(module, 8, 0, 2, 8, BinaryenFloat64(), makeInt32(module, 9)), BinaryenStore(module, 4, 0, 0, temp13, temp14, BinaryenInt32()), diff --git a/test/example/c-api-kitchen-sink.txt b/test/example/c-api-kitchen-sink.txt index f4bfa19e7..6544f9f33 100644 --- a/test/example/c-api-kitchen-sink.txt +++ b/test/example/c-api-kitchen-sink.txt @@ -486,7 +486,7 @@ BinaryenFloat64: 4 ) ) (drop - (i64.load8_s offset=2 align=4 + (i64.load16_s offset=2 align=1 (i32.const 8) ) ) @@ -1528,7 +1528,7 @@ int main() { expressions[228] = BinaryenConst(the_module, BinaryenLiteralInt32(1)); expressions[229] = BinaryenLoad(the_module, 4, 0, 0, 0, 1, expressions[228]); expressions[230] = BinaryenConst(the_module, BinaryenLiteralInt32(8)); - expressions[231] = BinaryenLoad(the_module, 1, 1, 2, 4, 2, expressions[230]); + expressions[231] = BinaryenLoad(the_module, 2, 1, 2, 1, 2, expressions[230]); expressions[232] = BinaryenConst(the_module, BinaryenLiteralInt32(2)); expressions[233] = BinaryenLoad(the_module, 4, 0, 0, 0, 3, expressions[232]); expressions[234] = BinaryenConst(the_module, BinaryenLiteralInt32(9)); @@ -2077,7 +2077,7 @@ int main() { ) ) (drop - (i64.load8_s offset=2 align=4 + (i64.load16_s offset=2 align=1 (i32.const 8) ) ) diff --git a/test/example/c-api-kitchen-sink.txt.txt b/test/example/c-api-kitchen-sink.txt.txt index d564ce7ca..b37814f89 100644 --- a/test/example/c-api-kitchen-sink.txt.txt +++ b/test/example/c-api-kitchen-sink.txt.txt @@ -481,7 +481,7 @@ ) ) (drop - (i64.load8_s offset=2 align=4 + (i64.load16_s offset=2 align=1 (i32.const 8) ) ) diff --git a/test/passes/duplicate-function-elimination.txt b/test/passes/duplicate-function-elimination.txt index e043300c4..c49f7fd6f 100644 --- a/test/passes/duplicate-function-elimination.txt +++ b/test/passes/duplicate-function-elimination.txt @@ -507,7 +507,7 @@ ) ) (drop - (i32.load8_s offset=3 align=2 + (i32.load16_s offset=3 (i32.const 0) ) ) @@ -518,14 +518,14 @@ (type $0 (func)) (func $keep2 (type $0) (drop - (i32.load16_s offset=3 + (i32.load offset=3 (i32.const 0) ) ) ) (func $other (type $0) (drop - (i32.load8_s offset=3 align=2 + (i32.load16_s offset=3 (i32.const 0) ) ) @@ -536,14 +536,14 @@ (type $0 (func)) (func $keep2 (type $0) (drop - (i32.load8_s offset=3 + (i32.load16_s offset=3 (i32.const 0) ) ) ) (func $other (type $0) (drop - (i32.load8_s offset=3 align=2 + (i32.load16_s offset=3 align=1 (i32.const 0) ) ) @@ -554,14 +554,14 @@ (type $0 (func)) (func $keep2 (type $0) (drop - (i32.load8_s align=2 + (i32.load16_s (i32.const 0) ) ) ) (func $other (type $0) (drop - (i32.load8_s offset=3 align=2 + (i32.load16_s offset=3 (i32.const 0) ) ) @@ -572,14 +572,14 @@ (type $0 (func)) (func $keep2 (type $0) (drop - (i32.load8_s offset=3 align=2 + (i32.load16_s offset=3 (i32.const 0) ) ) ) (func $other (type $0) (drop - (i32.load8_s offset=3 align=2 + (i32.load16_s offset=3 (i32.const 1) ) ) @@ -590,14 +590,14 @@ (type $0 (func)) (func $keep2 (type $0) (drop - (i32.load8_u offset=3 align=2 + (i32.load16_u offset=3 (i32.const 0) ) ) ) (func $other (type $0) (drop - (i32.load8_s offset=3 align=2 + (i32.load16_s offset=3 (i32.const 0) ) ) @@ -611,7 +611,7 @@ (i32.const 0) (i32.const 100) ) - (i32.store8 offset=3 align=2 + (i32.store16 offset=3 (i32.const 0) (i32.const 100) ) @@ -621,13 +621,13 @@ (memory 10) (type $0 (func)) (func $keep2 (type $0) - (i32.store16 offset=3 + (i32.store offset=3 (i32.const 0) (i32.const 100) ) ) (func $other (type $0) - (i32.store8 offset=3 align=2 + (i32.store16 offset=3 (i32.const 0) (i32.const 100) ) @@ -637,13 +637,13 @@ (memory 10) (type $0 (func)) (func $keep2 (type $0) - (i32.store8 offset=3 + (i32.store16 offset=3 (i32.const 0) (i32.const 100) ) ) (func $other (type $0) - (i32.store8 offset=3 align=2 + (i32.store16 offset=3 align=1 (i32.const 0) (i32.const 100) ) @@ -653,13 +653,13 @@ (memory 10) (type $0 (func)) (func $keep2 (type $0) - (i32.store8 align=2 + (i32.store16 (i32.const 0) (i32.const 100) ) ) (func $other (type $0) - (i32.store8 offset=3 align=2 + (i32.store16 offset=3 (i32.const 0) (i32.const 100) ) @@ -669,13 +669,13 @@ (memory 10) (type $0 (func)) (func $keep2 (type $0) - (i32.store8 offset=3 align=2 + (i32.store16 offset=3 (i32.const 0) (i32.const 100) ) ) (func $other (type $0) - (i32.store8 offset=3 align=2 + (i32.store16 offset=3 (i32.const 1) (i32.const 100) ) @@ -685,13 +685,13 @@ (memory 10) (type $0 (func)) (func $keep2 (type $0) - (i32.store8 offset=3 align=2 + (i32.store16 offset=3 (i32.const 0) (i32.const 100) ) ) (func $other (type $0) - (i32.store8 offset=3 align=2 + (i32.store16 offset=3 (i32.const 0) (i32.const 101) ) diff --git a/test/passes/duplicate-function-elimination.wast b/test/passes/duplicate-function-elimination.wast index 843e812f9..f72ef542e 100644 --- a/test/passes/duplicate-function-elimination.wast +++ b/test/passes/duplicate-function-elimination.wast @@ -593,7 +593,7 @@ ) ) (drop - (i32.load8_s offset=3 align=2 + (i32.load16_s offset=3 align=2 (i32.const 0) ) ) @@ -605,7 +605,7 @@ ) ) (drop - (i32.load8_s offset=3 align=2 + (i32.load16_s offset=3 align=2 (i32.const 0) ) ) @@ -616,14 +616,14 @@ (type $0 (func)) (func $keep2 (type $0) (drop - (i32.load16_s offset=3 + (i32.load offset=3 (i32.const 0) ) ) ) (func $other (type $0) (drop - (i32.load8_s offset=3 align=2 + (i32.load16_s offset=3 align=2 (i32.const 0) ) ) @@ -634,14 +634,14 @@ (type $0 (func)) (func $keep2 (type $0) (drop - (i32.load8_s offset=3 + (i32.load16_s offset=3 (i32.const 0) ) ) ) (func $other (type $0) (drop - (i32.load8_s offset=3 align=2 + (i32.load16_s offset=3 align=1 (i32.const 0) ) ) @@ -652,14 +652,14 @@ (type $0 (func)) (func $keep2 (type $0) (drop - (i32.load8_s align=2 + (i32.load16_s align=2 (i32.const 0) ) ) ) (func $other (type $0) (drop - (i32.load8_s offset=3 align=2 + (i32.load16_s offset=3 align=2 (i32.const 0) ) ) @@ -670,14 +670,14 @@ (type $0 (func)) (func $keep2 (type $0) (drop - (i32.load8_s offset=3 align=2 + (i32.load16_s offset=3 align=2 (i32.const 0) ) ) ) (func $other (type $0) (drop - (i32.load8_s offset=3 align=2 + (i32.load16_s offset=3 align=2 (i32.const 1) ) ) @@ -688,14 +688,14 @@ (type $0 (func)) (func $keep2 (type $0) (drop - (i32.load8_u offset=3 align=2 + (i32.load16_u offset=3 align=2 (i32.const 0) ) ) ) (func $other (type $0) (drop - (i32.load8_s offset=3 align=2 + (i32.load16_s offset=3 align=2 (i32.const 0) ) ) @@ -709,7 +709,7 @@ (i32.const 0) (i32.const 100) ) - (i32.store8 offset=3 align=2 + (i32.store16 offset=3 align=2 (i32.const 0) (i32.const 100) ) @@ -719,7 +719,7 @@ (i32.const 0) (i32.const 100) ) - (i32.store8 offset=3 align=2 + (i32.store16 offset=3 align=2 (i32.const 0) (i32.const 100) ) @@ -729,13 +729,13 @@ (memory 10) (type $0 (func)) (func $keep2 (type $0) - (i32.store16 offset=3 + (i32.store32 offset=3 (i32.const 0) (i32.const 100) ) ) (func $other (type $0) - (i32.store8 offset=3 align=2 + (i32.store16 offset=3 align=2 (i32.const 0) (i32.const 100) ) @@ -745,13 +745,13 @@ (memory 10) (type $0 (func)) (func $keep2 (type $0) - (i32.store8 offset=3 + (i32.store16 offset=3 (i32.const 0) (i32.const 100) ) ) (func $other (type $0) - (i32.store8 offset=3 align=2 + (i32.store16 offset=3 align=1 (i32.const 0) (i32.const 100) ) @@ -761,13 +761,13 @@ (memory 10) (type $0 (func)) (func $keep2 (type $0) - (i32.store8 align=2 + (i32.store16 align=2 (i32.const 0) (i32.const 100) ) ) (func $other (type $0) - (i32.store8 offset=3 align=2 + (i32.store16 offset=3 align=2 (i32.const 0) (i32.const 100) ) @@ -777,13 +777,13 @@ (memory 10) (type $0 (func)) (func $keep2 (type $0) - (i32.store8 offset=3 align=2 + (i32.store16 offset=3 align=2 (i32.const 0) (i32.const 100) ) ) (func $other (type $0) - (i32.store8 offset=3 align=2 + (i32.store16 offset=3 align=2 (i32.const 1) (i32.const 100) ) @@ -793,13 +793,13 @@ (memory 10) (type $0 (func)) (func $keep2 (type $0) - (i32.store8 offset=3 align=2 + (i32.store16 offset=3 align=2 (i32.const 0) (i32.const 100) ) ) (func $other (type $0) - (i32.store8 offset=3 align=2 + (i32.store16 offset=3 align=2 (i32.const 0) (i32.const 101) ) |