diff options
-rwxr-xr-x | scripts/fuzz_opt.py | 13 | ||||
-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 | ||||
-rw-r--r-- | test/passes/fuzz_metrics_noprint.bin.txt | 51 | ||||
-rw-r--r-- | test/passes/translate-to-fuzz_all-features_metrics_noprint.txt | 70 |
8 files changed, 85 insertions, 71 deletions
diff --git a/scripts/fuzz_opt.py b/scripts/fuzz_opt.py index d7c82e244..21d39853a 100755 --- a/scripts/fuzz_opt.py +++ b/scripts/fuzz_opt.py @@ -312,8 +312,6 @@ def pick_initial_contents(): global FEATURE_OPTS FEATURE_OPTS += [ - # has not been enabled in the fuzzer yet - '--disable-exception-handling', # has not been fuzzed in general yet '--disable-memory64', # avoid multivalue for now due to bad interactions with gc rtts in @@ -793,7 +791,7 @@ class CompareVMs(TestCaseHandler): compare(before[vm], after[vm], 'CompareVMs between before and after: ' + vm.name) def can_run_on_feature_opts(self, feature_opts): - return all_disallowed(['simd', 'exception-handling', 'multivalue']) + return all_disallowed(['simd', 'multivalue']) # Check for determinism - the same command must have the same output. @@ -1184,9 +1182,6 @@ def randomize_opt_flags(): if has_flatten: print('avoiding multiple --flatten in a single command, due to exponential overhead') continue - if '--enable-exception-handling' in FEATURE_OPTS: - print('avoiding --flatten due to exception catching which does not support it yet') - continue if '--enable-multivalue' in FEATURE_OPTS and '--enable-reference-types' in FEATURE_OPTS: print('avoiding --flatten due to multivalue + reference types not supporting it (spilling of non-nullable tuples)') continue @@ -1198,6 +1193,10 @@ def randomize_opt_flags(): continue else: has_flatten = True + if ('--rereloop' in choice or '--dfo' in choice) and \ + '--enable-exception-handling' in FEATURE_OPTS: + print('avoiding --rereloop or --dfo due to exception-handling not supporting it') + continue flag_groups.append(choice) if len(flag_groups) > 20 or random.random() < 0.3: break @@ -1238,7 +1237,7 @@ print('POSSIBLE_FEATURE_OPTS:', POSSIBLE_FEATURE_OPTS) # some features depend on other features, so if a required feature is # disabled, its dependent features need to be disabled as well. IMPLIED_FEATURE_OPTS = { - '--disable-reference-types': ['--disable-exception-handling', '--disable-gc'] + '--disable-reference-types': ['--disable-gc'] } if __name__ == '__main__': 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"; } diff --git a/test/passes/fuzz_metrics_noprint.bin.txt b/test/passes/fuzz_metrics_noprint.bin.txt index d65d67831..4c481cd8f 100644 --- a/test/passes/fuzz_metrics_noprint.bin.txt +++ b/test/passes/fuzz_metrics_noprint.bin.txt @@ -1,31 +1,32 @@ total - [exports] : 38 - [funcs] : 62 + [exports] : 39 + [funcs] : 50 [globals] : 7 [imports] : 4 [memory-data] : 4 - [table-data] : 22 + [table-data] : 17 [tables] : 1 [tags] : 0 - [total] : 7561 - [vars] : 214 - Binary : 542 - Block : 1140 - Break : 287 - Call : 236 - CallIndirect : 94 - Const : 1510 - Drop : 66 - GlobalGet : 625 - GlobalSet : 266 - If : 487 - Load : 128 - LocalGet : 477 - LocalSet : 264 - Loop : 182 - Nop : 223 - RefFunc : 22 - Return : 301 - Select : 58 - Store : 91 - Unary : 562 + [total] : 3442 + [vars] : 108 + Binary : 299 + Block : 495 + Break : 110 + Call : 193 + CallIndirect : 29 + Const : 650 + Drop : 48 + GlobalGet : 295 + GlobalSet : 131 + If : 183 + Load : 79 + LocalGet : 199 + LocalSet : 153 + Loop : 71 + Nop : 45 + RefFunc : 17 + Return : 155 + Select : 25 + Store : 29 + Unary : 235 + Unreachable : 1 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 853206211..a172095ef 100644 --- a/test/passes/translate-to-fuzz_all-features_metrics_noprint.txt +++ b/test/passes/translate-to-fuzz_all-features_metrics_noprint.txt @@ -1,42 +1,46 @@ total - [exports] : 8 - [funcs] : 9 + [exports] : 13 + [funcs] : 18 [globals] : 6 [imports] : 5 [memory-data] : 22 - [table-data] : 4 + [table-data] : 14 [tables] : 1 [tags] : 1 - [total] : 465 - [vars] : 10 - ArrayInit : 1 - AtomicCmpxchg : 1 + [total] : 728 + [vars] : 41 + ArrayInit : 6 + AtomicFence : 1 AtomicNotify : 1 - Binary : 64 - Block : 51 - Break : 6 - Call : 19 - Const : 121 - DataDrop : 1 - Drop : 6 - GlobalGet : 22 - GlobalSet : 12 - If : 20 - Load : 13 - LocalGet : 22 - LocalSet : 18 - Loop : 3 + AtomicRMW : 1 + Binary : 80 + Block : 83 + Break : 13 + Call : 33 + CallIndirect : 1 + CallRef : 1 + Const : 162 + Drop : 10 + GlobalGet : 50 + GlobalSet : 27 + I31Get : 3 + I31New : 5 + If : 32 + Load : 20 + LocalGet : 35 + LocalSet : 21 + Loop : 8 MemoryFill : 1 - Nop : 20 + MemoryInit : 1 + Nop : 14 RefAs : 1 - RefFunc : 5 - RefIs : 3 - RefNull : 3 - Return : 18 - SIMDExtract : 3 - Select : 1 - Store : 3 - StructNew : 3 - TupleExtract : 2 - TupleMake : 4 - Unary : 17 + RefFunc : 16 + RefIs : 2 + RefNull : 6 + Return : 27 + SIMDExtract : 1 + Select : 8 + Store : 2 + StructNew : 7 + TupleMake : 5 + Unary : 44 |