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

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

Introduction

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

Prototype

public void set(final AbstractInsnNode oldInsnNode, final AbstractInsnNode newInsnNode) 

Source Link

Document

Replaces an instruction of this list with another instruction.

Usage

From source file:com.github.fge.grappa.transform.process.GroupClassGenerator.java

License:Apache License

protected static void convertXLoads(InstructionGroup group) {
    String owner = group.getGroupClassType().getInternalName();

    InsnList insnList;

    for (InstructionGraphNode node : group.getNodes()) {
        if (!node.isXLoad())
            continue;

        VarInsnNode insn = (VarInsnNode) node.getInstruction();
        FieldNode field = group.getFields().get(insn.var);
        FieldInsnNode fieldNode = new FieldInsnNode(GETFIELD, owner, field.name, field.desc);

        insnList = group.getInstructions();

        // insert the correct GETFIELD after the xLoad
        insnList.insert(insn, fieldNode);
        // change the load to ALOAD 0
        insnList.set(insn, new VarInsnNode(ALOAD, 0));
    }/*from w  ww . j a  va 2  s.  co m*/
}

From source file:de.tuberlin.uebb.jbop.optimizer.var.LocalVarInliner.java

License:Open Source License

private AbstractInsnNode hanldeLoad(final InsnList original, final AbstractInsnNode currentNode,
        final Map<Integer, Object> knownValues) {
    final int index = NodeHelper.getVarIndex(currentNode);
    if (knownValues.containsKey(index) && currentNode.getNext() != null && currentNode.getPrevious() != null) {
        final Object value = knownValues.get(index);
        final AbstractInsnNode replacement = NodeHelper.getInsnNodeFor(value);
        original.set(currentNode, replacement);
        optimized = true;/*w w  w .jav  a  2  s.c o  m*/
        return replacement;
    }
    return currentNode;
}

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

License:Open Source License

/** Mtodo que implementa a deteco e correco do problema dos mltiplos fluxos de controlo.
  * Retorna true se alterou o mtodo, e false cc.
  **///from   w w w.ja va2s.com
