Skip to content

Commit 3de52df

Browse files
committed
new validation checks for upcoming spec tests
1 parent 816ec66 commit 3de52df

7 files changed

+85
-56
lines changed

src/wasm-s-parser.h

+2-1
Original file line numberDiff line numberDiff line change
@@ -1402,9 +1402,10 @@ class SExpressionWasmBuilder {
14021402
}
14031403

14041404
void parseData(Element& s) {
1405+
if (!hasMemory) throw ParseException("data but no memory");
14051406
Index i = 1;
14061407
Expression* offset;
1407-
if (s[i]->isList()) {
1408+
if (i < s.size() && s[i]->isList()) {
14081409
// there is an init expression
14091410
offset = parseExpression(s[i++]);
14101411
} else {

src/wasm-validator.h

+32-4
Original file line numberDiff line numberDiff line change
@@ -197,11 +197,11 @@ struct WasmValidator : public PostWalker<WasmValidator, Visitor<WasmValidator>>
197197
}
198198
}
199199
void visitLoad(Load *curr) {
200-
validateAlignment(curr->align);
200+
validateAlignment(curr->align, curr->type, curr->bytes);
201201
shouldBeEqualOrFirstIsUnreachable(curr->ptr->type, i32, curr, "load pointer type must be i32");
202202
}
203203
void visitStore(Store *curr) {
204-
validateAlignment(curr->align);
204+
validateAlignment(curr->align, curr->type, curr->bytes);
205205
shouldBeEqualOrFirstIsUnreachable(curr->ptr->type, i32, curr, "store pointer type must be i32");
206206
shouldBeUnequal(curr->value->type, none, curr, "store value type must not be none");
207207
shouldBeEqualOrFirstIsUnreachable(curr->value->type, curr->valueType, curr, "store value type must match");
@@ -351,12 +351,26 @@ struct WasmValidator : public PostWalker<WasmValidator, Visitor<WasmValidator>>
351351
}
352352

353353
bool isConstant(Expression* curr) {
354-
return curr->is<Const>();
354+
return curr->is<Const>() || curr->is<GetGlobal>();
355355
}
356356

357357
void visitMemory(Memory *curr) {
358358
shouldBeFalse(curr->initial > curr->max, "memory", "memory max >= initial");
359359
shouldBeTrue(curr->max <= Memory::kMaxSize, "memory", "max memory must be <= 4GB");
360+
Index mustBeGreaterOrEqual = 0;
361+
for (auto& segment : curr->segments) {
362+
if (!shouldBeEqual(segment.offset->type, i32, segment.offset, "segment offset should be i32")) continue;
363+
shouldBeTrue(isConstant(segment.offset), segment.offset, "segment offset should be constant");
364+
Index size = segment.data.size();
365+
shouldBeTrue(size <= curr->initial * Memory::kPageSize, segment.data.size(), "segment size should fit in memory");
366+
if (segment.offset->is<Const>()) {
367+
Index start = segment.offset->cast<Const>()->value.geti32();
368+
Index end = start + size;
369+
shouldBeTrue(end <= curr->initial * Memory::kPageSize, segment.data.size(), "segment size should fit in memory");
370+
shouldBeTrue(start >= mustBeGreaterOrEqual, segment.data.size(), "segment size should fit in memory");
371+
mustBeGreaterOrEqual = end;
372+
}
373+
}
360374
}
361375
void visitTable(Table* curr) {
362376
for (auto& segment : curr->segments) {
@@ -476,7 +490,7 @@ struct WasmValidator : public PostWalker<WasmValidator, Visitor<WasmValidator>>
476490
return true;
477491
}
478492

479-
void validateAlignment(size_t align) {
493+
void validateAlignment(size_t align, WasmType type, Index bytes) {
480494
switch (align) {
481495
case 1:
482496
case 2:
@@ -488,6 +502,20 @@ struct WasmValidator : public PostWalker<WasmValidator, Visitor<WasmValidator>>
488502
break;
489503
}
490504
}
505+
shouldBeTrue(align <= bytes, align, "alignment must not exceed natural");
506+
switch (type) {
507+
case i32:
508+
case f32: {
509+
shouldBeTrue(align <= 4, align, "alignment must not exceed natural");
510+
break;
511+
}
512+
case i64:
513+
case f64: {
514+
shouldBeTrue(align <= 8, align, "alignment must not exceed natural");
515+
break;
516+
}
517+
default: {}
518+
}
491519
}
492520
};
493521

test/example/c-api-kitchen-sink.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -209,7 +209,7 @@ void test_core() {
209209
BinaryenSetLocal(module, 0, makeInt32(module, 101)),
210210
BinaryenDrop(module, BinaryenTeeLocal(module, 0, makeInt32(module, 102))),
211211
BinaryenLoad(module, 4, 0, 0, 0, BinaryenInt32(), makeInt32(module, 1)),
212-
BinaryenLoad(module, 1, 1, 2, 4, BinaryenInt64(), makeInt32(module, 8)),
212+
BinaryenLoad(module, 2, 1, 2, 1, BinaryenInt64(), makeInt32(module, 8)),
213213
BinaryenLoad(module, 4, 0, 0, 0, BinaryenFloat32(), makeInt32(module, 2)),
214214
BinaryenLoad(module, 8, 0, 2, 8, BinaryenFloat64(), makeInt32(module, 9)),
215215
BinaryenStore(module, 4, 0, 0, temp13, temp14, BinaryenInt32()),

test/example/c-api-kitchen-sink.txt

+3-3
Original file line numberDiff line numberDiff line change
@@ -486,7 +486,7 @@ BinaryenFloat64: 4
486486
)
487487
)
488488
(drop
489-
(i64.load8_s offset=2 align=4
489+
(i64.load16_s offset=2 align=1
490490
(i32.const 8)
491491
)
492492
)
@@ -1528,7 +1528,7 @@ int main() {
15281528
expressions[228] = BinaryenConst(the_module, BinaryenLiteralInt32(1));
15291529
expressions[229] = BinaryenLoad(the_module, 4, 0, 0, 0, 1, expressions[228]);
15301530
expressions[230] = BinaryenConst(the_module, BinaryenLiteralInt32(8));
1531-
expressions[231] = BinaryenLoad(the_module, 1, 1, 2, 4, 2, expressions[230]);
1531+
expressions[231] = BinaryenLoad(the_module, 2, 1, 2, 1, 2, expressions[230]);
15321532
expressions[232] = BinaryenConst(the_module, BinaryenLiteralInt32(2));
15331533
expressions[233] = BinaryenLoad(the_module, 4, 0, 0, 0, 3, expressions[232]);
15341534
expressions[234] = BinaryenConst(the_module, BinaryenLiteralInt32(9));
@@ -2077,7 +2077,7 @@ int main() {
20772077
)
20782078
)
20792079
(drop
2080-
(i64.load8_s offset=2 align=4
2080+
(i64.load16_s offset=2 align=1
20812081
(i32.const 8)
20822082
)
20832083
)

test/example/c-api-kitchen-sink.txt.txt

+1-1
Original file line numberDiff line numberDiff line change
@@ -481,7 +481,7 @@
481481
)
482482
)
483483
(drop
484-
(i64.load8_s offset=2 align=4
484+
(i64.load16_s offset=2 align=1
485485
(i32.const 8)
486486
)
487487
)

test/passes/duplicate-function-elimination.txt

+22-22
Original file line numberDiff line numberDiff line change
@@ -507,7 +507,7 @@
507507
)
508508
)
509509
(drop
510-
(i32.load8_s offset=3 align=2
510+
(i32.load16_s offset=3
511511
(i32.const 0)
512512
)
513513
)
@@ -518,14 +518,14 @@
518518
(type $0 (func))
519519
(func $keep2 (type $0)
520520
(drop
521-
(i32.load16_s offset=3
521+
(i32.load offset=3
522522
(i32.const 0)
523523
)
524524
)
525525
)
526526
(func $other (type $0)
527527
(drop
528-
(i32.load8_s offset=3 align=2
528+
(i32.load16_s offset=3
529529
(i32.const 0)
530530
)
531531
)
@@ -536,14 +536,14 @@
536536
(type $0 (func))
537537
(func $keep2 (type $0)
538538
(drop
539-
(i32.load8_s offset=3
539+
(i32.load16_s offset=3
540540
(i32.const 0)
541541
)
542542
)
543543
)
544544
(func $other (type $0)
545545
(drop
546-
(i32.load8_s offset=3 align=2
546+
(i32.load16_s offset=3 align=1
547547
(i32.const 0)
548548
)
549549
)
@@ -554,14 +554,14 @@
554554
(type $0 (func))
555555
(func $keep2 (type $0)
556556
(drop
557-
(i32.load8_s align=2
557+
(i32.load16_s
558558
(i32.const 0)
559559
)
560560
)
561561
)
562562
(func $other (type $0)
563563
(drop
564-
(i32.load8_s offset=3 align=2
564+
(i32.load16_s offset=3
565565
(i32.const 0)
566566
)
567567
)
@@ -572,14 +572,14 @@
572572
(type $0 (func))
573573
(func $keep2 (type $0)
574574
(drop
575-
(i32.load8_s offset=3 align=2
575+
(i32.load16_s offset=3
576576
(i32.const 0)
577577
)
578578
)
579579
)
580580
(func $other (type $0)
581581
(drop
582-
(i32.load8_s offset=3 align=2
582+
(i32.load16_s offset=3
583583
(i32.const 1)
584584
)
585585
)
@@ -590,14 +590,14 @@
590590
(type $0 (func))
591591
(func $keep2 (type $0)
592592
(drop
593-
(i32.load8_u offset=3 align=2
593+
(i32.load16_u offset=3
594594
(i32.const 0)
595595
)
596596
)
597597
)
598598
(func $other (type $0)
599599
(drop
600-
(i32.load8_s offset=3 align=2
600+
(i32.load16_s offset=3
601601
(i32.const 0)
602602
)
603603
)
@@ -611,7 +611,7 @@
611611
(i32.const 0)
612612
(i32.const 100)
613613
)
614-
(i32.store8 offset=3 align=2
614+
(i32.store16 offset=3
615615
(i32.const 0)
616616
(i32.const 100)
617617
)
@@ -621,13 +621,13 @@
621621
(memory 10)
622622
(type $0 (func))
623623
(func $keep2 (type $0)
624-
(i32.store16 offset=3
624+
(i32.store offset=3
625625
(i32.const 0)
626626
(i32.const 100)
627627
)
628628
)
629629
(func $other (type $0)
630-
(i32.store8 offset=3 align=2
630+
(i32.store16 offset=3
631631
(i32.const 0)
632632
(i32.const 100)
633633
)
@@ -637,13 +637,13 @@
637637
(memory 10)
638638
(type $0 (func))
639639
(func $keep2 (type $0)
640-
(i32.store8 offset=3
640+
(i32.store16 offset=3
641641
(i32.const 0)
642642
(i32.const 100)
643643
)
644644
)
645645
(func $other (type $0)
646-
(i32.store8 offset=3 align=2
646+
(i32.store16 offset=3 align=1
647647
(i32.const 0)
648648
(i32.const 100)
649649
)
@@ -653,13 +653,13 @@
653653
(memory 10)
654654
(type $0 (func))
655655
(func $keep2 (type $0)
656-
(i32.store8 align=2
656+
(i32.store16
657657
(i32.const 0)
658658
(i32.const 100)
659659
)
660660
)
661661
(func $other (type $0)
662-
(i32.store8 offset=3 align=2
662+
(i32.store16 offset=3
663663
(i32.const 0)
664664
(i32.const 100)
665665
)
@@ -669,13 +669,13 @@
669669
(memory 10)
670670
(type $0 (func))
671671
(func $keep2 (type $0)
672-
(i32.store8 offset=3 align=2
672+
(i32.store16 offset=3
673673
(i32.const 0)
674674
(i32.const 100)
675675
)
676676
)
677677
(func $other (type $0)
678-
(i32.store8 offset=3 align=2
678+
(i32.store16 offset=3
679679
(i32.const 1)
680680
(i32.const 100)
681681
)
@@ -685,13 +685,13 @@
685685
(memory 10)
686686
(type $0 (func))
687687
(func $keep2 (type $0)
688-
(i32.store8 offset=3 align=2
688+
(i32.store16 offset=3
689689
(i32.const 0)
690690
(i32.const 100)
691691
)
692692
)
693693
(func $other (type $0)
694-
(i32.store8 offset=3 align=2
694+
(i32.store16 offset=3
695695
(i32.const 0)
696696
(i32.const 101)
697697
)

0 commit comments

Comments
 (0)