use of org.jetbrains.org.objectweb.asm.tree.AbstractInsnNode in project kotlin by JetBrains.
the class ControlFlowGraph method toString.
/**
* Creates a human readable version of the graph
*
* @param start the starting instruction, or null if not known or to use the
* first instruction
* @return a string version of the graph
*/
@NonNull
public String toString(@Nullable Node start) {
StringBuilder sb = new StringBuilder(400);
AbstractInsnNode curr;
if (start != null) {
curr = start.instruction;
} else {
if (mNodeMap.isEmpty()) {
return "<empty>";
} else {
curr = mNodeMap.keySet().iterator().next();
while (curr.getPrevious() != null) {
curr = curr.getPrevious();
}
}
}
while (curr != null) {
Node node = mNodeMap.get(curr);
if (node != null) {
sb.append(node.toString(true));
}
curr = curr.getNext();
}
return sb.toString();
}
use of org.jetbrains.org.objectweb.asm.tree.AbstractInsnNode in project kotlin by JetBrains.
the class ControlFlowGraph method exception.
/** Adds an exception try block node to this graph */
protected void exception(@NonNull AbstractInsnNode from, @NonNull TryCatchBlockNode tcb) {
// Add tcb's to all instructions in the range
LabelNode start = tcb.start;
// exclusive
LabelNode end = tcb.end;
// Add exception edges for all method calls in the range
AbstractInsnNode curr = start;
Node handlerNode = getNode(tcb.handler);
while (curr != end && curr != null) {
// A method can throw can exception, or a throw instruction directly
if (curr.getType() == AbstractInsnNode.METHOD_INSN || (curr.getType() == AbstractInsnNode.INSN && curr.getOpcode() == Opcodes.ATHROW)) {
// Method call; add exception edge to handler
if (tcb.type == null) {
// finally block: not an exception path
getNode(curr).addSuccessor(handlerNode);
}
getNode(curr).addExceptionPath(handlerNode);
}
curr = curr.getNext();
}
}
use of org.jetbrains.org.objectweb.asm.tree.AbstractInsnNode in project kotlin by JetBrains.
the class ControlFlowGraph method getNode.
/**
* Looks up (and if necessary) creates a graph node for the given instruction
*
* @param instruction the instruction
* @return the control flow graph node corresponding to the given
* instruction
*/
@NonNull
public Node getNode(@NonNull AbstractInsnNode instruction) {
Node node = mNodeMap.get(instruction);
if (node == null) {
node = new Node(instruction);
mNodeMap.put(instruction, node);
}
return node;
}
use of org.jetbrains.org.objectweb.asm.tree.AbstractInsnNode in project kotlin by JetBrains.
the class ClassContext method findLineNumber.
/**
* Finds the line number closest to the given node
*
* @param node the instruction node to get a line number for
* @return the closest line number, or -1 if not known
*/
public static int findLineNumber(@NonNull AbstractInsnNode node) {
AbstractInsnNode curr = node;
// First search backwards
while (curr != null) {
if (curr.getType() == AbstractInsnNode.LINE) {
return ((LineNumberNode) curr).line;
}
curr = curr.getPrevious();
}
// Then search forwards
curr = node;
while (curr != null) {
if (curr.getType() == AbstractInsnNode.LINE) {
return ((LineNumberNode) curr).line;
}
curr = curr.getNext();
}
return -1;
}
use of org.jetbrains.org.objectweb.asm.tree.AbstractInsnNode in project kotlin by JetBrains.
the class AsmVisitor method runClassDetectors.
// ASM API uses raw types
@SuppressWarnings("rawtypes")
void runClassDetectors(ClassContext context) {
ClassNode classNode = context.getClassNode();
for (Detector detector : mAllDetectors) {
detector.beforeCheckFile(context);
}
for (Detector detector : mFullClassChecks) {
Detector.ClassScanner scanner = (Detector.ClassScanner) detector;
scanner.checkClass(context, classNode);
detector.afterCheckFile(context);
}
if (!mMethodNameToChecks.isEmpty() || !mMethodOwnerToChecks.isEmpty() || mNodeTypeDetectors != null && mNodeTypeDetectors.length > 0) {
List methodList = classNode.methods;
for (Object m : methodList) {
MethodNode method = (MethodNode) m;
InsnList nodes = method.instructions;
for (int i = 0, n = nodes.size(); i < n; i++) {
AbstractInsnNode instruction = nodes.get(i);
int type = instruction.getType();
if (type == AbstractInsnNode.METHOD_INSN) {
MethodInsnNode call = (MethodInsnNode) instruction;
String owner = call.owner;
List<ClassScanner> scanners = mMethodOwnerToChecks.get(owner);
if (scanners != null) {
for (ClassScanner scanner : scanners) {
scanner.checkCall(context, classNode, method, call);
}
}
String name = call.name;
scanners = mMethodNameToChecks.get(name);
if (scanners != null) {
for (ClassScanner scanner : scanners) {
scanner.checkCall(context, classNode, method, call);
}
}
}
if (mNodeTypeDetectors != null && type < mNodeTypeDetectors.length) {
List<ClassScanner> scanners = mNodeTypeDetectors[type];
if (scanners != null) {
for (ClassScanner scanner : scanners) {
scanner.checkInstruction(context, classNode, method, instruction);
}
}
}
}
}
}
for (Detector detector : mAllDetectors) {
detector.afterCheckFile(context);
}
}
Aggregations