private static boolean computeControlFlowGraph(String owner, String superOwner, MethodNode mn,
        LabelMap labelMap, boolean ranBefore) {
    //Log.debug("Visiting: {}.{}", owner, mn.name);

    FlowAnalyzer analyzer = new FlowAnalyzer(new FutureVerifier(owner, superOwner));

    try {
        analyzer.analyze(owner, mn);
        //if (ranBefore) printCode(mn, Arrays.asList(analyzer.getFrames()), null, null);
        FrameInjector.injectFrames(mn, analyzer.getFrames());
        return false;
    } catch (AnalyzerException e) {
        /*e.printStackTrace();*/ }

    // Se chegmos aqui, o Analyzer detectou problemas, e vamos ter que fazer correces no mtodo

    // Detectar o primeiro LabelNode onde aparece um MergedUninitializedValue
    LabelNode problemLabelNode = null;
    FlowFrame problemFrame = null;
    int problemPosition = -1;
    boolean problemInStack = false;

    List<FlowFrame> frames = listGenericCast(Arrays.asList(analyzer.getFrames()));

    outer: for (int i = 0; i < frames.size(); i++) {
        FlowFrame f = frames.get(i);
        if (f == null)
            continue;

        int localsStartPos = 0;
        int stackStartPos = 0;
        // Identificar se alguma entrada nos locals/stack da frame deve ser escolhida como
        // problemtica
        // Isto  um loop porque algumas das entradas encontradas podem ser backwards edges,
        // e no estamos interessadas nessas
        while (true) {
            for (int j = localsStartPos; j < f.getLocals(); j++) {
                if (f.getLocal(j) instanceof MergedUninitializedValue) {
                    problemPosition = j;
                    problemInStack = false;
                    localsStartPos = j + 1;
                }
            }
            for (int j = stackStartPos; j < f.getStackSize() && (problemPosition < 0); j++) {
                if (f.getStack(j) instanceof MergedUninitializedValue) {
                    problemPosition = j;
                    problemInStack = true;
                    stackStartPos = j + 1;
                }
            }

            // J processamos completamente a frame e no encontramos nada, ou s
            // encontramos backwards edges, passar  prxima
            if (problemPosition < 0)
                continue outer;

            if ((f.predecessors().size() > 0)
                    && (getPredecessorWithFuture(f, problemInStack, problemPosition) == null)) {
                // Isto pode acontecer quando instruco que encontrmos  o target de
                // um "backwards edge". Nesse caso, no  esta a instruco que queremos
                // processar, mas queremos uma que tenha como predecessor um Future,
                // no um MergedUninitializedValue
                /*Log.debug("Found result of backwards edge at " +
                   (problemInStack ? "stack" : "locals") + " position " + i +
                   ", continuing");*/
                problemPosition = -1;
                continue;
            }

            if (problemInStack && !(mn.instructions.get(i) instanceof LabelNode)
                    && (mn.instructions.get(i - 1) instanceof VarInsnNode)) {
                // Caso especial: Uma instruco de load colocou um
                // MergedUninitializedValue na stack, e como no estava l na instruco
                // anterior o getPredecessorWithFuture no detecta este caso, mas no
                // estamos interessados nesta frame, estamos interessadas na que originou
                // o MUV que estava nos locals
                problemPosition = -1;
                continue;
            }

            // Frame e posio escolhidas so consideradas problemticas
            break;
        }

        AbstractInsnNode insn = mn.instructions.get(i);
        // First node with problematic frame should be a LabelNode
        if (!(insn instanceof LabelNode))
            throw new AssertionError();
        problemLabelNode = (LabelNode) insn;
        problemFrame = f;

        printCode(mn, frames, problemFrame.predecessors(), f);
        Log.trace("First problematic frame is " + f + "\n\t\tPredecessors: " + f.predecessors());
        break;
    }

    if (problemLabelNode == null) {
        Log.warn("Errors found during analysis, bytecode possibly invalid, bailing out");
        throw new AssertionError(); // Causar revert de todas as alteraes no mtodo
        //return false;
    }

    // Duplicar cdigo problemtico, para depois o alterar com o DelayGetFutureMethodVisitor
    InsnList il = new InsnList();

    // Label que marca o inicio do cdigo a copiar
    LabelNode copiedBlockStartLabel = new LabelNode();

    // Criar mapa para passar ao AbstractInsnNode (ver javadoc ASM)
    //LabelMap labelMap = new LabelMap();
    labelMap.put(problemLabelNode, copiedBlockStartLabel);

    // Adiciona copiedBlockStartLabel  nova il
    il.add(problemLabelNode.clone(labelMap));

    // Usado para manter a ltima (inclusiv) instruco do bloco copiado
    AbstractInsnNode lastInsn = null;

    // Simular execuo das frames durante a cpia
    // O objectivo disto  resolver problemas como o NewSpecExample17, onde cdigo copiado deve
    // fazer branch para:
    // -- Cdigo copiado numa iterao anterior ("cdigo novo") se a frame continuar a conter um
    //    futuro, porque o cdigo novo  o que  suposto lidar com a existncia do futuro
    // -- Cdigo existente do mtodo ("cdigo antigo") se a frame j no contm um futuro, o que
    //    significa que a concretizao se faz durante o bloco actual
    FlowFrame currentFrame = analyzer.newFrame(problemFrame);
    if (problemInStack) {
        currentFrame.setStack(problemPosition,
                ((MergedUninitializedValue) currentFrame.getStack(problemPosition)).getFuture());
    } else {
        currentFrame.setLocal(problemPosition,
                ((MergedUninitializedValue) currentFrame.getLocal(problemPosition)).getFuture());
    }

    for (AbstractInsnNode n = problemLabelNode.getNext(); n != null; n = n.getNext()) {
        if (n instanceof LabelNode) {
            LabelNode labelNode = (LabelNode) n;
            if (getNextIgnoreLabelLineNop(labelNode) instanceof FrameNode) {
                // Se label se refere a uma frame, o bloco terminou
                // FIXME: Tem que se saltar sempre para labels novas, se existirem?
                il.add(new JumpInsnNode(GOTO, labelMap.get(labelNode)));
                break;
            } else {
                // Caso contrrio, substituimos por uma nova label, para permitir
                // que os LineNumberNodes continuem a existir no novo cdigo.
                labelMap.put(labelNode, new LabelNode());
            }
        }

        // Detectar, no caso de um salto, qual a label que se deve utilizar (ver comentrios acima)
        // FIXME: Ser que no caso do switch/case algumas das labels tm que apontar para o cdigo
        //     novo, e outras para o antigo?
        if (n instanceof JumpInsnNode || n instanceof LookupSwitchInsnNode
                || n instanceof TableSwitchInsnNode) {
            // Se ProblemPosition ainda tem um Futuro, saltar para cdigo novo
            if ((problemInStack && isFuture(currentFrame.getStack(problemPosition)))
                    || (!problemInStack && isFuture(currentFrame.getLocal(problemPosition)))) {
                il.add(n.clone(labelMap));
            } else { // Deixou de ter um Futuro, saltar para cdigo antigo
                il.add(n.clone(new LabelMap()));
            }
        } else {
            il.add(n.clone(labelMap));
        }

        lastInsn = n;

        // Se chegamos ao fim do bloco (GOTO, ATHROW ou *RETURN) tambm paramos a cpia
        if (n.getOpcode() == GOTO || n.getOpcode() == ATHROW || returnOpcodes.contains(n.getOpcode()))
            break;

        // Actualizar currentFrame -- simular execuo da instruco actual
        try {
            currentFrame = analyzer.computeNextFrame(currentFrame, n);
        } catch (AnalyzerException e) {
            // Ocorreu um erro, continuamos com a ltima frame vlida
            //Log.debug("WARNING: AnalyzerException during computeNextFrame");
        }
        //Log.debug("CurrentFrame: " + currentFrame + " (isFuture? " +
        //   (isFuture(currentFrame.getLocal(problemPosition)) ? "yes" : "no") + ")");
    }

    LabelNode copiedBlockEndLabel = new LabelNode();
    il.add(copiedBlockEndLabel);

    mn.instructions.add(il);
    il = mn.instructions;

    // Detectar qual dos seus predecessores originou o Futuro que ficou no MergedUninitializedValue

    if (problemFrame.predecessors().isEmpty()) { // ProblemFrame  o inicio de um exception handler
        // Popular predecessors da problemFrame com control flows de exceptions
        analyzer.populateExceptionPredecessors(problemFrame);

        //printCode(mn, frames, problemFrame.predecessors());

        // Adicionar um novo tryCatchBlock com:
        // - Range [Primeira instruco com Future,
        //      ltima instruco que tem future *E* faz parte da lista de predecessors]
        //   Razo: Lista de predecessors --> handler ainda est activo
        //          Tem future --> future pode ser substituido mais tarde
        //             (por exemplo { i = doA(); j = doB(); i = 0 })
        // - Target: Novo bloco copiado -- copiedBlockStartLabel

        AbstractInsnNode startBlockInsn = null;
        AbstractInsnNode endBlockInsn = null;

        for (FlowFrame f : problemFrame.predecessors()) {
            BasicValue v = problemInStack ? f.getStack(problemPosition) : f.getLocal(problemPosition);
            if (isFuture(v)) {
                AbstractInsnNode insn = insnForFrame(il, frames, f);

                if (startBlockInsn == null) {
                    startBlockInsn = insn;
                }

                if (endBlockInsn != null) {
                    // Detectar se o bloco actual terminou
                    if (getTryCatchBlock(mn, startBlockInsn, insn) == null)
                        break;
                }

                endBlockInsn = insn;
            } else if (startBlockInsn != null) {
                break;
            }
        }

        // Provavelmente o problema do NewSpecExample20, ver comentrios no ficheiro
        if (startBlockInsn == null || endBlockInsn == null) {
            throw new AssertionError("KNOWN BUG: Probably picked the wrong code to copy");
        }

        //Log.debug("PredecessorInsn [Exception]: First " + startBlockInsn + " Last " + endBlockInsn);

        LabelNode startBlockLabel = labelBefore(il, startBlockInsn);
        LabelNode endBlockLabel = labelAfter(il, endBlockInsn);

        TryCatchBlockNode originalBlock = getTryCatchBlock(mn, startBlockInsn, endBlockInsn);
        assert (originalBlock != null);

        mn.tryCatchBlocks.add(0, new SafeTryCatchBlockNode(startBlockLabel, endBlockLabel,
                copiedBlockStartLabel, originalBlock.type));

        if (originalBlock.start.equals(startBlockLabel) && originalBlock.end.equals(endBlockLabel)) {
            // Novo bloco substitui completamente o antigo
            mn.tryCatchBlocks.remove(originalBlock);
        } else {
            // Como o novo try/catch substitui o antigo, para que o verificador da JVM e do ASM
            // lidem melhor com a coisa (embora segundo os specs no seria necessrio), vamos
            // alterar o inicio e/ou o fim do bloco original para deixar de conter as instruces
            // que esto cobertas pelo novo bloco
            if (originalBlock.start.equals(startBlockLabel)) {
                originalBlock.start = endBlockLabel;
            } else if (originalBlock.end.equals(endBlockLabel)) {
                originalBlock.end = startBlockLabel;
            } else {
                Log.debug("FIXME: Original (old) try catch block should be adjusted");
            }
        }
    } else { // Existem predecessores, problemFrame  um bloco de cdigo normal
        FlowFrame predecessorWithFuture = getPredecessorWithFuture(problemFrame, problemInStack,
                problemPosition);

        if (predecessorWithFuture == null)
            throw new AssertionError();

        AbstractInsnNode predecessorInsn = insnForFrame(il, frames, predecessorWithFuture);
        //Log.debug("PredecessorInsn: " + predecessorInsn);

        // Detectar como vai ser feito o salto para a nova seco do cdigo

        // Casos possveis:
        // - Predecessor  instruco imediatamente antes da labelnode (e no  um salto)
        //   -> No alteramos, adicionamos goto
        //   -> Se for um salto, podemos ou no ter que alterar, dependendo de ser ou no
        //      um salto para a labelNode que marca o incio da seco problemtica
        // - Predecessor  jump / table|lookup switch
        //   -> Temos que alterar
        // Fazendo clone com o labelmap obtemos um n que tem o salto para a nova label trocado
        // pelo salto para a antiga.
        if (directlyPrecedes(predecessorInsn, problemLabelNode)
                && !hasLabelAsTarget(predecessorInsn, problemLabelNode)) {
            // No temos que alterar n, saltamos directamente para novo bloco
            il.insert(predecessorInsn, new JumpInsnNode(GOTO, copiedBlockStartLabel));
        } else {
            if (!((predecessorInsn instanceof LookupSwitchInsnNode)
                    || (predecessorInsn instanceof TableSwitchInsnNode)
                    || (predecessorInsn instanceof JumpInsnNode))) {
                throw new AssertionError(); // Instruco tem que ser salto
            }
            // N tem que ser alterado
            AbstractInsnNode replacementNode = predecessorInsn.clone(labelMap);
            il.set(predecessorInsn, replacementNode);
            if (lastInsn == predecessorInsn)
                lastInsn = replacementNode;
        }
    }

    // Corrigir exception handlers do mtodo

    // Como blocos de cdigo so copiados, temos tambm que copiar os exception handlers,
    // para que os try/catch continuem a funcionar correctamente
    List<AbstractInsnNode> copiedCodeRange = getRange(problemLabelNode, lastInsn);
    List<SafeTryCatchBlockNode> newTryCatchBlocks = new ArrayList<SafeTryCatchBlockNode>();
    for (TryCatchBlockNode tryCatchBlock : mn.tryCatchBlocks) {
        List<AbstractInsnNode> blockRange = getRange(tryCatchBlock.start, tryCatchBlock.end);
        blockRange.retainAll(copiedCodeRange);
        if (blockRange.isEmpty())
            continue;
        // Corner case: Supostamente um try/catch block cobre [start, end[, enquanto
        // que o getRange devolve [start, end]
        if (blockRange.size() == 1 && problemLabelNode == tryCatchBlock.end)
            continue;

        //Log.debug("Exception handler table needs fixup");

        // Determinar a nova label de inicio
        LabelNode newStart;
        if (copiedCodeRange.contains(tryCatchBlock.start)) {
            // loco excepo comea j dentro do copiedCodeRange
            newStart = labelMap.getMapping(tryCatchBlock.start);
        } else {
            // Bloco excepo comea fora do copiedCodeRange
            newStart = copiedBlockStartLabel;
        }

        // Determinar a nova label de fim
        LabelNode newEnd;
        if (copiedCodeRange.contains(tryCatchBlock.end)) {
            // Bloco excepo comea dentro do copiedCodeRange
            newEnd = labelMap.getMapping(tryCatchBlock.end);
        } else {
            // Bloco excepo acaba fora do copiedCodeRange
            newEnd = copiedBlockEndLabel;
        }

        newTryCatchBlocks
                .add(new SafeTryCatchBlockNode(newStart, newEnd, tryCatchBlock.handler, tryCatchBlock.type));
    }
    mn.tryCatchBlocks.addAll(newTryCatchBlocks);

    return true;
}

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

