@@ -14,7 +14,7 @@ import 'dartfuzz_type_table.dart';
1414// Version of DartFuzz. Increase this each time changes are made
1515// to preserve the property that a given version of DartFuzz yields
1616// the same fuzzed program for a deterministic random seed.
17- const String version = '1.76 ' ;
17+ const String version = '1.77 ' ;
1818
1919// Restriction on statements and expressions.
2020const int stmtDepth = 1 ;
@@ -81,12 +81,21 @@ abstract class Method {
8181 }, parameters.length, start: 1 ));
8282 }
8383
84+ void disableRecursionScope (Function callback) {
85+ final originalState = recursionAllowed;
86+ recursionAllowed = false ;
87+ callback ();
88+ recursionAllowed = originalState;
89+ }
90+
8491 void emitRecursionBaseCase () {
8592 fuzzer.emitIfStatement (() {
8693 fuzzer.emit ("$recursionDepthParamName >= " );
8794 fuzzer.emitSmallPositiveInt ();
8895 }, () {
89- fuzzer.emitReturn (terminal: true );
96+ // Temporarily set recursionAllowed to false so that we don't have a
97+ // recursive call in the return statement of the base case.
98+ disableRecursionScope (fuzzer.emitReturn);
9099 return false ;
91100 });
92101 }
@@ -140,7 +149,7 @@ abstract class Method {
140149 final String name;
141150 final List <DartType > parameters;
142151 final DartFuzz fuzzer;
143- final bool recursionAllowed;
152+ bool recursionAllowed;
144153}
145154
146155/// Class for global methods generated by DartFuzz.
@@ -160,6 +169,9 @@ class FfiMethod extends Method {
160169 void emitFunctionBody () {
161170 fuzzer.emitBraceWrapped (() {
162171 assert (fuzzer.localVars.isEmpty);
172+ if (recursionAllowed) {
173+ emitRecursionBaseCase ();
174+ }
163175 if (fuzzer.emitStatements (0 )) {
164176 fuzzer.emitReturn ();
165177 }
@@ -1071,13 +1083,13 @@ class DartFuzz {
10711083 }
10721084
10731085 // Emit a return statement.
1074- bool emitReturn ({ bool terminal = false } ) {
1086+ bool emitReturn () {
10751087 List <DartType > proto = getCurrentProto ();
10761088 if (proto == null ) {
10771089 emitLn ('return;' );
10781090 } else {
10791091 emitLn ('return ' , newline: false );
1080- emitExpr (0 , proto[0 ], includeSemicolon: true , terminal : terminal );
1092+ emitExpr (0 , proto[0 ], includeSemicolon: true );
10811093 }
10821094 return false ;
10831095 }
@@ -2012,13 +2024,10 @@ class DartFuzz {
20122024
20132025 // Emit expression.
20142026 void emitExpr (int depth, DartType tp,
2015- {RhsFilter rhsFilter,
2016- bool includeSemicolon = false ,
2017- // Setting terminal to true forces the emission of a terminal.
2018- bool terminal = false }) {
2027+ {RhsFilter rhsFilter, bool includeSemicolon = false }) {
20192028 final resetExprStmt = processExprOpen (tp);
20202029 // Continuing nested expressions becomes less likely as the depth grows.
2021- if (terminal || ( choose (depth + 1 ) > exprDepth) ) {
2030+ if (choose (depth + 1 ) > exprDepth) {
20222031 emitTerminal (depth, tp, rhsFilter: rhsFilter);
20232032 } else {
20242033 // Possibly nested expression.
0 commit comments