List of usage examples for org.objectweb.asm Opcodes FCMPL
int FCMPL
To view the source code for org.objectweb.asm Opcodes FCMPL.
Click Source Link
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$ } }