Search in sources :

Example 6 with AbstractInsnNode

use of org.jetbrains.org.objectweb.asm.tree.AbstractInsnNode in project intellij-community by JetBrains.

the class OriginsAnalysis method resultOrigins.

/**
   *
   * @param frames fixpoint of frames
   * @param instructions method instructions
   * @param graph method control flow graph
   * @return array, array[i] == true means that the result of a method execution may originate at an i-th instruction
   * @throws AnalyzerException
   */
@NotNull
public static boolean[] resultOrigins(Frame<Value>[] frames, InsnList instructions, ControlFlowGraph graph) throws AnalyzerException {
    TIntArrayList[] backTransitions = new TIntArrayList[instructions.size()];
    for (int i = 0; i < backTransitions.length; i++) {
        backTransitions[i] = new TIntArrayList();
    }
    LinkedList<InsnLocation> queue = new LinkedList<>();
    HashSet<InsnLocation> queued = new HashSet<>();
    for (int from = 0; from < instructions.size(); from++) {
        for (int to : graph.transitions[from]) {
            TIntArrayList froms = backTransitions[to];
            froms.add(from);
            int opcode = instructions.get(to).getOpcode();
            if (opcode >= Opcodes.IRETURN && opcode <= Opcodes.ARETURN) {
                InsnLocation sourceLoc = new InsnLocation(false, from, frames[to].getStackSize() - 1);
                if (queued.add(sourceLoc)) {
                    queue.push(sourceLoc);
                }
            }
        }
    }
    boolean[] result = new boolean[instructions.size()];
    while (!queue.isEmpty()) {
        InsnLocation resultLocation = queue.pop();
        int insnIndex = resultLocation.insnIndex;
        AbstractInsnNode insn = instructions.get(insnIndex);
        int opcode = insn.getOpcode();
        Location preLocation = previousLocation(frames[insnIndex], resultLocation, insn);
        if (preLocation == null) {
            if (opcode != Opcodes.INVOKEINTERFACE && opcode != Opcodes.GETFIELD && !(opcode >= Opcodes.IALOAD && opcode <= Opcodes.SALOAD)) {
                result[insnIndex] = true;
            }
        } else {
            TIntArrayList froms = backTransitions[insnIndex];
            for (int i = 0; i < froms.size(); i++) {
                InsnLocation preILoc = new InsnLocation(preLocation.local, froms.getQuick(i), preLocation.slot);
                if (queued.add(preILoc)) {
                    queue.push(preILoc);
                }
            }
        }
    }
    return result;
}
Also used : AbstractInsnNode(org.jetbrains.org.objectweb.asm.tree.AbstractInsnNode) TIntArrayList(gnu.trove.TIntArrayList) LinkedList(java.util.LinkedList) HashSet(java.util.HashSet) NotNull(org.jetbrains.annotations.NotNull)

Example 7 with AbstractInsnNode

use of org.jetbrains.org.objectweb.asm.tree.AbstractInsnNode 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();
        }
    }
}
Also used : InsnList(org.jetbrains.org.objectweb.asm.tree.InsnList) AbstractInsnNode(org.jetbrains.org.objectweb.asm.tree.AbstractInsnNode)

Example 8 with AbstractInsnNode

use of org.jetbrains.org.objectweb.asm.tree.AbstractInsnNode in project kotlin by JetBrains.

the class InlineCodegen method generateAndInsertFinallyBlocks.

