Example usage for org.objectweb.asm Opcodes IFNONNULL

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

Introduction

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

Prototype

int IFNONNULL

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

Click Source Link

Usage

From source file:org.jboss.byteman.agent.adapter.RuleGeneratorAdapter.java

License:Open Source License

/**
 * Generates the instruction to jump to the given label if the top stack
 * value is not null.//from  w w w .  ja  va 2s.c  o  m
 *
 * @param label where to jump if the condition is <tt>true</tt>.
 */
public void ifNonNull(final Label label) {
    visitJumpInsn(Opcodes.IFNONNULL, label);
}

From source file:org.jboss.byteman.agent.adapter.RuleTriggerMethodAdapter.java

License:Open Source License

@Override
public void visitJumpInsn(int opcode, Label label) {
    super.visitJumpInsn(opcode, label);
    switch (opcode) {
    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: {
        // create a new current block and add the label supplied in the call as the
        // first out of the old current block and the label of the new current block as
        // the second out
        cfg.add(opcode);//ww  w  .j  av a2  s  . c  o  m
        Label newStart = super.newLabel();
        // must call split before visiting the label
        cfg.split(newStart, label, newStart);
        visitLabel(newStart);
    }
        break;
    case Opcodes.GOTO: {
        // create a new current block and  add the label supplied in the call as the
        // first out of the old current block
        cfg.add(opcode);
        Label newStart = super.newLabel();
        // must call split before visiting the label
        cfg.split(newStart, label);
        visitLabel(newStart);
    }
        break;
    case Opcodes.JSR: {
        // create a new current block and add the label supplied in the call as the first out
        // of the current block -- the new current block is a potential return point from the
        // JSR but we cannot represent that statically
        cfg.add(opcode);
        Label newStart = super.newLabel();
        // must call split before visiting the label
        cfg.split(newStart, label, newStart);
        visitLabel(newStart);
    }
        break;
    case Opcodes.IFNULL:
    case Opcodes.IFNONNULL: {
        // create a new current block and add the label supplied in the call as the
        // first out of the old current block and the label of the new current block as
        // the second out
        cfg.add(opcode);
        Label newStart = super.newLabel();
        // must call split before visiting the label
        cfg.split(newStart, label, newStart);
        visitLabel(newStart);
    }
        break;
    }
}

From source file:org.jboss.byteman.rule.expression.StringPlusExpression.java

License:Open Source License

public void compile(MethodVisitor mv, CompileContext compileContext) throws CompileException {
    // make sure we are at the right source line
    compileContext.notifySourceLine(line);

    Expression oper0 = getOperand(0);
    Expression oper1 = getOperand(1);

    int currentStack = compileContext.getStackCount();
    int expected = 1;

    // compile and type convert each operand n.b. the type conversion will ensure that
    // null operands are replaced with "null"

    oper0.compile(mv, compileContext);/*w ww  .  j a v a 2s  . co m*/
    compileTypeConversion(oper0.getType(), type, mv, compileContext);
    oper1.compile(mv, compileContext);
    compileTypeConversion(oper1.getType(), type, mv, compileContext);

    // ok, we could optimize this for the case where the left or right operand is a String plus expression
    // by employing a StringBuffer but for now we will just evaluate the left and right operand and
    // then call concat to join them
    // add two strings leaving one string

    // if second operand is null replace it with "null"
    Label skiptarget = new Label();
    // this adds a word then removes it -- do so to ensure the max height gets updated if need be
    mv.visitInsn(Opcodes.DUP);
    compileContext.addStackCount(1);
    // if it is not null we skip to the concat operation
    mv.visitJumpInsn(Opcodes.IFNONNULL, skiptarget);
    compileContext.addStackCount(-1);
    // it's null so we have to swap it fdr "null"
    mv.visitInsn(Opcodes.POP);
    mv.visitLdcInsn("null");
    mv.visitLabel(skiptarget);
    mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/String", "concat",
            "(Ljava/lang/String;)Ljava/lang/String;");

    compileContext.addStackCount(-1);

    if (compileContext.getStackCount() != currentStack + expected) {
        throw new CompileException("StringPlusExpression.compile : invalid stack height "
                + compileContext.getStackCount() + " expecting " + currentStack + expected);
    }
}

