Example usage for org.objectweb.asm.tree AbstractInsnNode getPrevious

List of usage examples for org.objectweb.asm.tree AbstractInsnNode getPrevious

Introduction

In this page you can find the example usage for org.objectweb.asm.tree AbstractInsnNode getPrevious.

Prototype

public AbstractInsnNode getPrevious() 

Source Link

Document

Returns the previous instruction in the list to which this instruction belongs, if any.

Usage

From source file:jaspex.speculation.newspec.FlowFrame.java

License:Open Source License

/** Obtm label antes da instruco. Se j existir uma,  reutilizada, cc uma nova  criada. **/
public static LabelNode labelBefore(InsnList il, AbstractInsnNode insn) {
    if (!(insn.getPrevious() instanceof LabelNode)) {
        il.insertBefore(insn, new LabelNode());
    }//  w  w  w.j  a va 2s .c om

    return (LabelNode) insn.getPrevious();
}

From source file:jvstm.atomic.ProcessParNestAnnotations.java

License:Open Source License

protected static void processClassFile(File classFile) {
    alreadyProcessed = new ArrayList<String>();
    callablesCreated = new HashMap<String, String>();
    InputStream is = null;//from w  ww. ja  v a  2s.c om

    try {
        // get an input stream to read the bytecode of the class
        is = new FileInputStream(classFile);
        ClassNode cn = new ClassNode(ASM4);
        ClassReader cr = new ClassReader(is);
        cr.accept(cn, 0);

        List<MethodNode> parNestedMethods = new ArrayList<MethodNode>();
        MethodNode combinerMethod = null;
        MethodNode execMethod = null;

        List<MethodNode> staticMethodsToAdd = new ArrayList<MethodNode>();

        boolean parallelSpawn = extendsParallelSpawn(cn);
        boolean unsafeSpawn = extendsUnsafeSpawn(cn);
        if (parallelSpawn || unsafeSpawn) {
            Iterator<MethodNode> methodIter = cn.methods.iterator();
            while (methodIter.hasNext()) {
                MethodNode mn = methodIter.next();
                if (mn.name.equals("exec") && execMethod == null) {
                    execMethod = mn;
                    continue;
                }
                if (mn.invisibleAnnotations == null) {
                    continue;
                }
                for (AnnotationNode an : mn.invisibleAnnotations) {
                    if (an.desc.equals(PAR_NEST.getDescriptor())) {
                        // Ensure the method can be called from outside
                        mn.access = (mn.access & ~ACC_PRIVATE) | ACC_PUBLIC;
                        parNestedMethods.add(mn);
                        String uniqueMethodName = createUniqueMethodName(mn.name);
                        String callableClass;
                        if (parallelSpawn) {
                            callableClass = cn.name + "$nested$work$unit$" + uniqueMethodName;
                        } else {
                            callableClass = cn.name + "$unsafe$work$unit$" + uniqueMethodName;
                        }
                        callablesCreated.put(mn.name, callableClass);
                        boolean readOnlyCallable = (an.values == null) ? false : (Boolean) an.values.get(1);
                        generateCallable(classFile, cn.name, callableClass, mn, readOnlyCallable, unsafeSpawn);
                        staticMethodsToAdd.add(generateStaticCallableCreation(cn, cn.name, callableClass, mn));
                        break;
                    } else if (an.desc.equals(COMBINER.getDescriptor())) {
                        if (combinerMethod != null) {
                            throw new RuntimeException("Class: " + cn.name + " contains two @Combiner methods: "
                                    + combinerMethod.name + " and " + mn.name);
                        }
                        combinerMethod = mn;
                    }
                }
            }

            // TODO Verify the @Combiner method
            // The return should be of the same type of the parameterization
            // of the ParallelSpawn

            for (MethodNode methodToAdd : staticMethodsToAdd) {
                cn.methods.add(methodToAdd);
            }

            if (alreadyProcessed.size() == 0) {
                throw new RuntimeException(
                        "Class: " + cn.name + " must have at least one method annotated with @ParNested");
            }
            if (combinerMethod == null) {
                throw new RuntimeException(
                        "Class: " + cn.name + " must have one method annotated with @Combiner");
            }

            List<Integer> localVariablesIdx = new ArrayList<Integer>();
            int numberLocalVariables = 0;
            int listIndex = execMethod.maxLocals;
            execMethod.maxLocals++;

            InsnList preamble = new InsnList();
            preamble.add(new TypeInsnNode(NEW, ARRAY_LIST.getInternalName()));
            preamble.add(new InsnNode(DUP));
            preamble.add(new MethodInsnNode(INVOKESPECIAL, ARRAY_LIST.getInternalName(), "<init>", "()V"));
            preamble.add(new VarInsnNode(ASTORE, listIndex));

            Iterator<AbstractInsnNode> execInstIter = execMethod.instructions.iterator();
            while (execInstIter.hasNext()) {
                AbstractInsnNode instr = execInstIter.next();
                // Look out for calls to methods
                if (instr.getOpcode() == INVOKEVIRTUAL || instr.getOpcode() == INVOKESPECIAL) {
                    MethodInsnNode methodInstr = (MethodInsnNode) instr;
                    // Is method being called annotated with @ParNested
                    for (MethodNode parNestedMethod : parNestedMethods) {
                        if (parNestedMethod.name.equals(methodInstr.name)) {
                            numberLocalVariables++;
                        }
                    }
                }
            }

            for (int i = 0; i < numberLocalVariables; i++) {
                localVariablesIdx.add(i, execMethod.maxLocals);
                execMethod.maxLocals++;
            }

            int callablesManipulated = 0;
            execInstIter = execMethod.instructions.iterator();
            while (execInstIter.hasNext()) {
                AbstractInsnNode instr = execInstIter.next();
                // Look out for calls to methods
                if (instr.getOpcode() != INVOKEVIRTUAL && instr.getOpcode() != INVOKESPECIAL) {
                    continue;
                }

                MethodInsnNode methodInstr = (MethodInsnNode) instr;
                // Is method being called annotated with @ParNested
                boolean isParNestedMethod = false;
                for (MethodNode parNestedMethod : parNestedMethods) {
                    if (parNestedMethod.name.equals(methodInstr.name)) {
                        isParNestedMethod = true;
                        break;
                    }
                }
                if (!isParNestedMethod) {
                    continue;
                }

                // Let's change this call
                // If it was a call to: @ParNested public int add(int i1,
                // int i2)
                // add(foo, bar) -> add$static$callable$creator(this, foo,
                // bar)
                // the 'this' will be already in the right place in the
                // stack
                // because the method being called now is static whereas
                // previously
                // it was not
                methodInstr.setOpcode(INVOKESTATIC);
                methodInstr.name = methodInstr.name + "$static$callable$creator";
                for (MethodNode staticCreated : staticMethodsToAdd) {
                    if (staticCreated.name.equals(methodInstr.name)) {
                        methodInstr.desc = staticCreated.desc;
                        break;
                    }
                }

                InsnList midterm = new InsnList();

                // Store the callable instantiated in local variable
                midterm.add(new VarInsnNode(ASTORE, localVariablesIdx.get(callablesManipulated)));
                // Load the list
                midterm.add(new VarInsnNode(ALOAD, listIndex));
                // Load the callable
                midterm.add(new VarInsnNode(ALOAD, localVariablesIdx.get(callablesManipulated)));
                // Add it to the list
                midterm.add(new MethodInsnNode(INVOKEVIRTUAL, ARRAY_LIST.getInternalName(), "add",
                        "(Ljava/lang/Object;)Z"));
                // Pop the boolean that results from the add(Object)
                // May reuse a POP if the previous call had a return
                if (methodInstr.getNext().getOpcode() != POP) {
                    midterm.add(new InsnNode(POP));
                }

                // Add this set of instructions after the call to the
                // constrution of the callable
                execMethod.instructions.insert(methodInstr, midterm);
                callablesManipulated++;

            }

            // Insert the preamble in the start
            execMethod.instructions.insert(preamble);

            InsnList finish = new InsnList();
            // Push 'this' for the call to the combiner method
            finish.add(new VarInsnNode(ALOAD, 0));
            // Call the static method current() of jvstm.Transaction
            finish.add(new MethodInsnNode(INVOKESTATIC, TRANSACTION.getInternalName(), "current",
                    "()Ljvstm/Transaction;"));
            // Load the callables list
            finish.add(new VarInsnNode(ALOAD, listIndex));
            // Call the manage parnested method
            finish.add(new MethodInsnNode(INVOKEVIRTUAL, TRANSACTION.getInternalName(),
                    "manageNestedParallelTxs", "(Ljava/util/List;)Ljava/util/List;"));
            // Call the combiner method
            finish.add(new MethodInsnNode(INVOKEVIRTUAL, cn.name, combinerMethod.name, combinerMethod.desc));
            // Return what the combiner returns
            finish.add(new InsnNode(ARETURN));

            // Remove the "return null" that's supposed to be at the end of
            // the exec method
            execInstIter = execMethod.instructions.iterator();
            while (execInstIter.hasNext()) {
                AbstractInsnNode curNode = execInstIter.next();
                if (!execInstIter.hasNext()) {
                    // Insert the finish in the end
                    execMethod.instructions.insert(curNode.getPrevious().getPrevious(), finish);
                    execMethod.instructions.remove(curNode.getPrevious());
                    execMethod.instructions.remove(curNode);
                    break;
                }
            }

        }

        ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS);
        cn.accept(cw);
        writeClassFile(classFile, cw.toByteArray());
    } catch (IOException e) {
        throw new Error("Error processing class file", e);
    } finally {
        if (is != null) {
            try {
                is.close();
            } catch (IOException e) {
            }
        }
    }
}

