Search in sources :

Example 36 with JumpInsnNode

use of org.objectweb.asm.tree.JumpInsnNode in project evosuite by EvoSuite.

the class Instrumenter method wrapMethod.

/**
 * 	public int myMethod(int i)
 *		{
 *			try
 *			{
 *				return _sw_prototype_original_myMethod(i)
 *			}
 *			finally
 *			{
 *				Capturer.enable();
 *			}
 *		}
 *
 * @param classNode
 * @param className
 * @param methodNode
 */
@SuppressWarnings("unchecked")
private MethodNode wrapMethod(final ClassNode classNode, final String className, final MethodNode methodNode) {
    methodNode.maxStack += 4;
    // create wrapper for original method
    final MethodNode wrappingMethodNode = new MethodNode(methodNode.access, methodNode.name, methodNode.desc, methodNode.signature, (String[]) methodNode.exceptions.toArray(new String[methodNode.exceptions.size()]));
    wrappingMethodNode.maxStack = methodNode.maxStack;
    // assign annotations to wrapping method
    wrappingMethodNode.visibleAnnotations = methodNode.visibleAnnotations;
    wrappingMethodNode.visibleParameterAnnotations = methodNode.visibleParameterAnnotations;
    // remove annotations from wrapped method to avoid wrong behavior controlled by annotations
    methodNode.visibleAnnotations = null;
    methodNode.visibleParameterAnnotations = null;
    // rename original method
    methodNode.access = TransformerUtil.modifyVisibility(methodNode.access, Opcodes.ACC_PRIVATE);
    final LabelNode l0 = new LabelNode();
    final LabelNode l1 = new LabelNode();
    final LabelNode l2 = new LabelNode();
    final InsnList wInstructions = wrappingMethodNode.instructions;
    if ("<init>".equals(methodNode.name)) {
        // wrap a constructor
        methodNode.name = WRAP_NAME_PREFIX + "init" + WRAP_NAME_PREFIX;
        // move call to other constructors to new method
        AbstractInsnNode ins = null;
        ListIterator<AbstractInsnNode> iter = methodNode.instructions.iterator();
        // number of invokespecial calls before actual constructor call
        int numInvokeSpecials = 0;
        while (iter.hasNext()) {
            ins = iter.next();
            iter.remove();
            wInstructions.add(ins);
            if (ins instanceof MethodInsnNode) {
                MethodInsnNode mins = (MethodInsnNode) ins;
                if (ins.getOpcode() == Opcodes.INVOKESPECIAL) {
                    if (mins.name.startsWith("<init>")) {
                        if (numInvokeSpecials == 0) {
                            break;
                        } else {
                            numInvokeSpecials--;
                        }
                    }
                }
            } else if (ins instanceof TypeInsnNode) {
                TypeInsnNode typeIns = (TypeInsnNode) ins;
                if (typeIns.getOpcode() == Opcodes.NEW || typeIns.getOpcode() == Opcodes.NEWARRAY) {
                    numInvokeSpecials++;
                }
            }
        }
    } else {
        methodNode.name = WRAP_NAME_PREFIX + methodNode.name;
    }
    int varReturnValue = 0;
    final Type returnType = Type.getReturnType(methodNode.desc);
    if (returnType.equals(Type.VOID_TYPE)) {
        wrappingMethodNode.tryCatchBlocks.add(new TryCatchBlockNode(l0, l1, l1, "java/lang/Throwable"));
    } else {
        wrappingMethodNode.tryCatchBlocks.add(new TryCatchBlockNode(l0, l1, l2, "java/lang/Throwable"));
        if (!TransformerUtil.isStatic(methodNode.access)) {
            // load "this"
            varReturnValue++;
        }
        // consider method arguments to find right variable index
        final Type[] argTypes = Type.getArgumentTypes(methodNode.desc);
        for (int i = 0; i < argTypes.length; i++) {
            varReturnValue++;
            // long/double take two registers
            if (argTypes[i].equals(Type.LONG_TYPE) || argTypes[i].equals(Type.DOUBLE_TYPE)) {
                varReturnValue++;
            }
        }
        // push NULL on the stack and initialize variable for return value for it
        wInstructions.add(new InsnNode(Opcodes.ACONST_NULL));
        wInstructions.add(new VarInsnNode(Opcodes.ASTORE, varReturnValue));
    }
    int var = 0;
    // --- L0
    wInstructions.add(l0);
    wInstructions.add(this.addCaptureCall(TransformerUtil.isStatic(methodNode.access), className, wrappingMethodNode.name, wrappingMethodNode.desc, Type.getArgumentTypes(methodNode.desc)));
    if (!TransformerUtil.isStatic(methodNode.access)) {
        // load "this" to call method
        wInstructions.add(new VarInsnNode(Opcodes.ALOAD, 0));
        var++;
    }
    final Type[] argTypes = Type.getArgumentTypes(methodNode.desc);
    for (int i = 0; i < argTypes.length; i++) {
        this.addLoadInsn(wInstructions, argTypes[i], var++);
        // long/double take two registers
        if (argTypes[i].equals(Type.LONG_TYPE) || argTypes[i].equals(Type.DOUBLE_TYPE)) {
            var++;
        }
    }
    if (TransformerUtil.isStatic(methodNode.access)) {
        wInstructions.add(new MethodInsnNode(Opcodes.INVOKESTATIC, classNode.name, methodNode.name, methodNode.desc));
    } else {
        wInstructions.add(new MethodInsnNode(Opcodes.INVOKEVIRTUAL, classNode.name, methodNode.name, methodNode.desc));
    }
    var++;
    if (returnType.equals(Type.VOID_TYPE)) {
        wInstructions.add(new JumpInsnNode(Opcodes.GOTO, l2));
        // --- L1
        wInstructions.add(l1);
        wInstructions.add(new FrameNode(Opcodes.F_SAME1, 0, null, 1, new Object[] { "java/lang/Throwable" }));
        wInstructions.add(new VarInsnNode(Opcodes.ASTORE, --var));
        this.addCaptureEnableStatement(className, methodNode, wInstructions, -1);
        wInstructions.add(new VarInsnNode(Opcodes.ALOAD, var));
        wInstructions.add(new InsnNode(Opcodes.ATHROW));
        // FIXME <--- DUPLICATE CODE
        // --- L2
        wInstructions.add(l2);
        wInstructions.add(new FrameNode(Opcodes.F_SAME, 0, null, 0, null));
        this.addCaptureEnableStatement(className, methodNode, wInstructions, -1);
        wInstructions.add(new InsnNode(Opcodes.RETURN));
    } else {
        // construct store of the wrapped method call's result
        this.addBoxingStmt(wInstructions, returnType);
        wInstructions.add(new VarInsnNode(Opcodes.ASTORE, varReturnValue));
        wInstructions.add(new VarInsnNode(Opcodes.ALOAD, varReturnValue));
        this.addUnBoxingStmt(wInstructions, returnType);
        final int storeOpcode = returnType.getOpcode(Opcodes.ISTORE);
        // might be only var
        wInstructions.add(new VarInsnNode(storeOpcode, ++var));
        // --- L1
        wInstructions.add(l1);
        this.addCaptureEnableStatement(className, methodNode, wInstructions, varReturnValue);
        // construct load of the wrapped method call's result
        int loadOpcode = returnType.getOpcode(Opcodes.ILOAD);
        wInstructions.add(new VarInsnNode(loadOpcode, var));
        // construct return of the wrapped method call's result
        this.addReturnInsn(wInstructions, returnType);
        // ---- L2
        wInstructions.add(l2);
        wInstructions.add(new FrameNode(Opcodes.F_FULL, 2, new Object[] { className, this.getInternalName(returnType) }, 1, new Object[] { "java/lang/Throwable" }));
        wInstructions.add(new VarInsnNode(Opcodes.ASTORE, --var));
        this.addCaptureEnableStatement(className, methodNode, wInstructions, varReturnValue);
        wInstructions.add(new VarInsnNode(Opcodes.ALOAD, var));
        wInstructions.add(new InsnNode(Opcodes.ATHROW));
    }
    transformWrapperCalls(methodNode);
    return wrappingMethodNode;
}
Also used : LabelNode(org.objectweb.asm.tree.LabelNode) TryCatchBlockNode(org.objectweb.asm.tree.TryCatchBlockNode) FrameNode(org.objectweb.asm.tree.FrameNode) TypeInsnNode(org.objectweb.asm.tree.TypeInsnNode) InsnList(org.objectweb.asm.tree.InsnList) AbstractInsnNode(org.objectweb.asm.tree.AbstractInsnNode) FieldInsnNode(org.objectweb.asm.tree.FieldInsnNode) MethodInsnNode(org.objectweb.asm.tree.MethodInsnNode) IntInsnNode(org.objectweb.asm.tree.IntInsnNode) TypeInsnNode(org.objectweb.asm.tree.TypeInsnNode) JumpInsnNode(org.objectweb.asm.tree.JumpInsnNode) LdcInsnNode(org.objectweb.asm.tree.LdcInsnNode) AbstractInsnNode(org.objectweb.asm.tree.AbstractInsnNode) VarInsnNode(org.objectweb.asm.tree.VarInsnNode) InsnNode(org.objectweb.asm.tree.InsnNode) Type(org.objectweb.asm.Type) MethodNode(org.objectweb.asm.tree.MethodNode) MethodInsnNode(org.objectweb.asm.tree.MethodInsnNode) JumpInsnNode(org.objectweb.asm.tree.JumpInsnNode) VarInsnNode(org.objectweb.asm.tree.VarInsnNode)

