Search in sources :

Example 1 with BlockRecorder

use of org.codehaus.groovy.classgen.asm.CompileStack.BlockRecorder in project groovy by apache.

the class StatementWriter method writeSynchronized.

public void writeSynchronized(SynchronizedStatement statement) {
    controller.getAcg().onLineNumber(statement, "visitSynchronizedStatement");
    writeStatementLabel(statement);
    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 = new Runnable() {

        public void run() {
            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);
    //pop fb
    compileStack.pop();
    finallyPart.run();
    mv.visitJumpInsn(GOTO, synchronizedEnd);
    mv.visitLabel(catchAll);
    finallyPart.run();
    mv.visitInsn(ATHROW);
    mv.visitLabel(synchronizedEnd);
    compileStack.removeVar(index);
}
Also used : BlockRecorder(org.codehaus.groovy.classgen.asm.CompileStack.BlockRecorder) Label(org.objectweb.asm.Label) MethodVisitor(org.objectweb.asm.MethodVisitor)

Example 2 with BlockRecorder

use of org.codehaus.groovy.classgen.asm.CompileStack.BlockRecorder in project groovy-core by groovy.

the class StatementWriter method writeTryCatchFinally.

public void writeTryCatchFinally(TryCatchStatement statement) {
    controller.getAcg().onLineNumber(statement, "visitTryCatchFinally");
    writeStatementLabel(statement);
    MethodVisitor mv = controller.getMethodVisitor();
    CompileStack compileStack = controller.getCompileStack();
    OperandStack operandStack = controller.getOperandStack();
    Statement tryStatement = statement.getTryStatement();
    final 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);
    }
    // Label 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());
    // **
    mv.visitInsn(NOP);
    // 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);
    finallyStatement.visit(controller.getAcg());
    // load the exception and rethrow it
    mv.visitVarInsn(ALOAD, anyExceptionIndex);
    mv.visitInsn(ATHROW);
    mv.visitLabel(skipCatchAll);
}
Also used : BlockRecorder(org.codehaus.groovy.classgen.asm.CompileStack.BlockRecorder) ClassNode(org.codehaus.groovy.ast.ClassNode) CatchStatement(org.codehaus.groovy.ast.stmt.CatchStatement) TryCatchStatement(org.codehaus.groovy.ast.stmt.TryCatchStatement) Statement(org.codehaus.groovy.ast.stmt.Statement) WhileStatement(org.codehaus.groovy.ast.stmt.WhileStatement) ExpressionStatement(org.codehaus.groovy.ast.stmt.ExpressionStatement) ThrowStatement(org.codehaus.groovy.ast.stmt.ThrowStatement) CaseStatement(org.codehaus.groovy.ast.stmt.CaseStatement) DoWhileStatement(org.codehaus.groovy.ast.stmt.DoWhileStatement) ContinueStatement(org.codehaus.groovy.ast.stmt.ContinueStatement) ForStatement(org.codehaus.groovy.ast.stmt.ForStatement) BreakStatement(org.codehaus.groovy.ast.stmt.BreakStatement) ReturnStatement(org.codehaus.groovy.ast.stmt.ReturnStatement) CatchStatement(org.codehaus.groovy.ast.stmt.CatchStatement) SynchronizedStatement(org.codehaus.groovy.ast.stmt.SynchronizedStatement) EmptyStatement(org.codehaus.groovy.ast.stmt.EmptyStatement) SwitchStatement(org.codehaus.groovy.ast.stmt.SwitchStatement) IfStatement(org.codehaus.groovy.ast.stmt.IfStatement) AssertStatement(org.codehaus.groovy.ast.stmt.AssertStatement) BlockStatement(org.codehaus.groovy.ast.stmt.BlockStatement) TryCatchStatement(org.codehaus.groovy.ast.stmt.TryCatchStatement) Label(org.objectweb.asm.Label) Parameter(org.codehaus.groovy.ast.Parameter) MethodVisitor(org.objectweb.asm.MethodVisitor)

Example 3 with BlockRecorder

use of org.codehaus.groovy.classgen.asm.CompileStack.BlockRecorder in project groovy-core by groovy.

