better solution for the last test in constant switch folding

This commit is contained in:
Mihai Bazon
2012-11-14 12:21:43 +02:00
parent dba8da4800
commit bdfcbf496b
2 changed files with 51 additions and 22 deletions

View File

@@ -1368,7 +1368,8 @@ merge(Compressor.prototype, {
self.expression = exp[0];
if (!compressor.option("dead_code")) break out;
var value = exp[1];
var in_substat = false;
var in_if = false;
var in_block = false;
var started = false;
var stopped = false;
var ruined = false;
@@ -1377,8 +1378,7 @@ merge(Compressor.prototype, {
// no need to descend these node types
return node;
}
else if (node instanceof AST_Switch) {
if (node === self) {
else if (node instanceof AST_Switch && node === self) {
node = node.clone();
descend(node, this);
return ruined ? node : make_node(AST_BlockStatement, node, {
@@ -1387,22 +1387,27 @@ merge(Compressor.prototype, {
}, [])
}).transform(compressor);
}
}
else if (node instanceof AST_StatementWithBody || node instanceof AST_Switch || node instanceof AST_Try) {
var save_substat = in_substat;
in_substat = true;
else if (node instanceof AST_If || node instanceof AST_Try) {
var save = in_if;
in_if = !in_block;
descend(node, this);
in_substat = save_substat;
in_if = save;
return node;
}
else if (node instanceof AST_StatementWithBody || node instanceof AST_Switch) {
var save = in_block;
in_block = true;
descend(node, this);
in_block = save;
return node;
}
else if (node instanceof AST_Break && this.loopcontrol_target(node.label) === self) {
if (in_substat) {
// won't handle situations like if (foo) break;
if (in_if) {
ruined = true;
return node;
} else {
stopped = true;
}
if (in_block) return node;
stopped = true;
return in_list ? MAP.skip : make_node(AST_EmptyStatement, node);
}
else if (node instanceof AST_SwitchBranch && this.parent() === self) {

View File

@@ -176,11 +176,35 @@ constant_switch_8: {
}
}
expect: {
OUT: switch (1) {
case 1:
OUT: {
x();
for (;;) break OUT;
y();
}
}
}
constant_switch_9: {
options = { dead_code: true, evaluate: true };
input: {
OUT: switch (1) {
case 1:
x();
for (;;) if (foo) break OUT;
y();
case 1+1:
bar();
default:
def();
}
}
expect: {
OUT: {
x();
for (;;) if (foo) break OUT;
y();
bar();
def();
}
}
}