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:org.apache.flink.api.java.sca.NestedMethodAnalyzer.java

License:Apache License

@Override
public BasicValue binaryOperation(AbstractInsnNode insn, BasicValue value1, BasicValue value2)
        throws AnalyzerException {
    switch (insn.getOpcode()) {
    case PUTFIELD: // put value2 into value1
        // skip untagged values
        if (!isTagged(value1)) {
            return null;
        }// ww w  . j a v a2  s. co  m

        final TaggedValue taggedValue = (TaggedValue) value1;
        final FieldInsnNode field = (FieldInsnNode) insn;
        final boolean value2HasInputDependency = hasImportantDependencies(value2);

        // if value1 is not an input, make value1 a container and add value2 to it
        // PUTFIELD on inputs is not allowed
        if (!taggedValue.isInput() && value2HasInputDependency) {
            if (!taggedValue.canContainFields()) {
                taggedValue.setTag(Tag.CONTAINER);
            }
            taggedValue.addContainerMapping(field.name, tagged(value2), currentFrame);
        }
        // if value1 is filled with non-input, make it container and mark the field
        // PUTFIELD on inputs is not allowed
        else if (!taggedValue.isInput() && !value2HasInputDependency) {
            if (!taggedValue.canContainFields()) {
                taggedValue.setTag(Tag.CONTAINER);
            }
            taggedValue.addContainerMapping(field.name, null, currentFrame);
        }
        // PUTFIELD on input leads to input modification
        // make input regular
        else if (taggedValue.isInput()) {
            taggedValue.makeRegular();
        }
        return null;
    default:
        return super.binaryOperation(insn, value1, value2);
    }
}

From source file:org.apache.flink.api.java.sca.NestedMethodAnalyzer.java

License:Apache License

