Example usage for org.objectweb.asm.tree AbstractInsnNode METHOD_INSN

List of usage examples for org.objectweb.asm.tree AbstractInsnNode METHOD_INSN

Introduction

In this page you can find the example usage for org.objectweb.asm.tree AbstractInsnNode METHOD_INSN.

Prototype

int METHOD_INSN

To view the source code for org.objectweb.asm.tree AbstractInsnNode METHOD_INSN.

Click Source Link

Document

The type of MethodInsnNode instructions.

Usage

From source file:com.android.tools.lint.checks.WakelockDetector.java

License:Apache License

private void checkFlow(@NonNull ClassContext context, @NonNull ClassNode classNode, @NonNull MethodNode method,
        @NonNull MethodInsnNode acquire) {
    // Track allocations such that we know whether the type of the call
    // is on a SecureRandom rather than a Random
    final InsnList instructions = method.instructions;
    MethodInsnNode release = null;//from   w ww  .j a v  a  2  s . com

    // Find release call
    for (int i = 0, n = instructions.size(); i < n; i++) {
        AbstractInsnNode instruction = instructions.get(i);
        int type = instruction.getType();
        if (type == AbstractInsnNode.METHOD_INSN) {
            MethodInsnNode call = (MethodInsnNode) instruction;
            if (call.name.equals(RELEASE_METHOD) && call.owner.equals(WAKELOCK_OWNER)) {
                release = call;
                break;
            }
        }
    }

    if (release == null) {
        // Didn't find both acquire and release in this method; no point in doing
        // local flow analysis
        return;
    }

    try {
        MyGraph graph = new MyGraph();
        ControlFlowGraph.create(graph, classNode, method);

        if (DEBUG) {
            // Requires util package
            //ClassNode clazz = classNode;
            //clazz.accept(new TraceClassVisitor(new PrintWriter(System.out)));
            System.out.println(graph.toString(graph.getNode(acquire)));
        }

        int status = dfs(graph.getNode(acquire));
        if ((status & SEEN_RETURN) != 0) {
            String message;
            if ((status & SEEN_EXCEPTION) != 0) {
                message = "The release() call is not always reached (via exceptional flow)";
            } else {
                message = "The release() call is not always reached";
            }

            context.report(ISSUE, method, acquire, context.getLocation(release), message, null);
        }
    } catch (AnalyzerException e) {
        context.log(e, null);
    }
}

From source file:com.android.tools.lint.checks.WakelockDetector.java

License:Apache License

/** Search from the given node towards the target; return false if we reach
 * an exit point such as a return or a call on the way there that is not within
 * a try/catch clause./*from  w  ww .  j a va2s.  c  o  m*/
 *
 * @param node the current node
 * @return true if the target was reached
 *    XXX RETURN VALUES ARE WRONG AS OF RIGHT NOW
 */