From source file:net.cazzar.corelib.asm.MethodTransformer.java

License:Open Source License

/**
 * Append the instructions to the method
 *
 * @param node               the Class being worked on
 * @param access             the Opcode access to the class
 * @param name               the name of the function
 * @param desc               the method description
 * @param insnList           the instructions to append
 * @param tryCatchBlockNodes a/*from  ww w  .  j  a  v  a 2s  . c  o  m*/
 */

public final void appendToMethod(ClassNode node, int access, String name, String desc, InsnList insnList,
        TryCatchBlockNode... tryCatchBlockNodes) {
    InsnList insns = transformInsns(insnList);
    String srgName = getMapping(name);
    List<MethodDescription> methodNames = Lists.newArrayList(new MethodDescription(name, desc),
            new MethodDescription(srgName, desc), McpMappings.instance().getMethod(srgName));

    MethodNode mtd = new MethodNode(access, srgName, desc, null, null);
    Collections.addAll(mtd.tryCatchBlocks, tryCatchBlockNodes);
    for (MethodNode methodNode : node.methods) {
        for (MethodDescription match : methodNames) {
            if (match == null)
                continue;
            if (methodNode.name.equals(match.getName()) && methodNode.desc.equals(match.getDesc())) {
                AbstractInsnNode lastInsn = methodNode.instructions.getLast();
                while (lastInsn instanceof LabelNode || lastInsn instanceof LineNumberNode)
                    lastInsn = lastInsn.getPrevious();

                if (isReturn(lastInsn))
                    methodNode.instructions.insertBefore(lastInsn, insns);
                else
                    methodNode.instructions.add(insns);
            }
        }
    }
}

