From cbf7269296896bdaf7cc29ec20e41434b5e6365a Mon Sep 17 00:00:00 2001 From: "Alex Lam S.L" Date: Sun, 1 Nov 2020 02:37:21 +0000 Subject: [PATCH] fix corner case in `merge_vars` (#4254) fixes #4253 --- lib/compress.js | 39 +++++++++++++++++++++++-------------- test/compress/merge_vars.js | 32 ++++++++++++++++++++++++++++++ 2 files changed, 56 insertions(+), 15 deletions(-) diff --git a/lib/compress.js b/lib/compress.js index e8c88016..8eb36191 100644 --- a/lib/compress.js +++ b/lib/compress.js @@ -4469,6 +4469,11 @@ merge(Compressor.prototype, { pop(); return true; } + if (node instanceof AST_Break) { + var target = tw.loopcontrol_target(node); + if (!(target instanceof AST_IterationStatement)) insert(target); + return true; + } if (node instanceof AST_Conditional) { node.condition.walk(tw); push(); @@ -4488,20 +4493,7 @@ merge(Compressor.prototype, { } if (node instanceof AST_Continue) { var target = tw.loopcontrol_target(node); - if (!(target instanceof AST_Do)) return true; - var stack = []; - while (!HOP(segment, "block") || segment.block !== target) { - stack.push(segment); - pop(); - } - segment.loop = "c"; - push(); - while (stack.length) { - var seg = stack.pop(); - push(); - if (HOP(seg, "block")) segment.block = seg.block; - if (HOP(seg, "loop")) segment.loop = seg.loop; - } + if (target instanceof AST_Do) insert(target); return true; } if (node instanceof AST_Do) { @@ -4550,7 +4542,7 @@ merge(Compressor.prototype, { } if (node instanceof AST_LabeledStatement) { push(); - segment.block = node; + segment.block = node.body; node.body.walk(tw); pop(); return true; @@ -4587,6 +4579,7 @@ merge(Compressor.prototype, { segment = save; node.body.forEach(function(branch) { push(); + segment.block = node; walk_body(branch, tw); pop(); }); @@ -4742,6 +4735,22 @@ merge(Compressor.prototype, { }); } + function insert(target) { + var stack = []; + while (!HOP(segment, "block") || segment.block !== target) { + stack.push(segment); + pop(); + } + segment.loop = "c"; + push(); + while (stack.length) { + var seg = stack.pop(); + push(); + if (HOP(seg, "block")) segment.block = seg.block; + if (HOP(seg, "loop")) segment.loop = seg.loop; + } + } + function must_visit(base, segment) { return base === segment || base.isPrototypeOf(segment); } diff --git a/test/compress/merge_vars.js b/test/compress/merge_vars.js index 6ada9297..b61b486d 100644 --- a/test/compress/merge_vars.js +++ b/test/compress/merge_vars.js @@ -3092,3 +3092,35 @@ issue_4237_2: { } expect_stdout: "PASS" } + +issue_4253: { + options = { + merge_vars: true, + toplevel: true, + } + input: { + switch (0) { + default: + var a = "FAIL"; + a = a && a; + try { + break; + } catch (e) {} + var b = 42; + } + console.log(b); + } + expect: { + switch (0) { + default: + var a = "FAIL"; + a = a && a; + try { + break; + } catch (e) {} + var b = 42; + } + console.log(b); + } + expect_stdout: "undefined" +} -- 2.34.1