aboutsummaryrefslogtreecommitdiff
path: root/tools/js-optimizer.js
diff options
context:
space:
mode:
Diffstat (limited to 'tools/js-optimizer.js')
-rw-r--r--tools/js-optimizer.js25
1 files changed, 21 insertions, 4 deletions
diff --git a/tools/js-optimizer.js b/tools/js-optimizer.js
index 151e573a..d04807a7 100644
--- a/tools/js-optimizer.js
+++ b/tools/js-optimizer.js
@@ -188,12 +188,12 @@ function traverseChildren(node, traverse, pre, post, stack) {
// was stopped, true. Otherwise undefined.
function traverse(node, pre, post, stack) {
var type = node[0], result, len;
- var relevant = typeof node[0] === 'string';
+ var relevant = typeof type === 'string';
if (relevant) {
if (stack) len = stack.length;
var result = pre(node, type, stack);
if (result === true) return true;
- if (Array.isArray(result)) node = result; // Continue processing on this node
+ if (result && result !== null) node = result; // Continue processing on this node
if (stack && len === stack.length) stack.push(0);
}
if (result !== null) {
@@ -584,6 +584,8 @@ function simplifyExpressionsPre(ast) {
node[3] = value[2];
}
}
+ } else if (type == 'sub' && node[1][0] == 'name' && /^FUNCTION_TABLE.*/.exec(node[1][1])) {
+ return null; // do not traverse subchildren here, we should not collapse 55 & 126. TODO: optimize this into a nonvirtual call (also because we lose some other opts here)!
}
});
@@ -2035,7 +2037,6 @@ function eliminate(ast, memSafe) {
// examine body and note locals
var hasSwitch = false;
traverse(func, function(node, type) {
- if (debug && type) type = type.toString();
if (type === 'var') {
var node1 = node[1];
for (var i = 0; i < node1.length; i++) {
@@ -2645,7 +2646,6 @@ function eliminate(ast, memSafe) {
var has_num = false;
var fail = false;
traverse(node, function(subNode, subType) {
- if (debug && subType) subType = subType.toString();
if (subType === 'binary') {
if (subNode[1] !== '+') {
fail = true;
@@ -2807,6 +2807,23 @@ function asmLoopOptimizer(ast) {
var stats = node[2][1];
var last = stats[stats.length-1];
if (last && last[0] === 'if' && !last[3] && last[2][0] === 'block' && last[2][1][0] && last[2][1][0][0] === 'break' && !last[2][1][0][1]) {
+ var abort = false;
+ var stack = 0;
+ traverse(stats, function(node, type) {
+ if (type == 'continue') {
+ if (stack == 0 || node[1]) { // abort if labeled (we do not analyze labels here yet), or a continue directly on us
+ abort = true;
+ return true;
+ }
+ } else if (type in LOOP) {
+ stack++;
+ }
+ }, function(node, type) {
+ if (type in LOOP) {
+ stack--;
+ }
+ });
+ if (abort) return;
var conditionToBreak = last[1];
stats.pop();
node[0] = 'do';