protected int dfs(ControlFlowGraph.Node node) {
    AbstractInsnNode instruction = node.instruction;
    if (instruction.getType() == AbstractInsnNode.JUMP_INSN) {
        int opcode = instruction.getOpcode();
        if (opcode == Opcodes.RETURN || opcode == Opcodes.ARETURN || opcode == Opcodes.LRETURN
                || opcode == Opcodes.IRETURN || opcode == Opcodes.DRETURN || opcode == Opcodes.FRETURN
                || opcode == Opcodes.ATHROW) {
            if (DEBUG) {
                System.out.println("Found exit via explicit return: " //$NON-NLS-1$
                        + node.toString(false));
            }
            return SEEN_RETURN;
        }
    }

    if (!DEBUG) {
        // There are no cycles, so no *NEED* for this, though it does avoid
        // researching shared labels. However, it makes debugging harder (no re-entry)
        // so this is only done when debugging is off
        if (node.visit != 0) {
            return 0;
        }
        node.visit = 1;
    }

    // Look for the target. This is any method call node which is a release on the
    // lock (later also check it's the same instance, though that's harder).
    // This is because finally blocks tend to be inlined so from a single try/catch/finally
    // with a release() in the finally, the bytecode can contain multiple repeated
    // (inlined) release() calls.
    if (instruction.getType() == AbstractInsnNode.METHOD_INSN) {
        MethodInsnNode method = (MethodInsnNode) instruction;
        if (method.name.equals(RELEASE_METHOD) && method.owner.equals(WAKELOCK_OWNER)) {
            return SEEN_TARGET;
        } else if (method.name.equals(ACQUIRE_METHOD) && method.owner.equals(WAKELOCK_OWNER)) {
            // OK
        } else if (method.name.equals(IS_HELD_METHOD) && method.owner.equals(WAKELOCK_OWNER)) {
            // OK
        } else {
            // Some non acquire/release method call: if this is not associated with a
            // try-catch block, it would mean the exception would exit the method,
            // which would be an error
            if (node.exceptions == null || node.exceptions.isEmpty()) {
                // Look up the corresponding frame, if any
                AbstractInsnNode curr = method.getPrevious();
                boolean foundFrame = false;
                while (curr != null) {
                    if (curr.getType() == AbstractInsnNode.FRAME) {
                        foundFrame = true;
                        break;
                    }
                    curr = curr.getPrevious();
                }

                if (!foundFrame) {
                    if (DEBUG) {
                        System.out.println("Found exit via unguarded method call: " //$NON-NLS-1$
                                + node.toString(false));
                    }
                    return SEEN_RETURN;
                }
            }
        }
    }

    // if (node.instruction is a call, and the call is not caught by
    // a try/catch block (provided the release is not inside the try/catch block)
    // then return false
    int status = 0;

    boolean implicitReturn = true;
    List<Node> successors = node.successors;
    List<Node> exceptions = node.exceptions;
    if (exceptions != null) {
        if (!exceptions.isEmpty()) {
            implicitReturn = false;
        }
        for (Node successor : exceptions) {
            status = dfs(successor) | status;
            if ((status & SEEN_RETURN) != 0) {
                if (DEBUG) {
                    System.out.println("Found exit via exception: " //$NON-NLS-1$
                            + node.toString(false));
                }
                return status;
            }
        }

        if (status != 0) {
            status |= SEEN_EXCEPTION;
        }
    }

    if (successors != null) {
        if (!successors.isEmpty()) {
            implicitReturn = false;
            if (successors.size() > 1) {
                status |= SEEN_BRANCH;
            }
        }
        for (Node successor : successors) {
            status = dfs(successor) | status;
            if ((status & SEEN_RETURN) != 0) {
                if (DEBUG) {
                    System.out.println("Found exit via branches: " //$NON-NLS-1$
                            + node.toString(false));
                }
                return status;
            }
        }
    }

    if (implicitReturn) {
        status |= SEEN_RETURN;
        if (DEBUG) {
            System.out.println("Found exit: via implicit return: " //$NON-NLS-1$
                    + node.toString(false));
        }
    }

    return status;
}

From source file:com.github.fge.grappa.transform.process.ImplicitActionsConverter.java

License:Apache License

private static boolean isObjectArgumentToRuleCreatingMethodCall(InstructionGraphNode node,
        InstructionGraphNode dependent) {
    // is the single dependent a method call ?
    AbstractInsnNode insn = dependent.getInstruction();
    if (insn.getType() != AbstractInsnNode.METHOD_INSN)
        return false;

    // Does this method call return a Rule ?
    MethodInsnNode methodNode = (MethodInsnNode) insn;
    if (!Type.getType(Rule.class).equals(Type.getReturnType(methodNode.desc)))
        return false;

    // Does the result of the Boolean.valueOf(boolean) call correspond to
    // an Object parameter ?
    Type[] argTypes = Type.getArgumentTypes(methodNode.desc);
    int argIndex = getArgumentIndex(dependent, node);

    Preconditions.checkState(argIndex < argTypes.length);

    String typeName = argTypes[argIndex].getInternalName();
    return CodegenUtils.p(Object.class).equals(typeName);
}

From source file:com.github.jasmo.obfuscate.InlineAccessors.java

License:Open Source License

