Example usage for org.objectweb.asm Opcodes FCMPL

List of usage examples for org.objectweb.asm Opcodes FCMPL

Introduction

In this page you can find the example usage for org.objectweb.asm Opcodes FCMPL.

Prototype

int FCMPL

To view the source code for org.objectweb.asm Opcodes FCMPL.

Click Source Link

Usage

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

License:Open Source License

/**
 * <p>transformMethod</p>/*from w  w w.j av  a2  s  .c  om*/
 *
 * @param mn a {@link org.objectweb.asm.tree.MethodNode} object.
 */
public void transformMethod(MethodNode mn) {
    AbstractInsnNode node = mn.instructions.getFirst();
    while (node != mn.instructions.getLast()) {
        AbstractInsnNode next = node.getNext();
        if (node instanceof InsnNode) {
            InsnNode in = (InsnNode) node;
            if (in.getOpcode() == Opcodes.LCMP) {
                insertLongComparison(in, mn.instructions);
                TransformationStatistics.transformedComparison();
            } else if (in.getOpcode() == Opcodes.DCMPG) {
                // TODO: Check treatment of NaN
                TransformationStatistics.transformedComparison();
                insertDoubleComparison(in, mn.instructions);
            } else if (in.getOpcode() == Opcodes.DCMPL) {
                TransformationStatistics.transformedComparison();
                insertDoubleComparison(in, mn.instructions);
            } else if (in.getOpcode() == Opcodes.FCMPG) {
                TransformationStatistics.transformedComparison();
                insertFloatComparison(in, mn.instructions);
            } else if (in.getOpcode() == Opcodes.FCMPL) {
                TransformationStatistics.transformedComparison();
                insertFloatComparison(in, mn.instructions);
            }
        }
        node = next;
    }
}

From source file:org.evosuite.instrumentation.testability.ComparisonTransformation.java

License:Open Source License

/**
 * <p>transformMethod</p>/* w w  w .  j a  v a2 s. c o m*/
 *
 * @param mn a {@link org.objectweb.asm.tree.MethodNode} object.
 */
public void transformMethod(MethodNode mn) {
    AbstractInsnNode node = mn.instructions.getFirst();
    while (node != mn.instructions.getLast()) {
        AbstractInsnNode next = node.getNext();
        if (node instanceof InsnNode) {
            InsnNode in = (InsnNode) node;
            if (in.getOpcode() == Opcodes.LCMP) {
                insertLongComparison(in, mn.instructions);
                TransformationStatistics.transformedComparison();
            } else if (in.getOpcode() == Opcodes.DCMPG) {
                TransformationStatistics.transformedComparison();
                insertDoubleComparisonG(in, mn.instructions);
            } else if (in.getOpcode() == Opcodes.DCMPL) {
                TransformationStatistics.transformedComparison();
                insertDoubleComparisonL(in, mn.instructions);
            } else if (in.getOpcode() == Opcodes.FCMPG) {
                TransformationStatistics.transformedComparison();
                insertFloatComparisonG(in, mn.instructions);
            } else if (in.getOpcode() == Opcodes.FCMPL) {
                TransformationStatistics.transformedComparison();
                insertFloatComparisonL(in, mn.instructions);
            }
        }
        node = next;
    }
}

From source file:org.evosuite.testcase.execution.ExecutionTraceImpl.java

License:Open Source License

/**
 * {@inheritDoc}/* ww w .  j  av a 2s. c o m*/
 * 
 * Add branch to currently active method call
 */
@Override
public void branchPassed(int branch, int bytecode_id, double true_distance, double false_distance) {

    assert (true_distance >= 0.0);
    assert (false_distance >= 0.0);
    updateTopStackMethodCall(branch, bytecode_id, true_distance, false_distance);

    // TODO: property should really be called TRACK_GRADIENT_BRANCHES!
    if (Properties.TRACK_BOOLEAN_BRANCHES) {
        if ((true_distance != 0 && true_distance != 1) || (false_distance != 0 && false_distance != 1))
            gradientBranches.add(branch);
    }

    if (traceCoverage) {
        if (!coveredPredicates.containsKey(branch))
            coveredPredicates.put(branch, 1);
        else
            coveredPredicates.put(branch, coveredPredicates.get(branch) + 1);

        if (true_distance == 0.0) {
            if (!coveredTrue.containsKey(branch))
                coveredTrue.put(branch, 1);
            else
                coveredTrue.put(branch, coveredTrue.get(branch) + 1);

        }

        if (false_distance == 0.0) {
            if (!coveredFalse.containsKey(branch))
                coveredFalse.put(branch, 1);
            else
                coveredFalse.put(branch, coveredFalse.get(branch) + 1);
        }
    }

    if (Properties.TRACK_COVERED_GRADIENT_BRANCHES) {
        if (gradientBranches.contains(branch)) {
            if ((coveredTrue.containsKey(branch)))
                gradientBranchesCoveredTrue.add(branch);
            if ((coveredFalse.containsKey(branch)))
                gradientBranchesCoveredFalse.add(branch);
        }
    }

    if (Properties.BRANCH_COMPARISON_TYPES) {
        int opcode = BranchPool.getInstance(TestGenerationContext.getInstance().getClassLoaderForSUT())
                .getBranch(branch).getInstruction().getASMNode().getOpcode();
        int previousOpcode = -2;
        if (BranchPool.getInstance(TestGenerationContext.getInstance().getClassLoaderForSUT()).getBranch(branch)
                .getInstruction().getASMNode().getPrevious() != null)
            previousOpcode = BranchPool.getInstance(TestGenerationContext.getInstance().getClassLoaderForSUT())
                    .getBranch(branch).getInstruction().getASMNode().getPrevious().getOpcode();
        boolean cTrue = coveredTrue.containsKey(branch);
        boolean cFalse = coveredFalse.containsKey(branch);
        switch (previousOpcode) {
        case Opcodes.LCMP:
            trackBranchOpcode(bytecodeInstructionReached, RuntimeVariable.Reached_lcmp, branch);
            if (cTrue)
                trackBranchOpcode(bytecodeInstructionCoveredTrue, RuntimeVariable.Covered_lcmp, branch);
            if (cFalse)
                trackBranchOpcode(bytecodeInstructionCoveredFalse, RuntimeVariable.Covered_lcmp, branch);
            break;
        case Opcodes.FCMPL:
            trackBranchOpcode(bytecodeInstructionReached, RuntimeVariable.Reached_fcmpl, branch);
            if (cTrue)
                trackBranchOpcode(bytecodeInstructionCoveredTrue, RuntimeVariable.Covered_fcmpl, branch);
            if (cFalse)
                trackBranchOpcode(bytecodeInstructionCoveredFalse, RuntimeVariable.Covered_fcmpl, branch);
            break;
        case Opcodes.FCMPG:
            trackBranchOpcode(bytecodeInstructionReached, RuntimeVariable.Reached_fcmpg, branch);
            if (cTrue)
                trackBranchOpcode(bytecodeInstructionCoveredTrue, RuntimeVariable.Covered_fcmpg, branch);
            if (cFalse)
                trackBranchOpcode(bytecodeInstructionCoveredFalse, RuntimeVariable.Covered_fcmpg, branch);
            break;
        case Opcodes.DCMPL:
            trackBranchOpcode(bytecodeInstructionReached, RuntimeVariable.Reached_dcmpl, branch);
            if (cTrue)
                trackBranchOpcode(bytecodeInstructionCoveredTrue, RuntimeVariable.Covered_dcmpl, branch);
            if (cFalse)
                trackBranchOpcode(bytecodeInstructionCoveredFalse, RuntimeVariable.Covered_dcmpl, branch);
            break;
        case Opcodes.DCMPG:
            trackBranchOpcode(bytecodeInstructionReached, RuntimeVariable.Reached_dcmpg, branch);
            if (cTrue)
                trackBranchOpcode(bytecodeInstructionCoveredTrue, RuntimeVariable.Covered_dcmpg, branch);
            if (cFalse)
                trackBranchOpcode(bytecodeInstructionCoveredFalse, RuntimeVariable.Covered_dcmpg, branch);
            break;
        }
        switch (opcode) {
        // copmpare int with zero
        case Opcodes.IFEQ:
        case Opcodes.IFNE:
        case Opcodes.IFLT:
        case Opcodes.IFGE:
        case Opcodes.IFGT:
        case Opcodes.IFLE:
            trackBranchOpcode(bytecodeInstructionReached, RuntimeVariable.Reached_IntZero, branch);
            if (cTrue)
                trackBranchOpcode(bytecodeInstructionCoveredTrue, RuntimeVariable.Covered_IntZero, branch);
            if (cFalse)
                trackBranchOpcode(bytecodeInstructionCoveredFalse, RuntimeVariable.Covered_IntZero, branch);
            break;
        // copmpare int with int
        case Opcodes.IF_ICMPEQ:
        case Opcodes.IF_ICMPNE:
        case Opcodes.IF_ICMPLT:
        case Opcodes.IF_ICMPGE:
        case Opcodes.IF_ICMPGT:
        case Opcodes.IF_ICMPLE:
            trackBranchOpcode(bytecodeInstructionReached, RuntimeVariable.Reached_IntInt, branch);
            if (cTrue)
                trackBranchOpcode(bytecodeInstructionCoveredTrue, RuntimeVariable.Covered_IntInt, branch);
            if (cFalse)
                trackBranchOpcode(bytecodeInstructionCoveredFalse, RuntimeVariable.Covered_IntInt, branch);
            break;
        // copmpare reference with reference
        case Opcodes.IF_ACMPEQ:
        case Opcodes.IF_ACMPNE:
            trackBranchOpcode(bytecodeInstructionReached, RuntimeVariable.Reached_RefRef, branch);
            if (cTrue)
                trackBranchOpcode(bytecodeInstructionCoveredTrue, RuntimeVariable.Covered_RefRef, branch);
            if (cFalse)
                trackBranchOpcode(bytecodeInstructionCoveredFalse, RuntimeVariable.Covered_RefRef, branch);
            break;
        // compare reference with null
        case Opcodes.IFNULL:
        case Opcodes.IFNONNULL:
            trackBranchOpcode(bytecodeInstructionReached, RuntimeVariable.Reached_RefNull, branch);
            if (cTrue)
                trackBranchOpcode(bytecodeInstructionCoveredTrue, RuntimeVariable.Covered_RefNull, branch);
            if (cFalse)
                trackBranchOpcode(bytecodeInstructionCoveredFalse, RuntimeVariable.Covered_RefNull, branch);
            break;

        }
    }

    if (!trueDistances.containsKey(branch))
        trueDistances.put(branch, true_distance);
    else
        trueDistances.put(branch, Math.min(trueDistances.get(branch), true_distance));

    if (!falseDistances.containsKey(branch))
        falseDistances.put(branch, false_distance);
    else
        falseDistances.put(branch, Math.min(falseDistances.get(branch), false_distance));

    if (!trueDistancesSum.containsKey(branch))
        trueDistancesSum.put(branch, true_distance);
    else
        trueDistancesSum.put(branch, trueDistancesSum.get(branch) + true_distance);

    if (!falseDistancesSum.containsKey(branch))
        falseDistancesSum.put(branch, false_distance);
    else
        falseDistancesSum.put(branch, falseDistancesSum.get(branch) + false_distance);

    if (!disableContext && (Properties.INSTRUMENT_CONTEXT || Properties.INSTRUMENT_METHOD_CALLS
            || ArrayUtil.contains(Properties.CRITERION, Criterion.IBRANCH)
            || ArrayUtil.contains(Properties.CRITERION, Criterion.CBRANCH))) {
        updateBranchContextMaps(branch, true_distance, false_distance);
    }

    // This requires a lot of memory and should not really be used
    if (Properties.BRANCH_EVAL) {
        branchesTrace.add(new BranchEval(branch, true_distance, false_distance));
    }
}

