use of org.mapleir.flowgraph.edges.DefaultSwitchEdge in project maple-ir by LLVM-but-worse.
the class GenerationPass method process.
protected void process(LabelNode label) {
/* it may not be properly initialised yet, however. */
BasicBlock block = builder.graph.getBlock(label);
/* if it is, we don't need to process it. */
if (block != null && finished.get(block.getNumericId())) {
return;
} else if (block == null) {
block = makeBlock(label);
} else {
// i.e. not finished.
}
preprocess(block);
/* populate instructions. */
int codeIndex = insns.indexOf(label);
finished.set(block.getNumericId());
while (codeIndex < insns.size() - 1) {
AbstractInsnNode ain = insns.get(++codeIndex);
int type = ain.type();
if (ain.opcode() != -1) {
process(block, ain);
}
if (type == LABEL) {
// split into new block
BasicBlock immediate = resolveTarget((LabelNode) ain);
builder.graph.addEdge(block, new ImmediateEdge<>(block, immediate));
break;
} else if (type == JUMP_INSN) {
JumpInsnNode jin = (JumpInsnNode) ain;
BasicBlock target = resolveTarget(jin.label);
if (jin.opcode() == JSR) {
throw new UnsupportedOperationException("jsr " + builder.method);
} else if (jin.opcode() == GOTO) {
builder.graph.addEdge(block, new UnconditionalJumpEdge<>(block, target));
} else {
builder.graph.addEdge(block, new ConditionalJumpEdge<>(block, target, jin.opcode()));
int nextIndex = codeIndex + 1;
AbstractInsnNode nextInsn = insns.get(nextIndex);
if (!(nextInsn instanceof LabelNode)) {
LabelNode newLabel = new LabelNode();
insns.insert(ain, newLabel);
nextInsn = newLabel;
}
// create immediate successor reference if it's not already done
BasicBlock immediate = resolveTarget((LabelNode) nextInsn);
builder.graph.addEdge(block, new ImmediateEdge<>(block, immediate));
}
break;
} else if (type == LOOKUPSWITCH_INSN) {
LookupSwitchInsnNode lsin = (LookupSwitchInsnNode) ain;
for (int i = 0; i < lsin.keys.size(); i++) {
BasicBlock target = resolveTarget(lsin.labels.get(i));
builder.graph.addEdge(block, new SwitchEdge<>(block, target, lsin, lsin.keys.get(i)));
}
BasicBlock dflt = resolveTarget(lsin.dflt);
builder.graph.addEdge(block, new DefaultSwitchEdge<>(block, dflt, lsin));
break;
} else if (type == TABLESWITCH_INSN) {
TableSwitchInsnNode tsin = (TableSwitchInsnNode) ain;
for (int i = tsin.min; i <= tsin.max; i++) {
BasicBlock target = resolveTarget(tsin.labels.get(i - tsin.min));
builder.graph.addEdge(block, new SwitchEdge<>(block, target, tsin, i));
}
BasicBlock dflt = resolveTarget(tsin.dflt);
builder.graph.addEdge(block, new DefaultSwitchEdge<>(block, dflt, tsin));
break;
} else if (isExitOpcode(ain.opcode())) {
break;
}
}
// TODO: check if it should have an immediate.
BasicBlock im = block.getImmediate();
if (im != null) /* && !queue.contains(im)*/
{
// System.out.println("Updating " + block.getId() + " -> " + im.getId());
// System.out.println(" Pre: " + currentStack);
update_target_stack(block, im, currentStack);
// System.out.println(" Pos: " + currentStack);
}
}
Aggregations