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

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

Introduction

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

Prototype

public int getOpcode() 

Source Link

Document

Returns the opcode of this instruction.

Usage

From source file:io.moshisho.plugins.MyMojo.java

License:Apache License

private static void betterCompile(String classFile) throws IOException {

    InputStream is = new FileInputStream(classFile);
    ClassReader cr = new ClassReader(is);
    is.close();/*from  ww  w  .  j av a 2  s. c  o m*/
    ClassNode cn = new ClassNode();
    cr.accept(cn, 0);

    List methods = cn.methods;
    for (int i = 0; i < methods.size(); ++i) {
        MethodNode method = (MethodNode) methods.get(i);

        if (!isStaticllyBound(method)) {
            continue;
        }

        InsnList instructions = method.instructions;
        AbstractInsnNode last = instructions.getLast();

        while (last != null && last.getType() == AbstractInsnNode.LABEL) {
            last = last.getPrevious();
        }

        if (last == null || !isReturnInstruction(last)
                || last.getPrevious().getType() != AbstractInsnNode.METHOD_INSN) {
            continue;
        }

        MethodInsnNode methodInv = (MethodInsnNode) last.getPrevious();

        if (!isRecursionCall(cn, method, methodInv)) {
            continue;
        }

        System.out.println("TailRec Optimizaing: " + method.name);

        // get arguments and types
        String methodDesc = method.desc;

        String argsDesc = methodDesc.substring(methodDesc.indexOf('(') + 1, methodDesc.indexOf(')'));
        System.out.println(argsDesc);

        // work with Type.getArgumentTypes
        List<AbstractInsnNode> listInstNodes = new LinkedList<AbstractInsnNode>();
        for (int j = argsDesc.length() - 1; j >= 0; j--) {
            char c = argsDesc.charAt(j);
            switch (c) {
            case 'I':
                listInstNodes.add(new VarInsnNode(ISTORE, argsDesc.length() - j));
                break;
            case 'Z':
                listInstNodes.add(new VarInsnNode(ISTORE, argsDesc.length() - j));
                break;
            case 'C':
                listInstNodes.add(new VarInsnNode(ISTORE, argsDesc.length() - j));
                break;
            case 'B':
                listInstNodes.add(new VarInsnNode(ISTORE, argsDesc.length() - j));
                break;
            case 'S':
                listInstNodes.add(new VarInsnNode(ISTORE, argsDesc.length() - j));
                break;
            case 'F':
                listInstNodes.add(new VarInsnNode(FSTORE, argsDesc.length() - j));
                break;
            case 'J':
                listInstNodes.add(new VarInsnNode(LSTORE, argsDesc.length() - j));
                break;
            case 'D':
                listInstNodes.add(new VarInsnNode(DSTORE, argsDesc.length() - j));
                break;
            case '[':
                // TODO:
            case 'L':
                // TODO:
            default:
                System.out.println("NOT TREATING: " + c);
            }

        }

        // remove the last aload_0 of the recursion
        AbstractInsnNode pnt = last;
        while (pnt != null && pnt.getOpcode() != 42
                && !(pnt.getOpcode() == 25 && ((VarInsnNode) pnt).var == 0)) {
            pnt = pnt.getPrevious();
        }
        method.instructions.remove(pnt);

        Collections.reverse(listInstNodes);
        for (AbstractInsnNode abstractInsnNode : listInstNodes) {
            method.instructions.insertBefore(last.getPrevious(), abstractInsnNode);
        }
        // place instead of return //goto

        LabelNode startOfMethodLabel = new LabelNode(new Label());
        method.instructions.insertBefore(method.instructions.getFirst(), startOfMethodLabel);
        JumpInsnNode gotoInst = new JumpInsnNode(GOTO, startOfMethodLabel);
        method.instructions.set(last.getPrevious(), gotoInst);
        method.instructions.remove(last);

        ClassWriter cw = new ClassWriter(0);
        cn.accept(cw);
        FileOutputStream fos = new FileOutputStream(classFile);
        fos.write(cw.toByteArray());
        fos.close();
    }
}

From source file:io.moshisho.plugins.MyMojo.java

License:Apache License

private static boolean isReturnInstruction(AbstractInsnNode inst) {
    int opcode = inst.getOpcode();
    return opcode <= 177 && opcode >= 172;
}

From source file:io.moshisho.plugins.OptimizeClasses.java

License:Apache License

