enhance functions & reduce_vars (#5045)

This commit is contained in:
Alex Lam S.L
2021-07-03 23:19:08 +01:00
committed by GitHub
parent 668f96623c
commit 972b9f0bef
9 changed files with 288 additions and 162 deletions

View File

@@ -484,9 +484,21 @@ merge(Compressor.prototype, {
def.single_use = undefined;
}
function reset_variables(tw, compressor, scope) {
function reset_block_variables(tw, compressor, scope) {
scope.variables.each(function(def) {
reset_def(tw, compressor, def);
});
}
function reset_variables(tw, compressor, scope) {
scope.fn_defs = [];
scope.variables.each(function(def) {
reset_def(tw, compressor, def);
var init = def.init;
if (init instanceof AST_LambdaDefinition) {
scope.fn_defs.push(init);
init.safe_ids = null;
}
if (def.fixed === null) {
def.safe_ids = tw.safe_ids;
mark(tw, def);
@@ -496,13 +508,7 @@ merge(Compressor.prototype, {
}
});
scope.may_call_this = function() {
scope.may_call_this = noop;
if (!scope.contains_this()) return;
scope.functions.each(function(def) {
if (def.init instanceof AST_LambdaDefinition && !(def.id in tw.defun_ids)) {
tw.defun_ids[def.id] = false;
}
});
scope.may_call_this = scope.contains_this() ? return_true : return_false;
};
if (scope.uses_arguments) scope.each_argname(function(node) {
node.definition().last_ref = false;
@@ -513,39 +519,56 @@ merge(Compressor.prototype, {
});
}
function mark_defun(tw, def) {
if (def.id in tw.defun_ids) {
var marker = tw.defun_ids[def.id];
if (!marker) return;
var visited = tw.defun_visited[def.id];
if (marker === tw.safe_ids) return !visited && def.fixed;
function mark_fn_def(tw, def, fn) {
if (!HOP(fn, "safe_ids")) return;
var marker = fn.safe_ids;
if (marker === false) return;
if (fn.parent_scope.resolve().may_call_this === return_true) return;
if (marker) {
var visited = member(fn, tw.fn_visited);
if (marker === tw.safe_ids) return !visited && fn;
if (visited) {
def.init.enclosed.forEach(function(d) {
if (def.init.variables.get(d.name) === d) return;
if (!safe_to_read(tw, d)) d.fixed = false;
fn.enclosed.forEach(function(d) {
if (fn.variables.get(d.name) === d) return;
if (safe_to_read(tw, d)) return;
d.single_use = false;
if (d.fixed instanceof AST_LambdaDefinition) return;
d.fixed = false;
});
return;
}
} else if (!tw.in_loop) {
var scope = def.scope;
var s = tw.find_parent(AST_Scope);
do {
if (s === scope) {
tw.defun_ids[def.id] = tw.safe_ids;
return def.fixed;
} else if (!tw.in_loop && !(tw.fn_scanning && tw.fn_scanning !== def.scope.resolve())) {
fn.safe_ids = tw.safe_ids;
return fn;
}
} while (s instanceof AST_LambdaExpression && (s = s.parent_scope.resolve()));
}
tw.defun_ids[def.id] = false;
fn.safe_ids = false;
}
function walk_defuns(tw, scope) {
scope.functions.each(function(def) {
if (def.init instanceof AST_LambdaDefinition && !tw.defun_visited[def.id]) {
tw.defun_ids[def.id] = tw.safe_ids;
def.init.walk(tw);
function walk_fn_def(tw, fn) {
var was_scanning = tw.fn_scanning;
tw.fn_scanning = fn;
fn.walk(tw);
tw.fn_scanning = was_scanning;
}
function pop_scope(tw, scope) {
var fn_defs = scope.fn_defs;
var tangled = scope.may_call_this === return_true ? fn_defs : fn_defs.filter(function(fn) {
if (fn.safe_ids === false) return true;
fn.safe_ids = tw.safe_ids;
walk_fn_def(tw, fn);
return false;
});
pop(tw);
tangled.forEach(function(fn) {
fn.safe_ids = tw.safe_ids;
walk_fn_def(tw, fn);
});
fn_defs.forEach(function(fn) {
delete fn.safe_ids;
});
delete scope.fn_defs;
delete scope.may_call_this;
}
function push(tw) {
@@ -592,13 +615,13 @@ merge(Compressor.prototype, {
if (def.fixed === undefined) return declare || all(def.orig, function(sym) {
return !(sym instanceof AST_SymbolLet);
});
if (def.fixed === null && def.safe_ids) {
def.safe_ids[def.id] = false;
delete def.safe_ids;
return true;
}
if (def.fixed === false) return false;
var safe = tw.safe_ids[def.id];
if (def.safe_ids) {
def.safe_ids[def.id] = false;
delete def.safe_ids;
return def.fixed === null || HOP(tw.safe_ids, def.id) && !safe.read;
}
if (!HOP(tw.safe_ids, def.id)) {
if (!safe) return false;
if (safe.read) {
@@ -813,8 +836,7 @@ merge(Compressor.prototype, {
}, visit);
walk_lambda(fn, tw);
var safe_ids = tw.safe_ids;
pop(tw);
walk_defuns(tw, fn);
pop_scope(tw, fn);
if (!aborts) tw.safe_ids = safe_ids;
return true;
@@ -835,7 +857,8 @@ merge(Compressor.prototype, {
var node = this;
var left = node.left;
var right = node.right;
var scan = left instanceof AST_Destructured || left instanceof AST_SymbolRef;
var ld = left instanceof AST_SymbolRef && left.definition();
var scan = ld || left instanceof AST_Destructured;
switch (node.operator) {
case "=":
if (left.equivalent_to(right) && !left.has_side_effects(compressor)) {
@@ -844,7 +867,17 @@ merge(Compressor.prototype, {
node.__drop = true;
return true;
}
if (scan) {
if (ld && right instanceof AST_LambdaExpression) {
walk_assign();
if (ld.escaped.length) {
right.walk(tw);
} else {
right.parent_scope.resolve().fn_defs.push(right);
right.safe_ids = null;
}
return true;
} else if (scan) {
right.walk(tw);
walk_assign();
return true;
}
@@ -856,6 +889,7 @@ merge(Compressor.prototype, {
left.walk(tw);
push(tw);
if (scan) {
right.walk(tw);
walk_assign();
} else {
mark_assignment_to_arguments(left);
@@ -868,20 +902,19 @@ merge(Compressor.prototype, {
mark_assignment_to_arguments(left);
return;
}
var d = left.definition();
d.assignments++;
var fixed = d.fixed;
ld.assignments++;
var fixed = ld.fixed;
if (is_modified(compressor, tw, node, node, 0)) {
d.fixed = false;
ld.fixed = false;
return;
}
var safe = safe_to_read(tw, d);
var safe = safe_to_read(tw, ld);
right.walk(tw);
if (safe && !left.in_arg && safe_to_assign(tw, d)) {
push_ref(d, left);
mark(tw, d);
if (d.single_use) d.single_use = false;
left.fixed = d.fixed = function() {
if (safe && !left.in_arg && safe_to_assign(tw, ld)) {
push_ref(ld, left);
mark(tw, ld);
if (ld.single_use) ld.single_use = false;
left.fixed = ld.fixed = function() {
return make_node(AST_Binary, node, {
operator: node.operator.slice(0, -1),
left: make_ref(left, fixed),
@@ -892,7 +925,7 @@ merge(Compressor.prototype, {
left.fixed.assigns.push(node);
} else {
left.walk(tw);
d.fixed = false;
ld.fixed = false;
}
return true;
}
@@ -920,8 +953,8 @@ merge(Compressor.prototype, {
}
function walk_assign() {
right.walk(tw);
var modified = is_modified(compressor, tw, node, right, 0, is_immutable(right), recursive_ref(tw, d));
var recursive = ld && recursive_ref(tw, ld);
var modified = is_modified(compressor, tw, node, right, 0, is_immutable(right), recursive);
scan_declaration(tw, compressor, left, function() {
return node.right;
}, function(sym, fixed, walk) {
@@ -956,9 +989,7 @@ merge(Compressor.prototype, {
return true;
});
def(AST_BlockScope, function(tw, descend, compressor) {
this.variables.each(function(def) {
reset_def(tw, compressor, def);
});
reset_block_variables(tw, compressor, this);
});
def(AST_Call, function(tw, descend) {
var node = this;
@@ -969,43 +1000,43 @@ merge(Compressor.prototype, {
arg.walk(tw);
if (arg instanceof AST_Spread) iife = false;
});
if (iife) exp.reduce_vars = reduce_iife;
if (iife) {
exp.reduce_vars = reduce_iife;
} else {
exp.safe_ids = tw.safe_ids;
}
exp.walk(tw);
if (iife) delete exp.reduce_vars;
return true;
}
var def = exp instanceof AST_SymbolRef && exp.definition();
if (node.TYPE == "Call" && tw.in_boolean_context()) {
if (def) {
def.bool_fn++;
if (exp instanceof AST_SymbolRef) {
exp.definition().bool_fn++;
} else if (exp instanceof AST_Assign && exp.operator == "=" && exp.left instanceof AST_SymbolRef) {
exp.left.definition().bool_fn++;
}
}
if (def && def.fixed instanceof AST_LambdaDefinition) {
var defun = mark_defun(tw, def);
if (defun) {
descend();
defun.walk(tw);
return true;
}
exp.walk(tw);
var fixed = exp instanceof AST_SymbolRef && exp.fixed_value();
var optional = node.optional;
var fn;
if (fixed instanceof AST_Lambda) {
fn = mark_fn_def(tw, exp.definition(), fixed);
optional = false;
} else {
tw.find_parent(AST_Scope).may_call_this();
}
if (!node.optional) return;
exp.walk(tw);
push(tw);
if (optional) push(tw);
node.args.forEach(function(arg) {
arg.walk(tw);
});
pop(tw);
if (optional) pop(tw);
if (fn) walk_fn_def(tw, fn);
return true;
});
def(AST_Class, function(tw, descend, compressor) {
var node = this;
node.variables.each(function(def) {
reset_def(tw, compressor, def);
});
reset_block_variables(tw, compressor, node);
if (node.extends) node.extends.walk(tw);
var props = node.properties.filter(function(prop) {
reset_flags(prop);
@@ -1057,7 +1088,7 @@ merge(Compressor.prototype, {
return true;
});
def(AST_Do, function(tw) {
var saved_loop = tw.in_loop;
var save_loop = tw.in_loop;
tw.in_loop = this;
push(tw);
this.body.walk(tw);
@@ -1067,39 +1098,37 @@ merge(Compressor.prototype, {
}
this.condition.walk(tw);
pop(tw);
tw.in_loop = saved_loop;
tw.in_loop = save_loop;
return true;
});
def(AST_For, function(tw, descend, compressor) {
this.variables.each(function(def) {
reset_def(tw, compressor, def);
});
if (this.init) this.init.walk(tw);
var saved_loop = tw.in_loop;
tw.in_loop = this;
var node = this;
reset_block_variables(tw, compressor, node);
if (node.init) node.init.walk(tw);
var save_loop = tw.in_loop;
tw.in_loop = node;
push(tw);
if (this.condition) this.condition.walk(tw);
this.body.walk(tw);
if (this.step) {
if (has_loop_control(this, tw.parent())) {
if (node.condition) node.condition.walk(tw);
node.body.walk(tw);
if (node.step) {
if (has_loop_control(node, tw.parent())) {
pop(tw);
push(tw);
}
this.step.walk(tw);
node.step.walk(tw);
}
pop(tw);
tw.in_loop = saved_loop;
tw.in_loop = save_loop;
return true;
});
def(AST_ForEnumeration, function(tw, descend, compressor) {
this.variables.each(function(def) {
reset_def(tw, compressor, def);
});
this.object.walk(tw);
var saved_loop = tw.in_loop;
tw.in_loop = this;
var node = this;
reset_block_variables(tw, compressor, node);
node.object.walk(tw);
var save_loop = tw.in_loop;
tw.in_loop = node;
push(tw);
var init = this.init;
var init = node.init;
if (init instanceof AST_Definitions) {
init.definitions[0].name.mark_symbol(function(node) {
if (node instanceof AST_SymbolDeclaration) {
@@ -1120,9 +1149,9 @@ merge(Compressor.prototype, {
} else {
init.walk(tw);
}
this.body.walk(tw);
node.body.walk(tw);
pop(tw);
tw.in_loop = saved_loop;
tw.in_loop = save_loop;
return true;
});
def(AST_If, function(tw) {
@@ -1145,13 +1174,14 @@ merge(Compressor.prototype, {
});
def(AST_Lambda, function(tw, descend, compressor) {
var fn = this;
if (HOP(fn, "safe_ids") && fn.safe_ids !== tw.safe_ids) return true;
if (!push_uniq(tw.fn_visited, fn)) return true;
fn.inlined = false;
push(tw);
reset_variables(tw, compressor, fn);
descend();
pop(tw);
pop_scope(tw, fn);
if (fn.name) mark_escaped(tw, fn.name.definition(), fn, fn.name, fn, 0, 1);
walk_defuns(tw, fn);
return true;
});
def(AST_LambdaDefinition, function(tw, descend, compressor) {
@@ -1159,15 +1189,13 @@ merge(Compressor.prototype, {
var def = fn.name.definition();
var parent = tw.parent();
if (parent instanceof AST_ExportDeclaration || parent instanceof AST_ExportDefault) def.single_use = false;
if (tw.defun_visited[def.id]) return true;
if (def.init === fn && tw.defun_ids[def.id] !== tw.safe_ids) return true;
tw.defun_visited[def.id] = true;
if (HOP(fn, "safe_ids") && fn.safe_ids !== tw.safe_ids) return true;
if (!push_uniq(tw.fn_visited, fn)) return true;
fn.inlined = false;
push(tw);
reset_variables(tw, compressor, fn);
descend();
pop(tw);
walk_defuns(tw, fn);
pop_scope(tw, fn);
return true;
});
def(AST_Sub, function(tw) {
@@ -1179,12 +1207,11 @@ merge(Compressor.prototype, {
return true;
});
def(AST_Switch, function(tw, descend, compressor) {
this.variables.each(function(def) {
reset_def(tw, compressor, def);
});
this.expression.walk(tw);
var node = this;
reset_block_variables(tw, compressor, node);
node.expression.walk(tw);
var first = true;
this.body.forEach(function(branch) {
node.body.forEach(function(branch) {
if (branch instanceof AST_Default) return;
branch.expression.walk(tw);
if (first) {
@@ -1193,7 +1220,7 @@ merge(Compressor.prototype, {
}
})
if (!first) pop(tw);
walk_body(this, tw);
walk_body(node, tw);
return true;
});
def(AST_SwitchBranch, function(tw) {
@@ -1258,36 +1285,62 @@ merge(Compressor.prototype, {
}
if (!this.fixed) this.fixed = d.fixed;
var parent;
if (d.fixed instanceof AST_LambdaDefinition
if (value instanceof AST_Lambda
&& !((parent = tw.parent()) instanceof AST_Call && parent.expression === this)) {
var defun = mark_defun(tw, d);
if (defun) defun.walk(tw);
var fn = mark_fn_def(tw, d, value);
if (fn) walk_fn_def(tw, fn);
}
});
def(AST_Template, function(tw, descend) {
var node = this;
var tag = node.tag;
if (!tag) return;
if (tag instanceof AST_LambdaExpression) {
node.expressions.forEach(function(exp) {
exp.walk(tw);
});
tag.safe_ids = tw.safe_ids;
tag.walk(tw);
delete tag.reduce_vars;
return true;
}
tag.walk(tw);
var fixed = tag instanceof AST_SymbolRef && tag.fixed_value();
var fn;
if (fixed instanceof AST_Lambda) {
fn = mark_fn_def(tw, tag.definition(), fixed);
} else {
tw.find_parent(AST_Scope).may_call_this();
}
node.expressions.forEach(function(exp) {
exp.walk(tw);
});
if (fn) walk_fn_def(tw, fn);
return true;
});
def(AST_Toplevel, function(tw, descend, compressor) {
this.globals.each(function(def) {
var node = this;
node.globals.each(function(def) {
reset_def(tw, compressor, def);
});
push(tw);
reset_variables(tw, compressor, this);
reset_variables(tw, compressor, node);
descend();
pop(tw);
walk_defuns(tw, this);
pop_scope(tw, node);
return true;
});
def(AST_Try, function(tw, descend, compressor) {
this.variables.each(function(def) {
reset_def(tw, compressor, def);
});
var node = this;
reset_block_variables(tw, compressor, node);
push(tw);
walk_body(this, tw);
walk_body(node, tw);
pop(tw);
if (this.bcatch) {
if (node.bcatch) {
push(tw);
this.bcatch.walk(tw);
node.bcatch.walk(tw);
pop(tw);
}
if (this.bfinally) this.bfinally.walk(tw);
if (node.bfinally) node.bfinally.walk(tw);
return true;
});
def(AST_Unary, function(tw, descend) {
@@ -1338,8 +1391,12 @@ merge(Compressor.prototype, {
});
def(AST_VarDef, function(tw, descend, compressor) {
var node = this;
if (node.value) {
node.value.walk(tw);
var value = node.value;
if (value instanceof AST_LambdaExpression && node.name instanceof AST_SymbolDeclaration) {
value.parent_scope.resolve().fn_defs.push(value);
value.safe_ids = null;
} else if (value) {
value.walk(tw);
} else if (!(tw.parent() instanceof AST_Let)) {
return;
}
@@ -1363,12 +1420,12 @@ merge(Compressor.prototype, {
return true;
});
def(AST_While, function(tw, descend) {
var saved_loop = tw.in_loop;
var save_loop = tw.in_loop;
tw.in_loop = this;
push(tw);
descend();
pop(tw);
tw.in_loop = saved_loop;
tw.in_loop = save_loop;
return true;
});
})(function(node, func) {
@@ -1387,9 +1444,9 @@ merge(Compressor.prototype, {
reset_flags(node);
return node.reduce_vars(tw, descend, compressor);
} : reset_flags);
// Flow control for visiting `AST_Defun`s
tw.defun_ids = Object.create(null);
tw.defun_visited = Object.create(null);
// Flow control for visiting lambda definitions
tw.fn_scanning = null;
tw.fn_visited = [];
// Record the loop body in which `AST_SymbolDeclaration` is first encountered
tw.in_loop = null;
tw.loop_ids = Object.create(null);
@@ -1642,9 +1699,7 @@ merge(Compressor.prototype, {
return all(block.body, function(stat) {
return is_empty(stat)
|| stat instanceof AST_Defun
|| stat instanceof AST_Var && all(stat.definitions, function(var_def) {
return !var_def.value;
});
|| stat instanceof AST_Var && declarations_only(stat);
});
}
@@ -6468,7 +6523,7 @@ merge(Compressor.prototype, {
}
} else if (compressor.option("functions")
&& !compressor.option("ie8")
&& node instanceof AST_Var
&& drop_sym
&& var_defs[sym.id] == 1
&& sym.assignments == 0
&& value instanceof AST_LambdaExpression
@@ -6542,7 +6597,7 @@ merge(Compressor.prototype, {
}
function can_declare_defun(fn) {
if (compressor.has_directive("use strict") || !(fn instanceof AST_Function)) {
if (!is_var || compressor.has_directive("use strict") || !(fn instanceof AST_Function)) {
return parent instanceof AST_Scope;
}
return parent instanceof AST_Block
@@ -9501,9 +9556,7 @@ merge(Compressor.prototype, {
for (var i = 0; i < len; i++) {
var line = fn.body[i];
if (line instanceof AST_Var) {
var assigned = var_assigned || !all(line.definitions, function(var_def) {
return !var_def.value;
});
var assigned = var_assigned || !declarations_only(line);
if (assigned) {
var_assigned = true;
if (stat) return false;

View File

@@ -556,6 +556,38 @@ reduce_iife_3: {
node_version: ">=4"
}
reduce_lambda: {
options = {
evaluate: true,
reduce_vars: true,
toplevel: true,
unused: true,
}
input: {
var f = () => {
console.log(a, b);
};
var a = "foo", b = 42;
f();
b = "bar";
f();
}
expect: {
var f = () => {
console.log("foo", b);
};
var b = 42;
f();
b = "bar";
f();
}
expect_stdout: [
"foo 42",
"foo bar",
]
node_version: ">=4"
}
single_use_recursive: {
options = {
reduce_vars: true,

View File

@@ -3081,7 +3081,8 @@ issue_4235: {
}
expect: {
void function() {
var f = console.log(f);
var f;
console.log(f);
}();
}
expect_stdout: "undefined"

View File

@@ -2905,6 +2905,7 @@ issue_2437: {
issue_2485_1: {
options = {
functions: true,
passes: 2,
reduce_funcs: true,
reduce_vars: true,
unused: true,
@@ -2955,6 +2956,7 @@ issue_2485_2: {
options = {
functions: true,
inline: true,
passes: 2,
reduce_funcs: true,
reduce_vars: true,
unused: true,

View File

@@ -152,7 +152,8 @@ issue_4487: {
}
expect: {
function a() {
var f = console.log(typeof f);
var f;
console.log(typeof f);
}
a();
}

View File

@@ -494,6 +494,41 @@ reduce_vars_3: {
node_version: ">=4"
}
reduce_lambda: {
options = {
evaluate: true,
functions: true,
reduce_vars: true,
toplevel: true,
unused: true,
}
input: {
"use strict";
let f = function() {
console.log(a, b);
};
let a = "foo", b = 42;
f();
b = "bar";
f();
}
expect: {
"use strict";
function f() {
console.log("foo", b);
}
let b = 42;
f();
b = "bar";
f();
}
expect_stdout: [
"foo 42",
"foo bar",
]
node_version: ">=4"
}
hoist_props: {
options = {
hoist_props: true,

View File

@@ -1320,6 +1320,7 @@ issue_2878: {
issue_3427: {
options = {
assignments: true,
evaluate: true,
inline: true,
pure_getters: "strict",

View File

@@ -3092,7 +3092,7 @@ accessor_1: {
a = 2;
return a;
},
b: 1
b: 1,
}.b, a);
}
expect: {
@@ -3102,7 +3102,7 @@ accessor_1: {
a = 2;
return a;
},
b: 1
b: 1,
}.b, a);
}
expect_stdout: "1 1"
@@ -3122,7 +3122,7 @@ accessor_2: {
var B = {
get c() {
console.log(A);
}
},
};
B.c;
}
@@ -3130,7 +3130,7 @@ accessor_2: {
({
get c() {
console.log(1);
}
},
}).c;
}
expect_stdout: "1"
@@ -3176,7 +3176,7 @@ obj_var_1: {
var obj = {
bar: function() {
return C + C;
}
},
};
console.log(obj.bar());
}
@@ -3184,7 +3184,7 @@ obj_var_1: {
console.log({
bar: function() {
return 2;
}
},
}.bar());
}
expect_stdout: "2"
@@ -3208,7 +3208,7 @@ obj_var_2: {
var obj = {
bar: function() {
return C + C;
}
},
};
console.log(obj.bar());
}
@@ -4422,6 +4422,7 @@ perf_2: {
perf_3: {
options = {
passes: 2,
reduce_funcs: true,
reduce_vars: true,
toplevel: true,
@@ -4430,10 +4431,10 @@ perf_3: {
input: {
var foo = function(x, y, z) {
return x < y ? x * y + z : x * z - y;
}
};
var indirect_foo = function(x, y, z) {
return foo(x, y, z);
}
};
var sum = 0;
for (var i = 0; i < 100; ++i)
sum += indirect_foo(i, i + 1, 3 * i);
@@ -4462,10 +4463,10 @@ perf_4: {
input: {
var foo = function(x, y, z) {
return x < y ? x * y + z : x * z - y;
}
};
var indirect_foo = function(x, y, z) {
return foo(x, y, z);
}
};
var sum = 0;
for (var i = 0; i < 100; ++i)
sum += indirect_foo(i, i + 1, 3 * i);
@@ -4474,10 +4475,10 @@ perf_4: {
expect: {
var foo = function(x, y, z) {
return x < y ? x * y + z : x * z - y;
}
};
var indirect_foo = function(x, y, z) {
return foo(x, y, z);
}
};
var sum = 0;
for (var i = 0; i < 100; ++i)
sum += indirect_foo(i, i + 1, 3 * i);
@@ -4566,9 +4567,9 @@ perf_7: {
var indirect_foo = function(x, y, z) {
var foo = function(x, y, z) {
return x < y ? x * y + z : x * z - y;
}
};
return foo(x, y, z);
}
};
var sum = 0;
for (var i = 0; i < 100; ++i)
sum += indirect_foo(i, i + 1, 3 * i);
@@ -4598,9 +4599,9 @@ perf_8: {
var indirect_foo = function(x, y, z) {
var foo = function(x, y, z) {
return x < y ? x * y + z : x * z - y;
}
};
return foo(x, y, z);
}
};
var sum = 0;
for (var i = 0; i < 100; ++i)
sum += indirect_foo(i, i + 1, 3 * i);
@@ -4611,7 +4612,7 @@ perf_8: {
return function(x, y, z) {
return x < y ? x * y + z : x * z - y;
}(x, y, z);
}
};
var sum = 0;
for (var i = 0; i < 100; ++i)
sum += indirect_foo(i, i + 1, 3 * i);

View File

@@ -726,7 +726,7 @@ function to_statement_init(node) {
return node instanceof U.AST_Const || node instanceof U.AST_Let ? new U.AST_BlockStatement({
body: [ node ],
start: {},
}) : to_statement(node);;
}) : to_statement(node);
}
function wrap_with_console_log(node) {