private void replace(int opcode, ClassNode owner, FieldNode field, MethodNode m) {
    if (Modifier.isStatic(field.access))
        opcode -= 2;/*  www.  ja v  a  2  s  . co m*/
    for (ClassNode cn : classMap.values()) {
        for (MethodNode mn : cn.methods) {
            AbstractInsnNode[] instructions = mn.instructions.toArray();
            for (AbstractInsnNode node : instructions) {
                if (node.getType() != AbstractInsnNode.METHOD_INSN) {
                    continue;
                }
                MethodInsnNode min = (MethodInsnNode) node;
                List<String> owners = getChildNames(owner);
                if (owners.contains(min.owner) && min.name.equals(m.name) && min.desc.equals(m.desc)) {
                    FieldInsnNode fin = new FieldInsnNode(opcode, min.owner, field.name, field.desc);
                    log.debug(" replace {}.{}.{}, insn: {}", cn.name, mn.name, mn.desc,
                            QueryUtil.query(fin, "index"));
                    mn.instructions.set(min, fin);
                }
            }
        }
    }
}

From source file:com.lodgon.parboiled.transform.ImplicitActionsConverter.java

License:Apache License

private boolean isObjectArgumentToRuleCreatingMethodCall(InstructionGraphNode node,
        InstructionGraphNode dependent) {
    // is the single dependent a method call ?
    AbstractInsnNode insn = dependent.getInstruction();
    if (insn.getType() != AbstractInsnNode.METHOD_INSN)
        return false;

    // Does this method call return a Rule ?
    MethodInsnNode mi = (MethodInsnNode) insn;
    if (!Types.RULE.equals(Type.getReturnType(mi.desc)))
        return false;

    // Doesthe result of the Boolean.valueOf(boolean) call correspond to an Object parameter ?
    Type[] argTypes = Type.getArgumentTypes(mi.desc);
    int argIndex = getArgumentIndex(dependent, node);
    checkState(argIndex < argTypes.length);
    return "java/lang/Object".equals(argTypes[argIndex].getInternalName());
}

From source file:cz.vutbr.fit.xhriba01.bc.lib.AbstractNodeVisitor.java

License:Open Source License

/**
 * This method detects what type of instruction the NodeInstruction is
 * representing and calls appropriate before/visit/after methods.
 * Subclasses could rather override methods specific for particular
 * instruction type./*  w w w .j ava2s  .co  m*/
 * 
 * @param nodeInstruction the instruction node
 */
public void visitNodeInstruction(NodeInstruction nodeInstruction) {
    AbstractInsnNode asmInsn = nodeInstruction.getAsmInsnNode();
    switch (asmInsn.getType()) {
    case AbstractInsnNode.LINE:
        visitLineNumberNode((LineNumberNode) asmInsn, nodeInstruction);
        break;
    case AbstractInsnNode.LABEL:
        visitLabelNode((LabelNode) asmInsn, nodeInstruction);
        break;
    case AbstractInsnNode.FIELD_INSN:
        visitFieldInsn((FieldInsnNode) asmInsn, nodeInstruction);
        break;
    case AbstractInsnNode.IINC_INSN:
        visitIincInsn((IincInsnNode) asmInsn, nodeInstruction);
        break;
    case AbstractInsnNode.INSN:
        visitInsn((InsnNode) asmInsn, nodeInstruction);
        break;
    case AbstractInsnNode.INT_INSN:
        visitIntInsn((IntInsnNode) asmInsn, nodeInstruction);
        break;
    case AbstractInsnNode.INVOKE_DYNAMIC_INSN:
        visitInvokeDynamicInsn((InvokeDynamicInsnNode) asmInsn, nodeInstruction);
        break;
    case AbstractInsnNode.JUMP_INSN:
        visitJumpInsn((JumpInsnNode) asmInsn, nodeInstruction);
        break;
    case AbstractInsnNode.LDC_INSN:
        visitLdcInsn((LdcInsnNode) asmInsn, nodeInstruction);
        break;
    case AbstractInsnNode.LOOKUPSWITCH_INSN:
        visitLookupSwitchInsn((LookupSwitchInsnNode) asmInsn, nodeInstruction);
        break;
    case AbstractInsnNode.METHOD_INSN:
        visitMethodInsn((MethodInsnNode) asmInsn, nodeInstruction);
        break;
    case AbstractInsnNode.MULTIANEWARRAY_INSN:
        visitMultiANewArrayInsn((MultiANewArrayInsnNode) asmInsn, nodeInstruction);
        break;
    case AbstractInsnNode.TABLESWITCH_INSN:
        visitTableSwitchInsn((TableSwitchInsnNode) asmInsn, nodeInstruction);
        break;
    case AbstractInsnNode.TYPE_INSN:
        visitTypeInsn((TypeInsnNode) asmInsn, nodeInstruction);
        break;
    case AbstractInsnNode.VAR_INSN:
        visitVarInsn((VarInsnNode) asmInsn, nodeInstruction);
        break;
    default:
        // shouldn't happen
        break;
    }
}

