fix corner case in reduce_vars (#3241)

fixes #3240
This commit is contained in:
Alex Lam S.L
2018-08-29 22:14:25 +08:00
committed by GitHub
parent f352bcec3a
commit aa0029204e
2 changed files with 183 additions and 27 deletions

View File

@@ -5751,38 +5751,34 @@ merge(Compressor.prototype, {
} }
var parent = compressor.parent(); var parent = compressor.parent();
if (compressor.option("reduce_vars") && is_lhs(self, parent) !== self) { if (compressor.option("reduce_vars") && is_lhs(self, parent) !== self) {
var d = self.definition(); var def = self.definition();
var fixed = self.fixed_value(); var fixed = self.fixed_value();
var single_use = d.single_use var single_use = def.single_use && !(parent instanceof AST_Call && parent.is_expr_pure(compressor));
&& !(parent instanceof AST_Call && parent.is_expr_pure(compressor));
if (single_use && fixed instanceof AST_Lambda) { if (single_use && fixed instanceof AST_Lambda) {
if (d.scope !== self.scope if (def.scope !== self.scope
&& (!compressor.option("reduce_funcs") && (!compressor.option("reduce_funcs") || def.escaped == 1 || fixed.inlined)) {
|| d.escaped == 1
|| fixed.inlined)) {
single_use = false; single_use = false;
} else if (recursive_ref(compressor, d)) { } else if (recursive_ref(compressor, def)) {
single_use = false; single_use = false;
} else if (d.scope !== self.scope || d.orig[0] instanceof AST_SymbolFunarg) { } else if (def.scope !== self.scope || def.orig[0] instanceof AST_SymbolFunarg) {
single_use = fixed.is_constant_expression(self.scope); single_use = fixed.is_constant_expression(self.scope);
if (single_use == "f") { if (single_use == "f") {
var scope = self.scope; var scope = self.scope;
do { do if (scope instanceof AST_Defun || scope instanceof AST_Function) {
if (scope instanceof AST_Defun || scope instanceof AST_Function) {
scope.inlined = true; scope.inlined = true;
}
} while (scope = scope.parent_scope); } while (scope = scope.parent_scope);
} }
} }
} }
if (single_use && fixed) { if (single_use && fixed) {
def.single_use = false;
if (fixed instanceof AST_Defun) { if (fixed instanceof AST_Defun) {
fixed._squeezed = true; fixed._squeezed = true;
fixed = make_node(AST_Function, fixed, fixed); fixed = make_node(AST_Function, fixed, fixed);
fixed.name = make_node(AST_SymbolLambda, fixed.name, fixed.name); fixed.name = make_node(AST_SymbolLambda, fixed.name, fixed.name);
} }
var value; var value;
if (d.recursive_refs > 0) { if (def.recursive_refs > 0) {
value = fixed.clone(true); value = fixed.clone(true);
var defun_def = value.name.definition(); var defun_def = value.name.definition();
var lambda_def = value.variables.get(value.name.name); var lambda_def = value.variables.get(value.name.name);
@@ -5794,9 +5790,13 @@ merge(Compressor.prototype, {
lambda_def = value.def_function(name); lambda_def = value.def_function(name);
} }
value.walk(new TreeWalker(function(node) { value.walk(new TreeWalker(function(node) {
if (node instanceof AST_SymbolRef && node.definition() === defun_def) { if (!(node instanceof AST_SymbolRef)) return;
var def = node.definition();
if (def === defun_def) {
node.thedef = lambda_def; node.thedef = lambda_def;
lambda_def.references.push(node); lambda_def.references.push(node);
} else {
def.single_use = false;
} }
})); }));
} else { } else {
@@ -5805,12 +5805,11 @@ merge(Compressor.prototype, {
} }
return value; return value;
} }
if (fixed && d.should_replace === undefined) { if (fixed && def.should_replace === undefined) {
var init; var init;
if (fixed instanceof AST_This) { if (fixed instanceof AST_This) {
if (!(d.orig[0] instanceof AST_SymbolFunarg) if (!(def.orig[0] instanceof AST_SymbolFunarg) && all(def.references, function(ref) {
&& all(d.references, function(ref) { return def.scope === ref.scope;
return d.scope === ref.scope;
})) { })) {
init = fixed; init = fixed;
} }
@@ -5835,18 +5834,18 @@ merge(Compressor.prototype, {
return result === init || result === fixed ? result.clone(true) : result; return result === init || result === fixed ? result.clone(true) : result;
}; };
} }
var name_length = d.name.length; var name_length = def.name.length;
var overhead = 0; var overhead = 0;
if (compressor.option("unused") && !compressor.exposed(d)) { if (compressor.option("unused") && !compressor.exposed(def)) {
overhead = (name_length + 2 + value_length) / (d.references.length - d.assignments); overhead = (name_length + 2 + value_length) / (def.references.length - def.assignments);
} }
d.should_replace = value_length <= name_length + overhead ? fn : false; def.should_replace = value_length <= name_length + overhead ? fn : false;
} else { } else {
d.should_replace = false; def.should_replace = false;
} }
} }
if (d.should_replace) { if (def.should_replace) {
return d.should_replace(); return def.should_replace();
} }
} }
return self; return self;

View File

@@ -5354,6 +5354,7 @@ issue_2774: {
issue_2799_1: { issue_2799_1: {
options = { options = {
passes: 2,
reduce_funcs: true, reduce_funcs: true,
reduce_vars: true, reduce_vars: true,
unused: true, unused: true,
@@ -6429,3 +6430,159 @@ issue_3140_5: {
} }
expect_stdout: "1" expect_stdout: "1"
} }
issue_3240_1: {
options = {
reduce_funcs: true,
reduce_vars: true,
unused: true,
}
input: {
(function() {
f(1);
function f(a) {
console.log(a);
var g = function() {
f(a - 1);
};
if (a) g();
}
})();
}
expect: {
(function() {
(function f(a) {
console.log(a);
var g = function() {
f(a - 1);
};
if (a) g();
})(1);
})();
}
expect_stdout: [
"1",
"0",
]
}
issue_3240_2: {
options = {
passes: 2,
reduce_funcs: true,
reduce_vars: true,
unused: true,
}
input: {
(function() {
f(1);
function f(a) {
console.log(a);
var g = function() {
f(a - 1);
};
if (a) g();
}
})();
}
expect: {
(function() {
(function f(a) {
console.log(a);
if (a) (function() {
f(a - 1);
})();
})(1);
})();
}
expect_stdout: [
"1",
"0",
]
}
issue_3240_3: {
options = {
reduce_funcs: true,
reduce_vars: true,
unused: true,
}
input: {
(function() {
f();
function f(b) {
if (!f.a) f.a = 0;
console.log(f.a.toString());
var g = function() {
(b ? function() {} : function() {
f.a++;
f(1);
})();
};
g();
}
})();
}
expect: {
(function() {
(function f(b) {
if (!f.a) f.a = 0;
console.log(f.a.toString());
var g = function() {
(b ? function() {} : function() {
f.a++;
f(1);
})();
};
g();
})();
})();
}
expect_stdout: [
"0",
"1",
]
}
issue_3240_4: {
options = {
passes: 2,
reduce_funcs: true,
reduce_vars: true,
unused: true,
}
input: {
(function() {
f();
function f(b) {
if (!f.a) f.a = 0;
console.log(f.a.toString());
var g = function() {
(b ? function() {} : function() {
f.a++;
f(1);
})();
};
g();
}
})();
}
expect: {
(function() {
(function f(b) {
if (!f.a) f.a = 0;
console.log(f.a.toString());
(function() {
(b ? function() {} : function() {
f.a++;
f(1);
})();
})();
})();
})();
}
expect_stdout: [
"0",
"1",
]
}