enhance reduce_vars (#3942)

This commit is contained in:
Alex Lam S.L
2020-06-01 13:55:23 +01:00
committed by GitHub
parent 06ba4e2ce8
commit b24eb22c6b
7 changed files with 260 additions and 192 deletions

View File

@@ -447,7 +447,7 @@ merge(Compressor.prototype, {
} }
function mark(tw, def, safe) { function mark(tw, def, safe) {
tw.safe_ids[def.id] = safe; tw.safe_ids[def.id] = safe && {};
} }
function push_ref(def, ref) { function push_ref(def, ref) {
@@ -455,44 +455,37 @@ merge(Compressor.prototype, {
def.last_ref = ref; def.last_ref = ref;
} }
function add_assign(tw, def, node) {
if (def.fixed === false) return;
tw.assigns.add(def.id, node);
}
function set_assign(tw, def, node) {
if (def.fixed === false) return;
var assigns = tw.assigns.get(def.id);
if (assigns) assigns.forEach(function(node) {
node.assigns = assigns;
});
tw.assigns.set(def.id, def.assigns = [ node ]);
}
function safe_to_read(tw, def) { function safe_to_read(tw, def) {
if (def.single_use == "m") return false; if (def.single_use == "m") return false;
if (tw.safe_ids[def.id]) { var safe = tw.safe_ids[def.id];
if (safe) {
if (!HOP(tw.safe_ids, def.id)) safe.read = safe.read ? true : tw.safe_ids;
if (def.fixed == null) { if (def.fixed == null) {
if (is_arguments(def)) return false; if (is_arguments(def)) return false;
if (def.global && def.name == "arguments") return false; if (def.global && def.name == "arguments") return false;
def.fixed = make_node(AST_Undefined, def.orig[0]); def.fixed = make_node(AST_Undefined, def.orig[0]);
}
return true; return true;
} }
return !safe.assign || safe.assign === tw.safe_ids;
}
return def.fixed instanceof AST_Defun; return def.fixed instanceof AST_Defun;
} }
function safe_to_assign(tw, def, value) { function safe_to_assign(tw, def) {
if (def.fixed === undefined) return true; if (def.fixed === undefined) return true;
if (def.fixed === null && def.safe_ids) { if (def.fixed === null && def.safe_ids) {
def.safe_ids[def.id] = false; def.safe_ids[def.id] = false;
delete def.safe_ids; delete def.safe_ids;
return true; return true;
} }
if (!HOP(tw.safe_ids, def.id)) return false; var safe = tw.safe_ids[def.id];
if (!HOP(tw.safe_ids, def.id)) {
if (!safe) return false;
safe.assign = safe.assign ? true : tw.safe_ids;
}
if (!safe_to_read(tw, def)) return false; if (!safe_to_read(tw, def)) return false;
if (def.fixed === false) return false; if (def.fixed === false) return false;
if (def.fixed != null && (!value || def.references.length > def.assignments)) return false; if (def.fixed != null && safe.read && safe.read !== tw.safe_ids) return false;
return all(def.orig, function(sym) { return all(def.orig, function(sym) {
return !(sym instanceof AST_SymbolLambda); return !(sym instanceof AST_SymbolLambda);
}); });
@@ -573,18 +566,30 @@ merge(Compressor.prototype, {
mark_assignment_to_arguments(sym); mark_assignment_to_arguments(sym);
return; return;
} }
if (sym.fixed) delete sym.fixed;
var d = sym.definition(); var d = sym.definition();
var safe = safe_to_assign(tw, d, node.right);
d.assignments++; d.assignments++;
var fixed = d.fixed;
if (!fixed && node.operator != "=") return;
var eq = node.operator == "="; var eq = node.operator == "=";
var value = eq ? node.right : node; var value = eq ? node.right : node;
if (is_modified(compressor, tw, node, value, 0)) return; if (is_modified(compressor, tw, node, value, 0)) return;
sym.fixed = d.fixed = eq ? function() { var safe = (eq || safe_to_read(tw, d)) && safe_to_assign(tw, d);
var fixed = d.fixed;
if (safe) {
push_ref(d, sym);
mark(tw, d, false);
node.right.walk(tw);
mark(tw, d, true);
if (eq) mark_escaped(tw, d, sym.scope, node, value, 0, 1);
} else {
descend();
}
if (fixed !== false && d.fixed !== false) {
if (eq) {
sym.fixed = d.fixed = function() {
return node.right; return node.right;
} : function() { };
} else {
if (fixed == null) fixed = make_node(AST_Undefined, d.orig[0]);
sym.fixed = d.fixed = function() {
var value = fixed instanceof AST_Node ? fixed : fixed(); var value = fixed instanceof AST_Node ? fixed : fixed();
return value && make_node(AST_Binary, node, { return value && make_node(AST_Binary, node, {
operator: node.operator.slice(0, -1), operator: node.operator.slice(0, -1),
@@ -592,16 +597,9 @@ merge(Compressor.prototype, {
right: node.right right: node.right
}); });
}; };
if (!safe) return; }
push_ref(d, sym); sym.fixed.assigns = eq || !fixed.assigns ? [] : fixed.assigns.slice();
mark(tw, d, false); sym.fixed.assigns.push(node);
node.right.walk(tw);
mark(tw, d, true);
if (eq) {
mark_escaped(tw, d, sym.scope, node, value, 0, 1);
set_assign(tw, d, node);
} else {
add_assign(tw, d, node);
} }
return true; return true;
}); });
@@ -740,13 +738,13 @@ merge(Compressor.prototype, {
fn.argnames.forEach(function(arg, i) { fn.argnames.forEach(function(arg, i) {
var d = arg.definition(); var d = arg.definition();
if (d.fixed === undefined && (!fn.uses_arguments || tw.has_directive("use strict"))) { if (d.fixed === undefined && (!fn.uses_arguments || tw.has_directive("use strict"))) {
tw.loop_ids[d.id] = tw.in_loop;
mark(tw, d, true);
var value = iife.args[i]; var value = iife.args[i];
d.fixed = function() { d.fixed = function() {
var j = fn.argnames.indexOf(arg); var j = fn.argnames.indexOf(arg);
return (j < 0 ? value : iife.args[j]) || make_node(AST_Undefined, iife); return (j < 0 ? value : iife.args[j]) || make_node(AST_Undefined, iife);
}; };
tw.loop_ids[d.id] = tw.in_loop;
mark(tw, d, true);
} else { } else {
d.fixed = false; d.fixed = false;
} }
@@ -787,7 +785,6 @@ merge(Compressor.prototype, {
this.definition().fixed = false; this.definition().fixed = false;
}); });
def(AST_SymbolRef, function(tw, descend, compressor) { def(AST_SymbolRef, function(tw, descend, compressor) {
if (this.fixed) delete this.fixed;
var d = this.definition(); var d = this.definition();
push_ref(d, this); push_ref(d, this);
if (d.references.length == 1 if (d.references.length == 1
@@ -826,6 +823,7 @@ merge(Compressor.prototype, {
} }
mark_escaped(tw, d, this.scope, this, value, 0, 1); mark_escaped(tw, d, this.scope, this, value, 0, 1);
} }
this.fixed = d.fixed;
var parent; var parent;
if (d.fixed instanceof AST_Defun if (d.fixed instanceof AST_Defun
&& !((parent = tw.parent()) instanceof AST_Call && parent.expression === this)) { && !((parent = tw.parent()) instanceof AST_Call && parent.expression === this)) {
@@ -864,12 +862,18 @@ merge(Compressor.prototype, {
mark_assignment_to_arguments(exp); mark_assignment_to_arguments(exp);
return; return;
} }
if (exp.fixed) delete exp.fixed;
var d = exp.definition(); var d = exp.definition();
var safe = safe_to_assign(tw, d, true);
d.assignments++; d.assignments++;
var safe = safe_to_read(tw, d) && safe_to_assign(tw, d);
var fixed = d.fixed; var fixed = d.fixed;
if (!fixed) return; if (safe) {
push_ref(d, exp);
mark(tw, d, true);
} else {
descend();
}
if (fixed !== false && d.fixed !== false) {
if (fixed == null) fixed = make_node(AST_Undefined, d.orig[0]);
d.fixed = function() { d.fixed = function() {
var value = fixed instanceof AST_Node ? fixed : fixed(); var value = fixed instanceof AST_Node ? fixed : fixed();
return value && make_node(AST_Binary, node, { return value && make_node(AST_Binary, node, {
@@ -883,32 +887,38 @@ merge(Compressor.prototype, {
}) })
}); });
}; };
exp.fixed = node instanceof AST_UnaryPrefix ? d.fixed : function() { d.fixed.assigns = fixed.assigns ? fixed.assigns.slice() : [];
d.fixed.assigns.push(node);
if (node instanceof AST_UnaryPrefix) {
exp.fixed = d.fixed;
} else {
exp.fixed = function() {
var value = fixed instanceof AST_Node ? fixed : fixed(); var value = fixed instanceof AST_Node ? fixed : fixed();
return value && make_node(AST_UnaryPrefix, node, { return value && make_node(AST_UnaryPrefix, node, {
operator: "+", operator: "+",
expression: value expression: value
}); });
}; };
if (!safe) return; exp.fixed.assigns = fixed.assigns;
push_ref(d, exp); }
mark(tw, d, true); }
add_assign(tw, d, node);
return true; return true;
}); });
def(AST_VarDef, function(tw, descend) { def(AST_VarDef, function(tw, descend) {
var node = this; var node = this;
var d = node.name.definition(); var d = node.name.definition();
if (node.value) { if (node.value) {
if (safe_to_assign(tw, d, node.value)) { if (safe_to_assign(tw, d)) {
d.fixed = function() {
return node.value;
};
tw.loop_ids[d.id] = tw.in_loop; tw.loop_ids[d.id] = tw.in_loop;
mark(tw, d, false); mark(tw, d, false);
descend(); descend();
mark(tw, d, true); mark(tw, d, true);
set_assign(tw, d, node); if (d.fixed !== false) {
d.fixed = function() {
return node.value;
};
d.fixed.assigns = [ node ];
}
return true; return true;
} else { } else {
d.fixed = false; d.fixed = false;
@@ -933,8 +943,6 @@ merge(Compressor.prototype, {
reset_flags(node); reset_flags(node);
return node.reduce_vars(tw, descend, compressor); return node.reduce_vars(tw, descend, compressor);
} : reset_flags); } : reset_flags);
// Assignment chains
tw.assigns = new Dictionary();
// Flow control for visiting `AST_Defun`s // Flow control for visiting `AST_Defun`s
tw.defun_ids = Object.create(null); tw.defun_ids = Object.create(null);
tw.defun_visited = Object.create(null); tw.defun_visited = Object.create(null);
@@ -951,6 +959,7 @@ merge(Compressor.prototype, {
function reset_flags(node) { function reset_flags(node) {
node._squeezed = false; node._squeezed = false;
node._optimized = false; node._optimized = false;
delete node.fixed;
if (node instanceof AST_Scope) delete node._var_names; if (node instanceof AST_Scope) delete node._var_names;
} }
}); });
@@ -4222,7 +4231,7 @@ merge(Compressor.prototype, {
})) return; })) return;
return sym; return sym;
}; };
var chained = Object.create(null); var assign_in_use = Object.create(null);
var in_use = []; var in_use = [];
var in_use_ids = Object.create(null); // avoid expensive linear scans of in_use var in_use_ids = Object.create(null); // avoid expensive linear scans of in_use
var value_read = Object.create(null); var value_read = Object.create(null);
@@ -4235,7 +4244,7 @@ merge(Compressor.prototype, {
} }
}); });
} }
var assign_in_use = new Dictionary(); var assignments = new Dictionary();
var var_defs_by_id = new Dictionary(); var var_defs_by_id = new Dictionary();
var initializations = new Dictionary(); var initializations = new Dictionary();
// pass 1: find out which symbols are directly used in // pass 1: find out which symbols are directly used in
@@ -4282,7 +4291,7 @@ merge(Compressor.prototype, {
} else { } else {
initializations.add(node_def.id, def.value); initializations.add(node_def.id, def.value);
} }
match_assigns(node_def, def); assignments.add(node_def.id, def);
} }
}); });
return true; return true;
@@ -4300,6 +4309,33 @@ merge(Compressor.prototype, {
init.walk(tw); init.walk(tw);
}); });
} }
Object.keys(assign_in_use).forEach(function(id) {
var assigns = assign_in_use[id];
if (!assigns) {
delete assign_in_use[id];
return;
}
assigns = assigns.reduce(function(in_use, assigns) {
assigns.forEach(function(assign) {
push_uniq(in_use, assign);
});
return in_use;
}, []);
var in_use = (assignments.get(id) || []).filter(function(node) {
return find_if(node instanceof AST_Unary ? function(assign) {
return assign === node;
} : function(assign) {
if (assign === node) return true;
if (assign instanceof AST_Unary) return false;
return get_rvalue(assign) === get_rvalue(node);
}, assigns);
});
if (assigns.length == in_use.length) {
assign_in_use[id] = in_use;
} else {
delete assign_in_use[id];
}
});
var drop_fn_name = compressor.option("keep_fnames") ? return_false : compressor.option("ie8") ? function(def) { var drop_fn_name = compressor.option("keep_fnames") ? return_false : compressor.option("ie8") ? function(def) {
return !compressor.exposed(def) && def.references.length == def.replaced; return !compressor.exposed(def) && def.references.length == def.replaced;
} : function(def) { } : function(def) {
@@ -4487,7 +4523,7 @@ merge(Compressor.prototype, {
right: def.value right: def.value
}); });
var index = indexOf_assign(sym, def); var index = indexOf_assign(sym, def);
if (index >= 0) assign_in_use.get(sym.id)[index] = assign; if (index >= 0) assign_in_use[sym.id][index] = assign;
sym.eliminated++; sym.eliminated++;
return assign.transform(tt); return assign.transform(tt);
})); }));
@@ -4605,30 +4641,20 @@ merge(Compressor.prototype, {
}; };
} }
function match_assigns(def, node) { function track_assigns(def, node) {
if (!def.fixed) return; if (def.scope !== self) return false;
if (!def.assigns) return; if (!def.fixed || !node.fixed) assign_in_use[def.id] = false;
if (find_if(node instanceof AST_Unary ? function(assign) { return assign_in_use[def.id] !== false;
return assign === node;
} : function(assign) {
if (assign === node) return true;
if (assign instanceof AST_Unary) return false;
return get_rvalue(assign) === get_rvalue(node);
}, def.assigns)) {
assign_in_use.add(def.id, node);
} }
function add_assigns(def, node) {
if (!assign_in_use[def.id]) assign_in_use[def.id] = [];
if (node.fixed.assigns) push_uniq(assign_in_use[def.id], node.fixed.assigns);
} }
function indexOf_assign(def, node) { function indexOf_assign(def, node) {
if (!def.fixed) return; var nodes = assign_in_use[def.id];
if (!def.assigns) return; return nodes && nodes.indexOf(node);
var assigns = assign_in_use.get(def.id);
if (!assigns) return;
if (assigns.length != def.assigns.length) return;
var index = assigns.indexOf(node);
if (index >= 0 || !chained[def.id] || node.assigns && all(node.assigns, function(assign) {
return assign.write_only || assign.operator == "=" || assign instanceof AST_VarDef;
})) return index;
} }
function verify_safe_usage(def, read, modified) { function verify_safe_usage(def, read, modified) {
@@ -4653,14 +4679,12 @@ merge(Compressor.prototype, {
function scan_ref_scoped(node, descend, init) { function scan_ref_scoped(node, descend, init) {
if (node instanceof AST_Assign && node.left instanceof AST_SymbolRef) { if (node instanceof AST_Assign && node.left instanceof AST_SymbolRef) {
var node_def = node.left.definition(); var def = node.left.definition();
if (node.operator != "=") chained[node_def.id] = true; if (def.scope === self) assignments.add(def.id, node);
match_assigns(node_def, node);
} }
if (node instanceof AST_Unary && node.expression instanceof AST_SymbolRef) { if (node instanceof AST_Unary && node.expression instanceof AST_SymbolRef) {
var node_def = node.expression.definition(); var def = node.expression.definition();
chained[node_def.id] = true; if (def.scope === self) assignments.add(def.id, node);
match_assigns(node_def, node);
} }
var node_def, props = [], sym = assign_as_unused(node, props); var node_def, props = [], sym = assign_as_unused(node, props);
if (sym && self.variables.get(sym.name) === (node_def = sym.definition())) { if (sym && self.variables.get(sym.name) === (node_def = sym.definition())) {
@@ -4686,6 +4710,7 @@ merge(Compressor.prototype, {
} }
} }
} }
track_assigns(node_def, sym);
return true; return true;
} }
if (node instanceof AST_SymbolRef) { if (node instanceof AST_SymbolRef) {
@@ -4694,6 +4719,7 @@ merge(Compressor.prototype, {
in_use_ids[node_def.id] = true; in_use_ids[node_def.id] = true;
in_use.push(node_def); in_use.push(node_def);
} }
if (track_assigns(node_def, node)) add_assigns(node_def, node);
return true; return true;
} }
if (node instanceof AST_Scope) { if (node instanceof AST_Scope) {
@@ -7641,7 +7667,8 @@ merge(Compressor.prototype, {
def.replaced++; def.replaced++;
return value; return value;
} }
if (fixed && def.should_replace === undefined) { var local = self.fixed !== def.fixed;
if (fixed && (local || def.should_replace !== false)) {
var init; var init;
if (fixed instanceof AST_This) { if (fixed instanceof AST_This) {
if (!(def.orig[0] instanceof AST_SymbolFunarg) && same_scope(def)) { if (!(def.orig[0] instanceof AST_SymbolFunarg) && same_scope(def)) {
@@ -7659,19 +7686,10 @@ merge(Compressor.prototype, {
} }
} }
if (init) { if (init) {
if (!local && def.should_replace === undefined) {
var value_length = init.optimize(compressor).print_to_string().length; var value_length = init.optimize(compressor).print_to_string().length;
var fn; if (!has_symbol_ref(fixed)) {
if (has_symbol_ref(fixed)) {
fn = function() {
var result = init.optimize(compressor);
return result === init ? result.clone(true) : result;
};
} else {
value_length = Math.min(value_length, fixed.print_to_string().length); value_length = Math.min(value_length, fixed.print_to_string().length);
fn = function() {
var result = best_of_expression(init.optimize(compressor), fixed);
return result === init || result === fixed ? result.clone(true) : result;
};
} }
var name_length = def.name.length; var name_length = def.name.length;
if (compressor.option("unused") && !compressor.exposed(def)) { if (compressor.option("unused") && !compressor.exposed(def)) {
@@ -7679,17 +7697,23 @@ merge(Compressor.prototype, {
name_length += (name_length + 2 + value_length) / (referenced - def.assignments); name_length += (name_length + 2 + value_length) / (referenced - def.assignments);
} }
var delta = value_length - Math.floor(name_length); var delta = value_length - Math.floor(name_length);
def.should_replace = delta < compressor.eval_threshold ? fn : false; def.should_replace = delta < compressor.eval_threshold;
}
if (local || def.should_replace) {
var value;
if (has_symbol_ref(fixed)) {
value = init.optimize(compressor);
if (value === init) value = value.clone(true);
} else { } else {
def.should_replace = false; value = best_of_expression(init.optimize(compressor), fixed);
if (value === init || value === fixed) value = value.clone(true);
} }
}
if (def.should_replace) {
var value = def.should_replace();
def.replaced++; def.replaced++;
return value; return value;
} }
} }
}
}
return self; return self;
function same_scope(def) { function same_scope(def) {

View File

@@ -3001,8 +3001,6 @@ issue_2298: {
expect: { expect: {
!function() { !function() {
(function() { (function() {
var a = undefined;
var undefined = a++;
try { try {
!function(b) { !function(b) {
(void 0)[1] = "foo"; (void 0)[1] = "foo";
@@ -3836,20 +3834,19 @@ issue_2436_3: {
}(o)); }(o));
} }
expect: { expect: {
var o = {
a: 1,
b: 2,
};
console.log(function(c) { console.log(function(c) {
o = { ({
a: 3, a: 3,
b: 4, b: 4,
}; });
return { return {
x: c.a, x: c.a,
y: c.b, y: c.b,
}; };
}(o)); }({
a: 1,
b: 2,
}));
} }
expect_stdout: true expect_stdout: true
} }
@@ -4071,16 +4068,15 @@ issue_2436_10: {
}(o).join(" ")); }(o).join(" "));
} }
expect: { expect: {
var o = {
a: 1,
b: 2,
};
function f(n) { function f(n) {
o = { b: 3 }; ({ b: 3 });
return n; return n;
} }
console.log([ console.log([
(c = o).a, (c = {
a: 1,
b: 2,
}).a,
f(c.b), f(c.b),
c.b, c.b,
].join(" ")); ].join(" "));

View File

@@ -1729,7 +1729,7 @@ chained_3: {
} }
expect: { expect: {
console.log(function(a, b) { console.log(function(a, b) {
var c = b; var c = 2;
b++; b++;
return c; return c;
}(0, 2)); }(0, 2));
@@ -2557,7 +2557,7 @@ issue_3899: {
console.log(typeof a); console.log(typeof a);
} }
expect: { expect: {
++a; 0;
var a = function() { var a = function() {
return 2; return 2;
}; };
@@ -2565,3 +2565,63 @@ issue_3899: {
} }
expect_stdout: "function" expect_stdout: "function"
} }
cross_scope_assign_chain: {
options = {
reduce_vars: true,
side_effects: true,
toplevel: true,
unused: true,
}
input: {
var a, b = 0;
(function() {
a = b;
a++;
while (b++);
})();
console.log(a ? "PASS" : "FAIL");
}
expect: {
var a, b = 0;
(function() {
a = b;
a++;
while (b++);
})();
console.log(a ? "PASS" : "FAIL");
}
expect_stdout: "PASS"
}
assign_if_assign_read: {
options = {
reduce_vars: true,
unused: true,
}
input: {
(function(a) {
var b;
do {
b = "FAIL";
if (Array.isArray(a)) {
b = a[0];
console.log(b);
}
} while (!console);
})([ "PASS" ]);
}
expect: {
(function(a) {
var b;
do {
"FAIL";
if (Array.isArray(a)) {
b = a[0];
console.log(b);
}
} while (!console);
})([ "PASS" ]);
}
expect_stdout: "PASS"
}

View File

@@ -2412,9 +2412,9 @@ issue_3887: {
expect: { expect: {
(function(b) { (function(b) {
try { try {
b-- && console.log("PASS"); 1, console.log("PASS");
} catch (a_2) {} } catch (a_2) {}
})(1); })();
} }
expect_stdout: "PASS" expect_stdout: "PASS"
} }
@@ -2478,10 +2478,10 @@ issue_3920: {
console.log(a); console.log(a);
} }
expect: { expect: {
var a = function(b) { (function(b) {
return (b[b = 0] = 0) >= (b ? 0 : 1); "foo"[0] = 0;
}("foo"); })();
console.log(a); console.log(false);
} }
expect_stdout: "false" expect_stdout: "false"
} }

View File

@@ -2336,6 +2336,7 @@ issue_3274: {
inline: true, inline: true,
join_vars: true, join_vars: true,
loops: true, loops: true,
passes: 2,
reduce_vars: true, reduce_vars: true,
unused: true, unused: true,
} }

View File

@@ -306,8 +306,6 @@ issue_2298: {
expect: { expect: {
!function() { !function() {
(function() { (function() {
var a = undefined;
var undefined = a++;
try { try {
!function() { !function() {
(void 0)[1] = "foo"; (void 0)[1] = "foo";

View File

@@ -905,7 +905,7 @@ use_before_var: {
} }
expect: { expect: {
function f(){ function f(){
console.log(t); console.log(void 0);
var t = 1; var t = 1;
} }
} }
@@ -981,12 +981,12 @@ inner_var_for_1: {
expect: { expect: {
function f() { function f() {
var a = 1; var a = 1;
x(1, b, d); x(1, void 0, d);
for (var b = 2, c = 3; x(1, b, 3, d); x(1, b, 3, d)) { for (var b = 2, c = 3; x(1, 2, 3, d); x(1, 2, 3, d)) {
var d = 4, e = 5; var d = 4, e = 5;
x(1, b, 3, d, e); x(1, 2, 3, d, e);
} }
x(1, b, 3, d, e); x(1, 2, 3, d, e);
} }
} }
} }
@@ -1521,9 +1521,7 @@ func_inline: {
expect: { expect: {
function f() { function f() {
console.log(1 + h()); console.log(1 + h());
var h = function() { var h;
return 2;
};
} }
} }
} }
@@ -2372,8 +2370,7 @@ delay_def: {
return; return;
} }
function g() { function g() {
return a; return;
var a = 1;
} }
console.log(f(), g()); console.log(f(), g());
} }
@@ -2395,7 +2392,7 @@ delay_def_lhs: {
expect: { expect: {
console.log(function() { console.log(function() {
long_name++; long_name++;
return long_name; return NaN;
var long_name; var long_name;
}()); }());
} }
@@ -2651,11 +2648,9 @@ var_assign_5: {
} }
expect: { expect: {
!function() { !function() {
var a;
!function(b) { !function(b) {
a = 2, console.log(2, void 0);
console.log(a, b); }();
}(a);
}(); }();
} }
expect_stdout: "2 undefined" expect_stdout: "2 undefined"
@@ -4725,7 +4720,7 @@ escape_conditional: {
function bar() {} function bar() {}
(function() { (function() {
var thing = baz(); var thing = baz();
if (thing !== (thing = baz())) if (thing !== baz())
console.log("FAIL"); console.log("FAIL");
else else
console.log("PASS"); console.log("PASS");
@@ -4763,7 +4758,7 @@ escape_sequence: {
function bar() {} function bar() {}
(function() { (function() {
var thing = baz(); var thing = baz();
if (thing !== (thing = baz())) if (thing !== baz())
console.log("FAIL"); console.log("FAIL");
else else
console.log("PASS"); console.log("PASS");
@@ -4808,7 +4803,7 @@ escape_throw: {
function foo() {} function foo() {}
(function() { (function() {
var thing = baz(); var thing = baz();
if (thing !== (thing = baz())) if (thing !== baz())
console.log("FAIL"); console.log("FAIL");
else else
console.log("PASS"); console.log("PASS");
@@ -4845,7 +4840,7 @@ escape_local_conditional: {
} }
(function() { (function() {
var thing = baz(); var thing = baz();
if (thing !== (thing = baz())) if (thing !== baz())
console.log("PASS"); console.log("PASS");
else else
console.log("FAIL"); console.log("FAIL");
@@ -4882,7 +4877,7 @@ escape_local_sequence: {
} }
(function() { (function() {
var thing = baz(); var thing = baz();
if (thing !== (thing = baz())) if (thing !== baz())
console.log("PASS"); console.log("PASS");
else else
console.log("FAIL"); console.log("FAIL");
@@ -4926,7 +4921,7 @@ escape_local_throw: {
} }
(function() { (function() {
var thing = baz(); var thing = baz();
if (thing !== (thing = baz())) if (thing !== baz())
console.log("PASS"); console.log("PASS");
else else
console.log("FAIL"); console.log("FAIL");
@@ -4980,11 +4975,7 @@ inverted_var: {
console.log(1, 2, 3, 4, 5, function c() { console.log(1, 2, 3, 4, 5, function c() {
c = 6; c = 6;
return c; return c;
}(), 7, function() { }(), 7, 8);
c = 8;
return c;
var c = "foo";
}());
} }
expect_stdout: true expect_stdout: true
} }
@@ -5180,9 +5171,7 @@ defun_var_3: {
var a = 42, b; var a = 42, b;
} }
expect: { expect: {
function a() {} console.log("function", "function");
console.log(typeof a, "function");
var a = 42;
} }
expect_stdout: "function function" expect_stdout: "function function"
} }