aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/compress.js26
-rw-r--r--test/compress/collapse_vars.js2
-rw-r--r--test/compress/join_vars.js119
-rw-r--r--test/ufuzz/index.js2
4 files changed, 140 insertions, 9 deletions
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);