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.codehaus.groovy.classgen.asm.StatementWriter.java

License:Apache License

protected void writeForLoopWithClosureList(ForStatement loop) {
    controller.getAcg().onLineNumber(loop, "visitForLoop");
    writeStatementLabel(loop);//from  ww  w  . j  a v a  2 s.c  o  m

    MethodVisitor mv = controller.getMethodVisitor();
    controller.getCompileStack().pushLoop(loop.getVariableScope(), loop.getStatementLabels());

    ClosureListExpression clExpr = (ClosureListExpression) loop.getCollectionExpression();
    controller.getCompileStack().pushVariableScope(clExpr.getVariableScope());

    List<Expression> expressions = clExpr.getExpressions();
    int size = expressions.size();

    // middle element is condition, lower half is init, higher half is increment
    int condIndex = (size - 1) / 2;

    // visit init
    for (int i = 0; i < condIndex; i++) {
        visitExpressionOfLoopStatement(expressions.get(i));
    }

    Label continueLabel = controller.getCompileStack().getContinueLabel();
    Label breakLabel = controller.getCompileStack().getBreakLabel();

    Label cond = new Label();
    mv.visitLabel(cond);
    // visit condition leave boolean on stack
    {
        Expression condExpr = expressions.get(condIndex);
        int mark = controller.getOperandStack().getStackLength();
        condExpr.visit(controller.getAcg());
        controller.getOperandStack().castToBool(mark, true);
    }
    // jump if we don't want to continue
    // note: ifeq tests for ==0, a boolean is 0 if it is false
    controller.getOperandStack().jump(IFEQ, breakLabel);

    // Generate the loop body
    loop.getLoopBlock().visit(controller.getAcg());

    // visit increment
    mv.visitLabel(continueLabel);
    // fix for being on the wrong line when debugging for loop
    controller.getAcg().onLineNumber(loop, "increment condition");
    for (int i = condIndex + 1; i < size; i += 1) {
        visitExpressionOfLoopStatement(expressions.get(i));
    }

    // jump to test the condition again
    mv.visitJumpInsn(GOTO, cond);

    // loop end
    mv.visitLabel(breakLabel);

    controller.getCompileStack().pop();
    controller.getCompileStack().pop();
}

From source file:org.codehaus.groovy.classgen.asm.StatementWriter.java

License:Apache License

private void visitConditionOfLoopingStatement(BooleanExpression bool, Label breakLabel, MethodVisitor mv) {
    boolean boolHandled = false;
    if (bool.getExpression() instanceof ConstantExpression) {
        ConstantExpression constant = (ConstantExpression) bool.getExpression();
        if (constant.getValue() == Boolean.TRUE) {
            boolHandled = true;//from  www .j  av a 2 s .com
            // do nothing
        } else if (constant.getValue() == Boolean.FALSE) {
            boolHandled = true;
            mv.visitJumpInsn(GOTO, breakLabel);
        }
    }

    if (!boolHandled) {
        bool.visit(controller.getAcg());
        controller.getOperandStack().jump(IFEQ, breakLabel);
    }
}

From source file:org.codehaus.groovy.classgen.asm.StatementWriter.java

License:Apache License

public void writeWhileLoop(WhileStatement loop) {
    controller.getAcg().onLineNumber(loop, "visitWhileLoop");
    writeStatementLabel(loop);//from   w w w  .  j  a  v  a2s.  c o m

    MethodVisitor mv = controller.getMethodVisitor();

    controller.getCompileStack().pushLoop(loop.getStatementLabels());
    Label continueLabel = controller.getCompileStack().getContinueLabel();
    Label breakLabel = controller.getCompileStack().getBreakLabel();

    mv.visitLabel(continueLabel);

    this.visitConditionOfLoopingStatement(loop.getBooleanExpression(), breakLabel, mv);
    loop.getLoopBlock().visit(controller.getAcg());

    mv.visitJumpInsn(GOTO, continueLabel);
    mv.visitLabel(breakLabel);

    controller.getCompileStack().pop();
}

From source file:org.codehaus.groovy.classgen.asm.StatementWriter.java

License:Apache License

