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.js103
1 files changed, 59 insertions, 44 deletions
diff --git a/tools/js-optimizer.js b/tools/js-optimizer.js
index 2b05aeb3..8e815100 100644
--- a/tools/js-optimizer.js
+++ b/tools/js-optimizer.js
@@ -2374,57 +2374,72 @@ function eliminate(ast, memSafe) {
ifTrue = temp;
flip = true;
}
- if (ifTrue[1][0][0] == 'break' && !ifTrue[1][1] && ifFalse[1].length == 1 && ifFalse[1][0][0] == 'stat' && ifFalse[1][0][1][0] == 'assign') {
- var assign = ifFalse[1][0][1];
- if (assign[1] === true && assign[2][0] == 'name' && assign[3][0] == 'name') {
- var looper = assign[2][1];
- var helper = assign[3][1];
- if (definitions[helper] == 1 && seenUses[looper] == namings[looper] &&
- !helperReplacements[helper] && !helperReplacements[looper]) {
- // the remaining issue is whether looper is used after the assignment to helper and before the last line (where we assign to it)
- var found = -1;
- for (var i = stats.length-2; i >= 0; i--) {
- var curr = stats[i];
- if (curr[0] == 'stat' && curr[1][0] == 'assign') {
- var currAssign = curr[1];
- if (currAssign[1] === true && currAssign[2][0] == 'name') {
- var to = currAssign[2][1];
- if (to == helper) {
- found = i;
- break;
- }
- }
+ if (ifTrue[1][0][0] == 'break' && !ifTrue[1][1]) {
+ var assigns = ifFalse[1];
+ var loopers = [], helpers = [];
+ for (var i = 0; i < assigns.length; i++) {
+ if (assigns[i][0] == 'stat' && assigns[i][1][0] == 'assign') {
+ var assign = assigns[i][1];
+ if (assign[1] === true && assign[2][0] == 'name' && assign[3][0] == 'name') {
+ var looper = assign[2][1];
+ var helper = assign[3][1];
+ if (definitions[helper] == 1 && seenUses[looper] == namings[looper] &&
+ !helperReplacements[helper] && !helperReplacements[looper]) {
+ loopers.push(looper);
+ helpers.push(helper);
}
}
- if (found >= 0) {
- var looperUsed = false;
- for (var i = found+1; i < stats.length && !looperUsed; i++) {
- var curr = i < stats.length-1 ? stats[i] : last[1]; // on the last line, just look in the condition
- traverse(curr, function(node, type) {
- if (type == 'name' && node[1] == looper) {
- looperUsed = true;
- return true;
- }
- });
- }
- if (!looperUsed) {
- // hurrah! this is safe to do
- varsToRemove[helper] = 2;
- traverse(node, function(node, type) { // replace all appearances of helper with looper
- if (type == 'name' && node[1] == helper) node[1] = looper;
- });
- helperReplacements[helper] = looper; // replace all future appearances of helper with looper
- helperReplacements[looper] = looper; // avoid any further attempts to optimize looper in this manner (seenUses is wrong anyhow, too)
- // simplify the if. we remove the if branch, leaving only the else
- if (flip) {
- last[1] = simplifyNotComps(['unary-prefix', '!', last[1]]);
- last[2] = last[3];
+ }
+ }
+ if (loopers.length < assigns.length) return; // TODO: handle the case where can can just eliminate one. (we can't optimize the break, but we can remove the var at least)
+ for (var l = 0; l < loopers.length; l++) {
+ var looper = loopers[l];
+ var helper = helpers[l];
+ // the remaining issue is whether loopers are used after the assignment to helper and before the last line (where we assign to it)
+ var found = -1;
+ for (var i = stats.length-2; i >= 0; i--) {
+ var curr = stats[i];
+ if (curr[0] == 'stat' && curr[1][0] == 'assign') {
+ var currAssign = curr[1];
+ if (currAssign[1] === true && currAssign[2][0] == 'name') {
+ var to = currAssign[2][1];
+ if (to == helper) {
+ found = i;
+ break;
}
- last.pop();
}
}
}
+ if (found < 0) return;
+ var looperUsed = false;
+ for (var i = found+1; i < stats.length && !looperUsed; i++) {
+ var curr = i < stats.length-1 ? stats[i] : last[1]; // on the last line, just look in the condition
+ traverse(curr, function(node, type) {
+ if (type == 'name' && node[1] == looper) {
+ looperUsed = true;
+ return true;
+ }
+ });
+ }
+ if (looperUsed) return;
+ }
+ // hurrah! this is safe to do
+ for (var l = 0; l < loopers.length; l++) {
+ var looper = loopers[l];
+ var helper = helpers[l];
+ varsToRemove[helper] = 2;
+ traverse(node, function(node, type) { // replace all appearances of helper with looper
+ if (type == 'name' && node[1] == helper) node[1] = looper;
+ });
+ helperReplacements[helper] = looper; // replace all future appearances of helper with looper
+ helperReplacements[looper] = looper; // avoid any further attempts to optimize looper in this manner (seenUses is wrong anyhow, too)
+ }
+ // simplify the if. we remove the if branch, leaving only the else
+ if (flip) {
+ last[1] = simplifyNotComps(['unary-prefix', '!', last[1]]);
+ last[2] = last[3];
}
+ last.pop();
}
}
}