From source file:cz.vutbr.fit.xhriba01.bc.lib.AbstractNodeVisitor.java

License:Open Source License

public void afterVisitNodeInstruction(NodeInstruction nodeInstruction) {

    AbstractInsnNode asmInsn = nodeInstruction.getAsmInsnNode();

    switch (asmInsn.getType()) {
    case AbstractInsnNode.LINE:
        afterVisitLineNumberNode((LineNumberNode) asmInsn, nodeInstruction);
        break;/*  www .ja  va  2 s  . co m*/
    case AbstractInsnNode.LABEL:
        afterVisitLabelNode((LabelNode) asmInsn, nodeInstruction);
        break;
    case AbstractInsnNode.FIELD_INSN:
        afterVisitFieldInsn((FieldInsnNode) asmInsn, nodeInstruction);
        break;
    case AbstractInsnNode.IINC_INSN:
        afterVisitIincInsn((IincInsnNode) asmInsn, nodeInstruction);
        break;
    case AbstractInsnNode.INSN:
        afterVisitInsn((InsnNode) asmInsn, nodeInstruction);
        break;
    case AbstractInsnNode.INT_INSN:
        afterVisitIntInsn((IntInsnNode) asmInsn, nodeInstruction);
        break;
    case AbstractInsnNode.INVOKE_DYNAMIC_INSN:
        afterVisitInvokeDynamicInsn((InvokeDynamicInsnNode) asmInsn, nodeInstruction);
        break;
    case AbstractInsnNode.JUMP_INSN:
        afterVisitJumpInsn((JumpInsnNode) asmInsn, nodeInstruction);
        break;
    case AbstractInsnNode.LDC_INSN:
        afterVisitLdcInsn((LdcInsnNode) asmInsn, nodeInstruction);
        break;
    case AbstractInsnNode.LOOKUPSWITCH_INSN:
        afterVisitLookupSwitchInsn((LookupSwitchInsnNode) asmInsn, nodeInstruction);
        break;
    case AbstractInsnNode.METHOD_INSN:
        afterVisitMethodInsn((MethodInsnNode) asmInsn, nodeInstruction);
        break;
    case AbstractInsnNode.MULTIANEWARRAY_INSN:
        afterVisitMultiANewArrayInsn((MultiANewArrayInsnNode) asmInsn, nodeInstruction);
        break;
    case AbstractInsnNode.TABLESWITCH_INSN:
        afterVisitTableSwitchInsn((TableSwitchInsnNode) asmInsn, nodeInstruction);
        break;
    case AbstractInsnNode.TYPE_INSN:
        afterVisitTypeInsn((TypeInsnNode) asmInsn, nodeInstruction);
        break;
    case AbstractInsnNode.VAR_INSN:
        afterVisitVarInsn((VarInsnNode) asmInsn, nodeInstruction);
        break;
    default:
        // shouldn't happen
        break;
    }

}

From source file:de.codesourcery.asm.util.Disassembler.java

License:Apache License