private void optimize(File clz) throws Exception {
    InputStream is = new FileInputStream(clz);
    ClassReader cr = new ClassReader(is);
    is.close();/*from   www  . j  av  a  2 s. c  om*/
    ClassNode cn = new ClassNode();
    cr.accept(cn, 0);

    List methods = cn.methods;
    for (int i = 0; i < methods.size(); ++i) {
        MethodNode method = (MethodNode) methods.get(i);

        if (!isStaticllyBound(method)) {
            continue;
        }

        InsnList instructions = method.instructions;
        AbstractInsnNode last = instructions.getLast();

        while (last != null && last.getType() == AbstractInsnNode.LABEL) {
            last = last.getPrevious();
        }

        if (last == null || !isReturnInstruction(last)
                || last.getPrevious().getType() != AbstractInsnNode.METHOD_INSN) {
            continue;
        }

        MethodInsnNode methodInv = (MethodInsnNode) last.getPrevious();

        if (!isRecursionCall(cn, method, methodInv)) {
            continue;
        }

        getLog().info("TailRec Optimizaing: " + method.name);

        // get arguments and types
        String methodDesc = method.desc;

        String argsDesc = methodDesc.substring(methodDesc.indexOf('(') + 1, methodDesc.indexOf(')'));
        //System.out.println(argsDesc);

        // work with Type.getArgumentTypes
        List<AbstractInsnNode> listInstNodes = new LinkedList<AbstractInsnNode>();
        for (int j = argsDesc.length() - 1; j >= 0; j--) {
            char c = argsDesc.charAt(j);
            switch (c) {
            case 'I':
                listInstNodes.add(new VarInsnNode(ISTORE, argsDesc.length() - j));
                break;
            case 'Z':
                listInstNodes.add(new VarInsnNode(ISTORE, argsDesc.length() - j));
                break;
            case 'C':
                listInstNodes.add(new VarInsnNode(ISTORE, argsDesc.length() - j));
                break;
            case 'B':
                listInstNodes.add(new VarInsnNode(ISTORE, argsDesc.length() - j));
                break;
            case 'S':
                listInstNodes.add(new VarInsnNode(ISTORE, argsDesc.length() - j));
                break;
            case 'F':
                listInstNodes.add(new VarInsnNode(FSTORE, argsDesc.length() - j));
                break;
            case 'J':
                listInstNodes.add(new VarInsnNode(LSTORE, argsDesc.length() - j));
                break;
            case 'D':
                listInstNodes.add(new VarInsnNode(DSTORE, argsDesc.length() - j));
                break;
            case '[':
                // TODO:
            case 'L':
                // TODO:
            default:
                System.out.println("NOT TREATING: " + c);
            }

        }

        // remove the last aload_0 of the recursion
        AbstractInsnNode pnt = last;
        while (pnt != null && pnt.getOpcode() != 42
                && !(pnt.getOpcode() == 25 && ((VarInsnNode) pnt).var == 0)) {
            pnt = pnt.getPrevious();
        }
        method.instructions.remove(pnt);

        Collections.reverse(listInstNodes);
        for (AbstractInsnNode abstractInsnNode : listInstNodes) {
            method.instructions.insertBefore(last.getPrevious(), abstractInsnNode);
        }
        // place instead of return //goto

        LabelNode startOfMethodLabel = new LabelNode(new Label());
        method.instructions.insertBefore(method.instructions.getFirst(), startOfMethodLabel);
        JumpInsnNode gotoInst = new JumpInsnNode(GOTO, startOfMethodLabel);
        method.instructions.set(last.getPrevious(), gotoInst);
        method.instructions.remove(last);

        ClassWriter cw = new ClassWriter(0);
        cn.accept(cw);
        FileOutputStream fos = new FileOutputStream(clz);
        fos.write(cw.toByteArray());
        fos.close();
    }
}

From source file:ivorius.ivtoolkit.asm.IvNodeMatcherField.java

License:Apache License

@Override
public boolean matchNode(AbstractInsnNode node) {
    if (node.getOpcode() != opCode) {
        return false;
    }//w  ww .j  av a 2 s .c o  m

    FieldInsnNode fieldInsnNode = (FieldInsnNode) node;

    if (srgFieldName != null && !srgFieldName.equals(fieldInsnNode.name)) {
        return false;
    }

    if (owner != null && !owner.equals(fieldInsnNode.owner)) {
        return false;
    }

    if (type != null && !type.equals(Type.getType(fieldInsnNode.desc))) {
        return false;
    }

    return true;
}

From source file:ivorius.ivtoolkit.asm.IvNodeMatcherFieldSRG.java

License:Apache License

@Override
public boolean matchNode(AbstractInsnNode node) {
    if (node.getOpcode() != opCode) {
        return false;
    }//from w w w.  java  2  s  .  c o  m

    FieldInsnNode fieldInsnNode = (FieldInsnNode) node;

    if (srgFieldName != null && !srgFieldName.equals(IvClassTransformer.getSrgName(fieldInsnNode))) {
        return false;
    }

    if (owner != null && !owner.equals(IvClassTransformer.getSrgClassName(fieldInsnNode.owner))) {
        return false;
    }

    if (type != null && !type.equals(Type.getType(fieldInsnNode.desc))) {
        return false;
    }

    return true;
}

From source file:ivorius.ivtoolkit.asm.IvNodeMatcherLDC.java

License:Apache License

