Merge branch 'master' into harmony-v3.1.9

This commit is contained in:
alexlamsl
2017-11-11 15:45:34 +08:00
24 changed files with 848 additions and 60 deletions

View File

@@ -78,6 +78,7 @@ function Compressor(options, false_by_default) {
properties : !false_by_default,
pure_getters : !false_by_default && "strict",
pure_funcs : null,
reduce_funcs : !false_by_default,
reduce_vars : !false_by_default,
sequences : !false_by_default,
side_effects : !false_by_default,
@@ -320,20 +321,14 @@ merge(Compressor.prototype, {
if (node instanceof AST_SymbolRef) {
var d = node.definition();
d.references.push(node);
var value;
if (d.fixed === undefined || !safe_to_read(d) || d.single_use == "m") {
d.fixed = false;
} else if (d.fixed) {
var value = node.fixed_value();
value = node.fixed_value();
if (value && ref_once(d) && !compressor.exposed(d)) {
if (value instanceof AST_Lambda) {
d.single_use = d.scope === node.scope
&& !(d.orig[0] instanceof AST_SymbolFunarg)
|| value.is_constant_expression(node.scope);
} else {
d.single_use = d.scope === node.scope
&& loop_ids[d.id] === in_loop
&& value.is_constant_expression();
}
d.single_use = value instanceof AST_Lambda
|| d.scope === node.scope && value.is_constant_expression();
} else {
d.single_use = false;
}
@@ -343,10 +338,9 @@ merge(Compressor.prototype, {
} else {
d.fixed = false;
}
} else {
mark_escaped(d, node, value, 0);
}
}
mark_escaped(d, node, value, 0);
}
if (node instanceof AST_SymbolCatch) {
node.definition().fixed = false;
@@ -397,11 +391,9 @@ merge(Compressor.prototype, {
d.fixed = false;
} else {
d.fixed = node;
loop_ids[d.id] = in_loop;
mark(d, true);
if (ref_once(d)) {
d.single_use = d.scope === d.references[0].scope
|| node.is_constant_expression(d.references[0].scope);
}
d.single_use = ref_once(d);
}
var save_ids = safe_ids;
safe_ids = Object.create(null);
@@ -593,7 +585,11 @@ merge(Compressor.prototype, {
}
function ref_once(def) {
return unused && !def.scope.uses_eval && !def.scope.uses_with && def.references.length == 1;
return unused
&& !def.scope.uses_eval
&& !def.scope.uses_with
&& def.references.length == 1
&& loop_ids[def.id] === in_loop;
}
function is_immutable(value) {
@@ -630,8 +626,11 @@ merge(Compressor.prototype, {
&& parent.expression === node
&& (!(value instanceof AST_Function) || value.contains_this(parent))) {
return true;
} else if (parent instanceof AST_Array || parent instanceof AST_Object) {
} else if (parent instanceof AST_Array) {
return is_modified(parent, parent, level + 1);
} else if (parent instanceof AST_ObjectKeyVal && node === parent.value) {
var obj = tw.parent(level + 1);
return is_modified(obj, obj, level + 2);
} else if (parent instanceof AST_PropAccess && parent.expression === node) {
return !immutable && is_modified(parent, read_property(value, parent.property), level + 1);
}
@@ -639,19 +638,19 @@ merge(Compressor.prototype, {
function mark_escaped(d, node, value, level) {
var parent = tw.parent(level);
if (value instanceof AST_Constant
|| value instanceof AST_Function
|| value instanceof AST_ClassExpression) {
return;
}
if (value instanceof AST_Constant || value instanceof AST_ClassExpression) return;
if (level > 0 && value instanceof AST_Function) return;
if (parent instanceof AST_Assign && parent.operator == "=" && node === parent.right
|| parent instanceof AST_Call && node !== parent.expression
|| parent instanceof AST_Return && node === parent.value && node.scope !== d.scope
|| parent instanceof AST_VarDef && node === parent.value) {
d.escaped = true;
return;
} else if (parent instanceof AST_Array || parent instanceof AST_Object) {
} else if (parent instanceof AST_Array) {
mark_escaped(d, parent, parent, level + 1);
} else if (parent instanceof AST_ObjectKeyVal && node === parent.value) {
var obj = tw.parent(level + 1);
mark_escaped(d, obj, obj, level + 2);
} else if (parent instanceof AST_PropAccess && node === parent.expression) {
value = read_property(value, parent.property);
mark_escaped(d, parent, value, level + 1);
@@ -1136,7 +1135,7 @@ merge(Compressor.prototype, {
var found = false;
return statements[stat_index].transform(new TreeTransformer(function(node, descend, in_list) {
if (found) return node;
if (node === expr) {
if (node === expr || node.body === expr) {
found = true;
if (node instanceof AST_VarDef) {
drop_decl(node.name.definition());
@@ -1150,7 +1149,6 @@ merge(Compressor.prototype, {
case 0: return null;
case 1: return node.expressions[0];
}
if (node instanceof AST_SimpleStatement && !node.body) return null;
}));
}
@@ -2324,7 +2322,10 @@ merge(Compressor.prototype, {
&& !self.variables.has(def.name)) {
if (scope) {
var scope_def = scope.find_variable(node);
if (def.undeclared ? !scope_def : scope_def === def) return true;
if (def.undeclared ? !scope_def : scope_def === def) {
result = "f";
return true;
}
}
result = false;
}
@@ -4472,6 +4473,17 @@ merge(Compressor.prototype, {
return self;
});
function recursive_ref(compressor, def) {
var node;
for (var i = 0; node = compressor.parent(i); i++) {
if (node instanceof AST_Lambda) {
var name = node.name;
if (name && name.definition() === def) break;
}
}
return node;
}
OPT(AST_SymbolRef, function(self, compressor){
var def = self.resolve_defines(compressor);
if (def) {
@@ -4497,20 +4509,24 @@ merge(Compressor.prototype, {
if (fixed instanceof AST_Defun) {
d.fixed = fixed = make_node(AST_Function, fixed, fixed);
}
if (fixed && d.single_use) {
var recurse;
if (fixed instanceof AST_Function) {
for (var i = 0; recurse = compressor.parent(i); i++) {
if (recurse instanceof AST_Lambda) {
var name = recurse.name;
if (name && name.definition() === d) break;
}
if (d.single_use && fixed instanceof AST_Function) {
if (!compressor.option("reduce_funcs") && d.scope !== self.scope) {
d.single_use = false;
} else if (d.escaped && d.scope !== self.scope || recursive_ref(compressor, d)) {
d.single_use = false;
} else if (d.scope !== self.scope || d.orig[0] instanceof AST_SymbolFunarg) {
d.single_use = fixed.is_constant_expression(self.scope);
if (d.single_use == "f") {
var scope = self.scope;
do {
if (scope.name) scope.name.definition().single_use = false;
} while (scope = scope.parent_scope);
}
}
if (!recurse) {
var value = fixed.optimize(compressor);
return value === fixed ? fixed.clone(true) : value;
}
}
if (d.single_use && fixed) {
var value = fixed.optimize(compressor);
return value === fixed ? fixed.clone(true) : value;
}
if (fixed && d.should_replace === undefined) {
var init;