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

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

Introduction

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

Prototype

int TYPE_INSN

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

Click Source Link

Document

The type of TypeInsnNode instructions.

Usage

From source file:analysis.ReferenceGenerator.java

License:Open Source License

private void refInstructions(InsnList insnList) {
    AbstractInsnNode insn;//from   ww w.  ja v  a  2  s  . co  m

    insn = insnList.getFirst();

    Object cst;

    while (insn != null) {
        switch (insn.getType()) {
        case AbstractInsnNode.FIELD_INSN:
            //addTypeClassRef(Type.getType(((FieldInsnNode)insn).desc));
            addFieldRef(((FieldInsnNode) insn).owner, ((FieldInsnNode) insn).name);
            break;
        /*case AbstractInsnNode.INVOKE_DYNAMIC_INSN:
                   
           break;*/
        /*case AbstractInsnNode.LDC_INSN:
           cst = ((LdcInsnNode)insn).cst;
           if(cst instanceof Type) {
              addTypeClassRef((Type)cst);
           }
           break;*/
        case AbstractInsnNode.METHOD_INSN:
            addMethodRef(((MethodInsnNode) insn).owner, ((MethodInsnNode) insn).name,
                    ((MethodInsnNode) insn).desc);
            break;
        case AbstractInsnNode.MULTIANEWARRAY_INSN:
            addTypeClassRef(Type.getType(((MultiANewArrayInsnNode) insn).desc));
            break;
        case AbstractInsnNode.TYPE_INSN:
            addTypeClassRef(Type.getType(((TypeInsnNode) insn).desc));
            break;
        }
        insn = insn.getNext();
    }
}

From source file:blockphysics.asm.BPTransformer.java

License:Open Source License

private byte[] transformEntityTrackerEntry(byte[] bytes) {
    /*try/* ww  w  .  j  av  a2s  .c om*/
    {
        FileOutputStream fos = new FileOutputStream("d:/EntityTrackerEntry.orig.class");
        fos.write(bytes);
      fos.close();
    } catch (IOException e) {
       // TODO Auto-generated catch block
       e.printStackTrace();
    }*/

    System.out.print("[BlockPhysics] Patching EntityTrackerEntry.class ......");
    boolean ok = false;

    ClassNode classNode = new ClassNode();
    ClassReader classReader = new ClassReader(bytes);
    classReader.accept(classNode, 0);

    MethodNode m;
    Iterator<MethodNode> methods = classNode.methods.iterator();
    while (methods.hasNext()) {
        m = methods.next();

        if (m.name.equals("c") && m.desc.equals("()Lex;")) {
            for (int index = 0; index < m.instructions.size(); index++) {
                if (m.instructions.get(index).getType() == AbstractInsnNode.TYPE_INSN
                        && m.instructions.get(index).getOpcode() == INSTANCEOF
                        && ((TypeInsnNode) m.instructions.get(index)).desc.equals("sq")) {
                    while (m.instructions.get(index).getOpcode() != IFEQ) {
                        index++;
                    }
                    index++;

                    while (m.instructions.get(index).getOpcode() != ARETURN) {
                        m.instructions.remove(m.instructions.get(index));
                    }

                    InsnList toInject = new InsnList();
                    toInject.add(new VarInsnNode(ALOAD, 0));
                    toInject.add(new FieldInsnNode(GETFIELD, "jw", "a", "Lnm;"));
                    toInject.add(new TypeInsnNode(CHECKCAST, "sq"));
                    toInject.add(new MethodInsnNode(INVOKESTATIC, "blockphysics/BlockPhysics",
                            "spawnFallingSandPacket", "(Lsq;)Ldc;"));

                    m.instructions.insertBefore(m.instructions.get(index), toInject);
                    ok = true;
                    break;
                }
            }
        }
    }

    ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS);
    classNode.accept(cw);

    if (ok)
        System.out.println("OK");
    else
        System.out.println("Failed." + ok);

    /*try
    {
       FileOutputStream fos = new FileOutputStream("d:/EntityTrackerEntry.class");
       fos.write(cw.toByteArray());
     fos.close();
    } catch (IOException e) {
     // TODO Auto-generated catch block
     e.printStackTrace();
    }*/

    return cw.toByteArray();
}

From source file:blockphysics.asm.BPTransformer.java

License:Open Source License