@Override
public boolean matchNode(AbstractInsnNode node) {
    if (node.getOpcode() != Opcodes.LDC) {
        return false;
    }/*  w  w  w.  j av a2s  . c om*/

    LdcInsnNode ldcInsnNode = (LdcInsnNode) node;

    if (cst != null && !cst.equals(ldcInsnNode.cst)) {
        return false;
    }

    return true;
}

From source file:ivorius.ivtoolkit.asm.IvNodeMatcherMethod.java

License:Apache License

@Override
public boolean matchNode(AbstractInsnNode node) {
    if (node.getOpcode() != opCode) {
        return false;
    }//from  w ww .  j  a v  a 2  s  .co m

    MethodInsnNode methodInsnNode = (MethodInsnNode) node;

    if (srgMethodName != null && !srgMethodName.equals(IvClassTransformer.getSrgName(methodInsnNode))) {
        return false;
    }

    if (owner != null && !owner.equals(methodInsnNode.owner)) {
        return false;
    }

    if (desc != null && !desc.equals(methodInsnNode.desc)) {
        return false;
    }

    return true;
}

From source file:ivorius.ivtoolkit.asm.IvNodeMatcherMethodSRG.java

License:Apache License

@Override
public boolean matchNode(AbstractInsnNode node) {
    if (node.getOpcode() != opCode) {
        return false;
    }/*from   www.  j  a va  2  s .  com*/

    MethodInsnNode methodInsnNode = (MethodInsnNode) node;

    if (srgMethodName != null && !srgMethodName.equals(IvClassTransformer.getSrgName(methodInsnNode))) {
        return false;
    }

    if (owner != null && !owner.equals(IvClassTransformer.getSrgClassName(methodInsnNode.owner))) {
        return false;
    }

    if (desc != null && !desc.equals(IvClassTransformer.getSRGDescriptor(methodInsnNode.desc))) {
        return false;
    }

    return true;
}

From source file:ivorius.ivtoolkit.asm.IvNodeMatcherSimple.java

License:Apache License

@Override
public boolean matchNode(AbstractInsnNode node) {
    return node.getOpcode() == opCode;
}

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

License:Open Source License

/** Tenta computar a frame correspondente  instruco na posio i com base numa frame existente
  * anterior.//from   w  w w .  j  a  v a 2s  .com
  **/
boolean fixNullFrame(List<FlowFrame> frames, int i) {
    Log.trace("Fixing null frame: " + i);
    AbstractInsnNode previousInsn = null;
    boolean computeFromFrameNode = false;
    boolean deadCode = false;

    int j = 1;
    for (;; j++) {
        previousInsn = _il.get(i - j);
        int opcode = previousInsn.getOpcode();
        FlowFrame previousFrame = frames.get(i - j);
        if (opcode < 0) {
            if (previousInsn instanceof FrameNode && previousFrame != null) {
                break;
            }
            if (previousInsn instanceof LabelNode) {
                // FIXME: Aqui devia-se analisar os
                // predecessores da frame, para tentar
                // obter uma frame correcta vinda deles.
            }
            continue;
        }
        if (opcode == NOP && previousFrame == null) {
            // Continuar busca se encontramos um NOP sem
            // frame computada
            continue;
        }
        // Encontrmos o fim do bloco anterior
        if (opcode == GOTO || opcode == ATHROW || returnOpcodes.contains(opcode)) {
            if (_il.get(i) instanceof FrameNode) {
                // No inicio de cada bloco deve estar um FrameNode
                // Se aqui chegamos, ento quer dizer no encontramos nenhuma
                // frame que pudessemos usar para computar a actual, e vamos
                // em vez disso usar a informao do FrameNode para criar uma
                // (mesmo que possivelmente incorrecta)
                computeFromFrameNode = true;
            } else {
                // Encontrmos dead code.
                // Em casos como o do NewSpecExample20, a seguinte estrutura
                // pode ocorrer:
                // GOTO L8
                // NOP
                // L9
                // FRAME FULL [I I J] []
                // ou seja, o NOP que foi adicionado antes da label  dead code
                // e poderemos estar a tentar analizar uma range que contm
                // este padro.
                deadCode = true;
            }
            break;
        }

        if (previousFrame == null) {
            // Vamos ter que calcular a frame da instruco actual antes de
            // podermos prosseguir
            Log.trace("Recursing fixNullFrame");
            fixNullFrame(frames, i - j);
        }

        break;
    }

    try {
        if (deadCode)
            return true;

        if (computeFromFrameNode) {
            frames.set(i, frameFromFrameNode((FrameNode) _il.get(i)));
        } else {
            frames.set(i, computeNextFrame(frames.get(i - j), previousInsn));
        }

        //FixFutureMultipleControlFlows.printCode(_mn, frames, frame.predecessors(), frame);

        return false;
    } catch (AnalyzerException e) {
        throw new Error(e);
    }
}