Example 37 with JumpInsnNode

use of org.objectweb.asm.tree.JumpInsnNode in project evosuite by EvoSuite.

the class LCSAJsInstrumentation method analyze.

/* (non-Javadoc)
	 * @see org.evosuite.cfg.MethodInstrumentation#analyze(org.objectweb.asm.tree.MethodNode, org.jgrapht.Graph, java.lang.String, java.lang.String)
	 */
/**
 * {@inheritDoc}
 */
@SuppressWarnings("unchecked")
// using external lib
@Override
public void analyze(ClassLoader classLoader, MethodNode mn, String className, String methodName, int access) {
    Queue<LCSAJ> lcsaj_queue = new LinkedList<LCSAJ>();
    HashSet<Integer> targets_reached = new HashSet<Integer>();
    AbstractInsnNode start = mn.instructions.getFirst();
    int startID = 0;
    // TODO: This should replace the hack below
    if (methodName.startsWith("<init>")) {
        Iterator<AbstractInsnNode> j = mn.instructions.iterator();
        boolean constructorInvoked = false;
        while (j.hasNext()) {
            AbstractInsnNode in = j.next();
            startID++;
            if (!constructorInvoked) {
                if (in.getOpcode() == Opcodes.INVOKESPECIAL) {
                    MethodInsnNode cn = (MethodInsnNode) in;
                    Collection<String> superClasses = DependencyAnalysis.getInheritanceTree().getSuperclasses(className);
                    superClasses.add(className);
                    String classNameWithDots = ResourceList.getClassNameFromResourcePath(cn.owner);
                    if (superClasses.contains(classNameWithDots)) {
                        constructorInvoked = true;
                        break;
                    }
                } else {
                    continue;
                }
            }
        }
    }
    /*
		if (methodName.startsWith("<init>")) {
			if (mn.instructions.size() >= 4) {
				start = mn.instructions.get(4);
				startID = 4;
			}
		}
		*/
    LCSAJ a = new LCSAJ(className, methodName, BytecodeInstructionPool.getInstance(classLoader).getInstruction(className, methodName, startID, start));
    lcsaj_queue.add(a);
    targets_reached.add(0);
    ArrayList<TryCatchBlockNode> tc_blocks = (ArrayList<TryCatchBlockNode>) mn.tryCatchBlocks;
    for (TryCatchBlockNode t : tc_blocks) {
        LCSAJ b = new LCSAJ(className, methodName, BytecodeInstructionPool.getInstance(classLoader).getInstruction(className, methodName, mn.instructions.indexOf(t.handler), t.handler));
        lcsaj_queue.add(b);
    }
    while (!lcsaj_queue.isEmpty()) {
        LCSAJ currentLCSAJ = lcsaj_queue.poll();
        int position = mn.instructions.indexOf(currentLCSAJ.getLastNodeAccessed());
        // go to next bytecode instruction
        position++;
        if (position >= mn.instructions.size()) {
            // New LCSAJ for current + return
            LCSAJPool.add_lcsaj(className, methodName, currentLCSAJ);
            continue;
        }
        AbstractInsnNode next = mn.instructions.get(position);
        currentLCSAJ.lookupInstruction(position, BytecodeInstructionPool.getInstance(classLoader).getInstruction(className, methodName, position, next));
        if (next instanceof JumpInsnNode) {
            JumpInsnNode jump = (JumpInsnNode) next;
            // New LCSAJ for current + jump to target
            LCSAJPool.add_lcsaj(className, methodName, currentLCSAJ);
            LabelNode target = jump.label;
            int targetPosition = mn.instructions.indexOf(target);
            if (jump.getOpcode() != Opcodes.GOTO) {
                LCSAJ copy = new LCSAJ(currentLCSAJ);
                lcsaj_queue.add(copy);
            }
            if (!targets_reached.contains(targetPosition)) {
                LCSAJ c = new LCSAJ(className, methodName, BytecodeInstructionPool.getInstance(classLoader).getInstruction(className, methodName, targetPosition, target));
                lcsaj_queue.add(c);
                targets_reached.add(targetPosition);
            }
        } else if (next instanceof TableSwitchInsnNode) {
            TableSwitchInsnNode tswitch = (TableSwitchInsnNode) next;
            List<LabelNode> allTargets = tswitch.labels;
            for (LabelNode target : allTargets) {
                int targetPosition = mn.instructions.indexOf(target);
                if (!targets_reached.contains(targetPosition)) {
                    LCSAJ b = new LCSAJ(className, methodName, BytecodeInstructionPool.getInstance(classLoader).getInstruction(className, methodName, targetPosition, target));
                    lcsaj_queue.add(b);
                    targets_reached.add(targetPosition);
                }
            }
        } else if (next instanceof InsnNode) {
            InsnNode insn = (InsnNode) next;
            // New LCSAJ for current + throw / return
            if (insn.getOpcode() == Opcodes.ATHROW || insn.getOpcode() == Opcodes.RETURN || insn.getOpcode() == Opcodes.ARETURN || insn.getOpcode() == Opcodes.IRETURN || insn.getOpcode() == Opcodes.DRETURN || insn.getOpcode() == Opcodes.LRETURN || insn.getOpcode() == Opcodes.FRETURN) {
                LCSAJPool.add_lcsaj(className, methodName, currentLCSAJ);
            } else
                lcsaj_queue.add(currentLCSAJ);
        } else
            lcsaj_queue.add(currentLCSAJ);
    }
    if (Properties.STRATEGY != Strategy.EVOSUITE)
        addInstrumentation(classLoader, mn, className, methodName);
// if (Properties.WRITE_CFG)
// for (LCSAJ l : LCSAJPool.getLCSAJs(className, methodName)) {
// LCSAJGraph graph = new LCSAJGraph(l, false);
// String graphDestination = "evosuite-graphs/LCSAJGraphs/" + className
// + "/" + methodName;
// File dir = new File(graphDestination);
// if (dir.mkdirs())
// graph.generate(new File(graphDestination + "/LCSAJGraph no: "
// + l.getID() + ".dot"));
// else if (dir.exists())
// graph.generate(new File(graphDestination + "/LCSAJGraph no: "
// + l.getID() + ".dot"));
// }
}
Also used : LabelNode(org.objectweb.asm.tree.LabelNode) TryCatchBlockNode(org.objectweb.asm.tree.TryCatchBlockNode) TableSwitchInsnNode(org.objectweb.asm.tree.TableSwitchInsnNode) ArrayList(java.util.ArrayList) LCSAJ(org.evosuite.coverage.lcsaj.LCSAJ) AbstractInsnNode(org.objectweb.asm.tree.AbstractInsnNode) LinkedList(java.util.LinkedList) MethodInsnNode(org.objectweb.asm.tree.MethodInsnNode) TableSwitchInsnNode(org.objectweb.asm.tree.TableSwitchInsnNode) JumpInsnNode(org.objectweb.asm.tree.JumpInsnNode) LdcInsnNode(org.objectweb.asm.tree.LdcInsnNode) AbstractInsnNode(org.objectweb.asm.tree.AbstractInsnNode) InsnNode(org.objectweb.asm.tree.InsnNode) MethodInsnNode(org.objectweb.asm.tree.MethodInsnNode) JumpInsnNode(org.objectweb.asm.tree.JumpInsnNode) ArrayList(java.util.ArrayList) LinkedList(java.util.LinkedList) InsnList(org.objectweb.asm.tree.InsnList) List(java.util.List) ResourceList(org.evosuite.classpath.ResourceList) HashSet(java.util.HashSet)

