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