From source file:net.lyonlancer5.mcmp.karasu.asm.KarasuTransformer.java

License:Apache License

private static void transformEntityLivingBase(ClassNode classNode) {
    Constants.LOGGER.info("======== Project Karasu ~ Water Walking Enchantment Patch ========");
    Constants.LOGGER.info("Patching net.minecraft.entity.EntityLivingBase");

    for (MethodNode method : classNode.methods) {
        if (method.desc.equals("(FF)V")) {

            AbstractInsnNode movefNode = null;
            AbstractInsnNode motionxNode = null;
            AbstractInsnNode motionzNode = null;
            AbstractInsnNode motionyNode = null;
            AbstractInsnNode[] moveList = method.instructions.toArray();
            int var11 = moveList.length;

            for (int var12 = 0; var12 < var11; ++var12) {
                AbstractInsnNode instruction = moveList[var12];
                if (instruction.getOpcode() == Opcodes.ALOAD) {
                    if (((VarInsnNode) instruction).var == 0 && instruction.getNext().getOpcode() == Opcodes.DUP
                            && motionxNode == null) {
                        motionxNode = instruction;
                    } else if (((VarInsnNode) instruction).var == 0
                            && instruction.getNext().getOpcode() == Opcodes.DUP && motionyNode == null) {
                        motionyNode = instruction;
                    } else if (((VarInsnNode) instruction).var == 0
                            && instruction.getNext().getOpcode() == Opcodes.DUP && motionzNode == null) {
                        motionzNode = instruction;
                    } else if (movefNode == null && ((VarInsnNode) instruction).var == 0
                            && instruction.getNext().getOpcode() == Opcodes.FLOAD
                            && ((VarInsnNode) instruction.getNext()).var == 1) {
                        movefNode = instruction;
                    }//ww w .j  a  v a2s  .c om
                }
            }

            int var14;
            InsnList var15;

            if (method.name.equals("e")) {
                Constants.LOGGER.info("Found matching method: " + method.name + " " + method.desc + " - (Obf)");
                if (motionxNode != null) {
                    for (var14 = 0; var14 < 6; ++var14) {
                        motionxNode = motionxNode.getNext();
                        method.instructions.remove(motionxNode.getPrevious());
                    }
                    Constants.LOGGER.info("Patching sv.w");
                    var15 = new InsnList();
                    var15.add(new VarInsnNode(Opcodes.ALOAD, 0));
                    var15.add(new InsnNode(Opcodes.DUP));
                    var15.add(new FieldInsnNode(Opcodes.GETFIELD, "net/minecraft/entity/EntityLivingBase", "w",
                            "D"));
                    var15.add(new MethodInsnNode(Opcodes.INVOKESTATIC,
                            "net/lyonlancer5/mcmp/karasu/asm/KarasuFeatherMetadata", "modifyHorizontalVel",
                            "()D", false));
                    var15.add(new InsnNode(Opcodes.DMUL));
                    var15.add(new FieldInsnNode(Opcodes.PUTFIELD, "net/minecraft/entity/EntityLivingBase", "w",
                            "D"));
                    method.instructions.insertBefore(motionxNode, var15);
                    Constants.LOGGER.info("Patched sv.w");
                }

                if (motionzNode != null) {
                    for (var14 = 0; var14 < 6; ++var14) {
                        motionzNode = motionzNode.getNext();
                        method.instructions.remove(motionzNode.getPrevious());
                    }

                    Constants.LOGGER.info("Patching sv.y");
                    var15 = new InsnList();
                    var15.add(new VarInsnNode(Opcodes.ALOAD, 0));
                    var15.add(new InsnNode(Opcodes.DUP));
                    var15.add(new FieldInsnNode(Opcodes.GETFIELD, "net/minecraft/entity/EntityLivingBase", "y",
                            "D"));
                    var15.add(new MethodInsnNode(Opcodes.INVOKESTATIC,
                            "net/lyonlancer5/mcmp/karasu/asm/KarasuFeatherMetadata", "modifyHorizontalVel",
                            "()D", false));
                    var15.add(new InsnNode(Opcodes.DMUL));
                    var15.add(new FieldInsnNode(Opcodes.PUTFIELD, "net/minecraft/entity/EntityLivingBase", "y",
                            "D"));
                    method.instructions.insertBefore(motionzNode, var15);
                    Constants.LOGGER.info("Patched sv.y");
                }

                if (movefNode != null) {
                    for (var14 = 0; var14 < 14; ++var14) {
                        movefNode = movefNode.getNext();
                        method.instructions.remove(movefNode.getPrevious());
                    }

                    var15 = new InsnList();
                    var15.add(new VarInsnNode(Opcodes.ALOAD, 0));
                    var15.add(new VarInsnNode(Opcodes.FLOAD, 1));
                    var15.add(new VarInsnNode(Opcodes.FLOAD, 2));
                    var15.add(new MethodInsnNode(Opcodes.INVOKESTATIC,
                            "net/lyonlancer5/mcmp/karasu/asm/KarasuFeatherMetadata", "modifyVerticalVel", "()F",
                            false));
                    var15.add(new MethodInsnNode(Opcodes.INVOKEVIRTUAL, "net/minecraft/entity/EntityLivingBase",
                            "a", "(FFF)V", false));
                    method.instructions.insertBefore(movefNode, var15);
                    Constants.LOGGER.info("Patching method -- sv.a (FFF)V");
                }

                Constants.LOGGER.info("Patch success!");
                return;
            } else if (method.name.equals("moveEntityWithHeading")) {
                Constants.LOGGER
                        .info("Found matching method: " + method.name + " " + method.desc + " - (Deobf)");
                if (motionxNode != null) {
                    for (var14 = 0; var14 < 6; ++var14) {
                        motionxNode = motionxNode.getNext();
                        method.instructions.remove(motionxNode.getPrevious());
                    }

                    Constants.LOGGER.info("Patching EntityLivingBase.motionX");
                    var15 = new InsnList();
                    var15.add(new VarInsnNode(Opcodes.ALOAD, 0));
                    var15.add(new InsnNode(Opcodes.DUP));
                    var15.add(new FieldInsnNode(Opcodes.GETFIELD, "net/minecraft/entity/EntityLivingBase",
                            "motionX", "D"));
                    var15.add(new MethodInsnNode(Opcodes.INVOKESTATIC,
                            "net/lyonlancer5/mcmp/karasu/asm/KarasuFeatherMetadata", "modifyHorizontalVel",
                            "()D", false));
                    var15.add(new InsnNode(Opcodes.DMUL));
                    var15.add(new FieldInsnNode(Opcodes.PUTFIELD, "net/minecraft/entity/EntityLivingBase",
                            "motionX", "D"));
                    method.instructions.insertBefore(motionxNode, var15);
                    Constants.LOGGER.info("Patched EntityLivingBase.motionX");
                }

                if (motionzNode != null) {
                    for (var14 = 0; var14 < 6; ++var14) {
                        motionzNode = motionzNode.getNext();
                        method.instructions.remove(motionzNode.getPrevious());
                    }

                    Constants.LOGGER.info("Patching EntityLivingBase.motionZ");
                    var15 = new InsnList();
                    var15.add(new VarInsnNode(Opcodes.ALOAD, 0));
                    var15.add(new InsnNode(Opcodes.DUP));
                    var15.add(new FieldInsnNode(Opcodes.GETFIELD, "net/minecraft/entity/EntityLivingBase",
                            "motionZ", "D"));
                    var15.add(new MethodInsnNode(Opcodes.INVOKESTATIC,
                            "net/lyonlancer5/mcmp/karasu/asm/KarasuFeatherMetadata", "modifyHorizontalVel",
                            "()D", false));
                    var15.add(new InsnNode(Opcodes.DMUL));
                    var15.add(new FieldInsnNode(Opcodes.PUTFIELD, "net/minecraft/entity/EntityLivingBase",
                            "motionZ", "D"));
                    method.instructions.insertBefore(motionzNode, var15);
                    Constants.LOGGER.info("Patched EntityLivingBase.motionZ");
                }

                if (movefNode != null) {
                    for (var14 = 0; var14 < 14; ++var14) {
                        movefNode = movefNode.getNext();
                        method.instructions.remove(movefNode.getPrevious());
                    }

                    var15 = new InsnList();
                    var15.add(new VarInsnNode(Opcodes.ALOAD, 0));
                    var15.add(new VarInsnNode(Opcodes.FLOAD, 1));
                    var15.add(new VarInsnNode(Opcodes.FLOAD, 2));
                    var15.add(new MethodInsnNode(Opcodes.INVOKESTATIC,
                            "net/lyonlancer5/mcmp/karasu/asm/KarasuFeatherMetadata", "modifyVerticalVel", "()F",
                            false));
                    var15.add(new MethodInsnNode(Opcodes.INVOKEVIRTUAL, "net/minecraft/entity/EntityLivingBase",
                            "moveFlying", "(FFF)V", false));
                    method.instructions.insertBefore(movefNode, var15);
                    Constants.LOGGER.info("Patched method - EntityLivingBase.moveFlying (FFF)V");
                }

                Constants.LOGGER.info("Patch success!");
                return;
            } else if (method.name.equals("func_70612_e")) {
                Constants.LOGGER.info("Found matching method: " + method.name + " " + method.desc + " - (srg)");
                if (motionxNode != null) {
                    for (var14 = 0; var14 < 6; ++var14) {
                        motionxNode = motionxNode.getNext();
                        method.instructions.remove(motionxNode.getPrevious());
                    }

                    Constants.LOGGER.info("Patching EntityLivingBase.field_70159_w");
                    var15 = new InsnList();
                    var15.add(new VarInsnNode(Opcodes.ALOAD, 0));
                    var15.add(new InsnNode(Opcodes.DUP));
                    var15.add(new FieldInsnNode(Opcodes.GETFIELD, "net/minecraft/entity/EntityLivingBase",
                            "field_70159_w", "D"));
                    var15.add(new MethodInsnNode(Opcodes.INVOKESTATIC,
                            "net/lyonlancer5/mcmp/karasu/asm/KarasuFeatherMetadata", "modifyHorizontalVel",
                            "()D", false));
                    var15.add(new InsnNode(Opcodes.DMUL));
                    var15.add(new FieldInsnNode(Opcodes.PUTFIELD, "net/minecraft/entity/EntityLivingBase",
                            "field_70159_w", "D"));
                    method.instructions.insertBefore(motionxNode, var15);
                    Constants.LOGGER.info("Patched EntityLivingBase.field_70159_w");
                }

                if (motionzNode != null) {
                    for (var14 = 0; var14 < 6; ++var14) {
                        motionzNode = motionzNode.getNext();
                        method.instructions.remove(motionzNode.getPrevious());
                    }

                    Constants.LOGGER.info("Patching EntityLivingBase.field_70179_y");
                    var15 = new InsnList();
                    var15.add(new VarInsnNode(Opcodes.ALOAD, 0));
                    var15.add(new InsnNode(Opcodes.DUP));
                    var15.add(new FieldInsnNode(Opcodes.GETFIELD, "net/minecraft/entity/EntityLivingBase",
                            "field_70179_y", "D"));
                    var15.add(new MethodInsnNode(Opcodes.INVOKESTATIC,
                            "net/lyonlancer5/mcmp/karasu/asm/KarasuFeatherMetadata", "modifyHorizontalVel",
                            "()D", false));
                    var15.add(new InsnNode(Opcodes.DMUL));
                    var15.add(new FieldInsnNode(Opcodes.PUTFIELD, "net/minecraft/entity/EntityLivingBase",
                            "field_70179_y", "D"));
                    method.instructions.insertBefore(motionzNode, var15);
                    Constants.LOGGER.info("Patched EntityLivingBase.field_70179_y");
                }

                if (movefNode != null) {
                    for (var14 = 0; var14 < 14; ++var14) {
                        movefNode = movefNode.getNext();
                        method.instructions.remove(movefNode.getPrevious());
                    }

                    var15 = new InsnList();
                    var15.add(new VarInsnNode(Opcodes.ALOAD, 0));
                    var15.add(new VarInsnNode(Opcodes.FLOAD, 1));
                    var15.add(new VarInsnNode(Opcodes.FLOAD, 2));
                    var15.add(new MethodInsnNode(Opcodes.INVOKESTATIC,
                            "net/lyonlancer5/mcmp/karasu/asm/KarasuFeatherMetadata", "modifyVerticalVel", "()F",
                            false));
                    var15.add(new MethodInsnNode(Opcodes.INVOKEVIRTUAL, "net/minecraft/entity/EntityLivingBase",
                            "func_70060_a", "(FFF)V", false));
                    method.instructions.insertBefore(movefNode, var15);
                    Constants.LOGGER.info("Patched method - EntityLivingBase.func_70060_a (FFF)V");
                }

                Constants.LOGGER.info("Patch success!");
                return;
            }
        }
    }
    // #OVERKILL
    throw new RuntimeException("Patch FAILED -- No matching method found");

}

