diff --git a/runtime/tools/dartfuzz/dartfuzz.dart b/runtime/tools/dartfuzz/dartfuzz.dart index 68f1749b9057..7d77b55d5fa8 100644 --- a/runtime/tools/dartfuzz/dartfuzz.dart +++ b/runtime/tools/dartfuzz/dartfuzz.dart @@ -14,7 +14,7 @@ import 'dartfuzz_type_table.dart'; // Version of DartFuzz. Increase this each time changes are made // to preserve the property that a given version of DartFuzz yields // the same fuzzed program for a deterministic random seed. -const String version = '1.76'; +const String version = '1.77'; // Restriction on statements and expressions. const int stmtDepth = 1; @@ -81,12 +81,21 @@ abstract class Method { }, parameters.length, start: 1)); } + void disableRecursionScope(Function callback) { + final originalState = recursionAllowed; + recursionAllowed = false; + callback(); + recursionAllowed = originalState; + } + void emitRecursionBaseCase() { fuzzer.emitIfStatement(() { fuzzer.emit("$recursionDepthParamName >= "); fuzzer.emitSmallPositiveInt(); }, () { - fuzzer.emitReturn(terminal: true); + // Temporarily set recursionAllowed to false so that we don't have a + // recursive call in the return statement of the base case. + disableRecursionScope(fuzzer.emitReturn); return false; }); } @@ -140,7 +149,7 @@ abstract class Method { final String name; final List parameters; final DartFuzz fuzzer; - final bool recursionAllowed; + bool recursionAllowed; } /// Class for global methods generated by DartFuzz. @@ -160,6 +169,9 @@ class FfiMethod extends Method { void emitFunctionBody() { fuzzer.emitBraceWrapped(() { assert(fuzzer.localVars.isEmpty); + if (recursionAllowed) { + emitRecursionBaseCase(); + } if (fuzzer.emitStatements(0)) { fuzzer.emitReturn(); } @@ -1071,13 +1083,13 @@ class DartFuzz { } // Emit a return statement. - bool emitReturn({bool terminal = false}) { + bool emitReturn() { List proto = getCurrentProto(); if (proto == null) { emitLn('return;'); } else { emitLn('return ', newline: false); - emitExpr(0, proto[0], includeSemicolon: true, terminal: terminal); + emitExpr(0, proto[0], includeSemicolon: true); } return false; } @@ -2012,13 +2024,10 @@ class DartFuzz { // Emit expression. void emitExpr(int depth, DartType tp, - {RhsFilter rhsFilter, - bool includeSemicolon = false, - // Setting terminal to true forces the emission of a terminal. - bool terminal = false}) { + {RhsFilter rhsFilter, bool includeSemicolon = false}) { final resetExprStmt = processExprOpen(tp); // Continuing nested expressions becomes less likely as the depth grows. - if (terminal || (choose(depth + 1) > exprDepth)) { + if (choose(depth + 1) > exprDepth) { emitTerminal(depth, tp, rhsFilter: rhsFilter); } else { // Possibly nested expression.