License:Open Source License

/**
 * Replaces any GETSTATIC/PUTSTATIC call of the field in the old class with the field
 * introduced in the new class./*from   w w  w  .j  a v a2s  .c om*/
 *
 * @param classNode containing the old class.
 * @param fieldNode containing the old field.
 */
@SuppressWarnings("unchecked")
private void replaceReferences(ClassNode classNode, FieldNode fieldNode) {
    List<MethodNode> methodNodes = classNode.methods;
    String contClass = classNode.name.substring(classNode.name.lastIndexOf("/") + 1);
    final String className = classPackage
            + TransformerNameGenerator.getPrivateStaticFieldClassName(contClass, fieldNode.name);
    for (MethodNode method : methodNodes) {
        InsnList inst = method.instructions;
        Iterator iter = inst.iterator();
        while (iter.hasNext()) {
            AbstractInsnNode absIns = (AbstractInsnNode) iter.next();
            int opcode = absIns.getOpcode();
            // check if instruction is GETSTATIC or PUTSTATIC
            if (opcode == Opcodes.GETSTATIC) {
                // get type
                if (absIns.getType() == AbstractInsnNode.FIELD_INSN) {
                    final Boolean[] foundField = { false };
                    final ClassNode cNode = classNode;
                    final FieldNode fNode = fieldNode;
                    absIns.accept(new MethodVisitor(Opcodes.ASM5) {
                        @Override
                        public void visitFieldInsn(int i, String s, String s2, String s3) {
                            if (cNode.name.equals(s) && fNode.name.equals(s2)) {
                                foundField[0] = true;
                            }
                            super.visitFieldInsn(i, s, s2, s3);
                        }
                    });
                    if (foundField[0]) {
                        inst.set(absIns, new FieldInsnNode(Opcodes.GETSTATIC, className, fieldNode.name,
                                fieldNode.desc));
                    }
                }
            } else if (opcode == Opcodes.PUTSTATIC) {
                if (absIns.getType() == AbstractInsnNode.FIELD_INSN) {
                    final Boolean[] foundField = { false };
                    final ClassNode cNode = classNode;
                    final FieldNode fNode = fieldNode;
                    absIns.accept(new MethodVisitor(Opcodes.ASM5) {
                        @Override
                        public void visitFieldInsn(int i, String s, String s2, String s3) {
                            if (cNode.name.equals(s) && fNode.name.equals(s2)) {
                                foundField[0] = true;
                            }
                            super.visitFieldInsn(i, s, s2, s3);
                        }
                    });
                    if (foundField[0]) {
                        inst.set(absIns, new FieldInsnNode(Opcodes.PUTSTATIC, className, fieldNode.name,
                                fieldNode.desc));
                    }
                }
            }
        }
    }
}

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

