Skip to content

Commit 1eb0126

Browse files
authored
Fuzzer: Generate TryTables (#6987)
Also make Try/TryTables with type none, and not just concrete types as before.
1 parent a1b8826 commit 1eb0126

File tree

3 files changed

+110
-41
lines changed

3 files changed

+110
-41
lines changed

src/tools/fuzzing.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -293,6 +293,7 @@ class TranslateToFuzzReader {
293293
Expression* buildIf(const struct ThreeArgs& args, Type type);
294294
Expression* makeIf(Type type);
295295
Expression* makeTry(Type type);
296+
Expression* makeTryTable(Type type);
296297
Expression* makeBreak(Type type);
297298
Expression* makeCall(Type type);
298299
Expression* makeCallIndirect(Type type);

src/tools/fuzzing/fuzzing.cpp

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1366,6 +1366,7 @@ Expression* TranslateToFuzzReader::_makeConcrete(Type type) {
13661366
&Self::makeCall,
13671367
&Self::makeCallIndirect)
13681368
.add(FeatureSet::ExceptionHandling, &Self::makeTry)
1369+
.add(FeatureSet::ExceptionHandling, &Self::makeTryTable)
13691370
.add(FeatureSet::GC | FeatureSet::ReferenceTypes, &Self::makeCallRef);
13701371
}
13711372
if (type.isSingle()) {
@@ -1451,6 +1452,8 @@ Expression* TranslateToFuzzReader::_makenone() {
14511452
&Self::makeGlobalSet)
14521453
.add(FeatureSet::BulkMemory, &Self::makeBulkMemory)
14531454
.add(FeatureSet::Atomics, &Self::makeAtomic)
1455+
.add(FeatureSet::ExceptionHandling, &Self::makeTry)
1456+
.add(FeatureSet::ExceptionHandling, &Self::makeTryTable)
14541457
.add(FeatureSet::GC | FeatureSet::ReferenceTypes, &Self::makeCallRef)
14551458
.add(FeatureSet::GC | FeatureSet::ReferenceTypes, &Self::makeStructSet)
14561459
.add(FeatureSet::GC | FeatureSet::ReferenceTypes, &Self::makeArraySet)
@@ -1688,6 +1691,71 @@ Expression* TranslateToFuzzReader::makeTry(Type type) {
16881691
return builder.makeTry(body, catchTags, catchBodies);
16891692
}
16901693

1694+
Expression* TranslateToFuzzReader::makeTryTable(Type type) {
1695+
auto* body = make(type);
1696+
1697+
if (funcContext->breakableStack.empty()) {
1698+
// Nothing to break to, emit a trivial TryTable.
1699+
// TODO: Perhaps generate a block wrapping us?
1700+
return builder.makeTryTable(body, {}, {}, {});
1701+
}
1702+
1703+
if (wasm.tags.empty()) {
1704+
addTag();
1705+
}
1706+
1707+
// Add catches of specific tags, and possibly a catch_all at the end. We use
1708+
// the last iteration of the loop for that.
1709+
std::vector<Name> catchTags;
1710+
std::vector<Name> catchDests;
1711+
std::vector<bool> catchRefs;
1712+
auto numCatches = upTo(MAX_TRY_CATCHES);
1713+
for (Index i = 0; i <= numCatches; i++) {
1714+
Name tagName;
1715+
Type tagType;
1716+
if (i < numCatches) {
1717+
// Look for a specific tag.
1718+
auto& tag = pick(wasm.tags);
1719+
tagName = tag->name;
1720+
tagType = tag->sig.params;
1721+
} else {
1722+
// Add a catch_all at the end, some of the time (but all of the time if we
1723+
// have nothing else).
1724+
if (!catchTags.empty() && oneIn(2)) {
1725+
break;
1726+
}
1727+
tagType = Type::none;
1728+
}
1729+
1730+
// We need to find a proper target to break to, which means a target that
1731+
// has the type of the tag, or the tag + an exnref at the end.
1732+
std::vector<Type> vec(tagType.begin(), tagType.end());
1733+
// Use a non-nullable exnref here, and then the subtyping check below will
1734+
// also accept a target that is nullable.
1735+
vec.push_back(Type(HeapType::exn, NonNullable));
1736+
auto tagTypeWithExn = Type(vec);
1737+
int tries = TRIES;
1738+
while (tries-- > 0) {
1739+
auto* target = pick(funcContext->breakableStack);
1740+
auto dest = getTargetName(target);
1741+
auto valueType = getTargetType(target);
1742+
auto subOfTagType = Type::isSubType(tagType, valueType);
1743+
auto subOfTagTypeWithExn = Type::isSubType(tagTypeWithExn, valueType);
1744+
if (subOfTagType || subOfTagTypeWithExn) {
1745+
catchTags.push_back(tagName);
1746+
catchDests.push_back(dest);
1747+
catchRefs.push_back(subOfTagTypeWithExn);
1748+
break;
1749+
}
1750+
}
1751+
// TODO: Perhaps generate a block wrapping us, if we fail to find a target?
1752+
// TODO: It takes a bit of luck to find a target with an exnref - perhaps
1753+
// generate those?
1754+
}
1755+
1756+
return builder.makeTryTable(body, catchTags, catchDests, catchRefs);
1757+
}
1758+
16911759
Expression* TranslateToFuzzReader::makeBreak(Type type) {
16921760
if (funcContext->breakableStack.empty()) {
16931761
return makeTrivial(type);
Lines changed: 41 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -1,53 +1,53 @@
11
Metrics
22
total
3-
[exports] : 5
4-
[funcs] : 9
3+
[exports] : 3
4+
[funcs] : 5
55
[globals] : 26
66
[imports] : 5
77
[memories] : 1
88
[memory-data] : 20
9-
[table-data] : 3
9+
[table-data] : 0
1010
[tables] : 1
1111
[tags] : 2
12-
[total] : 669
13-
[vars] : 27
14-
ArrayNew : 16
15-
ArrayNewFixed : 3
12+
[total] : 499
13+
[vars] : 20
14+
ArrayNew : 14
15+
ArrayNewFixed : 2
1616
AtomicCmpxchg : 1
17-
AtomicFence : 1
18-
Binary : 75
19-
Block : 70
20-
Break : 7
21-
Call : 26
22-
CallRef : 1
23-
Const : 143
24-
Drop : 3
25-
GlobalGet : 37
26-
GlobalSet : 27
17+
AtomicNotify : 1
18+
AtomicRMW : 1
19+
Binary : 69
20+
Block : 42
21+
Break : 8
22+
Call : 6
23+
Const : 126
24+
Drop : 2
25+
GlobalGet : 27
26+
GlobalSet : 16
2727
I31Get : 1
28-
If : 20
29-
Load : 21
30-
LocalGet : 55
31-
LocalSet : 40
32-
Loop : 6
33-
Nop : 5
34-
Pop : 5
28+
If : 10
29+
Load : 18
30+
LocalGet : 43
31+
LocalSet : 22
32+
Loop : 5
33+
Nop : 3
34+
Pop : 3
3535
RefAs : 2
36-
RefEq : 2
37-
RefFunc : 5
38-
RefI31 : 2
39-
RefNull : 11
40-
RefTest : 2
41-
Return : 6
42-
Select : 2
43-
StringConst : 6
44-
StringEq : 1
45-
StringMeasure : 1
46-
StringWTF16Get : 1
47-
StructNew : 17
36+
RefFunc : 2
37+
RefI31 : 1
38+
RefNull : 8
39+
RefTest : 1
40+
Return : 1
41+
Select : 1
42+
Store : 3
43+
StringConst : 9
44+
StringEncode : 1
45+
StringEq : 3
46+
StructNew : 12
4847
StructSet : 1
49-
Try : 4
50-
TupleExtract : 3
51-
TupleMake : 5
52-
Unary : 20
53-
Unreachable : 15
48+
Try : 3
49+
TryTable : 2
50+
TupleExtract : 1
51+
TupleMake : 4
52+
Unary : 13
53+
Unreachable : 11

0 commit comments

Comments
 (0)