Example 38 with JumpInsnNode

use of org.objectweb.asm.tree.JumpInsnNode in project Random-Things by lumien231.

the class ClassTransformer method patchWorldClass.

private byte[] patchWorldClass(byte[] basicClass) {
    ClassNode classNode = new ClassNode();
    ClassReader classReader = new ClassReader(basicClass);
    classReader.accept(classNode, 0);
    logger.log(Level.DEBUG, "Found World Class: " + classNode.name);
    MethodNode getRedstonePower = null;
    MethodNode getStrongPower = null;
    MethodNode isRainingAt = null;
    MethodNode canSnowAt = null;
    for (MethodNode mn : classNode.methods) {
        if (mn.name.equals(MCPNames.method("func_175651_c"))) {
            getRedstonePower = mn;
        } else if (mn.name.equals(MCPNames.method("func_175627_a")) && mn.desc.equals("(Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/util/EnumFacing;)I")) {
            getStrongPower = mn;
        } else if (mn.name.equals(MCPNames.method("func_175727_C"))) {
            isRainingAt = mn;
        } else if (mn.name.equals(MCPNames.method("func_175708_f"))) {
            canSnowAt = mn;
        }
    }
    if (getRedstonePower != null) {
        logger.log(Level.DEBUG, "- Found getRedstonePower (1/4)");
        InsnList toInsert = new InsnList();
        LabelNode l1 = new LabelNode(new Label());
        toInsert.add(new VarInsnNode(ALOAD, 0));
        toInsert.add(new VarInsnNode(ALOAD, 1));
        toInsert.add(new VarInsnNode(ALOAD, 2));
        toInsert.add(new MethodInsnNode(INVOKESTATIC, asmHandler, "getRedstonePower", "(Lnet/minecraft/world/World;Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/util/EnumFacing;)I", false));
        toInsert.add(new InsnNode(DUP));
        toInsert.add(new JumpInsnNode(IFEQ, l1));
        toInsert.add(new InsnNode(IRETURN));
        toInsert.add(l1);
        toInsert.add(new InsnNode(POP));
        getRedstonePower.instructions.insert(toInsert);
    }
    if (getStrongPower != null) {
        logger.log(Level.DEBUG, "- Found getStrongPower (2/4)");
        InsnList toInsert = new InsnList();
        LabelNode l1 = new LabelNode(new Label());
        toInsert.add(new VarInsnNode(ALOAD, 0));
        toInsert.add(new VarInsnNode(ALOAD, 1));
        toInsert.add(new VarInsnNode(ALOAD, 2));
        toInsert.add(new MethodInsnNode(INVOKESTATIC, asmHandler, "getStrongPower", "(Lnet/minecraft/world/World;Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/util/EnumFacing;)I", false));
        toInsert.add(new InsnNode(DUP));
        toInsert.add(new JumpInsnNode(IFEQ, l1));
        toInsert.add(new InsnNode(IRETURN));
        toInsert.add(l1);
        toInsert.add(new InsnNode(POP));
        getStrongPower.instructions.insert(toInsert);
    }
    if (isRainingAt != null) {
        logger.log(Level.DEBUG, "- Found isRainingAt (3/4)");
        AbstractInsnNode returnNode = null;
        for (int i = 0; i < isRainingAt.instructions.size(); i++) {
            AbstractInsnNode ain = isRainingAt.instructions.get(i);
            if (ain.getOpcode() == Opcodes.IRETURN) {
                returnNode = ain;
            }
        }
        InsnList toInsert = new InsnList();
        LabelNode returnLabel = new LabelNode(new Label());
        toInsert.add(new InsnNode(Opcodes.DUP));
        toInsert.add(new JumpInsnNode(IFEQ, returnLabel));
        toInsert.add(new InsnNode(POP));
        toInsert.add(new VarInsnNode(ALOAD, 0));
        toInsert.add(new VarInsnNode(ALOAD, 1));
        toInsert.add(new MethodInsnNode(INVOKESTATIC, asmHandler, "shouldRain", "(Lnet/minecraft/world/World;Lnet/minecraft/util/math/BlockPos;)Z", false));
        toInsert.add(returnLabel);
        isRainingAt.instructions.insertBefore(returnNode, toInsert);
    }
    if (canSnowAt != null) {
        logger.log(Level.DEBUG, "- Found canSnowAt (4/4)");
        AbstractInsnNode returnNode = null;
        for (int i = 0; i < canSnowAt.instructions.size(); i++) {
            AbstractInsnNode ain = canSnowAt.instructions.get(i);
            if (ain.getOpcode() == Opcodes.IRETURN) {
                returnNode = ain;
            }
        }
        InsnList toInsert = new InsnList();
        LabelNode returnLabel = new LabelNode(new Label());
        toInsert.add(new InsnNode(Opcodes.DUP));
        toInsert.add(new JumpInsnNode(IFEQ, returnLabel));
        toInsert.add(new InsnNode(POP));
        toInsert.add(new VarInsnNode(ALOAD, 0));
        toInsert.add(new VarInsnNode(ALOAD, 1));
        toInsert.add(new MethodInsnNode(INVOKESTATIC, asmHandler, "canSnowAt", "(Lnet/minecraft/world/World;Lnet/minecraft/util/math/BlockPos;)Z", false));
        toInsert.add(returnLabel);
        canSnowAt.instructions.insertBefore(returnNode, toInsert);
    }
    CustomClassWriter writer = new CustomClassWriter(ClassWriter.COMPUTE_MAXS | ClassWriter.COMPUTE_FRAMES);
    classNode.accept(writer);
    return writer.toByteArray();
}
Also used : LabelNode(org.objectweb.asm.tree.LabelNode) ClassNode(org.objectweb.asm.tree.ClassNode) Label(org.objectweb.asm.Label) InsnList(org.objectweb.asm.tree.InsnList) AbstractInsnNode(org.objectweb.asm.tree.AbstractInsnNode) FieldInsnNode(org.objectweb.asm.tree.FieldInsnNode) VarInsnNode(org.objectweb.asm.tree.VarInsnNode) MethodInsnNode(org.objectweb.asm.tree.MethodInsnNode) TypeInsnNode(org.objectweb.asm.tree.TypeInsnNode) JumpInsnNode(org.objectweb.asm.tree.JumpInsnNode) LdcInsnNode(org.objectweb.asm.tree.LdcInsnNode) AbstractInsnNode(org.objectweb.asm.tree.AbstractInsnNode) InsnNode(org.objectweb.asm.tree.InsnNode) MethodNode(org.objectweb.asm.tree.MethodNode) MethodInsnNode(org.objectweb.asm.tree.MethodInsnNode) ClassReader(org.objectweb.asm.ClassReader) JumpInsnNode(org.objectweb.asm.tree.JumpInsnNode) VarInsnNode(org.objectweb.asm.tree.VarInsnNode)