private static String disassemble(AbstractInsnNode node, MethodNode method) {
    final int opCode = node.getOpcode();
    String mnemonic = Printer.OPCODES[opCode];

    switch (node.getType()) {
    case AbstractInsnNode.FIELD_INSN: // GETSTATIC, PUTSTATIC, GETFIELD , PUTFIELD
        FieldInsnNode tmp = (FieldInsnNode) node;
        mnemonic += " " + (tmp.owner + "#" + tmp.name);
        break;//from   w ww. jav  a 2 s. c o  m
    case AbstractInsnNode.IINC_INSN: // IINC
        IincInsnNode tmp2 = (IincInsnNode) node;
        mnemonic += " " + (tmp2.var + " , " + tmp2.incr);
        break;
    case AbstractInsnNode.INSN: // regular opcodes
        break;
    case AbstractInsnNode.INT_INSN: // BIPUSH, SIPUSH or NEWARRAY
        IntInsnNode tmp3 = (IntInsnNode) node;
        mnemonic += " " + (tmp3.operand);
        break;
    case AbstractInsnNode.INVOKE_DYNAMIC_INSN: // INVOKEDYNAMIC
        break;
    case AbstractInsnNode.JUMP_INSN: // IFEQ, IFNE, IFLT, IFGE, IFGT, IFLE, IF_ICMPEQ,IF_ICMPNE, IF_ICMPLT, IF_ICMPGE, IF_ICMPGT, IF_ICMPLE,IF_ACMPEQ, IF_ACMPNE, GOTO, JSR, IFNULL or IFNONNULL
        JumpInsnNode tmp4 = (JumpInsnNode) node;
        int index = method.instructions.indexOf(tmp4.label);
        while (method.instructions.get(index).getOpcode() == -1) {
            index++;
        }
        mnemonic += " " + index;
        break;
    case AbstractInsnNode.LDC_INSN: // load constant
        LdcInsnNode tmp5 = (LdcInsnNode) node;
        Class<?> clazz = tmp5.cst.getClass();
        if (clazz == String.class) {
            mnemonic += " \"" + tmp5.cst + "\"";
        } else if (clazz == org.objectweb.asm.Type.class) {
            org.objectweb.asm.Type type = (org.objectweb.asm.Type) tmp5.cst;
            mnemonic += " (a " + type.getClassName() + ")";
        } else {
            mnemonic += " " + tmp5.cst + " (" + tmp5.cst.getClass().getName() + ")";
        }
        break;
    case AbstractInsnNode.LOOKUPSWITCH_INSN: // LOOKUPSWITCH
        break;
    case AbstractInsnNode.METHOD_INSN: // INVOKEVIRTUAL, INVOKESPECIAL, INVOKESTATIC , INVOKEINTERFACE
        MethodInsnNode tmp6 = (MethodInsnNode) node;
        mnemonic += " " + (tmp6.owner + "#" + tmp6.name + "()");
        break;
    case AbstractInsnNode.MULTIANEWARRAY_INSN: // MULTIANEWARRAY
        break;
    case AbstractInsnNode.TABLESWITCH_INSN: // TABLESWITCH
        break;
    case AbstractInsnNode.TYPE_INSN: // NEW, ANEWARRAY, CHECKCAST , INSTANCEOF
        TypeInsnNode tmp8 = (TypeInsnNode) node;
        mnemonic += " " + tmp8.desc;
        break;
    case AbstractInsnNode.VAR_INSN: // ILOAD, LLOAD, FLOAD, DLOAD, ALOAD, ISTORE, LSTORE, FSTORE, DSTORE, ASTORE , RET
        VarInsnNode tmp7 = (VarInsnNode) node;
        mnemonic += "_" + tmp7.var;
        break;
    // -- VIRTUAL --
    case AbstractInsnNode.FRAME: /* VIRTUAL */
    case AbstractInsnNode.LABEL: /* VIRTUAL */
    case AbstractInsnNode.LINE: /* VIRTUAL */
    default:
        throw new RuntimeException("Internal error, unhandled node type: " + node);
    }
    return mnemonic;
}

From source file:de.unisb.cs.st.javaslicer.tracer.instrumentation.TracingMethodInstrumenter.java

License:Open Source License

