Example usage for org.objectweb.asm.tree InsnList add

List of usage examples for org.objectweb.asm.tree InsnList add

Introduction

In this page you can find the example usage for org.objectweb.asm.tree InsnList add.

Prototype

public void add(final InsnList insnList) 

Source Link

Document

Adds the given instructions to the end of this list.

Usage

From source file:com.thomas15v.packetlib.codegenerator.asm.ASMHelper.java

License:MIT License

/**
 * Generate a new method "int name()", which returns a constant value.
 *
 * @param clazz Class to add method to/*  w  w  w .  j  a  v a 2  s .c om*/
 * @param name Name of method
 * @param retval Return value of method
 */
public static void generateIntegerMethodConst(ClassNode clazz, String name, short retval) {
    MethodNode method = new MethodNode(Opcodes.ASM5, Opcodes.ACC_PUBLIC | Opcodes.ACC_SYNTHETIC, name, "()I",
            null, null);
    InsnList code = method.instructions;

    code.add(ASMHelper.pushIntConstant(retval));
    code.add(new InsnNode(Opcodes.IRETURN));

    clazz.methods.add(method);
}

From source file:com.thomas15v.packetlib.codegenerator.asm.ASMHelper.java

License:MIT License

/**
 * Populate a forwarding method of the form
 * "T name() { return Class.forward(this); }".
 *
 * @param method Method to generate code for
 * @param forwardname Name of method to call
 * @param rettype Return type of method//from   w w  w. j a  v a2s .  c  om
 * @param thistype Type of object method is being generated on
 * @param forwardtype Type to forward method to
 */
public static void populateForwardingToStaticMethod(MethodNode method, String forwardname, Type rettype,
        Type thistype, Type forwardtype) {
    InsnList code = method.instructions;

    code.add(new VarInsnNode(thistype.getOpcode(Opcodes.ILOAD), 0));
    code.add(new MethodInsnNode(Opcodes.INVOKESTATIC, forwardtype.getInternalName(), forwardname,
            Type.getMethodDescriptor(rettype, thistype), false));
    code.add(new InsnNode(rettype.getOpcode(Opcodes.IRETURN)));
}

From source file:com.thomas15v.packetlib.codegenerator.asm.ASMHelper.java

License:MIT License

/**
 * Populate a forwarding method of the form
 * "T name() { return this.forward(); }". This is also valid for methods of
 * the form "static T name(S object) { return object.forward() }".
 *
 * @param method Method to generate code for
 * @param forwardname Name of method to call
 * @param rettype Return type of method/* ww  w . j  a  v a  2  s .  c o  m*/
 * @param thistype Type of object method is being generated on
 */
public static void populateSelfForwardingMethod(MethodNode method, String forwardname, Type rettype,
        Type thistype) {
    InsnList code = method.instructions;

    code.add(new VarInsnNode(thistype.getOpcode(Opcodes.ILOAD), 0));
    code.add(new MethodInsnNode(Opcodes.INVOKEVIRTUAL, thistype.getInternalName(), forwardname,
            "()" + rettype.getDescriptor(), false));
    code.add(new InsnNode(rettype.getOpcode(Opcodes.IRETURN)));
}

From source file:com.thomas15v.packetlib.codegenerator.asm.ASMHelper.java

License:MIT License

/**
 * Populate a forwarding method of the form
 * "T name(S object) { return object.forward(); }".
 *
 * @param method Method to generate code for
 * @param forwardname Name of method to call
 * @param rettype Return type of method/*  w w  w . j  av a 2 s  . co  m*/
 * @param argtype Type of object to call method on
 * @param thistype Type of object method is being generated on
 */
public static void populateForwardingMethod(MethodNode method, String forwardname, Type rettype, Type argtype,
        Type thistype) {
    InsnList code = method.instructions;

    code.add(new VarInsnNode(argtype.getOpcode(Opcodes.ILOAD), 1));
    code.add(new MethodInsnNode(Opcodes.INVOKEVIRTUAL, argtype.getInternalName(), forwardname,
            "()" + rettype.getDescriptor(), false));
    code.add(new InsnNode(rettype.getOpcode(Opcodes.IRETURN)));
}

From source file:com.thomas15v.packetlib.codegenerator.asm.ASMHelper.java

License:MIT License