@SuppressWarnings({ "rawtypes", "unchecked" })
@Override/*from   ww  w  . ja  v a2 s.com*/
public BasicValue naryOperation(AbstractInsnNode insn, List rawValues) throws AnalyzerException {
    final List<BasicValue> values = (List<BasicValue>) rawValues;
    boolean isStatic = false;
    switch (insn.getOpcode()) {
    case INVOKESTATIC:
        isStatic = true;
    case INVOKESPECIAL:
    case INVOKEVIRTUAL:
    case INVOKEINTERFACE:
        final MethodInsnNode method = (MethodInsnNode) insn;
        String methodOwner = method.owner;

        // special case: in case that class is extending tuple we need to find the class
        // that contains the actual implementation to determine the tuple size
        if (method.name.equals("getField") || method.name.equals("setField")) {
            try {
                final String newMethodOwner = (String) findMethodNode(methodOwner, method.name, method.desc)[1];
                if (newMethodOwner.startsWith("org/apache/flink/api/java/tuple/Tuple")) {
                    methodOwner = newMethodOwner;
                }
            } catch (IllegalStateException e) {
                // proceed with the known method owner
            }
        }

        // special case: collect method of Collector
        if (method.name.equals("collect") && methodOwner.equals("org/apache/flink/util/Collector")
                && isTagged(values.get(0)) && tagged(values.get(0)).isCollector()) {
            // check for invalid return value
            if (isTagged(values.get(1)) && tagged(values.get(1)).isNull()) {
                analyzer.handleNullReturn();
            }
            // valid return value with input dependencies
            else if (hasImportantDependencies(values.get(1))) {
                // add a copy and a reference
                // to capture the current state and future changes in alternative paths
                analyzer.getCollectorValues().add(tagged(values.get(1)));
                analyzer.getCollectorValues().add(tagged(values.get(1)).copy());
            }
            // valid return value without input dependencies
            else {
                analyzer.getCollectorValues().add(null);
            }
        }
        // special case: iterator method of Iterable
        else if (method.name.equals("iterator") && methodOwner.equals("java/lang/Iterable")
                && isTagged(values.get(0)) && tagged(values.get(0)).isInputIterable()) {
            return new TaggedValue(Type.getObjectType("java/util/Iterator"),
                    (tagged(values.get(0)).isInput1Iterable()) ? Tag.INPUT_1_ITERATOR : Tag.INPUT_2_ITERATOR);
        }
        // special case: hasNext method of Iterator
        else if (method.name.equals("hasNext") && methodOwner.equals("java/util/Iterator")
                && isTagged(values.get(0)) && tagged(values.get(0)).isInputIterator() && !analyzer.isUdfBinary()
                && !analyzer.isIteratorTrueAssumptionApplied()) {
            return new TaggedValue(Type.BOOLEAN_TYPE, Tag.ITERATOR_TRUE_ASSUMPTION);
        }
        // special case: next method of Iterator
        else if (method.name.equals("next") && methodOwner.equals("java/util/Iterator")
                && isTagged(values.get(0)) && tagged(values.get(0)).isInputIterator()) {
            // after this call it is not possible to assume "TRUE" of "hasNext()" again
            analyzer.applyIteratorTrueAssumption();
            if (tagged(values.get(0)).isInput1Iterator()) {
                return analyzer.getInput1AsTaggedValue();
            } else {
                return analyzer.getInput2AsTaggedValue();
            }
        }
        // if the UDF class contains instance variables that contain input,
        // we need to analyze also methods without input-dependent arguments
        // special case: do not follow the getRuntimeContext method of RichFunctions
        else if (!isStatic && isTagged(values.get(0)) && tagged(values.get(0)).isThis()
                && hasImportantDependencies(values.get(0)) && !isGetRuntimeContext(method)) {
            TaggedValue tv = invokeNestedMethod(values, method);
            if (tv != null) {
                return tv;
            }
        }
        // the arguments have input dependencies ("THIS" does not count to the arguments)
        // we can assume that method has at least one argument
        else if ((!isStatic && isTagged(values.get(0)) && tagged(values.get(0)).isThis()
                && hasImportantDependencies(values, true))
                || (!isStatic && (!isTagged(values.get(0)) || !tagged(values.get(0)).isThis())
                        && hasImportantDependencies(values, false))
                || (isStatic && hasImportantDependencies(values, false))) {
            // special case: Java unboxing/boxing methods on input
            Type newType;
            if (isTagged(values.get(0)) && tagged(values.get(0)).isInput()
                    && (!isStatic && (newType = checkForUnboxing(method.name, methodOwner)) != null || (isStatic
                            && (newType = checkForBoxing(method.name, method.desc, methodOwner)) != null))) {
                return tagged(values.get(0)).copy(newType);
            }
            // special case: setField method of TupleXX
            else if (method.name.equals("setField")
                    && methodOwner.startsWith("org/apache/flink/api/java/tuple/Tuple")
                    && isTagged(values.get(0))) {
                final TaggedValue tuple = tagged(values.get(0));
                tuple.setTag(Tag.CONTAINER);

                // check if fieldPos is constant
                // if not, we can not determine a state for the tuple
                if (!isTagged(values.get(2)) || !tagged(values.get(2)).isIntConstant()) {
                    tuple.makeRegular();
                } else {
                    final int constant = tagged(values.get(2)).getIntConstant();

                    if (constant < 0 || Integer.valueOf(methodOwner.split("Tuple")[1]) <= constant) {
                        analyzer.handleInvalidTupleAccess();
                    }

                    // if it is at least tagged, add it anyways
                    if (isTagged(values.get(1))) {
                        tuple.addContainerMapping("f" + constant, tagged(values.get(1)), currentFrame);
                    }
                    // mark the field as it has an undefined state
                    else {
                        tuple.addContainerMapping("f" + constant, null, currentFrame);
                    }
                }
            }
            // special case: getField method of TupleXX
            else if (method.name.equals("getField")
                    && methodOwner.startsWith("org/apache/flink/api/java/tuple/Tuple")) {
                final TaggedValue tuple = tagged(values.get(0)); // we can assume that 0 is an input dependent tuple
                // constant field index
                if (isTagged(values.get(1)) // constant
                        && tagged(values.get(1)).isIntConstant()) {
                    final int constant = tagged(values.get(1)).getIntConstant();

                    if (constant < 0 || Integer.valueOf(methodOwner.split("Tuple")[1]) <= constant) {
                        analyzer.handleInvalidTupleAccess();
                    }

                    if (tuple.containerContains("f" + constant)) {
                        final TaggedValue tupleField = tuple.getContainerMapping().get("f" + constant);
                        if (tupleField != null) {
                            return tupleField;
                        }
                    }
                }
                // unknown field index
                else {
                    // we need to make the tuple regular as we cannot track modifications of fields
                    tuple.makeRegular();
                    return new TaggedValue(Type.getObjectType("java/lang/Object"));
                }
            }
            // nested method invocation
            else {
                TaggedValue tv = invokeNestedMethod(values, method);
                if (tv != null) {
                    return tv;
                }
            }
        }
        return super.naryOperation(insn, values);
    default:
        // TODO support for INVOKEDYNAMIC instructions
        return super.naryOperation(insn, values);
    }
}

