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

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

Introduction

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

Prototype

public int getOpcode() 

Source Link

Document

Returns the opcode of this instruction.

Usage

From source file:com.builtbroken.profiler.asm.WorldTransformer.java

/** {@link World#setBlock(int, int, int, Block, int, int)} */
private void injectSetBlock(ClassNode cn) {
    MethodNode setBlockMethod = getMethod(cn, "setBlock", "(IIIL" + getName(CLASS_KEY_BLOCK) + ";II)Z");

    if (setBlockMethod != null) {
        //Create method call
        final InsnList nodeAdd = new InsnList();

        nodeAdd.add(new VarInsnNode(Opcodes.ALOAD, 0));
        nodeAdd.add(new VarInsnNode(Opcodes.ILOAD, 1));
        nodeAdd.add(new VarInsnNode(Opcodes.ILOAD, 2));
        nodeAdd.add(new VarInsnNode(Opcodes.ILOAD, 3));
        nodeAdd.add(new MethodInsnNode(Opcodes.INVOKESTATIC, BLOCK_HOOK_CLASS, "onBlockChange",
                "(L" + getName(CLASS_KEY_WORLD) + ";III)V", false));

        //Inject method call at top of method
        setBlockMethod.instructions.insertBefore(setBlockMethod.instructions.get(0), nodeAdd);

        //Locate all return points from the method
        List<AbstractInsnNode> returnNodes = new ArrayList();
        for (int i = 0; i < setBlockMethod.instructions.size(); i++) {
            AbstractInsnNode ain = setBlockMethod.instructions.get(i);
            if (ain.getOpcode() == Opcodes.IRETURN) {
                returnNodes.add(ain);//from ww  w .j ava2 s  .c o m
            }
        }

        //Inject calls in front of return points
        for (AbstractInsnNode node : returnNodes) {
            //Create method call
            final InsnList nodeAdd2 = new InsnList();
            nodeAdd2.add(new VarInsnNode(Opcodes.ALOAD, 0));
            nodeAdd2.add(new VarInsnNode(Opcodes.ILOAD, 1));
            nodeAdd2.add(new VarInsnNode(Opcodes.ILOAD, 2));
            nodeAdd2.add(new VarInsnNode(Opcodes.ILOAD, 3));
            nodeAdd2.add(new MethodInsnNode(Opcodes.INVOKESTATIC, BLOCK_HOOK_CLASS, "onPostBlockChange",
                    "(L" + getName(CLASS_KEY_WORLD) + ";III)V", false));
            //Inject method call before return node
            setBlockMethod.instructions.insertBefore(node, nodeAdd2);
        }
    }
}

From source file:com.builtbroken.profiler.asm.WorldTransformer.java

/** {@link World#setBlockMetadataWithNotify(int, int, int, int, int)} */
private void injectSetBlockWithMeta(ClassNode cn) {
    MethodNode setBlockMetaMethod = getMethod(cn, "setBlockMetadataWithNotify", "(IIIII)Z");

    if (setBlockMetaMethod != null) {
        final InsnList nodeAdd = new InsnList();

        nodeAdd.add(new VarInsnNode(Opcodes.ALOAD, 0)); //this
        nodeAdd.add(new VarInsnNode(Opcodes.ILOAD, 1)); //x
        nodeAdd.add(new VarInsnNode(Opcodes.ILOAD, 2)); //y
        nodeAdd.add(new VarInsnNode(Opcodes.ILOAD, 3)); //z
        nodeAdd.add(new MethodInsnNode(Opcodes.INVOKESTATIC, BLOCK_HOOK_CLASS, "onBlockMetaChange",
                "(L" + getName(CLASS_KEY_WORLD) + ";III)V", false));

        setBlockMetaMethod.instructions.insertBefore(setBlockMetaMethod.instructions.get(0), nodeAdd);

        //Locate all return points from the method
        List<AbstractInsnNode> returnNodes = new ArrayList();
        for (int i = 0; i < setBlockMetaMethod.instructions.size(); i++) {
            AbstractInsnNode ain = setBlockMetaMethod.instructions.get(i);
            if (ain.getOpcode() == Opcodes.IRETURN) {
                returnNodes.add(ain);/*from  w w  w . ja  v a 2 s . c  om*/
            }
        }

        //Inject calls in front of return points
        for (AbstractInsnNode node : returnNodes) {
            //Create method call
            final InsnList nodeAdd2 = new InsnList();
            nodeAdd2.add(new VarInsnNode(Opcodes.ALOAD, 0));
            nodeAdd2.add(new VarInsnNode(Opcodes.ILOAD, 1));
            nodeAdd2.add(new VarInsnNode(Opcodes.ILOAD, 2));
            nodeAdd2.add(new VarInsnNode(Opcodes.ILOAD, 3));
            nodeAdd2.add(new MethodInsnNode(Opcodes.INVOKESTATIC, BLOCK_HOOK_CLASS, "onPostBlockMetaChange",
                    "(L" + getName(CLASS_KEY_WORLD) + ";III)V", false));
            //Inject method call before return node
            setBlockMetaMethod.instructions.insertBefore(node, nodeAdd2);
        }
    }
}