From source file:net.minecraftforge.fml.common.asm.transformers.SoundEngineFixTransformer.java

License:Open Source License

@Override
public byte[] transform(String name, String transformedName, byte[] basicClass) {
    if (transformedName.equals("paulscode.sound.Source")) {
        ClassNode classNode = new ClassNode();
        ClassReader classReader = new ClassReader(basicClass);
        classReader.accept(classNode, 0);

        classNode.fields.add(new FieldNode(Opcodes.ACC_PUBLIC, "removed", "Z", null, null)); // adding field 'public boolean removed;'

        ClassWriter writer = new ClassWriter(ClassWriter.COMPUTE_MAXS);
        classNode.accept(writer);/*w  w  w  . j ava 2s. c  om*/
        return writer.toByteArray();
    } else if (transformedName.equals("paulscode.sound.Library")) {
        ClassNode classNode = new ClassNode();
        ClassReader classReader = new ClassReader(basicClass);
        classReader.accept(classNode, 0);

        MethodNode method = null;
        for (MethodNode m : classNode.methods) {
            if (m.name.equals("removeSource") && m.desc.equals("(Ljava/lang/String;)V")) // trying to find paulscode.sound.Library.removeSource(String)
            {
                method = m;
                break;
            }
        }
        if (method == null)
            throw new RuntimeException(
                    "Error processing " + transformedName + " - no removeSource method found");

        AbstractInsnNode referenceNode = null;

        for (Iterator<AbstractInsnNode> iterator = method.instructions.iterator(); iterator.hasNext();) {
            AbstractInsnNode insn = iterator.next();
            if (insn instanceof MethodInsnNode && ((MethodInsnNode) insn).owner.equals("paulscode/sound/Source") // searching for mySource.cleanup() node (line 1086)
                    && ((MethodInsnNode) insn).name.equals("cleanup")) {
                referenceNode = insn;
                break;
            }
        }

        if (referenceNode != null) {
            LabelNode after = (LabelNode) referenceNode.getNext();

            AbstractInsnNode beginning = referenceNode.getPrevious();

            int varIndex = ((VarInsnNode) beginning).var;

            method.instructions.insertBefore(beginning, new VarInsnNode(Opcodes.ALOAD, varIndex)); // adding extra if (mySource.toStream)
            method.instructions.insertBefore(beginning,
                    new FieldInsnNode(Opcodes.GETFIELD, "paulscode/sound/Source", "toStream", "Z"));
            LabelNode elseNode = new LabelNode();
            method.instructions.insertBefore(beginning, new JumpInsnNode(Opcodes.IFEQ, elseNode)); // if fails (else) -> go to mySource.cleanup();

            method.instructions.insertBefore(beginning, new VarInsnNode(Opcodes.ALOAD, varIndex)); // if (mySource.toStream) { mySource.removed = true; }
            method.instructions.insertBefore(beginning, new InsnNode(Opcodes.ICONST_1));
            method.instructions.insertBefore(beginning,
                    new FieldInsnNode(Opcodes.PUTFIELD, "paulscode/sound/Source", "removed", "Z"));

            method.instructions.insertBefore(beginning, new JumpInsnNode(Opcodes.GOTO, after)); // still inside if -> jump to sourceMap.remove( sourcename );

            method.instructions.insertBefore(beginning, elseNode);
        }

        ClassWriter writer = new ClassWriter(ClassWriter.COMPUTE_MAXS);
        classNode.accept(writer);
        return writer.toByteArray();
    } else if (transformedName.equals("paulscode.sound.StreamThread")) {
        ClassNode classNode = new ClassNode();
        ClassReader classReader = new ClassReader(basicClass);
        classReader.accept(classNode, 0);

        MethodNode method = null;
        for (MethodNode m : classNode.methods) {
            if (m.name.equals("run") && m.desc.equals("()V")) // trying to find paulscode.sound.StreamThread.run();
            {
                method = m;
                break;
            }
        }
        if (method == null)
            throw new RuntimeException("Error processing " + transformedName + " - no run method found");

        AbstractInsnNode referenceNode = null;

        for (Iterator<AbstractInsnNode> iterator = method.instructions.iterator(); iterator.hasNext();) {
            AbstractInsnNode insn = iterator.next();
            if (insn instanceof MethodInsnNode && ((MethodInsnNode) insn).owner.equals("java/util/ListIterator") // searching for 'src = iter.next();' node (line 110)
                    && ((MethodInsnNode) insn).name.equals("next")) {
                referenceNode = insn.getNext().getNext();
                break;
            }
        }

        if (referenceNode != null) {
            int varIndex = ((VarInsnNode) referenceNode).var;

            LabelNode after = (LabelNode) referenceNode.getNext();
            method.instructions.insertBefore(after, new VarInsnNode(Opcodes.ALOAD, varIndex)); // add if(removed)
            method.instructions.insertBefore(after,
                    new FieldInsnNode(Opcodes.GETFIELD, "paulscode/sound/Source", "removed", "Z"));
            method.instructions.insertBefore(after, new JumpInsnNode(Opcodes.IFEQ, after));

            // if the source has been marked as removed, clean it up and set the variable to null so it will be removed from the list
            method.instructions.insertBefore(after, new VarInsnNode(Opcodes.ALOAD, varIndex)); // src.cleanup();
            method.instructions.insertBefore(after, new MethodInsnNode(Opcodes.INVOKEVIRTUAL,
                    "paulscode/sound/Source", "cleanup", "()V", false));
            method.instructions.insertBefore(after, new InsnNode(Opcodes.ACONST_NULL)); // src = null;
            method.instructions.insertBefore(after, new VarInsnNode(Opcodes.ASTORE, varIndex));
        }

        ClassWriter writer = new ClassWriter(ClassWriter.COMPUTE_MAXS);
        classNode.accept(writer);
        return writer.toByteArray();
    }

    return basicClass;
}