the class StatementWriter method makeBlockRecorder.

private BlockRecorder makeBlockRecorder(final Statement finallyStatement) {
    final BlockRecorder block = new BlockRecorder();
    Runnable tryRunner = new Runnable() {

        public void run() {
            controller.getCompileStack().pushBlockRecorderVisit(block);
            finallyStatement.visit(controller.getAcg());
            controller.getCompileStack().popBlockRecorderVisit(block);
        }
    };
    block.excludedStatement = tryRunner;
    controller.getCompileStack().pushBlockRecorder(block);
    return block;
}
Also used : BlockRecorder(org.codehaus.groovy.classgen.asm.CompileStack.BlockRecorder)

Example 4 with BlockRecorder

use of org.codehaus.groovy.classgen.asm.CompileStack.BlockRecorder in project groovy-core by groovy.

the class StatementWriter method writeSynchronized.

public void writeSynchronized(SynchronizedStatement statement) {
    controller.getAcg().onLineNumber(statement, "visitSynchronizedStatement");
    writeStatementLabel(statement);
    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 = new Runnable() {

        public void run() {
            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);
    // pop fb
    compileStack.pop();
    finallyPart.run();
    mv.visitJumpInsn(GOTO, synchronizedEnd);
    mv.visitLabel(catchAll);
    finallyPart.run();
    mv.visitInsn(ATHROW);
    mv.visitLabel(synchronizedEnd);
}
Also used : BlockRecorder(org.codehaus.groovy.classgen.asm.CompileStack.BlockRecorder) Label(org.objectweb.asm.Label) MethodVisitor(org.objectweb.asm.MethodVisitor)

Example 5 with BlockRecorder

use of org.codehaus.groovy.classgen.asm.CompileStack.BlockRecorder in project groovy by apache.

the class StatementWriter method makeBlockRecorder.

private BlockRecorder makeBlockRecorder(final Statement finallyStatement) {
    final BlockRecorder block = new BlockRecorder();
    Runnable tryRunner = new Runnable() {

        public void run() {
            controller.getCompileStack().pushBlockRecorderVisit(block);
            finallyStatement.visit(controller.getAcg());
            controller.getCompileStack().popBlockRecorderVisit(block);
        }
    };
    block.excludedStatement = tryRunner;
    controller.getCompileStack().pushBlockRecorder(block);
    return block;
}
Also used : BlockRecorder(org.codehaus.groovy.classgen.asm.CompileStack.BlockRecorder)

Aggregations

BlockRecorder (org.codehaus.groovy.classgen.asm.CompileStack.BlockRecorder)6 Label (org.objectweb.asm.Label)4 MethodVisitor (org.objectweb.asm.MethodVisitor)4 ClassNode (org.codehaus.groovy.ast.ClassNode)2 Parameter (org.codehaus.groovy.ast.Parameter)2 AssertStatement (org.codehaus.groovy.ast.stmt.AssertStatement)2 BlockStatement (org.codehaus.groovy.ast.stmt.BlockStatement)2 BreakStatement (org.codehaus.groovy.ast.stmt.BreakStatement)2 CaseStatement (org.codehaus.groovy.ast.stmt.CaseStatement)2 CatchStatement (org.codehaus.groovy.ast.stmt.CatchStatement)2 ContinueStatement (org.codehaus.groovy.ast.stmt.ContinueStatement)2 DoWhileStatement (org.codehaus.groovy.ast.stmt.DoWhileStatement)2 EmptyStatement (org.codehaus.groovy.ast.stmt.EmptyStatement)2 ExpressionStatement (org.codehaus.groovy.ast.stmt.ExpressionStatement)2 ForStatement (org.codehaus.groovy.ast.stmt.ForStatement)2 IfStatement (org.codehaus.groovy.ast.stmt.IfStatement)2 ReturnStatement (org.codehaus.groovy.ast.stmt.ReturnStatement)2 Statement (org.codehaus.groovy.ast.stmt.Statement)2 SwitchStatement (org.codehaus.groovy.ast.stmt.SwitchStatement)2 SynchronizedStatement (org.codehaus.groovy.ast.stmt.SynchronizedStatement)2