diff options
-rw-r--r-- | src/analyzer.js | 39 | ||||
-rw-r--r-- | src/jsifier.js | 5 | ||||
-rw-r--r-- | src/parseTools.js | 4 |
3 files changed, 29 insertions, 19 deletions
diff --git a/src/analyzer.js b/src/analyzer.js index c3cdf573..fff9cd48 100644 --- a/src/analyzer.js +++ b/src/analyzer.js @@ -748,6 +748,15 @@ function analyzer(data) { exploreBlock(block.inner, singular(block.inner)); } else if (block.type == 'multiple') { block.entryLabels.forEach(function(entryLabel) { exploreBlock(entryLabel.block, singular(block.next)) }); + } else if (block.type === 'emulated' && block.next && block.next.type === 'multiple') { + assert(block.labels.length == 1); + var lastLine = block.labels[0].lines.slice(-1)[0]; + if (lastLine.intertype == 'branch' && lastLine.ident) { // TODO: handle switch, and other non-branch2 things + // 'Steal' the condition + block.next.stolenCondition = lastLine; + dprint('relooping', 'steal condition: ' + block.next.stolenCondition.ident); + lastLine.stolen = true; + } } exploreBlock(block.next, endOfTheWorld); @@ -767,27 +776,27 @@ function analyzer(data) { dprint('relooping', "// optimizing block: " + block.type + ' : ' + block.entries); + recurseBlock(block, optimizeBlock); + if (block.type === 'emulated' && block.willGetTo) { - dprint('relooping', '// removing (trying)'); + dprint('relooping', '// removing (trying): ' + block.willGetTo); replaceLabelLabels(block.labels, set('BJSET|' + block.willGetTo + '|' + block.willGetTo), 'BNOPP'); replaceLabelLabels(block.labels, set('BCONT|' + block.willGetTo + '|' + block.willGetTo), 'BNOPP'); replaceLabelLabels(block.labels, set('BREAK|*|' + block.willGetTo), 'BNOPP'); - } - - if (block.type === 'emulated' && block.next && block.next.type === 'multiple') { - assert(block.labels.length == 1); - var lastLine = block.labels[0].lines.slice(-1)[0]; - if (lastLine.intertype == 'branch' && lastLine.ident) { // TODO: handle switch, and other non-branch2 things - // 'Steal' the condition - block.next.stolenCondition = lastLine; - lastLine.intertype = 'deleted'; - dprint('relooping', 'steal condition: ' + block.next.stolenCondition.ident); + } else if (block.type === 'multiple') { + // Stolen conditions can be optimized further than the same branches in their original position + var stolen = block.stolenCondition; + if (stolen) { + [stolen.labelTrue, stolen.labelFalse].forEach(function(entry) { + entryLabel = block.entryLabels.filter(function(possible) { return possible.ident === getActualLabelId(entry) })[0]; + if (entryLabel) { + replaceLabelLabels([{ lines: [stolen] }], set(entry), 'BNOPP'); + } else { + replaceLabelLabels([{ lines: [stolen] }], set('BJSET|' + block.willGetTo + '|' + block.willGetTo), 'BNOPP'); + } + }); } - } - - recurseBlock(block, optimizeBlock); - if (block.type === 'multiple') { // Check if the one-time loop (that allows breaking out) is actually needed if (replaceLabelLabels(block.labels, set('BREAK|' + block.entries[0] + '|*')).length === 0) { block.loopless = true; diff --git a/src/jsifier.js b/src/jsifier.js index 13d2642d..715b44f7 100644 --- a/src/jsifier.js +++ b/src/jsifier.js @@ -350,9 +350,6 @@ function JSify(data) { } var stolen = block.stolenCondition; if (stolen) { - function getActualLabelId(labelId) { - return labelId.split('|').slice(-1)[0]; - } var intendedTrueLabel = stolen.labelTrue; assert(block.entryLabels.length <= 2); [stolen.labelTrue, stolen.labelFalse].forEach(function(entry) { @@ -537,7 +534,7 @@ function JSify(data) { } makeFuncLineZyme('branch', function(item) { - //print('branch: ' + dump(item)); + if (item.stolen) return ';'; // We will appear where we were stolen to if (!item.ident) { return makeBranch(item.label); } else { diff --git a/src/parseTools.js b/src/parseTools.js index d455ac03..3631fe24 100644 --- a/src/parseTools.js +++ b/src/parseTools.js @@ -466,3 +466,7 @@ function recurseBlock(block, func) { func(block.next); } +function getActualLabelId(labelId) { + return labelId.split('|').slice(-1)[0]; +} + |