suppress variable inlining within loops
This commit is contained in:
parent
1dbe97c655
commit
9480c46ac3
|
|
@ -4031,7 +4031,7 @@ merge(Compressor.prototype, {
|
||||||
if (compressor.option("inline")
|
if (compressor.option("inline")
|
||||||
&& !fn.uses_arguments
|
&& !fn.uses_arguments
|
||||||
&& !fn.uses_eval
|
&& !fn.uses_eval
|
||||||
&& can_flatten_body()
|
&& (value = can_flatten_body(stat))
|
||||||
&& (exp === fn ? !fn.name
|
&& (exp === fn ? !fn.name
|
||||||
: compressor.option("unused")
|
: compressor.option("unused")
|
||||||
&& (def = exp.definition()).references.length == 1
|
&& (def = exp.definition()).references.length == 1
|
||||||
|
|
@ -4039,8 +4039,7 @@ merge(Compressor.prototype, {
|
||||||
&& fn.is_constant_expression(exp.scope))
|
&& fn.is_constant_expression(exp.scope))
|
||||||
&& !self.pure
|
&& !self.pure
|
||||||
&& !fn.contains_this()
|
&& !fn.contains_this()
|
||||||
&& can_inject_symbols()
|
&& can_inject_symbols()) {
|
||||||
&& (value = return_value(stat))) {
|
|
||||||
return make_sequence(self, flatten_fn()).optimize(compressor);
|
return make_sequence(self, flatten_fn()).optimize(compressor);
|
||||||
}
|
}
|
||||||
if (compressor.option("side_effects") && all(fn.body, is_empty)) {
|
if (compressor.option("side_effects") && all(fn.body, is_empty)) {
|
||||||
|
|
@ -4071,10 +4070,25 @@ merge(Compressor.prototype, {
|
||||||
}
|
}
|
||||||
return self;
|
return self;
|
||||||
|
|
||||||
function can_flatten_body() {
|
function return_value(stat) {
|
||||||
|
if (!stat) return make_node(AST_Undefined, self);
|
||||||
|
if (stat instanceof AST_Return) {
|
||||||
|
if (!stat.value) return make_node(AST_Undefined, self);
|
||||||
|
return stat.value.clone(true);
|
||||||
|
}
|
||||||
|
if (stat instanceof AST_SimpleStatement) {
|
||||||
|
return make_node(AST_UnaryPrefix, stat, {
|
||||||
|
operator: "void",
|
||||||
|
expression: stat.body.clone(true)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function can_flatten_body(stat) {
|
||||||
var len = fn.body.length;
|
var len = fn.body.length;
|
||||||
if (len == 1) return true;
|
if (compressor.option("inline") < 3) {
|
||||||
if (compressor.option("inline") < 3) return false;
|
return len == 1 && return_value(stat);
|
||||||
|
}
|
||||||
stat = null;
|
stat = null;
|
||||||
for (var i = 0; i < len; i++) {
|
for (var i = 0; i < len; i++) {
|
||||||
var line = fn.body[i];
|
var line = fn.body[i];
|
||||||
|
|
@ -4090,7 +4104,7 @@ merge(Compressor.prototype, {
|
||||||
stat = line;
|
stat = line;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return stat;
|
return return_value(stat);
|
||||||
}
|
}
|
||||||
|
|
||||||
function can_inject_args(catches, defs, safe_to_inject) {
|
function can_inject_args(catches, defs, safe_to_inject) {
|
||||||
|
|
@ -4108,21 +4122,18 @@ merge(Compressor.prototype, {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
function can_inject_vars(catches, defs, safe_to_inject) {
|
function can_inject_vars(catches, safe_to_inject) {
|
||||||
var len = fn.body.length;
|
var len = fn.body.length;
|
||||||
if (len == 1) return true;
|
|
||||||
if (!safe_to_inject) return false;
|
|
||||||
for (var i = 0; i < len; i++) {
|
for (var i = 0; i < len; i++) {
|
||||||
var stat = fn.body[i];
|
var stat = fn.body[i];
|
||||||
if (stat instanceof AST_Definitions) {
|
if (!(stat instanceof AST_Definitions)) continue;
|
||||||
for (var j = stat.definitions.length; --j >= 0;) {
|
if (!safe_to_inject) return false;
|
||||||
var name = stat.definitions[j].name;
|
for (var j = stat.definitions.length; --j >= 0;) {
|
||||||
if (catches[name.name]
|
var name = stat.definitions[j].name;
|
||||||
|| identifier_atom(name.name)
|
if (catches[name.name]
|
||||||
|| scope.var_names()[name.name]) {
|
|| identifier_atom(name.name)
|
||||||
return false;
|
|| scope.var_names()[name.name]) {
|
||||||
}
|
return false;
|
||||||
if (defs) defs.push(name.definition());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -4143,7 +4154,7 @@ merge(Compressor.prototype, {
|
||||||
} while (!(scope instanceof AST_Scope));
|
} while (!(scope instanceof AST_Scope));
|
||||||
var safe_to_inject = !(scope instanceof AST_Toplevel) || compressor.toplevel.vars;
|
var safe_to_inject = !(scope instanceof AST_Toplevel) || compressor.toplevel.vars;
|
||||||
var inline = compressor.option("inline");
|
var inline = compressor.option("inline");
|
||||||
if (!can_inject_vars(catches, in_loop, inline >= 3 && safe_to_inject)) return false;
|
if (!can_inject_vars(catches, !in_loop && inline >= 3 && safe_to_inject)) return false;
|
||||||
if (!can_inject_args(catches, in_loop, inline >= 2 && safe_to_inject)) return false;
|
if (!can_inject_args(catches, in_loop, inline >= 2 && safe_to_inject)) return false;
|
||||||
return !in_loop || in_loop.length == 0 || !is_reachable(fn, in_loop);
|
return !in_loop || in_loop.length == 0 || !is_reachable(fn, in_loop);
|
||||||
}
|
}
|
||||||
|
|
@ -4193,10 +4204,9 @@ merge(Compressor.prototype, {
|
||||||
stat.definitions.forEach(function(var_def) {
|
stat.definitions.forEach(function(var_def) {
|
||||||
append_var(decls, expressions, var_def.name, var_def.value);
|
append_var(decls, expressions, var_def.name, var_def.value);
|
||||||
});
|
});
|
||||||
} else {
|
|
||||||
expressions.push(value.clone(true));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
expressions.push(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
function flatten_fn() {
|
function flatten_fn() {
|
||||||
|
|
@ -4212,17 +4222,6 @@ merge(Compressor.prototype, {
|
||||||
}
|
}
|
||||||
return expressions;
|
return expressions;
|
||||||
}
|
}
|
||||||
|
|
||||||
function return_value(stat) {
|
|
||||||
if (stat instanceof AST_Return) {
|
|
||||||
return stat.value;
|
|
||||||
} else if (stat instanceof AST_SimpleStatement) {
|
|
||||||
return make_node(AST_UnaryPrefix, stat, {
|
|
||||||
operator: "void",
|
|
||||||
expression: stat.body
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
OPT(AST_New, function(self, compressor){
|
OPT(AST_New, function(self, compressor){
|
||||||
|
|
|
||||||
|
|
@ -1901,3 +1901,27 @@ inline_true: {
|
||||||
"3",
|
"3",
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
use_before_init_in_loop: {
|
||||||
|
options = {
|
||||||
|
inline: true,
|
||||||
|
toplevel: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a = "PASS";
|
||||||
|
for (var b = 2; --b >= 0;) (function() {
|
||||||
|
var c = function() {
|
||||||
|
return 1;
|
||||||
|
}(c && (a = "FAIL"));
|
||||||
|
})();
|
||||||
|
console.log(a);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var a = "PASS";
|
||||||
|
for (var b = 2; --b >= 0;) (function() {
|
||||||
|
var c = (c && (a = "FAIL"), 1);
|
||||||
|
})();
|
||||||
|
console.log(a);
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user