From: Alex Lam S.L Date: Mon, 13 May 2019 21:26:40 +0000 (+0800) Subject: enhance `side_effects` (#3410) X-Git-Url: https://git.ndcode.org/public/gitweb.cgi?a=commitdiff_plain;h=d538a732501f6654ce359ae3ee44a55a873c6a7d;p=UglifyJS.git enhance `side_effects` (#3410) --- diff --git a/lib/compress.js b/lib/compress.js index 57df130a..71f2eae1 100644 --- a/lib/compress.js +++ b/lib/compress.js @@ -347,6 +347,12 @@ merge(Compressor.prototype, { } } + function is_arguments(def) { + if (def.name != "arguments") return false; + var orig = def.orig; + return orig.length == 1 && orig[0] instanceof AST_SymbolFunarg; + } + (function(def) { def(AST_Node, noop); @@ -444,9 +450,8 @@ merge(Compressor.prototype, { if (def.single_use == "m") return false; if (tw.safe_ids[def.id]) { if (def.fixed == null) { - var orig = def.orig[0]; - if (orig instanceof AST_SymbolFunarg || orig.name == "arguments") return false; - def.fixed = make_node(AST_Undefined, orig); + if (is_arguments(def)) return false; + def.fixed = make_node(AST_Undefined, def.orig); } return true; } @@ -522,7 +527,9 @@ merge(Compressor.prototype, { if (!(node instanceof AST_Sub)) return; var expr = node.expression; var prop = node.property; - if (expr instanceof AST_SymbolRef && expr.name == "arguments" && prop instanceof AST_Number) { + if (expr instanceof AST_SymbolRef + && is_arguments(expr.definition()) + && prop instanceof AST_Number) { expr.definition().reassigned = true; } } @@ -791,7 +798,7 @@ merge(Compressor.prototype, { }); def(AST_Unary, function(tw, descend) { var node = this; - if (node.operator != "++" && node.operator != "--") return; + if (!unary_arithmetic[node.operator]) return; var exp = node.expression; if (!(exp instanceof AST_SymbolRef)) { mark_assignment_to_arguments(exp); @@ -1437,7 +1444,7 @@ merge(Compressor.prototype, { extract_candidates(expr.expression); expr.body.forEach(extract_candidates); } else if (expr instanceof AST_Unary) { - if (expr.operator == "++" || expr.operator == "--") { + if (unary_arithmetic[expr.operator]) { candidates.push(hit_stack.slice()); } else { extract_candidates(expr.expression); @@ -1507,9 +1514,9 @@ merge(Compressor.prototype, { function mangleable_var(var_def) { var value = var_def.value; if (!(value instanceof AST_SymbolRef)) return; - if (value.name == "arguments") return; var def = value.definition(); if (def.undeclared) return; + if (is_arguments(def)) return; return value_def = def; } @@ -2313,6 +2320,7 @@ merge(Compressor.prototype, { if (!is_strict(compressor)) return false; if (is_undeclared_ref(this) && this.is_declared(compressor)) return false; if (this.is_immutable()) return false; + if (is_arguments(this.definition())) return false; var fixed = this.fixed_value(); if (!fixed) return true; this._dot_throw = return_true; @@ -2555,6 +2563,7 @@ merge(Compressor.prototype, { }); var lazy_op = makePredicate("&& ||"); + var unary_arithmetic = makePredicate("++ --"); var unary_side_effects = makePredicate("delete ++ --"); function is_lhs(node, parent) { @@ -4412,8 +4421,9 @@ merge(Compressor.prototype, { OPT(AST_For, function(self, compressor) { if (!compressor.option("loops")) return self; - if (compressor.option("side_effects") && self.init) { - self.init = self.init.drop_side_effect_free(compressor); + if (compressor.option("side_effects")) { + if (self.init) self.init = self.init.drop_side_effect_free(compressor); + if (self.step) self.step = self.step.drop_side_effect_free(compressor); } if (self.condition) { var cond = self.condition.evaluate(compressor); @@ -6644,8 +6654,7 @@ merge(Compressor.prototype, { var fn; if (compressor.option("arguments") && expr instanceof AST_SymbolRef - && expr.name == "arguments" - && expr.definition().orig.length == 1 + && is_arguments(expr.definition()) && prop instanceof AST_Number && (fn = expr.scope) === compressor.find_parent(AST_Lambda)) { var index = prop.getValue(); diff --git a/test/compress/loops.js b/test/compress/loops.js index 137fd9da..d835080d 100644 --- a/test/compress/loops.js +++ b/test/compress/loops.js @@ -673,3 +673,19 @@ issue_3371: { } expect_stdout: "PASS" } + +step: { + options = { + loops: true, + side_effects: true, + } + input: { + for (var i = 0; i < 42; "foo", i++, "bar"); + console.log(i); + } + expect: { + for (var i = 0; i < 42; i++); + console.log(i); + } + expect_stdout: "42" +} diff --git a/test/compress/pure_getters.js b/test/compress/pure_getters.js index 61ce8a92..b6e42f9d 100644 --- a/test/compress/pure_getters.js +++ b/test/compress/pure_getters.js @@ -1161,3 +1161,29 @@ collapse_rhs_lhs: { } expect_stdout: "1 3" } + +drop_arguments: { + options = { + pure_getters: "strict", + side_effects: true, + } + input: { + (function() { + arguments.slice = function() { + console.log("PASS"); + }; + arguments[42]; + arguments.length; + arguments.slice(); + })(); + } + expect: { + (function() { + arguments.slice = function() { + console.log("PASS"); + }; + arguments.slice(); + })(); + } + expect_stdout: "PASS" +}