@SuppressWarnings("unchecked")
public void transform(final ListIterator<MethodNode> methodIt) {

    // do not modify abstract or native methods
    if ((this.methodNode.access & ACC_ABSTRACT) != 0 || (this.methodNode.access & ACC_NATIVE) != 0)
        return;//from w w  w .jav  a 2 s .  c o m

    // check out what labels are jump targets (only these have to be traced)
    analyze(this.methodNode);

    this.instructionIterator = new FixedInstructionIterator(this.methodNode.instructions);
    // in the old method, initialize the new local variable for the threadtracer
    this.instructionIterator.add(new MethodInsnNode(INVOKESTATIC, Type.getInternalName(Tracer.class),
            "getInstance", "()L" + Type.getInternalName(Tracer.class) + ";", false));
    this.instructionIterator.add(new MethodInsnNode(INVOKEVIRTUAL, Type.getInternalName(Tracer.class),
            "getThreadTracer", "()L" + Type.getInternalName(ThreadTracer.class) + ";", false));
    this.instructionIterator.add(new InsnNode(DUP));
    this.instructionIterator.add(new VarInsnNode(ASTORE, this.tracerLocalVarIndex));

    this.instructionIterator.add(new MethodInsnNode(INVOKEINTERFACE, Type.getInternalName(ThreadTracer.class),
            "isPaused", "()Z", true));
    final LabelNode noTracingLabel = new LabelNode();
    this.instructionIterator.add(new JumpInsnNode(IFNE, noTracingLabel));
    // create a copy of the (uninstrumented) instructions (later, while iterating through the instructions)
    final InsnList oldInstructions = new InsnList();
    final Map<LabelNode, LabelNode> labelCopies = new LazyLabelMap();
    // copy the try-catch-blocks
    final Object[] oldTryCatchblockNodes = this.methodNode.tryCatchBlocks.toArray();
    for (final Object o : oldTryCatchblockNodes) {
        final TryCatchBlockNode tcb = (TryCatchBlockNode) o;
        final TryCatchBlockNode newTcb = new TryCatchBlockNode(labelCopies.get(tcb.start),
                labelCopies.get(tcb.end), labelCopies.get(tcb.handler), tcb.type);
        this.methodNode.tryCatchBlocks.add(newTcb);
    }

    // increment number of local variables by one (for the threadtracer)
    ++this.methodNode.maxLocals;

    // and increment all local variable indexes after the new one by one
    for (final Object o : this.methodNode.localVariables) {
        final LocalVariableNode localVar = (LocalVariableNode) o;
        if (localVar.index >= this.tracerLocalVarIndex)
            ++localVar.index;
    }

    // store information about local variables in the ReadMethod object
    List<LocalVariable> localVariables = new ArrayList<LocalVariable>();
    for (final Object o : this.methodNode.localVariables) {
        final LocalVariableNode localVar = (LocalVariableNode) o;
        while (localVariables.size() <= localVar.index)
            localVariables.add(null);
        localVariables.set(localVar.index, new LocalVariable(localVar.index, localVar.name, localVar.desc));
    }
    this.readMethod.setLocalVariables(localVariables.toArray(new LocalVariable[localVariables.size()]));
    localVariables = null;

    // each method must start with a (dedicated) label:
    assert this.readMethod.getInstructions().isEmpty();
    traceLabel(null, InstructionType.METHODENTRY);
    assert this.readMethod.getInstructions().size() == 1
            && this.readMethod.getInstructions().get(0) instanceof LabelMarker
            && ((LabelMarker) this.readMethod.getInstructions().get(0)).isAdditionalLabel();
    this.readMethod.setMethodEntryLabel((LabelMarker) this.readMethod.getInstructions().get(0));

    // needed later:
    final LabelNode l0 = new LabelNode();
    this.instructionIterator.add(l0);

    // then, visit the instructions that were in the method before
    while (this.instructionIterator.hasNext()) {

        final AbstractInsnNode insnNode = this.instructionIterator.next();
        switch (insnNode.getType()) {
        case AbstractInsnNode.INSN:
            transformInsn((InsnNode) insnNode);
            break;
        case AbstractInsnNode.INT_INSN:
            transformIntInsn((IntInsnNode) insnNode);
            break;
        case AbstractInsnNode.VAR_INSN:
            transformVarInsn((VarInsnNode) insnNode);
            break;
        case AbstractInsnNode.TYPE_INSN:
            transformTypeInsn((TypeInsnNode) insnNode);
            break;
        case AbstractInsnNode.FIELD_INSN:
            transformFieldInsn((FieldInsnNode) insnNode);
            break;
        case AbstractInsnNode.METHOD_INSN:
            transformMethodInsn((MethodInsnNode) insnNode);
            break;
        case AbstractInsnNode.JUMP_INSN:
            transformJumpInsn((JumpInsnNode) insnNode);
            break;
        case AbstractInsnNode.LABEL:
            transformLabel((LabelNode) insnNode);
            break;
        case AbstractInsnNode.LDC_INSN:
            transformLdcInsn((LdcInsnNode) insnNode);
            break;
        case AbstractInsnNode.IINC_INSN:
            transformIincInsn((IincInsnNode) insnNode);
            break;
        case AbstractInsnNode.TABLESWITCH_INSN:
            transformTableSwitchInsn((TableSwitchInsnNode) insnNode);
            break;
        case AbstractInsnNode.LOOKUPSWITCH_INSN:
            transformLookupSwitchInsn((LookupSwitchInsnNode) insnNode);
            break;
        case AbstractInsnNode.MULTIANEWARRAY_INSN:
            transformMultiANewArrayInsn((MultiANewArrayInsnNode) insnNode);
            break;
        case AbstractInsnNode.FRAME:
            // ignore
            break;
        case AbstractInsnNode.LINE:
            // ignore
            break;
        default:
            throw new RuntimeException("Unknown instruction type " + insnNode.getType() + " ("
                    + insnNode.getClass().getSimpleName() + ")");
        }
        oldInstructions.add(insnNode.clone(labelCopies));
    }

    assert this.outstandingInitializations == 0;

    // add the (old) try-catch blocks to the readMethods
    // (can only be done down here since we use the information in the
    // labels map)
    for (final Object o : oldTryCatchblockNodes) {
        final TryCatchBlockNode tcb = (TryCatchBlockNode) o;
        this.readMethod.addTryCatchBlock(new TryCatchBlock(this.labels.get(tcb.start), this.labels.get(tcb.end),
                this.labels.get(tcb.handler), tcb.type));
    }

    final LabelNode l1 = new LabelNode();
    this.instructionIterator.add(l1);
    final int newPos = this.readMethod.getInstructions().size();
    traceLabel(null, InstructionType.METHODEXIT);
    assert this.readMethod.getInstructions().size() == newPos + 1;
    final AbstractInstruction abnormalTerminationLabel = this.readMethod.getInstructions().get(newPos);
    assert abnormalTerminationLabel instanceof LabelMarker;
    this.readMethod.setAbnormalTerminationLabel((LabelMarker) abnormalTerminationLabel);
    this.methodNode.instructions.add(new InsnNode(ATHROW));

    // add a try catch block around the method so that we can trace when this method is left
    // by a thrown exception
    this.methodNode.tryCatchBlocks.add(new TryCatchBlockNode(l0, l1, l1, null));

    // now add the code that is executed if no tracing should be performed
    this.methodNode.instructions.add(noTracingLabel);
    if (this.firstLine != -1)
        this.methodNode.instructions.add(new LineNumberNode(this.firstLine, noTracingLabel));
    this.methodNode.instructions.add(new InsnNode(ACONST_NULL));
    this.methodNode.instructions.add(new VarInsnNode(ASTORE, this.tracerLocalVarIndex));
    this.methodNode.instructions.add(oldInstructions);

    // finally: create a copy of the method that gets the ThreadTracer as argument
    // this is only necessary for private methods or "<init>"
    if (this.tracer.wasRedefined(this.readMethod.getReadClass().getName())
            && (this.methodNode.access & ACC_PRIVATE) != 0) {
        final Type[] oldMethodArguments = Type.getArgumentTypes(this.methodNode.desc);
        final Type[] newMethodArguments = Arrays.copyOf(oldMethodArguments, oldMethodArguments.length + 1);
        newMethodArguments[oldMethodArguments.length] = Type.getType(ThreadTracer.class);
        final String newMethodDesc = Type.getMethodDescriptor(Type.getReturnType(this.methodNode.desc),
                newMethodArguments);
        final MethodNode newMethod = new MethodNode(this.methodNode.access, this.methodNode.name, newMethodDesc,
                this.methodNode.signature,
                (String[]) this.methodNode.exceptions.toArray(new String[this.methodNode.exceptions.size()]));
        methodIt.add(newMethod);

        int threadTracerParamPos = ((this.readMethod.getAccess() & Opcodes.ACC_STATIC) == 0 ? 1 : 0);
        for (final Type t : oldMethodArguments)
            threadTracerParamPos += t.getSize();

        final Map<LabelNode, LabelNode> newMethodLabels = new LazyLabelMap();

        // copy the local variables information to the new method
        for (final Object o : this.methodNode.localVariables) {
            final LocalVariableNode lv = (LocalVariableNode) o;
            newMethod.localVariables.add(new LocalVariableNode(lv.name, lv.desc, lv.signature,
                    newMethodLabels.get(lv.start), newMethodLabels.get(lv.end), lv.index));
        }

        newMethod.maxLocals = this.methodNode.maxLocals;
        newMethod.maxStack = this.methodNode.maxStack;

        // copy the try-catch-blocks
        for (final Object o : this.methodNode.tryCatchBlocks) {
            final TryCatchBlockNode tcb = (TryCatchBlockNode) o;
            newMethod.tryCatchBlocks.add(new TryCatchBlockNode(newMethodLabels.get(tcb.start),
                    newMethodLabels.get(tcb.end), newMethodLabels.get(tcb.handler), tcb.type));
        }

        // skip the first 6 instructions, replace them with these:
        newMethod.instructions.add(new VarInsnNode(ALOAD, threadTracerParamPos));
        newMethod.instructions.add(new InsnNode(DUP));
        newMethod.instructions.add(new VarInsnNode(ASTORE, this.tracerLocalVarIndex));
        newMethod.instructions.add(new JumpInsnNode(IFNULL, newMethodLabels.get(noTracingLabel)));
        final Iterator<AbstractInsnNode> oldInsnIt = this.methodNode.instructions.iterator(6);
        // and add all the other instructions
        while (oldInsnIt.hasNext()) {
            final AbstractInsnNode insn = oldInsnIt.next();
            newMethod.instructions.add(insn.clone(newMethodLabels));
        }
    }

    ready();
}