From source file:nova.core.wrapper.mc.forge.v17.asm.transformers.ChunkTransformer.java

License:Open Source License

@Override
public void transform(ClassNode cnode) {
    System.out.println("[NOVA] Transforming Chunk class for chunkModified event.");

    ObfMapping obfMap = new ObfMapping("apx", "a", "(IIILaji;I)Z");
    ObfMapping srgMap = new ObfMapping("net/minecraft/world/chunk/Chunk", "func_150807_a",
            "(IIILnet/minecraft/block/Block;I)Z");

    MethodNode method = ASMHelper.findMethod(obfMap, cnode);

    if (method == null) {
        System.out.println("[NOVA] Lookup " + obfMap + " failed. You are probably in a deobf environment.");
        method = ASMHelper.findMethod(srgMap, cnode);

        if (method == null) {
            System.out.println("[NOVA] Lookup " + srgMap + " failed!");
        }/* w  w  w  .  ja  v a2s  .  c om*/
    }

    System.out.println("[NOVA] Found method " + method.name);

    InsnList list = new InsnList();
    list.add(new VarInsnNode(ALOAD, 0));
    list.add(new VarInsnNode(ILOAD, 1));
    list.add(new VarInsnNode(ILOAD, 2));
    list.add(new VarInsnNode(ILOAD, 3));
    list.add(new VarInsnNode(ALOAD, 8));
    list.add(new VarInsnNode(ILOAD, 9));
    list.add(new VarInsnNode(ALOAD, 4));
    list.add(new VarInsnNode(ILOAD, 5));
    list.add(new MethodInsnNode(INVOKESTATIC, "nova/core/wrapper/mc/forge/v17/asm/StaticForwarder",
            "chunkSetBlockEvent",
            "(Lnet/minecraft/world/chunk/Chunk;IIILnet/minecraft/block/Block;ILnet/minecraft/block/Block;I)V",
            false));

    AbstractInsnNode lastInsn = method.instructions.getLast();
    while (lastInsn instanceof LabelNode || lastInsn instanceof LineNumberNode) {
        lastInsn = lastInsn.getPrevious();
    }

    if (ASMHelper.isReturn(lastInsn)) {
        method.instructions.insertBefore(lastInsn, list);
    } else {
        method.instructions.insert(list);
    }

    System.out.println("[NOVA] Injected instruction to method: " + method.name);
}

