List of usage examples for org.objectweb.asm Opcodes IF_ICMPLT
int IF_ICMPLT
To view the source code for org.objectweb.asm Opcodes IF_ICMPLT.
Click Source Link
From source file:org.lambdamatic.analyzer.ast.LambdaExpressionReader.java
License:Open Source License
/** * Extracts the comparison {@link CompoundExpressionOperator} from the given {@link JumpInsnNode}. * // w w w . ja v a 2 s.co m * @param currentInstruction the comparison instruction * @return the corresponding {@link CompoundExpressionOperator} */ private static CompoundExpressionOperator extractComparisonOperator(final AbstractInsnNode currentInstruction) { switch (currentInstruction.getOpcode()) { case Opcodes.IF_ACMPNE: case Opcodes.IF_ICMPNE: case Opcodes.IFNE: return CompoundExpressionOperator.NOT_EQUALS; case Opcodes.IF_ACMPEQ: case Opcodes.IF_ICMPEQ: case Opcodes.IFEQ: return CompoundExpressionOperator.EQUALS; case Opcodes.IF_ICMPLE: case Opcodes.IFLE: return CompoundExpressionOperator.LESS_EQUALS; case Opcodes.IF_ICMPLT: case Opcodes.IFLT: return CompoundExpressionOperator.LESS; case Opcodes.IF_ICMPGE: case Opcodes.IFGE: return CompoundExpressionOperator.GREATER_EQUALS; case Opcodes.IF_ICMPGT: case Opcodes.IFGT: return CompoundExpressionOperator.GREATER; default: throw new AnalyzeException( "Failed to retrieve the operator for the current comparison instruction (opcode: " + currentInstruction.getOpcode() + ")"); } }
From source file:org.lambdamatic.analyzer.ast.LambdaExpressionReader.java
License:Open Source License
/** * The {@link AbstractInsnNode#getOpcode()} value should be one of {@code IFEQ}, {@code IFNE}, * {@code IFLT}, {@code IFGE}, {@code IFGT}, {@code IFLE}, {@code IFLT}, {@code IFGE}, * {@code IFGT},{@code IF_ICMPEQ}, {@code IF_ICMPNE}, {@code IF_ICMPLT}, {@code IF_ICMPGE}, * {@code IF_ICMPGT}, {@code IF_ICMPLE}, {@code IF_ACMPEQ}, {@code IF_ACMPNE}, {@code GOTO}, * {@code JSR}, {@code IFNULL} or {@code IFNONNULL}. * // w ww . ja va2s. c o m * * @param instructionCursor the cursor for the current instruction to read * @param expressionStack the stack of Expressions * @param capturedArguments the captured arguments * @param localVariables the local variables * @return the list of statements read from the jump instruction */ private List<Statement> readJumpInstruction(final InsnCursor instructionCursor, final Stack<Expression> expressionStack, final List<CapturedArgument> capturedArguments, final LocalVariables localVariables) { final JumpInsnNode jumpInsnNode = (JumpInsnNode) instructionCursor.getCurrent(); final LabelNode jumpLabel = jumpInsnNode.label; // FIXME: add support for LCMP: // Takes two two-word long integers off the stack and compares them. If // the two integers are the same, the int 0 is pushed onto the stack. If // value2 is greater than value1, the int 1 is pushed onto the stack. If // value1 is greater than value2, the int -1 is pushed onto the stack. switch (jumpInsnNode.getOpcode()) { case Opcodes.IFEQ: case Opcodes.IFNE: case Opcodes.IFLE: case Opcodes.IFLT: case Opcodes.IFGE: case Opcodes.IFGT: case Opcodes.IF_ICMPEQ: case Opcodes.IF_ICMPNE: case Opcodes.IF_ICMPLE: case Opcodes.IF_ICMPLT: case Opcodes.IF_ICMPGE: case Opcodes.IF_ICMPGT: case Opcodes.IF_ACMPEQ: case Opcodes.IF_ACMPNE: return Arrays.asList(buildControlFlowStatement(instructionCursor, expressionStack, capturedArguments, localVariables)); case Opcodes.GOTO: final InsnCursor jumpInstructionCursor = instructionCursor.duplicate(); jumpInstructionCursor.move(jumpLabel.getLabel()); return readStatements(jumpInstructionCursor, expressionStack, capturedArguments, localVariables); default: throw new AnalyzeException("Unexpected JumpInsnNode OpCode: " + jumpInsnNode.getOpcode()); } }
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.// www. j av a 2 s. 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_compare_instructions() { int[] opcodes = { Opcodes.IF_ICMPEQ, Opcodes.IF_ICMPNE, Opcodes.IF_ICMPLT, Opcodes.IF_ICMPGE, Opcodes.IF_ACMPEQ, Opcodes.IF_ACMPNE }; SymbolicValue left = new SymbolicValue(); SymbolicValue right = new SymbolicValue(); for (int opcode : opcodes) { ProgramState programState = walker.branchingState(new Instruction(opcode), ProgramState.EMPTY_STATE.stackValue(left).stackValue(right)); RelationalSymbolicValue relSV = (RelationalSymbolicValue) programState.peekValue(); assertThat(relSV.getLeftOp()).isSameAs(left); assertThat(relSV.getRightOp()).isSameAs(right); }/*from ww w . j av a 2 s .com*/ // these opcodes inverse operator and swap operands int[] swapOperandsOpcodes = { Opcodes.IF_ICMPLE, Opcodes.IF_ICMPGT }; for (int opcode : swapOperandsOpcodes) { ProgramState programState = walker.branchingState(new Instruction(opcode), ProgramState.EMPTY_STATE.stackValue(left).stackValue(right)); RelationalSymbolicValue relSV = (RelationalSymbolicValue) programState.peekValue(); assertThat(relSV.getRightOp()).isSameAs(left); assertThat(relSV.getLeftOp()).isSameAs(right); } }
From source file:org.spongepowered.asm.mixin.injection.points.JumpInsnPoint.java
License:MIT License
public JumpInsnPoint(InjectionPointData data) { this.opCode = data.getOpcode(-1, Opcodes.IFEQ, Opcodes.IFNE, Opcodes.IFLT, Opcodes.IFGE, Opcodes.IFGT, Opcodes.IFLE, Opcodes.IF_ICMPEQ, Opcodes.IF_ICMPNE, Opcodes.IF_ICMPLT, Opcodes.IF_ICMPGE, Opcodes.IF_ICMPGT, Opcodes.IF_ICMPLE, Opcodes.IF_ACMPEQ, Opcodes.IF_ACMPNE, Opcodes.GOTO, Opcodes.JSR, Opcodes.IFNULL, Opcodes.IFNONNULL, -1); this.ordinal = data.getOrdinal(); }
From source file:serianalyzer.JVMImpl.java
License:Open Source License
/** * @param opcode//from w ww .j a va 2s . c o m * @param label * @param s * @return */ static boolean handleJVMJump(int opcode, Label label, JVMStackState s) { boolean tainted; switch (opcode) { case Opcodes.IF_ICMPEQ: case Opcodes.IF_ICMPNE: case Opcodes.IF_ICMPLT: case Opcodes.IF_ICMPGE: case Opcodes.IF_ICMPGT: case Opcodes.IF_ICMPLE: case Opcodes.IF_ACMPEQ: case Opcodes.IF_ACMPNE: BaseType o1 = s.pop(); BaseType o2 = s.pop(); tainted = !(o1 != null) || !(o2 != null) || o1.isTainted() || o2.isTainted(); break; case Opcodes.IFEQ: case Opcodes.IFNE: case Opcodes.IFLT: case Opcodes.IFGE: case Opcodes.IFGT: case Opcodes.IFLE: case Opcodes.IFNULL: case Opcodes.IFNONNULL: BaseType c = s.pop(); tainted = (c == null || c.isTainted()); break; case Opcodes.JSR: s.push(new BasicConstant(Type.INT_TYPE, label)); tainted = false; break; case Opcodes.GOTO: tainted = false; break; default: log.warn("Unsupported opcode " + opcode); //$NON-NLS-1$ tainted = true; } return tainted; }
From source file:v6.java.preverifier.MethodRewriter.java
License:Open Source License
/** * Visit the specified instruction and do the right thing. * /*from w w w.j a v a 2 s . co m*/ * @param method * @param region * @param insnNode * @throws AnalyzerException */ private void visitInstruction(MethodNode method, Region region, AbstractInsnNode insnNode) throws AnalyzerException { int opcode = insnNode.getOpcode(); switch (opcode) { case Opcodes.JSR: visitJumpToSubroutine(method, region, (JumpInsnNode) insnNode); break; case Opcodes.IFEQ: case Opcodes.IFNE: case Opcodes.IFLT: case Opcodes.IFGE: case Opcodes.IFGT: case Opcodes.IFLE: case Opcodes.IF_ICMPEQ: case Opcodes.IF_ICMPNE: case Opcodes.IF_ICMPLT: case Opcodes.IF_ICMPGE: case Opcodes.IF_ICMPGT: case Opcodes.IF_ICMPLE: case Opcodes.IF_ACMPEQ: case Opcodes.IF_ACMPNE: case Opcodes.GOTO: case Opcodes.IFNULL: case Opcodes.IFNONNULL: visitJump(method, region, (JumpInsnNode) insnNode); break; case Opcodes.LOOKUPSWITCH: visitLookupSwitch(method, region, (LookupSwitchInsnNode) insnNode); break; case Opcodes.TABLESWITCH: visitTableSwitch(method, region, (TableSwitchInsnNode) insnNode); break; default: insnNode.accept(method); } }