License:Open Source License

@SuppressWarnings("uncheked")
@Override//from w ww . ja  v  a  2 s  .c o  m
public int findAndReplace(ClassNode classNode) {
    int counter = 0;
    if (classNode.superName.equals(supperClass)) {
        List<MethodNode> methodNodes = classNode.methods;
        for (MethodNode method : methodNodes) {
            InsnList inst = method.instructions;
            Iterator iter = inst.iterator();
            while (iter.hasNext()) {
                AbstractInsnNode absIns = (AbstractInsnNode) iter.next();
                int opcode = absIns.getOpcode();
                // check if instruction is GETSTATIC or PUTSTATIC
                if (opcode == Opcodes.GETSTATIC) {
                    // get type
                    if (absIns.getType() == AbstractInsnNode.FIELD_INSN) {
                        final Boolean[] foundField = { false };
                        absIns.accept(new MethodVisitor(Opcodes.ASM5) {
                            @Override
                            public void visitFieldInsn(int i, String s, String s2, String s3) {
                                if (oldClass.equals(s) && fieldToReplace.name.equals(s2)) {
                                    foundField[0] = true;
                                }
                                super.visitFieldInsn(i, s, s2, s3);
                            }
                        });
                        if (foundField[0]) {
                            inst.set(absIns, new FieldInsnNode(Opcodes.GETSTATIC, newClass, fieldToReplace.name,
                                    fieldToReplace.desc));
                            counter++;
                        }
                    }
                } else if (opcode == Opcodes.PUTSTATIC) {
                    if (absIns.getType() == AbstractInsnNode.FIELD_INSN) {
                        final Boolean[] foundField = { false };
                        absIns.accept(new MethodVisitor(Opcodes.ASM5) {
                            @Override
                            public void visitFieldInsn(int i, String s, String s2, String s3) {
                                if (oldClass.equals(s) && fieldToReplace.name.equals(s2)) {
                                    foundField[0] = true;
                                }
                                super.visitFieldInsn(i, s, s2, s3);
                            }
                        });
                        if (foundField[0]) {
                            inst.set(absIns, new FieldInsnNode(Opcodes.PUTSTATIC, newClass, fieldToReplace.name,
                                    fieldToReplace.desc));
                            counter++;
                        }
                    }
                }
            }
        }
    }
    return counter;
}

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