From source file:nova.core.wrapper.mc.forge.v18.asm.transformers.ChunkTransformer.java

License:Open Source License

@Override
public void transform(ClassNode cnode) {
    System.out.println("[NOVA] Transforming Chunk class for chunkModified event.");

    //obf name: func_177436_a
    MethodNode method = ASMHelper.findMethod(new ObfMapping("net/minecraft/world/chunk/Chunk", "setBlockState",
            "(Lnet/minecraft/util/BlockPos;Lnet/minecraft/block/state/IBlockState;)Lnet/minecraft/block/state/IBlockState;"),
            cnode);//  ww  w. j av  a 2  s  .com

    System.out.println("[NOVA] Found method " + method.name);

    InsnList list = new InsnList();
    list.add(new VarInsnNode(ALOAD, 0)); //this
    list.add(new VarInsnNode(ALOAD, 1)); //BlockPos
    list.add(new VarInsnNode(ALOAD, 8)); //oldBlock IBlockState
    list.add(new VarInsnNode(ALOAD, 2)); //newBlock IBlockState
    list.add(new MethodInsnNode(INVOKESTATIC, "nova/core/wrapper/mc/forge/v18/asm/StaticForwarder",
            "chunkSetBlockEvent",
            "(Lnet/minecraft/world/chunk/Chunk;Lnet/minecraft/util/BlockPos;Lnet/minecraft/block/state/IBlockState;Lnet/minecraft/block/state/IBlockState;)V",
            false));

    AbstractInsnNode lastInsn = method.instructions.getLast();
    while (lastInsn instanceof LabelNode || lastInsn instanceof LineNumberNode) {
        lastInsn = lastInsn.getPrevious();
    }

    if (ASMHelper.isReturn(lastInsn)) {
        method.instructions.insertBefore(lastInsn, list);
    } else {
        method.instructions.insert(list);
    }

    System.out.println("[NOVA] Injected instruction to method: " + method.name);
}

