Example usage for org.objectweb.asm MethodVisitor visitJumpInsn

List of usage examples for org.objectweb.asm MethodVisitor visitJumpInsn

Introduction

In this page you can find the example usage for org.objectweb.asm MethodVisitor visitJumpInsn.

Prototype

public void visitJumpInsn(final int opcode, final Label label) 

Source Link

Document

Visits a jump instruction.

Usage

From source file:org.mbte.groovypp.compiler.asm.VisitJumpInsn.java

License:Apache License

public void visit(MethodVisitor mv) {
    mv.visitJumpInsn(opcode, label);
}

From source file:org.mbte.groovypp.compiler.bytecode.BytecodeExpr.java

License:Apache License

/**
 * convert boolean to Boolean//  w w w.j a  v a2  s  . com
 * @param mv
 */
public void boxBoolean(MethodVisitor mv) {
    Label l0 = new Label();
    mv.visitJumpInsn(Opcodes.IFEQ, l0);
    mv.visitFieldInsn(Opcodes.GETSTATIC, "java/lang/Boolean", "TRUE", "Ljava/lang/Boolean;");
    Label l1 = new Label();
    mv.visitJumpInsn(Opcodes.GOTO, l1);
    mv.visitLabel(l0);
    mv.visitFieldInsn(Opcodes.GETSTATIC, "java/lang/Boolean", "FALSE", "Ljava/lang/Boolean;");
    mv.visitLabel(l1);
}

From source file:org.mbte.groovypp.compiler.bytecode.BytecodeExpr.java

License:Apache License

/**
 * negate a boolean on stack. true->false, false->true
 * @param mv/*from  w  ww.j  a  v a  2  s .  co  m*/
 */
public void negateBoolean(MethodVisitor mv) {
    // code to negate the primitive boolean
    Label endLabel = new Label();
    Label falseLabel = new Label();
    mv.visitJumpInsn(Opcodes.IFNE, falseLabel);
    mv.visitInsn(Opcodes.ICONST_1);
    mv.visitJumpInsn(Opcodes.GOTO, endLabel);
    mv.visitLabel(falseLabel);
    mv.visitInsn(Opcodes.ICONST_0);
    mv.visitLabel(endLabel);
}

From source file:org.mbte.groovypp.compiler.bytecode.BytecodeExpr.java

License:Apache License

public static void cast(ClassNode expr, ClassNode type, MethodVisitor mv) {
    if (isPrimitiveType(expr) || isPrimitiveType(type)) {
        throw new RuntimeException("Cannot convert " + expr.getName() + " to " + type.getName());
    }//ww w  .  ja  v  a 2  s  .  c o  m

    expr = expr.redirect();
    type = type.redirect();

    if (TypeUtil.isDirectlyAssignableFrom(type, expr)) {
        return;
    }

    if (expr.isArray()) {
        castArray(expr, type, mv);
    } else if (isIntegralType(expr)) {
        castIntegral(expr, type, mv);
    } else if (expr == Character_TYPE) {
        unbox(getUnwrapper(expr), mv);
        box(int_TYPE, mv);
        castIntegral(Integer_TYPE, type, mv);
    } else if (expr == Boolean_TYPE) {
        unbox(getUnwrapper(expr), mv);
        box(int_TYPE, mv);
        castIntegral(Integer_TYPE, type, mv);
    } else if (expr == Long_TYPE) {
        castLong(expr, type, mv);
    } else if (expr == Double_TYPE) {
        castDouble(expr, type, mv);
    } else if (expr == Float_TYPE) {
        castFloat(expr, type, mv);
    } else if (expr == BigDecimal_TYPE) {
        castBigDecimal(expr, type, mv);
    } else if (expr == BigInteger_TYPE) {
        castBigInteger(expr, type, mv);
    } else if (expr == STRING_TYPE) {
        castString(expr, type, mv);
    } else if (expr.equals(TypeUtil.Number_TYPE)) {
        castNumber(expr, type, mv);
    } else if (expr.implementsInterface(TypeUtil.COLLECTION_TYPE) && type.isArray()) {
        castArrayToCollection(expr, type, mv);
    } else {
        if (TypeUtil.isNumericalType(type) && !type.equals(TypeUtil.Number_TYPE)) {
            if (TypeUtil.isBigDecimal(type) || TypeUtil.isBigInteger(type)) {
                checkCast(type, mv);
            } else {
                Label nullLabel = new Label(), doneLabel = new Label();
                mv.visitInsn(DUP);
                mv.visitJumpInsn(IFNULL, nullLabel);
                unbox(getUnwrapper(type), mv);
                box(getUnwrapper(type), mv);
                mv.visitJumpInsn(GOTO, doneLabel);
                mv.visitLabel(nullLabel);
                checkCast(type, mv);
                mv.visitLabel(doneLabel);
            }
        } else {
            if (expr != TypeUtil.NULL_TYPE) {
                if (type.equals(STRING_TYPE)) {
                    Label nullLabel = new Label(), doneLabel = new Label();
                    mv.visitInsn(DUP);
                    mv.visitJumpInsn(IFNULL, nullLabel);
                    mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Object", "toString", "()Ljava/lang/String;");
                    mv.visitJumpInsn(GOTO, doneLabel);
                    mv.visitLabel(nullLabel);
                    checkCast(type, mv);
                    mv.visitLabel(doneLabel);
                } else {
                    checkCast(type, mv);
                }
            }
        }
    }
}

