List of usage examples for org.objectweb.asm.tree AbstractInsnNode getOpcode
public int getOpcode()
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)); } } } } } }