From 5a169e1de756b5d62aff53cb567ee5169bd220b7 Mon Sep 17 00:00:00 2001 From: Thomas Lively Date: Sat, 3 Oct 2026 11:41:12 -0700 Subject: [PATCH] Fuzzer: Emit table.size and table.grow Add makeTableSize and makeTableGrow and include them in _makeConcrete when generating an integer matching any table's address type. Also cap table->max at ReasonableMaxTableSize instead of kUnlimitedSize in finalizeTable so table.grow cannot allocate unbounded memory during fuzzing. --- src/tools/fuzzing.h | 2 + src/tools/fuzzing/fuzzing.cpp | 38 +++- ...e-to-fuzz_all-features_metrics_noprint.txt | 174 +++++++++--------- 3 files changed, 125 insertions(+), 89 deletions(-) diff --git a/src/tools/fuzzing.h b/src/tools/fuzzing.h index 3a3b0d296d2..040106e6823 100644 --- a/src/tools/fuzzing.h +++ b/src/tools/fuzzing.h @@ -550,6 +550,8 @@ class TranslateToFuzzReader { Expression* makeBulkMemory(Type type); Expression* makeTableGet(Type type); Expression* makeTableSet(Type type); + Expression* makeTableSize(Type type); + Expression* makeTableGrow(Type type); // TODO: support other RefIs variants, and rename this Expression* makeRefIsNull(Type type); Expression* makeRefEq(Type type); diff --git a/src/tools/fuzzing/fuzzing.cpp b/src/tools/fuzzing/fuzzing.cpp index 8edba8aa981..b8e315d10bf 100644 --- a/src/tools/fuzzing/fuzzing.cpp +++ b/src/tools/fuzzing/fuzzing.cpp @@ -1033,7 +1033,7 @@ void TranslateToFuzzReader::finalizeTable() { table->initial = std::min(table->initial, ReasonableMaxTableSize); assert(ReasonableMaxTableSize <= Table::kMaxSize); - table->max = oneIn(2) ? Address(Table::kUnlimitedSize) : table->initial; + table->max = oneIn(2) ? ReasonableMaxTableSize : table->initial; if (!preserveImportsAndExports) { // Avoid an imported table (which the fuzz harness would need to handle). @@ -2885,6 +2885,12 @@ Expression* TranslateToFuzzReader::_makeConcrete(Type type) { options.add( FeatureSet::MVP, &Self::makeMemorySize, &Self::makeMemoryGrow); } + if (std::any_of(wasm.tables.begin(), wasm.tables.end(), [&](auto& table) { + return table->addressType == type; + })) { + options.add( + FeatureSet::ReferenceTypes, &Self::makeTableSize, &Self::makeTableGrow); + } } if (type == Type::i32) { if (callExportCatchImportName || callRefCatchImportName) { @@ -5694,6 +5700,36 @@ Expression* TranslateToFuzzReader::makeTableSet(Type type) { } } +Expression* TranslateToFuzzReader::makeTableSize(Type type) { + std::vector tables; + for (auto& table : wasm.tables) { + if (table->addressType == type) { + tables.push_back(table.get()); + } + } + if (tables.empty()) { + return makeTrivial(type); + } + auto* table = pick(tables); + return builder.makeTableSize(table->name); +} + +Expression* TranslateToFuzzReader::makeTableGrow(Type type) { + std::vector tables; + for (auto& table : wasm.tables) { + if (table->addressType == type) { + tables.push_back(table.get()); + } + } + if (tables.empty()) { + return makeTrivial(type); + } + auto* table = pick(tables); + auto* value = make(table->type); + auto* delta = make(type); + return builder.makeTableGrow(table->name, value, delta); +} + Expression* TranslateToFuzzReader::makeRefIsNull(Type type) { assert(type == Type::i32); assert(wasm.features.hasReferenceTypes()); diff --git a/test/passes/translate-to-fuzz_all-features_metrics_noprint.txt b/test/passes/translate-to-fuzz_all-features_metrics_noprint.txt index 741c1879ca2..7445170d882 100644 --- a/test/passes/translate-to-fuzz_all-features_metrics_noprint.txt +++ b/test/passes/translate-to-fuzz_all-features_metrics_noprint.txt @@ -1,101 +1,99 @@ Metrics total - [exports] : 183 - [funcs] : 338 + [exports] : 81 + [funcs] : 167 [globals] : 22 [imports] : 11 [memories] : 1 [memory-data] : 31 - [table-data] : 93 + [table-data] : 38 [tables] : 2 [tags] : 2 - [total] : 79045 - [vars] : 4334 - ArrayCmpxchg : 12 - ArrayCopy : 34 - ArrayFill : 27 - ArrayGet : 285 - ArrayLen : 411 - ArrayNew : 1475 - ArrayNewFixed : 435 - ArrayRMW : 7 - ArraySet : 56 - AtomicCmpxchg : 28 - AtomicFence : 35 - AtomicNotify : 28 - AtomicRMW : 39 - Binary : 3595 - Block : 5719 - BrOn : 467 - Break : 679 - Call : 917 - CallIndirect : 104 - CallRef : 153 - Const : 11918 - ContBind : 1 - ContNew : 123 - DataDrop : 2 - Drop : 653 - ElemDrop : 9 - GlobalGet : 4525 - GlobalSet : 1943 + [total] : 80243 + [vars] : 3568 + ArrayCmpxchg : 9 + ArrayCopy : 15 + ArrayFill : 13 + ArrayGet : 327 + ArrayLen : 391 + ArrayNew : 1667 + ArrayNewFixed : 497 + ArrayRMW : 8 + ArraySet : 47 + AtomicCmpxchg : 35 + AtomicFence : 44 + AtomicNotify : 18 + AtomicRMW : 23 + Binary : 3454 + Block : 5142 + BrOn : 523 + Break : 656 + Call : 789 + CallIndirect : 66 + CallRef : 158 + Const : 11199 + ContNew : 166 + DataDrop : 5 + Drop : 698 + ElemDrop : 5 + GlobalGet : 4307 + GlobalSet : 1519 I31Get : 42 - If : 2022 - Load : 264 - LocalGet : 5874 - LocalSet : 3053 - Loop : 631 - MemoryCopy : 6 - MemoryFill : 8 - MemoryGrow : 46 - MemoryInit : 12 - MemorySize : 35 - Nop : 587 - Pop : 140 - RefAs : 6772 - RefCast : 618 - RefEq : 191 - RefFunc : 1318 - RefGetDesc : 81 - RefI31 : 641 - RefIsNull : 46 - RefNull : 8464 - RefTest : 44 - Return : 371 - SIMDExtract : 133 - SIMDLoad : 2 - SIMDReplace : 3 + If : 1727 + Load : 224 + LocalGet : 7812 + LocalSet : 3049 + Loop : 586 + MemoryCopy : 9 + MemoryFill : 14 + MemoryGrow : 28 + MemoryInit : 9 + MemorySize : 22 + Nop : 436 + Pop : 148 + RefAs : 7495 + RefCast : 627 + RefEq : 169 + RefFunc : 1415 + RefGetDesc : 67 + RefI31 : 666 + RefIsNull : 38 + RefNull : 8739 + RefTest : 43 + Return : 281 + SIMDExtract : 104 SIMDShift : 1 SIMDShuffle : 1 - SIMDTernary : 2 - Select : 236 - Store : 102 - StringConcat : 2 - StringConst : 438 - StringEncode : 36 - StringEq : 53 - StringMeasure : 39 - StringNew : 5 + Select : 248 + Store : 87 + StringConcat : 1 + StringConst : 362 + StringEncode : 39 + StringEq : 43 + StringMeasure : 43 + StringNew : 6 StringSliceWTF : 2 - StringWTF16Get : 44 - StructCmpxchg : 42 - StructGet : 369 - StructNew : 8327 + StringWTF16Get : 52 + StructCmpxchg : 38 + StructGet : 340 + StructNew : 9491 StructRMW : 45 - StructSet : 44 - StructWait : 46 - Switch : 5 - TableGet : 1 - TableSet : 57 - Throw : 53 - ThrowRef : 5 - Try : 309 - TryTable : 361 - TupleExtract : 169 - TupleMake : 158 - Unary : 1676 - Unreachable : 991 - WaitqueueNew : 261 - WaitqueueNotify: 49 - WideIntAddSub : 16 - WideIntMul : 16 + StructSet : 54 + StructWait : 41 + Switch : 6 + TableGet : 5 + TableGrow : 46 + TableSet : 34 + TableSize : 48 + Throw : 83 + ThrowRef : 9 + Try : 291 + TryTable : 376 + TupleExtract : 233 + TupleMake : 187 + Unary : 1408 + Unreachable : 778 + WaitqueueNew : 251 + WaitqueueNotify: 39 + WideIntAddSub : 14 + WideIntMul : 10