From source file:org.blockartistry.DynSurround.asm.Transformer.java

License:MIT License

private byte[] transformSoundManager(final byte[] classBytes) {
    final String managerToReplace = "net/minecraft/client/audio/SoundManager";
    final String newManager = "org/blockartistry/DynSurround/client/sound/SoundManagerReplacement";

    final ClassReader cr = new ClassReader(classBytes);
    final ClassNode cn = new ClassNode(ASM5);
    cr.accept(cn, 0);// www  . ja  va  2 s . co  m

    for (final MethodNode m : cn.methods) {
        final ListIterator<AbstractInsnNode> itr = m.instructions.iterator();
        boolean foundNew = false;
        while (itr.hasNext()) {
            final AbstractInsnNode node = itr.next();
            if (node.getOpcode() == NEW) {
                final TypeInsnNode theNew = (TypeInsnNode) node;
                if (managerToReplace.equals(theNew.desc)) {
                    m.instructions.set(node, new TypeInsnNode(NEW, newManager));
                    foundNew = true;
                }
            } else if (node.getOpcode() == INVOKESPECIAL) {
                final MethodInsnNode theInvoke = (MethodInsnNode) node;
                if (managerToReplace.equals(theInvoke.owner)) {
                    if (foundNew) {
                        m.instructions.set(node, new MethodInsnNode(INVOKESPECIAL, newManager, theInvoke.name,
                                theInvoke.desc, false));
                        foundNew = false;
                    }
                }
            }
        }
    }

    final ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS);
    cn.accept(cw);
    return cw.toByteArray();
}

From source file:org.blockartistry.DynSurround.asm.Transformer.java

License:MIT License

private byte[] replaceRandom(final String name, final byte[] classBytes) {

    final String randomToReplace = "java/util/Random";
    final String newRandom = "org/blockartistry/lib/random/XorShiftRandom";

    boolean madeUpdate = false;

    final ClassReader cr = new ClassReader(classBytes);
    final ClassNode cn = new ClassNode(ASM5);
    cr.accept(cn, 0);/* ww w .j  a  v  a 2  s. c  o  m*/

    for (final MethodNode m : cn.methods) {
        final ListIterator<AbstractInsnNode> itr = m.instructions.iterator();
        boolean foundNew = false;
        while (itr.hasNext()) {
            final AbstractInsnNode node = itr.next();
            if (node.getOpcode() == NEW) {
                final TypeInsnNode theNew = (TypeInsnNode) node;
                if (randomToReplace.equals(theNew.desc)) {
                    m.instructions.set(node, new TypeInsnNode(NEW, newRandom));
                    madeUpdate = true;
                    foundNew = true;
                }
            } else if (node.getOpcode() == INVOKESPECIAL) {
                final MethodInsnNode theInvoke = (MethodInsnNode) node;
                if (randomToReplace.equals(theInvoke.owner)) {
                    if (foundNew) {
                        m.instructions.set(node, new MethodInsnNode(INVOKESPECIAL, newRandom, theInvoke.name,
                                theInvoke.desc, false));
                        foundNew = false;
                    }
                }
            }
        }
    }

    if (madeUpdate) {
        logger.debug("Replaced Random in " + name);
        ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS);
        cn.accept(cw);
        return cw.toByteArray();
    }
    return classBytes;
}

From source file:org.blockartistry.mod.Jiffy.asm.Transformer.java

License:MIT License

private byte[] replaceRandom(final String name, final byte[] classBytes) {

    final String randomToReplace = "java/util/Random";
    final String newRandom = "org/blockartistry/util/XorShiftRandom";

    boolean madeUpdate = false;

    final ClassReader cr = new ClassReader(classBytes);
    final ClassNode cn = new ClassNode(ASM5);
    cr.accept(cn, 0);/* w  w  w .j av  a 2 s.c  om*/

    for (final MethodNode m : cn.methods) {
        final ListIterator<AbstractInsnNode> itr = m.instructions.iterator();
        boolean foundNew = false;
        while (itr.hasNext()) {
            final AbstractInsnNode node = itr.next();
            if (node.getOpcode() == NEW) {
                final TypeInsnNode theNew = (TypeInsnNode) node;
                if (randomToReplace.equals(theNew.desc)) {
                    m.instructions.set(node, new TypeInsnNode(NEW, newRandom));
                    madeUpdate = true;
                    foundNew = true;
                }
            } else if (node.getOpcode() == INVOKESPECIAL) {
                final MethodInsnNode theInvoke = (MethodInsnNode) node;
                if (randomToReplace.equals(theInvoke.owner)) {
                    if (foundNew) {
                        m.instructions.set(node, new MethodInsnNode(INVOKESPECIAL, newRandom, theInvoke.name,
                                theInvoke.desc, false));
                        foundNew = false;
                    }
                }
            }
        }
    }

    if (madeUpdate) {
        logger.debug("Replaced Random in " + name);
        ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS);
        cn.accept(cw);
        return cw.toByteArray();
    }
    return classBytes;
}