From source file:org.jboss.byteman.rule.RuleElement.java

License:Open Source License

protected void compileStringConversion(Type fromType, Type toType, MethodVisitor mv,
        CompileContext compileContext) throws CompileException {
    assert toType == Type.STRING;
    if (fromType.isObject() || fromType.isArray() || (fromType.isNumeric() && !fromType.isPrimitive())) {
        // use the toString method if the object is non null otherwise just replace it with null
        Label elseLabel = new Label();
        Label endLabel = new Label();
        // if (object == null)
        mv.visitInsn(Opcodes.DUP);/*from ww w .j ava2s.  c o  m*/
        // the above dup bumps the stack height
        compileContext.addStackCount(1);
        mv.visitJumpInsn(Opcodes.IFNONNULL, elseLabel);
        compileContext.addStackCount(-1);
        // then string = "null"
        mv.visitInsn(Opcodes.POP);
        mv.visitInsn(Opcodes.ACONST_NULL);
        mv.visitJumpInsn(Opcodes.GOTO, endLabel);
        // else string = object.toString()
        mv.visitLabel(elseLabel);
        mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/Object", "toString", "()Ljava/lang/String;");
        mv.visitLabel(endLabel);
    } else if (fromType == Type.Z) {
        // use the toString method
        mv.visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/Boolean", "toString", "(Z)Ljava/lang/String;");
    } else if (fromType == Type.B) {
        // use the toString method
        mv.visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/Byte", "toString", "(B)Ljava/lang/String;");
    } else if (fromType == Type.S) {
        // use the toString method
        mv.visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/Short", "toString", "(S)Ljava/lang/String;");
    } else if (fromType == Type.C) {
        // use the toString method
        mv.visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/Character", "toString", "(C)Ljava/lang/String;");
    } else if (fromType == Type.I) {
        // use the toString method
        mv.visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/Integer", "toString", "(I)Ljava/lang/String;");
    } else if (fromType == Type.J) {
        // use the toString method
        mv.visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/Long", "toString", "(J)Ljava/lang/String;");
        compileContext.addStackCount(-1);
    } else if (fromType == Type.F) {
        // use the toString method
        mv.visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/Float", "toString", "(F)Ljava/lang/String;");
    } else if (fromType == Type.D) {
        // use the toString method
        mv.visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/Double", "toString", "(D)Ljava/lang/String;");
        compileContext.addStackCount(-1);
    }
}

From source file:org.kantega.dogmaticmvc.mutation.MutationMethodVisitor.java

License:Apache License

private int getMutatedJumpInsn(int i) {
    switch (i) {/* w  w  w  . java  2s  . c  om*/
    case Opcodes.IFEQ:
        return Opcodes.IFNE;
    case Opcodes.IFNE:
        return Opcodes.IFEQ;
    case Opcodes.IFLT:
        return Opcodes.IFGE;
    case Opcodes.IFGE:
        return Opcodes.IFLT;
    case Opcodes.IFGT:
        return Opcodes.IFLE;
    case Opcodes.IFLE:
        return Opcodes.IFGT;
    case Opcodes.IF_ICMPEQ:
        return Opcodes.IF_ICMPNE;
    case Opcodes.IF_ICMPNE:
        return Opcodes.IF_ICMPEQ;
    case Opcodes.IF_ICMPLT:
        return Opcodes.IF_ICMPGE;
    case Opcodes.IF_ICMPGE:
        return Opcodes.IF_ICMPLT;
    case Opcodes.IF_ICMPGT:
        return Opcodes.IF_ICMPLE;
    case Opcodes.IF_ICMPLE:
        return Opcodes.IF_ICMPGT;
    case Opcodes.IF_ACMPEQ:
        return Opcodes.IF_ACMPNE;
    case Opcodes.IF_ACMPNE:
        return Opcodes.IF_ACMPEQ;
    case Opcodes.IFNULL:
        return Opcodes.IFNONNULL;
    case Opcodes.IFNONNULL:
        return Opcodes.IFNULL;

    default:
        return i;
    }
}

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 ww.j  av  a 2 s  .com
 * -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.parboiled.compiler.notNullVerification.MyMethodAdapter.java

