@@ -197,11 +197,11 @@ struct WasmValidator : public PostWalker<WasmValidator, Visitor<WasmValidator>>
197
197
}
198
198
}
199
199
void visitLoad (Load *curr) {
200
- validateAlignment (curr->align );
200
+ validateAlignment (curr->align , curr-> type , curr-> bytes );
201
201
shouldBeEqualOrFirstIsUnreachable (curr->ptr ->type , i32, curr, " load pointer type must be i32" );
202
202
}
203
203
void visitStore (Store *curr) {
204
- validateAlignment (curr->align );
204
+ validateAlignment (curr->align , curr-> type , curr-> bytes );
205
205
shouldBeEqualOrFirstIsUnreachable (curr->ptr ->type , i32, curr, " store pointer type must be i32" );
206
206
shouldBeUnequal (curr->value ->type , none, curr, " store value type must not be none" );
207
207
shouldBeEqualOrFirstIsUnreachable (curr->value ->type , curr->valueType , curr, " store value type must match" );
@@ -351,12 +351,26 @@ struct WasmValidator : public PostWalker<WasmValidator, Visitor<WasmValidator>>
351
351
}
352
352
353
353
bool isConstant (Expression* curr) {
354
- return curr->is <Const>();
354
+ return curr->is <Const>() || curr-> is <GetGlobal>() ;
355
355
}
356
356
357
357
void visitMemory (Memory *curr) {
358
358
shouldBeFalse (curr->initial > curr->max , " memory" , " memory max >= initial" );
359
359
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
+ }
360
374
}
361
375
void visitTable (Table* curr) {
362
376
for (auto & segment : curr->segments ) {
@@ -476,7 +490,7 @@ struct WasmValidator : public PostWalker<WasmValidator, Visitor<WasmValidator>>
476
490
return true ;
477
491
}
478
492
479
- void validateAlignment (size_t align) {
493
+ void validateAlignment (size_t align, WasmType type, Index bytes ) {
480
494
switch (align) {
481
495
case 1 :
482
496
case 2 :
@@ -488,6 +502,20 @@ struct WasmValidator : public PostWalker<WasmValidator, Visitor<WasmValidator>>
488
502
break ;
489
503
}
490
504
}
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
+ }
491
519
}
492
520
};
493
521
0 commit comments