From source file:org.blockartistry.mod.Jiffy.asm.Transformer.java

License:MIT License

private byte[] replaceMath(final String name, final byte[] classBytes) {

    boolean madeUpdate = false;

    final ClassReader cr = new ClassReader(classBytes);
    final ClassNode cn = new ClassNode(ASM5);
    cr.accept(cn, 0);/*from  ww w. j  a v  a  2 s . c  o  m*/

    for (final MethodNode m : cn.methods) {
        final ListIterator<AbstractInsnNode> itr = m.instructions.iterator();
        while (itr.hasNext()) {
            final AbstractInsnNode node = itr.next();
            if (node.getOpcode() == INVOKESTATIC) {
                final MethodInsnNode theInvoke = (MethodInsnNode) node;
                if ("java/lang/Math".equals(theInvoke.owner)) {
                    if ("sin".equals(theInvoke.name) || "cos".equals(theInvoke.name)
                            || "random".equals(theInvoke.name)) {
                        madeUpdate = true;
                        m.instructions.set(node, new MethodInsnNode(INVOKESTATIC,
                                "org/blockartistry/util/MathHelper", theInvoke.name, theInvoke.desc, false));
                    }
                }
            }
        }
    }

    if (madeUpdate) {
        logger.debug("Replaced Math in " + name);
        ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS);
        cn.accept(cw);
        return cw.toByteArray();
    }
    return classBytes;
}

From source file:org.brutusin.instrumentation.Instrumentator.java

License:Apache License

private void addTraceReturn() {

    InsnList il = this.mn.instructions;

    Iterator<AbstractInsnNode> it = il.iterator();
    while (it.hasNext()) {
        AbstractInsnNode abstractInsnNode = it.next();

        switch (abstractInsnNode.getOpcode()) {
        case Opcodes.RETURN:
            il.insertBefore(abstractInsnNode, getVoidReturnTraceInstructions());
            break;
        case Opcodes.IRETURN:
        case Opcodes.LRETURN:
        case Opcodes.FRETURN:
        case Opcodes.ARETURN:
        case Opcodes.DRETURN:
            il.insertBefore(abstractInsnNode, getReturnTraceInstructions());
        }/*from   w  w w.  j  a v a2s . com*/
    }
}

From source file:org.brutusin.instrumentation.Instrumentator.java

License:Apache License

private void addTraceThrow() {

    InsnList il = this.mn.instructions;

    Iterator<AbstractInsnNode> it = il.iterator();
    while (it.hasNext()) {
        AbstractInsnNode abstractInsnNode = it.next();

        switch (abstractInsnNode.getOpcode()) {
        case Opcodes.ATHROW:
            il.insertBefore(abstractInsnNode, getThrowTraceInstructions());
            break;
        }/* ww  w  .  java 2  s.c om*/
    }

}

From source file:org.coldswap.asm.field.PrivateStaticFieldReplacer.java

License:Open Source License

/**
 * Removes any initializing reference of the field.
 *
 * @param classNode containing the old class.
 * @param fieldNode containing the old field.
 * @return the initializing list of instructions.
 *//*www  . j a v a2  s.co  m*/