License:Open Source License

/**
 * Replaces any GETSTATIC/PUTSTATIC call of the field in the old class with the field
 * introduced in the new class./* w ww  .  j  ava2s. c  o m*/
 *
 * @param classNode containing the old class.
 * @param fieldNode containing the old field.
 */
private void replaceReferences(ClassNode classNode, FieldNode fieldNode) {
    List<MethodNode> methodNodes = classNode.methods;
    String contClass = classNode.name.substring(classNode.name.lastIndexOf("/") + 1);
    final String className = classPackage
            + TransformerNameGenerator.getProtectedStaticFieldClassName(contClass, fieldNode.name);
    for (MethodNode method : methodNodes) {
        InsnList inst = method.instructions;
        Iterator iter = inst.iterator();
        while (iter.hasNext()) {
            AbstractInsnNode absIns = (AbstractInsnNode) iter.next();
            int opcode = absIns.getOpcode();
            // check if instruction is GETSTATIC or PUTSTATIC
            if (opcode == Opcodes.GETSTATIC) {
                // get type
                if (absIns.getType() == AbstractInsnNode.FIELD_INSN) {
                    final Boolean[] foundField = { false };
                    final ClassNode cNode = classNode;
                    final FieldNode fNode = fieldNode;
                    absIns.accept(new MethodVisitor(Opcodes.ASM5) {
                        @Override
                        public void visitFieldInsn(int i, String s, String s2, String s3) {
                            if (cNode.name.equals(s) && fNode.name.equals(s2)) {
                                foundField[0] = true;
                            }
                            super.visitFieldInsn(i, s, s2, s3);
                        }
                    });
                    if (foundField[0]) {
                        inst.set(absIns, new FieldInsnNode(Opcodes.GETSTATIC, className, fieldNode.name,
                                fieldNode.desc));
                    }
                }
            } else if (opcode == Opcodes.PUTSTATIC) {
                if (absIns.getType() == AbstractInsnNode.FIELD_INSN) {
                    final Boolean[] foundField = { false };
                    final ClassNode cNode = classNode;
                    final FieldNode fNode = fieldNode;
                    absIns.accept(new MethodVisitor(Opcodes.ASM5) {
                        @Override
                        public void visitFieldInsn(int i, String s, String s2, String s3) {
                            if (cNode.name.equals(s) && fNode.name.equals(s2)) {
                                foundField[0] = true;
                            }
                            super.visitFieldInsn(i, s, s2, s3);
                        }
                    });
                    if (foundField[0]) {
                        inst.set(absIns, new FieldInsnNode(Opcodes.PUTSTATIC, className, fieldNode.name,
                                fieldNode.desc));
                    }
                }
            }
        }
    }
}

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

