-
Notifications
You must be signed in to change notification settings - Fork 799
[Stack Switching] Fuzz Stack Switching #7834
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 85 commits
d20a437
8f1bed1
f988d9f
e719298
a94d31a
3f29688
058d05e
9944360
3a47f99
23f5846
c76f0a7
7f3630b
3e57bcd
252fae2
8eefbab
f8789f2
943aedc
444d8e0
689114f
922fe8c
33171c1
fc66e42
8e24d91
797e137
e367a42
add4a52
bb77eba
ed9d5e3
149ec27
c6fd413
e414980
612cf96
1d4532a
169f679
605620e
e403a23
42da090
2a50223
8bc214d
124c33f
bb42ddb
2659042
643142f
8d121da
a4959f4
2513194
9d4cc20
997579e
9cc2c7b
1759b03
45585fe
eb67fac
135c252
f02650b
96b2130
b523289
d5f8cc5
ceb4338
9daca9d
f1dd340
c963d6a
c5b2e3f
ff8d7b1
38df246
efdb9a7
8360dfc
7c81b78
1b987a8
e92d00e
4c2c02a
f7f032b
bc29e68
b0b9733
afe5df2
eeb8894
24bea1a
5808c64
64075e0
41cf9b6
b594c26
51257eb
00fc791
575ba68
45aa8d4
6e0b0b2
0512f00
090814f
8293638
0d3b16a
64ab851
9b8f59a
1155b7f
7abbee0
2243de7
1204577
a07976f
5591ad6
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -491,6 +491,7 @@ void TranslateToFuzzReader::setupHeapTypes() { | |
auto eq = HeapTypes::eq.getBasic(share); | ||
auto any = HeapTypes::any.getBasic(share); | ||
auto func = HeapTypes::func.getBasic(share); | ||
auto cont = HeapTypes::cont.getBasic(share); | ||
switch (type.getKind()) { | ||
case HeapTypeKind::Func: | ||
interestingHeapSubTypes[func].push_back(type); | ||
|
@@ -517,7 +518,8 @@ void TranslateToFuzzReader::setupHeapTypes() { | |
} | ||
break; | ||
case HeapTypeKind::Cont: | ||
WASM_UNREACHABLE("TODO: cont"); | ||
interestingHeapSubTypes[cont].push_back(type); | ||
break; | ||
case HeapTypeKind::Basic: | ||
WASM_UNREACHABLE("unexpected kind"); | ||
} | ||
|
@@ -614,6 +616,17 @@ void TranslateToFuzzReader::setupTables() { | |
} | ||
} | ||
|
||
static bool canCreateContentWithoutFunctionScope(Type type) { | ||
for (auto t : type) { | ||
if (t.isContinuation()) { | ||
// There is no way to make a continuation in a global. TODO: We could | ||
// allow null ones, at least, that are always set to null. | ||
return false; | ||
} | ||
} | ||
return true; | ||
} | ||
|
||
void TranslateToFuzzReader::setupGlobals() { | ||
// If there were initial wasm contents, there may be imported globals. That | ||
// would be a problem in the fuzzer harness as we'd error if we do not | ||
|
@@ -672,6 +685,10 @@ void TranslateToFuzzReader::setupGlobals() { | |
// Create new random globals. | ||
for (size_t index = upTo(fuzzParams->MAX_GLOBALS); index > 0; --index) { | ||
auto type = getConcreteType(); | ||
if (!canCreateContentWithoutFunctionScope(type)) { | ||
continue; | ||
} | ||
|
||
// Prefer immutable ones as they can be used in global.gets in other | ||
// globals, for more interesting patterns. | ||
auto mutability = oneIn(3) ? Builder::Mutable : Builder::Immutable; | ||
|
@@ -708,6 +725,9 @@ void TranslateToFuzzReader::setupTags() { | |
if (tag->imported() && !preserveImportsAndExports) { | ||
tag->module = tag->base = Name(); | ||
} | ||
if (tag->results() == Type::none) { | ||
exceptionTags.push_back(tag.get()); | ||
} | ||
} | ||
|
||
// Add some random tags. | ||
|
@@ -736,7 +756,8 @@ void TranslateToFuzzReader::setupTags() { | |
void TranslateToFuzzReader::addTag() { | ||
auto tag = builder.makeTag(Names::getValidTagName(wasm, "tag$"), | ||
Signature(getControlFlowType(), Type::none)); | ||
wasm.addTag(std::move(tag)); | ||
auto* tagg = wasm.addTag(std::move(tag)); | ||
exceptionTags.push_back(tagg); | ||
} | ||
|
||
void TranslateToFuzzReader::finalizeMemory() { | ||
|
@@ -2432,10 +2453,10 @@ Expression* TranslateToFuzzReader::makeTry(Type type) { | |
auto numTags = upTo(fuzzParams->MAX_TRY_CATCHES); | ||
std::unordered_set<Tag*> usedTags; | ||
for (Index i = 0; i < numTags; i++) { | ||
if (wasm.tags.empty()) { | ||
if (exceptionTags.empty()) { | ||
addTag(); | ||
} | ||
auto* tag = pick(wasm.tags).get(); | ||
auto* tag = pick(exceptionTags); | ||
if (usedTags.count(tag)) { | ||
continue; | ||
} | ||
|
@@ -2482,7 +2503,7 @@ Expression* TranslateToFuzzReader::makeTryTable(Type type) { | |
return builder.makeTryTable(body, {}, {}, {}); | ||
} | ||
|
||
if (wasm.tags.empty()) { | ||
if (exceptionTags.empty()) { | ||
addTag(); | ||
} | ||
|
||
|
@@ -2497,7 +2518,7 @@ Expression* TranslateToFuzzReader::makeTryTable(Type type) { | |
Type tagType; | ||
if (i < numCatches) { | ||
// Look for a specific tag. | ||
auto& tag = pick(wasm.tags); | ||
auto* tag = pick(exceptionTags); | ||
tagName = tag->name; | ||
tagType = tag->params(); | ||
} else { | ||
|
@@ -3449,7 +3470,14 @@ Expression* TranslateToFuzzReader::makeBasicRef(Type type) { | |
return makeRefFuncConst(type); | ||
} | ||
case HeapType::cont: { | ||
WASM_UNREACHABLE("not implemented"); | ||
if (type.isNullable() || oneIn(4)) { | ||
return builder.makeRefNull(HeapTypes::cont.getBasic(share)); | ||
} | ||
// Emit the simplest possible continuation. | ||
auto funcSig = Signature(Type::none, Type::none); | ||
auto funcType = Type(funcSig, NonNullable); | ||
auto contType = Continuation(funcSig); | ||
return builder.makeContNew(contType, makeRefFuncConst(funcType)); | ||
} | ||
case HeapType::any: { | ||
// Choose a subtype we can materialize a constant for. We cannot | ||
|
@@ -3673,8 +3701,10 @@ Expression* TranslateToFuzzReader::makeCompoundRef(Type type) { | |
builder.makeConst(int32_t(upTo(fuzzParams->MAX_ARRAY_SIZE))); | ||
return builder.makeArrayNew(type.getHeapType(), count, init); | ||
} | ||
case HeapTypeKind::Cont: | ||
WASM_UNREACHABLE("TODO: cont"); | ||
case HeapTypeKind::Cont: { | ||
auto funcType = Type(heapType.getContinuation().type, NonNullable); | ||
return builder.makeContNew(heapType, makeRefFuncConst(funcType)); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why not allow this to be an arbitrary expression with the expected type? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Hmm, yeah, I don't think it could recurse in a bad way. I'll try that. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done. |
||
} | ||
case HeapTypeKind::Basic: | ||
break; | ||
} | ||
|
@@ -5222,10 +5252,10 @@ Expression* TranslateToFuzzReader::makeThrow(Type type) { | |
} | ||
} else { | ||
// Get a random tag, adding a random one if necessary. | ||
if (wasm.tags.empty()) { | ||
if (exceptionTags.empty()) { | ||
addTag(); | ||
} | ||
tag = pick(wasm.tags).get(); | ||
tag = pick(exceptionTags); | ||
} | ||
auto tagType = tag->params(); | ||
std::vector<Expression*> operands; | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,57 +1,57 @@ | ||
Metrics | ||
total | ||
[exports] : 14 | ||
[funcs] : 20 | ||
[exports] : 10 | ||
[funcs] : 14 | ||
[globals] : 26 | ||
[imports] : 12 | ||
[memories] : 1 | ||
[memory-data] : 16 | ||
[table-data] : 6 | ||
[table-data] : 3 | ||
[tables] : 2 | ||
[tags] : 1 | ||
[total] : 734 | ||
[vars] : 45 | ||
ArrayNewFixed : 5 | ||
[tags] : 2 | ||
[total] : 642 | ||
[vars] : 48 | ||
ArrayNewFixed : 6 | ||
AtomicCmpxchg : 1 | ||
AtomicFence : 1 | ||
AtomicNotify : 2 | ||
AtomicRMW : 1 | ||
Binary : 43 | ||
Block : 115 | ||
BrOn : 1 | ||
Break : 11 | ||
Call : 27 | ||
CallRef : 2 | ||
Const : 144 | ||
Drop : 15 | ||
GlobalGet : 66 | ||
GlobalSet : 50 | ||
AtomicFence : 2 | ||
Binary : 40 | ||
Block : 106 | ||
Break : 8 | ||
Call : 26 | ||
CallRef : 1 | ||
Const : 109 | ||
DataDrop : 2 | ||
Drop : 14 | ||
GlobalGet : 57 | ||
GlobalSet : 44 | ||
If : 32 | ||
Load : 5 | ||
Load : 6 | ||
LocalGet : 20 | ||
LocalSet : 11 | ||
Loop : 5 | ||
LocalSet : 16 | ||
Loop : 8 | ||
MemoryCopy : 1 | ||
MemoryFill : 1 | ||
MemoryInit : 1 | ||
Nop : 13 | ||
RefEq : 3 | ||
RefFunc : 11 | ||
RefI31 : 12 | ||
RefNull : 11 | ||
Nop : 11 | ||
Pop : 1 | ||
RefAs : 2 | ||
RefCast : 2 | ||
RefEq : 4 | ||
RefFunc : 5 | ||
RefI31 : 8 | ||
RefNull : 8 | ||
RefTest : 1 | ||
Return : 6 | ||
SIMDExtract : 2 | ||
Select : 3 | ||
Store : 3 | ||
StringConst : 13 | ||
StringEq : 2 | ||
StringWTF16Get : 1 | ||
StructNew : 14 | ||
SIMDExtract : 1 | ||
Select : 1 | ||
Store : 1 | ||
StringConst : 8 | ||
StringEncode : 1 | ||
StringMeasure : 1 | ||
StructNew : 9 | ||
Switch : 1 | ||
Throw : 1 | ||
Try : 5 | ||
TryTable : 6 | ||
TupleExtract : 1 | ||
TupleMake : 8 | ||
Unary : 33 | ||
Unreachable : 25 | ||
Try : 1 | ||
TryTable : 4 | ||
TupleExtract : 2 | ||
TupleMake : 6 | ||
Unary : 36 | ||
Unreachable : 22 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nulls would just trap. But I guess we should cover that too. I can change this to use nulls rarely like we do elsewhere.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.