private void generateAndInsertFinallyBlocks(@NotNull MethodNode intoNode, @NotNull List<MethodInliner.PointForExternalFinallyBlocks> insertPoints, int offsetForFinallyLocalVar) {
    if (!codegen.hasFinallyBlocks())
        return;
    Map<AbstractInsnNode, MethodInliner.PointForExternalFinallyBlocks> extensionPoints = new HashMap<AbstractInsnNode, MethodInliner.PointForExternalFinallyBlocks>();
    for (MethodInliner.PointForExternalFinallyBlocks insertPoint : insertPoints) {
        extensionPoints.put(insertPoint.beforeIns, insertPoint);
    }
    DefaultProcessor processor = new DefaultProcessor(intoNode, offsetForFinallyLocalVar);
    int curFinallyDepth = 0;
    AbstractInsnNode curInstr = intoNode.instructions.getFirst();
    while (curInstr != null) {
        processor.processInstruction(curInstr, true);
        if (InlineCodegenUtil.isFinallyStart(curInstr)) {
            //TODO depth index calc could be more precise
            curFinallyDepth = getConstant(curInstr.getPrevious());
        }
        MethodInliner.PointForExternalFinallyBlocks extension = extensionPoints.get(curInstr);
        if (extension != null) {
            Label start = new Label();
            MethodNode finallyNode = InlineCodegenUtil.createEmptyMethodNode();
            finallyNode.visitLabel(start);
            ExpressionCodegen finallyCodegen = new ExpressionCodegen(finallyNode, codegen.getFrameMap(), codegen.getReturnType(), codegen.getContext(), codegen.getState(), codegen.getParentCodegen());
            finallyCodegen.addBlockStackElementsForNonLocalReturns(codegen.getBlockStackElements(), curFinallyDepth);
            FrameMap frameMap = finallyCodegen.getFrameMap();
            FrameMap.Mark mark = frameMap.mark();
            int marker = -1;
            Set<LocalVarNodeWrapper> intervals = processor.getLocalVarsMetaInfo().getCurrentIntervals();
            for (LocalVarNodeWrapper interval : intervals) {
                marker = Math.max(interval.getNode().index + 1, marker);
            }
            while (frameMap.getCurrentSize() < Math.max(processor.getNextFreeLocalIndex(), offsetForFinallyLocalVar + marker)) {
                frameMap.enterTemp(Type.INT_TYPE);
            }
            finallyCodegen.generateFinallyBlocksIfNeeded(extension.returnType, extension.finallyIntervalEnd.getLabel());
            //Exception table for external try/catch/finally blocks will be generated in original codegen after exiting this method
            InlineCodegenUtil.insertNodeBefore(finallyNode, intoNode, curInstr);
            SimpleInterval splitBy = new SimpleInterval((LabelNode) start.info, extension.finallyIntervalEnd);
            processor.getTryBlocksMetaInfo().splitCurrentIntervals(splitBy, true);
            //processor.getLocalVarsMetaInfo().splitAndRemoveIntervalsFromCurrents(splitBy);
            mark.dropTo();
        }
        curInstr = curInstr.getNext();
    }
    processor.substituteTryBlockNodes(intoNode);
//processor.substituteLocalVarTable(intoNode);
}
Also used : Label(org.jetbrains.org.objectweb.asm.Label) AbstractInsnNode(org.jetbrains.org.objectweb.asm.tree.AbstractInsnNode) MethodNode(org.jetbrains.org.objectweb.asm.tree.MethodNode)

Example 9 with AbstractInsnNode

use of org.jetbrains.org.objectweb.asm.tree.AbstractInsnNode 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));
            }
        }
    }
}
Also used : MethodNode(org.jetbrains.org.objectweb.asm.tree.MethodNode) List(java.util.List) InsnList(org.jetbrains.org.objectweb.asm.tree.InsnList) InsnList(org.jetbrains.org.objectweb.asm.tree.InsnList) AbstractInsnNode(org.jetbrains.org.objectweb.asm.tree.AbstractInsnNode) Location(com.android.tools.klint.detector.api.Location)

Example 10 with AbstractInsnNode

use of org.jetbrains.org.objectweb.asm.tree.AbstractInsnNode in project kotlin by JetBrains.

the class ControlFlowGraph method toDot.

/**
     * Generates dot output of the graph. This can be used with
     * graphwiz to visualize the graph. For example, if you
     * save the output as graph1.gv you can run
     * <pre>
     * $ dot -Tps graph1.gv -o graph1.ps
     * </pre>
     * to generate a postscript file, which you can then view
     * with "gv graph1.ps".
     *
     * (There are also some online web sites where you can
     * paste in dot graphs and see the visualization right
     * there in the browser.)
     *
     * @return a dot description of this control flow graph,
     *    useful for debugging
     */