From source file:org.coldswap.asm.field.PrivateStaticFieldReplacer.java

License:Open Source License

/**
 * Removes any initializing reference of the field.
 *
 * @param classNode containing the old class.
 * @param fieldNode containing the old field.
 * @return the initializing list of instructions.
 *//*  ww  w. ja  v a2 s  . c o  m*/
@SuppressWarnings("unchecked")
private InsnList cleanClInit(ClassNode classNode, FieldNode fieldNode) {
    List<MethodNode> methodNodes = classNode.methods;
    AbstractInsnNode firstInst = null;
    int counter = 0;
    for (MethodNode methodNode : methodNodes) {
        if (methodNode.name.equals("<clinit>")) {
            // search for PUTSTATIC
            InsnList insnList = methodNode.instructions;
            Iterator iterator1 = insnList.iterator();
            while (iterator1.hasNext()) {
                AbstractInsnNode ins2 = (AbstractInsnNode) iterator1.next();
                // if a initializing has been found, then copy everything from
                // the corresponding label to the PUTSTATIC
                if (ins2.getOpcode() == Opcodes.PUTSTATIC) {
                    final Boolean[] fieldFound = { false };
                    final FieldNode fNode = fieldNode;
                    ins2.accept(new MethodVisitor(Opcodes.ASM5) {
                        @Override
                        public void visitFieldInsn(int i, String s, String s2, String s3) {
                            if (s2.equals(fNode.name)) {
                                fieldFound[0] = true;
                            }
                            super.visitFieldInsn(i, s, s2, s3);
                        }
                    });
                    if (fieldFound[0]) {
                        // find the first PUTSTATIC before this one.
                        boolean staticFound = false;
                        while (!staticFound) {
                            AbstractInsnNode tmpInst = ins2.getPrevious();
                            if (tmpInst != null) {
                                if (tmpInst.getOpcode() != Opcodes.F_NEW) {
                                    if (tmpInst.getOpcode() == Opcodes.PUTSTATIC) {
                                        staticFound = true;
                                    } else {
                                        firstInst = tmpInst;
                                        counter++;
                                    }
                                }
                            } else {
                                staticFound = true;
                            }
                            ins2 = tmpInst;
                        }

                        break;
                    }
                }
            }

            if (firstInst != null) {
                InsnList iList = new InsnList();
                iList.add(firstInst.clone(null));
                counter--;
                while (counter > 0) {
                    AbstractInsnNode ain = firstInst.getNext();
                    iList.add(ain.clone(null));
                    counter--;
                    insnList.remove(firstInst);
                    firstInst = ain;
                }
                // remove last instruction and the putstatic instruction
                AbstractInsnNode putStatic = firstInst.getNext();
                insnList.remove(firstInst);
                insnList.remove(putStatic);
                return iList;
            }
        }
    }
    return null;
}

