List of usage examples for org.objectweb.asm.tree InsnList remove
public void remove(final AbstractInsnNode insnNode)
From source file:com.android.builder.testing.MockableJarGenerator.java
License:Apache License
/** * Rewrites the method bytecode to remove the "Stub!" exception. */// ww w . ja v a 2 s . c om private void fixMethodBody(MethodNode methodNode, ClassNode classNode) { if ((methodNode.access & Opcodes.ACC_NATIVE) != 0 || (methodNode.access & Opcodes.ACC_ABSTRACT) != 0) { // Abstract and native method don't have bodies to rewrite. return; } if ((classNode.access & Opcodes.ACC_ENUM) != 0 && ENUM_METHODS.contains(methodNode.name)) { // Don't break enum classes. return; } Type returnType = Type.getReturnType(methodNode.desc); InsnList instructions = methodNode.instructions; if (methodNode.name.equals(CONSTRUCTOR)) { // Keep the call to parent constructor, delete the exception after that. boolean deadCode = false; for (AbstractInsnNode instruction : instructions.toArray()) { if (!deadCode) { if (instruction.getOpcode() == Opcodes.INVOKESPECIAL) { instructions.insert(instruction, new InsnNode(Opcodes.RETURN)); // Start removing all following instructions. deadCode = true; } } else { instructions.remove(instruction); } } } else { instructions.clear(); if (returnDefaultValues || methodNode.name.equals(CLASS_CONSTRUCTOR)) { if (INTEGER_LIKE_TYPES.contains(returnType)) { instructions.add(new InsnNode(Opcodes.ICONST_0)); } else if (returnType.equals(Type.LONG_TYPE)) { instructions.add(new InsnNode(Opcodes.LCONST_0)); } else if (returnType.equals(Type.FLOAT_TYPE)) { instructions.add(new InsnNode(Opcodes.FCONST_0)); } else if (returnType.equals(Type.DOUBLE_TYPE)) { instructions.add(new InsnNode(Opcodes.DCONST_0)); } else { instructions.add(new InsnNode(Opcodes.ACONST_NULL)); } instructions.add(new InsnNode(returnType.getOpcode(Opcodes.IRETURN))); } else { instructions.insert(throwExceptionsList(methodNode, classNode)); } } }
From source file:com.github.antag99.retinazer.weaver.SystemProcessor.java
License:Open Source License
private void processMethod(MethodNode methodNode) { InsnList insns = methodNode.instructions; // Filter out debugging nodes/labels int count = 0; int maxCount = insns.size(); AbstractInsnNode[] nodes = new AbstractInsnNode[maxCount]; for (AbstractInsnNode node = insns.getFirst(); node != null; node = node.getNext()) if (node.getOpcode() > 0) nodes[count++] = node;/* w w w . ja va 2 s . c o m*/ // Find mapper get() calls and create an own flyweight instance for each for (int i = 0; i <= count - 4; i++) { if (!(nodes[i + 0] instanceof VarInsnNode)) continue; if (!(nodes[i + 1] instanceof FieldInsnNode)) continue; if (!(nodes[i + 2] instanceof VarInsnNode)) continue; if (!(nodes[i + 3] instanceof MethodInsnNode)) continue; VarInsnNode loadThis = (VarInsnNode) nodes[i + 0]; FieldInsnNode getField = (FieldInsnNode) nodes[i + 1]; VarInsnNode loadEntity = (VarInsnNode) nodes[i + 2]; MethodInsnNode getMethod = (MethodInsnNode) nodes[i + 3]; if (loadThis.var != 0 || loadThis.getOpcode() != ALOAD) continue; if (!getField.owner.equals(metadata.internalName) || !getField.desc.equals("L" + WeaverConstants.MAPPER_NAME + ";") || !metadata.mappersByName.containsKey(getField.name)) continue; if (loadEntity.getOpcode() != ILOAD) continue; if (!getMethod.owner.equals(WeaverConstants.MAPPER_NAME) || !getMethod.desc.equals("(I)L" + WeaverConstants.COMPONENT_NAME + ";") || !getMethod.name.equals("get")) continue; SystemMapper mapper = metadata.mappersByName.get(getField.name); // Add field to hold the flyweight String fieldName = "flyweight$" + flyweightFields.size(); String fieldDesc = mapper.componentType.getDescriptor(); FieldNode fieldNode = new FieldNode(ACC_PRIVATE, fieldName, fieldDesc, null, null); fieldNode.visitAnnotation("Lcom/github/antag99/retinazer/SkipWire;", true); FlyweightField flyweightField = new FlyweightField(); flyweightField.fieldNode = fieldNode; flyweightField.mapper = mapper; flyweightFields.add(flyweightField); // Rewrite access to use the flyweight getField.owner = metadata.internalName; getField.name = fieldName; getField.desc = fieldDesc; insns.insert(getField, new InsnNode(DUP)); insns.insert(loadEntity, new FieldInsnNode(PUTFIELD, mapper.componentType.getInternalName(), WeaverConstants.INDEX_FIELD_NAME, WeaverConstants.INDEX_FIELD_DESC)); insns.remove(getMethod); } }
From source file:com.triage.bytecodemaster.TestObjectReferenceSwitches.java
@Test public void testInjectingIntoMethodWithLotsOfParameters() throws Exception { final String FIELDPROXYWORKED = "FIELDPROXYWORKED"; //set up the proxy object. this is the object that will receive //the proxied calls TestSubClass tcc = new TestSubClass(); tcc.setBaseString(FIELDPROXYWORKED); TestBaseClassHolder.setTestBase(tcc); //get the dynamic source that has the donor body in it ClassNode donorSource = loadGroovyTestClassAsBytecode(GROOVY_CLASS_FIELDREF2); MethodNode donorMethod = findMethod(donorSource, "before_whatDoIThinkAbout"); System.out.println("Donor Method Before Modifications:"); printMethodNode(donorMethod);/*from w w w. j a v a 2s. c o m*/ String TARGETCLASSNAME = "com.triage.bytecodemaster.fortesting.Concatenator"; ClassNode targetSource = loadLocalClass(TARGETCLASSNAME); ClassNode exampleSource = loadLocalClass("com.triage.bytecodemaster.fortesting.JustLikeGroovyClass"); MethodNode exampleMethod = findMethod(exampleSource, "before_whatDoIThinkAbout"); System.out.println("Example Method-- Should be just like the Donor Source"); printMethodNode(exampleMethod); MethodNode targetMethod = findMethod(targetSource, "concat"); System.out.println("Target Method <Before Mods>"); printMethodNode(targetMethod); //alright here's the strategy: (1) inject a new local variable that points // to our remote instance, // (2) inject code that sets this local to the value of a method call, // (3) change references to 'this' ( ALOAD0 or ALOAD 0 ) to ALOAD1 InsnList instructionsToInject = donorMethod.instructions; InsnList targetInstructions = targetMethod.instructions; //make a new local variable in the donor method. //this variable needs to have a slot high enough that it doesnt //conflict with either the target or the source method //it will hold references to the objects we replace with 'this' LabelNode begin = new LabelNode(); LabelNode end = new LabelNode(); targetInstructions.insertBefore(targetInstructions.getFirst(), begin); targetInstructions.add(end); Type type = Type.getObjectType("com/triage/bytecodemaster/fortesting/TestBaseClass"); int variableIndex = targetMethod.maxLocals; targetMethod.maxLocals += type.getSize(); targetMethod.visitLocalVariable("proxy", type.getDescriptor(), null, begin.getLabel(), end.getLabel(), variableIndex); //set the value of the local variable with a new instruction at the top //fetch a reference to our proxy object MethodInsnNode getTestBase = new MethodInsnNode(Opcodes.INVOKESTATIC, "com/triage/bytecodemaster/fortesting/TestBaseClassHolder", "getTestBase", "()Lcom/triage/bytecodemaster/fortesting/TestBaseClass;"); //insert after begin label targetInstructions.insert(begin, getTestBase); //store reference VarInsnNode setRef = new VarInsnNode(Opcodes.ASTORE, variableIndex); //insert store after fetch targetInstructions.insert(getTestBase, setRef); //replace all references to 'this' in the DONOR method with the new variable //in the TARGET code for (int currentIndex = 0; currentIndex < instructionsToInject.size(); currentIndex++) { AbstractInsnNode node = instructionsToInject.get(currentIndex); if (node.getOpcode() == Opcodes.ALOAD) { VarInsnNode vin = (VarInsnNode) node; //'this' is var index 0. ours is var index varindex if (vin.var == 0) { vin.var = variableIndex; } } //remove return methods. this will prevent a return. it should cause the donor //method to have parameters that overlap with the target, which has more parameters if (node.getOpcode() == Opcodes.RETURN || node.getOpcode() == Opcodes.ARETURN) { instructionsToInject.remove(node); } } System.out.println(">>>>>>>>>Finished Modifying Donor Method <<<<<<<<"); printMethodNode(donorMethod); String NEWCLASSNAME = "ScriptTestClass"; //stash instructions at the beginning of the original method, //but after populating the new variable targetInstructions.insert(setRef, instructionsToInject); System.out.println("Modified Target:"); printMethodNode(targetMethod); //write a class Class c = createClassFromClassNode(targetSource, TARGETCLASSNAME); Object o = c.newInstance(); Method m = o.getClass().getDeclaredMethod("concat", String.class, String.class, String.class, String.class); //should return HAHAHA not baseStringValue String result = (String) m.invoke(o, new Object[] { "A", "B", "C", "D" }); System.out.println("Concatenator.concat Result: " + result); assertTrue(result.equals("ABCD")); }
From source file:com.typesafe.path_hole.PathHole.java
License:Open Source License
private static byte[] prependToClassLoader() { Object[] ourEnhancementsToLoadClass = getMethodNode(PathHole.class, "bytecodeToPrepend", "(Ljava/lang/String;Z)V"); Object[] jlClassLoader = getMethodNode(ClassLoader.class, "loadClass", "(Ljava/lang/String;Z)Ljava/lang/Class;"); // get the bytecode to prepend InsnList prependInst = ((MethodNode) ourEnhancementsToLoadClass[1]).instructions; // lets get rid of the return statement // remove the optional label if (prependInst.getLast().getOpcode() < 0) { prependInst.remove(prependInst.getLast()); }/* ww w.j ava 2s .c o m*/ // remove the return inst. It doesn't take any args so this is all we need prependInst.remove(prependInst.getLast()); // now add this to loadClass method of jlClassLoader InsnList baseInst = ((MethodNode) jlClassLoader[1]).instructions; baseInst.insertBefore(baseInst.getFirst(), prependInst); ClassNode clClassNode = (ClassNode) jlClassLoader[0]; // we just need to add any fields referenced by the prepended bytecode to the jlClassLoader // ClassNode prependClassNode = (ClassNode) ourEnhancementsToLoadClass[0]; // write the new bytecode ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS | ClassWriter.COMPUTE_FRAMES); clClassNode.accept(cw); return cw.toByteArray(); }
From source file:de.tuberlin.uebb.jbop.optimizer.arithmetic.ArithmeticExpressionInterpreter.java
License:Open Source License
private void clean(final InsnList original, final Iterator<AbstractInsnNode> iterator, final AbstractInsnNode currentNode, final AbstractInsnNode numberNode, final AbstractInsnNode castNode1, final AbstractInsnNode castNode2, final AbstractInsnNode op) { if (castNode1 != null) { iterator.next();// --> castNode1 }//from w ww .ja v a 2 s. c o m iterator.next();// --> numberNode if (castNode2 != null) { iterator.next();// --> castNode2 } iterator.next();// --> op original.remove(currentNode); if (castNode1 != null) { original.remove(castNode1); } original.remove(numberNode); if (castNode2 != null) { original.remove(castNode2); } original.remove(op); }
From source file:de.tuberlin.uebb.jbop.optimizer.array.FieldArrayLengthInliner.java
License:Open Source License
@Override public InsnList optimize(final InsnList original, final MethodNode method) throws JBOPClassException { optimized = false;// w w w . jav a 2s .c o m final ListIterator<AbstractInsnNode> iterator = original.iterator(); final ArrayHelper arrayHelper = new ArrayHelper(); while (iterator.hasNext()) { final AbstractInsnNode aload = iterator.next(); if (!arrayHelper.isArrayInstruction(classNode, aload, null)) { continue; } if (!arrayHelper.isArrayLength()) { continue; } final GetFieldChainInliner fieldChainInliner = new GetFieldChainInliner(); fieldChainInliner.setIterator(iterator); fieldChainInliner.setInputObject(instance); fieldChainInliner.optimize(original, null); if (fieldChainInliner.isOptimized()) { optimized = true; original.remove(aload); } } return original; }
From source file:de.tuberlin.uebb.jbop.optimizer.array.FieldArrayValueInliner.java
License:Open Source License
private void replaceNodes(final InsnList newList, final AbstractInsnNode aload, final ArrayHelper arrayHelper, final AbstractInsnNode replacementNode, final ListIterator<AbstractInsnNode> iterator) { if (replacementNode != null) { newList.insert(arrayHelper.getLastLoad(), replacementNode); }// w w w. ja v a2 s . c o m newList.remove(aload); for (final AbstractInsnNode node : arrayHelper.getIndexes()) { newList.remove(node); } for (final AbstractInsnNode node : arrayHelper.getArrayloads()) { newList.remove(node); } if (replacementNode != null) { iterator.next(); } newList.remove(arrayHelper.getFieldNode()); optimized = true; }
From source file:de.tuberlin.uebb.jbop.optimizer.array.LocalArrayLengthInliner.java
License:Open Source License
@Override protected boolean handleValues(final InsnList original, final Map<Integer, Object> knownArrays, final AbstractInsnNode currentNode) { if (!NodeHelper.isArrayLength(currentNode)) { return false; }/* w w w . ja va2 s .c o m*/ AbstractInsnNode previous = NodeHelper.getPrevious(currentNode); final List<AbstractInsnNode> toBeRemoved = new ArrayList<>(); int index2 = 0; while ((previous != null) && !NodeHelper.isAload(previous)) { if (NodeHelper.isAAload(previous)) { index2 += 1; } toBeRemoved.add(previous); previous = NodeHelper.getPrevious(previous); } final int index; if ((previous != null) && NodeHelper.isAload(previous)) { toBeRemoved.add(previous); index = ((VarInsnNode) previous).var; } else { return false; } final Object array = knownArrays.get(Integer.valueOf(index)); if ((array == null)) { return false; } Object array2 = array; for (int i = 0; i < index2; ++i) { array2 = Array.get(array2, i); } final int arrayLength = Array.getLength(array2); original.insertBefore(currentNode, NodeHelper.getInsnNodeFor(arrayLength)); for (final AbstractInsnNode remove : toBeRemoved) { original.remove(remove); } original.remove(currentNode); return true; }
From source file:de.tuberlin.uebb.jbop.optimizer.array.LocalArrayValueInliner.java
License:Open Source License
@Override protected boolean handleValues(final InsnList original, final Map<Integer, Object> knownArrays, final AbstractInsnNode currentNode) { AbstractInsnNode arrayload = currentNode; AbstractInsnNode indexNode;/*from ww w .jav a2s . co m*/ final List<AbstractInsnNode> arrayloads = new ArrayList<>(); final List<AbstractInsnNode> indexes = new ArrayList<>(); do { if (!Predicates.IS_XALOAD.evaluate(arrayload)) { return false; } arrayloads.add(arrayload); indexNode = NodeHelper.getPrevious(arrayload); if (!NodeHelper.isNumberNode(indexNode)) { return false; } indexes.add(indexNode); arrayload = NodeHelper.getPrevious(indexNode); if (arrayload instanceof VarInsnNode) { break; } } while (true); final VarInsnNode previous2 = (VarInsnNode) arrayload; final Integer varIndex = Integer.valueOf(previous2.var); Object array = knownArrays.get(varIndex); if (array == null) { return false; } for (int i = indexes.size() - 1; i >= 0; --i) { final int indexInArray = NodeHelper.getNumberValue(indexes.get(i)).intValue(); array = Array.get(array, indexInArray); } if (!(array instanceof Number)) { return false; } final AbstractInsnNode replacement = NodeHelper.getInsnNodeFor((Number) array); original.insertBefore(previous2, replacement); for (int i = 0; i < indexes.size(); ++i) { original.remove(indexes.get(i)); original.remove(arrayloads.get(i)); } original.remove(previous2); return true; }
From source file:de.tuberlin.uebb.jbop.optimizer.controlflow.ConstantIfInliner.java
License:Open Source License
private boolean handleNullInstruction(final AbstractInsnNode currentNode, final AbstractInsnNode node1, final InsnList list, final Iterator<AbstractInsnNode> iterator) throws JBOPClassException { if ((currentNode.getOpcode() == Opcodes.IFNULL) || (currentNode.getOpcode() == Opcodes.IFNONNULL)) { final boolean eval; if (node1.getOpcode() == Opcodes.ACONST_NULL) { if (!checkNullInstruction(node1, currentNode, list, iterator)) { return false; }/*w w w. j a v a 2 s . c om*/ eval = evalSingleOpValue(null, currentNode.getOpcode()); } else { final AbstractInsnNode node2 = NodeHelper.getPrevious(node1); if (!checkNumberInstruction(node1, node2, currentNode, list, iterator)) { return false; } // doesn't work for multiarrays yet final AbstractInsnNode node3 = NodeHelper.getPrevious(node2); final AbstractInsnNode node4 = NodeHelper.getPrevious(node3); boolean isNonNullArrayValue = false; if (arrayValue != null) { for (final NonNullArrayValue nonNullarrayValue : arrayValue.getNonNullArrayValues()) { if (nonNullarrayValue.is(node4, node3, Arrays.asList(node2), Arrays.asList(node1))) { isNonNullArrayValue = true; break; } } } if (!isNonNullArrayValue) { return false; } if (node2 != null) { list.remove(node2); } if (node3 != null) { list.remove(node3); } if (node4 != null) { list.remove(node4); } eval = evalSingleOpValue(NONNULL, currentNode.getOpcode()); } removeNodes(currentNode, node1, null, null, list, iterator, eval); return true; } return false; }