From: Alex Lam S.L Date: Fri, 17 Apr 2020 18:53:26 +0000 (+0100) Subject: fix corner cases in `join_vars` (#3790) X-Git-Url: https://git.ndcode.org/public/gitweb.cgi?a=commitdiff_plain;h=da68ec6e190e8969741606b2b2a3eb2d327061ba;p=UglifyJS.git fix corner cases in `join_vars` (#3790) fixes #3789 fixes #3791 --- diff --git a/lib/compress.js b/lib/compress.js index 2491757f..70ac9b8f 100644 --- a/lib/compress.js +++ b/lib/compress.js @@ -2330,7 +2330,7 @@ merge(Compressor.prototype, { statements.length = n; } - function join_assigns(defn, body) { + function join_assigns(defn, body, keep) { var exprs; if (body instanceof AST_Assign) { exprs = [ body ]; @@ -2352,14 +2352,14 @@ merge(Compressor.prototype, { if (defn instanceof AST_Definitions) { var def = defn.definitions[defn.definitions.length - 1]; if (trim_assigns(def.name, def.value, exprs)) trimmed = true; - if (join_var_assign(defn.definitions, exprs)) trimmed = true; + if (join_var_assign(defn.definitions, exprs, keep || 0)) trimmed = true; } return trimmed && exprs; } - function join_var_assign(definitions, exprs) { + function join_var_assign(definitions, exprs, keep) { var trimmed = false; - while (exprs.length) { + while (exprs.length > keep) { var expr = exprs[0]; if (!(expr instanceof AST_Assign)) break; if (expr.operator != "=") break; @@ -2367,7 +2367,9 @@ merge(Compressor.prototype, { if (!(lhs instanceof AST_SymbolRef)) break; if (is_undeclared_ref(lhs)) break; var def = lhs.definition(); - if (def.scope !== definitions[0].name.scope) break; + if (def.scope !== lhs.scope) break; + if (def.orig.length > def.eliminated + 1) break; + if (def.orig[0].TYPE != "SymbolVar") break; var name = make_node(AST_SymbolVar, lhs, lhs); definitions.push(make_node(AST_VarDef, expr, { name: name, @@ -2478,7 +2480,7 @@ merge(Compressor.prototype, { function join_assigns_expr(value) { statements[++j] = stat; - var exprs = join_assigns(prev, value); + var exprs = join_assigns(prev, value, 1); if (!exprs) return value; CHANGED = true; var tail = value.tail_node(); @@ -6045,11 +6047,21 @@ merge(Compressor.prototype, { function can_inject_symbols() { var catches = Object.create(null); + var child; + scope = compressor.self(); do { + child = scope; scope = compressor.parent(++level); if (scope instanceof AST_Catch) { catches[scope.argname.name] = true; - } else if (scope instanceof AST_IterationStatement) { + } else if (scope instanceof AST_DWLoop) { + in_loop = []; + } else if (scope instanceof AST_For) { + if (scope.init === child) continue; + in_loop = []; + } else if (scope instanceof AST_ForIn) { + if (scope.init === child) continue; + if (scope.object === child) continue; in_loop = []; } else if (scope instanceof AST_SymbolRef) { if (scope.fixed_value() instanceof AST_Scope) return false; diff --git a/test/compress/collapse_vars.js b/test/compress/collapse_vars.js index a9167262..fd421a20 100644 --- a/test/compress/collapse_vars.js +++ b/test/compress/collapse_vars.js @@ -804,7 +804,7 @@ collapse_vars_assignment: { function log(x) { return console.log(x), x; } function f0(c) { var a = 3 / c; - return a; + return a = a; } function f1(c) { return 1 - 3 / c; diff --git a/test/compress/join_vars.js b/test/compress/join_vars.js index bfbebdef..9901c486 100644 --- a/test/compress/join_vars.js +++ b/test/compress/join_vars.js @@ -663,3 +663,122 @@ issue_3788: { "PASS", ] } + +issue_3789_1: { + options = { + join_vars: true, + } + input: { + try { + c; + console.log("FAIL"); + } catch (e) { + console.log("PASS"); + } + try {} catch (c) { + var a; + c = 0; + } + } + expect: { + try { + c; + console.log("FAIL"); + } catch (e) { + console.log("PASS"); + } + try {} catch (c) { + var a; + c = 0; + } + } + expect_stdout: "PASS" +} + +issue_3789_2: { + options = { + join_vars: true, + } + input: { + try { + c; + console.log("FAIL"); + } catch (e) { + console.log("PASS"); + } + try {} catch (c) { + try {} catch (c) { + var a; + c = 0; + } + } + } + expect: { + try { + c; + console.log("FAIL"); + } catch (e) { + console.log("PASS"); + } + try {} catch (c) { + try {} catch (c) { + var a; + c = 0; + } + } + } + expect_stdout: "PASS" +} + +issue_3791_1: { + options = { + collapse_vars: true, + join_vars: true, + toplevel: true, + } + input: { + var a = "PASS"; + switch (a) { + case console: + } + var a = a; + console.log(a); + } + expect: { + var a; + switch (a = "PASS") { + case console: + } + var a = a; + console.log(a); + } + expect_stdout: "PASS" +} + +issue_3791_2: { + options = { + collapse_vars: true, + join_vars: true, + } + input: { + function f(a) { + var b; + return b = a || g; + function g() { + return b; + } + } + console.log(typeof f()()); + } + expect: { + function f(a) { + var b; + return b = a || g; + function g() { + return b; + } + } + console.log(typeof f()()); + } + expect_stdout: "function" +} diff --git a/test/ufuzz/index.js b/test/ufuzz/index.js index 24bf86d1..ec2a442c 100644 --- a/test/ufuzz/index.js +++ b/test/ufuzz/index.js @@ -1156,7 +1156,7 @@ for (var round = 1; round <= num_iterations; round++) { uglify_code = uglify_code.code; uglify_result = sandbox.run_code(uglify_code, toplevel); ok = sandbox.same_stdout(original_result, uglify_result); - if (!ok && typeof uglify_result == "string" && o.compress.unsafe_math) { + if (!ok && typeof uglify_result == "string" && o.compress && o.compress.unsafe_math) { ok = fuzzy_match(original_result, uglify_result); if (!ok) { var fuzzy_result = sandbox.run_code(original_code.replace(/( - 0\.1){3}/g, " - 0.3"), toplevel);