public void writeDoWhileLoop(DoWhileStatement loop) {
    controller.getAcg().onLineNumber(loop, "visitDoWhileLoop");
    writeStatementLabel(loop);/*from w ww  . j  a va2  s. co  m*/

    MethodVisitor mv = controller.getMethodVisitor();

    controller.getCompileStack().pushLoop(loop.getStatementLabels());
    Label continueLabel = controller.getCompileStack().getContinueLabel();
    Label breakLabel = controller.getCompileStack().getBreakLabel();

    mv.visitLabel(continueLabel);

    loop.getLoopBlock().visit(controller.getAcg());
    this.visitConditionOfLoopingStatement(loop.getBooleanExpression(), breakLabel, mv);

    mv.visitJumpInsn(GOTO, continueLabel);
    mv.visitLabel(breakLabel);

    controller.getCompileStack().pop();
}

From source file:org.codehaus.groovy.classgen.asm.StatementWriter.java

License:Apache License

public void writeIfElse(IfStatement ifElse) {
    controller.getAcg().onLineNumber(ifElse, "visitIfElse");
    writeStatementLabel(ifElse);/*www .j  ava  2 s.  c om*/

    MethodVisitor mv = controller.getMethodVisitor();

    ifElse.getBooleanExpression().visit(controller.getAcg());
    Label l0 = controller.getOperandStack().jump(IFEQ);

    // if-else is here handled as a special version
    // of a boolean expression
    controller.getCompileStack().pushBooleanExpression();
    ifElse.getIfBlock().visit(controller.getAcg());
    controller.getCompileStack().pop();

    if (ifElse.getElseBlock() instanceof EmptyStatement) {
        mv.visitLabel(l0);
    } else {
        Label l1 = new Label();
        mv.visitJumpInsn(GOTO, l1);
        mv.visitLabel(l0);

        controller.getCompileStack().pushBooleanExpression();
        ifElse.getElseBlock().visit(controller.getAcg());
        controller.getCompileStack().pop();

        mv.visitLabel(l1);
    }
}

From source file:org.codehaus.groovy.classgen.asm.StatementWriter.java

License:Apache License

public void writeTryCatchFinally(TryCatchStatement statement) {
    controller.getAcg().onLineNumber(statement, "visitTryCatchFinally");
    writeStatementLabel(statement);//from w ww .j  a v a 2s. c om

    MethodVisitor mv = controller.getMethodVisitor();
    CompileStack compileStack = controller.getCompileStack();
    OperandStack operandStack = controller.getOperandStack();

    Statement tryStatement = statement.getTryStatement();
    Statement finallyStatement = statement.getFinallyStatement();

    // start try block, label needed for exception table
    Label tryStart = new Label();
    mv.visitLabel(tryStart);
    BlockRecorder tryBlock = makeBlockRecorder(finallyStatement);
    tryBlock.startRange(tryStart);

    tryStatement.visit(controller.getAcg());

    // goto finally part
    Label finallyStart = new Label();
    mv.visitJumpInsn(GOTO, finallyStart);

    Label tryEnd = new Label();
    mv.visitLabel(tryEnd);
    tryBlock.closeRange(tryEnd);
    // pop for "makeBlockRecorder(finallyStatement)"
    controller.getCompileStack().pop();

    BlockRecorder catches = makeBlockRecorder(finallyStatement);
    for (CatchStatement catchStatement : statement.getCatchStatements()) {
        ClassNode exceptionType = catchStatement.getExceptionType();
        String exceptionTypeInternalName = BytecodeHelper.getClassInternalName(exceptionType);

        // start catch block, label needed for exception table
        Label catchStart = new Label();
        mv.visitLabel(catchStart);
        catches.startRange(catchStart);

        // create exception variable and store the exception
        Parameter exceptionVariable = catchStatement.getVariable();
        compileStack.pushState();
        compileStack.defineVariable(exceptionVariable, true);
        // handle catch body
        catchStatement.visit(controller.getAcg());
        // place holder to avoid problems with empty catch blocks
        mv.visitInsn(NOP);
        // pop for the variable
        controller.getCompileStack().pop();

        // end of catch
        Label catchEnd = new Label();
        mv.visitLabel(catchEnd);
        catches.closeRange(catchEnd);

        // goto finally start
        mv.visitJumpInsn(GOTO, finallyStart);
        compileStack.writeExceptionTable(tryBlock, catchStart, exceptionTypeInternalName);
    }

    // used to handle exceptions in catches and regularly visited finals
    Label catchAny = new Label();

    // add "catch any" block to exception table for try part we do this
    // after the exception blocks, because else this one would supersede
    // any of those otherwise
    compileStack.writeExceptionTable(tryBlock, catchAny, null);
    // same for the catch parts
    compileStack.writeExceptionTable(catches, catchAny, null);

    // pop for "makeBlockRecorder(catches)"
    compileStack.pop();

    // start finally
    mv.visitLabel(finallyStart);
    finallyStatement.visit(controller.getAcg());

    // goto after all-catching block
    Label skipCatchAll = new Label();
    mv.visitJumpInsn(GOTO, skipCatchAll);

    // start a block catching any Exception
    mv.visitLabel(catchAny);
    // store exception
    // TODO: maybe define a Throwable and use it here instead of Object
    operandStack.push(ClassHelper.OBJECT_TYPE);
    int anyExceptionIndex = compileStack.defineTemporaryVariable("exception", true);

    // GROOVY-9199
    controller.resetLineNumber();
    int line = finallyStatement.getLineNumber();
    if (line > 0)
        mv.visitLineNumber(line, catchAny);

    finallyStatement.visit(controller.getAcg());

    // load the exception and rethrow it
    mv.visitVarInsn(ALOAD, anyExceptionIndex);
    mv.visitInsn(ATHROW);

    mv.visitLabel(skipCatchAll);
    compileStack.removeVar(anyExceptionIndex);
}

