aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoralon@honor <none@none>2010-10-26 18:38:02 -0700
committeralon@honor <none@none>2010-10-26 18:38:02 -0700
commit86a4aea383b815ce6e2fb6078c7dc88700262ded (patch)
treeecc43d06d56550f7b44d13fc48cc686c51f17904
parentd6aefb39d6df0abf9104882fa89998e8e8b05dea (diff)
proper blockIds, fixes relooper bug
-rw-r--r--src/analyzer.js20
-rw-r--r--src/jsifier.js11
2 files changed, 19 insertions, 12 deletions
diff --git a/src/analyzer.js b/src/analyzer.js
index 671ba85a..4af7cbc5 100644
--- a/src/analyzer.js
+++ b/src/analyzer.js
@@ -485,6 +485,12 @@ function analyzer(data) {
});
}
+ var idCounter = 0;
+ function makeBlockId(entries) {
+ idCounter++;
+ return entries.join('$') + '$' + idCounter;
+ }
+
// There are X main kinds of blocks:
//
//----------------------------------------------------------------------------------------
@@ -515,8 +521,11 @@ function analyzer(data) {
dprint('relooping', 'prelooping: ' + entries + ',' + labels.length + ' labels');
assert(entries && entries[0]); // need at least 1 entry
+ var blockId = makeBlockId(entries);
+
var emulated = {
type: 'emulated',
+ id: blockId,
labels: labels,
entries: entries.slice(0),
};
@@ -563,6 +572,7 @@ function analyzer(data) {
//}
return {
type: 'emulated',
+ id: blockId,
labels: [entryLabel],
entries: entries,
next: makeBlock(others, keys(entryLabel.outLabels), labelsDict),
@@ -574,6 +584,7 @@ function analyzer(data) {
function makeLoop() {
var ret = {
type: 'reloop',
+ id: blockId,
entries: entries,
labels: labels,
};
@@ -599,7 +610,7 @@ function analyzer(data) {
// We will be in a loop, |continue| gets us back to the entry
entries.forEach(function(entry) {
- replaceLabelLabels(internals, searchable(entries), 'BCONT|' + entries[0]); // entries[0] is the name of the loop, see walkBlock
+ replaceLabelLabels(internals, searchable(entries), 'BCONT|' + blockId);
});
// To get to any of our (not our parents') exit labels, we will break.
@@ -607,7 +618,7 @@ function analyzer(data) {
var enteredExitLabels = {};
if (externals.length > 0) {
entries.forEach(function(entry) {
- mergeInto(enteredExitLabels, set(replaceLabelLabels(internals, currExitLabels, 'BREAK|' + entries[0]))); // see comment on entries[0] above
+ mergeInto(enteredExitLabels, set(replaceLabelLabels(internals, currExitLabels, 'BREAK|' + blockId)));
});
enteredExitLabels = keys(enteredExitLabels).map(cleanLabel);
dprint('relooping', 'enteredExitLabels: ' + dump(enteredExitLabels));
@@ -693,13 +704,14 @@ function analyzer(data) {
dprint('relooping', ' creating sub-block in multiple for ' + actualEntryLabel.ident + ' : ' + getLabelIds(actualEntryLabel.blockChildren) + ' ::: ' + actualEntryLabel.blockChildren.length);
keys(postEntryLabels).forEach(function(post) {
- replaceLabelLabels(actualEntryLabel.blockChildren, set(post), 'BREAK|' + actualEntries[0]);
+ replaceLabelLabels(actualEntryLabel.blockChildren, set(post), 'BREAK|' + blockId);
});
// Create child block
actualEntryLabel.block = makeBlock(actualEntryLabel.blockChildren, [actualEntryLabel.blockChildren[0].ident], labelsDict);
});
return {
type: 'multiple',
+ id: blockId,
entries: actualEntries,
entryLabels: actualEntryLabels,
labels: handlingNow,
@@ -800,7 +812,7 @@ function analyzer(data) {
}
// Check if the one-time loop (that allows breaking out) is actually needed
- if (replaceLabelLabels(block.labels, set('BREAK|' + block.entries[0] + '|*')).length === 0) {
+ if (replaceLabelLabels(block.labels, set('BREAK|' + block.id + '|*')).length === 0) {
block.loopless = true;
}
}
diff --git a/src/jsifier.js b/src/jsifier.js
index 7676cf4b..1a67e1cd 100644
--- a/src/jsifier.js
+++ b/src/jsifier.js
@@ -284,13 +284,9 @@ function JSify(data) {
func.JS += ' var __lastLabel__ = null;\n';
}
- var usedLabels = {}; // We can get a loop and inside it a multiple, which will try to use the same
- // label for their loops (until we remove loops from multiples! TODO). So, just
- // do not use the label twice, that will prevent that
// Walk function blocks and generate JS
function walkBlock(block, indent) {
if (!block) return '';
- block.entry = block.entries[0]; // convention: first entry is the representative
dprint('relooping', 'walking block: ' + block.type + ',' + block.entries + ' : ' + block.labels.length);
function getLabelLines(label, indent) {
if (!label) return '';
@@ -312,7 +308,7 @@ function JSify(data) {
if (block.type == 'emulated') {
if (block.labels.length > 1) {
if (block.entries.length == 1) {
- ret += indent + '__label__ = ' + getLabelId(block.entry) + '; /* ' + block.entry + ' */\n';
+ ret += indent + '__label__ = ' + getLabelId(block.entries[0]) + '; /* ' + block.entries[0] + ' */\n';
} // otherwise, should have been set before!
ret += indent + 'while(1) switch(__label__) {\n';
ret += block.labels.map(function(label) {
@@ -325,15 +321,14 @@ function JSify(data) {
}
ret += '\n';
} else if (block.type == 'reloop') {
- usedLabels[block.entry] = 1;
- ret += indent + block.entry + ': while(1) { // ' + block.entry + '\n';
+ ret += indent + block.id + ': while(1) { // ' + block.entries + '\n';
ret += walkBlock(block.inner, indent + ' ');
ret += indent + '}\n';
} else if (block.type == 'multiple') {
var first = true;
var multipleIdent = '';
if (!block.loopless) {
- ret += indent + ((block.entry in usedLabels) ? '' : (block.entry+':')) + ' do { \n';
+ ret += indent + block.id + ':' + ' do { \n';
multipleIdent = ' ';
}
var stolen = block.stolenCondition;