From source file:com.dragome.callbackevictor.serverside.bytecode.transformation.asm.ContinuationMethodAnalyzer.java

License:Apache License

@SuppressWarnings("unchecked")
void moveNew() throws AnalyzerException {
    SourceInterpreter i = new SourceInterpreter();
    Analyzer a = new Analyzer(i);
    a.analyze(className, this);

    final HashMap<AbstractInsnNode, MethodInsnNode> movable = new HashMap<AbstractInsnNode, MethodInsnNode>();

    Frame[] frames = a.getFrames();
    for (int j = 0; j < methods.size(); j++) {
        MethodInsnNode mnode = methods.get(j);
        // require to move NEW instruction
        int n = instructions.indexOf(mnode);
        Frame f = frames[n];//from w w w  .  j a v  a  2 s  .c o  m
        Type[] args = Type.getArgumentTypes(mnode.desc);

        SourceValue v = (SourceValue) f.getStack(f.getStackSize() - args.length - 1);
        Set<AbstractInsnNode> insns = v.insns;
        for (final AbstractInsnNode ins : insns) {
            if (ins.getOpcode() == NEW) {
                movable.put(ins, mnode);
            } else {
                // other known patterns
                int n1 = instructions.indexOf(ins);
                if (ins.getOpcode() == DUP) { // <init> with params
                    AbstractInsnNode ins1 = instructions.get(n1 - 1);
                    if (ins1.getOpcode() == NEW) {
                        movable.put(ins1, mnode);
                    }
                } else if (ins.getOpcode() == SWAP) { // in exception handler
                    AbstractInsnNode ins1 = instructions.get(n1 - 1);
                    AbstractInsnNode ins2 = instructions.get(n1 - 2);
                    if (ins1.getOpcode() == DUP_X1 && ins2.getOpcode() == NEW) {
                        movable.put(ins2, mnode);
                    }
                }
            }
        }
    }

    int updateMaxStack = 0;
    for (final Map.Entry<AbstractInsnNode, MethodInsnNode> e : movable.entrySet()) {
        AbstractInsnNode node1 = e.getKey();
        int n1 = instructions.indexOf(node1);
        AbstractInsnNode node2 = instructions.get(n1 + 1);
        AbstractInsnNode node3 = instructions.get(n1 + 2);
        int producer = node2.getOpcode();

        instructions.remove(node1); // NEW
        boolean requireDup = false;
        if (producer == DUP) {
            instructions.remove(node2); // DUP
            requireDup = true;
        } else if (producer == DUP_X1) {
            instructions.remove(node2); // DUP_X1
            instructions.remove(node3); // SWAP
            requireDup = true;
        }

        MethodInsnNode mnode = (MethodInsnNode) e.getValue();
        AbstractInsnNode nm = mnode;

        int varOffset = stackRecorderVar + 1;
        Type[] args = Type.getArgumentTypes(mnode.desc);

        // optimizations for some common cases
        if (args.length == 0) {
            final InsnList doNew = new InsnList();
            doNew.add(node1); // NEW
            if (requireDup)
                doNew.add(new InsnNode(DUP));
            instructions.insertBefore(nm, doNew);
            nm = doNew.getLast();
            continue;
        }

        if (args.length == 1 && args[0].getSize() == 1) {
            final InsnList doNew = new InsnList();
            doNew.add(node1); // NEW
            if (requireDup) {
                doNew.add(new InsnNode(DUP));
                doNew.add(new InsnNode(DUP2_X1));
                doNew.add(new InsnNode(POP2));
                updateMaxStack = updateMaxStack < 2 ? 2 : updateMaxStack; // a two extra slots for temp values
            } else
                doNew.add(new InsnNode(SWAP));
            instructions.insertBefore(nm, doNew);
            nm = doNew.getLast();
            continue;
        }

        // TODO this one untested!
        if ((args.length == 1 && args[0].getSize() == 2)
                || (args.length == 2 && args[0].getSize() == 1 && args[1].getSize() == 1)) {
            final InsnList doNew = new InsnList();
            doNew.add(node1); // NEW
            if (requireDup) {
                doNew.add(new InsnNode(DUP));
                doNew.add(new InsnNode(DUP2_X2));
                doNew.add(new InsnNode(POP2));
                updateMaxStack = updateMaxStack < 2 ? 2 : updateMaxStack; // a two extra slots for temp values
            } else {
                doNew.add(new InsnNode(DUP_X2));
                doNew.add(new InsnNode(POP));
                updateMaxStack = updateMaxStack < 1 ? 1 : updateMaxStack; // an extra slot for temp value
            }
            instructions.insertBefore(nm, doNew);
            nm = doNew.getLast();
            continue;
        }

        final InsnList doNew = new InsnList();
        // generic code using temporary locals
        // save stack
        for (int j = args.length - 1; j >= 0; j--) {
            Type type = args[j];

            doNew.add(new VarInsnNode(type.getOpcode(ISTORE), varOffset));
            varOffset += type.getSize();
        }
        if (varOffset > maxLocals) {
            maxLocals = varOffset;
        }

        doNew.add(node1); // NEW

        if (requireDup)
            doNew.add(new InsnNode(DUP));

        // restore stack
        for (int j = 0; j < args.length; j++) {
            Type type = args[j];
            varOffset -= type.getSize();

            doNew.add(new VarInsnNode(type.getOpcode(ILOAD), varOffset));

            // clean up store to avoid memory leak?
            if (type.getSort() == Type.OBJECT || type.getSort() == Type.ARRAY) {
                updateMaxStack = updateMaxStack < 1 ? 1 : updateMaxStack; // an extra slot for ACONST_NULL

                doNew.add(new InsnNode(ACONST_NULL));

                doNew.add(new VarInsnNode(type.getOpcode(ISTORE), varOffset));
            }
        }
        instructions.insertBefore(nm, doNew);
        nm = doNew.getLast();
    }

    maxStack += updateMaxStack;
}