From source file:org.mbte.groovypp.compiler.CompilerTransformer.java

License:Apache License

public void mathOp(MethodVisitor mv, ClassNode type, Token op, BinaryExpression be) {
    switch (op.getType()) {
    case Types.PLUS:
        if (type == ClassHelper.int_TYPE)
            mv.visitInsn(IADD);/*from   ww  w  .  j  a v a  2 s  .co  m*/
        else if (type == ClassHelper.double_TYPE)
            mv.visitInsn(DADD);
        else if (type == ClassHelper.long_TYPE)
            mv.visitInsn(LADD);
        else
            throw new RuntimeException("Internal Error");
        break;

    case Types.COMPARE_NOT_EQUAL: {
        Label _true = new Label();
        if (type == ClassHelper.int_TYPE)
            mv.visitJumpInsn(IF_ICMPEQ, _true);
        else if (type == ClassHelper.double_TYPE) {
            mv.visitInsn(DCMPG);
            mv.visitJumpInsn(IFEQ, _true);
        } else if (type == ClassHelper.float_TYPE) {
            mv.visitInsn(FCMPG);
            mv.visitJumpInsn(IFEQ, _true);
        } else if (type == ClassHelper.long_TYPE) {
            mv.visitInsn(LCMP);
            mv.visitJumpInsn(IFEQ, _true);
        } else
            throw new RuntimeException("Internal Error");
        mv.visitInsn(ICONST_1);
        Label _false = new Label();
        mv.visitJumpInsn(GOTO, _false);
        mv.visitLabel(_true);
        mv.visitInsn(ICONST_0);
        mv.visitLabel(_false);
        break;
    }

    case Types.MULTIPLY:
        if (type == ClassHelper.int_TYPE)
            mv.visitInsn(IMUL);
        else if (type == ClassHelper.double_TYPE)
            mv.visitInsn(DMUL);
        else if (type == ClassHelper.long_TYPE)
            mv.visitInsn(LMUL);
        else
            throw new RuntimeException("Internal Error");
        break;

    case Types.MINUS:
        if (type == ClassHelper.int_TYPE)
            mv.visitInsn(ISUB);
        else if (type == ClassHelper.double_TYPE)
            mv.visitInsn(DSUB);
        else if (type == ClassHelper.long_TYPE)
            mv.visitInsn(LSUB);
        else
            throw new RuntimeException("Internal Error");
        break;

    case Types.DIVIDE:
        if (type == ClassHelper.int_TYPE) {
            mv.visitInsn(IDIV);
        } else if (type == ClassHelper.double_TYPE)
            mv.visitInsn(DDIV);
        else if (type == ClassHelper.long_TYPE)
            mv.visitInsn(LDIV);
        else
            throw new RuntimeException("Internal Error");
        break;

    case Types.BITWISE_XOR:
        if (type == ClassHelper.int_TYPE)
            mv.visitInsn(IXOR);
        else if (type == ClassHelper.long_TYPE)
            mv.visitInsn(LXOR);
        else
            throw new RuntimeException("Internal Error");
        break;

    case Types.BITWISE_AND:
        if (type == ClassHelper.int_TYPE)
            mv.visitInsn(IAND);
        else if (type == ClassHelper.long_TYPE)
            mv.visitInsn(LAND);
        else
            throw new RuntimeException("Internal Error");
        break;

    case Types.INTDIV:
        if (type == ClassHelper.int_TYPE)
            mv.visitInsn(IDIV);
        else if (type == ClassHelper.long_TYPE)
            mv.visitInsn(LDIV);
        else
            throw new RuntimeException("Internal Error");
        break;

    case Types.LEFT_SHIFT:
        if (type == ClassHelper.int_TYPE)
            mv.visitInsn(ISHL);
        else if (type == ClassHelper.long_TYPE) {
            mv.visitInsn(L2I);
            mv.visitInsn(LSHL);
        } else
            throw new RuntimeException("Internal Error");
        break;

    case Types.RIGHT_SHIFT:
        if (type == ClassHelper.int_TYPE)
            mv.visitInsn(ISHR);
        else if (type == ClassHelper.long_TYPE) {
            mv.visitInsn(L2I);
            mv.visitInsn(LSHR);
        } else
            throw new RuntimeException("Internal Error");
        break;

    case Types.RIGHT_SHIFT_UNSIGNED:
        if (type == ClassHelper.int_TYPE)
            mv.visitInsn(IUSHR);
        else if (type == ClassHelper.long_TYPE) {
            mv.visitInsn(L2I);
            mv.visitInsn(LUSHR);
        } else
            throw new RuntimeException("Internal Error");
        break;

    case Types.MOD:
        if (type == ClassHelper.int_TYPE)
            mv.visitInsn(IREM);
        else if (type == ClassHelper.double_TYPE)
            mv.visitInsn(DREM);
        else if (type == ClassHelper.long_TYPE)
            mv.visitInsn(LREM);
        else
            throw new RuntimeException("Internal Error");
        break;

    case Types.BITWISE_OR:
        if (type == ClassHelper.int_TYPE)
            mv.visitInsn(IOR);
        else if (type == ClassHelper.long_TYPE)
            mv.visitInsn(LOR);
        else
            throw new RuntimeException("Internal Error");
        break;

    default:
        addError("Operation " + op.getDescription() + " doesn't supported", be);
    }
}

