[Pkg-javascript-commits] [uglifyjs] 11/491: support safe reassignments in `reduce_vars` (#1823)
Jonas Smedegaard
dr at jones.dk
Wed Feb 14 19:51:17 UTC 2018
This is an automated email from the git hooks/post-receive script.
js pushed a commit to annotated tag debian/3.3.10-1
in repository uglifyjs.
commit 5d9f1da3abc58bce95dd240bd586bedb4eb04771
Author: Alex Lam S.L <alexlamsl at gmail.com>
Date: Tue Apr 18 13:38:42 2017 +0800
support safe reassignments in `reduce_vars` (#1823)
`var a=1;a=2;x(a)` => `x(2)`
fix pre-existing issues
- reference counting on assignment
- walking of anonymous functions
- chained assignment
---
lib/compress.js | 51 +++++++++++++++------
test/compress/collapse_vars.js | 22 +++++++++
test/compress/reduce_vars.js | 102 ++++++++++++++++++++++++++++++++++-------
3 files changed, 145 insertions(+), 30 deletions(-)
diff --git a/lib/compress.js b/lib/compress.js
index 0dfe2a3..596b03f 100644
--- a/lib/compress.js
+++ b/lib/compress.js
@@ -267,7 +267,7 @@ merge(Compressor.prototype, {
if (node instanceof AST_SymbolRef) {
var d = node.definition();
d.references.push(node);
- if (d.fixed === undefined || !is_safe(d)
+ if (d.fixed === undefined || !safe_to_read(d)
|| is_modified(node, 0, is_immutable(node.fixed_value()))) {
d.fixed = false;
}
@@ -277,7 +277,7 @@ merge(Compressor.prototype, {
}
if (node instanceof AST_VarDef) {
var d = node.name.definition();
- if (d.fixed == null) {
+ if (d.fixed === undefined || safe_to_assign(d, node.value)) {
if (node.value) {
d.fixed = function() {
return node.value;
@@ -297,7 +297,8 @@ merge(Compressor.prototype, {
&& node.operator == "="
&& node.left instanceof AST_SymbolRef) {
var d = node.left.definition();
- if (HOP(safe_ids, d.id) && d.fixed == null) {
+ if (safe_to_assign(d, node.right)) {
+ d.references.push(node.left);
d.fixed = function() {
return node.right;
};
@@ -309,7 +310,7 @@ merge(Compressor.prototype, {
}
if (node instanceof AST_Defun) {
var d = node.name.definition();
- if (!toplevel && d.global || is_safe(d)) {
+ if (!toplevel && d.global || safe_to_read(d)) {
d.fixed = false;
} else {
d.fixed = node;
@@ -321,13 +322,12 @@ merge(Compressor.prototype, {
safe_ids = save_ids;
return true;
}
- var iife;
- if (node instanceof AST_Function
- && (iife = tw.parent()) instanceof AST_Call
- && iife.expression === node) {
- if (node.name) {
- node.name.definition().fixed = node;
- } else {
+ if (node instanceof AST_Function) {
+ push();
+ var iife;
+ if (!node.name
+ && (iife = tw.parent()) instanceof AST_Call
+ && iife.expression === node) {
// Virtually turn IIFE parameters into variable definitions:
// (function(a,b) {...})(c,d) => (function() {var a=c,b=d; ...})()
// So existing transformation rules can work on them.
@@ -339,6 +339,9 @@ merge(Compressor.prototype, {
mark(d, true);
});
}
+ descend();
+ pop();
+ return true;
}
if (node instanceof AST_Binary
&& (node.operator == "&&" || node.operator == "||")) {
@@ -385,11 +388,19 @@ merge(Compressor.prototype, {
}
if (node instanceof AST_For) {
if (node.init) node.init.walk(tw);
+ if (node.condition) {
+ push();
+ node.condition.walk(tw);
+ pop();
+ }
push();
- if (node.condition) node.condition.walk(tw);
node.body.walk(tw);
- if (node.step) node.step.walk(tw);
pop();
+ if (node.step) {
+ push();
+ node.step.walk(tw);
+ pop();
+ }
return true;
}
if (node instanceof AST_ForIn) {
@@ -426,7 +437,7 @@ merge(Compressor.prototype, {
safe_ids[def.id] = safe;
}
- function is_safe(def) {
+ function safe_to_read(def) {
if (safe_ids[def.id]) {
if (def.fixed == null) {
var orig = def.orig[0];
@@ -437,6 +448,18 @@ merge(Compressor.prototype, {
}
}
+ function safe_to_assign(def, value) {
+ if (!HOP(safe_ids, def.id)) return false;
+ if (!safe_to_read(def)) return false;
+ if (def.fixed === false) return false;
+ if (def.fixed != null && (!value || def.references.length > 0)) return false;
+ return !def.orig.some(function(sym) {
+ return sym instanceof AST_SymbolConst
+ || sym instanceof AST_SymbolDefun
+ || sym instanceof AST_SymbolLambda;
+ });
+ }
+
function push() {
safe_ids = Object.create(safe_ids);
}
diff --git a/test/compress/collapse_vars.js b/test/compress/collapse_vars.js
index 2264783..c01572d 100644
--- a/test/compress/collapse_vars.js
+++ b/test/compress/collapse_vars.js
@@ -1592,3 +1592,25 @@ var_side_effects_3: {
}
expect_stdout: true
}
+
+reduce_vars_assign: {
+ options = {
+ collapse_vars: true,
+ reduce_vars: true,
+ }
+ input: {
+ !function() {
+ var a = 1;
+ a = [].length,
+ console.log(a);
+ }();
+ }
+ expect: {
+ !function() {
+ var a = 1;
+ a = [].length,
+ console.log(a);
+ }();
+ }
+ expect_stdout: "0"
+}
diff --git a/test/compress/reduce_vars.js b/test/compress/reduce_vars.js
index ad2c90b..c5f2690 100644
--- a/test/compress/reduce_vars.js
+++ b/test/compress/reduce_vars.js
@@ -66,7 +66,7 @@ modified: {
conditionals : true,
evaluate : true,
reduce_vars : true,
- unused : true
+ unused : true,
}
input: {
function f0() {
@@ -136,12 +136,11 @@ modified: {
}
function f2() {
- var b = 2;
- b = 3;
- console.log(1 + b);
- console.log(b + 3);
+ 3;
console.log(4);
- console.log(1 + b + 3);
+ console.log(6);
+ console.log(4);
+ console.log(7);
}
function f3() {
@@ -375,12 +374,11 @@ passes: {
}
expect: {
function f() {
- var b = 2;
- b = 3;
- console.log(1 + b);
- console.log(b + 3);
+ 3;
console.log(4);
- console.log(1 + b + 3);
+ console.log(6);
+ console.log(4);
+ console.log(7);
}
}
}
@@ -573,7 +571,7 @@ inner_var_label: {
}
}
-inner_var_for: {
+inner_var_for_1: {
options = {
evaluate: true,
reduce_vars: true,
@@ -602,6 +600,29 @@ inner_var_for: {
}
}
+inner_var_for_2: {
+ options = {
+ evaluate: true,
+ reduce_vars: true,
+ unused: true,
+ }
+ input: {
+ !function() {
+ var a = 1;
+ for (var b = 1; --b;) var a = 2;
+ console.log(a);
+ }();
+ }
+ expect: {
+ !function() {
+ a = 1;
+ for (var b = 1; --b;) var a = 2;
+ console.log(a);
+ }();
+ }
+ expect_stdout: "1"
+}
+
inner_var_for_in_1: {
options = {
evaluate: true,
@@ -1828,10 +1849,7 @@ redefine_farg_3: {
console.log(function(a) {
var a;
return typeof a;
- }([]), "number", function(a) {
- var a = void 0;
- return typeof a;
- }([]));
+ }([]), "number", "undefined");
}
expect_stdout: "object number undefined"
}
@@ -2115,6 +2133,27 @@ var_assign_5: {
expect_stdout: "2 undefined"
}
+var_assign_6: {
+ options = {
+ evaluate: true,
+ reduce_vars: true,
+ unused: true,
+ }
+ input: {
+ !function() {
+ var a = function(){}(a = 1);
+ console.log(a);
+ }();
+ }
+ expect: {
+ !function() {
+ var a = function(){}(a = 1);
+ console.log(a);
+ }();
+ }
+ expect_stdout: "undefined"
+}
+
immutable: {
options = {
evaluate: true,
@@ -2263,3 +2302,34 @@ cond_assign: {
}
expect_stdout: "undefined"
}
+
+iife_assign: {
+ options = {
+ evaluate: true,
+ reduce_vars: true,
+ unused: true,
+ }
+ input: {
+ !function() {
+ var a = 1, b = 0;
+ !function() {
+ b++;
+ return;
+ a = 2;
+ }();
+ console.log(a);
+ }();
+ }
+ expect: {
+ !function() {
+ var a = 1, b = 0;
+ !function() {
+ b++;
+ return;
+ a = 2;
+ }();
+ console.log(a);
+ }();
+ }
+ expect_stdout: "1"
+}
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-javascript/uglifyjs.git
More information about the Pkg-javascript-commits
mailing list