License:Open Source License

@SuppressWarnings("unchecked")
@Override/*from   w  ww. j  a v a 2 s . c  o m*/
public int findAndReplace(ClassNode classNode) {
    int counter = 0;
    List<MethodNode> methodNodes = classNode.methods;
    for (MethodNode method : methodNodes) {
        InsnList inst = method.instructions;
        Iterator iter = inst.iterator();
        while (iter.hasNext()) {
            AbstractInsnNode absIns = (AbstractInsnNode) iter.next();
            int opcode = absIns.getOpcode();
            // check if instruction is GETSTATIC or PUTSTATIC
            if (opcode == Opcodes.GETSTATIC) {
                // get type
                if (absIns.getType() == AbstractInsnNode.FIELD_INSN) {
                    final Boolean[] foundField = { false };
                    absIns.accept(new MethodVisitor(Opcodes.ASM5) {
                        @Override
                        public void visitFieldInsn(int i, String s, String s2, String s3) {
                            if (oldClass.equals(s) && fieldToReplace.name.equals(s2)) {
                                foundField[0] = true;
                            }
                            super.visitFieldInsn(i, s, s2, s3);
                        }
                    });
                    if (foundField[0]) {
                        inst.set(absIns, new FieldInsnNode(Opcodes.GETSTATIC, newClass, fieldToReplace.name,
                                fieldToReplace.desc));
                        counter++;
                    }
                }
            } else if (opcode == Opcodes.PUTSTATIC) {
                if (absIns.getType() == AbstractInsnNode.FIELD_INSN) {
                    final Boolean[] foundField = { false };
                    absIns.accept(new MethodVisitor(Opcodes.ASM5) {
                        @Override
                        public void visitFieldInsn(int i, String s, String s2, String s3) {
                            if (oldClass.equals(s) && fieldToReplace.name.equals(s2)) {
                                foundField[0] = true;
                            }
                            super.visitFieldInsn(i, s, s2, s3);
                        }
                    });
                    if (foundField[0]) {
                        inst.set(absIns, new FieldInsnNode(Opcodes.PUTSTATIC, newClass, fieldToReplace.name,
                                fieldToReplace.desc));
                        counter++;
                    }
                }
            }
        }
    }
    return counter;
}

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

License:Open Source License

/**
 * Replaces any GETSTATIC/PUTSTATIC call of the field in the old class with the field
 * introduced in the new class./*from ww w .  j  av  a2 s  . co m*/
 *
 * @param classNode containing the old class.
 * @param fieldNode containing the old field.
 */