From source file:org.mbte.groovypp.compiler.CompilerTransformer.java

License:Apache License

public BytecodeExpr castToBoolean(final BytecodeExpr be, final ClassNode type) {
    if (be.getType().equals(ClassHelper.boolean_TYPE))
        return be;

    if (ClassHelper.isPrimitiveType(be.getType())) {
        return new BytecodeExpr(be, type) {
            protected void compile(MethodVisitor mv) {
                ClassNode btype = be.getType();
                if (btype == ClassHelper.long_TYPE) {
                    be.visit(mv);/*  w ww . ja  v a2  s  . co m*/
                    mv.visitInsn(L2I);
                } else if (btype == ClassHelper.float_TYPE) {
                    mv.visitInsn(ICONST_0);
                    be.visit(mv);
                    mv.visitInsn(FCONST_0);
                    mv.visitInsn(FCMPG);
                    final Label falseL = new Label();
                    mv.visitJumpInsn(IFEQ, falseL);
                    mv.visitInsn(POP);
                    mv.visitInsn(ICONST_1);
                    mv.visitLabel(falseL);
                } else if (btype == ClassHelper.double_TYPE) {
                    mv.visitInsn(ICONST_0);
                    be.visit(mv);
                    mv.visitInsn(DCONST_0);
                    mv.visitInsn(DCMPG);
                    final Label falseL = new Label();
                    mv.visitJumpInsn(IFEQ, falseL);
                    mv.visitInsn(POP);
                    mv.visitInsn(ICONST_1);
                    mv.visitLabel(falseL);
                } else {
                    be.visit(mv); // int, short, byte, char
                }

                if (type.equals(ClassHelper.Boolean_TYPE))
                    box(ClassHelper.boolean_TYPE, mv);
            }
        };
    } else {
        MethodCallExpression safeCall = new MethodCallExpression(new BytecodeExpr(be, be.getType()) {
            protected void compile(MethodVisitor mv) {
            }
        }, be.getType().equals(ClassHelper.OBJECT_TYPE) ? "asBooleanDynamic" : "asBoolean",
                ArgumentListExpression.EMPTY_ARGUMENTS);
        safeCall.setSourcePosition(be);

        final BytecodeExpr call = (BytecodeExpr) transform(safeCall);

        if (!call.getType().equals(ClassHelper.boolean_TYPE))
            addError("method asBoolean () should return 'boolean'", be);

        return new BytecodeExpr(be, type) {
            protected void compile(MethodVisitor mv) {
                be.visit(mv);
                mv.visitInsn(DUP);
                Label nullLabel = new Label(), endLabel = new Label();

                mv.visitJumpInsn(IFNULL, nullLabel);

                call.visit(mv);
                mv.visitJumpInsn(GOTO, endLabel);

                mv.visitLabel(nullLabel);
                mv.visitInsn(POP);
                mv.visitInsn(ICONST_0);

                mv.visitLabel(endLabel);

                if (type.equals(ClassHelper.Boolean_TYPE))
                    box(ClassHelper.boolean_TYPE, mv);
            }
        };
    }
}