Example 39 with JumpInsnNode

use of org.objectweb.asm.tree.JumpInsnNode in project Random-Things by lumien231.

the class ClassTransformer method patchBlockRendererDispatcher.

private byte[] patchBlockRendererDispatcher(byte[] basicClass) {
    ClassNode classNode = new ClassNode();
    ClassReader classReader = new ClassReader(basicClass);
    classReader.accept(classNode, 0);
    logger.log(Level.DEBUG, "Found BlockRendererDispatcher Class: " + classNode.name);
    MethodNode renderBlock = null;
    for (MethodNode mn : classNode.methods) {
        if (mn.name.equals(MCPNames.method("func_175018_a"))) {
            renderBlock = mn;
        }
    }
    if (renderBlock != null) {
        logger.log(Level.DEBUG, "- Found renderBlock (1/1)");
        InsnList toInsert = new InsnList();
        LabelNode l1 = new LabelNode(new Label());
        toInsert.add(new VarInsnNode(ALOAD, 0));
        toInsert.add(new VarInsnNode(ALOAD, 1));
        toInsert.add(new VarInsnNode(ALOAD, 2));
        toInsert.add(new VarInsnNode(ALOAD, 3));
        toInsert.add(new VarInsnNode(ALOAD, 4));
        toInsert.add(new MethodInsnNode(INVOKESTATIC, asmHandler, "renderBlock", "(Lnet/minecraft/client/renderer/BlockRendererDispatcher;Lnet/minecraft/block/state/IBlockState;Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/world/IBlockAccess;Lnet/minecraft/client/renderer/BufferBuilder;)I", false));
        toInsert.add(new InsnNode(DUP));
        toInsert.add(new InsnNode(ICONST_2));
        toInsert.add(new JumpInsnNode(IF_ICMPEQ, l1));
        toInsert.add(new InsnNode(IRETURN));
        toInsert.add(l1);
        toInsert.add(new InsnNode(POP));
        renderBlock.instructions.insert(toInsert);
    }
    CustomClassWriter writer = new CustomClassWriter(ClassWriter.COMPUTE_MAXS | ClassWriter.COMPUTE_FRAMES);
    classNode.accept(writer);
    return writer.toByteArray();
}
Also used : LabelNode(org.objectweb.asm.tree.LabelNode) ClassNode(org.objectweb.asm.tree.ClassNode) FieldInsnNode(org.objectweb.asm.tree.FieldInsnNode) VarInsnNode(org.objectweb.asm.tree.VarInsnNode) MethodInsnNode(org.objectweb.asm.tree.MethodInsnNode) TypeInsnNode(org.objectweb.asm.tree.TypeInsnNode) JumpInsnNode(org.objectweb.asm.tree.JumpInsnNode) LdcInsnNode(org.objectweb.asm.tree.LdcInsnNode) AbstractInsnNode(org.objectweb.asm.tree.AbstractInsnNode) InsnNode(org.objectweb.asm.tree.InsnNode) MethodNode(org.objectweb.asm.tree.MethodNode) MethodInsnNode(org.objectweb.asm.tree.MethodInsnNode) Label(org.objectweb.asm.Label) ClassReader(org.objectweb.asm.ClassReader) JumpInsnNode(org.objectweb.asm.tree.JumpInsnNode) InsnList(org.objectweb.asm.tree.InsnList) VarInsnNode(org.objectweb.asm.tree.VarInsnNode)