From source file:org.codehaus.groovy.classgen.asm.StatementWriter.java

License:Apache License

protected void writeCaseStatement(CaseStatement statement, int switchVariableIndex, Label thisLabel,
        Label nextLabel) {//w  ww.  j ava  2 s  . c o  m
    controller.getAcg().onLineNumber(statement, "visitCaseStatement");
    MethodVisitor mv = controller.getMethodVisitor();
    OperandStack operandStack = controller.getOperandStack();

    mv.visitVarInsn(ALOAD, switchVariableIndex);

    statement.getExpression().visit(controller.getAcg());
    operandStack.box();
    controller.getBinaryExpressionHelper().getIsCaseMethod().call(mv);
    operandStack.replace(ClassHelper.boolean_TYPE);

    Label l0 = controller.getOperandStack().jump(IFEQ);

    mv.visitLabel(thisLabel);

    statement.getCode().visit(controller.getAcg());

    // now if we don't finish with a break we need to jump past
    // the next comparison
    if (nextLabel != null) {
        mv.visitJumpInsn(GOTO, nextLabel);
    }

    mv.visitLabel(l0);
}

From source file:org.codehaus.groovy.classgen.asm.StatementWriter.java

License:Apache License

public void writeSynchronized(SynchronizedStatement statement) {
    controller.getAcg().onLineNumber(statement, "visitSynchronizedStatement");
    writeStatementLabel(statement);//from w  ww.j a v  a  2  s  . c om
    final MethodVisitor mv = controller.getMethodVisitor();
    CompileStack compileStack = controller.getCompileStack();

    statement.getExpression().visit(controller.getAcg());
    controller.getOperandStack().box();
    final int index = compileStack.defineTemporaryVariable("synchronized", ClassHelper.OBJECT_TYPE, true);

    final Label synchronizedStart = new Label();
    final Label synchronizedEnd = new Label();
    final Label catchAll = new Label();

    mv.visitVarInsn(ALOAD, index);
    mv.visitInsn(MONITORENTER);
    mv.visitLabel(synchronizedStart);
    // place holder for "empty" synchronized blocks, for example
    // if there is only a break/continue.
    mv.visitInsn(NOP);

    Runnable finallyPart = () -> {
        mv.visitVarInsn(ALOAD, index);
        mv.visitInsn(MONITOREXIT);
    };
    BlockRecorder fb = new BlockRecorder(finallyPart);
    fb.startRange(synchronizedStart);
    compileStack.pushBlockRecorder(fb);
    statement.getCode().visit(controller.getAcg());

    fb.closeRange(catchAll);
    compileStack.writeExceptionTable(fb, catchAll, null);
    compileStack.pop(); //pop fb

    finallyPart.run();
    mv.visitJumpInsn(GOTO, synchronizedEnd);
    mv.visitLabel(catchAll);
    finallyPart.run();
    mv.visitInsn(ATHROW);

    mv.visitLabel(synchronizedEnd);
    compileStack.removeVar(index);
}

From source file:org.codehaus.groovy.classgen.AsmClassGenerator.java

License:Apache License