From source file:org.mbte.groovypp.compiler.CompilerTransformer.java

License:Apache License

public BytecodeExpr castToString(final BytecodeExpr be) {
    if (be.getType().equals(TypeUtil.NULL_TYPE) || be.getType().equals(ClassHelper.STRING_TYPE))
        return be;

    MethodCallExpression safeCall = new MethodCallExpression(
            new BytecodeExpr(be, TypeUtil.wrapSafely(be.getType())) {
                protected void compile(MethodVisitor mv) {
                }/*w  w w.j  a v a  2 s  . c  o  m*/
            }, "toString", ArgumentListExpression.EMPTY_ARGUMENTS);
    safeCall.setSourcePosition(be);

    final BytecodeExpr call = (BytecodeExpr) transform(safeCall);

    if (!call.getType().equals(ClassHelper.STRING_TYPE))
        addError("method toString () should return 'java.lang.String'", be);

    return new BytecodeExpr(be, ClassHelper.STRING_TYPE) {
        protected void compile(MethodVisitor mv) {
            be.visit(mv);
            box(be.getType(), mv);
            mv.visitInsn(DUP);
            Label nullLabel = new Label(), endLabel = new Label();

            mv.visitJumpInsn(IFNULL, nullLabel);

            call.visit(mv);
            mv.visitJumpInsn(GOTO, endLabel);

            mv.visitLabel(nullLabel);
            mv.visitTypeInsn(CHECKCAST, BytecodeHelper.getClassInternalName(ClassHelper.STRING_TYPE));

            mv.visitLabel(endLabel);
        }
    };
}

From source file:org.mbte.groovypp.compiler.StaticCompiler.java

License:Apache License

