Permalink
Browse files

cfg: determine correct hasDeclaration

  • Loading branch information...
1 parent da58ee7 commit 8b5a93477500528afd439fd2b4718bd8d29521bd @indutny committed Sep 27, 2012
Showing with 23 additions and 5 deletions.
  1. +23 −5 lib/spoon/cfg.js
View
@@ -176,11 +176,16 @@ Cfg.prototype.asyncify = function asyncify(asts, level) {
// Replace async instruction in all blocks that either have
// "enable spoon" declaration or are children of blocks with declaration.
var hasDeclaration = {},
+ visited = {},
+ queue = this.roots.slice(),
rootBlocks = this.blocks.length;
- for (var i = 0; i < this.blocks.length; i++) {
- var block = this.blocks[i];
- if (i < rootBlocks && !hasDeclaration[block.id]) {
+ while (queue.length > 0) {
+ var block = queue.shift();
+ if (visited[block.id]) continue;
+ visited[block.id] = true;
+
+ if (!hasDeclaration[block.id]) {
// Find declaration first
var found = block.instructions.some(function(instr) {
if (instr.type !== 'literal' ||
@@ -195,14 +200,26 @@ Cfg.prototype.asyncify = function asyncify(asts, level) {
// Skip block if it hasn't one
if (!found) continue;
- } else {
- hasDeclaration[block.id] = block;
}
block.successors.forEach(function(succ) {
+ // Visit some blocks twice if needed
+ if (!hasDeclaration[succ.id]) visited[succ.id] = false;
+
// All children should be processed too
hasDeclaration[succ.id] = succ;
+ queue.push(succ);
});
+ }
+
+ for (var i = 0; i < this.blocks.length; i++) {
+ var block = this.blocks[i];
+ if (i >= rootBlocks) {
+ // Extra blocks should be counted as async blocks
+ hasDeclaration[block.id] = block;
+ } else if (!hasDeclaration[block.id]) {
+ continue;
+ }
block.instructions.forEach(function(instr) {
if (!match(instr)) return;
@@ -514,6 +531,7 @@ Cfg.prototype.deriveCFrontier = function deriveCFrontier(leafs) {
Object.keys(cr).forEach(function(id) {
if (cr[id].cparent === node) return;
+ if (cr[id].id === node.id) return;
r[id] = cr[id];
});
});

0 comments on commit 8b5a934

Please sign in to comment.