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