/**
 * Injects appropriate LOAD opcodes into the supplied InsnList appropriate
 * for each entry in the args array starting at start and ending at end
 * // w  w w.  jav  a 2s. com
 * @param args Argument types
 * @param insns Instruction List to inject into
 * @param start Start position
 * @param end End position
 */
public static void loadArgs(Type[] args, InsnList insns, int start, int end) {
    int pos = start;

    for (Type type : args) {
        insns.add(new VarInsnNode(type.getOpcode(Opcodes.ILOAD), pos));
        pos += type.getSize();
        if (end >= start && pos >= end) {
            return;
        }
    }
}

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);/*w  ww .  j ava 2 s.com*/

    //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);//w ww  .  j a v a2  s .  co 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);/*w  w w . j  a v  a 2  s .  c  o  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.sanandrew.core.manpack.transformer.InstructionComparator.java

License:Creative Commons License

public static InsnList getImportantList(InsnList list) {
    if (list.size() == 0) {
        return list;
    }/*  w  w  w  . ja va  2s. c  om*/

    HashMap<LabelNode, LabelNode> labels = new HashMap<>();

    for (AbstractInsnNode insn = list.getFirst(); insn != null; insn = insn.getNext()) {
        if (insn instanceof LabelNode) {
            labels.put((LabelNode) insn, (LabelNode) insn);
        }
    }

    InsnList importantNodeList = new InsnList();

    for (AbstractInsnNode insn = list.getFirst(); insn != null; insn = insn.getNext()) {
        if (insn instanceof LabelNode || insn instanceof LineNumberNode) {
            continue;
        }

        importantNodeList.add(insn.clone(labels));
    }
    return importantNodeList;
}

From source file:de.sanandrew.core.manpack.transformer.TransformEnderman.java

License:Creative Commons License

private static byte[] transformEnderman(byte[] bytes) {
    ClassNode clazz = ASMHelper.createClassNode(bytes);
    MethodNode method = ASMHelper.findMethod(clazz, ASMNames.MD_ENDERMAN_SHOULD_ATTACK_PLAYER);

    InsnList needle = new InsnList();
    needle.add(new VarInsnNode(Opcodes.ALOAD, 1));
    needle.add(ASMHelper.getFieldInsnNode(Opcodes.GETFIELD, ASMNames.FD_PLAYER_INVENTORY));
    needle.add(ASMHelper.getFieldInsnNode(Opcodes.GETFIELD, ASMNames.FD_INVPLAYER_ARMOR_INVENTORY));
    needle.add(new InsnNode(Opcodes.ICONST_3));
    needle.add(new InsnNode(Opcodes.AALOAD));
    needle.add(new VarInsnNode(Opcodes.ASTORE, 2));

    AbstractInsnNode insertPt = ASMHelper.findFirstNodeFromNeedle(method.instructions, needle);

    InsnList newInstr = new InsnList();
    newInstr.add(ASMHelper.getFieldInsnNode(Opcodes.GETSTATIC, ASMNames.FD_SAPUTILS_EVENT_BUS));
    newInstr.add(new TypeInsnNode(Opcodes.NEW, ASMNames.CL_ENDER_FACING_EVENT));
    newInstr.add(new InsnNode(Opcodes.DUP));
    newInstr.add(new VarInsnNode(Opcodes.ALOAD, 1));
    newInstr.add(new VarInsnNode(Opcodes.ALOAD, 0));
    newInstr.add(ASMHelper.getMethodInsnNode(Opcodes.INVOKESPECIAL, ASMNames.MD_ENDERFACINGEVENT_INIT, false));
    newInstr.add(ASMHelper.getMethodInsnNode(Opcodes.INVOKEVIRTUAL, ASMNames.MD_EVENT_BUS_POST, false));
    LabelNode l1 = new LabelNode();
    newInstr.add(new JumpInsnNode(Opcodes.IFEQ, l1));
    newInstr.add(new InsnNode(Opcodes.ICONST_0));
    newInstr.add(new InsnNode(Opcodes.IRETURN));
    newInstr.add(l1);//from   ww w .  j ava2s  .c om

    method.instructions.insertBefore(insertPt, newInstr);

    return ASMHelper.createBytes(clazz, /*ClassWriter.COMPUTE_FRAMES |*/ ClassWriter.COMPUTE_MAXS);
}