introduce eager evaluation (#3587)

This commit is contained in:
Alex Lam S.L
2019-11-16 06:10:47 +08:00
committed by GitHub
parent dcfc4aca5b
commit 552be61c4d
4 changed files with 192 additions and 45 deletions

View File

@@ -96,6 +96,8 @@ function Compressor(options, false_by_default) {
unsafe_undefined: false,
unused : !false_by_default,
}, true);
var evaluate = this.options["evaluate"];
this.eval_threshold = /eager/.test(evaluate) ? 1 / 0 : +evaluate;
var global_defs = this.options["global_defs"];
if (typeof global_defs == "object") for (var key in global_defs) {
if (/^@/.test(key) && HOP(global_defs, key)) {
@@ -2676,22 +2678,21 @@ merge(Compressor.prototype, {
node.DEFMETHOD("_find_defs", func);
});
function best_of_expression(ast1, ast2) {
return ast1.print_to_string().length >
ast2.print_to_string().length
? ast2 : ast1;
function best_of_expression(ast1, ast2, threshold) {
var delta = ast2.print_to_string().length - ast1.print_to_string().length;
return delta < (threshold || 0) ? ast2 : ast1;
}
function best_of_statement(ast1, ast2) {
function best_of_statement(ast1, ast2, threshold) {
return best_of_expression(make_node(AST_SimpleStatement, ast1, {
body: ast1
}), make_node(AST_SimpleStatement, ast2, {
body: ast2
})).body;
}), threshold).body;
}
function best_of(compressor, ast1, ast2) {
return (first_in_statement(compressor) ? best_of_statement : best_of_expression)(ast1, ast2);
function best_of(compressor, ast1, ast2, threshold) {
return (first_in_statement(compressor) ? best_of_statement : best_of_expression)(ast1, ast2, threshold);
}
function convert_to_predicate(obj) {
@@ -2700,6 +2701,13 @@ merge(Compressor.prototype, {
});
}
function try_evaluate(compressor, node) {
var ev = node.evaluate(compressor);
if (ev === node) return node;
ev = make_node_from_constant(ev, node).optimize(compressor);
return best_of(compressor, node, ev, compressor.eval_threshold);
}
var object_fns = [
"constructor",
"toString",
@@ -5366,12 +5374,7 @@ merge(Compressor.prototype, {
&& is_iife_call(self)) {
return self.negate(compressor, true);
}
var ev = self.evaluate(compressor);
if (ev !== self) {
ev = make_node_from_constant(ev, self).optimize(compressor);
return best_of(compressor, ev, self);
}
return self;
return try_evaluate(compressor, self);
function return_value(stat) {
if (!stat) return make_node(AST_Undefined, self);
@@ -5702,15 +5705,8 @@ merge(Compressor.prototype, {
});
}
// avoids infinite recursion of numerals
if (self.operator != "-"
|| !(e instanceof AST_Number || e instanceof AST_Infinity)) {
var ev = self.evaluate(compressor);
if (ev !== self) {
ev = make_node_from_constant(ev, self).optimize(compressor);
return best_of(compressor, ev, self);
}
}
return self;
return self.operator == "-" && (e instanceof AST_Number || e instanceof AST_Infinity)
? self : try_evaluate(compressor, self);
});
AST_Binary.DEFMETHOD("lift_sequences", function(compressor) {
@@ -6274,12 +6270,7 @@ merge(Compressor.prototype, {
self.right = self.right.right;
return self.transform(compressor);
}
var ev = self.evaluate(compressor);
if (ev !== self) {
ev = make_node_from_constant(ev, self).optimize(compressor);
return best_of(compressor, ev, self);
}
return self;
return try_evaluate(compressor, self);
function align(ref, op) {
switch (ref) {
@@ -6448,11 +6439,11 @@ merge(Compressor.prototype, {
};
}
var name_length = def.name.length;
var overhead = 0;
if (compressor.option("unused") && !compressor.exposed(def)) {
overhead = (name_length + 2 + value_length) / (def.references.length - def.assignments);
name_length += (name_length + 2 + value_length) / (def.references.length - def.assignments);
}
def.should_replace = value_length <= name_length + overhead ? fn : false;
var delta = value_length - Math.floor(name_length);
def.should_replace = delta < compressor.eval_threshold ? fn : false;
} else {
def.should_replace = false;
}
@@ -7046,12 +7037,7 @@ merge(Compressor.prototype, {
});
}
}
var ev = self.evaluate(compressor);
if (ev !== self) {
ev = make_node_from_constant(ev, self).optimize(compressor);
return best_of(compressor, ev, self);
}
return self;
return try_evaluate(compressor, self);
function find_lambda() {
var i = 0, p;
@@ -7152,12 +7138,7 @@ merge(Compressor.prototype, {
}
var sub = self.flatten_object(self.property, compressor);
if (sub) return sub.optimize(compressor);
var ev = self.evaluate(compressor);
if (ev !== self) {
ev = make_node_from_constant(ev, self).optimize(compressor);
return best_of(compressor, ev, self);
}
return self;
return try_evaluate(compressor, self);
});
OPT(AST_Object, function(self, compressor) {