Skip to content

Commit

Permalink
Merge pull request #1528 from alexlamsl/harmony-v2.8.4
Browse files Browse the repository at this point in the history
Merging from master for 2.8.4
  • Loading branch information
alexlamsl authored Mar 2, 2017
2 parents 22f7af2 + 80f3ad3 commit e27dab7
Show file tree
Hide file tree
Showing 4 changed files with 211 additions and 25 deletions.
113 changes: 90 additions & 23 deletions lib/compress.js
Original file line number Diff line number Diff line change
Expand Up @@ -180,38 +180,105 @@ merge(Compressor.prototype, {

AST_Node.DEFMETHOD("reset_opt_flags", function(compressor, rescan){
var reduce_vars = rescan && compressor.option("reduce_vars");
var unsafe = compressor.option("unsafe");
var safe_ids = [];
push();
var tw = new TreeWalker(function(node){
if (!(node instanceof AST_Directive || node instanceof AST_Constant)) {
node._squeezed = false;
node._optimized = false;
}
if (reduce_vars) {
if (node instanceof AST_Toplevel) node.globals.each(reset_def);
if (node instanceof AST_Scope) node.variables.each(reset_def);
if (node instanceof AST_SymbolRef) {
var d = node.definition();
d.references.push(node);
if (d.fixed && (d.orig.length > 1 || isModified(node, 0))) {
if (!d.fixed || isModified(node, 0) || !is_safe(d)) {
d.fixed = false;
}
}
if (node instanceof AST_VarDef) {
var d = node.name.definition();
if (d.fixed === undefined) {
d.fixed = node.value || make_node(AST_Undefined, node);
mark_as_safe(d);
} else {
d.fixed = false;
}
}
if (node instanceof AST_Call && node.expression instanceof AST_Function) {
node.expression.argnames.forEach(function(arg, i) {
arg.definition().init = node.args[i] || make_node(AST_Undefined, node);
var iife;
if (node instanceof AST_Function
&& (iife = tw.parent()) instanceof AST_Call
&& iife.expression === node) {
node.argnames.forEach(function(arg, i) {
var d = arg.definition();
d.fixed = iife.args[i] || make_node(AST_Undefined, iife);
mark_as_safe(d);
});
}
}
if (!(node instanceof AST_Directive || node instanceof AST_Constant)) {
node._squeezed = false;
node._optimized = false;
if (node instanceof AST_If || node instanceof AST_DWLoop) {
node.condition.walk(tw);
push();
node.body.walk(tw);
pop();
if (node.alternative) {
push();
node.alternative.walk(tw);
pop();
}
return true;
}
if (node instanceof AST_LabeledStatement) {
push();
node.body.walk(tw);
pop();
return true;
}
if (node instanceof AST_For) {
if (node.init) node.init.walk(tw);
push();
if (node.condition) node.condition.walk(tw);
node.body.walk(tw);
if (node.step) node.step.walk(tw);
pop();
return true;
}
if (node instanceof AST_ForIn) {
if (node.init instanceof AST_SymbolRef) {
node.init.definition().fixed = false;
}
node.object.walk(tw);
push();
node.body.walk(tw);
pop();
return true;
}
}
});
this.walk(tw);

function mark_as_safe(def) {
safe_ids[safe_ids.length - 1][def.id] = true;
}

function is_safe(def) {
for (var i = safe_ids.length, id = def.id; --i >= 0;) {
if (safe_ids[i][id]) return true;
}
}

function push() {
safe_ids.push(Object.create(null));
}

function pop() {
safe_ids.pop();
}

function reset_def(def) {
def.fixed = true;
def.fixed = undefined;
def.references = [];
def.should_replace = undefined;
if (unsafe && def.init) {
def.init._evaluated = undefined;
}
}

function isModified(node, level) {
Expand Down Expand Up @@ -1295,14 +1362,14 @@ merge(Compressor.prototype, {
this._evaluating = true;
try {
var d = this.definition();
if (compressor.option("reduce_vars") && d.fixed && d.init) {
if (compressor.option("reduce_vars") && d.fixed) {
if (compressor.option("unsafe")) {
if (d.init._evaluated === undefined) {
d.init._evaluated = ev(d.init, compressor);
if (!HOP(d.fixed, "_evaluated")) {
d.fixed._evaluated = ev(d.fixed, compressor);
}
return d.init._evaluated;
return d.fixed._evaluated;
}
return ev(d.init, compressor);
return ev(d.fixed, compressor);
}
} finally {
this._evaluating = false;
Expand Down Expand Up @@ -2307,7 +2374,7 @@ merge(Compressor.prototype, {
// here because they are only used in an equality comparison later on.
self.condition = negated;
var tmp = self.body;
self.body = self.alternative || make_node(AST_EmptyStatement);
self.body = self.alternative || make_node(AST_EmptyStatement, self);
self.alternative = tmp;
}
if (is_empty(self.body) && is_empty(self.alternative)) {
Expand Down Expand Up @@ -2586,7 +2653,7 @@ merge(Compressor.prototype, {
case "Boolean":
if (self.args.length == 0) return make_node(AST_False, self);
if (self.args.length == 1) return make_node(AST_UnaryPrefix, self, {
expression: make_node(AST_UnaryPrefix, null, {
expression: make_node(AST_UnaryPrefix, self, {
expression: self.args[0],
operator: "!"
}),
Expand Down Expand Up @@ -2988,7 +3055,7 @@ merge(Compressor.prototype, {
compressor.warn("Boolean && always false [{file}:{line},{col}]", self.start);
return make_node(AST_Seq, self, {
car: self.left,
cdr: make_node(AST_False)
cdr: make_node(AST_False, self)
}).optimize(compressor);
}
if (ll.length > 1 && ll[1]) {
Expand Down Expand Up @@ -3179,9 +3246,9 @@ merge(Compressor.prototype, {
}
if (compressor.option("evaluate") && compressor.option("reduce_vars")) {
var d = self.definition();
if (d.fixed && d.init) {
if (d.fixed) {
if (d.should_replace === undefined) {
var init = d.init.evaluate(compressor);
var init = d.fixed.evaluate(compressor);
if (init.length > 1) {
var value = init[0].print_to_string().length;
var name = d.name.length;
Expand Down
2 changes: 1 addition & 1 deletion lib/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -185,7 +185,7 @@ function push_uniq(array, el) {

function string_template(text, props) {
return text.replace(/\{(.+?)\}/g, function(str, p){
return props[p];
return props && props[p];
});
};

Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
"homepage": "http://lisperator.net/uglifyjs",
"author": "Mihai Bazon <mihai.bazon@gmail.com> (http://lisperator.net/)",
"license": "BSD-2-Clause",
"version": "2.8.2",
"version": "2.8.4",
"engines": {
"node": ">=0.8.0"
},
Expand Down
119 changes: 119 additions & 0 deletions test/compress/reduce_vars.js
Original file line number Diff line number Diff line change
Expand Up @@ -470,3 +470,122 @@ multi_def_2: {
var repeatLength = this.getBits(bitsLength) + bitsOffset;
}
}

use_before_var: {
options = {
evaluate: true,
reduce_vars: true,
}
input: {
console.log(t);
var t = 1;
}
expect: {
console.log(t);
var t = 1;
}
}

inner_var_if: {
options = {
evaluate: true,
reduce_vars: true,
}
input: {
function f(){
return 0;
}
if (f())
var t = 1;
if (!t)
console.log(t);
}
expect: {
function f(){
return 0;
}
if (f())
var t = 1;
if (!t)
console.log(t);
}
}

inner_var_label: {
options = {
evaluate: true,
reduce_vars: true,
}
input: {
function f(){
return 1;
}
l: {
if (f()) break l;
var t = 1;
}
console.log(t);
}
expect: {
function f(){
return 1;
}
l: {
if (f()) break l;
var t = 1;
}
console.log(t);
}
}

inner_var_for: {
options = {
evaluate: true,
reduce_vars: true,
}
input: {
var a = 1;
x(a, b, d);
for (var b = 2, c = 3; x(a, b, c, d); x(a, b, c, d)) {
var d = 4, e = 5;
x(a, b, c, d, e);
}
x(a, b, c, d, e)
}
expect: {
var a = 1;
x(1, b, d);
for (var b = 2, c = 3; x(1, b, 3, d); x(1, b, 3, d)) {
var d = 4, e = 5;
x(1, b, 3, d, e);
}
x(1, b, 3, d, e);
}
}

inner_var_for_in: {
options = {
evaluate: true,
reduce_vars: true,
}
input: {
var a = 1, b = 2;
for (b in (function() {
return x(a, b, c);
})()) {
var c = 3, d = 4;
x(a, b, c, d);
}
x(a, b, c, d);
}
expect: {
var a = 1, b = 2;
for (b in (function() {
return x(1, b, c);
})()) {
var c = 3, d = 4;
x(1, b, c, d);
}
x(1, b, c, d);
}
}

0 comments on commit e27dab7

Please sign in to comment.