use of org.jetbrains.org.objectweb.asm.tree.InsnList in project kotlin by JetBrains.
the class ControlFlowGraph method create.
/**
* Creates a new {@link ControlFlowGraph} and populates it with the flow
* control for the given method. If the optional {@code initial} parameter is
* provided with an existing graph, then the graph is simply populated, not
* created. This allows subclassing of the graph instance, if necessary.
*
* @param initial usually null, but can point to an existing instance of a
* {@link ControlFlowGraph} in which that graph is reused (but
* populated with new edges)
* @param classNode the class containing the method to be analyzed
* @param method the method to be analyzed
* @return a {@link ControlFlowGraph} with nodes for the control flow in the
* given method
* @throws AnalyzerException if the underlying bytecode library is unable to
* analyze the method bytecode
*/
@NonNull
public static ControlFlowGraph create(@Nullable ControlFlowGraph initial, @NonNull ClassNode classNode, @NonNull MethodNode method) throws AnalyzerException {
final ControlFlowGraph graph = initial != null ? initial : new ControlFlowGraph();
final InsnList instructions = method.instructions;
graph.mNodeMap = Maps.newHashMapWithExpectedSize(instructions.size());
graph.mMethod = method;
// Create a flow control graph using ASM5's analyzer. According to the ASM 4 guide
// (download.forge.objectweb.org/asm/asm4-guide.pdf) there are faster ways to construct
// it, but those require a lot more code.
Analyzer analyzer = new Analyzer(new BasicInterpreter()) {
@Override
protected void newControlFlowEdge(int insn, int successor) {
// Update the information as of whether the this object has been
// initialized at the given instruction.
AbstractInsnNode from = instructions.get(insn);
AbstractInsnNode to = instructions.get(successor);
graph.add(from, to);
}
@Override
protected boolean newControlFlowExceptionEdge(int insn, TryCatchBlockNode tcb) {
AbstractInsnNode from = instructions.get(insn);
graph.exception(from, tcb);
return super.newControlFlowExceptionEdge(insn, tcb);
}
@Override
protected boolean newControlFlowExceptionEdge(int insn, int successor) {
AbstractInsnNode from = instructions.get(insn);
AbstractInsnNode to = instructions.get(successor);
graph.exception(from, to);
return super.newControlFlowExceptionEdge(insn, successor);
}
};
analyzer.analyze(classNode.name, method);
return graph;
}
use of org.jetbrains.org.objectweb.asm.tree.InsnList in project kotlin by JetBrains.
the class InlineCodegen method removeStaticInitializationTrigger.
private static void removeStaticInitializationTrigger(@NotNull MethodNode methodNode) {
InsnList insnList = methodNode.instructions;
AbstractInsnNode insn = insnList.getFirst();
while (insn != null) {
if (MultifileClassPartCodegen.isStaticInitTrigger(insn)) {
AbstractInsnNode clinitTriggerCall = insn;
insn = insn.getNext();
insnList.remove(clinitTriggerCall);
} else {
insn = insn.getNext();
}
}
}
use of org.jetbrains.org.objectweb.asm.tree.InsnList in project kotlin by JetBrains.
the class TrustAllX509TrustManagerDetector method checkClass.
// ---- Implements ClassScanner ----
// Only used for libraries where we have to analyze bytecode
@Override
@SuppressWarnings("rawtypes")
public void checkClass(@NonNull final ClassContext context, @NonNull ClassNode classNode) {
if (!context.isFromClassLibrary()) {
// Non-library code checked at the AST level
return;
}
if (!classNode.interfaces.contains("javax/net/ssl/X509TrustManager")) {
return;
}
List methodList = classNode.methods;
for (Object m : methodList) {
MethodNode method = (MethodNode) m;
if ("checkServerTrusted".equals(method.name) || "checkClientTrusted".equals(method.name)) {
InsnList nodes = method.instructions;
// Stays true if method doesn't perform any "real"
boolean emptyMethod = true;
// operations
for (int i = 0, n = nodes.size(); i < n; i++) {
// Future work: Improve this check to be less sensitive to irrelevant
// instructions/statements/invocations (e.g. System.out.println) by
// looking for calls that could lead to a CertificateException being
// thrown, e.g. throw statement within the method itself or invocation
// of another method that may throw a CertificateException, and only
// reporting an issue if none of these calls are found. ControlFlowGraph
// may be useful here.
AbstractInsnNode instruction = nodes.get(i);
int type = instruction.getType();
if (type != AbstractInsnNode.LABEL && type != AbstractInsnNode.LINE && !(type == AbstractInsnNode.INSN && instruction.getOpcode() == Opcodes.RETURN)) {
emptyMethod = false;
break;
}
}
if (emptyMethod) {
Location location = context.getLocation(method, classNode);
context.report(ISSUE, location, getErrorMessage(method.name));
}
}
}
}
use of org.jetbrains.org.objectweb.asm.tree.InsnList 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