From source file:com.dragome.callbackevictor.serverside.bytecode.transformation.asm.MonitoringFrame.java

License:Apache License

public void execute(AbstractInsnNode insn, Interpreter interpreter) throws AnalyzerException {

    boolean never = false;
    if (never) {//from www  . ja v  a2s  . co m
        super.execute(insn, interpreter);
        return;
    }

    int insnOpcode = insn.getOpcode();

    if (insnOpcode == Opcodes.MONITORENTER || insnOpcode == Opcodes.MONITOREXIT) {
        Value pop = pop();
        interpreter.unaryOperation(insn, pop);

        int local = -1;
        for (int i = 0; i < getLocals(); i++) {
            if (getLocal(i) == pop)
                local = i;
        }

        if (local > -1) {
            if (insnOpcode == Opcodes.MONITORENTER) {
                monitorEnter(local);
            } else {
                monitorExit(local);
            }
        }

    } else {
        super.execute(insn, interpreter);
    }
}

From source file:com.friz.instruction.utility.InstructionUtil.java

License:Open Source License

/**
 * Reads the value of a numeric push instruction (which can be an
 * {@code ICONST_*} instruction, an {@code BIPUSH} instruction, an
 * {@code SIPUSH} instruction or a {@code LDC_*} instruction.
 * /*www.  j  av  a  2  s  .c  o  m*/
 * @param push
 *            The instruction node.
 * @return The numeric value.
 */
