fix corner case in reduce_vars (#3129)

This commit is contained in:
Alex Lam S.L
2018-05-10 18:45:20 +08:00
committed by GitHub
parent 14e712ee80
commit 7bc7704edf
2 changed files with 53 additions and 13 deletions

View File

@@ -361,7 +361,7 @@ merge(Compressor.prototype, {
if (def.scope === scope) return true; if (def.scope === scope) return true;
} while (scope instanceof AST_Function && (scope = scope.parent_scope)); } while (scope instanceof AST_Function && (scope = scope.parent_scope));
})) { })) {
tw.defun_ids[def.id] = undefined; tw.defun_ids[def.id] = false;
} }
def.recursive_refs = 0; def.recursive_refs = 0;
def.references = []; def.references = [];
@@ -386,23 +386,29 @@ merge(Compressor.prototype, {
if (def.id in tw.defun_ids) { if (def.id in tw.defun_ids) {
var marker = tw.defun_ids[def.id]; var marker = tw.defun_ids[def.id];
if (!marker) return; if (!marker) return;
if (marker !== tw.safe_ids) { var visited = tw.defun_visited[def.id];
tw.defun_ids[def.id] = undefined; if (marker === tw.safe_ids) {
return; if (!visited) return def.fixed;
} else 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;
});
} else {
tw.defun_ids[def.id] = false;
} }
return def.fixed; } else {
} if (!tw.in_loop) {
if (!tw.in_loop) { tw.defun_ids[def.id] = tw.safe_ids;
tw.defun_ids[def.id] = tw.safe_ids; return def.fixed;
return def.fixed; }
} else if (tw.defun_ids[def.id] !== false) { tw.defun_ids[def.id] = false;
tw.defun_ids[def.id] = undefined;
} }
} }
function walk_defuns(tw, scope) { function walk_defuns(tw, scope) {
scope.functions.each(function(def) { scope.functions.each(function(def) {
if (def.init instanceof AST_Defun && tw.defun_ids[def.id] === undefined) { if (def.init instanceof AST_Defun && !tw.defun_visited[def.id]) {
tw.defun_ids[def.id] = tw.safe_ids; tw.defun_ids[def.id] = tw.safe_ids;
def.init.walk(tw); def.init.walk(tw);
} }
@@ -587,8 +593,9 @@ merge(Compressor.prototype, {
}); });
def(AST_Defun, function(tw, descend, compressor) { def(AST_Defun, function(tw, descend, compressor) {
var id = this.name.definition().id; var id = this.name.definition().id;
if (tw.defun_visited[id]) return true;
if (tw.defun_ids[id] !== tw.safe_ids) return true; if (tw.defun_ids[id] !== tw.safe_ids) return true;
tw.defun_ids[id] = false; tw.defun_visited[id] = true;
this.inlined = false; this.inlined = false;
push(tw); push(tw);
reset_variables(tw, compressor, this); reset_variables(tw, compressor, this);
@@ -820,6 +827,7 @@ merge(Compressor.prototype, {
}); });
// 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);
// Record the loop body in which `AST_SymbolDeclaration` is first encountered // Record the loop body in which `AST_SymbolDeclaration` is first encountered
tw.in_loop = null; tw.in_loop = null;
tw.loop_ids = Object.create(null); tw.loop_ids = Object.create(null);

View File

@@ -6059,6 +6059,38 @@ conditional_nested_2: {
expect_stdout: "1" expect_stdout: "1"
} }
conditional_nested_3: {
options = {
evaluate: true,
reduce_vars: true,
}
input: {
var n = 2, c = 0;
(function f(a) {
0 < n-- && g(a = 1);
function g() {
a && c++;
}
g();
0 < n-- && f();
})();
console.log(c);
}
expect: {
var n = 2, c = 0;
(function f(a) {
0 < n-- && g(a = 1);
function g() {
a && c++;
}
g();
0 < n-- && f();
})();
console.log(c);
}
expect_stdout: "2"
}
issue_2436: { issue_2436: {
options = { options = {
evaluate: true, evaluate: true,