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

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

Introduction

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

Prototype

public void insert(final AbstractInsnNode previousInsn, final InsnList insnList) 

Source Link

Document

Inserts the given instructions after the specified instruction.

Usage

From source file:de.tuberlin.uebb.jbop.optimizer.array.FieldArrayValueInliner.java

License:Open Source License

private void replaceNodes(final InsnList newList, final AbstractInsnNode aload, final ArrayHelper arrayHelper,
        final AbstractInsnNode replacementNode, final ListIterator<AbstractInsnNode> iterator) {
    if (replacementNode != null) {
        newList.insert(arrayHelper.getLastLoad(), replacementNode);
    }//from  w  w  w  .j  a  v  a  2 s  .  c om
    newList.remove(aload);
    for (final AbstractInsnNode node : arrayHelper.getIndexes()) {
        newList.remove(node);
    }
    for (final AbstractInsnNode node : arrayHelper.getArrayloads()) {
        newList.remove(node);
    }
    if (replacementNode != null) {
        iterator.next();
    }
    newList.remove(arrayHelper.getFieldNode());
    optimized = true;
}

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.
  **///w w  w . ja  v  a  2 s .  c o m
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:jaspex.speculation.newspec.FlowFrame.java

License:Open Source License

/** Obtm label depois da instruco. Se j existir uma,  reutilizada, cc uma nova  criada. **/
public static LabelNode labelAfter(InsnList il, AbstractInsnNode insn) {
    if (!(insn.getNext() instanceof LabelNode)) {
        il.insert(insn, new LabelNode());
    }/* w w w. j a v a  2 s.  co m*/

    return (LabelNode) insn.getNext();
}

From source file:net.doubledoordev.inventorylock.asm.Transformer.java

License:Open Source License