public static Number getNumericPush(AbstractInsnNode push) {
    if (push instanceof InsnNode) {
        switch (push.getOpcode()) {
        case ICONST_M1:
            return -1;
        case ICONST_0:
            return 0;
        case LCONST_0:
            return 0L;
        case FCONST_0:
            return 0.0F;
        case DCONST_0:
            return 0.0D;
        case ICONST_1:
            return 1;
        case LCONST_1:
            return 1L;
        case FCONST_1:
            return 1.0F;
        case DCONST_1:
            return 1.0D;
        case ICONST_2:
            return 2;
        case FCONST_2:
            return 2.0F;
        case ICONST_3:
            return 3;
        case ICONST_4:
            return 4;
        case ICONST_5:
            return 5;
        default:
            throw new AssertionError(Printer.OPCODES[push.getOpcode()]);
        }
    } else if (push instanceof IntInsnNode) {
        return ((IntInsnNode) push).operand;
    } else {
        return ((Number) ((LdcInsnNode) push).cst);
    }
}

From source file:com.friz.instruction.utility.InstructionUtil.java

License:Open Source License

public static boolean isStaticPush(AbstractInsnNode node) {
    return node.getOpcode() == ACONST_NULL || node.getOpcode() == ICONST_M1 || node.getOpcode() == ICONST_0
            || node.getOpcode() == ICONST_1 || node.getOpcode() == ICONST_2 || node.getOpcode() == ICONST_3
            || node.getOpcode() == ICONST_4 || node.getOpcode() == ICONST_5 || node.getOpcode() == LCONST_0
            || node.getOpcode() == LCONST_1 || node.getOpcode() == FCONST_0 || node.getOpcode() == FCONST_1
            || node.getOpcode() == FCONST_2 || node.getOpcode() == DCONST_0 || node.getOpcode() == DCONST_1
            || node.getOpcode() == BIPUSH || node.getOpcode() == SIPUSH || node.getOpcode() == LDC;
}

From source file:com.friz.instruction.utility.InstructionUtil.java

License:Open Source License

/**
 * Finds the next non-psuedo node following the specified node.
 * //from   w w w .j  ava  2  s  .co m
 * @param node
 *            The node.
 * @return The next non-psuedo node, or {@code null} if the end of the
 *         instruction list is reached.
 */
public static AbstractInsnNode nextNonPsuedoNode(AbstractInsnNode node) {
    while ((node = node.getNext()) != null && node.getOpcode() == -1)
        ;
    return node;
}

From source file:com.friz.instruction.utility.InstructionUtil.java

License:Open Source License

/**
 * Finds the previous non-psuedo node following the specified node.
 * /*from   w  w  w  .j a  va  2  s  .c o  m*/
 * @param node
 *            The node.
 * @return The previous non-psuedo node, or {@code null} if the start of the
 *         instruction list is reached.
 */
public static AbstractInsnNode previousNonPsuedoNode(AbstractInsnNode node) {
    while ((node = node.getPrevious()) != null && node.getOpcode() == -1)
        ;
    return node;
}

From source file:com.friz.instruction.utility.InstructionUtil.java

License:Open Source License

/**
 * Finds the previous non-psuedo node following the specified node.
 * //from  w  w  w  . j  a  v a2 s  . c om
 * @param node
 *            The node.
 * @return The previous non-psuedo node, or {@code null} if the start of the
 *         instruction list is reached.
 */
public static AbstractInsnNode previousNonPsuedoNode(AbstractInsnNode node, int opcode) {
    while ((node = node.getPrevious()) != null && node.getOpcode() == opcode)
        ;
    return node;
}

From source file:com.friz.instruction.utility.InstructionUtil.java

License:Open Source License

/**
 * Finds the next psuedo node following the specified node.
 * /*from  ww w  .  j a  va  2  s  .  c  o  m*/
 * @param node
 *            The node.
 * @return The next psuedo node, or {@code null} if the end of the
 *         instruction list is reached.
 */
public static AbstractInsnNode nextPsuedoNode(AbstractInsnNode node) {
    while ((node = node.getNext()) != null && node.getOpcode() != -1)
        ;
    return node;
}