[Pkg-javascript-commits] [uglifyjs] 268/491: preserve function identity in `reduce_vars` (#2451)
Jonas Smedegaard
dr at jones.dk
Wed Feb 14 19:51:43 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 4c0b0177b6fa556c31f0099c6d52a4ad4f670ba3
Author: Alex Lam S.L <alexlamsl at gmail.com>
Date: Wed Nov 8 03:28:46 2017 +0800
preserve function identity in `reduce_vars` (#2451)
fixes #2450
---
lib/compress.js | 45 ++++++++-----
test/compress/reduce_vars.js | 154 +++++++++++++++++++++++++++++++++++++++++--
2 files changed, 176 insertions(+), 23 deletions(-)
diff --git a/lib/compress.js b/lib/compress.js
index 274ab60..6354197 100644
--- a/lib/compress.js
+++ b/lib/compress.js
@@ -324,9 +324,8 @@ merge(Compressor.prototype, {
|| value.is_constant_expression(node.scope);
} else {
d.single_use = d.scope === node.scope
- && loop_ids[d.id] === in_loop
&& value.is_constant_expression();
- }
+ }
} else {
d.single_use = false;
}
@@ -384,6 +383,7 @@ merge(Compressor.prototype, {
d.fixed = false;
} else {
d.fixed = node;
+ loop_ids[d.id] = in_loop;
mark(d, true);
if (ref_once(d)) {
d.single_use = d.scope === d.references[0].scope
@@ -577,7 +577,11 @@ merge(Compressor.prototype, {
}
function ref_once(def) {
- return unused && !def.scope.uses_eval && !def.scope.uses_with && def.references.length == 1;
+ return unused
+ && !def.scope.uses_eval
+ && !def.scope.uses_with
+ && def.references.length == 1
+ && loop_ids[def.id] === in_loop;
}
function is_immutable(value) {
@@ -623,7 +627,8 @@ merge(Compressor.prototype, {
function mark_escaped(d, node, value, level) {
var parent = tw.parent(level);
- if (value instanceof AST_Constant || value instanceof AST_Function) return;
+ if (value instanceof AST_Constant) return;
+ if (level > 0 && value instanceof AST_Function) return;
if (parent instanceof AST_Assign && parent.operator == "=" && node === parent.right
|| parent instanceof AST_Call && node !== parent.expression
|| parent instanceof AST_Return && node === parent.value && node.scope !== d.scope
@@ -4216,6 +4221,17 @@ merge(Compressor.prototype, {
return self;
});
+ function recursive_ref(compressor, def) {
+ var node;
+ for (var i = 0; node = compressor.parent(i); i++) {
+ if (node instanceof AST_Lambda) {
+ var name = node.name;
+ if (name && name.definition() === def) break;
+ }
+ }
+ return node;
+ }
+
OPT(AST_SymbolRef, function(self, compressor){
var def = self.resolve_defines(compressor);
if (def) {
@@ -4241,20 +4257,13 @@ merge(Compressor.prototype, {
if (fixed instanceof AST_Defun) {
d.fixed = fixed = make_node(AST_Function, fixed, fixed);
}
- if (fixed && d.single_use) {
- var recurse;
- if (fixed instanceof AST_Function) {
- for (var i = 0; recurse = compressor.parent(i); i++) {
- if (recurse instanceof AST_Lambda) {
- var name = recurse.name;
- if (name && name.definition() === d) break;
- }
- }
- }
- if (!recurse) {
- var value = fixed.optimize(compressor);
- return value === fixed ? fixed.clone(true) : value;
- }
+ if (fixed
+ && d.single_use
+ && !(fixed instanceof AST_Function
+ && (d.escaped && d.scope !== self.scope
+ || recursive_ref(compressor, d)))) {
+ var value = fixed.optimize(compressor);
+ return value === fixed ? fixed.clone(true) : value;
}
if (fixed && d.should_replace === undefined) {
var init;
diff --git a/test/compress/reduce_vars.js b/test/compress/reduce_vars.js
index f1a27ff..8afea85 100644
--- a/test/compress/reduce_vars.js
+++ b/test/compress/reduce_vars.js
@@ -1123,11 +1123,12 @@ toplevel_on_loops_1: {
while (x);
}
expect: {
+ function bar() {
+ console.log("bar:", --x);
+ }
var x = 3;
do
- (function() {
- console.log("bar:", --x);
- })();
+ bar();
while (x);
}
expect_stdout: true
@@ -1180,9 +1181,10 @@ toplevel_on_loops_2: {
while (x);
}
expect: {
- for (;;) (function() {
+ function bar() {
console.log("bar:");
- })();
+ }
+ for (;;) bar();
}
}
@@ -3845,3 +3847,145 @@ recursive_inlining_5: {
"foo 0",
]
}
+
+issue_2450_1: {
+ options = {
+ reduce_vars: true,
+ toplevel: true,
+ unused: true,
+ }
+ input: {
+ function f() {}
+ function g() {
+ return f;
+ }
+ console.log(g() === g());
+ }
+ expect: {
+ function f() {}
+ function g() {
+ return f;
+ }
+ console.log(g() === g());
+ }
+ expect_stdout: "true"
+}
+
+issue_2450_2: {
+ options = {
+ reduce_vars: true,
+ toplevel: true,
+ unused: true,
+ }
+ input: {
+ function g() {
+ function f() {}
+ return f;
+ }
+ console.log(g() === g());
+ }
+ expect: {
+ function g() {
+ return function() {};
+ }
+ console.log(g() === g());
+ }
+ expect_stdout: "false"
+}
+
+issue_2450_3: {
+ options = {
+ reduce_vars: true,
+ unused: true,
+ }
+ input: {
+ var x = (function() {
+ function test() {
+ return "foo";
+ }
+ return function b() {
+ return [1, test];
+ }
+ })();
+ console.log(x()[1] === x()[1]);
+ }
+ expect: {
+ var x = (function() {
+ function test() {
+ return "foo";
+ }
+ return function() {
+ return [1, test];
+ }
+ })();
+ console.log(x()[1] === x()[1]);
+ }
+ expect_stdout: "true"
+}
+
+issue_2450_4: {
+ options = {
+ reduce_vars: true,
+ toplevel: true,
+ unused: true,
+ }
+ input: {
+ var a;
+ function f(b) {
+ console.log(a === b);
+ a = b;
+ }
+ function g() {}
+ for (var i = 3; --i >= 0;)
+ f(g);
+ }
+ expect: {
+ var a;
+ function f(b) {
+ console.log(a === b);
+ a = b;
+ }
+ function g() {}
+ for (var i = 3; --i >= 0;)
+ f(g);
+ }
+ expect_stdout: [
+ "false",
+ "true",
+ "true",
+ ]
+}
+
+issue_2450_5: {
+ options = {
+ reduce_vars: true,
+ toplevel: true,
+ unused: true,
+ }
+ input: {
+ var a;
+ function f(b) {
+ console.log(a === b);
+ a = b;
+ }
+ function g() {}
+ [1, 2, 3].forEach(function() {
+ f(g);
+ });
+ }
+ expect: {
+ var a;
+ function g() {}
+ [1, 2, 3].forEach(function() {
+ (function(b) {
+ console.log(a === b);
+ a = b;
+ })(g);
+ });
+ }
+ expect_stdout: [
+ "false",
+ "true",
+ "true",
+ ]
+}
--
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