@Override
public byte[] transform(String name, String transformedName, byte[] basicClass) {
    ClassNode classNode = new ClassNode();
    ClassReader classReader = new ClassReader(basicClass);
    classReader.accept(classNode, READER_FLAGS);

    boolean isPlayer = transformedName.equals(ENTITY_PLAYER_OWNER_NAME);
    if (isPlayer)
        LOGGER.info("Found EntityPlayer");

    for (MethodNode method : classNode.methods) {
        InsnList list = method.instructions;
        if (isPlayer && INSTANCE.mapMethodDesc(method.desc).equals(ENTITY_PLAYER_DESC)
                && INSTANCE.mapMethodName(name, method.name, method.desc).equals(ENTITY_PLAYER_TARGET)) {
            final LabelNode newLabel = new LabelNode();
            LOGGER.info("Found canOpen");
            AbstractInsnNode node = list.getFirst();
            while (node.getOpcode() != IRETURN && node != list.getLast()) {
                if (node.getOpcode() == IFEQ)
                    ((JumpInsnNode) node).label = newLabel;
                node = node.getNext();/*w ww .  j a  va  2 s.c o  m*/
            }
            if (node.getOpcode() != IRETURN)
                throw new RuntimeException("ASM failed. (return not found)");
            final AbstractInsnNode target = node;
            while (node.getType() != LABEL && node != list.getLast())
                node = node.getNext();
            if (node.getType() != LABEL)
                throw new RuntimeException("ASM failed. (label not found)");
            final LabelNode label = ((LabelNode) node);

            //Adding "else if (code instanceof BetterLockCode) return ((BetterLockCode) code).contains(this.getUniqueID());"
            InsnList inject = new InsnList();

            inject.add(newLabel);
            inject.add(new VarInsnNode(ALOAD, 1));
            inject.add(new TypeInsnNode(INSTANCEOF, BETTER_LOCK_TYPE));
            inject.add(new JumpInsnNode(IFEQ, label));
            inject.add(new VarInsnNode(ALOAD, 1));
            inject.add(new TypeInsnNode(CHECKCAST, BETTER_LOCK_TYPE));
            inject.add(new VarInsnNode(ALOAD, 0));
            //inject.add(new MethodInsnNode(Opcodes.INVOKEVIRTUAL, ENTITY_PLAYER_OWNER, ENTITY_PLAYER_GET_UUID, ENTITY_PLATER_GET_UUID_DESC, false));
            inject.add(new MethodInsnNode(Opcodes.INVOKEVIRTUAL, BETTER_LOCK_TYPE, BETTER_LOCK_CONTAINS,
                    BETTER_LOCK_CONTAINS_DESC, false));
            inject.add(new InsnNode(IRETURN));

            list.insert(target, inject);
            LOGGER.info("Injected elseif into EntityPlayer's canOpen");
        }
        for (AbstractInsnNode node = list.getFirst(); node != list.getLast(); node = node.getNext()) {
            if (node.getOpcode() != INVOKESTATIC)
                continue;
            MethodInsnNode methodInsnNode = ((MethodInsnNode) node);
            //                if (transformedName.equals("net.minecraft.tileentity.TileEntityLockable"))
            //                    LOGGER.info("In {} ({}) Method {}.{}{} Translated {}.{}{}", name, transformedName,
            //                            methodInsnNode.owner, methodInsnNode.name, methodInsnNode.desc,
            //                            INSTANCE.map(methodInsnNode.owner), INSTANCE.mapMethodName(methodInsnNode.owner, methodInsnNode.name, methodInsnNode.desc), INSTANCE.mapMethodDesc(methodInsnNode.desc).equals(LOCK_CODE_DESC));
            if (INSTANCE.map(methodInsnNode.owner).equals(LOCK_CODE_OWNER)
                    && INSTANCE.mapMethodDesc(methodInsnNode.desc).equals(LOCK_CODE_DESC)
                    && INSTANCE.mapMethodName(methodInsnNode.owner, methodInsnNode.name, methodInsnNode.desc)
                            .equals(LOCK_CODE_TARGET)) {
                methodInsnNode.owner = LOCK_CODE_OWNER_REPLACE;
                methodInsnNode.name = LOCK_CODE_NAME;
                LOGGER.info("Replaced call in class {} ({}), method {}{}", name, transformedName, method.name,
                        method.desc);
            }
        }
    }

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

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 a2  s . c  o m
                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.diorite.inject.controller.TransformerFieldInjector.java

License:Open Source License

private void injectField(TransformerFieldPair fieldPair, TransformerInjectTracker result) {
    ControllerFieldData<?> fieldData = fieldPair.data;
    assert fieldData != null;

    MethodInsnNode injectionInvokeNode = result.getResult();
    FieldInsnNode putfieldNode = result.getFieldInsnNode();

    // insert invoke methods:
    MethodNode codeBefore = new MethodNode();
    MethodNode codeAfter = new MethodNode();
    this.injectTransformer.fillMethodInvokes(codeBefore, codeAfter, fieldData);

    // node list for PUTFIELD
    InsnList initNodeList = result.getInitNodeList();
    // node list for invoke execution
    InsnList resultNodeList = result.getResultNodeList();

    if (codeBefore.instructions.size() != 0) {
        // invoke before should be added before PUTFIELD and before INVOKE
        resultNodeList.insertBefore(injectionInvokeNode, codeBefore.instructions);
    }/*from  www  .  ja v a  2s.c o  m*/
    if (codeAfter.instructions.size() != 0) {
        // invoke after should be added after PUTFIELD
        initNodeList.insert(putfieldNode, codeAfter.instructions);
    }

    // and replace placeholder node with real injections:
    {
        MethodNode tempNode = new MethodNode();
        TransformerInvokerGenerator.generateFieldInjection(this.injectTransformer.classData, fieldData,
                tempNode, -1);
        resultNodeList.insertBefore(injectionInvokeNode, tempNode.instructions);
        resultNodeList.remove(injectionInvokeNode);
    }
}

From source file:org.diorite.inject.impl.controller.TransformerFieldInjector.java

License:Open Source License

private void injectField(TransformerFieldPair fieldPair, TransformerInjectTracker result) {
    ControllerFieldData<?> fieldData = fieldPair.data;
    assert fieldData != null;

    MethodInsnNode injectionInvokeNode = result.getResult();
    FieldInsnNode putfieldNode = result.getFieldInsnNode();

    // insert invoke methods:
    MethodNode codeBefore = new MethodNode();
    MethodNode codeAfter = new MethodNode();
    this.injectTransformer.fillMethodInvokes(codeBefore, codeAfter, fieldData);

    // node list for PUTFIELD
    InsnList initNodeList = result.getInitNodeList();
    // node list for invoke execution
    InsnList resultNodeList = result.getResultNodeList();

    if (codeBefore.instructions.size() != 0) {
        // invoke before should be added before PUTFIELD and before INVOKE
        resultNodeList.insertBefore(injectionInvokeNode, codeBefore.instructions);
    }/*from w  w  w  . ja  va2  s.  c om*/
    if (codeAfter.instructions.size() != 0) {
        // invoke after should be added after PUTFIELD
        initNodeList.insert(putfieldNode, codeAfter.instructions);
    }

    // and replace placeholder node with real injections:
    {
        MethodNode tempNode = new MethodNode();
        TransformerInvokerGenerator.generateFieldInjection(this.injectTransformer.classData, fieldData,
                tempNode, -1, fieldPair.placeholderType);
        resultNodeList.insertBefore(injectionInvokeNode, tempNode.instructions);
        resultNodeList.remove(injectionInvokeNode);
    }
}

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

License:Open Source License

/**
 * Adds a new Label to an existing switch statement
 * @param instructions the instructions, in which the switch statement is defined
 * @param newInstructions the instructions of the new label
 * @param labelIndex the index of the label
 *///from   w w  w . j a  v a 2 s .c  o  m
@SuppressWarnings("unchecked")
protected void addNewLabelToSwitch(InsnList instructions, InsnList newInstructions, int labelIndex) {
    ListIterator<AbstractInsnNode> iter = instructions.iterator();
    LookupSwitchInsnNode lSwitch = null;
    while (iter.hasNext()) {
        AbstractInsnNode node = (AbstractInsnNode) iter.next();
        if (node.getType() == AbstractInsnNode.LOOKUPSWITCH_INSN) {
            lSwitch = (LookupSwitchInsnNode) node;
            LabelNode label = new LabelNode();
            boolean labelAdded = false;
            for (int i = 0; i < lSwitch.keys.size(); i++) {
                Integer key = (Integer) lSwitch.keys.get(i);
                if (key >= labelIndex) {
                    lSwitch.keys.add(i, labelIndex);
                    lSwitch.labels.add(i, label);
                    labelAdded = true;
                    break;
                }
            }
            if (!labelAdded) {
                lSwitch.labels.add(label);
                lSwitch.keys.add(labelIndex);
            }
            boolean foundDefLabel = false;
            AbstractInsnNode prevNode = node;
            while (iter.hasNext()) {
                node = (AbstractInsnNode) iter.next();
                if (node.getType() == AbstractInsnNode.LABEL) {
                    if (!foundDefLabel) {
                        foundDefLabel = true;
                    } else {
                        break;
                    }
                }
                prevNode = node;
            }
            instructions.insert(prevNode, label);
            instructions.insert(label, newInstructions);
        }
    }
    if (lSwitch == null) {
        throw new RuntimeException("No switch statement found.");
    }
}

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  av  a  2s. co m*/
    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()));
    }
}

From source file:org.evosuite.instrumentation.BooleanTestabilityTransformation.java

License:Open Source License

/**
 * Insert a call that takes a boolean from the stack, and returns the
 * appropriate distance//from w  w  w .j a  va 2  s. co m
 * 
 * @param position
 * @param list
 */
public void insertGet(AbstractInsnNode position, InsnList list) {
    logger.info("Inserting get call");
    // Here, branchId is the first control dependency
    //list.insertBefore(position,
    //                  new LdcInsnNode(getControlDependentBranchID(currentMethodNode,
    //                                                              position)));
    insertControlDependencyPlaceholder(currentMethodNode, position);

    MethodInsnNode get = new MethodInsnNode(Opcodes.INVOKESTATIC, Type.getInternalName(BooleanHelper.class),
            "getDistance", Type.getMethodDescriptor(Type.INT_TYPE,
                    new Type[] { Type.INT_TYPE, Type.INT_TYPE, Type.INT_TYPE }));
    list.insert(position, get);
}