aboutsummaryrefslogtreecommitdiff
path: root/tools
diff options
context:
space:
mode:
Diffstat (limited to 'tools')
-rw-r--r--tools/js-optimizer.js122
-rw-r--r--tools/test-js-optimizer-output.js7
-rw-r--r--tools/test-js-optimizer.js10
3 files changed, 76 insertions, 63 deletions
diff --git a/tools/js-optimizer.js b/tools/js-optimizer.js
index c5d3a79f..7ac2195f 100644
--- a/tools/js-optimizer.js
+++ b/tools/js-optimizer.js
@@ -101,7 +101,7 @@ function traverse(node, pre, post, stack) {
// Only walk through the generated functions
function traverseGenerated(ast, pre, post, stack) {
- ast[1].forEach(function(node, i) {
+ traverse(ast, function(node) {
if (node[0] == 'defun' && isGenerated(node[1])) {
traverse(node, pre, post, stack);
}
@@ -109,7 +109,7 @@ function traverseGenerated(ast, pre, post, stack) {
}
function traverseGeneratedFunctions(ast, callback) {
- ast[1].forEach(function(node, i) {
+ traverse(ast, function(node) {
if (node[0] == 'defun' && isGenerated(node[1])) {
callback(node);
}
@@ -717,72 +717,69 @@ function vacuum(ast) {
var more = true;
while (more) {
more = false;
- ast[1].forEach(function(node, i) {
- function simplifyList(node, i) {
- var changed = false;
- var pre = node[i].length;
- node[i] = node[i].filter(function(node) { return !isEmpty(node) });
- if (node[i].length < pre) changed = true;
- // Also, seek blocks with single items we can simplify
- node[i] = node[i].map(function(subNode) {
- if (subNode[0] == 'block' && typeof subNode[1] == 'object' && subNode[1].length == 1 && subNode[1][0][0] == 'if') {
- return subNode[1][0];
- }
- return subNode;
- });
- if (changed) {
- more = true;
- return node;
+ function simplifyList(node, i) {
+ var changed = false;
+ var pre = node[i].length;
+ node[i] = node[i].filter(function(node) { return !isEmpty(node) });
+ if (node[i].length < pre) changed = true;
+ // Also, seek blocks with single items we can simplify
+ node[i] = node[i].map(function(subNode) {
+ if (subNode[0] == 'block' && typeof subNode[1] == 'object' && subNode[1].length == 1 && subNode[1][0][0] == 'if') {
+ return subNode[1][0];
}
+ return subNode;
+ });
+ if (changed) {
+ more = true;
+ return node;
}
- var type = node[0];
- if (type == 'defun' && isGenerated(node[1])) {
- simplifyNotComps(node);
- traverse(node, function(node, type) {
- if (type == 'block' && node[1] && node[1].length == 1 && node[1][0][0] == 'block') {
- more = true;
- return node[1][0];
- } else if (type == 'stat' && node[1][0] == 'block') {
- more = true;
- return node[1];
- } else if (type == 'block' && typeof node[1] == 'object') {
- ret = simplifyList(node, 1);
- if (ret) return ret;
- } else if (type == 'defun' && node[3].length == 1 && node[3][0][0] == 'block') {
+ }
+ traverseGeneratedFunctions(ast, function(node) {
+ simplifyNotComps(node);
+ traverse(node, function(node, type) {
+ if (type == 'block' && node[1] && node[1].length == 1 && node[1][0][0] == 'block') {
+ more = true;
+ return node[1][0];
+ } else if (type == 'stat' && node[1][0] == 'block') {
+ more = true;
+ return node[1];
+ } else if (type == 'block' && typeof node[1] == 'object') {
+ ret = simplifyList(node, 1);
+ if (ret) return ret;
+ } else if (type == 'defun' && node[3].length == 1 && node[3][0][0] == 'block') {
+ more = true;
+ node[3] = node[3][0][1];
+ return node;
+ } else if (type == 'defun') {
+ ret = simplifyList(node, 3);
+ if (ret) return ret;
+ } else if (type == 'do' && node[1][0] == 'num' && jsonCompare(node[2], emptyNode())) {
+ more = true;
+ return emptyNode();
+ } else if (type == 'label' && jsonCompare(node[2], emptyNode())) {
+ more = true;
+ return emptyNode();
+ } else if (type == 'if') {
+ var empty2 = isEmpty(node[2]), empty3 = isEmpty(node[3]), has3 = node.length == 4;
+ if (!empty2 && empty3 && has3) { // empty else clauses
more = true;
- node[3] = node[3][0][1];
- return node;
- } else if (type == 'defun') {
- ret = simplifyList(node, 3);
- if (ret) return ret;
- } else if (type == 'do' && node[1][0] == 'num' && jsonCompare(node[2], emptyNode())) {
+ return node.slice(0, 3);
+ } else if (empty2 && !empty3) { // empty if blocks
more = true;
- return emptyNode();
- } else if (type == 'label' && jsonCompare(node[2], emptyNode())) {
+ return ['if', ['unary-prefix', '!', node[1]], node[3]];
+ } else if (empty2 && empty3) {
more = true;
- return emptyNode();
- } else if (type == 'if') {
- var empty2 = isEmpty(node[2]), empty3 = isEmpty(node[3]), has3 = node.length == 4;
- if (!empty2 && empty3 && has3) { // empty else clauses
- more = true;
- return node.slice(0, 3);
- } else if (empty2 && !empty3) { // empty if blocks
- more = true;
- return ['if', ['unary-prefix', '!', node[1]], node[3]];
- } else if (empty2 && empty3) {
- more = true;
- if (hasSideEffects(node[1])) {
- return ['stat', node[1]];
- } else {
- return emptyNode();
- }
+ if (hasSideEffects(node[1])) {
+ return ['stat', node[1]];
+ } else {
+ return emptyNode();
}
- } else if (type == 'do' && isEmpty(node[2]) && !hasSideEffects(node[1])) {
- more = true;
- return emptyNode();
}
- });
- }
+ } else if (type == 'do' && isEmpty(node[2]) && !hasSideEffects(node[1])) {
+ more = true;
+ return emptyNode();
+ }
+ });
});
}
}
@@ -803,8 +800,7 @@ function getStatements(node) {
// if (condition) { __label__ == x } else ..
// We can hoist the multiple block into the condition, thus removing code and one 'if' check
function hoistMultiples(ast) {
- ast[1].forEach(function(node, i) {
- if (!(node[0] == 'defun' && isGenerated(node[1]))) return;
+ traverseGeneratedFunctions(ast, function(node) {
traverse(node, function(node, type) {
var statements = getStatements(node);
if (!statements) return;
diff --git a/tools/test-js-optimizer-output.js b/tools/test-js-optimizer-output.js
index b1bdc0f8..acf48008 100644
--- a/tools/test-js-optimizer-output.js
+++ b/tools/test-js-optimizer-output.js
@@ -174,6 +174,13 @@ function hoisting() {
var $79 = $_pr6;
}
}
+function innerShouldAlsoBeHoisted() {
+ function hoisting() {
+ if ($i < $N) {
+ callOther();
+ }
+ }
+}
var FS = {
absolutePath: (function(relative, base) {
if (typeof relative !== "string") return null;
diff --git a/tools/test-js-optimizer.js b/tools/test-js-optimizer.js
index 155aa647..f9c499f4 100644
--- a/tools/test-js-optimizer.js
+++ b/tools/test-js-optimizer.js
@@ -217,6 +217,16 @@ function hoisting() {
}
} while (0);
}
+function innerShouldAlsoBeHoisted() {
+ function hoisting() {
+ if ($i < $N) {
+ __label__ = 2;
+ }
+ if (__label__ == 2) {
+ callOther();
+ }
+ }
+}
var FS = {
absolutePath: function(relative, base) { // Don't touch this!
if (typeof relative !== 'string') return null;