diff --git a/base/org.codehaus.groovy24/src/org/codehaus/groovy/classgen/asm/StatementWriter.java b/base/org.codehaus.groovy24/src/org/codehaus/groovy/classgen/asm/StatementWriter.java index a57e06c5d6..417dc76d3d 100644 --- a/base/org.codehaus.groovy24/src/org/codehaus/groovy/classgen/asm/StatementWriter.java +++ b/base/org.codehaus.groovy24/src/org/codehaus/groovy/classgen/asm/StatementWriter.java @@ -110,19 +110,19 @@ public void writeForStatement(ForStatement loop) { writeForInLoop(loop); } } - + protected void writeIteratorHasNext(MethodVisitor mv) { iteratorHasNextMethod.call(mv); } - + protected void writeIteratorNext(MethodVisitor mv) { iteratorNextMethod.call(mv); } - + protected void writeForInLoop(ForStatement loop) { controller.getAcg().onLineNumber(loop,"visitForLoop"); writeStatementLabel(loop); - + CompileStack compileStack = controller.getCompileStack(); MethodVisitor mv = controller.getMethodVisitor(); OperandStack operandStack = controller.getOperandStack(); @@ -221,7 +221,7 @@ protected void writeForLoopWithClosureList(ForStatement loop) { controller.getCompileStack().pop(); controller.getCompileStack().pop(); } - + private void visitExpressionOrStatement(Object o) { if (o == EmptyExpression.INSTANCE) return; if (o instanceof Expression) { @@ -258,7 +258,7 @@ public void writeWhileLoop(WhileStatement loop) { } } - if(!boolHandled) { + if (!boolHandled) { bool.visit(controller.getAcg()); controller.getOperandStack().jump(IFEQ, breakLabel); } @@ -268,7 +268,7 @@ public void writeWhileLoop(WhileStatement loop) { mv.visitJumpInsn(GOTO, continueLabel); mv.visitLabel(breakLabel); - controller.getCompileStack().pop(); + controller.getCompileStack().pop(); } public void writeDoWhileLoop(DoWhileStatement loop) { @@ -315,25 +315,25 @@ public void writeIfElse(IfStatement ifElse) { 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); - } + } } 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(); + Statement finallyStatement = statement.getFinallyStatement(); // start try block, label needed for exception table Label tryStart = new Label(); @@ -384,11 +384,10 @@ public void writeTryCatchFinally(TryCatchStatement statement) { compileStack.writeExceptionTable(tryBlock, catchStart, exceptionTypeInternalName); } - // Label used to handle exceptions in catches and regularly - // visited finals. + // 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 + // 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); @@ -401,7 +400,6 @@ public void writeTryCatchFinally(TryCatchStatement statement) { // start finally mv.visitLabel(finallyStart); finallyStatement.visit(controller.getAcg()); - mv.visitInsn(NOP); //** // goto after all-catching block Label skipCatchAll = new Label(); @@ -409,10 +407,15 @@ public void writeTryCatchFinally(TryCatchStatement statement) { // start a block catching any Exception mv.visitLabel(catchAny); - //store exception - //TODO: maybe define a Throwable and use it here instead of Object + // store exception + // TODO: maybe define a Throwable and use it here instead of Object operandStack.push(ClassHelper.OBJECT_TYPE); - final int anyExceptionIndex = compileStack.defineTemporaryVariable("exception", true); + 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()); @@ -423,17 +426,17 @@ public void writeTryCatchFinally(TryCatchStatement statement) { mv.visitLabel(skipCatchAll); compileStack.removeVar(anyExceptionIndex); } - - private BlockRecorder makeBlockRecorder(final Statement finallyStatement) { + + private BlockRecorder makeBlockRecorder(Statement finallyStatement) { final BlockRecorder block = new BlockRecorder(); - Runnable tryRunner = new Runnable() { + block.excludedStatement = new Runnable() { + @Override public void run() { controller.getCompileStack().pushBlockRecorderVisit(block); finallyStatement.visit(controller.getAcg()); controller.getCompileStack().popBlockRecorderVisit(block); } }; - block.excludedStatement = tryRunner; controller.getCompileStack().pushBlockRecorder(block); return block; } @@ -467,19 +470,19 @@ public void writeSwitch(SwitchStatement statement) { controller.getMethodVisitor().visitLabel(breakLabel); controller.getCompileStack().removeVar(switchVariableIndex); - controller.getCompileStack().pop(); + controller.getCompileStack().pop(); } - + protected void writeCaseStatement( CaseStatement statement, int switchVariableIndex, - Label thisLabel, Label nextLabel) + Label thisLabel, Label nextLabel) { 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); @@ -544,6 +547,7 @@ public void writeSynchronized(SynchronizedStatement statement) { mv.visitInsn(NOP); Runnable finallyPart = new Runnable() { + @Override public void run() { mv.visitVarInsn(ALOAD, index); mv.visitInsn(MONITOREXIT); @@ -584,7 +588,7 @@ public void writeThrow(ThrowStatement statement) { // we should infer the type of the exception from the expression mv.visitTypeInsn(CHECKCAST, "java/lang/Throwable"); mv.visitInsn(ATHROW); - + controller.getOperandStack().remove(1); } diff --git a/base/org.codehaus.groovy25/src/org/codehaus/groovy/classgen/asm/StatementWriter.java b/base/org.codehaus.groovy25/src/org/codehaus/groovy/classgen/asm/StatementWriter.java index a57e06c5d6..417dc76d3d 100644 --- a/base/org.codehaus.groovy25/src/org/codehaus/groovy/classgen/asm/StatementWriter.java +++ b/base/org.codehaus.groovy25/src/org/codehaus/groovy/classgen/asm/StatementWriter.java @@ -110,19 +110,19 @@ public void writeForStatement(ForStatement loop) { writeForInLoop(loop); } } - + protected void writeIteratorHasNext(MethodVisitor mv) { iteratorHasNextMethod.call(mv); } - + protected void writeIteratorNext(MethodVisitor mv) { iteratorNextMethod.call(mv); } - + protected void writeForInLoop(ForStatement loop) { controller.getAcg().onLineNumber(loop,"visitForLoop"); writeStatementLabel(loop); - + CompileStack compileStack = controller.getCompileStack(); MethodVisitor mv = controller.getMethodVisitor(); OperandStack operandStack = controller.getOperandStack(); @@ -221,7 +221,7 @@ protected void writeForLoopWithClosureList(ForStatement loop) { controller.getCompileStack().pop(); controller.getCompileStack().pop(); } - + private void visitExpressionOrStatement(Object o) { if (o == EmptyExpression.INSTANCE) return; if (o instanceof Expression) { @@ -258,7 +258,7 @@ public void writeWhileLoop(WhileStatement loop) { } } - if(!boolHandled) { + if (!boolHandled) { bool.visit(controller.getAcg()); controller.getOperandStack().jump(IFEQ, breakLabel); } @@ -268,7 +268,7 @@ public void writeWhileLoop(WhileStatement loop) { mv.visitJumpInsn(GOTO, continueLabel); mv.visitLabel(breakLabel); - controller.getCompileStack().pop(); + controller.getCompileStack().pop(); } public void writeDoWhileLoop(DoWhileStatement loop) { @@ -315,25 +315,25 @@ public void writeIfElse(IfStatement ifElse) { 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); - } + } } 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(); + Statement finallyStatement = statement.getFinallyStatement(); // start try block, label needed for exception table Label tryStart = new Label(); @@ -384,11 +384,10 @@ public void writeTryCatchFinally(TryCatchStatement statement) { compileStack.writeExceptionTable(tryBlock, catchStart, exceptionTypeInternalName); } - // Label used to handle exceptions in catches and regularly - // visited finals. + // 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 + // 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); @@ -401,7 +400,6 @@ public void writeTryCatchFinally(TryCatchStatement statement) { // start finally mv.visitLabel(finallyStart); finallyStatement.visit(controller.getAcg()); - mv.visitInsn(NOP); //** // goto after all-catching block Label skipCatchAll = new Label(); @@ -409,10 +407,15 @@ public void writeTryCatchFinally(TryCatchStatement statement) { // start a block catching any Exception mv.visitLabel(catchAny); - //store exception - //TODO: maybe define a Throwable and use it here instead of Object + // store exception + // TODO: maybe define a Throwable and use it here instead of Object operandStack.push(ClassHelper.OBJECT_TYPE); - final int anyExceptionIndex = compileStack.defineTemporaryVariable("exception", true); + 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()); @@ -423,17 +426,17 @@ public void writeTryCatchFinally(TryCatchStatement statement) { mv.visitLabel(skipCatchAll); compileStack.removeVar(anyExceptionIndex); } - - private BlockRecorder makeBlockRecorder(final Statement finallyStatement) { + + private BlockRecorder makeBlockRecorder(Statement finallyStatement) { final BlockRecorder block = new BlockRecorder(); - Runnable tryRunner = new Runnable() { + block.excludedStatement = new Runnable() { + @Override public void run() { controller.getCompileStack().pushBlockRecorderVisit(block); finallyStatement.visit(controller.getAcg()); controller.getCompileStack().popBlockRecorderVisit(block); } }; - block.excludedStatement = tryRunner; controller.getCompileStack().pushBlockRecorder(block); return block; } @@ -467,19 +470,19 @@ public void writeSwitch(SwitchStatement statement) { controller.getMethodVisitor().visitLabel(breakLabel); controller.getCompileStack().removeVar(switchVariableIndex); - controller.getCompileStack().pop(); + controller.getCompileStack().pop(); } - + protected void writeCaseStatement( CaseStatement statement, int switchVariableIndex, - Label thisLabel, Label nextLabel) + Label thisLabel, Label nextLabel) { 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); @@ -544,6 +547,7 @@ public void writeSynchronized(SynchronizedStatement statement) { mv.visitInsn(NOP); Runnable finallyPart = new Runnable() { + @Override public void run() { mv.visitVarInsn(ALOAD, index); mv.visitInsn(MONITOREXIT); @@ -584,7 +588,7 @@ public void writeThrow(ThrowStatement statement) { // we should infer the type of the exception from the expression mv.visitTypeInsn(CHECKCAST, "java/lang/Throwable"); mv.visitInsn(ATHROW); - + controller.getOperandStack().remove(1); } diff --git a/base/org.codehaus.groovy30/src/org/codehaus/groovy/classgen/asm/StatementWriter.java b/base/org.codehaus.groovy30/src/org/codehaus/groovy/classgen/asm/StatementWriter.java index e822798d67..d660b0d3f1 100644 --- a/base/org.codehaus.groovy30/src/org/codehaus/groovy/classgen/asm/StatementWriter.java +++ b/base/org.codehaus.groovy30/src/org/codehaus/groovy/classgen/asm/StatementWriter.java @@ -110,19 +110,19 @@ public void writeForStatement(ForStatement loop) { writeForInLoop(loop); } } - + protected void writeIteratorHasNext(MethodVisitor mv) { iteratorHasNextMethod.call(mv); } - + protected void writeIteratorNext(MethodVisitor mv) { iteratorNextMethod.call(mv); } - + protected void writeForInLoop(ForStatement loop) { controller.getAcg().onLineNumber(loop,"visitForLoop"); writeStatementLabel(loop); - + CompileStack compileStack = controller.getCompileStack(); MethodVisitor mv = controller.getMethodVisitor(); OperandStack operandStack = controller.getOperandStack(); @@ -229,7 +229,7 @@ protected void writeForLoopWithClosureList(ForStatement loop) { controller.getCompileStack().pop(); controller.getCompileStack().pop(); } - + private void visitExpressionOrStatement(Object o) { if (o == EmptyExpression.INSTANCE) return; if (o instanceof Expression) { @@ -255,7 +255,7 @@ private void visitConditionOfLoopingStatement(BooleanExpression bool, Label brea } } - if(!boolHandled) { + if (!boolHandled) { bool.visit(controller.getAcg()); controller.getOperandStack().jump(IFEQ, breakLabel); } @@ -279,7 +279,7 @@ public void writeWhileLoop(WhileStatement loop) { mv.visitJumpInsn(GOTO, continueLabel); mv.visitLabel(breakLabel); - controller.getCompileStack().pop(); + controller.getCompileStack().pop(); } public void writeDoWhileLoop(DoWhileStatement loop) { @@ -327,25 +327,25 @@ public void writeIfElse(IfStatement ifElse) { 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); - } + } } 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(); + Statement finallyStatement = statement.getFinallyStatement(); // start try block, label needed for exception table Label tryStart = new Label(); @@ -396,11 +396,10 @@ public void writeTryCatchFinally(TryCatchStatement statement) { compileStack.writeExceptionTable(tryBlock, catchStart, exceptionTypeInternalName); } - // Label used to handle exceptions in catches and regularly - // visited finals. + // 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 + // 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); @@ -413,7 +412,6 @@ public void writeTryCatchFinally(TryCatchStatement statement) { // start finally mv.visitLabel(finallyStart); finallyStatement.visit(controller.getAcg()); - mv.visitInsn(NOP); //** // goto after all-catching block Label skipCatchAll = new Label(); @@ -421,10 +419,15 @@ public void writeTryCatchFinally(TryCatchStatement statement) { // start a block catching any Exception mv.visitLabel(catchAny); - //store exception - //TODO: maybe define a Throwable and use it here instead of Object + // store exception + // TODO: maybe define a Throwable and use it here instead of Object operandStack.push(ClassHelper.OBJECT_TYPE); - final int anyExceptionIndex = compileStack.defineTemporaryVariable("exception", true); + 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()); @@ -435,17 +438,17 @@ public void writeTryCatchFinally(TryCatchStatement statement) { mv.visitLabel(skipCatchAll); compileStack.removeVar(anyExceptionIndex); } - - private BlockRecorder makeBlockRecorder(final Statement finallyStatement) { + + private BlockRecorder makeBlockRecorder(Statement finallyStatement) { final BlockRecorder block = new BlockRecorder(); - Runnable tryRunner = new Runnable() { + block.excludedStatement = new Runnable() { + @Override public void run() { controller.getCompileStack().pushBlockRecorderVisit(block); finallyStatement.visit(controller.getAcg()); controller.getCompileStack().popBlockRecorderVisit(block); } }; - block.excludedStatement = tryRunner; controller.getCompileStack().pushBlockRecorder(block); return block; } @@ -479,19 +482,19 @@ public void writeSwitch(SwitchStatement statement) { controller.getMethodVisitor().visitLabel(breakLabel); controller.getCompileStack().removeVar(switchVariableIndex); - controller.getCompileStack().pop(); + controller.getCompileStack().pop(); } - + protected void writeCaseStatement( CaseStatement statement, int switchVariableIndex, - Label thisLabel, Label nextLabel) + Label thisLabel, Label nextLabel) { 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); @@ -556,6 +559,7 @@ public void writeSynchronized(SynchronizedStatement statement) { mv.visitInsn(NOP); Runnable finallyPart = new Runnable() { + @Override public void run() { mv.visitVarInsn(ALOAD, index); mv.visitInsn(MONITOREXIT); @@ -596,7 +600,7 @@ public void writeThrow(ThrowStatement statement) { // we should infer the type of the exception from the expression mv.visitTypeInsn(CHECKCAST, "java/lang/Throwable"); mv.visitInsn(ATHROW); - + controller.getOperandStack().remove(1); }