private void visitForLoopWithIterator(ForStatement forLoop, BytecodeExpr collectionExpression) {
    compileStack.pushLoop(forLoop.getVariableScope(), forLoop.getStatementLabel());

    Label continueLabel = compileStack.getContinueLabel();
    Label breakLabel = compileStack.getBreakLabel();
    BytecodeExpr fakeObject = new BytecodeExpr(collectionExpression, collectionExpression.getType()) {
        protected void compile(MethodVisitor mv) {
        }//from  w  ww. j  a v  a  2 s  .c  o  m
    };

    MethodCallExpression iterator = new MethodCallExpression(fakeObject, "iterator",
            new ArgumentListExpression());
    iterator.setSourcePosition(collectionExpression);
    BytecodeExpr expr = (BytecodeExpr) transform(iterator);
    expr.visit(mv);

    ClassNode etype = ClassHelper.OBJECT_TYPE;
    ClassNode iteratorType = expr.getType();
    GenericsType[] generics = iteratorType.getGenericsTypes();
    if (generics != null && generics.length == 1) {
        if (!TypeUtil.isSuper(generics[0])) {
            etype = generics[0].getType();
        }
    }
    if (forLoop.getVariable().getType() == ClassHelper.DYNAMIC_TYPE)
        forLoop.getVariable().setType(etype);
    else
        etype = forLoop.getVariable().getType();

    Register variable = compileStack.defineVariable(forLoop.getVariable(), false);

    final int iteratorIdx = compileStack.defineTemporaryVariable("iterator", ClassHelper.make(Iterator.class),
            true);

    mv.startLoopVisitLabel(continueLabel);
    mv.visitVarInsn(ALOAD, iteratorIdx);
    mv.visitMethodInsn(INVOKEINTERFACE, "java/util/Iterator", "hasNext", "()Z");
    mv.visitJumpInsn(IFEQ, breakLabel);

    mv.visitVarInsn(ALOAD, iteratorIdx);
    mv.visitMethodInsn(INVOKEINTERFACE, "java/util/Iterator", "next", "()Ljava/lang/Object;");
    if (ClassHelper.isPrimitiveType(etype)) {
        BytecodeExpr.unbox(etype, mv);
    } else {
        BytecodeExpr.cast(ClassHelper.OBJECT_TYPE, etype, mv);
    }
    BytecodeExpr.store(etype, variable.getIndex(), mv);

    forLoop.getLoopBlock().visit(this);

    mv.visitJumpInsn(GOTO, continueLabel);
    mv.visitLabel(breakLabel);
    compileStack.pop();
}

From source file:org.mbte.groovypp.compiler.StaticCompiler.java

License:Apache License