From source file:org.evosuite.TestSuiteGenerator.java

License:Open Source License

private void getBytecodeStatistics() {
    if (Properties.TRACK_BOOLEAN_BRANCHES) {
        int gradientBranchCount = ExecutionTraceImpl.gradientBranches.size() * 2;
        ClientServices.getInstance().getClientNode().trackOutputVariable(RuntimeVariable.Gradient_Branches,
                gradientBranchCount);//from   w w  w.  java2 s  . c o m
    }
    if (Properties.TRACK_COVERED_GRADIENT_BRANCHES) {
        int coveredGradientBranchCount = ExecutionTraceImpl.gradientBranchesCoveredTrue.size()
                + ExecutionTraceImpl.gradientBranchesCoveredFalse.size();
        ClientServices.getInstance().getClientNode()
                .trackOutputVariable(RuntimeVariable.Gradient_Branches_Covered, coveredGradientBranchCount);
    }
    if (Properties.BRANCH_COMPARISON_TYPES) {
        int cmp_intzero = 0, cmp_intint = 0, cmp_refref = 0, cmp_refnull = 0;
        int bc_lcmp = 0, bc_fcmpl = 0, bc_fcmpg = 0, bc_dcmpl = 0, bc_dcmpg = 0;
        for (Branch b : BranchPool.getInstance(TestGenerationContext.getInstance().getClassLoaderForSUT())
                .getAllBranches()) {
            int branchOpCode = b.getInstruction().getASMNode().getOpcode();
            int previousOpcode = -2;
            if (b.getInstruction().getASMNode().getPrevious() != null)
                previousOpcode = b.getInstruction().getASMNode().getPrevious().getOpcode();
            switch (previousOpcode) {
            case Opcodes.LCMP:
                bc_lcmp++;
                break;
            case Opcodes.FCMPL:
                bc_fcmpl++;
                break;
            case Opcodes.FCMPG:
                bc_fcmpg++;
                break;
            case Opcodes.DCMPL:
                bc_dcmpl++;
                break;
            case Opcodes.DCMPG:
                bc_dcmpg++;
                break;
            }
            switch (branchOpCode) {
            // copmpare int with zero
            case Opcodes.IFEQ:
            case Opcodes.IFNE:
            case Opcodes.IFLT:
            case Opcodes.IFGE:
            case Opcodes.IFGT:
            case Opcodes.IFLE:
                cmp_intzero++;
                break;
            // copmpare int with int
            case Opcodes.IF_ICMPEQ:
            case Opcodes.IF_ICMPNE:
            case Opcodes.IF_ICMPLT:
            case Opcodes.IF_ICMPGE:
            case Opcodes.IF_ICMPGT:
            case Opcodes.IF_ICMPLE:
                cmp_intint++;
                break;
            // copmpare reference with reference
            case Opcodes.IF_ACMPEQ:
            case Opcodes.IF_ACMPNE:
                cmp_refref++;
                break;
            // compare reference with null
            case Opcodes.IFNULL:
            case Opcodes.IFNONNULL:
                cmp_refnull++;
                break;

            }
        }
        ClientServices.getInstance().getClientNode().trackOutputVariable(RuntimeVariable.Cmp_IntZero,
                cmp_intzero);
        ClientServices.getInstance().getClientNode().trackOutputVariable(RuntimeVariable.Cmp_IntInt,
                cmp_intint);
        ClientServices.getInstance().getClientNode().trackOutputVariable(RuntimeVariable.Cmp_RefRef,
                cmp_refref);
        ClientServices.getInstance().getClientNode().trackOutputVariable(RuntimeVariable.Cmp_RefNull,
                cmp_refnull);

        ClientServices.getInstance().getClientNode().trackOutputVariable(RuntimeVariable.BC_lcmp, bc_lcmp);
        ClientServices.getInstance().getClientNode().trackOutputVariable(RuntimeVariable.BC_fcmpl, bc_fcmpl);
        ClientServices.getInstance().getClientNode().trackOutputVariable(RuntimeVariable.BC_fcmpg, bc_fcmpg);
        ClientServices.getInstance().getClientNode().trackOutputVariable(RuntimeVariable.BC_dcmpl, bc_dcmpl);
        ClientServices.getInstance().getClientNode().trackOutputVariable(RuntimeVariable.BC_dcmpg, bc_dcmpg);

        RuntimeVariable[] bytecodeVarsCovered = new RuntimeVariable[] { RuntimeVariable.Covered_lcmp,
                RuntimeVariable.Covered_fcmpl, RuntimeVariable.Covered_fcmpg, RuntimeVariable.Covered_dcmpl,
                RuntimeVariable.Covered_dcmpg, RuntimeVariable.Covered_IntInt, RuntimeVariable.Covered_IntInt,
                RuntimeVariable.Covered_IntZero, RuntimeVariable.Covered_RefRef,
                RuntimeVariable.Covered_RefNull };

        for (RuntimeVariable bcvar : bytecodeVarsCovered) {
            ClientServices.getInstance().getClientNode().trackOutputVariable(bcvar,
                    getBytecodeCount(bcvar, ExecutionTraceImpl.bytecodeInstructionCoveredFalse)
                            + getBytecodeCount(bcvar, ExecutionTraceImpl.bytecodeInstructionCoveredTrue));
        }

        RuntimeVariable[] bytecodeVarsReached = new RuntimeVariable[] { RuntimeVariable.Reached_lcmp,
                RuntimeVariable.Reached_fcmpl, RuntimeVariable.Reached_fcmpg, RuntimeVariable.Reached_dcmpl,
                RuntimeVariable.Reached_dcmpg, RuntimeVariable.Reached_IntInt, RuntimeVariable.Reached_IntInt,
                RuntimeVariable.Reached_IntZero, RuntimeVariable.Reached_RefRef,
                RuntimeVariable.Reached_RefNull };

        for (RuntimeVariable bcvar : bytecodeVarsReached) {
            ClientServices.getInstance().getClientNode().trackOutputVariable(bcvar,
                    getBytecodeCount(bcvar, ExecutionTraceImpl.bytecodeInstructionReached) * 2);
        }

    }

}

From source file:org.evosuite.TestSuiteGeneratorHelper.java

License:Open Source License