From source file:gemlite.core.internal.admin.measurement.CheckPointService.java

License:Apache License

private void analyzeMethod(CheckPointContext ctx, ClassNode cn, MethodNode mn, ScannedMethodItem caller) {
    // ???// ww w .j  a  v  a2  s.co m
    Set<ScannedMethodItem> methods = new HashSet<ScannedMethodItem>();
    GemliteSibingsLoader loader = ctx.loader;
    InsnList insnList = mn.instructions;
    for (int j = 0; j < insnList.size(); j++) {
        AbstractInsnNode insn = insnList.get(j);

        if (insn.getType() == AbstractInsnNode.METHOD_INSN) {
            MethodInsnNode methodInsn = (MethodInsnNode) insn;
            if (CONSTRUCT_NAME.equals(methodInsn.name))
                continue;
            URL url = loader.findResource(methodInsn.owner + ".class");
            boolean blCurrentModule = url != null;
            if (blCurrentModule) {
                ScannedMethodItem item = new ScannedMethodItem(methodInsn.owner, methodInsn.name,
                        methodInsn.desc);
                LogUtil.getCoreLog().trace("I={} owner={} name={} op={}", j, methodInsn.owner, methodInsn.name,
                        methodInsn.getOpcode());

                // ???
                if (methods.contains(item))
                    continue;

                caller.children.add(item);

                // methods
                methods.add(item);

                if (!methodInsn.owner.equals(cn.name))
                    analazyClass(ctx, item.className, item.methodName, item);
                else
                    analazyClass(ctx, cn, item.methodName, item);
            }
        }
    }
}