private byte[] transformEntityTracker(byte[] bytes) {
    /*try/*from  w  w  w . j ava 2 s . c o m*/
    {
        FileOutputStream fos = new FileOutputStream("d:/EntityTracker.orig.class");
        fos.write(bytes);
      fos.close();
    } catch (IOException e) {
       // TODO Auto-generated catch block
       e.printStackTrace();
    }*/

    System.out.print("[BlockPhysics] Patching EntityTracker.class ...........");
    boolean ok = false;
    boolean ok2 = false;
    boolean ok3 = false;
    boolean ok4 = false;

    ClassNode classNode = new ClassNode();
    ClassReader classReader = new ClassReader(bytes);
    classReader.accept(classNode, 0);

    MethodNode m;
    Iterator<MethodNode> methods = classNode.methods.iterator();
    while (methods.hasNext()) {
        m = methods.next();

        if (m.name.equals("<init>") && m.desc.equals("(Ljr;)V")) {
            for (int index = m.instructions.size() - 1; index >= 0; index--) {
                if (m.instructions.get(index).getOpcode() == RETURN) {
                    InsnList toInject = new InsnList();
                    toInject.add(new VarInsnNode(ALOAD, 0));
                    toInject.add(new InsnNode(ICONST_0));
                    toInject.add(new FieldInsnNode(PUTFIELD, "jl", "movingblocks", "I"));

                    m.instructions.insertBefore(m.instructions.get(index), toInject);
                    ok = true;
                    break;
                }
            }
        } else if (m.name.equals("a") && m.desc.equals("(Lnm;)V")) {
            for (int index = 0; index < m.instructions.size(); index++) {
                if (m.instructions.get(index).getType() == AbstractInsnNode.TYPE_INSN
                        && m.instructions.get(index).getOpcode() == INSTANCEOF
                        && ((TypeInsnNode) m.instructions.get(index)).desc.equals("tb")) {
                    m.instructions.remove(m.instructions.get(index - 1));

                    while (m.instructions.get(index).getType() != AbstractInsnNode.TYPE_INSN
                            || m.instructions.get(index).getOpcode() != INSTANCEOF) {
                        m.instructions.remove(m.instructions.get(index - 1));
                        ok2 = true;
                    }
                    break;
                }
            }

            for (int index = 0; index < m.instructions.size(); index++) {
                if (m.instructions.get(index).getType() == AbstractInsnNode.TYPE_INSN
                        && m.instructions.get(index).getOpcode() == INSTANCEOF
                        && ((TypeInsnNode) m.instructions.get(index)).desc.equals("sq")) {
                    while (m.instructions.get(index).getOpcode() != GOTO) {
                        index++;
                        if (m.instructions.get(index).getType() == AbstractInsnNode.INT_INSN
                                && m.instructions.get(index).getOpcode() == BIPUSH
                                && ((IntInsnNode) m.instructions.get(index)).operand == 20) {
                            m.instructions.set(m.instructions.get(index), new IntInsnNode(BIPUSH, 40));
                            ok3 = true;
                        }
                    }

                    InsnList toInject = new InsnList();
                    toInject.add(new VarInsnNode(ALOAD, 0));
                    toInject.add(new InsnNode(DUP));
                    toInject.add(new FieldInsnNode(GETFIELD, "jl", "movingblocks", "I"));
                    toInject.add(new InsnNode(ICONST_1));
                    toInject.add(new InsnNode(IADD));
                    toInject.add(new FieldInsnNode(PUTFIELD, "jl", "movingblocks", "I"));

                    m.instructions.insertBefore(m.instructions.get(index), toInject);
                    break;
                }
            }
        } else if (m.name.equals("b") && m.desc.equals("(Lnm;)V")) {
            InsnList toInject = new InsnList();

            toInject.add(new VarInsnNode(ALOAD, 1));
            toInject.add(new TypeInsnNode(INSTANCEOF, "sq"));
            LabelNode l3 = new LabelNode();
            toInject.add(new JumpInsnNode(IFEQ, l3));
            toInject.add(new VarInsnNode(ALOAD, 0));
            toInject.add(new InsnNode(DUP));
            toInject.add(new FieldInsnNode(GETFIELD, "jl", "movingblocks", "I"));
            toInject.add(new InsnNode(ICONST_1));
            toInject.add(new InsnNode(ISUB));
            toInject.add(new FieldInsnNode(PUTFIELD, "jl", "movingblocks", "I"));
            toInject.add(l3);

            for (int index = m.instructions.size() - 1; index >= 0; index--) {
                if (m.instructions.get(index).getOpcode() == RETURN) {
                    m.instructions.insertBefore(m.instructions.get(index), toInject);
                    ok4 = true;
                    break;
                }
            }
        }
    }

    ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS);
    classNode.accept(cw);

    FieldVisitor fv;

    fv = cw.visitField(ACC_PUBLIC, "movingblocks", "I", null, null);
    fv.visitEnd();

    cw.visitEnd();

    if (ok && ok2 && ok3 && ok4)
        System.out.println("OK");
    else
        System.out.println("Failed." + ok + ok2 + ok3 + ok4);

    /*try
    {
       FileOutputStream fos = new FileOutputStream("d:/EntityTracker.class");
       fos.write(cw.toByteArray());
     fos.close();
    } catch (IOException e) {
     // TODO Auto-generated catch block
     e.printStackTrace();
    }*/

    return cw.toByteArray();
}

