26
26
27
27
namespace wasm {
28
28
29
- namespace {
30
-
31
- } // anonymous namespace
32
-
33
29
TranslateToFuzzReader::TranslateToFuzzReader (Module& wasm,
34
30
std::vector<char >&& input,
35
31
bool closedWorld)
@@ -395,9 +391,12 @@ void TranslateToFuzzReader::setupMemory() {
395
391
396
392
auto & memory = wasm.memories [0 ];
397
393
if (wasm.features .hasBulkMemory ()) {
398
- size_t memCovered = 0 ;
394
+ size_t numSegments = upTo ( 8 ) ;
399
395
// need at least one segment for memory.inits
400
- size_t numSegments = upTo (8 ) + 1 ;
396
+ if (wasm.dataSegments .empty () && !numSegments) {
397
+ numSegments = 1 ;
398
+ }
399
+ size_t memCovered = 0 ;
401
400
for (size_t i = 0 ; i < numSegments; i++) {
402
401
auto segment = builder.makeDataSegment ();
403
402
segment->setName (Names::getValidDataSegmentName (wasm, Name::fromInt (i)),
@@ -417,19 +416,21 @@ void TranslateToFuzzReader::setupMemory() {
417
416
wasm.addDataSegment (std::move (segment));
418
417
}
419
418
} else {
420
- // init some data
421
- auto segment = builder.makeDataSegment ();
422
- segment->memory = memory->name ;
423
- segment->offset =
424
- builder.makeConst (Literal::makeFromInt32 (0 , memory->addressType ));
425
- segment->setName (Names::getValidDataSegmentName (wasm, Name::fromInt (0 )),
426
- false );
427
- auto num = upTo (fuzzParams->USABLE_MEMORY * 2 );
428
- for (size_t i = 0 ; i < num; i++) {
429
- auto value = upTo (512 );
430
- segment->data .push_back (value >= 256 ? 0 : (value & 0xff ));
419
+ // init some data, especially if none exists before
420
+ if (!oneIn (wasm.dataSegments .empty () ? 10 : 2 )) {
421
+ auto segment = builder.makeDataSegment ();
422
+ segment->memory = memory->name ;
423
+ segment->offset =
424
+ builder.makeConst (Literal::makeFromInt32 (0 , memory->addressType ));
425
+ segment->setName (Names::getValidDataSegmentName (wasm, Name::fromInt (0 )),
426
+ false );
427
+ auto num = upTo (fuzzParams->USABLE_MEMORY * 2 );
428
+ for (size_t i = 0 ; i < num; i++) {
429
+ auto value = upTo (512 );
430
+ segment->data .push_back (value >= 256 ? 0 : (value & 0xff ));
431
+ }
432
+ wasm.addDataSegment (std::move (segment));
431
433
}
432
- wasm.addDataSegment (std::move (segment));
433
434
}
434
435
}
435
436
@@ -588,17 +589,27 @@ void TranslateToFuzzReader::setupTables() {
588
589
// When EH is enabled, set up an exnref table.
589
590
if (wasm.features .hasExceptionHandling ()) {
590
591
Type exnref = Type (HeapType::exn, Nullable);
591
- Address initial = upTo (10 );
592
- Address max = oneIn (2 ) ? initial + upTo (4 ) : Memory::kUnlimitedSize ;
593
- auto tablePtr =
594
- builder.makeTable (Names::getValidTableName (wasm, " exnref_table" ),
595
- exnref,
596
- initial,
597
- max,
598
- Type::i32 ); // TODO: wasm64
599
- tablePtr->hasExplicitName = true ;
600
- table = wasm.addTable (std::move (tablePtr));
601
- exnrefTableName = table->name ;
592
+ auto iter =
593
+ std::find_if (wasm.tables .begin (), wasm.tables .end (), [&](auto & table) {
594
+ return table->type == exnref;
595
+ });
596
+ if (iter != wasm.tables .end ()) {
597
+ // Use the existing one.
598
+ exnrefTableName = iter->get ()->name ;
599
+ } else {
600
+ // Create a new exnref table.
601
+ Address initial = upTo (10 );
602
+ Address max = oneIn (2 ) ? initial + upTo (4 ) : Memory::kUnlimitedSize ;
603
+ auto tablePtr =
604
+ builder.makeTable (Names::getValidTableName (wasm, " exnref_table" ),
605
+ exnref,
606
+ initial,
607
+ max,
608
+ Type::i32 ); // TODO: wasm64
609
+ tablePtr->hasExplicitName = true ;
610
+ table = wasm.addTable (std::move (tablePtr));
611
+ exnrefTableName = table->name ;
612
+ }
602
613
}
603
614
}
604
615
@@ -1073,6 +1084,11 @@ void TranslateToFuzzReader::addImportSleepSupport() {
1073
1084
}
1074
1085
1075
1086
void TranslateToFuzzReader::addHashMemorySupport () {
1087
+ // Don't always add this.
1088
+ if (oneIn (2 )) {
1089
+ return ;
1090
+ }
1091
+
1076
1092
// Add memory hasher helper (for the hash, see hash.h). The function looks
1077
1093
// like:
1078
1094
// function hashMemory() {
@@ -1107,13 +1123,13 @@ void TranslateToFuzzReader::addHashMemorySupport() {
1107
1123
}
1108
1124
contents.push_back (builder.makeLocalGet (0 , Type::i32 ));
1109
1125
auto * body = builder.makeBlock (contents);
1110
- auto name = Names::getValidFunctionName (wasm, " hashMemory" );
1126
+ hashMemoryName = Names::getValidFunctionName (wasm, " hashMemory" );
1111
1127
auto * hasher = wasm.addFunction (builder.makeFunction (
1112
- name , Signature (Type::none, Type::i32 ), {Type::i32 }, body));
1128
+ hashMemoryName , Signature (Type::none, Type::i32 ), {Type::i32 }, body));
1113
1129
1114
- if (!preserveImportsAndExports) {
1130
+ if (!preserveImportsAndExports && !wasm. getExportOrNull ( " hashMemory " ) ) {
1115
1131
wasm.addExport (
1116
- builder.makeExport (hasher-> name , hasher->name , ExternalKind::Function));
1132
+ builder.makeExport (" hashMemory " , hasher->name , ExternalKind::Function));
1117
1133
// Export memory so JS fuzzing can use it
1118
1134
if (!wasm.getExportOrNull (" memory" )) {
1119
1135
wasm.addExport (builder.makeExport (
@@ -1321,7 +1337,7 @@ Expression* TranslateToFuzzReader::makeImportSleep(Type type) {
1321
1337
}
1322
1338
1323
1339
Expression* TranslateToFuzzReader::makeMemoryHashLogging () {
1324
- auto * hash = builder.makeCall (std::string ( " hashMemory " ) , {}, Type::i32 );
1340
+ auto * hash = builder.makeCall (hashMemoryName , {}, Type::i32 );
1325
1341
return builder.makeCall (logImportNames[Type::i32 ], {hash}, Type::none);
1326
1342
}
1327
1343
@@ -2019,7 +2035,7 @@ void TranslateToFuzzReader::addInvocations(Function* func) {
2019
2035
}
2020
2036
invocations.push_back (invoke);
2021
2037
// log out memory in some cases
2022
- if (oneIn (2 )) {
2038
+ if (hashMemoryName && oneIn (2 )) {
2023
2039
invocations.push_back (makeMemoryHashLogging ());
2024
2040
}
2025
2041
}
@@ -2177,7 +2193,7 @@ Expression* TranslateToFuzzReader::_makeConcrete(Type type) {
2177
2193
Expression* TranslateToFuzzReader::_makenone () {
2178
2194
auto choice = upTo (100 );
2179
2195
if (choice < LOGGING_PERCENT) {
2180
- if (choice < LOGGING_PERCENT / 2 ) {
2196
+ if (!hashMemoryName || choice < LOGGING_PERCENT / 2 ) {
2181
2197
return makeImportLogging ();
2182
2198
} else {
2183
2199
return makeMemoryHashLogging ();
0 commit comments