private void replaceReferences(ClassNode classNode, FieldNode fieldNode) {
    List<MethodNode> methodNodes = classNode.methods;
    String contClass = classNode.name.substring(classNode.name.lastIndexOf("/") + 1);
    final String className = classPackage
            + TransformerNameGenerator.getPublicStaticFieldClassName(contClass, fieldNode.name);
    for (MethodNode method : methodNodes) {
        InsnList inst = method.instructions;
        Iterator iter = inst.iterator();
        while (iter.hasNext()) {
            AbstractInsnNode absIns = (AbstractInsnNode) iter.next();
            int opcode = absIns.getOpcode();
            // check if instruction is GETSTATIC or PUTSTATIC
            if (opcode == Opcodes.GETSTATIC) {
                // get type
                if (absIns.getType() == AbstractInsnNode.FIELD_INSN) {
                    final Boolean[] foundField = { false };
                    final ClassNode cNode = classNode;
                    final FieldNode fNode = fieldNode;
                    absIns.accept(new MethodVisitor(Opcodes.ASM5) {
                        @Override
                        public void visitFieldInsn(int i, String s, String s2, String s3) {
                            if (cNode.name.equals(s) && fNode.name.equals(s2)) {
                                foundField[0] = true;
                            }
                            super.visitFieldInsn(i, s, s2, s3);
                        }
                    });
                    if (foundField[0]) {
                        inst.set(absIns, new FieldInsnNode(Opcodes.GETSTATIC, className, fieldNode.name,
                                fieldNode.desc));
                    }
                }
            } else if (opcode == Opcodes.PUTSTATIC) {
                if (absIns.getType() == AbstractInsnNode.FIELD_INSN) {
                    final Boolean[] foundField = { false };
                    final ClassNode cNode = classNode;
                    final FieldNode fNode = fieldNode;
                    absIns.accept(new MethodVisitor(Opcodes.ASM5) {
                        @Override
                        public void visitFieldInsn(int i, String s, String s2, String s3) {
                            if (cNode.name.equals(s) && fNode.name.equals(s2)) {
                                foundField[0] = true;
                            }
                            super.visitFieldInsn(i, s, s2, s3);
                        }
                    });
                    if (foundField[0]) {
                        inst.set(absIns, new FieldInsnNode(Opcodes.PUTSTATIC, className, fieldNode.name,
                                fieldNode.desc));
                    }
                }
            }
        }
    }
}

From source file:org.coldswap.asm.VirtualMethodReplacer.java

License:Open Source License

@Override
public MethodNode replaceInvoke(MethodNode methodNode) {
    InsnList instructions = methodNode.instructions;
    Iterator it = instructions.iterator();
    while (it.hasNext()) {
        AbstractInsnNode code = (AbstractInsnNode) it.next();
        if (code.getOpcode() == Opcodes.INVOKEVIRTUAL) {
            // check if methodToReplace is called
            final boolean[] callFounded = new boolean[] { false };
            code.accept(new MethodVisitor(Opcodes.ASM5) {
                @Override//  ww w.j  av  a  2 s  .c  om
                public void visitMethodInsn(int i, String s, String s2, String s3) {
                    if (s.equals(classContainer) && s2.equals(methodName)) {
                        callFounded[0] = true;
                    }
                    super.visitMethodInsn(i, s, s2, s3);
                }
            });

            if (callFounded[0]) {
                // if the return type is primitive and the value is not discarded, unbox
                if (AutoBoxing.isPrimitive(retType.getDescriptor())) {
                    AbstractInsnNode codeNext = code.getNext();
                    boolean discarded = false;
                    // if returning primitive double or long and it is discarded with a pop2 than discard with
                    // simple pop, because we use an Object as return value.
                    if (codeNext.getOpcode() == Opcodes.POP2
                            && (retType.getDescriptor().equals("D") || retType.getDescriptor().equals("J"))) {
                        instructions.set(codeNext, new InsnNode(Opcodes.POP));

                    }
                    if (codeNext.getOpcode() == Opcodes.POP || codeNext.getOpcode() == Opcodes.POP2) {
                        discarded = true;
                    }
                    if (!discarded) {
                        instructions.insert(code, AutoBoxing.unbox(retType));
                    }
                }

                // replace call with a custom call
                String newMethodName;
                AbstractInsnNode newInvoke = null;
                if (Constants.VAROBJECT.equals(methodType)) {
                    newMethodName = TransformerNameGenerator.getObjectMethodNameWithCounter(classContainer,
                            methodNumber);
                    newInvoke = new MethodInsnNode(Opcodes.INVOKEVIRTUAL, classContainer, newMethodName,
                            "([Ljava/lang/Object;)Ljava/lang/Object;");
                } else if (Constants.INT.equals(methodType)) {
                    newMethodName = TransformerNameGenerator.getIntMethodNameWithCounter(classContainer,
                            methodNumber);
                    newInvoke = new MethodInsnNode(Opcodes.INVOKEVIRTUAL, classContainer, newMethodName,
                            "(I)Ljava/lang/Object;");
                } else if (Constants.FLOAT.equals(methodType)) {
                    newMethodName = TransformerNameGenerator.getFloatMethodNameWithCounter(classContainer,
                            methodNumber);
                    newInvoke = new MethodInsnNode(Opcodes.INVOKEVIRTUAL, classContainer, newMethodName,
                            "(F)Ljava/lang/Object;");
                } else if (Constants.STRING.equals(methodType)) {
                    newMethodName = TransformerNameGenerator.getStringMethodNameWithCounter(classContainer,
                            methodNumber);
                    newInvoke = new MethodInsnNode(Opcodes.INVOKEVIRTUAL, classContainer, newMethodName,
                            "(Ljava/lang/String;)Ljava/lang/Object;");
                } else if (Constants.LONG.equals(methodType)) {
                    newMethodName = TransformerNameGenerator.getLongMethodNameWithCounter(classContainer,
                            methodNumber);
                    newInvoke = new MethodInsnNode(Opcodes.INVOKEVIRTUAL, classContainer, newMethodName,
                            "(J)Ljava/lang/Object;");
                }
                if (newInvoke != null) {
                    instructions.set(code, newInvoke);
                }
            }
        }
    }
    return methodNode;
}

