aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/analyzer.js39
-rw-r--r--src/jsifier.js5
-rw-r--r--src/parseTools.js4
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];
+}
+