@SuppressWarnings("unused")
public String toDot(@Nullable Set<Node> highlight) {
    StringBuilder sb = new StringBuilder();
    sb.append("digraph G {\n");
    AbstractInsnNode instruction = mMethod.instructions.getFirst();
    // Special start node
    sb.append("  start -> ").append(getId(mNodeMap.get(instruction))).append(";\n");
    sb.append("  start [shape=plaintext];\n");
    while (instruction != null) {
        Node node = mNodeMap.get(instruction);
        if (node != null) {
            if (node.successors != null) {
                for (Node to : node.successors) {
                    sb.append("  ").append(getId(node)).append(" -> ").append(getId(to));
                    if (node.instruction instanceof JumpInsnNode) {
                        sb.append(" [label=\"");
                        if (((JumpInsnNode) node.instruction).label == to.instruction) {
                            sb.append("yes");
                        } else {
                            sb.append("no");
                        }
                        sb.append("\"]");
                    }
                    sb.append(";\n");
                }
            }
            if (node.exceptions != null) {
                for (Node to : node.exceptions) {
                    sb.append(getId(node)).append(" -> ").append(getId(to));
                    sb.append(" [label=\"exception\"];\n");
                }
            }
        }
        instruction = instruction.getNext();
    }
    // Labels
    sb.append("\n");
    for (Node node : mNodeMap.values()) {
        instruction = node.instruction;
        sb.append("  ").append(getId(node)).append(" ");
        sb.append("[label=\"").append(dotDescribe(node)).append("\"");
        if (highlight != null && highlight.contains(node)) {
            sb.append(",shape=box,style=filled");
        } else if (instruction instanceof LineNumberNode || instruction instanceof LabelNode || instruction instanceof FrameNode) {
            sb.append(",shape=oval,style=dotted");
        } else {
            sb.append(",shape=box");
        }
        sb.append("];\n");
    }
    sb.append("}");
    return sb.toString();
}
Also used : LabelNode(org.jetbrains.org.objectweb.asm.tree.LabelNode) FrameNode(org.jetbrains.org.objectweb.asm.tree.FrameNode) FieldInsnNode(org.jetbrains.org.objectweb.asm.tree.FieldInsnNode) FrameNode(org.jetbrains.org.objectweb.asm.tree.FrameNode) JumpInsnNode(org.jetbrains.org.objectweb.asm.tree.JumpInsnNode) MethodInsnNode(org.jetbrains.org.objectweb.asm.tree.MethodInsnNode) TryCatchBlockNode(org.jetbrains.org.objectweb.asm.tree.TryCatchBlockNode) AbstractInsnNode(org.jetbrains.org.objectweb.asm.tree.AbstractInsnNode) LineNumberNode(org.jetbrains.org.objectweb.asm.tree.LineNumberNode) TypeInsnNode(org.jetbrains.org.objectweb.asm.tree.TypeInsnNode) ClassNode(org.jetbrains.org.objectweb.asm.tree.ClassNode) IntInsnNode(org.jetbrains.org.objectweb.asm.tree.IntInsnNode) LabelNode(org.jetbrains.org.objectweb.asm.tree.LabelNode) LdcInsnNode(org.jetbrains.org.objectweb.asm.tree.LdcInsnNode) MethodNode(org.jetbrains.org.objectweb.asm.tree.MethodNode) JumpInsnNode(org.jetbrains.org.objectweb.asm.tree.JumpInsnNode) LineNumberNode(org.jetbrains.org.objectweb.asm.tree.LineNumberNode) AbstractInsnNode(org.jetbrains.org.objectweb.asm.tree.AbstractInsnNode)

Aggregations

AbstractInsnNode (org.jetbrains.org.objectweb.asm.tree.AbstractInsnNode)15 FieldInsnNode (org.jetbrains.org.objectweb.asm.tree.FieldInsnNode)7 MethodNode (org.jetbrains.org.objectweb.asm.tree.MethodNode)7 LineNumberNode (org.jetbrains.org.objectweb.asm.tree.LineNumberNode)6 MethodInsnNode (org.jetbrains.org.objectweb.asm.tree.MethodInsnNode)6 ClassNode (org.jetbrains.org.objectweb.asm.tree.ClassNode)5 FrameNode (org.jetbrains.org.objectweb.asm.tree.FrameNode)5 IntInsnNode (org.jetbrains.org.objectweb.asm.tree.IntInsnNode)5 LabelNode (org.jetbrains.org.objectweb.asm.tree.LabelNode)5 LdcInsnNode (org.jetbrains.org.objectweb.asm.tree.LdcInsnNode)5 TryCatchBlockNode (org.jetbrains.org.objectweb.asm.tree.TryCatchBlockNode)5 TypeInsnNode (org.jetbrains.org.objectweb.asm.tree.TypeInsnNode)5 InsnList (org.jetbrains.org.objectweb.asm.tree.InsnList)4 JumpInsnNode (org.jetbrains.org.objectweb.asm.tree.JumpInsnNode)4 NonNull (com.android.annotations.NonNull)3 List (java.util.List)2 Detector (com.android.tools.klint.detector.api.Detector)1 ClassScanner (com.android.tools.klint.detector.api.Detector.ClassScanner)1 Location (com.android.tools.klint.detector.api.Location)1 Edge (com.intellij.codeInspection.bytecodeAnalysis.asm.ControlFlowGraph.Edge)1