diff options
author | Heejin Ahn <aheejin@gmail.com> | 2022-01-04 12:39:38 -0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-01-04 12:39:38 -0800 |
commit | 16ac2eb73a57eb530f78b632cffacac97c6b8fdd (patch) | |
tree | 81e0945bbb828b880f8292647c21318c600b783c /src | |
parent | 28665b1d8f0632216ceb2de475560c64dc260b9d (diff) | |
download | binaryen-16ac2eb73a57eb530f78b632cffacac97c6b8fdd.tar.gz binaryen-16ac2eb73a57eb530f78b632cffacac97c6b8fdd.tar.bz2 binaryen-16ac2eb73a57eb530f78b632cffacac97c6b8fdd.zip |
[EH] Enable fuzzer with initial contents (#4409)
This enables fuzzing EH with initial contents. fuzzing.cpp/h does not
yet support generation of EH instructions, but with this we can still
fuzz EH based on initial contents.
The fuzzer ran successfully for more than 1,900,000 iterations, with my
local modification that always enables EH and lets the fuzzer select
only EH tests for its initial contents.
Diffstat (limited to 'src')
-rw-r--r-- | src/ir/eh-utils.cpp | 2 | ||||
-rw-r--r-- | src/ir/eh-utils.h | 2 | ||||
-rw-r--r-- | src/tools/fuzzing.h | 7 | ||||
-rw-r--r-- | src/tools/fuzzing/fuzzing.cpp | 8 | ||||
-rw-r--r-- | src/wasm/wasm-validator.cpp | 3 |
5 files changed, 16 insertions, 6 deletions
diff --git a/src/ir/eh-utils.cpp b/src/ir/eh-utils.cpp index 31ddfe306..37af738ce 100644 --- a/src/ir/eh-utils.cpp +++ b/src/ir/eh-utils.cpp @@ -100,7 +100,7 @@ getFirstPop(Expression* catchBody, bool& isPopNested, Expression**& popPtr) { } } -bool isPopValid(Expression* catchBody) { +bool containsValidDanglingPop(Expression* catchBody) { bool isPopNested = false; Expression** popPtr = nullptr; auto* pop = getFirstPop(catchBody, isPopNested, popPtr); diff --git a/src/ir/eh-utils.h b/src/ir/eh-utils.h index 733eedc67..c0d6e59ea 100644 --- a/src/ir/eh-utils.h +++ b/src/ir/eh-utils.h @@ -29,7 +29,7 @@ namespace EHUtils { // whose tag type is void or a catch_all's body, this returns false. // - This returns true even if there are more pops after the first one within a // catch body, which is invalid. That will be taken care of in validation. -bool isPopValid(Expression* catchBody); +bool containsValidDanglingPop(Expression* catchBody); // Fixes up 'pop's nested in blocks, which are currently not supported without // block param types, by creating a new local, putting a (local.set $new (pop diff --git a/src/tools/fuzzing.h b/src/tools/fuzzing.h index a9cc9eec0..fe5191475 100644 --- a/src/tools/fuzzing.h +++ b/src/tools/fuzzing.h @@ -31,6 +31,7 @@ high chance for set at start of loop #include "ir/memory-utils.h" #include "support/insert_ordered.h" #include "tools/fuzzing/random.h" +#include <ir/eh-utils.h> #include <ir/find_all.h> #include <ir/literal-utils.h> #include <ir/manipulation.h> @@ -182,8 +183,12 @@ private: // type, but should not do so for certain types that are dangerous. For // example, it would be bad to add an RTT in a tuple, as that would force us // to use temporary locals for the tuple, but RTTs are not defaultable. + // Also, 'pop' pseudo instruction for EH is supposed to exist only at the + // beginning of a 'catch' block, so it shouldn't be moved around or deleted + // freely. bool canBeArbitrarilyReplaced(Expression* curr) { - return curr->type.isDefaultable(); + return curr->type.isDefaultable() && + !EHUtils::containsValidDanglingPop(curr); } void recombine(Function* func); void mutate(Function* func); diff --git a/src/tools/fuzzing/fuzzing.cpp b/src/tools/fuzzing/fuzzing.cpp index 8194c52d3..a41e6704e 100644 --- a/src/tools/fuzzing/fuzzing.cpp +++ b/src/tools/fuzzing/fuzzing.cpp @@ -581,14 +581,18 @@ void TranslateToFuzzReader::recombine(Function* func) { // First, scan and group all expressions by type. struct Scanner : public PostWalker<Scanner, UnifiedExpressionVisitor<Scanner>> { + TranslateToFuzzReader& parent; // A map of all expressions, categorized by type. InsertOrderedMap<Type, std::vector<Expression*>> exprsByType; + Scanner(TranslateToFuzzReader& parent) : parent(parent) {} void visitExpression(Expression* curr) { - exprsByType[curr->type].push_back(curr); + if (parent.canBeArbitrarilyReplaced(curr)) { + exprsByType[curr->type].push_back(curr); + } } }; - Scanner scanner; + Scanner scanner(*this); scanner.walk(func->body); // Potentially trim the list of possible picks, so replacements are more // likely to collide. diff --git a/src/wasm/wasm-validator.cpp b/src/wasm/wasm-validator.cpp index e7e1d7fd5..1ad1380c9 100644 --- a/src/wasm/wasm-validator.cpp +++ b/src/wasm/wasm-validator.cpp @@ -2202,7 +2202,8 @@ void FunctionValidator::visitTry(Try* curr) { << "catch's tag (" << tagName << ")'s pop doesn't have the same type as the tag's params"; } - if (!shouldBeTrue(EHUtils::isPopValid(catchBody), curr, "")) { + if (!shouldBeTrue( + EHUtils::containsValidDanglingPop(catchBody), curr, "")) { getStream() << "catch's body (" << tagName << ")'s pop's location is not valid"; } |