summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/wasm-s-parser.h3
-rw-r--r--src/wasm-validator.h36
-rw-r--r--test/example/c-api-kitchen-sink.c2
-rw-r--r--test/example/c-api-kitchen-sink.txt6
-rw-r--r--test/example/c-api-kitchen-sink.txt.txt2
-rw-r--r--test/passes/duplicate-function-elimination.txt44
-rw-r--r--test/passes/duplicate-function-elimination.wast48
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)
)