You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@groovy.apache.org by su...@apache.org on 2020/09/30 16:29:02 UTC

[groovy] 01/01: Minor refactoring: remove duplicated code for bytecode generation of loop statement

This is an automated email from the ASF dual-hosted git repository.

sunlan pushed a commit to branch danielsun/tweak-loop
in repository https://gitbox.apache.org/repos/asf/groovy.git

commit 4e677d488cea1edc70dbd457f2766cd9bc92aed3
Author: Daniel Sun <su...@apache.org>
AuthorDate: Thu Oct 1 00:28:54 2020 +0800

    Minor refactoring: remove duplicated code for bytecode generation of loop statement
---
 .../groovy/classgen/asm/StatementWriter.java       | 17 +++++--
 .../asm/sc/StaticTypesStatementWriter.java         | 53 ++++++----------------
 2 files changed, 25 insertions(+), 45 deletions(-)

diff --git a/src/main/java/org/codehaus/groovy/classgen/asm/StatementWriter.java b/src/main/java/org/codehaus/groovy/classgen/asm/StatementWriter.java
index e452b9e..d0d703d 100644
--- a/src/main/java/org/codehaus/groovy/classgen/asm/StatementWriter.java
+++ b/src/main/java/org/codehaus/groovy/classgen/asm/StatementWriter.java
@@ -127,19 +127,27 @@ public class StatementWriter {
         writeStatementLabel(statement);
 
         CompileStack compileStack = controller.getCompileStack();
-        MethodVisitor mv = controller.getMethodVisitor();
         OperandStack operandStack = controller.getOperandStack();
 
         compileStack.pushLoop(statement.getVariableScope(), statement.getStatementLabels());
 
-        // declare the loop counter
-        BytecodeVariable variable = compileStack.defineVariable(statement.getVariable(), false);
-
         // then get the iterator and generate the loop control
         MethodCallExpression iterator = new MethodCallExpression(statement.getCollectionExpression(), "iterator", new ArgumentListExpression());
         iterator.visit(controller.getAcg());
         operandStack.doGroovyCast(ClassHelper.Iterator_TYPE);
 
+        writeForInLoopControlAndBlock(statement);
+        compileStack.pop();
+    }
+
+    protected void writeForInLoopControlAndBlock(ForStatement statement) {
+        CompileStack compileStack = controller.getCompileStack();
+        MethodVisitor mv = controller.getMethodVisitor();
+        OperandStack operandStack = controller.getOperandStack();
+
+        // declare the loop counter
+        BytecodeVariable variable = compileStack.defineVariable(statement.getVariable(), false);
+
         int iteratorIndex = compileStack.defineTemporaryVariable("iterator", ClassHelper.Iterator_TYPE, true);
         Label continueLabel = compileStack.getContinueLabel();
         Label breakLabel = compileStack.getBreakLabel();
@@ -162,7 +170,6 @@ public class StatementWriter {
         mv.visitLabel(breakLabel);
 
         compileStack.removeVar(iteratorIndex);
-        compileStack.pop();
     }
 
     protected void writeIteratorHasNext(final MethodVisitor mv) {
diff --git a/src/main/java/org/codehaus/groovy/classgen/asm/sc/StaticTypesStatementWriter.java b/src/main/java/org/codehaus/groovy/classgen/asm/sc/StaticTypesStatementWriter.java
index 8165224..01e0928 100644
--- a/src/main/java/org/codehaus/groovy/classgen/asm/sc/StaticTypesStatementWriter.java
+++ b/src/main/java/org/codehaus/groovy/classgen/asm/sc/StaticTypesStatementWriter.java
@@ -99,9 +99,9 @@ public class StaticTypesStatementWriter extends StatementWriter {
         if (collectionType.isArray() && loopVariable.getOriginType().equals(collectionType.getComponentType())) {
             writeOptimizedForEachLoop(compileStack, operandStack, mv, loop, collectionExpression, collectionType, loopVariable);
         } else if (ENUMERATION_CLASSNODE.equals(collectionType)) {
-            writeEnumerationBasedForEachLoop(compileStack, operandStack, mv, loop, collectionExpression, collectionType, loopVariable);
+            writeEnumerationBasedForEachLoop(loop, collectionExpression, collectionType);
         } else {
-            writeIteratorBasedForEachLoop(compileStack, operandStack, mv, loop, collectionExpression, collectionType, loopVariable);
+            writeIteratorBasedForEachLoop(loop, collectionExpression, collectionType);
         }
         operandStack.popDownTo(size);
         compileStack.pop();
@@ -206,15 +206,9 @@ public class StaticTypesStatementWriter extends StatementWriter {
     }
 
     private void writeIteratorBasedForEachLoop(
-            CompileStack compileStack,
-            OperandStack operandStack,
-            MethodVisitor mv,
             ForStatement loop,
             Expression collectionExpression,
-            ClassNode collectionType,
-            Parameter loopVariable) {
-        // Declare the loop counter.
-        BytecodeVariable variable = compileStack.defineVariable(loopVariable, false);
+            ClassNode collectionType) {
 
         if (StaticTypeCheckingSupport.implementsInterfaceOrIsSubclassOf(collectionType, ITERABLE_CLASSNODE)) {
             MethodCallExpression iterator = new MethodCallExpression(collectionExpression, "iterator", new ArgumentListExpression());
@@ -223,46 +217,25 @@ public class StaticTypesStatementWriter extends StatementWriter {
             iterator.visit(controller.getAcg());
         } else {
             collectionExpression.visit(controller.getAcg());
-            mv.visitMethodInsn(INVOKESTATIC, "org/codehaus/groovy/runtime/DefaultGroovyMethods", "iterator", "(Ljava/lang/Object;)Ljava/util/Iterator;", false);
-            operandStack.replace(ClassHelper.Iterator_TYPE);
+            controller.getMethodVisitor().visitMethodInsn(INVOKESTATIC, "org/codehaus/groovy/runtime/DefaultGroovyMethods", "iterator", "(Ljava/lang/Object;)Ljava/util/Iterator;", false);
+            controller.getOperandStack().replace(ClassHelper.Iterator_TYPE);
         }
 
         // Then get the iterator and generate the loop control
-
-        int iteratorIdx = compileStack.defineTemporaryVariable("iterator", ClassHelper.Iterator_TYPE, true);
-
-        Label continueLabel = compileStack.getContinueLabel();
-        Label breakLabel = compileStack.getBreakLabel();
-
-        mv.visitLabel(continueLabel);
-        mv.visitVarInsn(ALOAD, iteratorIdx);
-        writeIteratorHasNext(mv);
-        // note: ifeq tests for ==0, a boolean is 0 if it is false
-        mv.visitJumpInsn(IFEQ, breakLabel);
-
-        mv.visitVarInsn(ALOAD, iteratorIdx);
-        writeIteratorNext(mv);
-        operandStack.push(ClassHelper.OBJECT_TYPE);
-        operandStack.storeVar(variable);
-
-        // Generate the loop body
-        loop.getLoopBlock().visit(controller.getAcg());
-
-        mv.visitJumpInsn(GOTO, continueLabel);
-        mv.visitLabel(breakLabel);
-        compileStack.removeVar(iteratorIdx);
+        writeForInLoopControlAndBlock(loop);
     }
 
     private void writeEnumerationBasedForEachLoop(
-            CompileStack compileStack,
-            OperandStack operandStack,
-            MethodVisitor mv,
             ForStatement loop,
             Expression collectionExpression,
-            ClassNode collectionType,
-            Parameter loopVariable) {
+            ClassNode collectionType) {
+
+        CompileStack compileStack = controller.getCompileStack();
+        MethodVisitor mv = controller.getMethodVisitor();
+        OperandStack operandStack = controller.getOperandStack();
+
         // Declare the loop counter.
-        BytecodeVariable variable = compileStack.defineVariable(loopVariable, false);
+        BytecodeVariable variable = compileStack.defineVariable(loop.getVariable(), false);
 
         collectionExpression.visit(controller.getAcg());