Example 40 with JumpInsnNode

use of org.objectweb.asm.tree.JumpInsnNode in project Random-Things by lumien231.

the class ClassTransformer method patchEntityRenderer.

private byte[] patchEntityRenderer(byte[] basicClass) {
    ClassNode classNode = new ClassNode();
    ClassReader classReader = new ClassReader(basicClass);
    classReader.accept(classNode, 0);
    logger.log(Level.DEBUG, "Found EntityRenderer Class: " + classNode.name);
    MethodNode renderRainSnow = null;
    MethodNode addRainParticles = null;
    for (MethodNode mn : classNode.methods) {
        if (mn.name.equals(MCPNames.method("func_78474_d"))) {
            renderRainSnow = mn;
        } else if (mn.name.equals(MCPNames.method("func_78484_h"))) {
            addRainParticles = mn;
        }
    }
    if (renderRainSnow != null) {
        logger.log(Level.DEBUG, "- Found renderRainSnow");
        VarInsnNode insnPoint = null;
        for (int i = 0; i < renderRainSnow.instructions.size(); i++) {
            AbstractInsnNode ain = renderRainSnow.instructions.get(i);
            if (ain instanceof MethodInsnNode) {
                MethodInsnNode min = (MethodInsnNode) ain;
                if (min.name.equals(MCPNames.method("func_76738_d"))) {
                    logger.log(Level.DEBUG, "- Found canRain");
                    insnPoint = (VarInsnNode) renderRainSnow.instructions.get(i - 1);
                }
                if (min.name.equals(MCPNames.method("func_76746_c"))) {
                    logger.log(Level.DEBUG, "- Found getEnableSnow");
                    int jumpCounter = i + 1;
                    int worldIndex = 5;
                    int blockPosIndex = 21;
                    // Optifine Why :'(
                    for (LocalVariableNode lv : renderRainSnow.localVariables) {
                        if (lv.desc.equals("Lnet/minecraft/client/multiplayer/WorldClient;") || lv.desc.equals("Lnet/minecraft/world/World;")) {
                            worldIndex = lv.index;
                        } else if (lv.desc.equals("Lnet/minecraft/util/math/BlockPos$MutableBlockPos;")) {
                            blockPosIndex = lv.index;
                        }
                    }
                    AbstractInsnNode jumpNode;
                    while (!((jumpNode = renderRainSnow.instructions.get(jumpCounter)) instanceof JumpInsnNode)) {
                        jumpCounter++;
                    }
                    JumpInsnNode jin = (JumpInsnNode) jumpNode;
                    LabelNode labelNode = jin.label;
                    InsnList toInsert = new InsnList();
                    toInsert.add(new VarInsnNode(ALOAD, worldIndex));
                    toInsert.add(new VarInsnNode(ALOAD, blockPosIndex));
                    toInsert.add(new MethodInsnNode(INVOKESTATIC, asmHandler, "shouldRain", "(Lnet/minecraft/world/World;Lnet/minecraft/util/math/BlockPos;)Z", false));
                    toInsert.add(new JumpInsnNode(IFEQ, labelNode));
                    renderRainSnow.instructions.insertBefore(insnPoint, toInsert);
                    i += 4;
                }
            }
        }
    }
    if (addRainParticles != null) {
        logger.log(Level.DEBUG, "- Found addRainParticles");
        for (int i = 0; i < addRainParticles.instructions.size(); i++) {
            AbstractInsnNode ain = addRainParticles.instructions.get(i);
            if (ain instanceof JumpInsnNode) {
                JumpInsnNode jin = (JumpInsnNode) ain;
                if (jin.getOpcode() == Opcodes.IF_ICMPGT) {
                    LabelNode jumpTarget = jin.label;
                    InsnList toInsert = new InsnList();
                    toInsert.add(new VarInsnNode(ALOAD, 3));
                    toInsert.add(new VarInsnNode(ALOAD, 15));
                    toInsert.add(new MethodInsnNode(INVOKESTATIC, asmHandler, "shouldRain", "(Lnet/minecraft/world/World;Lnet/minecraft/util/math/BlockPos;)Z", false));
                    toInsert.add(new JumpInsnNode(IFEQ, jumpTarget));
                    addRainParticles.instructions.insert(jin, toInsert);
                    break;
                }
            }
        }
    }
    CustomClassWriter writer = new CustomClassWriter(ClassWriter.COMPUTE_MAXS | ClassWriter.COMPUTE_FRAMES);
    classNode.accept(writer);
    return writer.toByteArray();
}
Also used : LabelNode(org.objectweb.asm.tree.LabelNode) ClassNode(org.objectweb.asm.tree.ClassNode) MethodNode(org.objectweb.asm.tree.MethodNode) MethodInsnNode(org.objectweb.asm.tree.MethodInsnNode) ClassReader(org.objectweb.asm.ClassReader) JumpInsnNode(org.objectweb.asm.tree.JumpInsnNode) VarInsnNode(org.objectweb.asm.tree.VarInsnNode) AbstractInsnNode(org.objectweb.asm.tree.AbstractInsnNode) InsnList(org.objectweb.asm.tree.InsnList) LocalVariableNode(org.objectweb.asm.tree.LocalVariableNode)

