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:jaspex.speculation.newspec.FlowFrame.java

License:Open Source License

FlowFrame computeNextFrame(FlowFrame previousFrame, AbstractInsnNode insn) throws AnalyzerException {
    if (previousFrame == null)
        throw new NullPointerException("Null previousFrame");

    FlowFrame newFrame = newFrame(previousFrame);

    // Verificar que instruco produz uma frame
    if (insn.getOpcode() == ATHROW || returnOpcodes.contains(insn.getOpcode())) {
        throw new AssertionError();
    }/*  w  ww.  j a va 2 s  .c  o  m*/

    if (!(insn instanceof FrameNode || insn instanceof LabelNode || insn instanceof LineNumberNode)) {
        try {
            newFrame.execute(insn, _interpreter);
        } catch (IndexOutOfBoundsException e) {
            throw new AnalyzerException(insn, "Error inside computeNextFrame", e);
        } catch (NullPointerException e) {
            throw new AnalyzerException(insn, "Error inside computeNextFrame", e);
        }
    }

    return newFrame;
}

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

License:Open Source License

@Override
public BasicValue copyOperation(AbstractInsnNode insn, BasicValue value) throws AnalyzerException {
    // DelayGetFutureMethodVisitor.visitVarInsn, verso interpetador
    int opcode = insn.getOpcode();

    if (opcode == DUP2 || opcode == DUP2_X1 || opcode == DUP2_X2 || opcode == POP2) {
        if (isFuture(value)) {
            Type t = stripFuture(value).getType();
            if (t.equals(Type.LONG_TYPE) || t.equals(Type.DOUBLE_TYPE)) {
                // Temos de fazer substituio de bytecodes
                switch (opcode) {
                case DUP2:
                    opcode = DUP;/*from  w  w  w  . j  a  va 2s. c  o m*/
                    break;
                case DUP2_X1:
                    opcode = DUP_X1;
                    break;
                case DUP2_X2:
                    opcode = DUP_X2;
                    break;
                case POP2:
                    opcode = POP;
                    break;
                }
                insn = new InsnNode(opcode);
            }
        }
    } else if (localLoadOpcodes.contains(opcode) && isFuture(value)) {
        insn = new VarInsnNode(ALOAD, ((VarInsnNode) insn).var);
    } else if (localStoreOpcodes.contains(opcode) && isFuture(value)) {
        insn = new VarInsnNode(ASTORE, ((VarInsnNode) insn).var);
    }
    return super.copyOperation(insn, value);
}

From source file:jaspex.transactifier.ChangeClinitMethodVisitor.java

License:Open Source License