From source file:blockphysics.asm.BPTransformer.java

License:Open Source License

private byte[] transformNetClientHandler(byte[] bytes) {
    /*try/*  w ww  .  j a v a2  s.c  o  m*/
    {
        FileOutputStream fos = new FileOutputStream("d:/NetClientHandler.orig.class");
        fos.write(bytes);
      fos.close();
    } catch (IOException e) {
       // TODO Auto-generated catch block
       e.printStackTrace();
    }*/

    System.out.print("[BlockPhysics] Patching NetClientHandler.class ........");
    boolean ok = false;

    ClassNode classNode = new ClassNode();
    ClassReader classReader = new ClassReader(bytes);
    classReader.accept(classNode, 0);

    MethodNode m;
    Iterator<MethodNode> methods = classNode.methods.iterator();
    while (methods.hasNext()) {
        m = methods.next();

        if (m.name.equals("a") && m.desc.equals("(Ldc;)V")) {
            InsnList toInject = new InsnList();

            toInject.add(new VarInsnNode(ALOAD, 0));
            toInject.add(new FieldInsnNode(GETFIELD, "bct", "i", "Lbda;"));
            toInject.add(new VarInsnNode(DLOAD, 2));
            toInject.add(new VarInsnNode(DLOAD, 4));
            toInject.add(new VarInsnNode(DLOAD, 6));
            toInject.add(new VarInsnNode(ALOAD, 1));
            toInject.add(new MethodInsnNode(INVOKESTATIC, "blockphysics/BlockPhysics", "createFallingsand",
                    "(Labv;DDDLdc;)Lsq;"));
            toInject.add(new VarInsnNode(ASTORE, 8));
            toInject.add(new VarInsnNode(ALOAD, 1));
            toInject.add(new InsnNode(ICONST_1));
            toInject.add(new FieldInsnNode(PUTFIELD, "dc", "k", "I"));

            for (int index = 0; index < m.instructions.size(); index++) {
                if (m.instructions.get(index).getOpcode() == INVOKESPECIAL
                        && m.instructions.get(index).getType() == AbstractInsnNode.METHOD_INSN
                        && ((MethodInsnNode) m.instructions.get(index)).owner.equals("sq")
                        && ((MethodInsnNode) m.instructions.get(index)).name.equals("<init>")) {
                    while (m.instructions.get(index).getType() != AbstractInsnNode.FIELD_INSN
                            || m.instructions.get(index).getOpcode() != PUTFIELD
                            || !((FieldInsnNode) m.instructions.get(index)).owner.equals("dc")
                            || !((FieldInsnNode) m.instructions.get(index)).name.equals("k")) {
                        index++;
                    }

                    while (m.instructions.get(index).getType() != AbstractInsnNode.TYPE_INSN
                            || !((TypeInsnNode) m.instructions.get(index)).desc.equals("sq")) {
                        m.instructions.remove(m.instructions.get(index));
                        index--;
                        ok = true;
                    }

                    if (ok) {
                        m.instructions.remove(m.instructions.get(index));
                        m.instructions.insertBefore(m.instructions.get(index), toInject);
                    }

                    break;
                }
            }
        }
    }

    ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS);
    classNode.accept(cw);

    if (ok)
        System.out.println("OK");
    else
        System.out.println("Failed." + ok);

    /*try
    {
       FileOutputStream fos = new FileOutputStream("d:/NetClientHandler.class");
       fos.write(cw.toByteArray());
     fos.close();
    } catch (IOException e) {
     // TODO Auto-generated catch block
     e.printStackTrace();
    }*/

    return cw.toByteArray();
}

From source file:cl.inria.stiq.instrumenter.BCIUtils.java

License:Open Source License