static void getBytecodeStatistics() {
    if (Properties.TRACK_BOOLEAN_BRANCHES) {
        int gradientBranchCount = ExecutionTraceImpl.gradientBranches.size() * 2;
        ClientServices.track(RuntimeVariable.Gradient_Branches, gradientBranchCount);
    }// www  .jav a 2 s .com
    if (Properties.TRACK_COVERED_GRADIENT_BRANCHES) {
        int coveredGradientBranchCount = ExecutionTraceImpl.gradientBranchesCoveredTrue.size()
                + ExecutionTraceImpl.gradientBranchesCoveredFalse.size();
        ClientServices.track(RuntimeVariable.Gradient_Branches_Covered, coveredGradientBranchCount);
    }
    if (Properties.BRANCH_COMPARISON_TYPES) {
        int cmp_intzero = 0, cmp_intint = 0, cmp_refref = 0, cmp_refnull = 0;
        int bc_lcmp = 0, bc_fcmpl = 0, bc_fcmpg = 0, bc_dcmpl = 0, bc_dcmpg = 0;
        for (Branch b : BranchPool.getInstance(TestGenerationContext.getInstance().getClassLoaderForSUT())
                .getAllBranches()) {
            int branchOpCode = b.getInstruction().getASMNode().getOpcode();
            int previousOpcode = -2;
            if (b.getInstruction().getASMNode().getPrevious() != null) {
                previousOpcode = b.getInstruction().getASMNode().getPrevious().getOpcode();
            }
            switch (previousOpcode) {
            case Opcodes.LCMP:
                bc_lcmp++;
                break;
            case Opcodes.FCMPL:
                bc_fcmpl++;
                break;
            case Opcodes.FCMPG:
                bc_fcmpg++;
                break;
            case Opcodes.DCMPL:
                bc_dcmpl++;
                break;
            case Opcodes.DCMPG:
                bc_dcmpg++;
                break;
            }
            switch (branchOpCode) {
            // copmpare int with zero
            case Opcodes.IFEQ:
            case Opcodes.IFNE:
            case Opcodes.IFLT:
            case Opcodes.IFGE:
            case Opcodes.IFGT:
            case Opcodes.IFLE:
                cmp_intzero++;
                break;
            // copmpare int with int
            case Opcodes.IF_ICMPEQ:
            case Opcodes.IF_ICMPNE:
            case Opcodes.IF_ICMPLT:
            case Opcodes.IF_ICMPGE:
            case Opcodes.IF_ICMPGT:
            case Opcodes.IF_ICMPLE:
                cmp_intint++;
                break;
            // copmpare reference with reference
            case Opcodes.IF_ACMPEQ:
            case Opcodes.IF_ACMPNE:
                cmp_refref++;
                break;
            // compare reference with null
            case Opcodes.IFNULL:
            case Opcodes.IFNONNULL:
                cmp_refnull++;
                break;

            }
        }
        ClientServices.track(RuntimeVariable.Cmp_IntZero, cmp_intzero);
        ClientServices.track(RuntimeVariable.Cmp_IntInt, cmp_intint);
        ClientServices.track(RuntimeVariable.Cmp_RefRef, cmp_refref);
        ClientServices.track(RuntimeVariable.Cmp_RefNull, cmp_refnull);

        ClientServices.track(RuntimeVariable.BC_lcmp, bc_lcmp);
        ClientServices.track(RuntimeVariable.BC_fcmpl, bc_fcmpl);
        ClientServices.track(RuntimeVariable.BC_fcmpg, bc_fcmpg);
        ClientServices.track(RuntimeVariable.BC_dcmpl, bc_dcmpl);
        ClientServices.track(RuntimeVariable.BC_dcmpg, bc_dcmpg);

        RuntimeVariable[] bytecodeVarsCovered = new RuntimeVariable[] { RuntimeVariable.Covered_lcmp,
                RuntimeVariable.Covered_fcmpl, RuntimeVariable.Covered_fcmpg, RuntimeVariable.Covered_dcmpl,
                RuntimeVariable.Covered_dcmpg, RuntimeVariable.Covered_IntInt, RuntimeVariable.Covered_IntInt,
                RuntimeVariable.Covered_IntZero, RuntimeVariable.Covered_RefRef,
                RuntimeVariable.Covered_RefNull };

        for (RuntimeVariable bcvar : bytecodeVarsCovered) {
            ClientServices.track(bcvar,
                    getBytecodeCount(bcvar, ExecutionTraceImpl.bytecodeInstructionCoveredFalse)
                            + getBytecodeCount(bcvar, ExecutionTraceImpl.bytecodeInstructionCoveredTrue));
        }

        RuntimeVariable[] bytecodeVarsReached = new RuntimeVariable[] { RuntimeVariable.Reached_lcmp,
                RuntimeVariable.Reached_fcmpl, RuntimeVariable.Reached_fcmpg, RuntimeVariable.Reached_dcmpl,
                RuntimeVariable.Reached_dcmpg, RuntimeVariable.Reached_IntInt, RuntimeVariable.Reached_IntInt,
                RuntimeVariable.Reached_IntZero, RuntimeVariable.Reached_RefRef,
                RuntimeVariable.Reached_RefNull };

        for (RuntimeVariable bcvar : bytecodeVarsReached) {
            ClientServices.track(bcvar,
                    getBytecodeCount(bcvar, ExecutionTraceImpl.bytecodeInstructionReached) * 2);
        }

    }

}

From source file:org.jacoco.core.internal.instr.FrameTracker.java

License:Open Source License

@Override
public void visitInsn(final int opcode) {
    final Object t1, t2, t3, t4;
    switch (opcode) {
    case Opcodes.NOP:
    case Opcodes.RETURN:
        break;//from w w  w . j  av a2  s .com
    case Opcodes.ARETURN:
    case Opcodes.ATHROW:
    case Opcodes.FRETURN:
    case Opcodes.IRETURN:
    case Opcodes.MONITORENTER:
    case Opcodes.MONITOREXIT:
    case Opcodes.POP:
        pop(1);
        break;
    case Opcodes.DRETURN:
    case Opcodes.LRETURN:
    case Opcodes.POP2:
        pop(2);
        break;
    case Opcodes.AASTORE:
    case Opcodes.BASTORE:
    case Opcodes.CASTORE:
    case Opcodes.FASTORE:
    case Opcodes.IASTORE:
    case Opcodes.SASTORE:
        pop(3);
        break;
    case Opcodes.LASTORE:
    case Opcodes.DASTORE:
        pop(4);
        break;
    case Opcodes.ICONST_M1:
    case Opcodes.ICONST_0:
    case Opcodes.ICONST_1:
    case Opcodes.ICONST_2:
    case Opcodes.ICONST_3:
    case Opcodes.ICONST_4:
    case Opcodes.ICONST_5:
        push(Opcodes.INTEGER);
        break;
    case Opcodes.ARRAYLENGTH:
    case Opcodes.F2I:
    case Opcodes.I2B:
    case Opcodes.I2C:
    case Opcodes.I2S:
    case Opcodes.INEG:
        pop(1);
        push(Opcodes.INTEGER);
        break;
    case Opcodes.BALOAD:
    case Opcodes.CALOAD:
    case Opcodes.D2I:
    case Opcodes.FCMPG:
    case Opcodes.FCMPL:
    case Opcodes.IADD:
    case Opcodes.IALOAD:
    case Opcodes.IAND:
    case Opcodes.IDIV:
    case Opcodes.IMUL:
    case Opcodes.IOR:
    case Opcodes.IREM:
    case Opcodes.ISHL:
    case Opcodes.ISHR:
    case Opcodes.ISUB:
    case Opcodes.IUSHR:
    case Opcodes.IXOR:
    case Opcodes.L2I:
    case Opcodes.SALOAD:
        pop(2);
        push(Opcodes.INTEGER);
        break;
    case Opcodes.DCMPG:
    case Opcodes.DCMPL:
    case Opcodes.LCMP:
        pop(4);
        push(Opcodes.INTEGER);
        break;
    case Opcodes.FCONST_0:
    case Opcodes.FCONST_1:
    case Opcodes.FCONST_2:
        push(Opcodes.FLOAT);
        break;
    case Opcodes.FNEG:
    case Opcodes.I2F:
        pop(1);
        push(Opcodes.FLOAT);
        break;
    case Opcodes.D2F:
    case Opcodes.FADD:
    case Opcodes.FALOAD:
    case Opcodes.FDIV:
    case Opcodes.FMUL:
    case Opcodes.FREM:
    case Opcodes.FSUB:
    case Opcodes.L2F:
        pop(2);
        push(Opcodes.FLOAT);
        break;
    case Opcodes.LCONST_0:
    case Opcodes.LCONST_1:
        push(Opcodes.LONG);
        push(Opcodes.TOP);
        break;
    case Opcodes.F2L:
    case Opcodes.I2L:
        pop(1);
        push(Opcodes.LONG);
        push(Opcodes.TOP);
        break;
    case Opcodes.D2L:
    case Opcodes.LALOAD:
    case Opcodes.LNEG:
        pop(2);
        push(Opcodes.LONG);
        push(Opcodes.TOP);
        break;
    case Opcodes.LSHL:
    case Opcodes.LSHR:
    case Opcodes.LUSHR:
        pop(3);
        push(Opcodes.LONG);
        push(Opcodes.TOP);
        break;
    case Opcodes.LADD:
    case Opcodes.LAND:
    case Opcodes.LDIV:
    case Opcodes.LMUL:
    case Opcodes.LOR:
    case Opcodes.LREM:
    case Opcodes.LSUB:
    case Opcodes.LXOR:
        pop(4);
        push(Opcodes.LONG);
        push(Opcodes.TOP);
        break;
    case Opcodes.DCONST_0:
    case Opcodes.DCONST_1:
        push(Opcodes.DOUBLE);
        push(Opcodes.TOP);
        break;
    case Opcodes.F2D:
    case Opcodes.I2D:
        pop(1);
        push(Opcodes.DOUBLE);
        push(Opcodes.TOP);
        break;
    case Opcodes.DALOAD:
    case Opcodes.DNEG:
    case Opcodes.L2D:
        pop(2);
        push(Opcodes.DOUBLE);
        push(Opcodes.TOP);
        break;
    case Opcodes.DADD:
    case Opcodes.DDIV:
    case Opcodes.DMUL:
    case Opcodes.DREM:
    case Opcodes.DSUB:
        pop(4);
        push(Opcodes.DOUBLE);
        push(Opcodes.TOP);
        break;
    case Opcodes.ACONST_NULL:
        push(Opcodes.NULL);
        break;
    case Opcodes.AALOAD:
        pop(1);
        t1 = pop();
        push(Type.getType(((String) t1).substring(1)));
        break;
    case Opcodes.DUP:
        t1 = pop();
        push(t1);
        push(t1);
        break;
    case Opcodes.DUP_X1:
        t1 = pop();
        t2 = pop();
        push(t1);
        push(t2);
        push(t1);
        break;
    case Opcodes.DUP_X2:
        t1 = pop();
        t2 = pop();
        t3 = pop();
        push(t1);
        push(t3);
        push(t2);
        push(t1);
        break;
    case Opcodes.DUP2:
        t1 = pop();
        t2 = pop();
        push(t2);
        push(t1);
        push(t2);
        push(t1);
        break;
    case Opcodes.DUP2_X1:
        t1 = pop();
        t2 = pop();
        t3 = pop();
        push(t2);
        push(t1);
        push(t3);
        push(t2);
        push(t1);
        break;
    case Opcodes.DUP2_X2:
        t1 = pop();
        t2 = pop();
        t3 = pop();
        t4 = pop();
        push(t2);
        push(t1);
        push(t4);
        push(t3);
        push(t2);
        push(t1);
        break;
    case Opcodes.SWAP:
        t1 = pop();
        t2 = pop();
        push(t1);
        push(t2);
        break;
    default:
        throw new IllegalArgumentException();
    }
    mv.visitInsn(opcode);
}

