diff --git a/tools/js-optimizer.js b/tools/js-optimizer.js index 3cd1b2294..d04807a73 100644 --- a/tools/js-optimizer.js +++ b/tools/js-optimizer.js @@ -2807,6 +2807,23 @@ function asmLoopOptimizer(ast) { var stats = node[2][1]; var last = stats[stats.length-1]; if (last && last[0] === 'if' && !last[3] && last[2][0] === 'block' && last[2][1][0] && last[2][1][0][0] === 'break' && !last[2][1][0][1]) { + var abort = false; + var stack = 0; + traverse(stats, function(node, type) { + if (type == 'continue') { + if (stack == 0 || node[1]) { // abort if labeled (we do not analyze labels here yet), or a continue directly on us + abort = true; + return true; + } + } else if (type in LOOP) { + stack++; + } + }, function(node, type) { + if (type in LOOP) { + stack--; + } + }); + if (abort) return; var conditionToBreak = last[1]; stats.pop(); node[0] = 'do'; diff --git a/tools/test-js-optimizer-asm-last-output.js b/tools/test-js-optimizer-asm-last-output.js index cbc0a4d34..0f95d5448 100644 --- a/tools/test-js-optimizer-asm-last-output.js +++ b/tools/test-js-optimizer-asm-last-output.js @@ -42,5 +42,33 @@ function looop() { do { do_it(); } while (x()); + while (1) { + do_it(); + if (a()) continue; + if (!x()) { + break; + } + } + do { + do_it(); + do { + if (a()) continue; + } while (b()); + } while (x()); + do { + do_it(); + while (b()) { + if (a()) continue; + } + } while (x()); + X : while (1) { + do_it(); + while (b()) { + if (a()) continue X; + } + if (!x()) { + break; + } + } } diff --git a/tools/test-js-optimizer-asm-last.js b/tools/test-js-optimizer-asm-last.js index 6331879ea..05e1049ee 100644 --- a/tools/test-js-optimizer-asm-last.js +++ b/tools/test-js-optimizer-asm-last.js @@ -51,6 +51,40 @@ function looop() { break; } } + while (1) { + do_it(); + if (a()) continue; // we cannot move to do-while, continue will hit the while check + if (!x()) { + break; + } + } + while (1) { + do_it(); + do { + if (a()) continue; // ok to optimize, continue is not for us + } while (b()); + if (!x()) { + break; + } + } + while (1) { + do_it(); + while (b()) { + if (a()) continue; // also ok to optimize, continue is not for us + } + if (!x()) { + break; + } + } + X: while (1) { + do_it(); + while (b()) { + if (a()) continue X; // not ok to optimize + } + if (!x()) { + break; + } + } } // EMSCRIPTEN_GENERATED_FUNCTIONS: ["finall", "looop"]