List of usage examples for org.objectweb.asm.tree InsnList insert
public void insert(final AbstractInsnNode previousInsn, final InsnList insnList)
From source file:com.android.builder.testing.MockableJarGenerator.java
License:Apache License
/** * Rewrites the method bytecode to remove the "Stub!" exception. *//*from w w w . j a va 2 s .co m*/ 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;//from w ww. j a v a 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.github.fge.grappa.transform.process.GroupClassGenerator.java
License:Apache License
protected static void insertSetContextCalls(InstructionGroup group, int localVarIx) { InsnList instructions = group.getInstructions(); CodeBlock block = CodeBlock.newCodeBlock(); for (InstructionGraphNode node : group.getNodes()) { if (!node.isCallOnContextAware()) continue; AbstractInsnNode insn = node.getInstruction(); if (node.getPredecessors().size() > 1) { // store the target of the call in a new local variable AbstractInsnNode loadTarget = node.getPredecessors().get(0).getInstruction(); block.clear().dup().astore(++localVarIx); instructions.insert(loadTarget, block.getInstructionList()); // immediately before the call get the target from the local var // and set the context on it instructions.insertBefore(insn, new VarInsnNode(ALOAD, localVarIx)); } else {/*from ww w.jav a2 s .c o m*/ // if we have only one predecessor the call does not take any // parameters and we can skip the storing and loading of the // invocation target instructions.insertBefore(insn, new InsnNode(DUP)); } block.clear().aload(1).invokeinterface(CodegenUtils.p(ContextAware.class), "setContext", CodegenUtils.sig(void.class, Context.class)); instructions.insertBefore(insn, block.getInstructionList()); } }
From source file:com.github.fge.grappa.transform.process.GroupClassGenerator.java
License:Apache License
protected static void convertXLoads(InstructionGroup group) { String owner = group.getGroupClassType().getInternalName(); InsnList insnList; for (InstructionGraphNode node : group.getNodes()) { if (!node.isXLoad()) continue; VarInsnNode insn = (VarInsnNode) node.getInstruction(); FieldNode field = group.getFields().get(insn.var); FieldInsnNode fieldNode = new FieldInsnNode(GETFIELD, owner, field.name, field.desc); insnList = group.getInstructions(); // insert the correct GETFIELD after the xLoad insnList.insert(insn, fieldNode); // change the load to ALOAD 0 insnList.set(insn, new VarInsnNode(ALOAD, 0)); }/*www .ja va 2 s. c o m*/ }
From source file:com.lodgon.parboiled.transform.GroupClassGenerator.java
License:Apache License
protected void insertSetContextCalls(InstructionGroup group, int localVarIx) { InsnList instructions = group.getInstructions(); for (InstructionGraphNode node : group.getNodes()) { if (node.isCallOnContextAware()) { AbstractInsnNode insn = node.getInstruction(); if (node.getPredecessors().size() > 1) { // store the target of the call in a new local variable AbstractInsnNode loadTarget = node.getPredecessors().get(0).getInstruction(); instructions.insert(loadTarget, new VarInsnNode(ASTORE, ++localVarIx)); instructions.insert(loadTarget, new InsnNode(DUP)); // the DUP is inserted BEFORE the ASTORE // immediately before the call get the target from the local var and set the context on it instructions.insertBefore(insn, new VarInsnNode(ALOAD, localVarIx)); } else { // if we have only one predecessor the call does not take any parameters and we can // skip the storing and loading of the invocation target instructions.insertBefore(insn, new InsnNode(DUP)); }//from ww w.ja va 2 s . co m instructions.insertBefore(insn, new VarInsnNode(ALOAD, 1)); instructions.insertBefore(insn, new MethodInsnNode(INVOKEINTERFACE, Types.CONTEXT_AWARE.getInternalName(), "setContext", "(" + Types.CONTEXT_DESC + ")V")); } } }
From source file:com.sun.tdk.jcov.instrument.BlockCodeMethodAdapter.java
License:Open Source License
private void insertInstrumentation() { MethodNode methodNode = (MethodNode) mv; InsnList instructions = methodNode.instructions; for (Map.Entry<AbstractInsnNode, SimpleBasicBlock> entry : insnToBB.entrySet()) { // Basic block 'bb' starts at instruction 'insn' AbstractInsnNode insn = entry.getKey(); SimpleBasicBlock bb = entry.getValue(); // System.out.println("insn = " + insn); instructions.insert(insn, Instrumenter.instrumentation(bb, params.isDetectInternal())); }/*from w ww . jav a 2 s.com*/ }
From source file:com.triage.bytecodemaster.TestObjectReferenceSwitches.java
public void testReplacingThisWithOtherVariable() 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_FIELDREF); MethodNode donorMethod = findMethod(donorSource, "before_whatDoIThinkAbout"); System.out.println("Donor"); printMethodNode(donorMethod);/* ww w . j a va2 s . co m*/ //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; //make a new local variable LabelNode begin = new LabelNode(); LabelNode end = new LabelNode(); instructionsToInject.insertBefore(instructionsToInject.getFirst(), begin); instructionsToInject.add(end); Type type = Type.getObjectType("com/triage/bytecodemaster/fortesting/TestBaseClass"); int variableIndex = donorMethod.maxLocals; donorMethod.maxLocals += type.getSize(); donorMethod.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 instructionsToInject.insert(begin, getTestBase); //store reference VarInsnNode setRef = new VarInsnNode(Opcodes.ASTORE, variableIndex); //insert store after fetch instructionsToInject.insert(getTestBase, setRef); //replace all references to 'this' with the new variable 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; } } } System.out.println(">>>>>>>>>Finished Modifying<<<<<<<<"); printMethodNode(donorMethod); String NEWCLASSNAME = "ScriptTestClass"; //write a class Class c = createClassFromClassNode(donorSource, NEWCLASSNAME); Object o = c.newInstance(); Method m = o.getClass().getDeclaredMethod("before_whatDoIThinkAbout", String.class); //should return HAHAHA not baseStringValue String result = (String) m.invoke(o, new Object[] { "AAAA" }); System.out.println("TestDonorClass.whatDoIThinkAbout Result: " + result); assertTrue(result.equals(FIELDPROXYWORKED + "AAAA")); }
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);/* ww w . j a v a2 s . c om*/ 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.triage.bytecodemaster.TestObjectReferenceSwitches.java
public void testMergedInReplacingThisWithOtherVariable() 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_FIELDREF); MethodNode donorMethod = findMethod(donorSource, "before_whatDoIThinkAbout"); //load the target class String TARGETCLASSNAME = "com.triage.bytecodemaster.fortesting.TestFriend"; ClassNode targetSource = loadLocalClass(TARGETCLASSNAME); MethodNode targetMethod = findMethod(targetSource, "whatDoIThinkAbout"); System.out.println("Target"); printMethodNode(targetMethod);//from w w w . j a v a 2s .co m System.out.println("Donor"); printMethodNode(donorMethod); //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; //make a new local variable LabelNode begin = new LabelNode(); LabelNode end = new LabelNode(); instructionsToInject.insertBefore(instructionsToInject.getFirst(), begin); instructionsToInject.add(end); Type type = Type.getObjectType("com/triage/bytecodemaster/fortesting/TestBaseClass"); int variableIndex = donorMethod.maxLocals; donorMethod.maxLocals += type.getSize(); donorMethod.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 instructionsToInject.insert(begin, getTestBase); //store reference VarInsnNode setRef = new VarInsnNode(Opcodes.ASTORE, variableIndex); //insert store after fetch instructionsToInject.insert(getTestBase, setRef); //replace all references to 'this' with the new variable 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; } } } System.out.println(">>>>>>>>>Finished Modifying<<<<<<<<"); printMethodNode(donorMethod); //insert the donorMethod targetMethod.instructions.insert(instructionsToInject); System.out.println(">>>>>>>>>Final Method<<<<<<<<"); printMethodNode(targetMethod); //write a class Class c = createClassFromClassNode(targetSource, TARGETCLASSNAME); Object o = c.newInstance(); Method m = o.getClass().getDeclaredMethod("whatDoIThinkAbout", TestPerson.class); TestPerson testPerson = new TestPerson(); testPerson.setName("AAAA"); //should return HAHAHA not baseStringValue String result = (String) m.invoke(o, new Object[] { testPerson }); System.out.println("TestFriend.whatDoIThinkAbout Result: " + result); assertTrue(result.equals(FIELDPROXYWORKED + "AAAA")); }
From source file:de.tuberlin.uebb.jbop.optimizer.arithmetic.ArithmeticExpressionInterpreter.java
License:Open Source License
private boolean runIntern(final InsnList original) { boolean intern = false; final Iterator<AbstractInsnNode> iterator = original.iterator(); while (iterator.hasNext()) { final AbstractInsnNode currentNode = iterator.next(); Number one, two;/*w w w.ja v a 2 s. c o m*/ AbstractInsnNode numberNode; AbstractInsnNode castNode1 = null; AbstractInsnNode castNode2 = null; try { one = NodeHelper.getNumberValue(currentNode); numberNode = NodeHelper.getNext(currentNode); if (NodeHelper.isCast(numberNode)) { castNode1 = numberNode; numberNode = NodeHelper.getNext(castNode1); } two = NodeHelper.getNumberValue(numberNode); } catch (final NotANumberException nane) { continue; } AbstractInsnNode op = NodeHelper.getNext(numberNode); if (NodeHelper.isCast(op)) { castNode2 = op; op = NodeHelper.getNext(castNode2); } if (isArithmeticOp(op)) { final AbstractInsnNode replacement = getReplacement(one, two, op); original.insert(op, replacement); clean(original, iterator, currentNode, numberNode, castNode1, castNode2, op); optimized = true; intern = true; } } return intern; }