diff options
Diffstat (limited to 'tools')
-rw-r--r-- | tools/js-optimizer.js | 122 | ||||
-rw-r--r-- | tools/test-js-optimizer-output.js | 7 | ||||
-rw-r--r-- | tools/test-js-optimizer.js | 10 |
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; |