protected void createSyntheticStaticFields() {
    if (referencedClasses.isEmpty()) {
        return;/*from w ww  .  j  a v a2  s.  c  om*/
    }
    MethodVisitor mv;
    for (Map.Entry<String, ClassNode> entry : referencedClasses.entrySet()) {
        String staticFieldName = entry.getKey();
        ClassNode cn = entry.getValue();
        // generate a field node
        FieldNode fn = controller.getClassNode().getDeclaredField(staticFieldName);
        if (fn != null) {
            boolean type = fn.getType().equals(ClassHelper.CLASS_Type);
            boolean modifiers = fn.getModifiers() == ACC_STATIC + ACC_SYNTHETIC;
            if (!type || !modifiers) {
                String text = "";
                if (!type)
                    text = " with wrong type: " + fn.getType() + " (java.lang.Class needed)";
                if (!modifiers)
                    text = " with wrong modifiers: " + fn.getModifiers() + " (" + (ACC_STATIC + ACC_SYNTHETIC)
                            + " needed)";
                throwException("tried to set a static synthetic field " + staticFieldName + " in "
                        + controller.getClassNode().getName()
                        + " for class resolving, but found already a node of that name " + text);
            }
        } else {
            classVisitor.visitField(ACC_PRIVATE + ACC_STATIC + ACC_SYNTHETIC, staticFieldName,
                    "Ljava/lang/Class;", null, null);
        }

        mv = classVisitor.visitMethod(ACC_PRIVATE + ACC_STATIC + ACC_SYNTHETIC, "$get$" + staticFieldName,
                "()Ljava/lang/Class;", null, null);
        mv.visitCode();
        mv.visitFieldInsn(GETSTATIC, controller.getInternalClassName(), staticFieldName, "Ljava/lang/Class;");
        mv.visitInsn(DUP);
        Label l0 = new Label();
        mv.visitJumpInsn(IFNONNULL, l0);
        mv.visitInsn(POP);
        mv.visitLdcInsn(BytecodeHelper.getClassLoadingTypeDescription(cn));
        mv.visitMethodInsn(INVOKESTATIC, controller.getInternalClassName(), "class$",
                "(Ljava/lang/String;)Ljava/lang/Class;", false);
        mv.visitInsn(DUP);
        mv.visitFieldInsn(PUTSTATIC, controller.getInternalClassName(), staticFieldName, "Ljava/lang/Class;");
        mv.visitLabel(l0);
        mv.visitInsn(ARETURN);
        mv.visitMaxs(0, 0);
        mv.visitEnd();
    }

    mv = classVisitor.visitMethod(ACC_STATIC + ACC_SYNTHETIC, "class$", "(Ljava/lang/String;)Ljava/lang/Class;",
            null, null);
    Label l0 = new Label();
    mv.visitLabel(l0);
    mv.visitVarInsn(ALOAD, 0);
    mv.visitMethodInsn(INVOKESTATIC, "java/lang/Class", "forName", "(Ljava/lang/String;)Ljava/lang/Class;",
            false);
    Label l1 = new Label();
    mv.visitLabel(l1);
    mv.visitInsn(ARETURN);
    Label l2 = new Label();
    mv.visitLabel(l2);
    mv.visitVarInsn(ASTORE, 1);
    mv.visitTypeInsn(NEW, "java/lang/NoClassDefFoundError");
    mv.visitInsn(DUP);
    mv.visitVarInsn(ALOAD, 1);
    mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/ClassNotFoundException", "getMessage", "()Ljava/lang/String;",
            false);
    mv.visitMethodInsn(INVOKESPECIAL, "java/lang/NoClassDefFoundError", "<init>", "(Ljava/lang/String;)V",
            false);
    mv.visitInsn(ATHROW);
    mv.visitTryCatchBlock(l0, l2, l2, "java/lang/ClassNotFoundException"); // br using l2 as the 2nd param seems create the right table entry
    mv.visitMaxs(3, 2);
}

From source file:org.codehaus.groovy.classgen.AsmClassGenerator.java

License:Apache License

