diff --git a/src/compiler/emitter.ts b/src/compiler/emitter.ts index a91d7a68b8..aaee1e1ef9 100644 --- a/src/compiler/emitter.ts +++ b/src/compiler/emitter.ts @@ -3232,8 +3232,9 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge // loop is considered simple if it does not have any return statements or break\continue that transfer control outside of the loop // simple loops are emitted as just 'loop()'; + // NOTE: if loop uses only 'continue' it still will be emitted as simple loop const isSimpleLoop = - !loop.state.nonLocalJumps && + !(loop.state.nonLocalJumps & ~Jump.Continue) && !loop.state.labeledNonLocalBreaks && !loop.state.labeledNonLocalContinues; @@ -3274,13 +3275,9 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge writeLine(); } - if (loop.state.nonLocalJumps & Jump.Continue) { - write(`if (${loopResult} === "continue") continue;`); - writeLine(); - } - // in case of labeled breaks emit code that either breaks to some known label inside outer loop or delegates jump decision to outer loop emitDispatchTableForLabeledJumps(loopResult, loop.state, convertedLoopState); + // in case of 'continue' we'll just fallthough here } if (emitAsBlock) { @@ -3575,6 +3572,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge } else { convertedLoopState.nonLocalJumps |= Jump.Continue; + // note: return value is emitted only to simplify debugging, call to converted loop body does not do any dispatching on it. write(`"continue";`); } } diff --git a/tests/baselines/reference/blockScopedBindingsReassignedInLoop2.js b/tests/baselines/reference/blockScopedBindingsReassignedInLoop2.js index c48ecd96ff..68bfd3cb67 100644 --- a/tests/baselines/reference/blockScopedBindingsReassignedInLoop2.js +++ b/tests/baselines/reference/blockScopedBindingsReassignedInLoop2.js @@ -73,10 +73,9 @@ var _loop_2 = function(x, y) { }; var out_x_2, out_y_2; for (var x = 1, y = 2; x < y; ++x, --y) { - var state_2 = _loop_2(x, y); + _loop_2(x, y); x = out_x_2; y = out_y_2; - if (state_2 === "continue") continue; } var _loop_3 = function(x, y) { var a = function () { return x++ + y++; }; diff --git a/tests/baselines/reference/blockScopedBindingsReassignedInLoop3.js b/tests/baselines/reference/blockScopedBindingsReassignedInLoop3.js index 1016020262..7e3bac4ff5 100644 --- a/tests/baselines/reference/blockScopedBindingsReassignedInLoop3.js +++ b/tests/baselines/reference/blockScopedBindingsReassignedInLoop3.js @@ -147,9 +147,8 @@ var _loop_3 = function(x, y) { }; var out_a_2_1; for (var a_2 = 1; a_2 < 5; --a_2) { - var state_3 = _loop_4(a_2); + _loop_4(a_2); a_2 = out_a_2_1; - if (state_3 === "continue") continue; } y = 5; } @@ -158,10 +157,9 @@ var _loop_3 = function(x, y) { }; var out_x_2, out_y_2; for (var x = 1, y = 2; x < y; ++x, --y) { - var state_4 = _loop_3(x, y); + _loop_3(x, y); x = out_x_2; y = out_y_2; - if (state_4 === "continue") continue; } var _loop_5 = function(x, y) { var a = function () { return x++ + y++; }; diff --git a/tests/baselines/reference/capturedLetConstInLoop6.js b/tests/baselines/reference/capturedLetConstInLoop6.js index e196950e69..6a2b4c9a33 100644 --- a/tests/baselines/reference/capturedLetConstInLoop6.js +++ b/tests/baselines/reference/capturedLetConstInLoop6.js @@ -254,7 +254,6 @@ for (var _i = 0, _a = []; _i < _a.length; _i++) { var x = _a[_i]; var state_1 = _loop_1(x); if (state_1 === "break") break; - if (state_1 === "continue") continue; } var _loop_2 = function(x) { (function () { return x; }); @@ -269,7 +268,6 @@ var _loop_2 = function(x) { for (var x in []) { var state_2 = _loop_2(x); if (state_2 === "break") break; - if (state_2 === "continue") continue; } var _loop_3 = function(x) { (function () { return x; }); @@ -284,7 +282,6 @@ var _loop_3 = function(x) { for (var x = 0; x < 1; ++x) { var state_3 = _loop_3(x); if (state_3 === "break") break; - if (state_3 === "continue") continue; } var _loop_4 = function() { var x; @@ -300,7 +297,6 @@ var _loop_4 = function() { while (1 === 1) { var state_4 = _loop_4(); if (state_4 === "break") break; - if (state_4 === "continue") continue; } var _loop_5 = function() { var x; @@ -316,7 +312,6 @@ var _loop_5 = function() { do { var state_5 = _loop_5(); if (state_5 === "break") break; - if (state_5 === "continue") continue; } while (1 === 1); var _loop_6 = function(y) { var x = 1; @@ -332,7 +327,6 @@ var _loop_6 = function(y) { for (var y = 0; y < 1; ++y) { var state_6 = _loop_6(y); if (state_6 === "break") break; - if (state_6 === "continue") continue; } var _loop_7 = function(x, y) { (function () { return x + y; }); @@ -347,7 +341,6 @@ var _loop_7 = function(x, y) { for (var x = 0, y = 1; x < 1; ++x) { var state_7 = _loop_7(x, y); if (state_7 === "break") break; - if (state_7 === "continue") continue; } var _loop_8 = function() { var x, y; @@ -363,7 +356,6 @@ var _loop_8 = function() { while (1 === 1) { var state_8 = _loop_8(); if (state_8 === "break") break; - if (state_8 === "continue") continue; } var _loop_9 = function() { var x, y; @@ -379,7 +371,6 @@ var _loop_9 = function() { do { var state_9 = _loop_9(); if (state_9 === "break") break; - if (state_9 === "continue") continue; } while (1 === 1); var _loop_10 = function(y) { var x = 1; @@ -395,7 +386,6 @@ var _loop_10 = function(y) { for (var y = 0; y < 1; ++y) { var state_10 = _loop_10(y); if (state_10 === "break") break; - if (state_10 === "continue") continue; } // ====const var _loop_11 = function(x) { @@ -412,7 +402,6 @@ for (var _b = 0, _c = []; _b < _c.length; _b++) { var x = _c[_b]; var state_11 = _loop_11(x); if (state_11 === "break") break; - if (state_11 === "continue") continue; } var _loop_12 = function(x) { (function () { return x; }); @@ -427,7 +416,6 @@ var _loop_12 = function(x) { for (var x in []) { var state_12 = _loop_12(x); if (state_12 === "break") break; - if (state_12 === "continue") continue; } var _loop_13 = function(x) { (function () { return x; }); @@ -442,7 +430,6 @@ var _loop_13 = function(x) { for (var x = 0; x < 1;) { var state_13 = _loop_13(x); if (state_13 === "break") break; - if (state_13 === "continue") continue; } var _loop_14 = function() { var x = 1; @@ -458,7 +445,6 @@ var _loop_14 = function() { while (1 === 1) { var state_14 = _loop_14(); if (state_14 === "break") break; - if (state_14 === "continue") continue; } var _loop_15 = function() { var x = 1; @@ -474,7 +460,6 @@ var _loop_15 = function() { do { var state_15 = _loop_15(); if (state_15 === "break") break; - if (state_15 === "continue") continue; } while (1 === 1); var _loop_16 = function(y) { var x = 1; @@ -490,7 +475,6 @@ var _loop_16 = function(y) { for (var y = 0; y < 1;) { var state_16 = _loop_16(y); if (state_16 === "break") break; - if (state_16 === "continue") continue; } var _loop_17 = function(x, y) { (function () { return x + y; }); @@ -505,7 +489,6 @@ var _loop_17 = function(x, y) { for (var x = 0, y = 1; x < 1;) { var state_17 = _loop_17(x, y); if (state_17 === "break") break; - if (state_17 === "continue") continue; } var _loop_18 = function() { var x = 1, y = 1; @@ -521,7 +504,6 @@ var _loop_18 = function() { while (1 === 1) { var state_18 = _loop_18(); if (state_18 === "break") break; - if (state_18 === "continue") continue; } var _loop_19 = function() { var x = 1, y = 1; @@ -537,7 +519,6 @@ var _loop_19 = function() { do { var state_19 = _loop_19(); if (state_19 === "break") break; - if (state_19 === "continue") continue; } while (1 === 1); var _loop_20 = function(y) { var x = 1; @@ -553,5 +534,4 @@ var _loop_20 = function(y) { for (var y = 0; y < 1;) { var state_20 = _loop_20(y); if (state_20 === "break") break; - if (state_20 === "continue") continue; } diff --git a/tests/baselines/reference/capturedLetConstInLoop7.js b/tests/baselines/reference/capturedLetConstInLoop7.js index 8df93bca60..56b84e7802 100644 --- a/tests/baselines/reference/capturedLetConstInLoop7.js +++ b/tests/baselines/reference/capturedLetConstInLoop7.js @@ -397,7 +397,6 @@ l0: for (var _i = 0, _a = []; _i < _a.length; _i++) { var x = _a[_i]; var state_1 = _loop_1(x); if (state_1 === "break") break; - if (state_1 === "continue") continue; switch(state_1) { case "break-l0": break l0; case "continue-l0": continue l0; @@ -422,7 +421,6 @@ var _loop_2 = function(x) { l00: for (var x in []) { var state_2 = _loop_2(x); if (state_2 === "break") break; - if (state_2 === "continue") continue; switch(state_2) { case "break-l00": break l00; case "continue-l00": continue l00; @@ -447,7 +445,6 @@ var _loop_3 = function(x) { l1: for (var x = 0; x < 1; ++x) { var state_3 = _loop_3(x); if (state_3 === "break") break; - if (state_3 === "continue") continue; switch(state_3) { case "break-l1": break l1; case "continue-l1": continue l1; @@ -473,7 +470,6 @@ var _loop_4 = function() { l2: while (1 === 1) { var state_4 = _loop_4(); if (state_4 === "break") break; - if (state_4 === "continue") continue; switch(state_4) { case "break-l2": break l2; case "continue-l2": continue l2; @@ -499,7 +495,6 @@ var _loop_5 = function() { l3: do { var state_5 = _loop_5(); if (state_5 === "break") break; - if (state_5 === "continue") continue; switch(state_5) { case "break-l3": break l3; case "continue-l3": continue l3; @@ -525,7 +520,6 @@ var _loop_6 = function(y) { l4: for (var y = 0; y < 1; ++y) { var state_6 = _loop_6(y); if (state_6 === "break") break; - if (state_6 === "continue") continue; switch(state_6) { case "break-l4": break l4; case "continue-l4": continue l4; @@ -550,7 +544,6 @@ var _loop_7 = function(x, y) { l5: for (var x = 0, y = 1; x < 1; ++x) { var state_7 = _loop_7(x, y); if (state_7 === "break") break; - if (state_7 === "continue") continue; switch(state_7) { case "break-l5": break l5; case "continue-l5": continue l5; @@ -576,7 +569,6 @@ var _loop_8 = function() { l6: while (1 === 1) { var state_8 = _loop_8(); if (state_8 === "break") break; - if (state_8 === "continue") continue; switch(state_8) { case "break-l6": break l6; case "continue-l6": continue l6; @@ -602,7 +594,6 @@ var _loop_9 = function() { l7: do { var state_9 = _loop_9(); if (state_9 === "break") break; - if (state_9 === "continue") continue; switch(state_9) { case "break-l7": break l7; case "continue-l7": continue l7; @@ -628,7 +619,6 @@ var _loop_10 = function(y) { l8: for (var y = 0; y < 1; ++y) { var state_10 = _loop_10(y); if (state_10 === "break") break; - if (state_10 === "continue") continue; switch(state_10) { case "break-l8": break l8; case "continue-l8": continue l8; @@ -655,7 +645,6 @@ l0_c: for (var _b = 0, _c = []; _b < _c.length; _b++) { var x = _c[_b]; var state_11 = _loop_11(x); if (state_11 === "break") break; - if (state_11 === "continue") continue; switch(state_11) { case "break-l0_c": break l0_c; case "continue-l0_c": continue l0_c; @@ -680,7 +669,6 @@ var _loop_12 = function(x) { l00_c: for (var x in []) { var state_12 = _loop_12(x); if (state_12 === "break") break; - if (state_12 === "continue") continue; switch(state_12) { case "break-l00_c": break l00_c; case "continue-l00_c": continue l00_c; @@ -705,7 +693,6 @@ var _loop_13 = function(x) { l1_c: for (var x = 0; x < 1;) { var state_13 = _loop_13(x); if (state_13 === "break") break; - if (state_13 === "continue") continue; switch(state_13) { case "break-l1_c": break l1_c; case "continue-l1_c": continue l1_c; @@ -731,7 +718,6 @@ var _loop_14 = function() { l2_c: while (1 === 1) { var state_14 = _loop_14(); if (state_14 === "break") break; - if (state_14 === "continue") continue; switch(state_14) { case "break-l2_c": break l2_c; case "continue-l2_c": continue l2_c; @@ -757,7 +743,6 @@ var _loop_15 = function() { l3_c: do { var state_15 = _loop_15(); if (state_15 === "break") break; - if (state_15 === "continue") continue; switch(state_15) { case "break-l3_c": break l3_c; case "continue-l3_c": continue l3_c; @@ -783,7 +768,6 @@ var _loop_16 = function(y) { l4_c: for (var y = 0; y < 1;) { var state_16 = _loop_16(y); if (state_16 === "break") break; - if (state_16 === "continue") continue; switch(state_16) { case "break-l4_c": break l4_c; case "continue-l4_c": continue l4_c; @@ -808,7 +792,6 @@ var _loop_17 = function(x, y) { l5_c: for (var x = 0, y = 1; x < 1;) { var state_17 = _loop_17(x, y); if (state_17 === "break") break; - if (state_17 === "continue") continue; switch(state_17) { case "break-l5_c": break l5_c; case "continue-l5_c": continue l5_c; @@ -834,7 +817,6 @@ var _loop_18 = function() { l6_c: while (1 === 1) { var state_18 = _loop_18(); if (state_18 === "break") break; - if (state_18 === "continue") continue; switch(state_18) { case "break-l6_c": break l6_c; case "continue-l6_c": continue l6_c; @@ -860,7 +842,6 @@ var _loop_19 = function() { l7_c: do { var state_19 = _loop_19(); if (state_19 === "break") break; - if (state_19 === "continue") continue; switch(state_19) { case "break-l7_c": break l7_c; case "continue-l7_c": continue l7_c; @@ -886,7 +867,6 @@ var _loop_20 = function(y) { l8_c: for (var y = 0; y < 1;) { var state_20 = _loop_20(y); if (state_20 === "break") break; - if (state_20 === "continue") continue; switch(state_20) { case "break-l8_c": break l8_c; case "continue-l8_c": continue l8_c; diff --git a/tests/baselines/reference/capturedLetConstInLoop8.js b/tests/baselines/reference/capturedLetConstInLoop8.js index 560b99bb56..122bdb96e3 100644 --- a/tests/baselines/reference/capturedLetConstInLoop8.js +++ b/tests/baselines/reference/capturedLetConstInLoop8.js @@ -165,7 +165,6 @@ function foo() { var state_1 = _loop_2(y); if (typeof state_1 === "object") return state_1; if (state_1 === "break") break; - if (state_1 === "continue") continue; switch(state_1) { case "break-l1": return state_1; case "break-ll1": break ll1; @@ -200,7 +199,6 @@ function foo() { var state_2 = _loop_1(x); if (typeof state_2 === "object") return state_2.value; if (state_2 === "break") break; - if (state_2 === "continue") continue; switch(state_2) { case "break-l1": break l1; case "continue-l0": continue l0; @@ -247,7 +245,6 @@ function foo_c() { var state_3 = _loop_4(y); if (typeof state_3 === "object") return state_3; if (state_3 === "break") break; - if (state_3 === "continue") continue; switch(state_3) { case "break-l1": return state_3; case "break-ll1": break ll1; @@ -282,7 +279,6 @@ function foo_c() { var state_4 = _loop_3(x); if (typeof state_4 === "object") return state_4.value; if (state_4 === "break") break; - if (state_4 === "continue") continue; switch(state_4) { case "break-l1": break l1; case "continue-l0": continue l0; diff --git a/tests/baselines/reference/continueInLoopsWithCapturedBlockScopedBindings1.js b/tests/baselines/reference/continueInLoopsWithCapturedBlockScopedBindings1.js new file mode 100644 index 0000000000..431bdee6c8 --- /dev/null +++ b/tests/baselines/reference/continueInLoopsWithCapturedBlockScopedBindings1.js @@ -0,0 +1,30 @@ +//// [continueInLoopsWithCapturedBlockScopedBindings1.ts] +function foo() { + for (const i of [0, 1]) { + if (i === 0) { + continue; + } + + // Trigger non-simple-loop emit + (() => { + return i; + })(); + } +} + +//// [continueInLoopsWithCapturedBlockScopedBindings1.js] +function foo() { + var _loop_1 = function(i) { + if (i === 0) { + return "continue"; + } + // Trigger non-simple-loop emit + (function () { + return i; + })(); + }; + for (var _i = 0, _a = [0, 1]; _i < _a.length; _i++) { + var i = _a[_i]; + _loop_1(i); + } +} diff --git a/tests/baselines/reference/continueInLoopsWithCapturedBlockScopedBindings1.symbols b/tests/baselines/reference/continueInLoopsWithCapturedBlockScopedBindings1.symbols new file mode 100644 index 0000000000..bce177ca81 --- /dev/null +++ b/tests/baselines/reference/continueInLoopsWithCapturedBlockScopedBindings1.symbols @@ -0,0 +1,21 @@ +=== tests/cases/compiler/continueInLoopsWithCapturedBlockScopedBindings1.ts === +function foo() { +>foo : Symbol(foo, Decl(continueInLoopsWithCapturedBlockScopedBindings1.ts, 0, 0)) + + for (const i of [0, 1]) { +>i : Symbol(i, Decl(continueInLoopsWithCapturedBlockScopedBindings1.ts, 1, 14)) + + if (i === 0) { +>i : Symbol(i, Decl(continueInLoopsWithCapturedBlockScopedBindings1.ts, 1, 14)) + + continue; + } + + // Trigger non-simple-loop emit + (() => { + return i; +>i : Symbol(i, Decl(continueInLoopsWithCapturedBlockScopedBindings1.ts, 1, 14)) + + })(); + } +} diff --git a/tests/baselines/reference/continueInLoopsWithCapturedBlockScopedBindings1.types b/tests/baselines/reference/continueInLoopsWithCapturedBlockScopedBindings1.types new file mode 100644 index 0000000000..2aeb286d60 --- /dev/null +++ b/tests/baselines/reference/continueInLoopsWithCapturedBlockScopedBindings1.types @@ -0,0 +1,30 @@ +=== tests/cases/compiler/continueInLoopsWithCapturedBlockScopedBindings1.ts === +function foo() { +>foo : () => void + + for (const i of [0, 1]) { +>i : number +>[0, 1] : number[] +>0 : number +>1 : number + + if (i === 0) { +>i === 0 : boolean +>i : number +>0 : number + + continue; + } + + // Trigger non-simple-loop emit + (() => { +>(() => { return i; })() : number +>(() => { return i; }) : () => number +>() => { return i; } : () => number + + return i; +>i : number + + })(); + } +} diff --git a/tests/cases/compiler/continueInLoopsWithCapturedBlockScopedBindings1.ts b/tests/cases/compiler/continueInLoopsWithCapturedBlockScopedBindings1.ts new file mode 100644 index 0000000000..8a17435edd --- /dev/null +++ b/tests/cases/compiler/continueInLoopsWithCapturedBlockScopedBindings1.ts @@ -0,0 +1,13 @@ +// @target: ES5 +function foo() { + for (const i of [0, 1]) { + if (i === 0) { + continue; + } + + // Trigger non-simple-loop emit + (() => { + return i; + })(); + } +} \ No newline at end of file