public void visitSwitch(SwitchStatement statement) {
    visitStatement(statement);//from   w ww.  ja  v a2  s  .c o m

    List caseStatements = statement.getCaseStatements();

    BytecodeExpr cond = (BytecodeExpr) transform(statement.getExpression());
    cond.visit(mv);

    if (statement.getExpression() instanceof VariableExpression) {
        final VariableExpression ve = (VariableExpression) statement.getExpression();

        if (!ve.getName().equals("this")) {
            for (Iterator iter = caseStatements.iterator(); iter.hasNext();) {
                CaseStatement caseStatement = (CaseStatement) iter.next();
                final Expression option = caseStatement.getExpression();
                if (option instanceof ClassExpression && !ve.getType().equals(ClassHelper.CLASS_Type)) {
                    final BlockStatement newCode = new BlockStatement();
                    final VariableExpression newVar = new VariableExpression(ve.getName(), option.getType());
                    final DeclarationExpression newVarDecl = new DeclarationExpression(newVar,
                            Token.newSymbol(Types.EQUAL, -1, -1), ve);
                    newVarDecl.setSourcePosition(caseStatement);
                    newCode.addStatement(new ExpressionStatement(newVarDecl));
                    newCode.addStatement(caseStatement.getCode());
                    caseStatement.setCode(newCode);
                    newCode.visit(new ClassCodeExpressionTransformer() {
                        @Override
                        public Expression transform(Expression exp) {
                            if (exp instanceof VariableExpression) {
                                VariableExpression vexp = (VariableExpression) exp;
                                if (vexp.getName().equals(ve.getName())) {
                                    vexp.setAccessedVariable(newVar);
                                }
                            }
                            return super.transform(exp);
                        }

                        protected SourceUnit getSourceUnit() {
                            return su;
                        }
                    });
                }
            }
        }
    }

    // switch does not have a continue label. use its parent's for continue
    Label breakLabel = compileStack.pushSwitch();

    int switchVariableIndex = compileStack.defineTemporaryVariable("switch", cond.getType(), true);

    int caseCount = caseStatements.size();
    Label[] codeLabels = new Label[caseCount];
    Label[] condLabels = new Label[caseCount + 1];
    int i;
    for (i = 0; i < caseCount; i++) {
        codeLabels[i] = new Label();
        condLabels[i] = new Label();
    }

    Label defaultLabel = new Label();

    i = 0;
    for (Iterator iter = caseStatements.iterator(); iter.hasNext(); i++) {
        CaseStatement caseStatement = (CaseStatement) iter.next();

        mv.visitLabel(condLabels[i]);

        visitStatement(caseStatement);

        BytecodeExpr.load(cond.getType(), switchVariableIndex, mv);
        BytecodeExpr option = (BytecodeExpr) transformToGround(caseStatement.getExpression());

        if (ClassHelper.isPrimitiveType(option.getType()) && ClassHelper.isPrimitiveType(cond.getType())) {
            option.visit(mv);
            final BytecodeExpr caseValue = new BytecodeExpr(option, option.getType()) {
                protected void compile(MethodVisitor mv) {
                }
            };

            final BytecodeExpr switchValue = new BytecodeExpr(cond, cond.getType()) {
                protected void compile(MethodVisitor mv) {
                }
            };
            BinaryExpression eq = new BinaryExpression(caseValue, Token.newSymbol(Types.COMPARE_EQUAL, -1, -1),
                    switchValue);
            eq.setSourcePosition(caseValue);
            transformLogical(eq, codeLabels[i], true).visit(mv);
        } else {
            if (ClassHelper.isPrimitiveType(cond.getType())) {
                if (caseStatement.getExpression() instanceof ClassExpression) {
                    addError(
                            "Primitive type " + cond.getType().getName() + " con not be instance of "
                                    + ((ClassExpression) caseStatement.getExpression()).getType().getName(),
                            caseStatement.getExpression());
                    continue;
                }

                BytecodeExpr.box(cond.getType(), mv);

                option.visit(mv);
                BytecodeExpr.box(option.getType(), mv);

                Label next = i == caseCount - 1 ? defaultLabel : condLabels[i + 1];

                Label notNull = new Label();
                mv.visitInsn(DUP);
                mv.visitJumpInsn(IFNONNULL, notNull);
                mv.visitJumpInsn(IF_ACMPEQ, codeLabels[i]);
                mv.visitJumpInsn(GOTO, next);

                mv.visitLabel(notNull);

                final BytecodeExpr caseValue = new BytecodeExpr(option, TypeUtil.wrapSafely(option.getType())) {
                    protected void compile(MethodVisitor mv) {
                    }
                };

                final BytecodeExpr switchValue = new BytecodeExpr(cond, TypeUtil.wrapSafely(cond.getType())) {
                    protected void compile(MethodVisitor mv) {
                        mv.visitInsn(SWAP);
                    }
                };
                MethodCallExpression exp = new MethodCallExpression(caseValue, "isCase",
                        new ArgumentListExpression(switchValue));
                exp.setSourcePosition(caseValue);
                transformLogical(exp, codeLabels[i], true).visit(mv);
            } else {
                if (caseStatement.getExpression() instanceof ClassExpression
                        && !cond.getType().equals(ClassHelper.CLASS_Type)) {
                    BytecodeExpr.box(cond.getType(), mv);
                    mv.visitTypeInsn(INSTANCEOF,
                            BytecodeHelper.getClassInternalName(caseStatement.getExpression().getType()));
                    mv.visitJumpInsn(IFNE, codeLabels[i]);
                } else {
                    option.visit(mv);
                    BytecodeExpr.box(option.getType(), mv);

                    Label next = i == caseCount - 1 ? defaultLabel : condLabels[i + 1];

                    Label notNull = new Label();
                    mv.visitInsn(DUP);
                    mv.visitJumpInsn(IFNONNULL, notNull);
                    mv.visitJumpInsn(IF_ACMPEQ, codeLabels[i]);
                    mv.visitJumpInsn(GOTO, next);

                    mv.visitLabel(notNull);

                    final BytecodeExpr caseValue = new BytecodeExpr(option,
                            TypeUtil.wrapSafely(option.getType())) {
                        protected void compile(MethodVisitor mv) {
                        }
                    };

                    final BytecodeExpr switchValue = new BytecodeExpr(cond,
                            TypeUtil.wrapSafely(cond.getType())) {
                        protected void compile(MethodVisitor mv) {
                            mv.visitInsn(SWAP);
                        }
                    };
                    MethodCallExpression exp = new MethodCallExpression(caseValue, "isCase",
                            new ArgumentListExpression(switchValue));
                    exp.setSourcePosition(caseValue);
                    transformLogical(exp, codeLabels[i], true).visit(mv);
                }
            }
        }
    }

    mv.visitJumpInsn(GOTO, defaultLabel);

    i = 0;
    for (Iterator iter = caseStatements.iterator(); iter.hasNext(); i++) {
        CaseStatement caseStatement = (CaseStatement) iter.next();
        visitStatement(caseStatement);
        mv.visitLabel(codeLabels[i]);
        caseStatement.getCode().visit(this);
    }

    mv.visitLabel(defaultLabel);
    statement.getDefaultStatement().visit(this);

    mv.visitLineNumber(statement.getLastLineNumber(), new Label());
    mv.visitLabel(breakLabel);

    compileStack.pop();
}