@Override
public void visitClosureListExpression(final ClosureListExpression expression) {
    MethodVisitor mv = controller.getMethodVisitor();
    controller.getCompileStack().pushVariableScope(expression.getVariableScope());

    List<Expression> expressions = expression.getExpressions();
    final int size = expressions.size();
    // init declarations
    for (int i = 0; i < size; i += 1) {
        Expression expr = expressions.get(i);
        if (expr instanceof DeclarationExpression) {
            DeclarationExpression de = (DeclarationExpression) expr;
            BinaryExpression be = new BinaryExpression(de.getLeftExpression(), de.getOperation(),
                    de.getRightExpression());
            expressions.set(i, be);/*from  www.j a  v a  2  s .c o  m*/
            de.setRightExpression(ConstantExpression.NULL);
            visitDeclarationExpression(de);
        }
    }

    List<Object> instructions = new LinkedList<>();
    BytecodeSequence seq = new BytecodeSequence(instructions);
    BlockStatement bs = new BlockStatement();
    bs.addStatement(seq);
    Parameter closureIndex = new Parameter(ClassHelper.int_TYPE, "__closureIndex");
    ClosureExpression ce = new ClosureExpression(new Parameter[] { closureIndex }, bs);
    ce.setVariableScope(expression.getVariableScope());

    // to keep stack height put a null on stack
    instructions.add(ConstantExpression.NULL);

    // init table
    final Label dflt = new Label();
    final Label tableEnd = new Label();
    final Label[] labels = new Label[size];
    instructions.add(new BytecodeInstruction() {
        public void visit(MethodVisitor mv) {
            mv.visitVarInsn(ILOAD, 1);
            mv.visitTableSwitchInsn(0, size - 1, dflt, labels);
        }
    });

    // visit cases
    for (int i = 0; i < size; i += 1) {
        Label label = new Label();
        Expression expr = expressions.get(i);
        labels[i] = label;
        instructions.add(new BytecodeInstruction() {
            public void visit(MethodVisitor mv) {
                mv.visitLabel(label);
                // expressions will leave a value on stack, so need to pop the alibi null
                mv.visitInsn(POP);
            }
        });
        instructions.add(expr);
        instructions.add(new BytecodeInstruction() {
            public void visit(MethodVisitor mv) {
                mv.visitJumpInsn(GOTO, tableEnd);
            }
        });
    }

    // default case
    instructions.add(new BytecodeInstruction() {
        public void visit(MethodVisitor mv) {
            mv.visitLabel(dflt);
        }
    });
    ConstantExpression text = new ConstantExpression("invalid index for closure");
    ConstructorCallExpression cce = new ConstructorCallExpression(
            ClassHelper.make(IllegalArgumentException.class), text);
    ThrowStatement ts = new ThrowStatement(cce);
    instructions.add(ts);

    // return
    instructions.add(new BytecodeInstruction() {
        public void visit(MethodVisitor mv) {
            mv.visitLabel(tableEnd);
            mv.visitInsn(ARETURN);
        }
    });

    // load main Closure
    visitClosureExpression(ce);

    // we need later an array to store the curried
    // closures, so we create it here and ave it
    // in a temporary variable
    BytecodeHelper.pushConstant(mv, size);
    mv.visitTypeInsn(ANEWARRAY, "java/lang/Object");
    int listArrayVar = controller.getCompileStack().defineTemporaryVariable("_listOfClosures", true);

    // add curried versions
    for (int i = 0; i < size; i += 1) {
        // stack: closure

        // we need to create a curried closure version
        // so we store the type on stack
        mv.visitTypeInsn(NEW, "org/codehaus/groovy/runtime/CurriedClosure");
        // stack: closure, type
        // for a constructor call we need the type two times

        // and the closure after them
        mv.visitInsn(DUP2);
        mv.visitInsn(SWAP);
        // stack: closure,type,type,closure

        // so we can create the curried closure
        mv.visitInsn(ICONST_1);
        mv.visitTypeInsn(ANEWARRAY, "java/lang/Object");
        mv.visitInsn(DUP);
        mv.visitInsn(ICONST_0);
        mv.visitLdcInsn(i);
        mv.visitMethodInsn(INVOKESTATIC, "java/lang/Integer", "valueOf", "(I)Ljava/lang/Integer;", false);
        mv.visitInsn(AASTORE);
        mv.visitMethodInsn(INVOKESPECIAL, "org/codehaus/groovy/runtime/CurriedClosure", "<init>",
                "(Lgroovy/lang/Closure;[Ljava/lang/Object;)V", false);
        // stack: closure,curriedClosure

        // we need to save the result
        mv.visitVarInsn(ALOAD, listArrayVar);
        mv.visitInsn(SWAP);
        BytecodeHelper.pushConstant(mv, i);
        mv.visitInsn(SWAP);
        mv.visitInsn(AASTORE);
        // stack: closure
    }

    // we don't need the closure any longer, so remove it
    mv.visitInsn(POP);
    // we load the array and create a list from it
    mv.visitVarInsn(ALOAD, listArrayVar);
    createListMethod.call(mv);

    // remove the temporary variable to keep the
    // stack clean
    controller.getCompileStack().removeVar(listArrayVar);
    controller.getOperandStack().pop();
}