aboutsummaryrefslogtreecommitdiff
path: root/tools
diff options
context:
space:
mode:
authorAlon Zakai <alonzakai@gmail.com>2014-03-15 21:39:23 -0700
committerAlon Zakai <alonzakai@gmail.com>2014-03-17 17:56:17 -0700
commitc4fc4453aacc8c1933e9cd256c04890978095003 (patch)
tree18b9f7065863fa8bd32abad2ae2454471b2058f6 /tools
parent6c31546ced32fd968ae50da7803964c9195ebd62 (diff)
simplify nested ifs with identical elses
Diffstat (limited to 'tools')
-rw-r--r--tools/js-optimizer.js18
-rw-r--r--tools/test-js-optimizer-si-output.js29
-rw-r--r--tools/test-js-optimizer-si.js33
3 files changed, 77 insertions, 3 deletions
diff --git a/tools/js-optimizer.js b/tools/js-optimizer.js
index bb6acf73..4b63ab9b 100644
--- a/tools/js-optimizer.js
+++ b/tools/js-optimizer.js
@@ -303,6 +303,16 @@ function removeAllEmptySubNodes(ast) {
traverse(ast, removeEmptySubNodes);
}
+function astCompare(x, y) {
+ if (!Array.isArray(x)) return x === y;
+ if (!Array.isArray(y)) return false;
+ if (x.length !== y.length) return false;
+ for (var i = 0; i < x.length; i++) {
+ if (!astCompare(x[i], y[i])) return false;
+ }
+ return true;
+}
+
// Passes
// Dump the AST. Useful for debugging. For example,
@@ -830,14 +840,14 @@ function simplifyExpressions(ast) {
function simplifyIfs(ast) {
traverse(ast, function(node, type) {
// simplify if (x) { if (y) { .. } } to if (x ? y : 0) { .. }
- if (type === 'if' && !node[3]) {
+ if (type === 'if') {
var body = node[2];
// recurse to handle chains
while (body[0] === 'block') {
var stats = body[1];
if (stats.length > 1) {
var last = stats[stats.length-1];
- if (last[0] === 'if' && !last[3]) {
+ if (last[0] === 'if') {
// try to commaify - turn everything between the ifs into a comma operator inside the second if
var ok = true;
for (var i = 0; i < stats.length-1; i++) {
@@ -857,7 +867,9 @@ function simplifyIfs(ast) {
}
if (stats.length !== 1) break;
var singleton = stats[0];
- if (singleton[0] === 'if' && !singleton[3]) {
+ // we can handle elses, but must be fully identical
+ if (!astCompare(node[3], singleton[3])) break;
+ if (singleton[0] === 'if') {
node[1] = ['conditional', node[1], singleton[1], ['num', 0]];
body = node[2] = singleton[2];
} else {
diff --git a/tools/test-js-optimizer-si-output.js b/tools/test-js-optimizer-si-output.js
index bd36ef10..8b93803d 100644
--- a/tools/test-js-optimizer-si-output.js
+++ b/tools/test-js-optimizer-si-output.js
@@ -66,5 +66,34 @@ function a() {
g();
}
}
+ andNowForElses();
+ if (x ? y : 0) {
+ f();
+ } else {
+ label = 5;
+ }
+ if (x) {
+ if (y) {
+ f();
+ } else {
+ label = 5;
+ }
+ } else {
+ label = 6;
+ }
+ if (x) {
+ if (y) {
+ f();
+ } else {
+ label = 5;
+ }
+ }
+ if (x) {
+ if (y) {
+ f();
+ }
+ } else {
+ label = 5;
+ }
}
diff --git a/tools/test-js-optimizer-si.js b/tools/test-js-optimizer-si.js
index 5f6b334f..6952b183 100644
--- a/tools/test-js-optimizer-si.js
+++ b/tools/test-js-optimizer-si.js
@@ -84,5 +84,38 @@ function a() {
g();
}
}
+ andNowForElses();
+ if (x) {
+ if (y) {
+ f();
+ } else {
+ label = 5;
+ }
+ } else {
+ label = 5;
+ }
+ if (x) {
+ if (y) {
+ f();
+ } else {
+ label = 5;
+ }
+ } else {
+ label = 6;
+ }
+ if (x) {
+ if (y) {
+ f();
+ } else {
+ label = 5;
+ }
+ }
+ if (x) {
+ if (y) {
+ f();
+ }
+ } else {
+ label = 5;
+ }
}