From source file:org.eclipse.objectteams.otredyn.bytecode.asm.MoveCodeToCallOrigAdapter.java

License:Open Source License

/** To avoid infinite recursion, calls super.m(a1, a2) must be translated to super.callOrig(boundMethodId, new Object[] {a1, a2}). */
private void adjustSuperCalls(InsnList instructions, String selector, Type[] args, Type returnType,
        int boundMethodIdSlot) {
    // search://from  w  w w  .  j a  va  2s  .c om
    List<MethodInsnNode> toReplace = new ArrayList<MethodInsnNode>();
    ListIterator<AbstractInsnNode> orgMethodIter = instructions.iterator();
    while (orgMethodIter.hasNext()) {
        AbstractInsnNode orgMethodNode = orgMethodIter.next();
        if (orgMethodNode.getOpcode() == Opcodes.INVOKESPECIAL
                && ((MethodInsnNode) orgMethodNode).name.equals(selector))
            toReplace.add((MethodInsnNode) orgMethodNode);
    }
    if (toReplace.isEmpty())
        return;
    // replace:
    for (MethodInsnNode oldNode : toReplace) {
        // we need to insert into the loading sequence before the invocation, find the insertion points:
        AbstractInsnNode[] insertionPoints = StackBalanceAnalyzer.findInsertionPointsBefore(oldNode, args);
        AbstractInsnNode firstInsert = insertionPoints.length > 0 ? insertionPoints[0] : oldNode;

        // push first arg to _OT$callOrig():
        instructions.insertBefore(firstInsert, new IntInsnNode(Opcodes.ILOAD, boundMethodIdSlot));

        // prepare array as second arg to _OT$callOrig():
        instructions.insertBefore(firstInsert, new IntInsnNode(Opcodes.BIPUSH, args.length));
        instructions.insertBefore(firstInsert, new TypeInsnNode(Opcodes.ANEWARRAY, "java/lang/Object"));

        for (int i = 0; i < insertionPoints.length; i++) {
            // NB: each iteration has an even stack balance, where the top is the Object[].
            instructions.insertBefore(insertionPoints[i], new InsnNode(Opcodes.DUP));
            instructions.insertBefore(insertionPoints[i], new IntInsnNode(Opcodes.BIPUSH, i));
            // leave the original loading sequence in tact and continue at the next point:
            AbstractInsnNode insertAt = (i + 1 < insertionPoints.length) ? insertionPoints[i + 1] : oldNode;
            instructions.insertBefore(insertAt, AsmTypeHelper.getBoxingInstructionForType(args[i]));
            instructions.insertBefore(insertAt, new InsnNode(Opcodes.AASTORE));
        }

        if (returnType == Type.VOID_TYPE)
            instructions.insert(oldNode, new InsnNode(Opcodes.POP));
        else
            instructions.insert(oldNode, AsmTypeHelper.getUnboxingInstructionForType(returnType));

        instructions.set(oldNode, new MethodInsnNode(Opcodes.INVOKESPECIAL, ((MethodInsnNode) oldNode).owner,
                callOrig.getName(), callOrig.getSignature()));
    }
}