Aggregations

JumpInsnNode (org.objectweb.asm.tree.JumpInsnNode)49 LabelNode (org.objectweb.asm.tree.LabelNode)36 MethodInsnNode (org.objectweb.asm.tree.MethodInsnNode)28 AbstractInsnNode (org.objectweb.asm.tree.AbstractInsnNode)26 InsnNode (org.objectweb.asm.tree.InsnNode)25 VarInsnNode (org.objectweb.asm.tree.VarInsnNode)24 InsnList (org.objectweb.asm.tree.InsnList)22 FieldInsnNode (org.objectweb.asm.tree.FieldInsnNode)19 LdcInsnNode (org.objectweb.asm.tree.LdcInsnNode)18 MethodNode (org.objectweb.asm.tree.MethodNode)18 TypeInsnNode (org.objectweb.asm.tree.TypeInsnNode)15 ClassNode (org.objectweb.asm.tree.ClassNode)14 ClassReader (org.objectweb.asm.ClassReader)12 Label (org.objectweb.asm.Label)11 Type (org.objectweb.asm.Type)9 LocalVariable (org.develnext.jphp.core.compiler.jvm.misc.LocalVariable)6 LineNumberNode (org.objectweb.asm.tree.LineNumberNode)4 LinkedList (java.util.LinkedList)3 Mutation (org.evosuite.coverage.mutation.Mutation)3 FieldNode (org.objectweb.asm.tree.FieldNode)3