@SuppressWarnings("unchecked")
private InsnList cleanClInit(ClassNode classNode, FieldNode fieldNode) {
    List<MethodNode> methodNodes = classNode.methods;
    AbstractInsnNode firstInst = null;
    int counter = 0;
    for (MethodNode methodNode : methodNodes) {
        if (methodNode.name.equals("<clinit>")) {
            // search for PUTSTATIC
            InsnList insnList = methodNode.instructions;
            Iterator iterator1 = insnList.iterator();
            while (iterator1.hasNext()) {
                AbstractInsnNode ins2 = (AbstractInsnNode) iterator1.next();
                // if a initializing has been found, then copy everything from
                // the corresponding label to the PUTSTATIC
                if (ins2.getOpcode() == Opcodes.PUTSTATIC) {
                    final Boolean[] fieldFound = { false };
                    final FieldNode fNode = fieldNode;
                    ins2.accept(new MethodVisitor(Opcodes.ASM5) {
                        @Override
                        public void visitFieldInsn(int i, String s, String s2, String s3) {
                            if (s2.equals(fNode.name)) {
                                fieldFound[0] = true;
                            }
                            super.visitFieldInsn(i, s, s2, s3);
                        }
                    });
                    if (fieldFound[0]) {
                        // find the first PUTSTATIC before this one.
                        boolean staticFound = false;
                        while (!staticFound) {
                            AbstractInsnNode tmpInst = ins2.getPrevious();
                            if (tmpInst != null) {
                                if (tmpInst.getOpcode() != Opcodes.F_NEW) {
                                    if (tmpInst.getOpcode() == Opcodes.PUTSTATIC) {
                                        staticFound = true;
                                    } else {
                                        firstInst = tmpInst;
                                        counter++;
                                    }
                                }
                            } else {
                                staticFound = true;
                            }
                            ins2 = tmpInst;
                        }

                        break;
                    }
                }
            }

            if (firstInst != null) {
                InsnList iList = new InsnList();
                iList.add(firstInst.clone(null));
                counter--;
                while (counter > 0) {
                    AbstractInsnNode ain = firstInst.getNext();
                    iList.add(ain.clone(null));
                    counter--;
                    insnList.remove(firstInst);
                    firstInst = ain;
                }
                // remove last instruction and the putstatic instruction
                AbstractInsnNode putStatic = firstInst.getNext();
                insnList.remove(firstInst);
                insnList.remove(putStatic);
                return iList;
            }
        }
    }
    return null;
}

From source file:org.coldswap.asm.field.PrivateStaticFieldReplacer.java

License:Open Source License

/**
 * Replaces any GETSTATIC/PUTSTATIC call of the field in the old class with the field
 * introduced in the new class./*from w  w w . j  ava2 s . c o m*/
 *
 * @param classNode containing the old class.
 * @param fieldNode containing the old field.
 */
@SuppressWarnings("unchecked")
private void replaceReferences(ClassNode classNode, FieldNode fieldNode) {
    List<MethodNode> methodNodes = classNode.methods;
    String contClass = classNode.name.substring(classNode.name.lastIndexOf("/") + 1);
    final String className = classPackage
            + TransformerNameGenerator.getPrivateStaticFieldClassName(contClass, fieldNode.name);
    for (MethodNode method : methodNodes) {
        InsnList inst = method.instructions;
        Iterator iter = inst.iterator();
        while (iter.hasNext()) {
            AbstractInsnNode absIns = (AbstractInsnNode) iter.next();
            int opcode = absIns.getOpcode();
            // check if instruction is GETSTATIC or PUTSTATIC
            if (opcode == Opcodes.GETSTATIC) {
                // get type
                if (absIns.getType() == AbstractInsnNode.FIELD_INSN) {
                    final Boolean[] foundField = { false };
                    final ClassNode cNode = classNode;
                    final FieldNode fNode = fieldNode;
                    absIns.accept(new MethodVisitor(Opcodes.ASM5) {
                        @Override
                        public void visitFieldInsn(int i, String s, String s2, String s3) {
                            if (cNode.name.equals(s) && fNode.name.equals(s2)) {
                                foundField[0] = true;
                            }
                            super.visitFieldInsn(i, s, s2, s3);
                        }
                    });
                    if (foundField[0]) {
                        inst.set(absIns, new FieldInsnNode(Opcodes.GETSTATIC, className, fieldNode.name,
                                fieldNode.desc));
                    }
                }
            } else if (opcode == Opcodes.PUTSTATIC) {
                if (absIns.getType() == AbstractInsnNode.FIELD_INSN) {
                    final Boolean[] foundField = { false };
                    final ClassNode cNode = classNode;
                    final FieldNode fNode = fieldNode;
                    absIns.accept(new MethodVisitor(Opcodes.ASM5) {
                        @Override
                        public void visitFieldInsn(int i, String s, String s2, String s3) {
                            if (cNode.name.equals(s) && fNode.name.equals(s2)) {
                                foundField[0] = true;
                            }
                            super.visitFieldInsn(i, s, s2, s3);
                        }
                    });
                    if (foundField[0]) {
                        inst.set(absIns, new FieldInsnNode(Opcodes.PUTSTATIC, className, fieldNode.name,
                                fieldNode.desc));
                    }
                }
            }
        }
    }
}