From source file:org.coldswap.asm.field.ProtectedStaticFieldReplacer.java

License:Open Source License

/**
 * Removes any initializing reference of the field.
 *
 * @param classNode containing the old class.
 * @param fieldNode containing the old field.
 * @param canRemove <code>true</code> if this method should remove the initializing code and return it
 *                  or <code>false</code> if you only want to return the init code.
 * @return the initializing list of instructions.
 *///ww w  .  j a  va2 s  .  co  m
@SuppressWarnings("unchecked")
private InsnList cleanClInit(ClassNode classNode, FieldNode fieldNode, boolean canRemove) {
    List<MethodNode> methodNodes = classNode.methods;
    AbstractInsnNode firstInst = null;
    int counter = 0;
    for (MethodNode methodNode : methodNodes) {
        if (methodNode.name.equals("<clinit>")) {
            // search for PUTSTATIC
            InsnList insnList = methodNode.instructions;
            Iterator iterator1 = insnList.iterator();
            while (iterator1.hasNext()) {
                AbstractInsnNode ins2 = (AbstractInsnNode) iterator1.next();
                // if a initializing has been found, then copy everything from
                // the coresponding label to the PUTSTATIC
                if (ins2.getOpcode() == Opcodes.PUTSTATIC) {
                    final Boolean[] fieldFound = { false };
                    final FieldNode fNode = fieldNode;
                    ins2.accept(new MethodVisitor(Opcodes.ASM5) {
                        @Override
                        public void visitFieldInsn(int i, String s, String s2, String s3) {
                            if (s2.equals(fNode.name)) {
                                fieldFound[0] = true;
                            }
                            super.visitFieldInsn(i, s, s2, s3);
                        }
                    });
                    if (fieldFound[0]) {
                        // find the first PUTSTATIC before this one.
                        boolean staticFound = false;
                        while (!staticFound) {
                            AbstractInsnNode tmpInst = ins2.getPrevious();
                            if (tmpInst != null) {
                                if (tmpInst.getOpcode() != Opcodes.F_NEW) {
                                    if (tmpInst.getOpcode() == Opcodes.PUTSTATIC) {
                                        staticFound = true;
                                    } else {
                                        firstInst = tmpInst;
                                        counter++;
                                    }
                                }
                            } else {
                                staticFound = true;
                            }
                            ins2 = tmpInst;
                        }

                        break;
                    }
                }
            }

            if (firstInst != null) {
                InsnList iList = new InsnList();
                iList.add(firstInst.clone(null));
                counter--;
                while (counter > 0) {
                    AbstractInsnNode ain = firstInst.getNext();
                    iList.add(ain.clone(null));
                    counter--;
                    if (canRemove) {
                        insnList.remove(firstInst);
                    }
                    firstInst = ain;
                }
                if (canRemove) {
                    // remove last instruction and the putstatic instruction
                    AbstractInsnNode putStatic = firstInst.getNext();
                    insnList.remove(firstInst);
                    insnList.remove(putStatic);
                }
                return iList;
            }
        }
    }
    return null;
}

From source file:org.diorite.inject.controller.TransformerInjectTracker.java

License:Open Source License

private AbstractInsnNode skipCheckCastBackwards(AbstractInsnNode node) {
    // skip possible (?) ALOAD 0 if not static
    if (!this.isStatic && (node instanceof VarInsnNode) && (node.getOpcode() == ALOAD)
            && (((VarInsnNode) node).var == 0)) {
        node = node.getPrevious();
    }//from w w w .j a va 2s.  c o m

    // skip possible check cast
    if ((node instanceof TypeInsnNode) && (node.getOpcode() == CHECKCAST)) {
        node = node.getPrevious();
    }

    // skip possible (?) ALOAD 0 if not static
    if (!this.isStatic && (node instanceof VarInsnNode) && (node.getOpcode() == ALOAD)
            && (((VarInsnNode) node).var == 0)) {
        node = node.getPrevious();
    }
    return node;
}