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());