From source file:org.lambdamatic.analyzer.ast.LambdaExpressionReader.java

License:Open Source License

/**
 * Reads the current {@link InsnNode} instruction and returns a {@link Statement} or {@code null}
 * if the instruction is not a full statement (in that case, the instruction is stored in the
 * given Expression {@link Stack})./*from  w  ww .  j av  a 2 s . c o  m*/
 * 
 * @param insnNode the instruction to read
 * @param expressionStack the expression stack to put on or pop from.
 * @param localVariables the local variables
 * @return a {@link List} of {@link Statement} or empty list if no {@link Statement} was created
 *         after reading the current instruction.
 * @see <a href="https://en.wikipedia.org/wiki/Java_bytecode_instruction_listings">Java bytcode
 *      instruction listings on Wikipedia</a>
 */
private List<Statement> readInstruction(final InsnCursor insnCursor, final Stack<Expression> expressionStack,
        final List<CapturedArgument> capturedArguments, final LocalVariables localVariables) {
    final List<Statement> statements = new ArrayList<>();
    final AbstractInsnNode insnNode = insnCursor.getCurrent();
    switch (insnNode.getOpcode()) {
    // return a reference from a method
    case Opcodes.ARETURN:
        // return an integer from a method
    case Opcodes.IRETURN:
        statements.add(new ReturnStatement(expressionStack.pop()));
        break;
    // return void from method
    case Opcodes.RETURN:
        // wrap all pending expressions into ExpressionStatements
        while (!expressionStack.isEmpty()) {
            final Expression pendingExpression = expressionStack.pop();
            statements.add(new ExpressionStatement(pendingExpression));
        }
        break;
    // push a null reference onto the stack
    case Opcodes.ACONST_NULL:
        expressionStack.add(new NullLiteral());
        break;
    // load the int value 0 onto the stack
    case Opcodes.ICONST_0:
        // applies for byte, short, int and boolean
        expressionStack.add(new NumberLiteral(0));
        break;
    // load the int value 1 onto the stack
    case Opcodes.ICONST_1:
        // applies for byte, short, int and boolean
        expressionStack.add(new NumberLiteral(1));
        break;
    // load the int value 2 onto the stack
    case Opcodes.ICONST_2:
        expressionStack.add(new NumberLiteral(2));
        break;
    // load the int value 3 onto the stack
    case Opcodes.ICONST_3:
        expressionStack.add(new NumberLiteral(3));
        break;
    // load the int value 4 onto the stack
    case Opcodes.ICONST_4:
        expressionStack.add(new NumberLiteral(4));
        break;
    // load the int value 5 onto the stack
    case Opcodes.ICONST_5:
        expressionStack.add(new NumberLiteral(5));
        break;
    // push the long 0 onto the stack
    case Opcodes.LCONST_0:
        expressionStack.add(new NumberLiteral(0L));
        break;
    // push the long 1 onto the stack
    case Opcodes.LCONST_1:
        expressionStack.add(new NumberLiteral(1L));
        break;
    // push the 0.0f onto the stack
    case Opcodes.FCONST_0:
        expressionStack.add(new NumberLiteral(0f));
        break;
    // push the 1.0f onto the stack
    case Opcodes.FCONST_1:
        expressionStack.add(new NumberLiteral(1f));
        break;
    // push the 2.0f onto the stack
    case Opcodes.FCONST_2:
        expressionStack.add(new NumberLiteral(2f));
        break;
    // push the constant 0.0 onto the stack
    case Opcodes.DCONST_0:
        expressionStack.add(new NumberLiteral(0d));
        break;
    // push the constant 1.0 onto the stack
    case Opcodes.DCONST_1:
        expressionStack.add(new NumberLiteral(1d));
        break;
    // compare two longs values
    case Opcodes.LCMP:
        // compare two doubles
    case Opcodes.DCMPL:
        // compare two doubles
    case Opcodes.DCMPG:
        // compare two floats
    case Opcodes.FCMPL:
        // compare two floats
    case Opcodes.FCMPG:
        statements.addAll(
                readJumpInstruction(insnCursor.next(), expressionStack, capturedArguments, localVariables));
        break;
    // add 2 ints
    case Opcodes.IADD:
        expressionStack.add(readOperation(Operator.ADD, expressionStack));
        break;
    // int subtract
    case Opcodes.ISUB:
        expressionStack.add(readOperation(Operator.SUBTRACT, expressionStack));
        break;
    // multiply 2 integers
    case Opcodes.IMUL:
        expressionStack.add(readOperation(Operator.MULTIPLY, expressionStack));
        break;
    // divide 2 integers
    case Opcodes.IDIV:
        expressionStack.add(readOperation(Operator.DIVIDE, expressionStack));
        break;
    // negate int
    case Opcodes.INEG:
        expressionStack.add(inverseInteger(expressionStack));
        break;
    // discard the top value on the stack
    case Opcodes.POP:
        statements.add(new ExpressionStatement(expressionStack.pop()));
        break;
    // duplicate the value on top of the stack
    case Opcodes.DUP:
        expressionStack.push(expressionStack.peek());
        break;
    // insert a copy of the top value into the stack two values from the top.
    case Opcodes.DUP_X1:
        expressionStack.add(expressionStack.size() - 2, expressionStack.peek());
        break;
    // store into a reference in an array
    case Opcodes.AASTORE:
        readArrayStoreInstruction(insnNode, expressionStack);
        break;
    // converts Float to Double -> ignored.
    case Opcodes.F2D:
        break;
    default:
        throw new AnalyzeException(
                "Bytecode instruction with OpCode '" + insnNode.getOpcode() + "' is not supported.");
    }
    return statements;
}

From source file:org.openquark.cal.internal.javamodel.AsmJavaBytecodeGenerator.java

License:Open Source License

/**  
 * Boolean valued operators (!, &&, ||, ==, !=, <, <=, > and >=) are highly optimized during compilation to bytecode.
 * Here is a quick outline of the optimizations used:
 * -not (e1 && e2) is compiled as a single notAnd operator
 * -not (e1 || e2) is compiled as a single notOr operator
 * -not (not e) is optimized out./*from w w  w .jav a2s .c o  m*/
 * -not (x < y) is compiled as x >= y for integral comparisons. A similar thing is done for not (double <), but it is not quite double >= because
 *  of NaN. However, there is special java bytecode support for treatment of this.
 * -Comparisons where the right-hand-side is an int 0 are treated more efficiently i.e. x > 0.
 * -Comparisons to null are treated specially i.e. x != null, x == null.  
 * -if the result of a boolean valued operator is used by the condition part of an if-then-else statement (or ternary operator) then
 *  the resulting true or false value is not pushed onto the stack and then tested. Rather we directly branch to the appropriate
 *  continuation.
 * -the most complicated optimization is that "trees" of boolean valued operators are effectively compiled as a single operator. 
 *  What this means is that the resulting "true" and "false" values are not popped onto the stack and consumed by subsequent operators
 *  but rather a "continuation style" is employed where we just jump to the correct next comparison.
 *  This saves an extra comparison per operator, as well as unecessary pushes of trues and falses compared to the naive compilation scheme. 
 *  The precise bytecode instructions used in the compilation schemes varies depending on context (see the endsWithTrueForm argument).
 * 
 * @param operatorExpr
 * @param context
 * @param trueContinuation label to jump to if the expression has a true value
 * @param falseContinuation label to jump to if the expression has a false value 
 * @param endsWithTrueForm operators are encoded as a series of tests with jumps where if none of the jumps are taken the operator slips
 *    through to the default case. This is usually "true" but if the "endsWithTrueForm" flag is set to false, then the default case will
 *    be false. For example, this is useful when encoding a boolean-valued operator that is the left argument of the || operator. 
 *    In that case we want the default case to proceed to evaluation of the second argument of ||.
 * @throws JavaGenerationException
 */