private static boolean clinitIsSafe(Type t) {
    try {//  w w w  .  j  a  va2s .com
        ClassReader cr = new ClassReader(t.commonName());
        ClassNode cNode = new ClassNode();
        cr.accept(cNode, 0);

        for (MethodNode method : cNode.methods) {
            if (!method.name.equals("<clinit>"))
                continue;
            // Examinar instruces
            Iterator<AbstractInsnNode> it = method.instructions.iterator();
            while (it.hasNext()) {
                AbstractInsnNode insn = it.next();
                switch (insn.getType()) {
                case AbstractInsnNode.FRAME:
                case AbstractInsnNode.INT_INSN:
                case AbstractInsnNode.JUMP_INSN:
                case AbstractInsnNode.LABEL:
                case AbstractInsnNode.LDC_INSN:
                case AbstractInsnNode.LINE:
                case AbstractInsnNode.LOOKUPSWITCH_INSN:
                case AbstractInsnNode.MULTIANEWARRAY_INSN:
                case AbstractInsnNode.TABLESWITCH_INSN:
                case AbstractInsnNode.TYPE_INSN:
                case AbstractInsnNode.VAR_INSN:
                    break;
                case AbstractInsnNode.FIELD_INSN:
                    FieldInsnNode fieldInsn = (FieldInsnNode) insn;
                    if (fieldInsn.getOpcode() != PUTSTATIC) {
                        // GETSTATIC, GETFIELD, PUTFIELD
                        return false;
                    }
                    break;
                case AbstractInsnNode.IINC_INSN:
                    return false;
                case AbstractInsnNode.INSN:
                    if (unsafeInsnBytecodes.contains(insn.getOpcode())) {
                        Log.debug(t.commonName() + ".<clinit>() is unsafe " + "because of bytecode "
                                + insn.getOpcode());
                        return false;
                    }
                    break;
                case AbstractInsnNode.METHOD_INSN:
                    MethodInsnNode methodInsn = (MethodInsnNode) insn;
                    if (!ClassFilter.isMethodWhitelisted(Type.fromAsm(methodInsn.owner), methodInsn.name,
                            methodInsn.desc)) {
                        Log.debug(t.commonName() + ".<clinit>() is unsafe " + "because it invokes "
                                + Type.fromAsm(methodInsn.owner).commonName() + "." + methodInsn.name);
                        return false;
                    }
                    break;
                default:
                    throw new Error("Unexpected bytecode " + insn);
                }
            }

            //Log.debug(t.commonName() + ".<clinit>() for " + t + " is safe");
            return true;
        }

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

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  ww  w  .  j ava2  s  .  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:kilim.analysis.BasicBlock.java

License:Open Source License

/**
 * Absorb as many instructions until the next label or the next transfer of
 * control instruction. In the first pass we may end up creating many many
 * BBs because there may be a lot of non-target labels (esp. when debug
 * information is available). The constraints are as follows:
 *   1. A transfer of control instruction must be the last instruction. It 
 *      may also be the first (and only) instruction
 *   2. A labeled instruction must be the first instruction in a BB. It
 *      may optionally be the last (and only) instruction
 *   3. A pausable method is treated like a labeled instruction, and is 
 *      given a label if there isn't one already. Constraint 2 applies.
 *//*from www  . j  av  a 2s .c  om*/
@SuppressWarnings("unchecked")
int initialize(int pos) {
    AbstractInsnNode ain;
    startPos = pos;

    BasicBlock bb;
    boolean endOfBB = false;
    boolean hasFollower = true;
    int size = flow.instructions.size();
    for (; pos < size; pos++) {
        if (pos > startPos && flow.getLabelAt(pos) != null) {
            pos--;
            hasFollower = true;
            endOfBB = true;
            break;
        }
        ain = getInstruction(pos);
        int opcode = ain.getOpcode();
        switch (opcode) {
        case ALOAD:
        case ILOAD:
        case LLOAD:
        case FLOAD:
        case DLOAD:
            usage.read(((VarInsnNode) ain).var);
            break;

        case ISTORE:
        case LSTORE:
        case FSTORE:
        case DSTORE:
        case ASTORE:
            usage.write(((VarInsnNode) ain).var);
            break;

        case IINC:
            int v = ((IincInsnNode) ain).var;
            usage.read(v);
            usage.write(v);
            break;

        case IFEQ:
        case IFNE:
        case IFLT:
        case IFGE:
        case IFGT:
        case IFLE:
        case IFNULL:
        case IFNONNULL:
        case IF_ICMPEQ:
        case IF_ICMPNE:
        case IF_ICMPLT:
        case IF_ICMPGE:
        case IF_ICMPGT:
        case IF_ICMPLE:
        case IF_ACMPEQ:
        case IF_ACMPNE:
        case JSR:
        case GOTO:
            bb = flow.getOrCreateBasicBlock(((JumpInsnNode) ain).label.getLabel());
            if (opcode == JSR) {
                bb.setFlag(IS_SUBROUTINE);
                hasFollower = false;
            }
            addSuccessor(bb);
            if (opcode == GOTO) {
                hasFollower = false;
            }
            endOfBB = true;
            break;

        case RET:
        case IRETURN:
        case LRETURN:
        case FRETURN:
        case DRETURN:
        case ARETURN:
        case RETURN:
        case ATHROW:
            hasFollower = false;
            endOfBB = true;
            break;

        case TABLESWITCH:
        case LOOKUPSWITCH:
            LabelNode defaultLabel;
            List<LabelNode> otherLabels;
            if (opcode == TABLESWITCH) {
                defaultLabel = ((TableSwitchInsnNode) ain).dflt;
                otherLabels = ((TableSwitchInsnNode) ain).labels;
            } else {
                defaultLabel = ((LookupSwitchInsnNode) ain).dflt;
                otherLabels = ((LookupSwitchInsnNode) ain).labels;
            }
            for (Iterator<LabelNode> it = otherLabels.iterator(); it.hasNext();) {
                addSuccessor(flow.getOrCreateBasicBlock(((LabelNode) it.next()).getLabel()));
            }
            addSuccessor(flow.getOrCreateBasicBlock(defaultLabel.getLabel()));
            endOfBB = true;
            hasFollower = false;
            break;

        case INVOKEVIRTUAL:
        case INVOKESTATIC:
        case INVOKEINTERFACE:
        case INVOKEDYNAMIC: // TODO this is new and mysterious
        case INVOKESPECIAL:
            if (flow.isPausableMethodInsn((MethodInsnNode) ain)) {
                if (pos == startPos) {
                    setFlag(PAUSABLE);
                } else {
                    bb = flow.getOrCreateBasicBlock(flow.getOrCreateLabelAtPos(pos));
                    bb.setFlag(PAUSABLE);
                    addSuccessor(bb);
                    pos--; // don't consume this instruction
                    hasFollower = true;
                    endOfBB = true;
                }
            }
            break;

        default:
            if (opcode >= 26 && opcode <= 45)
                throw new IllegalStateException("instruction variants not expected here");

            break;
        }

        if (endOfBB)
            break;
    }
    endPos = pos;
    if (hasFollower && (pos + 1) < flow.instructions.size()) {
        // add the following basic block as a successor
        Label l = flow.getOrCreateLabelAtPos(pos + 1);
        bb = flow.getOrCreateBasicBlock(l);
        addFollower(bb);
    }

    return pos;
}

From source file:kilim.analysis.BasicBlock.java

License:Open Source License

int lastInstruction() {
    AbstractInsnNode ainode = getInstruction(endPos);
    return ainode.getOpcode();
}

From source file:kilim.analysis.BasicBlock.java

License:Open Source License

void interpret() {
    Value v, v1, v2, v3, v4;//from   w  w w.  j a v a  2s  .  co  m
    Frame frame = startFrame.dup();
    if (isCatchHandler()) {
        // When an exception is thrown, the stack is cleared
        // and the thrown exception is pushed into the stack
        frame.clearStack();
        frame.push(Value.make(startPos, caughtExceptionType));
    } else if (hasFlag(IS_SUBROUTINE)) {
        // The target of a JSR instruction has a JVM-internal
        // return address which we model with a type of its
        // own
        frame.push(Value.make(startPos, D_RETURN_ADDRESS));
    }
    String componentType = null;
    @SuppressWarnings("unused")
    boolean canThrowException = false;
    boolean propagateFrame = true;
    int i = 0;
    try {
        for (i = startPos; i <= endPos; i++) {
            AbstractInsnNode ain = getInstruction(i);
            int opcode = ain.getOpcode();
            int val, var;
            switch (opcode) {
            case NOP:
                break;
            case ACONST_NULL:
                frame.push(Value.make(i, D_NULL));
                break;

            case ICONST_M1:
            case ICONST_0:
            case ICONST_1:
            case ICONST_2:
            case ICONST_3:
            case ICONST_4:
            case ICONST_5:
                frame.push(Value.make(i, D_INT, new Integer(opcode - ICONST_0)));
                break;

            case LCONST_0:
            case LCONST_1:
                frame.push(Value.make(i, D_LONG, new Long(opcode - LCONST_0)));
                break;

            case ILOAD:
            case LLOAD:
            case FLOAD:
            case DLOAD:
            case ALOAD:
                var = ((VarInsnNode) ain).var;
                v = frame.getLocal(var, opcode);
                frame.push(v);
                break;

            case FCONST_0:
            case FCONST_1:
            case FCONST_2:
                frame.push(Value.make(i, D_FLOAT, new Float(opcode - FCONST_0)));
                break;

            case DCONST_0:
            case DCONST_1:
                frame.push(Value.make(i, D_DOUBLE, new Double(opcode - DCONST_0)));
                break;

            case BIPUSH:
                val = ((IntInsnNode) ain).operand;
                frame.push(Value.make(i, D_BYTE, new Integer(val)));
                break;

            case SIPUSH:
                val = ((IntInsnNode) ain).operand;
                frame.push(Value.make(i, D_SHORT, new Integer(val)));
                break;

            case LDC:
                Object cval = ((LdcInsnNode) ain).cst;
                frame.push(Value.make(i, TypeDesc.getTypeDesc(cval), cval));
                break;

            case IALOAD:
            case LALOAD:
            case FALOAD:
            case DALOAD:
            case AALOAD:
            case BALOAD:
            case CALOAD:
            case SALOAD:
                canThrowException = true;
                frame.popWord(); // pop index
                v = frame.popWord(); // array ref
                frame.push(Value.make(i, TypeDesc.getComponentType(v.getTypeDesc()))); // push
                // component
                // of
                // array
                break;

            case ISTORE:
            case LSTORE:
            case FSTORE:
            case DSTORE:
            case ASTORE:
                v1 = frame.pop();
                var = ((VarInsnNode) ain).var;
                frame.setLocal(var, v1);
                break;

            case IASTORE:
            case LASTORE:
            case FASTORE:
            case DASTORE:
            case AASTORE:
            case BASTORE:
            case CASTORE:
            case SASTORE:
                canThrowException = true;
                frame.popn(3);
                break;

            case POP:
                frame.popWord();
                break;

            case POP2:
                if (frame.pop().isCategory1()) {
                    frame.popWord();
                }
                break;

            case DUP:
                // ... w => ... w w
                v = frame.popWord();
                frame.push(v);
                frame.push(v);
                break;

            case DUP_X1:
                // Insert top word beneath the next word
                // .. w2 w1 => .. w1 w2 w1
                v1 = frame.popWord();
                v2 = frame.popWord();
                frame.push(v1);
                frame.push(v2);
                frame.push(v1);
                break;

            case DUP_X2:
                // Insert top word beneath the next two words (or dword)
                v1 = frame.popWord();
                v2 = frame.pop();
                if (v2.isCategory1()) {
                    v3 = frame.pop();
                    if (v3.isCategory1()) {
                        // w3,w2,w1 => w1,w3,w2,w1
                        frame.push(v1);
                        frame.push(v3);
                        frame.push(v2);
                        frame.push(v1);
                        break;
                    }
                } else {
                    // dw2,w1 => w1,dw2,w1
                    frame.push(v1);
                    frame.push(v2);
                    frame.push(v1);
                    break;
                }
                throw new InternalError("Illegal use of DUP_X2");

            case DUP2:
                // duplicate top two words (or dword)
                v1 = frame.pop();
                if (v1.isCategory1()) {
                    v2 = frame.pop();
                    if (v2.isCategory1()) {
                        // w2,w1 => w2,w1,w2,w1
                        frame.push(v2);
                        frame.push(v1);
                        frame.push(v2);
                        frame.push(v1);
                        break;
                    }
                } else {
                    // dw1 => dw1,dw1
                    frame.push(v1);
                    frame.push(v1);
                    break;
                }
                throw new InternalError("Illegal use of DUP2");

            case DUP2_X1:
                // insert two words (or dword) beneath next word
                v1 = frame.pop();
                if (v1.isCategory1()) {
                    v2 = frame.pop();
                    if (v2.isCategory1()) {
                        v3 = frame.popWord();
                        // w3,w2,w1 => w2,w1,w3,w2,w1
                        frame.push(v2);
                        frame.push(v1);
                        frame.push(v3);
                        frame.push(v2);
                        frame.push(v1);
                        break;
                    }
                } else { // TypeDesc.isDoubleWord(t1)
                    // w2,dw1 => dw1,w2,dw1
                    v2 = frame.popWord();
                    frame.push(v1);
                    frame.push(v2);
                    frame.push(v1);
                    break;
                }
                throw new InternalError("Illegal use of DUP2_X1");
            case DUP2_X2:
                // insert two words (or dword) beneath next two words (or
                // dword)
                v1 = frame.pop();
                if (v1.isCategory1()) {
                    v2 = frame.pop();
                    if (v2.isCategory1()) {
                        v3 = frame.pop();
                        if (v3.isCategory1()) {
                            v4 = frame.pop();
                            if (v4.isCategory1()) {
                                // w4,w3,w2,w1 => w2,w1,w4,w3,w2,w1
                                frame.push(v2);
                                frame.push(v1);
                                frame.push(v4);
                                frame.push(v3);
                                frame.push(v2);
                                frame.push(v1);
                                break;
                            }
                        } else { // TypeDesc.isDoubleWord(t3)
                            // dw3,w2,w1 => w2,w1,dw3,w2,w1
                            frame.push(v2);
                            frame.push(v1);
                            frame.push(v3);
                            frame.push(v2);
                            frame.push(v1);
                            break;
                        }
                    }
                } else { // TypeDesc.isDoubleWord(t1)
                    v2 = frame.pop();
                    if (v2.isCategory1()) {
                        v3 = frame.pop();
                        if (v3.isCategory1()) {
                            // w3,w2,dw1 => dw1,w3,w2,dw1
                            frame.push(v1);
                            frame.push(v3);
                            frame.push(v2);
                            frame.push(v1);
                            break;
                        }
                    } else {
                        // dw2,dw1 => dw1,dw2,dw1
                        frame.push(v1);
                        frame.push(v2);
                        frame.push(v1);
                        break;
                    }
                }
                throw new InternalError("Illegal use of DUP2_X2");

            case SWAP:
                // w2, w1 => w1, w2
                v1 = frame.popWord();
                v2 = frame.popWord();
                frame.push(v1);
                frame.push(v2);
                break;

            case IDIV:
            case IREM:
            case LDIV:
            case LREM:
                frame.pop(); // See next case
                canThrowException = true;
                break;

            case IADD:
            case LADD:
            case FADD:
            case DADD:
            case ISUB:
            case LSUB:
            case FSUB:
            case DSUB:
            case IMUL:
            case LMUL:
            case FMUL:
            case DMUL:
            case FDIV:
            case DDIV:
            case FREM:
            case DREM:
            case ISHL:
            case LSHL:
            case ISHR:
            case LSHR:
            case IUSHR:
            case LUSHR:
            case IAND:
            case LAND:
            case IOR:
            case LOR:
            case IXOR:
            case LXOR:
                // Binary op.
                frame.pop();
                v = frame.pop();
                // The result is always the same type as the first arg
                frame.push(Value.make(i, v.getTypeDesc()));
                break;

            case LCMP:
            case FCMPL:
            case FCMPG:
            case DCMPL:
            case DCMPG:
                frame.popn(2);
                frame.push(Value.make(i, D_INT));
                break;

            case INEG:
            case LNEG:
            case FNEG:
            case DNEG:
                v = frame.pop();
                frame.push(Value.make(i, v.getTypeDesc()));
                break;

            case IINC:
                var = ((IincInsnNode) ain).var;
                frame.setLocal(var, Value.make(i, D_INT));
                break;

            case I2L:
            case F2L:
            case D2L:
                frame.pop();
                frame.push(Value.make(i, D_LONG));
                break;

            case I2D:
            case L2D:
            case F2D:
                frame.pop();
                frame.push(Value.make(i, D_DOUBLE));
                break;

            case I2F:
            case L2F:
            case D2F:
                frame.pop();
                frame.push(Value.make(i, D_FLOAT));
                break;

            case L2I:
            case F2I:
            case D2I:
                frame.pop();
                frame.push(Value.make(i, D_INT));
                break;

            case I2B:
                frame.popWord();
                frame.push(Value.make(i, D_BOOLEAN));
                break;

            case I2C:
                frame.popWord();
                frame.push(Value.make(i, D_CHAR));
                break;

            case I2S:
                frame.popWord();
                frame.push(Value.make(i, D_SHORT));
                break;

            case IFEQ:
            case IFNE:
            case IFLT:
            case IFGE:
            case IFGT:
            case IFLE:
            case IFNULL:
            case IFNONNULL:
                frame.popWord();
                break;

            case IF_ICMPEQ:
            case IF_ICMPNE:
            case IF_ICMPLT:
            case IF_ICMPGE:
            case IF_ICMPGT:
            case IF_ICMPLE:
            case IF_ACMPEQ:
            case IF_ACMPNE:
                frame.popn(2);
                break;

            case GOTO:
            case JSR: // note: the targetBB pushes the return address
                // itself
                // because it is marked with isSubroutine
            case RET:
                break;

            case TABLESWITCH:
            case LOOKUPSWITCH:
                frame.pop();
                break;

            case IRETURN:
            case LRETURN:
            case FRETURN:
            case DRETURN:
            case ARETURN:
            case RETURN:
                canThrowException = true;
                if (opcode != RETURN) {
                    frame.pop();
                }
                if (frame.stacklen != 0) {
                    throw new InternalError("stack non null at method return");
                }
                break;

            case GETSTATIC:
                canThrowException = true;
                v = Value.make(i, TypeDesc.getInterned(((FieldInsnNode) ain).desc));
                frame.push(v);
                break;

            case PUTSTATIC:
                canThrowException = true;
                frame.pop();
                break;

            case GETFIELD:
                canThrowException = true;
                v1 = frame.pop();
                v = Value.make(i, TypeDesc.getInterned(((FieldInsnNode) ain).desc));
                //if (TypeDesc.isRefType(v.getTypeDesc())) {
                //    System.out.println("GETFIELD " + ((FieldInsnNode)ain).name  + ": " + v + "---->" + v1);
                //}
                frame.push(v);
                break;

            case PUTFIELD:
                canThrowException = true;
                v1 = frame.pop();
                v = frame.pop();
                //if (TypeDesc.isRefType(v.getTypeDesc())) {
                //    System.out.println("PUTFIELD " + ((FieldInsnNode)ain).name  + ": " + v + " ----> " + v1);
                //}
                break;

            case INVOKEVIRTUAL:
            case INVOKESPECIAL:
            case INVOKESTATIC:
            case INVOKEINTERFACE:
            case INVOKEDYNAMIC: // TODO this is new and mysterious
                // pop args, push return value
                MethodInsnNode min = ((MethodInsnNode) ain);
                String desc = min.desc;
                if (flow.isPausableMethodInsn(min) && frame.numMonitorsActive > 0) {
                    throw new KilimException(
                            "Error: Can not call pausable nethods from within a synchronized block\n"
                                    + "Caller: " + this.flow.name + "\nCallee: " + ((MethodInsnNode) ain).name);
                }
                canThrowException = true;
                frame.popn(TypeDesc.getNumArgumentTypes(desc));
                if (opcode != INVOKESTATIC) {
                    v = frame.pop(); // "this" ref
                    //assert checkReceiverType(v, min) : "Method " + flow.name + " calls " + min.name + " on a receiver with incompatible type " + v.getTypeDesc() ;
                }
                desc = TypeDesc.getReturnTypeDesc(desc);
                if (desc != D_VOID) {
                    frame.push(Value.make(i, desc));
                }
                break;

            case NEW:
                canThrowException = true;
                v = Value.make(i, TypeDesc.getInterned(((TypeInsnNode) ain).desc));
                frame.push(v);
                break;

            case NEWARRAY:
                canThrowException = true;
                frame.popWord();
                int atype = ((IntInsnNode) ain).operand;
                String t;
                switch (atype) {
                case T_BOOLEAN:
                    t = D_ARRAY_BOOLEAN;
                    break;
                case T_CHAR:
                    t = D_ARRAY_CHAR;
                    break;
                case T_FLOAT:
                    t = D_ARRAY_FLOAT;
                    break;
                case T_DOUBLE:
                    t = D_ARRAY_DOUBLE;
                    break;
                case T_BYTE:
                    t = D_ARRAY_BYTE;
                    break;
                case T_SHORT:
                    t = D_ARRAY_SHORT;
                    break;
                case T_INT:
                    t = D_ARRAY_INT;
                    break;
                case T_LONG:
                    t = D_ARRAY_LONG;
                    break;
                default:
                    throw new InternalError("Illegal argument to NEWARRAY: " + atype);
                }
                frame.push(Value.make(i, t));
                break;
            case ANEWARRAY:
                canThrowException = true;
                frame.popWord();
                componentType = TypeDesc.getInterned(((TypeInsnNode) ain).desc);
                v = Value.make(i, TypeDesc.getInterned("[" + componentType));
                frame.push(v);
                break;

            case ARRAYLENGTH:
                canThrowException = true;
                frame.popWord();
                frame.push(Value.make(i, D_INT));
                break;

            case ATHROW:
                canThrowException = true;
                frame.pop();
                propagateFrame = false;
                break;

            case CHECKCAST:
                canThrowException = true;
                frame.pop();
                v = Value.make(i, TypeDesc.getInterned(((TypeInsnNode) ain).desc));
                frame.push(v);
                break;

            case INSTANCEOF:
                canThrowException = true;
                frame.pop();
                frame.push(Value.make(i, D_INT));
                break;

            case MONITORENTER:
            case MONITOREXIT:
                if (opcode == MONITORENTER) {
                    frame.numMonitorsActive++;
                } else {
                    frame.numMonitorsActive--;
                }
                canThrowException = true;
                frame.pop();
                canThrowException = true;
                break;

            case MULTIANEWARRAY:
                MultiANewArrayInsnNode minode = (MultiANewArrayInsnNode) ain;
                int dims = minode.dims;
                frame.popn(dims);
                componentType = TypeDesc.getInterned(minode.desc);
                StringBuffer sb = new StringBuffer(componentType.length() + dims);
                for (int j = 0; j < dims; j++)
                    sb.append('[');
                sb.append(componentType);
                v = Value.make(i, TypeDesc.getInterned(sb.toString()));
                frame.push(v);
                break;
            case -1: // TODO this is new and mysterious
                break;
            default:
                assert false : "Unexpected opcode: " + ain.getOpcode();
            }
        }
        i = -1; // reset for assertion catch block below
        if (propagateFrame) {
            mergeSuccessors(frame);
        }
        if (handlers != null) {
            for (Handler handler : handlers) {
                handler.catchBB.merge(frame, /* localsOnly= */true); // merge
                // only
                // locals
            }
            canThrowException = false;
        }
    } catch (AssertionError ae) {
        System.err.println("**** Assertion Error analyzing " + flow.classFlow.name + "." + flow.name);
        System.err.println("Basic block " + this);
        System.err.println("i = " + i);
        System.err.println("Frame: " + frame);
        throw ae;
    }

}

From source file:kilim.analysis.BasicBlock.java

License:Open Source License

@SuppressWarnings("unchecked")
static ArrayList<BasicBlock> dupCopyContents(boolean deepCopy, BasicBlock targetBB, BasicBlock returnToBB,
        HashMap<BasicBlock, BasicBlock> bbCopyMap, HashMap<Label, LabelNode> labelCopyMap)
        throws KilimException {

    ArrayList<BasicBlock> newBBs = new ArrayList<BasicBlock>(targetBB.getSubBlocks().size());
    for (BasicBlock orig : targetBB.getSubBlocks()) {
        BasicBlock dup = bbCopyMap.get(orig);
        dup.flags = orig.flags;//  w  ww.j  a  va2 s.  c  o m
        dup.caughtExceptionType = orig.caughtExceptionType;
        dup.startPos = orig.startPos;
        dup.endPos = orig.endPos;
        dup.flow = orig.flow;
        dup.numPredecessors = orig.numPredecessors;
        dup.startFrame = null;
        dup.usage = orig.usage.copy();
        dup.handlers = orig.handlers;
        if (orig.follower != null) {
            dup.follower = bbCopyMap.get(orig.follower);
            if (dup.follower == null) {
                assert dup.lastInstruction() == RET;
            }
        }
        dup.successors = new ArrayList<BasicBlock>(orig.successors.size());
        if (orig.lastInstruction() == RET) {
            dup.addSuccessor(returnToBB);
        } else {
            for (BasicBlock s : orig.successors) {
                BasicBlock b = bbCopyMap.get(s);
                dup.addSuccessor(b);
            }
        }

        if (deepCopy) {
            MethodFlow flow = targetBB.flow;
            InsnList instructions = flow.instructions;
            // copy instructions
            dup.startLabel = labelCopyMap.get(orig.startLabel).getLabel();
            dup.startPos = instructions.size();
            dup.endPos = dup.startPos + (orig.endPos - orig.startPos);
            // Note: last instruction (@endPos) isn't copied in the loop.
            // If it has labels, a new instruction is generated; either
            // way the last instruction is appended separately.
            int newPos = instructions.size();
            int end = orig.endPos;

            // create new labels and instructions
            for (int i = orig.startPos; i <= end; i++, newPos++) {
                Label l = flow.getLabelAt(i);
                if (l != null) {
                    l = labelCopyMap.get(l).getLabel();
                    assert l != null;
                    flow.setLabel(newPos, l);
                }
                if (i != end) {
                    // last insn gets special treatment
                    instructions.add(instructions.get(i));
                }
            }

            AbstractInsnNode lastInsn = (AbstractInsnNode) instructions.get(orig.endPos);
            LabelNode dupLabel;
            int opcode = lastInsn.getOpcode();
            if (lastInsn instanceof JumpInsnNode) {
                JumpInsnNode jin = (JumpInsnNode) lastInsn;
                if (lastInsn.getOpcode() != JSR) {
                    dupLabel = labelCopyMap.get(jin.label);
                    assert dupLabel != null;
                    lastInsn = new JumpInsnNode(lastInsn.getOpcode(), dupLabel);
                }
            } else if (opcode == TABLESWITCH) {
                TableSwitchInsnNode tsin = (TableSwitchInsnNode) lastInsn;
                LabelNode[] labels = new LabelNode[tsin.labels.size()];
                for (int i = 0; i < labels.length; i++) {
                    dupLabel = labelCopyMap.get(tsin.labels.get(i));
                    assert dupLabel != null;
                    labels[i] = dupLabel;
                }
                dupLabel = labelCopyMap.get(tsin.dflt);
                assert dupLabel != null;
                lastInsn = new TableSwitchInsnNode(tsin.min, tsin.max, dupLabel, labels);
            } else if (opcode == LOOKUPSWITCH) {
                LookupSwitchInsnNode lsin = (LookupSwitchInsnNode) lastInsn;
                LabelNode[] labels = new LabelNode[lsin.labels.size()];
                for (int i = 0; i < labels.length; i++) {
                    dupLabel = labelCopyMap.get(lsin.labels.get(i));
                    assert dupLabel != null;
                    labels[i] = dupLabel;
                }
                dupLabel = labelCopyMap.get(lsin.dflt);
                assert dupLabel != null;
                int[] keys = new int[lsin.keys.size()];
                for (int i = 0; i < keys.length; i++) {
                    keys[i] = (Integer) lsin.keys.get(i);
                }
                lastInsn = new LookupSwitchInsnNode(dupLabel, keys, labels);
            }
            instructions.add(lastInsn);
            // new handlers
            dup.handlers = new ArrayList<Handler>(orig.handlers.size());
            if (orig.handlers.size() > 0) {
                for (Handler oh : orig.handlers) {
                    Handler h = new Handler(dup.startPos + (oh.from - orig.startPos),
                            dup.endPos + (oh.to - orig.endPos), oh.type, oh.catchBB);
                    dup.handlers.add(h);
                }
            }
        }
        newBBs.add(dup);
    }
    return newBBs;
}

From source file:kilim.analysis.BasicBlock.java

License:Open Source License

public boolean isGetCurrentTask() {
    AbstractInsnNode ain = getInstruction(startPos);
    if (ain.getOpcode() == INVOKESTATIC) {
        MethodInsnNode min = (MethodInsnNode) ain;
        return min.owner.equals(TASK_CLASS) && min.name.equals("getCurrentTask");
    }// w  w  w. j  a  v a2s  .  c o m
    return false;
}

From source file:name.martingeisse.minimal.compiler.Compiler.java

License:Open Source License

/**
 * Compiles a {@link MethodNode} to MCode.
 * //  w w  w  . ja va2  s  .co  m
 * @param methodNode the method node to compile
 * @return the compiled code
 */
public ImmutableList<MCodeEntry> compile(final MethodNode methodNode) {
    for (int i = 0; i < methodNode.instructions.size(); i++) {
        final AbstractInsnNode instruction = methodNode.instructions.get(i);
        if (instruction instanceof LineNumberNode) {
            // ignored
        } else if (instruction instanceof FrameNode) {
            // this could be useful in the future
        } else if (instruction instanceof LabelNode) {
            label(((LabelNode) instruction).getLabel());
        } else if (instruction instanceof InsnNode) {
            switch (instruction.getOpcode()) {

            case Opcodes.ICONST_M1:
                iconst(-1);
                break;

            case Opcodes.ICONST_0:
                iconst(0);
                break;

            case Opcodes.ICONST_1:
                iconst(1);
                break;

            case Opcodes.ICONST_2:
                iconst(2);
                break;

            case Opcodes.ICONST_3:
                iconst(3);
                break;

            case Opcodes.ICONST_4:
                iconst(4);
                break;

            case Opcodes.ICONST_5:
                iconst(5);
                break;

            default:
                unsupported(instruction);
                break;

            }
        } else if (instruction instanceof VarInsnNode) {
            final VarInsnNode varInsnNode = (VarInsnNode) instruction;
            switch (varInsnNode.getOpcode()) {

            case Opcodes.ILOAD:
                iload(varInsnNode.var);
                break;

            case Opcodes.ISTORE:
                istore(varInsnNode.var);
                break;

            default:
                unsupported(instruction);
                break;

            }
        } else if (instruction instanceof IincInsnNode) {
            final IincInsnNode iincInsnNode = (IincInsnNode) instruction;
            iinc(iincInsnNode.var, iincInsnNode.incr);
        } else if (instruction instanceof JumpInsnNode) {
            final JumpInsnNode jumpInsnNode = (JumpInsnNode) instruction;
            switch (jumpInsnNode.getOpcode()) {

            case Opcodes.IFEQ:
            case Opcodes.IFNE:
            case Opcodes.IFLT:
            case Opcodes.IFGE:
            case Opcodes.IFGT:
            case Opcodes.IFLE:
                branch1(jumpInsnNode.label.getLabel(), jumpInsnNode.getOpcode());
                break;

            case Opcodes.IF_ICMPEQ:
            case Opcodes.IF_ICMPNE:
            case Opcodes.IF_ICMPLT:
            case Opcodes.IF_ICMPGE:
            case Opcodes.IF_ICMPGT:
            case Opcodes.IF_ICMPLE:
                branch2(jumpInsnNode.label.getLabel(), jumpInsnNode.getOpcode());
                break;

            case Opcodes.IFNULL:
            case Opcodes.IFNONNULL:
                // unsupported: one-argument reference comparison operator
                unsupported(instruction);
                break;

            case Opcodes.IF_ACMPEQ:
            case Opcodes.IF_ACMPNE:
                // unsupported: two-argument reference comparison operator
                unsupported(instruction);
                break;

            case Opcodes.GOTO:
                jump(jumpInsnNode.label.getLabel());
                break;

            case Opcodes.JSR:
                jsr(jumpInsnNode.label.getLabel());
                break;

            default:
                unsupported(instruction);
                break;

            }
        } else if (instruction instanceof IntInsnNode) {
            final IntInsnNode intInsnNode = (IntInsnNode) instruction;
            if (instruction.getOpcode() == Opcodes.BIPUSH || instruction.getOpcode() == Opcodes.SIPUSH) {
                iconst(intInsnNode.operand);
            } else {
                // NEWARRAY
                unsupported(instruction);
            }
        } else if (instruction instanceof MethodInsnNode) {
            final MethodInsnNode methodInsnNode = (MethodInsnNode) instruction;
            if (methodInsnNode.getOpcode() == Opcodes.INVOKESTATIC) {
                if (methodInsnNode.owner.replace('/', '.').equals(Native.class.getName())) {
                    nativeCall(methodInsnNode.name, methodInsnNode.desc);
                } else {
                    unsupported(instruction);
                }
            } else {
                unsupported(instruction);
            }
        } else {
            unsupported(instruction);
        }
    }
    return builder.build();
}