@@ -83,6 +83,9 @@ static size_t timeout = 2;
8383// default of enabling all features should work in most cases.
8484static std::string extraFlags = " -all" ;
8585
86+ // Whether to save all intermediate working files as we go.
87+ static bool saveAllWorkingFiles = false ;
88+
8689struct ProgramResult {
8790 int code;
8891 std::string output;
@@ -231,6 +234,11 @@ ProgramResult expected;
231234// case we may try again but much later.
232235static std::unordered_set<Name> functionsWeTriedToRemove;
233236
237+ // The index of the working file we save, when saveAllWorkingFiles. We must
238+ // store this globally so that the difference instances of Reducer do not
239+ // overlap.
240+ static size_t workingFileIndex = 0 ;
241+
234242struct Reducer
235243 : public WalkerPass<PostWalker<Reducer, UnifiedExpressionVisitor<Reducer>>> {
236244 std::string command, test, working;
@@ -322,7 +330,7 @@ struct Reducer
322330 if (ProgramResult (command) == expected) {
323331 std::cerr << " | command \" " << currCommand
324332 << " \" succeeded, reduced size to " << newSize << ' \n ' ;
325- copy_file (test, working );
333+ applyTestToWorking ( );
326334 more = true ;
327335 oldSize = newSize;
328336 }
@@ -335,6 +343,16 @@ struct Reducer
335343 }
336344 }
337345
346+ // Apply the test file to the working file, after we saw that it successfully
347+ // reduced the testcase.
348+ void applyTestToWorking () {
349+ copy_file (test, working);
350+
351+ if (saveAllWorkingFiles) {
352+ copy_file (working, working + ' .' + std::to_string (workingFileIndex++));
353+ }
354+ }
355+
338356 // does one pass of slow and destructive reduction. returns whether it
339357 // succeeded or not
340358 // the criterion here is a logical change in the program. this may actually
@@ -471,7 +489,7 @@ struct Reducer
471489
472490 void noteReduction (size_t amount = 1 ) {
473491 reduced += amount;
474- copy_file (test, working );
492+ applyTestToWorking ( );
475493 }
476494
477495 // tests a reduction on an arbitrary child
@@ -1302,6 +1320,15 @@ int main(int argc, const char* argv[]) {
13021320 extraFlags = argument;
13031321 std::cout << " |applying extraFlags: " << extraFlags << " \n " ;
13041322 })
1323+ .add (" --save-all-working" ,
1324+ " -saw" ,
1325+ " Save all intermediate working files, as $WORKING.0, .1, .2 etc" ,
1326+ WasmReduceOption,
1327+ Options::Arguments::Zero,
1328+ [&](Options* o, const std::string& argument) {
1329+ saveAllWorkingFiles = true ;
1330+ std::cout << " |saving all intermediate working files\n " ;
1331+ })
13051332 .add_positional (
13061333 " INFILE" ,
13071334 Options::Arguments::One,
0 commit comments