private static void encodeBooleanValuedOperatorHelper(JavaExpression.OperatorExpression operatorExpr,
        GenerationContext context, Label trueContinuation, Label falseContinuation, boolean endsWithTrueForm)
        throws JavaGenerationException {

    MethodVisitor mv = context.getMethodVisitor();

    JavaOperator operator = operatorExpr.getJavaOperator();
    String symbol = operator.getSymbol();
    JavaTypeName valueType = operator.getValueType();

    if (operator.isLogicalOp()) {

        // Logical op:    {"!", "&&", "||"}
        // Note: conditional statements should not be handled here..
        //   eg. "if" conditional evaluation happens during "if" source generation.
        //   We can get here if, eg. printing the result of a conditional.            

        // boolean negation
        if (symbol.equals("!")) {

            JavaExpression arg0Expr = operatorExpr.getArgument(0);

            //attempt to optimize a variety of cases where not is composed with another boolean valued operator.

            if (arg0Expr instanceof JavaExpression.OperatorExpression) {

                if (arg0Expr instanceof JavaExpression.OperatorExpression.Binary) {

                    JavaExpression.OperatorExpression.Binary arg0BinaryOperatorExpr = (JavaExpression.OperatorExpression.Binary) arg0Expr;
                    JavaOperator arg0BinaryOperator = arg0BinaryOperatorExpr.getJavaOperator();

                    //not (expr1 && expr2) is encoded in a special way. Effectively there is a notAnd operator.

                    if (arg0BinaryOperator == JavaOperator.CONDITIONAL_AND) {

                        //x notAnd y                    
                        //is encoded as                    
                        //if x == false then goto trueContinuation
                        //if y == true then goto falseContinuation

                        ////what follows is a sample continuation in the case when a literal value is pushed onto the stack
                        //label trueContinuation:
                        //push true
                        //goto next
                        //label falseContinuation:
                        //push false
                        //next: 

                        JavaExpression andOpArg0Expr = arg0BinaryOperatorExpr.getArgument(0);
                        if (isBooleanValuedOperatorExpr(andOpArg0Expr)) {
                            Label innerTrueContinuation = new Label();
                            encodeBooleanValuedOperatorHelper((JavaExpression.OperatorExpression) andOpArg0Expr,
                                    context, innerTrueContinuation, trueContinuation);
                            mv.visitLabel(innerTrueContinuation);
                        } else {
                            encodeExpr(andOpArg0Expr, context);
                            mv.visitJumpInsn(Opcodes.IFEQ, trueContinuation);
                        }

                        JavaExpression andOpArg1Expr = arg0BinaryOperatorExpr.getArgument(1);
                        if (isBooleanValuedOperatorExpr(andOpArg1Expr)) {
                            encodeBooleanValuedOperatorHelper((JavaExpression.OperatorExpression) andOpArg1Expr,
                                    context, falseContinuation, trueContinuation, !endsWithTrueForm);
                        } else {
                            encodeExpr(andOpArg1Expr, context);
                            if (endsWithTrueForm) {
                                mv.visitJumpInsn(Opcodes.IFNE, falseContinuation);
                            } else {
                                mv.visitJumpInsn(Opcodes.IFEQ, trueContinuation);
                            }
                        }

                        return;
                    }

                    //not (expr1 || expr2) is encoded in a special way. Effectively there is a notOr operator.

                    if (arg0BinaryOperator == JavaOperator.CONDITIONAL_OR) {

                        //x notOr y                    
                        //is encoded as                    
                        //if x == true then goto falseContinuation
                        //if y == true then goto falseContinuation

                        ////what follows is a sample continuation in the case when a literal value is pushed onto the stack                           
                        //label trueContinuation:
                        //push true
                        //goto next
                        //label falseContinuation:
                        //push false
                        //next: 

                        JavaExpression orOpArg0Expr = arg0BinaryOperatorExpr.getArgument(0);
                        if (isBooleanValuedOperatorExpr(orOpArg0Expr)) {
                            Label innerFalseContinuation = new Label();
                            //if x evaluates to false, we want to continue with evaluating y, this is why the "endsWithTrueForm" argument is false here.
                            //if x evaluates to false, then x notOr y returns true without needing to evaluate y. That is why the trueContinuation for x, is
                            //the falseContinuation for the call that encodes x.
                            encodeBooleanValuedOperatorHelper((JavaExpression.OperatorExpression) orOpArg0Expr,
                                    context, falseContinuation, innerFalseContinuation, false);
                            mv.visitLabel(innerFalseContinuation);
                        } else {
                            encodeExpr(orOpArg0Expr, context);
                            mv.visitJumpInsn(Opcodes.IFNE, falseContinuation);
                        }

                        JavaExpression orOpArg1Expr = arg0BinaryOperatorExpr.getArgument(1);
                        if (isBooleanValuedOperatorExpr(orOpArg1Expr)) {
                            encodeBooleanValuedOperatorHelper((JavaExpression.OperatorExpression) orOpArg1Expr,
                                    context, falseContinuation, trueContinuation, !endsWithTrueForm);
                        } else {
                            encodeExpr(orOpArg1Expr, context);
                            if (endsWithTrueForm) {
                                mv.visitJumpInsn(Opcodes.IFNE, falseContinuation);
                            } else {
                                mv.visitJumpInsn(Opcodes.IFEQ, trueContinuation);
                            }
                        }

                        return;
                    }

                    //try to optimize not composed with a boolean valued operator as a single operation
                    //for example, for int operators, not (x < y) is actually encoded as x >= y.                        

                    JavaExpression.OperatorExpression.Binary notComposedOperatorExpr = arg0BinaryOperatorExpr
                            .getNotComposedOperatorExpr();
                    if (notComposedOperatorExpr != null) {

                        encodeBooleanValuedOperatorHelper(notComposedOperatorExpr, context, trueContinuation,
                                falseContinuation, endsWithTrueForm);
                        return;
                    }

                    //not (x Double.< y) is encoded like x Double.>= y except that the opposite DCMP instruction is used.                           
                    //this is to handle NAN. Similar for the others.

                    if (arg0BinaryOperator == JavaOperator.LESS_THAN_DOUBLE
                            || arg0BinaryOperator == JavaOperator.LESS_THAN_EQUALS_DOUBLE
                            || arg0BinaryOperator == JavaOperator.GREATER_THAN_DOUBLE
                            || arg0BinaryOperator == JavaOperator.GREATER_THAN_EQUALS_DOUBLE) {

                        //encode the first argument
                        JavaTypeName firstArgType = encodeExpr(arg0BinaryOperatorExpr.getArgument(0), context);

                        // Add instructions to widen the first argument if necessary.
                        int wideningOpCode = getWideningOpCode(firstArgType, JavaTypeName.DOUBLE);
                        if (wideningOpCode != Opcodes.NOP) {
                            mv.visitInsn(wideningOpCode);
                        }

                        //endcode the second argument
                        JavaExpression secondArgExpr = arg0BinaryOperatorExpr.getArgument(1);
                        JavaTypeName secondArgType = encodeExpr(secondArgExpr, context);
                        wideningOpCode = getWideningOpCode(secondArgType, JavaTypeName.DOUBLE);
                        if (wideningOpCode != Opcodes.NOP) {
                            mv.visitInsn(wideningOpCode);
                        }

                        if (arg0BinaryOperator == JavaOperator.LESS_THAN_DOUBLE) {

                            mv.visitInsn(Opcodes.DCMPG);
                            if (endsWithTrueForm) {
                                mv.visitJumpInsn(Opcodes.IFLT, falseContinuation);
                            } else {
                                mv.visitJumpInsn(Opcodes.IFGE, trueContinuation);
                            }

                        } else if (arg0BinaryOperator == JavaOperator.LESS_THAN_EQUALS_DOUBLE) {

                            mv.visitInsn(Opcodes.DCMPG);
                            if (endsWithTrueForm) {
                                mv.visitJumpInsn(Opcodes.IFLE, falseContinuation);
                            } else {
                                mv.visitJumpInsn(Opcodes.IFGT, trueContinuation);
                            }

                        } else if (arg0BinaryOperator == JavaOperator.GREATER_THAN_DOUBLE) {

                            mv.visitInsn(Opcodes.DCMPL);
                            if (endsWithTrueForm) {
                                mv.visitJumpInsn(Opcodes.IFGT, falseContinuation);
                            } else {
                                mv.visitJumpInsn(Opcodes.IFLE, trueContinuation);
                            }

                        } else if (arg0BinaryOperator == JavaOperator.GREATER_THAN_EQUALS_DOUBLE) {

                            mv.visitInsn(Opcodes.DCMPL);
                            if (endsWithTrueForm) {
                                mv.visitJumpInsn(Opcodes.IFGE, falseContinuation);
                            } else {
                                mv.visitJumpInsn(Opcodes.IFLT, trueContinuation);
                            }

                        } else {

                            throw new JavaGenerationException(
                                    "Expecting one of the double operators <, >, <= or >=.");
                        }

                        return;
                    }

                    //fall through to the unoptimized case...

                } else if (arg0Expr instanceof JavaExpression.OperatorExpression.Unary) {

                    //"not (not expr)" is encoded as "id expr"

                    JavaExpression.OperatorExpression.Unary arg0UnaryOperatorExpr = (JavaExpression.OperatorExpression.Unary) arg0Expr;
                    if (arg0UnaryOperatorExpr.getJavaOperator() != JavaOperator.LOGICAL_NEGATE) {
                        throw new JavaGenerationException("Unary logical negation expected.");
                    }

                    JavaExpression expr = arg0UnaryOperatorExpr.getArgument(0);
                    if (isBooleanValuedOperatorExpr(expr)) {
                        encodeBooleanValuedOperatorHelper((JavaExpression.OperatorExpression) expr, context,
                                trueContinuation, falseContinuation, endsWithTrueForm);
                    } else {
                        encodeExpr(expr, context);
                        if (endsWithTrueForm) {
                            mv.visitJumpInsn(Opcodes.IFEQ, falseContinuation);
                        } else {
                            mv.visitJumpInsn(Opcodes.IFNE, trueContinuation);
                        }
                    }

                    return;
                }
            }

            //!x 
            //is encoded as
            //if x == true then goto falseContinuation;

            ////what follows is a sample continuation in the case when a literal value is pushed onto the stack
            //push true;
            //goto next;
            //falseContinuation:
            //push false;
            //label next:                                   

            encodeExpr(arg0Expr, context);
            if (endsWithTrueForm) {
                //Note that IFNE consumes a value on the stack.
                mv.visitJumpInsn(Opcodes.IFNE, falseContinuation);
            } else {
                mv.visitJumpInsn(Opcodes.IFEQ, trueContinuation);
            }

            return;
        }

        if (symbol.equals("&&")) {

            //x && y                    
            //is encoded as                    
            //if x == false then goto falseContinuation
            //if y == false then goto falseContinuation

            ////what follows is a sample continuation in the case when a literal value is pushed onto the stack
            //push true
            //goto next
            //label falseContinuation:
            //push false
            //label next:

            JavaExpression arg0Expr = operatorExpr.getArgument(0);
            if (isBooleanValuedOperatorExpr(arg0Expr)) {
                Label innerTrueContinuation = new Label();
                encodeBooleanValuedOperatorHelper((JavaExpression.OperatorExpression) arg0Expr, context,
                        innerTrueContinuation, falseContinuation);
                mv.visitLabel(innerTrueContinuation);
            } else {
                encodeExpr(arg0Expr, context);
                mv.visitJumpInsn(Opcodes.IFEQ, falseContinuation);
            }

            JavaExpression arg1Expr = operatorExpr.getArgument(1);
            if (isBooleanValuedOperatorExpr(arg1Expr)) {
                encodeBooleanValuedOperatorHelper((JavaExpression.OperatorExpression) arg1Expr, context,
                        trueContinuation, falseContinuation, endsWithTrueForm);
            } else {
                encodeExpr(arg1Expr, context);
                if (endsWithTrueForm) {
                    mv.visitJumpInsn(Opcodes.IFEQ, falseContinuation);
                } else {
                    mv.visitJumpInsn(Opcodes.IFNE, trueContinuation);
                }
            }

            return;
        }

        if (symbol.equals("||")) {

            //x || y
            //is encoded as
            //if x == true then goto trueContinuation
            //if y == false then goto falseContinuation

            ////what follows is a sample continuation in the case when a literal value is pushed onto the stack
            //push true
            //goto next
            //label falseContinuation:
            //push false
            //label next:

            JavaExpression arg0Expr = operatorExpr.getArgument(0);
            if (isBooleanValuedOperatorExpr(arg0Expr)) {
                Label innerFalseContinuation = new Label();
                //if x evaluates to false, we want to continue with evaluating y, this is why the "endsWithTrueForm" argument is false here.
                encodeBooleanValuedOperatorHelper((JavaExpression.OperatorExpression) arg0Expr, context,
                        trueContinuation, innerFalseContinuation, false);
                mv.visitLabel(innerFalseContinuation);
            } else {
                encodeExpr(arg0Expr, context);
                mv.visitJumpInsn(Opcodes.IFNE, trueContinuation);
            }

            JavaExpression arg1Expr = operatorExpr.getArgument(1);
            if (isBooleanValuedOperatorExpr(arg1Expr)) {
                encodeBooleanValuedOperatorHelper((JavaExpression.OperatorExpression) arg1Expr, context,
                        trueContinuation, falseContinuation, endsWithTrueForm);
            } else {
                encodeExpr(arg1Expr, context);
                if (endsWithTrueForm) {
                    mv.visitJumpInsn(Opcodes.IFEQ, falseContinuation);
                } else {
                    mv.visitJumpInsn(Opcodes.IFNE, trueContinuation);
                }
            }

            return;
        }

        throw new JavaGenerationException("Unknown logical operator " + symbol + ".");

    } // if(operator.isLogicalOp()) 

    // A relational operator

    //one comment on the bytecode sequences: there is some subtle points here because of the treatment of special values e.g. such
    //as not a number, plus infinity, minus 0 etc in the double and float types. The code below is based on copying what the Java
    //compiler generates for simple functions such as:
    //double foo(double x, double y) {double z = x < y; return z;}

    //encode the first argument
    JavaTypeName firstArgType = encodeExpr(operatorExpr.getArgument(0), context);

    // Add instructions to widen the first argument if necessary.
    int wideningOpCode = getWideningOpCode(firstArgType, valueType);
    if (wideningOpCode != Opcodes.NOP) {
        mv.visitInsn(wideningOpCode);
    }

    //Deal with comparisons to null as a special case. Don't push the second argument, since the null is 
    //implicit in the bytecode instruction.
    JavaExpression secondArgExpr = operatorExpr.getArgument(1);
    final boolean compareToNull = secondArgExpr == LiteralWrapper.NULL;

    //Deal with comparisons to int zero as a special case. There are special 1 argument operators for this case.
    //javac makes use of this optimization. Interestingly, javac does not optimize the case when the first argument
    //is a literal int zero i.e. 0 < x, is not converted to x > 0 which then can make use of the 1 argument comparison.        
    final boolean compareToIntZero = isInternalIntType(valueType) && isLiteralIntZeroExpr(secondArgExpr);

    if (!compareToNull && !compareToIntZero) {
        //endcode the second argument
        JavaTypeName secondArgType = encodeExpr(secondArgExpr, context);
        wideningOpCode = getWideningOpCode(secondArgType, valueType);
        if (wideningOpCode != Opcodes.NOP) {
            mv.visitInsn(wideningOpCode);
        }
    }

    // relational symbols: {">", ">=", "<", "<=", "==", "!="}
    if (symbol.equals(">")) {

        switch (valueType.getTag()) {
        case JavaTypeName.BYTE_TAG:
        case JavaTypeName.SHORT_TAG:
        case JavaTypeName.CHAR_TAG:
        case JavaTypeName.INT_TAG: {
            if (endsWithTrueForm) {
                if (compareToIntZero) {
                    mv.visitJumpInsn(Opcodes.IFLE, falseContinuation);
                } else {
                    mv.visitJumpInsn(Opcodes.IF_ICMPLE, falseContinuation);
                }
            } else {
                if (compareToIntZero) {
                    mv.visitJumpInsn(Opcodes.IFGT, trueContinuation);
                } else {
                    mv.visitJumpInsn(Opcodes.IF_ICMPGT, trueContinuation);
                }
            }
            break;
        }

        case JavaTypeName.LONG_TAG: {
            mv.visitInsn(Opcodes.LCMP);
            if (endsWithTrueForm) {
                mv.visitJumpInsn(Opcodes.IFLE, falseContinuation);
            } else {
                mv.visitJumpInsn(Opcodes.IFGT, trueContinuation);
            }
            break;
        }

        case JavaTypeName.DOUBLE_TAG: {
            mv.visitInsn(Opcodes.DCMPL);
            if (endsWithTrueForm) {
                mv.visitJumpInsn(Opcodes.IFLE, falseContinuation);
            } else {
                mv.visitJumpInsn(Opcodes.IFGT, trueContinuation);
            }
            break;
        }

        case JavaTypeName.FLOAT_TAG: {
            mv.visitInsn(Opcodes.FCMPL);
            if (endsWithTrueForm) {
                mv.visitJumpInsn(Opcodes.IFLE, falseContinuation);
            } else {
                mv.visitJumpInsn(Opcodes.IFGT, trueContinuation);
            }
            break;
        }

        default:
            throw new IllegalArgumentException("Unsupported operand type for JVM > operator.");
        }

    } else if (symbol.equals(">=")) {

        switch (valueType.getTag()) {
        case JavaTypeName.BYTE_TAG:
        case JavaTypeName.SHORT_TAG:
        case JavaTypeName.CHAR_TAG:
        case JavaTypeName.INT_TAG: {
            if (endsWithTrueForm) {
                if (compareToIntZero) {
                    mv.visitJumpInsn(Opcodes.IFLT, falseContinuation);
                } else {
                    mv.visitJumpInsn(Opcodes.IF_ICMPLT, falseContinuation);
                }
            } else {
                if (compareToIntZero) {
                    mv.visitJumpInsn(Opcodes.IFGE, trueContinuation);
                } else {
                    mv.visitJumpInsn(Opcodes.IF_ICMPGE, trueContinuation);
                }
            }
            break;
        }

        case JavaTypeName.LONG_TAG: {
            mv.visitInsn(Opcodes.LCMP);
            if (endsWithTrueForm) {
                mv.visitJumpInsn(Opcodes.IFLT, falseContinuation);
            } else {
                mv.visitJumpInsn(Opcodes.IFGE, trueContinuation);
            }
            break;
        }

        case JavaTypeName.DOUBLE_TAG: {
            mv.visitInsn(Opcodes.DCMPL);
            if (endsWithTrueForm) {
                mv.visitJumpInsn(Opcodes.IFLT, falseContinuation);
            } else {
                mv.visitJumpInsn(Opcodes.IFGE, trueContinuation);
            }
            break;
        }

        case JavaTypeName.FLOAT_TAG: {
            mv.visitInsn(Opcodes.FCMPL);
            if (endsWithTrueForm) {
                mv.visitJumpInsn(Opcodes.IFLT, falseContinuation);
            } else {
                mv.visitJumpInsn(Opcodes.IFGE, trueContinuation);
            }
            break;
        }

        default:
            throw new IllegalArgumentException("Unsupported operand type for JVM >= operator.");
        }

    } else if (symbol.equals("<")) {

        switch (valueType.getTag()) {
        case JavaTypeName.BYTE_TAG:
        case JavaTypeName.SHORT_TAG:
        case JavaTypeName.CHAR_TAG:
        case JavaTypeName.INT_TAG: {
            if (endsWithTrueForm) {
                if (compareToIntZero) {
                    mv.visitJumpInsn(Opcodes.IFGE, falseContinuation);
                } else {
                    mv.visitJumpInsn(Opcodes.IF_ICMPGE, falseContinuation);
                }
            } else {
                if (compareToIntZero) {
                    mv.visitJumpInsn(Opcodes.IFLT, trueContinuation);
                } else {
                    mv.visitJumpInsn(Opcodes.IF_ICMPLT, trueContinuation);
                }
            }
            break;
        }

        case JavaTypeName.LONG_TAG: {
            mv.visitInsn(Opcodes.LCMP);
            if (endsWithTrueForm) {
                mv.visitJumpInsn(Opcodes.IFGE, falseContinuation);
            } else {
                mv.visitJumpInsn(Opcodes.IFLT, trueContinuation);
            }
            break;
        }

        case JavaTypeName.DOUBLE_TAG: {
            mv.visitInsn(Opcodes.DCMPG);
            if (endsWithTrueForm) {
                mv.visitJumpInsn(Opcodes.IFGE, falseContinuation);
            } else {
                mv.visitJumpInsn(Opcodes.IFLT, trueContinuation);
            }
            break;
        }

        case JavaTypeName.FLOAT_TAG: {
            mv.visitInsn(Opcodes.FCMPG);
            if (endsWithTrueForm) {
                mv.visitJumpInsn(Opcodes.IFGE, falseContinuation);
            } else {
                mv.visitJumpInsn(Opcodes.IFLT, trueContinuation);
            }
            break;
        }

        default:
            throw new IllegalArgumentException("Unsupported operand type for JVM < operator.");
        }

    } else if (symbol.equals("<=")) {

        switch (valueType.getTag()) {
        case JavaTypeName.BYTE_TAG:
        case JavaTypeName.SHORT_TAG:
        case JavaTypeName.CHAR_TAG:
        case JavaTypeName.INT_TAG: {
            if (endsWithTrueForm) {
                if (compareToIntZero) {
                    mv.visitJumpInsn(Opcodes.IFGT, falseContinuation);
                } else {
                    mv.visitJumpInsn(Opcodes.IF_ICMPGT, falseContinuation);
                }
            } else {
                if (compareToIntZero) {
                    mv.visitJumpInsn(Opcodes.IFLE, trueContinuation);
                } else {
                    mv.visitJumpInsn(Opcodes.IF_ICMPLE, trueContinuation);
                }
            }
            break;
        }

        case JavaTypeName.LONG_TAG: {
            mv.visitInsn(Opcodes.LCMP);
            if (endsWithTrueForm) {
                mv.visitJumpInsn(Opcodes.IFGT, falseContinuation);
            } else {
                mv.visitJumpInsn(Opcodes.IFLE, trueContinuation);
            }
            break;
        }

        case JavaTypeName.DOUBLE_TAG: {
            mv.visitInsn(Opcodes.DCMPG);
            if (endsWithTrueForm) {
                mv.visitJumpInsn(Opcodes.IFGT, falseContinuation);
            } else {
                mv.visitJumpInsn(Opcodes.IFLE, trueContinuation);
            }
            break;
        }

        case JavaTypeName.FLOAT_TAG: {
            mv.visitInsn(Opcodes.FCMPG);
            if (endsWithTrueForm) {
                mv.visitJumpInsn(Opcodes.IFGT, falseContinuation);
            } else {
                mv.visitJumpInsn(Opcodes.IFLE, trueContinuation);
            }
            break;
        }

        default:
            throw new IllegalArgumentException("Unsupported operand type for JVM <= operator.");
        }

    } else if (symbol.equals("==")) {

        switch (valueType.getTag()) {
        case JavaTypeName.BOOLEAN_TAG:
        case JavaTypeName.BYTE_TAG:
        case JavaTypeName.SHORT_TAG:
        case JavaTypeName.CHAR_TAG:
        case JavaTypeName.INT_TAG: {
            if (endsWithTrueForm) {
                if (compareToIntZero) {
                    mv.visitJumpInsn(Opcodes.IFNE, falseContinuation);
                } else {
                    mv.visitJumpInsn(Opcodes.IF_ICMPNE, falseContinuation);
                }
            } else {
                if (compareToIntZero) {
                    mv.visitJumpInsn(Opcodes.IFEQ, trueContinuation);
                } else {
                    mv.visitJumpInsn(Opcodes.IF_ICMPEQ, trueContinuation);
                }
            }
            break;
        }

        case JavaTypeName.LONG_TAG: {
            mv.visitInsn(Opcodes.LCMP);
            if (endsWithTrueForm) {
                mv.visitJumpInsn(Opcodes.IFNE, falseContinuation);
            } else {
                mv.visitJumpInsn(Opcodes.IFEQ, trueContinuation);
            }
            break;
        }

        case JavaTypeName.DOUBLE_TAG: {
            mv.visitInsn(Opcodes.DCMPL);
            if (endsWithTrueForm) {
                mv.visitJumpInsn(Opcodes.IFNE, falseContinuation);
            } else {
                mv.visitJumpInsn(Opcodes.IFEQ, trueContinuation);
            }
            break;
        }

        case JavaTypeName.FLOAT_TAG: {
            mv.visitInsn(Opcodes.FCMPL);
            if (endsWithTrueForm) {
                mv.visitJumpInsn(Opcodes.IFNE, falseContinuation);
            } else {
                mv.visitJumpInsn(Opcodes.IFEQ, trueContinuation);
            }
            break;
        }

        case JavaTypeName.ARRAY_TAG:
        case JavaTypeName.OBJECT_TAG: {
            if (endsWithTrueForm) {
                if (compareToNull) {
                    mv.visitJumpInsn(Opcodes.IFNONNULL, falseContinuation);
                } else {
                    mv.visitJumpInsn(Opcodes.IF_ACMPNE, falseContinuation);
                }
            } else {
                if (compareToNull) {
                    mv.visitJumpInsn(Opcodes.IFNULL, trueContinuation);
                } else {
                    mv.visitJumpInsn(Opcodes.IF_ACMPEQ, trueContinuation);
                }
            }
            break;
        }

        default:
            throw new IllegalArgumentException("Unsupported operand type for JVM == operator.");
        }

    } else if (symbol.equals("!=")) {

        switch (valueType.getTag()) {
        case JavaTypeName.BOOLEAN_TAG:
        case JavaTypeName.BYTE_TAG:
        case JavaTypeName.SHORT_TAG:
        case JavaTypeName.CHAR_TAG:
        case JavaTypeName.INT_TAG: {
            if (endsWithTrueForm) {
                if (compareToIntZero) {
                    mv.visitJumpInsn(Opcodes.IFEQ, falseContinuation);
                } else {
                    mv.visitJumpInsn(Opcodes.IF_ICMPEQ, falseContinuation);
                }
            } else {
                if (compareToIntZero) {
                    mv.visitJumpInsn(Opcodes.IFNE, trueContinuation);
                } else {
                    mv.visitJumpInsn(Opcodes.IF_ICMPNE, trueContinuation);
                }
            }
            break;
        }

        case JavaTypeName.LONG_TAG: {
            mv.visitInsn(Opcodes.LCMP);
            if (endsWithTrueForm) {
                mv.visitJumpInsn(Opcodes.IFEQ, falseContinuation);
            } else {
                mv.visitJumpInsn(Opcodes.IFNE, trueContinuation);
            }
            break;
        }

        case JavaTypeName.DOUBLE_TAG: {
            mv.visitInsn(Opcodes.DCMPL);
            if (endsWithTrueForm) {
                mv.visitJumpInsn(Opcodes.IFEQ, falseContinuation);
            } else {
                mv.visitJumpInsn(Opcodes.IFNE, trueContinuation);
            }
            break;
        }

        case JavaTypeName.FLOAT_TAG: {
            mv.visitInsn(Opcodes.FCMPL);
            if (endsWithTrueForm) {
                mv.visitJumpInsn(Opcodes.IFEQ, falseContinuation);
            } else {
                mv.visitJumpInsn(Opcodes.IFNE, trueContinuation);
            }
            break;
        }

        case JavaTypeName.ARRAY_TAG:
        case JavaTypeName.OBJECT_TAG: {
            if (endsWithTrueForm) {
                if (compareToNull) {
                    mv.visitJumpInsn(Opcodes.IFNULL, falseContinuation);
                } else {
                    mv.visitJumpInsn(Opcodes.IF_ACMPEQ, falseContinuation);
                }
            } else {
                if (compareToNull) {
                    mv.visitJumpInsn(Opcodes.IFNONNULL, trueContinuation);
                } else {
                    mv.visitJumpInsn(Opcodes.IF_ACMPNE, trueContinuation);
                }
            }
            break;
        }

        default:
            throw new IllegalArgumentException("Unsupported operand type for JVM != operator.");
        }

    } else {
        throw new JavaGenerationException("Unknown relational operator " + symbol + ".");
    }
}

