[Pkg-javascript-commits] [uglifyjs] 205/228: implement delayed resolution for `reduce_vars` (#1788)
Jonas Smedegaard
dr at jones.dk
Sat Apr 15 14:25:30 UTC 2017
This is an automated email from the git hooks/post-receive script.
js pushed a commit to branch master
in repository uglifyjs.
commit ff289b90a92739641dcb7fc7f6c8ecf8ee74d15f
Author: Alex Lam S.L <alexlamsl at gmail.com>
Date: Wed Apr 5 21:06:42 2017 +0800
implement delayed resolution for `reduce_vars` (#1788)
Although it would be nice to enforce `AST_Node` cloning during transformation, that ship has sailed a long time ago.
We now get the assigned value when resolving `AST_SymbolRef` instead of `reset_opt_flags()`, which has the added advantage of improved compressor efficiency.
fixes #1787
---
lib/compress.js | 50 ++++++++++++++++++++++++++++-----------------
test/compress/issue-1609.js | 7 +++----
test/compress/issue-1787.js | 19 +++++++++++++++++
3 files changed, 53 insertions(+), 23 deletions(-)
diff --git a/lib/compress.js b/lib/compress.js
index 14083fe..ef7f044 100644
--- a/lib/compress.js
+++ b/lib/compress.js
@@ -273,7 +273,7 @@ merge(Compressor.prototype, {
var d = node.definition();
d.references.push(node);
if (d.fixed === undefined || !is_safe(d)
- || is_modified(node, 0, d.fixed instanceof AST_Lambda)) {
+ || is_modified(node, 0, node.fixed_value() instanceof AST_Lambda)) {
d.fixed = false;
}
}
@@ -283,7 +283,9 @@ merge(Compressor.prototype, {
if (node instanceof AST_VarDef) {
var d = node.name.definition();
if (d.fixed == null) {
- d.fixed = node.value;
+ d.fixed = node.value && function() {
+ return node.value;
+ };
mark_as_safe(d);
} else if (node.value) {
d.fixed = false;
@@ -314,7 +316,9 @@ merge(Compressor.prototype, {
// So existing transformation rules can work on them.
node.argnames.forEach(function(arg, i) {
var d = arg.definition();
- d.fixed = iife.args[i] || make_node(AST_Undefined, iife);
+ d.fixed = function() {
+ return iife.args[i] || make_node(AST_Undefined, iife);
+ };
mark_as_safe(d);
});
}
@@ -409,6 +413,12 @@ merge(Compressor.prototype, {
}
});
+ AST_SymbolRef.DEFMETHOD("fixed_value", function() {
+ var fixed = this.definition().fixed;
+ if (!fixed || fixed instanceof AST_Node) return fixed;
+ return fixed();
+ });
+
function find_variable(compressor, name) {
var scope, i = 0;
while (scope = compressor.parent(i++)) {
@@ -1487,15 +1497,15 @@ merge(Compressor.prototype, {
if (this._evaluating) throw def;
this._evaluating = true;
try {
- var d = this.definition();
- if (compressor.option("reduce_vars") && d.fixed) {
+ var fixed = this.fixed_value();
+ if (compressor.option("reduce_vars") && fixed) {
if (compressor.option("unsafe")) {
- if (!HOP(d.fixed, "_evaluated")) {
- d.fixed._evaluated = ev(d.fixed, compressor);
+ if (!HOP(fixed, "_evaluated")) {
+ fixed._evaluated = ev(fixed, compressor);
}
- return d.fixed._evaluated;
+ return fixed._evaluated;
}
- return ev(d.fixed, compressor);
+ return ev(fixed, compressor);
}
} finally {
this._evaluating = false;
@@ -2689,11 +2699,12 @@ merge(Compressor.prototype, {
if (compressor.option("reduce_vars")
&& exp instanceof AST_SymbolRef) {
var def = exp.definition();
- if (def.fixed instanceof AST_Defun) {
- def.fixed = make_node(AST_Function, def.fixed, def.fixed).clone(true);
+ var fixed = exp.fixed_value();
+ if (fixed instanceof AST_Defun) {
+ def.fixed = fixed = make_node(AST_Function, fixed, fixed).clone(true);
}
- if (def.fixed instanceof AST_Function) {
- exp = def.fixed;
+ if (fixed instanceof AST_Function) {
+ exp = fixed;
if (compressor.option("unused")
&& def.references.length == 1
&& !(def.scope.uses_arguments
@@ -3080,7 +3091,7 @@ merge(Compressor.prototype, {
&& (e.operator == "*" || e.operator == "/" || e.operator == "%")) {
self.expression = e.left;
e.left = self;
- return e.optimize(compressor);
+ return e;
}
// avoids infinite recursion of numerals
if (self.operator != "-"
@@ -3511,12 +3522,13 @@ merge(Compressor.prototype, {
}
if (compressor.option("evaluate") && compressor.option("reduce_vars")) {
var d = self.definition();
- if (d.fixed) {
+ var fixed = self.fixed_value();
+ if (fixed) {
if (d.should_replace === undefined) {
- var init = d.fixed.evaluate(compressor);
- if (init !== d.fixed) {
- init = make_node_from_constant(init, d.fixed).optimize(compressor);
- init = best_of_expression(init, d.fixed);
+ var init = fixed.evaluate(compressor);
+ if (init !== fixed) {
+ init = make_node_from_constant(init, fixed).optimize(compressor);
+ init = best_of_expression(init, fixed);
var value = init.print_to_string().length;
var name = d.name.length;
var freq = d.references.length;
diff --git a/test/compress/issue-1609.js b/test/compress/issue-1609.js
index 577a3ee..da4b54a 100644
--- a/test/compress/issue-1609.js
+++ b/test/compress/issue-1609.js
@@ -45,11 +45,10 @@ chained_evaluation_2: {
}
expect: {
(function() {
- var a = "long piece of string";
(function() {
- var c;
- c = f(a);
- c.bar = a;
+ var c, b = "long piece of string";
+ c = f(b);
+ c.bar = b;
})();
})();
}
diff --git a/test/compress/issue-1787.js b/test/compress/issue-1787.js
new file mode 100644
index 0000000..43d1f1b
--- /dev/null
+++ b/test/compress/issue-1787.js
@@ -0,0 +1,19 @@
+unary_prefix: {
+ options = {
+ evaluate: true,
+ reduce_vars: true,
+ unused: true,
+ }
+ input: {
+ console.log(function() {
+ var x = -(2 / 3);
+ return x;
+ }());
+ }
+ expect: {
+ console.log(function() {
+ return -2 / 3;
+ }());
+ }
+ expect_stdout: 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