diff options
author | alon@honor <none@none> | 2010-10-26 18:38:02 -0700 |
---|---|---|
committer | alon@honor <none@none> | 2010-10-26 18:38:02 -0700 |
commit | 86a4aea383b815ce6e2fb6078c7dc88700262ded (patch) | |
tree | ecc43d06d56550f7b44d13fc48cc686c51f17904 | |
parent | d6aefb39d6df0abf9104882fa89998e8e8b05dea (diff) |
proper blockIds, fixes relooper bug
-rw-r--r-- | src/analyzer.js | 20 | ||||
-rw-r--r-- | src/jsifier.js | 11 |
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; |