From source file:org.sonar.java.bytecode.se.BytecodeEGWalkerExecuteTest.java

License:Open Source License

@Test
public void test_cmp() throws Exception {
    int[] opcodes = new int[] { Opcodes.LCMP, Opcodes.FCMPG, Opcodes.FCMPL, Opcodes.DCMPG, Opcodes.FCMPL };
    assertConsume2produceNotNull(opcodes);

    assertThrowWhenInvalidStack(opcodes, " needs 2 values on stack");
}

From source file:serianalyzer.JVMImpl.java

License:Open Source License

/**
 * @param opcode//  ww  w. ja v a2  s. c om
 * @param s
 */
static void handleJVMInsn(int opcode, JVMStackState s) {
    BaseType o1;
    BaseType o2;
    BaseType o3;
    List<BaseType> l1;
    List<BaseType> l2;
    switch (opcode) {
    case Opcodes.NOP:
        break;

    case Opcodes.ARRAYLENGTH:
        o1 = s.pop();
        s.push(new BasicConstant(Type.INT_TYPE, 0, !(o1 != null && !o1.isTainted())));
        break;
    case Opcodes.ACONST_NULL:
        s.push(new BasicConstant(Type.VOID_TYPE, "<null>")); //$NON-NLS-1$
        break;
    case Opcodes.ICONST_M1:
    case Opcodes.ICONST_0:
    case Opcodes.ICONST_1:
    case Opcodes.ICONST_2:
    case Opcodes.ICONST_3:
    case Opcodes.ICONST_4:
    case Opcodes.ICONST_5:
        s.push(new BasicConstant(Type.INT_TYPE, opcode - 3));
        break;
    case Opcodes.LCONST_0:
    case Opcodes.LCONST_1:
        s.push(new BasicConstant(Type.LONG_TYPE, opcode - 9L));
        break;
    case Opcodes.FCONST_0:
    case Opcodes.FCONST_1:
    case Opcodes.FCONST_2:
        s.push(new BasicConstant(Type.FLOAT_TYPE, opcode - 11f));
        break;
    case Opcodes.DCONST_0:
    case Opcodes.DCONST_1:
        s.push(new BasicConstant(Type.DOUBLE_TYPE, opcode - 14d));
        break;
    case Opcodes.IALOAD:
    case Opcodes.LALOAD:
    case Opcodes.FALOAD:
    case Opcodes.DALOAD:
    case Opcodes.BALOAD:
    case Opcodes.CALOAD:
    case Opcodes.SALOAD:
        o1 = s.pop();
        o2 = s.pop();
        s.push(new BasicVariable(toType(opcode), "primitive array elem", //$NON-NLS-1$
                (o1 == null || o1.isTainted()) | (o2 == null || o2.isTainted())));
        break;

    case Opcodes.AALOAD:
        o1 = s.pop();
        o2 = s.pop();
        if (o1 != null && o2 instanceof SimpleType && ((SimpleType) o2).getType().toString().startsWith("[")) { //$NON-NLS-1$
            Type atype = Type.getType(((SimpleType) o2).getType().toString().substring(1));
            if (o2.getAlternativeTypes() != null && !o2.getAlternativeTypes().isEmpty()) {
                s.clear();
                break;
            }
            s.push(new BasicVariable(atype, "array elem " + atype, o1.isTainted() | o2.isTainted())); //$NON-NLS-1$
        } else {
            s.clear();
        }
        break;

    case Opcodes.IASTORE:
    case Opcodes.LASTORE:
    case Opcodes.FASTORE:
    case Opcodes.DASTORE:
    case Opcodes.AASTORE:
    case Opcodes.BASTORE:
    case Opcodes.CASTORE:
    case Opcodes.SASTORE:
        s.pop(3);
        break;

    case Opcodes.POP2:
        s.pop();
    case Opcodes.MONITORENTER:
    case Opcodes.MONITOREXIT:
    case Opcodes.POP:
        s.pop();
        break;

    case Opcodes.DUP:
        if (!s.isEmpty()) {
            o1 = s.pop();
            s.push(o1);
            s.push(o1);
        }
        break;
    case Opcodes.DUP_X1:
        o1 = s.pop();
        o2 = s.pop();
        s.push(o1);
        s.push(o2);
        s.push(o1);
        break;
    case Opcodes.DUP_X2:
        o1 = s.pop();
        o2 = s.pop();
        o3 = s.pop();
        s.push(o1);
        s.push(o3);
        s.push(o2);
        s.push(o1);
        break;
    case Opcodes.DUP2:
        l1 = s.popWord();
        if (l1.isEmpty()) {
            log.trace("DUP2 with unknown operand"); //$NON-NLS-1$
            s.clear();
        } else {
            s.pushWord(l1);
            s.pushWord(l1);
        }
        break;
    case Opcodes.DUP2_X1:
        l1 = s.popWord();
        o1 = s.pop();
        if (l1.isEmpty()) {
            log.trace("DUP2 with unknown operand"); //$NON-NLS-1$
            s.clear();
        } else {
            s.pushWord(l1);
            s.push(o1);
            s.pushWord(l1);
        }
        break;
    case Opcodes.DUP2_X2:
        l1 = s.popWord();
        l2 = s.popWord();
        if (l1.isEmpty() || l2.isEmpty()) {
            log.trace("DUP2 with unknown operand"); //$NON-NLS-1$
            s.clear();
        } else {
            s.pushWord(l1);
            s.pushWord(l2);
            s.pushWord(l1);
        }
        break;

    case Opcodes.SWAP:
        o1 = s.pop();
        o2 = s.pop();
        s.push(o1);
        s.push(o2);
        break;

    case Opcodes.IADD:
    case Opcodes.LADD:
    case Opcodes.FADD:
    case Opcodes.DADD:
    case Opcodes.ISUB:
    case Opcodes.LSUB:
    case Opcodes.FSUB:
    case Opcodes.DSUB:
    case Opcodes.IMUL:
    case Opcodes.LMUL:
    case Opcodes.FMUL:
    case Opcodes.DMUL:
    case Opcodes.IDIV:
    case Opcodes.LDIV:
    case Opcodes.FDIV:
    case Opcodes.DDIV:
    case Opcodes.IREM:
    case Opcodes.LREM:
    case Opcodes.FREM:
    case Opcodes.DREM:
    case Opcodes.IAND:
    case Opcodes.LAND:
    case Opcodes.IOR:
    case Opcodes.LOR:
    case Opcodes.IXOR:
    case Opcodes.LXOR:
    case Opcodes.LCMP:
    case Opcodes.FCMPL:
    case Opcodes.FCMPG:
    case Opcodes.DCMPL:
    case Opcodes.DCMPG:
        s.merge(2);
        break;

    case Opcodes.ISHL:
    case Opcodes.LSHL:
    case Opcodes.ISHR:
    case Opcodes.LSHR:
    case Opcodes.IUSHR:
    case Opcodes.LUSHR:
        s.pop(); // amount
        // ignore value
        break;

    case Opcodes.INEG:
    case Opcodes.F2I:
    case Opcodes.D2I:
    case Opcodes.L2I:
        s.push(cast(s.pop(), Type.INT_TYPE));
        break;

    case Opcodes.LNEG:
    case Opcodes.I2L:
    case Opcodes.F2L:
    case Opcodes.D2L:
        s.push(cast(s.pop(), Type.LONG_TYPE));
        break;

    case Opcodes.FNEG:
    case Opcodes.I2F:
    case Opcodes.L2F:
    case Opcodes.D2F:
        s.push(cast(s.pop(), Type.FLOAT_TYPE));

    case Opcodes.DNEG:
    case Opcodes.I2D:
    case Opcodes.L2D:
    case Opcodes.F2D:
        s.push(cast(s.pop(), Type.DOUBLE_TYPE));

    case Opcodes.I2B:
        s.push(cast(s.pop(), Type.BYTE_TYPE));
        break;
    case Opcodes.I2C:
        s.push(cast(s.pop(), Type.CHAR_TYPE));
        break;
    case Opcodes.I2S:
        s.push(cast(s.pop(), Type.SHORT_TYPE));
        break;

    case Opcodes.ARETURN:
        s.clear();
        break;

    case Opcodes.IRETURN:
    case Opcodes.LRETURN:
    case Opcodes.FRETURN:
    case Opcodes.DRETURN:
    case Opcodes.RETURN:
        if (log.isTraceEnabled()) {
            log.trace("Found return " + s.pop()); //$NON-NLS-1$
        }
        s.clear();
        break;

    case Opcodes.ATHROW:
        Object thrw = s.pop();
        log.trace("Found throw " + thrw); //$NON-NLS-1$
        s.clear();
        break;

    default:
        log.warn("Unsupported instruction code " + opcode); //$NON-NLS-1$
    }
}