[Pkg-javascript-commits] [uglifyjs] 208/228: fix incorrect context in variable substitution (#1791)
Jonas Smedegaard
dr at jones.dk
Sat Apr 15 14:25:31 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 cc6aa3e5ac13c0da9f2481181f5b4f11275ca8c8
Author: Alex Lam S.L <alexlamsl at gmail.com>
Date: Fri Apr 7 03:42:17 2017 +0800
fix incorrect context in variable substitution (#1791)
`AST_Node.optimize()` is context-aware, so don't cache its results to be used elsewhere.
Also fixed a few cases of AST corruption and beef up safety of `pure_getters`.
---
lib/compress.js | 80 +++++++++++++++++++++++++++++++++-----------
test/compress/reduce_vars.js | 72 +++++++++++++++++++++++++++++++++++++++
2 files changed, 133 insertions(+), 19 deletions(-)
diff --git a/lib/compress.js b/lib/compress.js
index 22c79b8..de3b4db 100644
--- a/lib/compress.js
+++ b/lib/compress.js
@@ -283,10 +283,16 @@ merge(Compressor.prototype, {
if (node instanceof AST_VarDef) {
var d = node.name.definition();
if (d.fixed == null) {
- d.fixed = node.value && function() {
- return node.value;
- };
+ if (node.value) {
+ d.fixed = function() {
+ return node.value;
+ };
+ descend();
+ } else {
+ d.fixed = null;
+ }
mark_as_safe(d);
+ return true;
} else if (node.value) {
d.fixed = false;
}
@@ -1160,13 +1166,42 @@ merge(Compressor.prototype, {
&& !node.expression.has_side_effects(compressor);
}
+ // may_eq_null()
+ // returns true if this node may evaluate to null or undefined
(function(def) {
- def(AST_Node, return_false);
+ def(AST_Node, return_true);
def(AST_Null, return_true);
def(AST_Undefined, return_true);
+ def(AST_Constant, return_false);
+ def(AST_Array, return_false);
+ def(AST_Object, return_false);
+ def(AST_Function, return_false);
+ def(AST_UnaryPostfix, return_false);
def(AST_UnaryPrefix, function() {
return this.operator == "void";
});
+ def(AST_Binary, function(compressor) {
+ switch (this.operator) {
+ case "&&":
+ return this.left.may_eq_null(compressor);
+ case "||":
+ return this.left.may_eq_null(compressor)
+ && this.right.may_eq_null(compressor);
+ default:
+ return false;
+ }
+ })
+ def(AST_Assign, function(compressor) {
+ return this.operator == "="
+ && this.right.may_eq_null(compressor);
+ })
+ def(AST_Conditional, function(compressor) {
+ return this.consequent.may_eq_null(compressor)
+ || this.alternative.may_eq_null(compressor);
+ })
+ def(AST_Seq, function(compressor) {
+ return this.cdr.may_eq_null(compressor);
+ });
def(AST_PropAccess, function(compressor) {
return !compressor.option("unsafe");
});
@@ -3055,8 +3090,9 @@ merge(Compressor.prototype, {
if (this.expression instanceof AST_Seq) {
var seq = this.expression;
var x = seq.to_array();
- this.expression = x.pop();
- x.push(this);
+ var e = this.clone();
+ e.expression = x.pop();
+ x.push(e);
seq = AST_Seq.from_array(x).transform(compressor);
return seq;
}
@@ -3110,9 +3146,14 @@ merge(Compressor.prototype, {
if (e instanceof AST_Binary
&& (self.operator == "+" || self.operator == "-")
&& (e.operator == "*" || e.operator == "/" || e.operator == "%")) {
- self.expression = e.left;
- e.left = self;
- return e;
+ return make_node(AST_Binary, self, {
+ operator: e.operator,
+ left: make_node(AST_UnaryPrefix, e.left, {
+ operator: self.operator,
+ expression: e.left
+ }),
+ right: e.right
+ });
}
// avoids infinite recursion of numerals
if (self.operator != "-"
@@ -3131,23 +3172,25 @@ merge(Compressor.prototype, {
if (this.left instanceof AST_Seq) {
var seq = this.left;
var x = seq.to_array();
- this.left = x.pop();
- x.push(this);
+ var e = this.clone();
+ e.left = x.pop();
+ x.push(e);
return AST_Seq.from_array(x).optimize(compressor);
}
if (this.right instanceof AST_Seq && !this.left.has_side_effects(compressor)) {
var assign = this.operator == "=" && this.left instanceof AST_SymbolRef;
- var root = this.right;
+ var root = this.right.clone();
var cursor, seq = root;
while (assign || !seq.car.has_side_effects(compressor)) {
cursor = seq;
if (seq.cdr instanceof AST_Seq) {
- seq = seq.cdr;
+ seq = seq.cdr = seq.cdr.clone();
} else break;
}
if (cursor) {
- this.right = cursor.cdr;
- cursor.cdr = this;
+ var e = this.clone();
+ e.right = cursor.cdr;
+ cursor.cdr = e;
return root.optimize(compressor);
}
}
@@ -3547,9 +3590,8 @@ merge(Compressor.prototype, {
if (d.should_replace === undefined) {
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;
+ init = make_node_from_constant(init, fixed);
+ var value = best_of_expression(init.optimize(compressor), fixed).print_to_string().length;
var name = d.name.length;
var freq = d.references.length;
var overhead = d.global || !freq ? 0 : (name + 2 + value) / freq;
@@ -3559,7 +3601,7 @@ merge(Compressor.prototype, {
}
}
if (d.should_replace) {
- return d.should_replace.clone(true);
+ return best_of_expression(d.should_replace.optimize(compressor), fixed).clone(true);
}
}
}
diff --git a/test/compress/reduce_vars.js b/test/compress/reduce_vars.js
index cdc4ef2..fdfec99 100644
--- a/test/compress/reduce_vars.js
+++ b/test/compress/reduce_vars.js
@@ -1866,3 +1866,75 @@ delay_def: {
}
expect_stdout: true
}
+
+booleans: {
+ options = {
+ booleans: true,
+ evaluate: true,
+ reduce_vars: true,
+ }
+ input: {
+ console.log(function(a) {
+ if (a != 0);
+ switch (a) {
+ case 0:
+ return "FAIL";
+ case false:
+ return "PASS";
+ }
+ }(false));
+ }
+ expect: {
+ console.log(function(a) {
+ if (!1);
+ switch (!1) {
+ case 0:
+ return "FAIL";
+ case !1:
+ return "PASS";
+ }
+ }(!1));
+ }
+ expect_stdout: "PASS"
+}
+
+side_effects_assign: {
+ options = {
+ evaluate: true,
+ reduce_vars: true,
+ sequences: true,
+ side_effects: true,
+ toplevel: true,
+ }
+ input: {
+ var a = typeof void (a && a.in == 1, 0);
+ console.log(a);
+ }
+ expect: {
+ var a = typeof void (a && a.in);
+ console.log(a);
+ }
+ expect_stdout: "undefined"
+}
+
+pure_getters: {
+ options = {
+ pure_getters: true,
+ reduce_vars: true,
+ side_effects: true,
+ toplevel: true,
+ }
+ input: {
+ try {
+ var a = (a.b, 2);
+ } catch (e) {}
+ console.log(a);
+ }
+ expect: {
+ try {
+ var a = (a.b, 2);
+ } catch (e) {}
+ console.log(a);
+ }
+ expect_stdout: "undefined"
+}
--
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