private static void printFrames(MethodNode aNode, Frame[] aFrames) {
    int bcIndex = 1;

    for (int i = 0; i < aFrames.length; i++) {
        Frame theFrame = aFrames[i];
        AbstractInsnNode theInsn = aNode.instructions.get(i);

        switch (theInsn.getType()) {
        case AbstractInsnNode.INSN:
        case AbstractInsnNode.INT_INSN:
        case AbstractInsnNode.VAR_INSN:
        case AbstractInsnNode.TYPE_INSN:
        case AbstractInsnNode.FIELD_INSN:
        case AbstractInsnNode.METHOD_INSN:
        case AbstractInsnNode.JUMP_INSN:
        case AbstractInsnNode.LDC_INSN:
        case AbstractInsnNode.IINC_INSN:
        case AbstractInsnNode.TABLESWITCH_INSN:
        case AbstractInsnNode.LOOKUPSWITCH_INSN:
        case AbstractInsnNode.MULTIANEWARRAY_INSN:
            TraceMethodVisitor theTraceVisitor = new TraceMethodVisitor();
            theInsn.accept(theTraceVisitor);
            StringWriter theWriter = new StringWriter();
            theTraceVisitor.print(new PrintWriter(theWriter));
            String theTraced = theWriter.toString().replace("\n", "");
            System.out.println(bcIndex + "\t" + frameString(theFrame) + " |\t" + theTraced);
            bcIndex++;//from  w  w w  . j a  v a 2s.c  om
            break;

        case AbstractInsnNode.FRAME:
        case AbstractInsnNode.LINE:
        case AbstractInsnNode.LABEL:
            break;
        }
    }
}

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./*ww w. j  a v  a2  s  .  c om*/
 * 
 * @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;//  w w w  .  j a  va2  s .com
    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  om
    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 ww.ja  va 2 s.co  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:jaspex.transactifier.ChangeClinitMethodVisitor.java

License:Open Source License

private static boolean clinitIsSafe(Type t) {
    try {//from  w w w.java  2  s . c  o  m
        ClassReader cr = new ClassReader(t.commonName());
        ClassNode cNode = new ClassNode();
        cr.accept(cNode, 0);

        for (MethodNode method : cNode.methods) {
            if (!method.name.equals("<clinit>"))
                continue;
            // Examinar instruces
            Iterator<AbstractInsnNode> it = method.instructions.iterator();
            while (it.hasNext()) {
                AbstractInsnNode insn = it.next();
                switch (insn.getType()) {
                case AbstractInsnNode.FRAME:
                case AbstractInsnNode.INT_INSN:
                case AbstractInsnNode.JUMP_INSN:
                case AbstractInsnNode.LABEL:
                case AbstractInsnNode.LDC_INSN:
                case AbstractInsnNode.LINE:
                case AbstractInsnNode.LOOKUPSWITCH_INSN:
                case AbstractInsnNode.MULTIANEWARRAY_INSN:
                case AbstractInsnNode.TABLESWITCH_INSN:
                case AbstractInsnNode.TYPE_INSN:
                case AbstractInsnNode.VAR_INSN:
                    break;
                case AbstractInsnNode.FIELD_INSN:
                    FieldInsnNode fieldInsn = (FieldInsnNode) insn;
                    if (fieldInsn.getOpcode() != PUTSTATIC) {
                        // GETSTATIC, GETFIELD, PUTFIELD
                        return false;
                    }
                    break;
                case AbstractInsnNode.IINC_INSN:
                    return false;
                case AbstractInsnNode.INSN:
                    if (unsafeInsnBytecodes.contains(insn.getOpcode())) {
                        Log.debug(t.commonName() + ".<clinit>() is unsafe " + "because of bytecode "
                                + insn.getOpcode());
                        return false;
                    }
                    break;
                case AbstractInsnNode.METHOD_INSN:
                    MethodInsnNode methodInsn = (MethodInsnNode) insn;
                    if (!ClassFilter.isMethodWhitelisted(Type.fromAsm(methodInsn.owner), methodInsn.name,
                            methodInsn.desc)) {
                        Log.debug(t.commonName() + ".<clinit>() is unsafe " + "because it invokes "
                                + Type.fromAsm(methodInsn.owner).commonName() + "." + methodInsn.name);
                        return false;
                    }
                    break;
                default:
                    throw new Error("Unexpected bytecode " + insn);
                }
            }

            //Log.debug(t.commonName() + ".<clinit>() for " + t + " is safe");
            return true;
        }

        return false;
    } catch (IOException e) {
        throw new Error(e);
    }
}