License:Apache License

@Override
public void visitCode() {
    if (myNotNullParams.size() > 0) {
        myStartGeneratedCodeLabel = new Label();
        mv.visitLabel(myStartGeneratedCodeLabel);
    }/*www  . ja  va 2s.c om*/
    for (Object myNotNullParam : myNotNullParams) {
        int var = ((access & Opcodes.ACC_STATIC) == 0) ? 1 : 0;
        int param = (Integer) myNotNullParam;
        for (int i = 0; i < param + startParameter; ++i) {
            var += args[i].getSize();
        }
        mv.visitVarInsn(Opcodes.ALOAD, var);

        Label end = new Label();
        mv.visitJumpInsn(Opcodes.IFNONNULL, end);

        generateThrow(
                "java/lang/IllegalArgumentException", toOrdinalString(param) + " argument of method "
                        + getFullMethodName() + "(...) corresponds to @NotNull parameter and must not be null",
                end);
    }
}

From source file:org.parboiled.compiler.notNullVerification.MyMethodAdapter.java

License:Apache License

@Override
public void visitInsn(int opcode) {
    if (opcode == Opcodes.ARETURN && myIsNotNull) {
        mv.visitInsn(Opcodes.DUP);// w  ww .  ja  v  a  2  s .  c om
        if (myThrowLabel == null) {
            Label skipLabel = new Label();
            mv.visitJumpInsn(Opcodes.IFNONNULL, skipLabel);
            myThrowLabel = new Label();
            mv.visitLabel(myThrowLabel);
            generateThrow("java/lang/IllegalStateException",
                    "@NotNull method " + getFullMethodName() + " must not return null", skipLabel);
        } else {
            mv.visitJumpInsn(Opcodes.IFNULL, myThrowLabel);
        }
    }

    mv.visitInsn(opcode);
}

From source file:org.pitest.mutationtest.engine.gregor.mutators.ReturnValsMutator.java

License:Apache License

private static ZeroOperandMutation areturnMutation() {
    return new ZeroOperandMutation() {

        public void apply(final int opCode, final MethodVisitor mv) {

            // Strategy translated from jumble BCEL code
            // if result is non-null make it null, otherwise hard case
            // for moment throw runtime exception
            final Label l1 = new Label();
            mv.visitJumpInsn(Opcodes.IFNONNULL, l1);
            mv.visitTypeInsn(Opcodes.NEW, "java/lang/RuntimeException");
            mv.visitInsn(Opcodes.DUP);//from  ww w  .  j a v a2s.c  om
            mv.visitMethodInsn(Opcodes.INVOKESPECIAL, "java/lang/RuntimeException", "<init>", "()V", false);
            mv.visitInsn(Opcodes.ATHROW);
            mv.visitLabel(l1);
            mv.visitInsn(Opcodes.ACONST_NULL);
            mv.visitInsn(Opcodes.ARETURN);
        }

        public String decribe(final int opCode, final MethodInfo methodInfo) {
            return "mutated return of Object value for " + methodInfo.getDescription()
                    + " to ( if (x != null) null else throw new RuntimeException )";
        }

    };
}

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

License:Open Source License

@Test
public void test_compare_with_null() {
    SymbolicValue sv = new SymbolicValue();
    int[] opcodes = { Opcodes.IFNULL, Opcodes.IFNONNULL };
    for (int opcode : opcodes) {
        ProgramState programState = walker.branchingState(new Instruction(opcode),
                ProgramState.EMPTY_STATE.stackValue(sv));
        RelationalSymbolicValue relSV = (RelationalSymbolicValue) programState.peekValue();
        assertThat(relSV.getLeftOp()).isSameAs(sv);
        assertThat(relSV.getRightOp()).isSameAs(SymbolicValue.NULL_LITERAL);
    }// w  ww .  j  a va 2 s  .com
}