List of usage examples for org.objectweb.asm.tree InsnList insertBefore
public void insertBefore(final AbstractInsnNode nextInsn, final InsnList insnList)
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)); }// w ww. j a v a 2s.c om 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.lodgon.parboiled.transform.LabellingGenerator.java
License:Apache License
public void process(ParserClassNode classNode, RuleMethod method) throws Exception { checkArgNotNull(classNode, "classNode"); checkArgNotNull(method, "method"); checkState(!method.isSuperMethod()); // super methods have flag moved to the overriding method InsnList instructions = method.instructions; AbstractInsnNode ret = instructions.getLast(); while (ret.getOpcode() != ARETURN) { ret = ret.getPrevious();/*from w ww . j a v a2 s. c o m*/ } LabelNode isNullLabel = new LabelNode(); // stack: <rule> instructions.insertBefore(ret, new InsnNode(DUP)); // stack: <rule> :: <rule> instructions.insertBefore(ret, new JumpInsnNode(IFNULL, isNullLabel)); // stack: <rule> instructions.insertBefore(ret, new LdcInsnNode(getLabelText(method))); // stack: <rule> :: <labelText> instructions.insertBefore(ret, new MethodInsnNode(INVOKEINTERFACE, Types.RULE.getInternalName(), "label", "(Ljava/lang/String;)" + Types.RULE_DESC)); // stack: <rule> instructions.insertBefore(ret, isNullLabel); // stack: <rule> }
From source file:com.lodgon.parboiled.transform.VarFramingGenerator.java
License:Apache License
public void process(ParserClassNode classNode, RuleMethod method) throws Exception { checkArgNotNull(classNode, "classNode"); checkArgNotNull(method, "method"); InsnList instructions = method.instructions; AbstractInsnNode ret = instructions.getLast(); while (ret.getOpcode() != ARETURN) { ret = ret.getPrevious();/*from w ww . j a v a 2s.c o m*/ } // stack: <Matcher> instructions.insertBefore(ret, new TypeInsnNode(NEW, VAR_FRAMING_MATCHER.getInternalName())); // stack: <Matcher> :: <VarFramingMatcher> instructions.insertBefore(ret, new InsnNode(DUP_X1)); // stack: <VarFramingMatcher> :: <Matcher> :: <VarFramingMatcher> instructions.insertBefore(ret, new InsnNode(SWAP)); // stack: <VarFramingMatcher> :: <VarFramingMatcher> :: <Matcher> createVarFieldArray(method, instructions, ret); // stack: <VarFramingMatcher> :: <VarFramingMatcher> :: <Matcher> :: <VarFieldArray> instructions.insertBefore(ret, new MethodInsnNode(INVOKESPECIAL, VAR_FRAMING_MATCHER.getInternalName(), "<init>", '(' + RULE_DESC + '[' + VAR_DESC + ")V")); // stack: <VarFramingMatcher> method.setBodyRewritten(); }
From source file:com.lodgon.parboiled.transform.VarFramingGenerator.java
License:Apache License
private void createVarFieldArray(RuleMethod method, InsnList instructions, AbstractInsnNode ret) { int count = method.getLocalVarVariables().size(); // stack:// w w w . jav a 2 s.c o m instructions.insertBefore(ret, new IntInsnNode(BIPUSH, count)); // stack: <length> instructions.insertBefore(ret, new TypeInsnNode(ANEWARRAY, VAR.getInternalName())); // stack: <array> for (int i = 0; i < count; i++) { LocalVariableNode var = method.getLocalVarVariables().get(i); // stack: <array> instructions.insertBefore(ret, new InsnNode(DUP)); // stack: <array> :: <array> instructions.insertBefore(ret, new IntInsnNode(BIPUSH, i)); // stack: <array> :: <array> :: <index> instructions.insertBefore(ret, new VarInsnNode(ALOAD, var.index)); // stack: <array> :: <array> :: <index> :: <var> instructions.insertBefore(ret, new InsnNode(DUP)); // stack: <array> :: <array> :: <index> :: <var> :: <var> instructions.insertBefore(ret, new LdcInsnNode(method.name + ':' + var.name)); // stack: <array> :: <array> :: <index> :: <var> :: <var> :: <varName> instructions.insertBefore(ret, new MethodInsnNode(INVOKEVIRTUAL, VAR.getInternalName(), "setName", "(Ljava/lang/String;)V")); // stack: <array> :: <array> :: <index> :: <var> instructions.insertBefore(ret, new InsnNode(AASTORE)); // stack: <array> } // stack: <array> }
From source file:com.sun.tdk.jcov.instrument.BranchCodeMethodAdapter.java
License:Open Source License
private void insertInstrumentation() { MethodNode methodNode = (MethodNode) mv; InsnList instructions = methodNode.instructions; for (Map.Entry<AbstractInsnNode, BasicBlock> entry : insnToBB.entrySet()) { // Basic block 'bb' starts at instruction 'insn' AbstractInsnNode insn = entry.getKey(); BasicBlock bb = entry.getValue(); // Get the entry blocks for this basic block Set<Map.Entry<DataBlock, LabelNode>> pairs = bb.blockLabelSet(); int remaining = pairs.size(); LabelNode realStuff = null;// www . j a v a 2s. c o m if (remaining > 1) { // There are two or more entries to this block. // We will need a label to jump over the other entries. realStuff = new LabelNode(); } // any fallen into entry blocks must be instrumented first (no label // switching was done for them. DataBlock fallenInto = bb.fallenInto(); if (fallenInto != null) { assert (bb.getLabel(fallenInto) == null); instructions.insertBefore(insn, Instrumenter.instrumentation(fallenInto, params.isDetectInternal())); if (--remaining > 0) { // jump over the next instrumentation of this basic block instructions.insertBefore(insn, new JumpInsnNode(GOTO, realStuff)); } } // Process the other entry blocks for (Map.Entry<DataBlock, LabelNode> pair : pairs) { DataBlock block = pair.getKey(); if (!block.isFallenInto()) { // insert the label LabelNode lnode = pair.getValue(); assert (lnode != null); // insert created label instructions.insertBefore(insn, lnode); // insert the instrumentation instructions.insertBefore(insn, Instrumenter.instrumentation(block, params.isDetectInternal())); if (--remaining > 0) { // jump over the next instrumentation of this basic block instructions.insertBefore(insn, new JumpInsnNode(GOTO, realStuff)); } } } if (realStuff != null) { // insert label for the real code instructions.insertBefore(insn, realStuff); } assert (remaining == 0); } }
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);//from w ww .j a va2s . 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);/*from w w w. jav a 2 s .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.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 . ja 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: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()); }/*w w w .ja va 2 s. co 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.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 v a2s . 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; }