groovy-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From sun...@apache.org
Subject groovy git commit: GROOVY-8229: nested try-catch-finally handling inside Closures generates wrong bytecode
Date Fri, 16 Jun 2017 00:12:04 GMT
Repository: groovy
Updated Branches:
  refs/heads/GROOVY_2_6_X 931992412 -> 9098baa91


GROOVY-8229: nested try-catch-finally handling inside Closures generates wrong bytecode

(cherry picked from commit 0406787)


Project: http://git-wip-us.apache.org/repos/asf/groovy/repo
Commit: http://git-wip-us.apache.org/repos/asf/groovy/commit/9098baa9
Tree: http://git-wip-us.apache.org/repos/asf/groovy/tree/9098baa9
Diff: http://git-wip-us.apache.org/repos/asf/groovy/diff/9098baa9

Branch: refs/heads/GROOVY_2_6_X
Commit: 9098baa91409f293acc7fc4efb351c78f570fa13
Parents: 9319924
Author: sunlan <sunlan@apache.org>
Authored: Thu Jun 15 22:46:21 2017 +0800
Committer: sunlan <sunlan@apache.org>
Committed: Fri Jun 16 08:11:52 2017 +0800

----------------------------------------------------------------------
 .../groovy/classgen/asm/CompileStack.java       | 28 +++++++-----
 src/test/groovy/bugs/Groovy8229Bug.groovy       | 46 ++++++++++++++++++++
 2 files changed, 63 insertions(+), 11 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/groovy/blob/9098baa9/src/main/org/codehaus/groovy/classgen/asm/CompileStack.java
----------------------------------------------------------------------
diff --git a/src/main/org/codehaus/groovy/classgen/asm/CompileStack.java b/src/main/org/codehaus/groovy/classgen/asm/CompileStack.java
index ba856bc..2d7d8b1 100644
--- a/src/main/org/codehaus/groovy/classgen/asm/CompileStack.java
+++ b/src/main/org/codehaus/groovy/classgen/asm/CompileStack.java
@@ -29,7 +29,13 @@ import org.objectweb.asm.Label;
 import org.objectweb.asm.MethodVisitor;
 import org.objectweb.asm.Opcodes;
 
-import java.util.*;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.ListIterator;
+import java.util.Map;
 
 /**
  * This class is a helper for AsmClassGenerator. It manages
@@ -567,7 +573,7 @@ public class CompileStack implements Opcodes {
         return answer;
     }
 
-    private void makeLocalVariablesOffset(Parameter[] paras,boolean isInStaticContext) {
+    private void makeLocalVariablesOffset(Parameter[] paras, boolean isInStaticContext) {
         resetVariableIndex(isInStaticContext);
 
         for (Parameter para : paras) {
@@ -633,11 +639,11 @@ public class CompileStack implements Opcodes {
 
     private static void pushInitValue(ClassNode type, MethodVisitor mv) {
         if (ClassHelper.isPrimitiveType(type)) {
-            if (type==ClassHelper.long_TYPE) {
+            if (type== ClassHelper.long_TYPE) {
                 mv.visitInsn(LCONST_0);
-            } else if (type==ClassHelper.double_TYPE) {
+            } else if (type== ClassHelper.double_TYPE) {
                 mv.visitInsn(DCONST_0);
-            } else if (type==ClassHelper.float_TYPE) {
+            } else if (type== ClassHelper.float_TYPE) {
                 mv.visitInsn(FCONST_0);
             } else {
                 mv.visitLdcInsn(0);
@@ -706,7 +712,7 @@ public class CompileStack implements Opcodes {
      */
     private void makeNextVariableID(ClassNode type, boolean useReferenceDirectly) {
         currentVariableIndex = nextVariableIndex;
-        if ((type==ClassHelper.long_TYPE || type==ClassHelper.double_TYPE) && !useReferenceDirectly)
{
+        if ((type== ClassHelper.long_TYPE || type== ClassHelper.double_TYPE) && !useReferenceDirectly)
{
             nextVariableIndex++;
         }
         nextVariableIndex++;
@@ -767,10 +773,12 @@ public class CompileStack implements Opcodes {
         applyBlockRecorder(blocks);
     }
 
+
     private void applyBlockRecorder(List<BlockRecorder> blocks) {
-        if (blocks.isEmpty() || blocks.size()==visitedBlocks.size()) return;
+        if (blocks.isEmpty() || blocks.size() == visitedBlocks.size()) return;
 
         MethodVisitor mv = controller.getMethodVisitor();
+        Label newStart = new Label();
 
         for (BlockRecorder fb : blocks) {
             if (visitedBlocks.contains(fb)) continue;
@@ -785,13 +793,11 @@ public class CompileStack implements Opcodes {
             // here to avoid double visiting of finally statements
             fb.excludedStatement.run();
 
-            Label newStart = new Label();
             fb.startRange(newStart);
-
-            mv.visitInsn(NOP);
-            mv.visitLabel(newStart);
         }
 
+        mv.visitInsn(NOP);
+        mv.visitLabel(newStart);
     }
 
     public void applyBlockRecorder() {

http://git-wip-us.apache.org/repos/asf/groovy/blob/9098baa9/src/test/groovy/bugs/Groovy8229Bug.groovy
----------------------------------------------------------------------
diff --git a/src/test/groovy/bugs/Groovy8229Bug.groovy b/src/test/groovy/bugs/Groovy8229Bug.groovy
new file mode 100644
index 0000000..eac96a2
--- /dev/null
+++ b/src/test/groovy/bugs/Groovy8229Bug.groovy
@@ -0,0 +1,46 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+package groovy.bugs
+
+class Groovy8229Bug extends GroovyTestCase {
+    void testFinallyBlockInClosureCalledOnce() {
+        assert shouldFail(
+                '''
+                class TryCatchProblem {
+                    static int count = 0
+                    static void main(args) {
+                        def cl = {
+                            try {
+                                try {
+                                    assert count == 0
+                                } catch (Throwable e) { }
+                            } finally {
+                                check()
+                            }
+                        }
+                        cl()
+                    }
+                    static void check() {
+                        throw new UnsupportedOperationException("check call count: ${++count}")
+                    }
+                }
+            '''
+        ) == 'check call count: 1'
+    }
+}


Mime
View raw message