Skip to content

Commit 81f72e8

Browse files
authored
Fuzzer: Emit signed Struct/ArrayGet operations (#6486)
1 parent d662d73 commit 81f72e8

File tree

3 files changed

+61
-48
lines changed

3 files changed

+61
-48
lines changed

src/tools/fuzzing.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -345,6 +345,11 @@ class TranslateToFuzzReader {
345345
Expression* makeRefEq(Type type);
346346
Expression* makeRefTest(Type type);
347347
Expression* makeRefCast(Type type);
348+
349+
// Decide to emit a signed Struct/ArrayGet sometimes, when the field is
350+
// packed.
351+
bool maybeSignedGet(const Field& field);
352+
348353
Expression* makeStructGet(Type type);
349354
Expression* makeStructSet(Type type);
350355
Expression* makeArrayGet(Type type);

src/tools/fuzzing/fuzzing.cpp

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3681,13 +3681,20 @@ Expression* TranslateToFuzzReader::makeRefCast(Type type) {
36813681
return builder.makeRefCast(make(refType), type);
36823682
}
36833683

3684+
bool TranslateToFuzzReader::maybeSignedGet(const Field& field) {
3685+
if (field.isPacked()) {
3686+
return oneIn(2);
3687+
}
3688+
return false;
3689+
}
3690+
36843691
Expression* TranslateToFuzzReader::makeStructGet(Type type) {
36853692
auto& structFields = typeStructFields[type];
36863693
assert(!structFields.empty());
36873694
auto [structType, fieldIndex] = pick(structFields);
36883695
auto* ref = makeTrappingRefUse(structType);
3689-
// TODO: fuzz signed and unsigned
3690-
return builder.makeStructGet(fieldIndex, ref, type);
3696+
auto signed_ = maybeSignedGet(structType.getStruct().fields[fieldIndex]);
3697+
return builder.makeStructGet(fieldIndex, ref, type, signed_);
36913698
}
36923699

36933700
Expression* TranslateToFuzzReader::makeStructSet(Type type) {
@@ -3752,18 +3759,18 @@ Expression* TranslateToFuzzReader::makeArrayGet(Type type) {
37523759
auto arrayType = pick(arrays);
37533760
auto* ref = makeTrappingRefUse(arrayType);
37543761
auto* index = make(Type::i32);
3762+
auto signed_ = maybeSignedGet(arrayType.getArray().element);
37553763
// Only rarely emit a plain get which might trap. See related logic in
37563764
// ::makePointer().
37573765
if (allowOOB && oneIn(10)) {
3758-
// TODO: fuzz signed and unsigned, and also below
3759-
return builder.makeArrayGet(ref, index, type);
3766+
return builder.makeArrayGet(ref, index, type, signed_);
37603767
}
37613768
// To avoid a trap, check the length dynamically using this pattern:
37623769
//
37633770
// index < array.len ? array[index] : ..some fallback value..
37643771
//
37653772
auto check = makeArrayBoundsCheck(ref, index, funcContext->func, builder);
3766-
auto* get = builder.makeArrayGet(check.getRef, check.getIndex, type);
3773+
auto* get = builder.makeArrayGet(check.getRef, check.getIndex, type, signed_);
37673774
auto* fallback = makeTrivial(type);
37683775
return builder.makeIf(check.condition, get, fallback);
37693776
}
Lines changed: 44 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -1,56 +1,57 @@
11
total
2-
[exports] : 3
3-
[funcs] : 5
2+
[exports] : 4
3+
[funcs] : 7
44
[globals] : 1
55
[imports] : 5
66
[memories] : 1
77
[memory-data] : 20
88
[table-data] : 1
99
[tables] : 1
1010
[tags] : 2
11-
[total] : 661
12-
[vars] : 21
13-
ArrayGet : 1
14-
ArrayLen : 1
11+
[total] : 674
12+
[vars] : 37
13+
ArrayCopy : 1
14+
ArrayGet : 3
15+
ArrayLen : 3
1516
ArrayNew : 4
16-
ArrayNewFixed : 6
17-
AtomicFence : 1
17+
ArraySet : 1
18+
AtomicCmpxchg : 1
19+
AtomicNotify : 3
1820
AtomicRMW : 1
19-
Binary : 87
20-
Block : 78
21-
Break : 17
22-
Call : 11
23-
Const : 125
24-
DataDrop : 1
25-
Drop : 7
26-
GlobalGet : 26
27-
GlobalSet : 26
28-
I31Get : 1
29-
If : 24
30-
Load : 22
31-
LocalGet : 65
32-
LocalSet : 38
33-
Loop : 9
34-
MemoryCopy : 1
35-
Nop : 9
36-
RefAs : 8
37-
RefCast : 1
21+
Binary : 81
22+
Block : 75
23+
Break : 12
24+
Call : 25
25+
CallRef : 1
26+
Const : 121
27+
Drop : 5
28+
GlobalGet : 24
29+
GlobalSet : 24
30+
I31Get : 2
31+
If : 23
32+
Load : 19
33+
LocalGet : 75
34+
LocalSet : 50
35+
Loop : 7
36+
MemoryFill : 1
37+
Nop : 4
38+
Pop : 6
39+
RefAs : 9
40+
RefCast : 5
3841
RefEq : 2
39-
RefFunc : 1
40-
RefI31 : 3
42+
RefFunc : 3
43+
RefI31 : 6
4144
RefIsNull : 2
42-
RefNull : 13
43-
RefTest : 1
44-
Return : 4
45-
SIMDExtract : 3
46-
SIMDLoad : 1
47-
Select : 2
48-
Store : 4
49-
StructGet : 2
50-
StructNew : 3
51-
Throw : 1
52-
Try : 1
53-
TupleExtract : 2
54-
TupleMake : 5
55-
Unary : 28
45+
RefNull : 12
46+
RefTest : 3
47+
Return : 6
48+
SIMDExtract : 2
49+
Select : 4
50+
StructGet : 1
51+
StructNew : 1
52+
StructSet : 1
53+
Try : 5
54+
TupleExtract : 3
55+
TupleMake : 4
56+
Unary : 20
5657
Unreachable : 13

0 commit comments

Comments
 (0)