From source file:org.mbte.groovypp.compiler.transformers.BinaryExpressionTransformer.java

License:Apache License

private BytecodeExpr evaluateInstanceof(final BinaryExpression be, final CompilerTransformer compiler,
        final Label label, final boolean onTrue) {
    final BytecodeExpr l = (BytecodeExpr) compiler.transform(be.getLeftExpression());
    final ClassNode type = be.getRightExpression().getType();
    if (be.getLeftExpression() instanceof VariableExpression) {
        final VariableExpression leftExpression = (VariableExpression) be.getLeftExpression();
        if (leftExpression.getType() == ClassHelper.DYNAMIC_TYPE
                && !(leftExpression.getName().equals("this"))) {
            if (onTrue) {
                compiler.addLocalVarInferenceType(label, leftExpression, type,
                        ((ResolvedVarBytecodeExpr) l).var.getIndex());
                return new BytecodeExpr(be, ClassHelper.VOID_TYPE) {
                    protected void compile(MethodVisitor mv) {
                        l.visit(mv);/*  w ww. j  a  v  a 2  s .c om*/
                        box(l.getType(), mv);
                        mv.visitTypeInsn(INSTANCEOF, BytecodeHelper.getClassInternalName(type));
                        mv.visitJumpInsn(IFNE, label);
                    }
                };
            } else {
                final LocalVarInferenceTypes inferenceTypes = compiler.getLocalVarInferenceTypes();
                final ClassNode saved = inferenceTypes.get(leftExpression);
                inferenceTypes.add(leftExpression, type);
                return new BytecodeExpr(be, ClassHelper.VOID_TYPE) {
                    protected void compile(MethodVisitor mv) {
                        inferenceTypes.add(leftExpression, saved);
                        l.visit(mv);
                        box(l.getType(), mv);
                        mv.visitTypeInsn(INSTANCEOF, BytecodeHelper.getClassInternalName(type));
                        mv.visitJumpInsn(IFEQ, label);
                        VariableExpression leftExpression = (VariableExpression) be.getLeftExpression();
                        inferenceTypes.add(leftExpression, type);

                        Register var = compiler.compileStack.getRegister(leftExpression.getName(), true);

                        // we do it in order to make JVM verifier happy and do not check cast on each use of variable
                        mv.visitVarInsn(ALOAD, var.getIndex());
                        mv.visitTypeInsn(CHECKCAST, BytecodeHelper.getClassInternalName(type));
                        mv.visitVarInsn(ASTORE, var.getIndex());
                    }
                };
            }
        }
    }
    return new BytecodeExpr(be, ClassHelper.VOID_TYPE) {
        protected void compile(MethodVisitor mv) {
            l.visit(mv);
            box(l.getType(), mv);
            mv.visitTypeInsn(INSTANCEOF, BytecodeHelper.getClassInternalName(type));
            mv.visitJumpInsn(onTrue ? IFNE : IFEQ, label);
        }
    };
}