Skip to content

Instantly share code, notes, and snippets.

@t81lal
Last active August 29, 2015 14:26
Show Gist options
  • Save t81lal/51a8f96675b4258cfecb to your computer and use it in GitHub Desktop.
Save t81lal/51a8f96675b4258cfecb to your computer and use it in GitHub Desktop.
sort
public void visit(FlowBlock cur, Frame frame, Collection<FlowBlock> consider) {
int index = frame.indexOf(cur);
int dfs = frame.dfsnum;
frame.low[index] = dfs;
frame.index[index] = dfs;
frame.dfsnum++;
frame.stack.push(cur);
for(FlowBlock s : cur.successors()) {
if(consider.contains(s)) {
int sIndex = frame.indexOf(s);
if(frame.index[sIndex] == Frame.TODO) {
visit(s, frame, consider);
frame.low[index] = Math.min(frame.low[index], frame.low[sIndex]);
} else if(frame.index[sIndex] == Frame.DONE) {
/* Do nothing */
} else {
frame.low[index] = Math.min(frame.low[index], frame.index[sIndex]);
}
}
}
if(frame.low[index] == frame.index[index]) {
SSC ssc = new SSC();
FlowBlock w;
do {
w = frame.stack.pop();
ssc.blocks.add(w);
int pIndex = frame.indexOf(w);
frame.index[pIndex] = Frame.DONE;
} while(w != cur);
if(ssc.blocks.size() == 1) {
frame.newOrder.add(0, cur);
} else {
frame.newOrder.addAll(0, deobfuscate(ssc.blocks.get(0), ssc.blocks));
}
}
}
public List<FlowBlock> deobfuscate(FlowBlock v, Collection<FlowBlock> consider) {
Frame frame = new Frame(new ArrayList<FlowBlock>(), blocks, new LinkedList<FlowBlock>(), blocks.size(), 0);
for(FlowBlock b : consider) {
int index = frame.indexOf(b);
frame.index[index] = Frame.TODO;
}
int vIndex = frame.indexOf(v);
frame.index[vIndex] = Frame.DONE;
for(FlowBlock s : v.successors()) {
if(consider.contains(s)) {
int child = frame.indexOf(s);
if(frame.index[child] == Frame.TODO) {
visit(s, frame, consider);
}
}
}
frame.newOrder.add(0, v);
return frame.newOrder;
}
static class Frame {
static final int TODO = Integer.MIN_VALUE + 1;
static final int DONE = Integer.MIN_VALUE + 2;
final List<FlowBlock> newOrder;
final List<FlowBlock> blocks;
final Deque<FlowBlock> stack;
final int[] index;
final int[] low;
int dfsnum;
Frame(List<FlowBlock> newOrder, List<FlowBlock> blocks, Deque<FlowBlock> stack, int size, int dfsnum) {
this.newOrder = newOrder;
this.blocks = blocks;
this.stack = stack;
this.dfsnum = dfsnum;
index = new int[size];
low = new int[size];
}
int indexOf(FlowBlock b) {
return blocks.indexOf(b);
}
}
static class SSC {
public final List<FlowBlock> blocks = new ArrayList<FlowBlock>();
@Override
public String toString() {
StringBuilder sb = new StringBuilder("SSC: { ");
Iterator<FlowBlock> it = blocks.iterator();
while (it.hasNext()) {
FlowBlock b = it.next();
sb.append(b.id());
if (it.hasNext()) {
sb.append(',');
}
sb.append(' ');
}
sb.append('}');
return sb.toString();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment