This is an automated email from the ASF dual-hosted git repository.
emilles pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/groovy.git
The following commit(s) were added to refs/heads/master by this push:
new 2f890c1dbf reduce dynamic variables
2f890c1dbf is described below
commit 2f890c1dbff956834100ebaa81e01567db339af4
Author: Eric Milles <[email protected]>
AuthorDate: Sat Feb 14 21:36:08 2026 -0600
reduce dynamic variables
---
.../groovy/ast/tools/ConstructorNodeUtils.java | 18 +++++------
.../groovy/classgen/AsmClassGenerator.java | 2 +-
.../groovy/classgen/asm/AssertionWriter.java | 13 +++++---
.../groovy/classgen/asm/BytecodeHelper.java | 36 +++++++++-------------
.../groovy/classgen/asm/BytecodeVariable.java | 5 +--
.../codehaus/groovy/classgen/asm/CompileStack.java | 4 +--
.../groovy/classgen/asm/StatementWriter.java | 2 +-
.../transform/AutoCloneASTTransformation.java | 14 ++++-----
.../EqualsAndHashCodeASTTransformation.java | 4 +--
.../groovy/transform/LazyASTTransformation.java | 24 ++++++++-------
.../transform/ToStringASTTransformation.java | 12 ++++----
11 files changed, 68 insertions(+), 66 deletions(-)
diff --git
a/src/main/java/org/apache/groovy/ast/tools/ConstructorNodeUtils.java
b/src/main/java/org/apache/groovy/ast/tools/ConstructorNodeUtils.java
index dd263c974c..e663d5d912 100644
--- a/src/main/java/org/apache/groovy/ast/tools/ConstructorNodeUtils.java
+++ b/src/main/java/org/apache/groovy/ast/tools/ConstructorNodeUtils.java
@@ -37,7 +37,6 @@ import java.util.List;
import static java.util.stream.Collectors.toList;
import static org.apache.groovy.ast.tools.MethodCallUtils.appendS;
import static org.apache.groovy.ast.tools.MethodCallUtils.toStringX;
-import static org.codehaus.groovy.ast.ClassHelper.make;
import static org.codehaus.groovy.ast.tools.GeneralUtils.args;
import static org.codehaus.groovy.ast.tools.GeneralUtils.block;
import static org.codehaus.groovy.ast.tools.GeneralUtils.callX;
@@ -58,13 +57,14 @@ import static
org.codehaus.groovy.ast.tools.GeneralUtils.varX;
* Utility class for working with ConstructorNodes
*/
public class ConstructorNodeUtils {
- private static final ClassNode EXCEPTION =
make(IllegalArgumentException.class);
- private static final ClassNode IMMUTABLE_TYPE =
make(ImmutableASTTransformation.class);
- private static final ClassNode STRINGBUILDER_TYPE =
make(StringBuilder.class);
- private static final ClassNode INVOKER_TYPE = make(InvokerHelper.class);
private ConstructorNodeUtils() { }
+ private static final ClassNode EXCEPTION_TYPE =
ClassHelper.make(IllegalArgumentException.class);
+ private static final ClassNode IMMUTABLE_TYPE =
ClassHelper.make(ImmutableASTTransformation.class);
+ private static final ClassNode INVOKER_HELPER_TYPE =
ClassHelper.make(InvokerHelper.class);
+ private static final ClassNode STRING_BUILDER_TYPE =
ClassHelper.make(StringBuilder.class);
+
/**
* Return the first statement from the constructor code if it is a call to
super or this, otherwise null.
*
@@ -103,13 +103,13 @@ public class ConstructorNodeUtils {
MethodCallExpression isNameValid = callX(validNames, "contains",
varX(name));
isNameValid.setImplicitThis(false);
- Expression sb = localVarX("sb");
- Expression toString = pojo ? toStringX(sb) : callX(INVOKER_TYPE,
"toString", sb);
+ Expression sb = localVarX("sb", STRING_BUILDER_TYPE);
+ Expression toString = pojo ? toStringX(sb) :
callX(INVOKER_HELPER_TYPE, "toString", sb);
Statement errorBlock = block(
- declS(sb, ctorX(STRINGBUILDER_TYPE)),
+ declS(sb, ctorX(STRING_BUILDER_TYPE)),
appendS(sb, constX("Unknown named argument: ")),
appendS(sb, varX(name)),
- throwS(ctorX(EXCEPTION, toString))
+ throwS(ctorX(EXCEPTION_TYPE, toString))
);
return block(
diff --git a/src/main/java/org/codehaus/groovy/classgen/AsmClassGenerator.java
b/src/main/java/org/codehaus/groovy/classgen/AsmClassGenerator.java
index ef413fc294..a3a3ff0bdd 100644
--- a/src/main/java/org/codehaus/groovy/classgen/AsmClassGenerator.java
+++ b/src/main/java/org/codehaus/groovy/classgen/AsmClassGenerator.java
@@ -1892,7 +1892,7 @@ public class AsmClassGenerator extends ClassGenerator {
// in a temporary variable
BytecodeHelper.pushConstant(mv, size);
mv.visitTypeInsn(ANEWARRAY, "java/lang/Object");
- int listArrayVar =
controller.getCompileStack().defineTemporaryVariable("_listOfClosures", true);
+ int listArrayVar =
controller.getCompileStack().defineTemporaryVariable("_listOfClosures",
ClassHelper.OBJECT_TYPE.makeArray(), true);
// add curried versions
for (int i = 0; i < size; i += 1) {
diff --git
a/src/main/java/org/codehaus/groovy/classgen/asm/AssertionWriter.java
b/src/main/java/org/codehaus/groovy/classgen/asm/AssertionWriter.java
index 211998881e..cf9588bcb5 100644
--- a/src/main/java/org/codehaus/groovy/classgen/asm/AssertionWriter.java
+++ b/src/main/java/org/codehaus/groovy/classgen/asm/AssertionWriter.java
@@ -19,6 +19,7 @@
package org.codehaus.groovy.classgen.asm;
import org.codehaus.groovy.ast.ClassHelper;
+import org.codehaus.groovy.ast.ClassNode;
import org.codehaus.groovy.ast.expr.BinaryExpression;
import org.codehaus.groovy.ast.expr.BooleanExpression;
import org.codehaus.groovy.ast.expr.Expression;
@@ -27,6 +28,7 @@ import org.codehaus.groovy.ast.stmt.AssertStatement;
import org.codehaus.groovy.control.Janitor;
import org.codehaus.groovy.runtime.powerassert.SourceText;
import org.codehaus.groovy.runtime.powerassert.SourceTextNotAvailableException;
+import org.codehaus.groovy.runtime.powerassert.ValueRecorder;
import org.codehaus.groovy.syntax.Token;
import org.objectweb.asm.Label;
import org.objectweb.asm.MethodVisitor;
@@ -48,6 +50,9 @@ import static org.objectweb.asm.Opcodes.POP;
public class AssertionWriter {
+ private static final ClassNode STRING_BUILDER_TYPE =
ClassHelper.make(StringBuilder.class);
+ private static final ClassNode VALUE_RECORDER_TYPE =
ClassHelper.make(ValueRecorder.class);
+
private static class AssertionTracker {
int recorderIndex;
SourceText sourceText;
@@ -96,8 +101,8 @@ public class AssertionWriter {
mv.visitTypeInsn(NEW,
"org/codehaus/groovy/runtime/powerassert/ValueRecorder");
mv.visitInsn(DUP);
mv.visitMethodInsn(INVOKESPECIAL,
"org/codehaus/groovy/runtime/powerassert/ValueRecorder", "<init>", "()V",
false);
- operandStack.push(ClassHelper.OBJECT_TYPE); // TODO: maybe use
more specialized type here
- assertionTracker.recorderIndex =
compileStack.defineTemporaryVariable("recorder", true);
+ operandStack.push(VALUE_RECORDER_TYPE);
+ assertionTracker.recorderIndex =
compileStack.defineTemporaryVariable("recorder", VALUE_RECORDER_TYPE, true);
Label tryStart = new Label(), tryEnd = new Label();
mv.visitLabel(tryStart);
@@ -175,8 +180,8 @@ public class AssertionWriter {
mv.visitInsn(DUP);
mv.visitLdcInsn(expressionText + ". Values: ");
mv.visitMethodInsn(INVOKESPECIAL, "java/lang/StringBuilder",
"<init>", "(Ljava/lang/String;)V", false);
- operandStack.push(ClassHelper.OBJECT_TYPE); // TODO: maybe use
more special type StringBuilder here
- int tempIndex = compileStack.defineTemporaryVariable("assert",
true);
+ operandStack.push(STRING_BUILDER_TYPE);
+ int tempIndex = compileStack.defineTemporaryVariable("assert",
STRING_BUILDER_TYPE, true);
boolean first = true;
for (String name : names) {
diff --git a/src/main/java/org/codehaus/groovy/classgen/asm/BytecodeHelper.java
b/src/main/java/org/codehaus/groovy/classgen/asm/BytecodeHelper.java
index 8f292bca89..466a882a1f 100644
--- a/src/main/java/org/codehaus/groovy/classgen/asm/BytecodeHelper.java
+++ b/src/main/java/org/codehaus/groovy/classgen/asm/BytecodeHelper.java
@@ -476,16 +476,23 @@ public class BytecodeHelper {
ret.append(end);
}
- public static void doCast(MethodVisitor mv, ClassNode type) {
- if (isObjectType(type)) return;
+ public static void doCast(final MethodVisitor mv, final Class<?> type) {
+ if (type.isPrimitive() && type != Void.TYPE) {
+ unbox(mv, type);
+ } else if (type != Object.class) {
+ mv.visitTypeInsn(CHECKCAST, type.isArray()
+ ? BytecodeHelper.getTypeDescription(type)
+ : BytecodeHelper.getClassInternalName(type.getName()));
+ }
+ }
+
+ public static void doCast(final MethodVisitor mv, final ClassNode type) {
if (isPrimitiveType(type) && !isPrimitiveVoid(type)) {
unbox(mv, type);
- } else {
- mv.visitTypeInsn(
- CHECKCAST,
- type.isArray() ?
- BytecodeHelper.getTypeDescription(type) :
-
BytecodeHelper.getClassInternalName(type.getName()));
+ } else if (!isObjectType(type)) {
+ mv.visitTypeInsn(CHECKCAST, type.isArray()
+ ? BytecodeHelper.getTypeDescription(type)
+ : BytecodeHelper.getClassInternalName(type.getName()));
}
}
@@ -515,19 +522,6 @@ public class BytecodeHelper {
mv.visitMethodInsn(INVOKESTATIC, getClassInternalName(targetType),
"valueOf", "(" + getTypeDescription(sourceType) + ")" +
getTypeDescription(targetType), false);
}
- public static void doCast(MethodVisitor mv, Class type) {
- if (type == Object.class) return;
- if (type.isPrimitive() && type != Void.TYPE) {
- unbox(mv, type);
- } else {
- mv.visitTypeInsn(
- CHECKCAST,
- type.isArray() ?
- BytecodeHelper.getTypeDescription(type) :
-
BytecodeHelper.getClassInternalName(type.getName()));
- }
- }
-
/**
* Generates the bytecode to autobox the current value on the stack.
*/
diff --git
a/src/main/java/org/codehaus/groovy/classgen/asm/BytecodeVariable.java
b/src/main/java/org/codehaus/groovy/classgen/asm/BytecodeVariable.java
index 4c4c5dda5f..723bf63e07 100644
--- a/src/main/java/org/codehaus/groovy/classgen/asm/BytecodeVariable.java
+++ b/src/main/java/org/codehaus/groovy/classgen/asm/BytecodeVariable.java
@@ -53,6 +53,7 @@ public class BytecodeVariable {
this.type = type;
this.name = name;
this.prevCurrent = prevCurrent;
+ this.dynamicTyped = ClassHelper.isDynamicTyped(type);
}
/**
@@ -83,8 +84,8 @@ public class BytecodeVariable {
return dynamicTyped;
}
- public void setDynamicTyped(final boolean b) {
- dynamicTyped = b;
+ public void setDynamicTyped(final boolean dynamicTyped) {
+ this.dynamicTyped = dynamicTyped;
}
/**
diff --git a/src/main/java/org/codehaus/groovy/classgen/asm/CompileStack.java
b/src/main/java/org/codehaus/groovy/classgen/asm/CompileStack.java
index ed6b860af7..f903a8c53f 100644
--- a/src/main/java/org/codehaus/groovy/classgen/asm/CompileStack.java
+++ b/src/main/java/org/codehaus/groovy/classgen/asm/CompileStack.java
@@ -309,7 +309,7 @@ public class CompileStack {
}
/**
- * creates a temporary variable.
+ * Creates a temporary variable.
*
* @param name defines type and name
* @param store defines if the top-level argument of the stack should be
stored
@@ -320,7 +320,7 @@ public class CompileStack {
}
/**
- * creates a temporary variable.
+ * Creates a temporary variable.
*
* @param name the variable name
* @param type the variable type
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 022e228d71..309b4ae416 100644
--- a/src/main/java/org/codehaus/groovy/classgen/asm/StatementWriter.java
+++ b/src/main/java/org/codehaus/groovy/classgen/asm/StatementWriter.java
@@ -424,7 +424,7 @@ public class StatementWriter {
mv.visitLabel(catchAll);
operandStack.push(ClassHelper.THROWABLE_TYPE);
- int anyThrowable = compileStack.defineTemporaryVariable("throwable",
true);
+ int anyThrowable = compileStack.defineTemporaryVariable("throwable",
ClassHelper.THROWABLE_TYPE, true);
finallyStatement.visit(controller.getAcg());
diff --git
a/src/main/java/org/codehaus/groovy/transform/AutoCloneASTTransformation.java
b/src/main/java/org/codehaus/groovy/transform/AutoCloneASTTransformation.java
index eacbf0ef7d..ef6d57adc4 100644
---
a/src/main/java/org/codehaus/groovy/transform/AutoCloneASTTransformation.java
+++
b/src/main/java/org/codehaus/groovy/transform/AutoCloneASTTransformation.java
@@ -143,8 +143,8 @@ public class AutoCloneASTTransformation extends
AbstractASTTransformation {
private void createCloneSerialization(ClassNode cNode) {
final BlockStatement body = new BlockStatement();
- // def baos = new ByteArrayOutputStream()
- final Expression baos = localVarX("baos");
+ // ByteArrayOutputStream baos = new ByteArrayOutputStream()
+ final Expression baos = localVarX("baos", BAOS_TYPE);
body.addStatement(declS(baos, ctorX(BAOS_TYPE)));
// baos.withObjectOutputStream{ it.writeObject(this) }
@@ -154,8 +154,8 @@ public class AutoCloneASTTransformation extends
AbstractASTTransformation {
writeClos.setVariableScope(new VariableScope());
body.addStatement(stmt(callX(baos, "withObjectOutputStream",
args(writeClos))));
- // def bais = new ByteArrayInputStream(baos.toByteArray())
- final Expression bais = localVarX("bais");
+ // ByteArrayInputStream bais = new
ByteArrayInputStream(baos.toByteArray())
+ final Expression bais = localVarX("bais", BAIS_TYPE);
body.addStatement(declS(bais, ctorX(BAIS_TYPE, args(callX(baos,
"toByteArray")))));
// return bais.withObjectInputStream(getClass().classLoader){ (<type>)
it.readObject() }
@@ -238,7 +238,7 @@ public class AutoCloneASTTransformation extends
AbstractASTTransformation {
addGeneratedConstructor(cNode, ACC_PUBLIC, Parameter.EMPTY_ARRAY,
ClassNode.EMPTY_ARRAY, block(EmptyStatement.INSTANCE));
}
addSimpleCloneHelperMethod(cNode, fieldNodes, excludes);
- final Expression result = localVarX("_result");
+ final Expression result = localVarX("_result", cNode);
ClassNode[] exceptions = {make(CloneNotSupportedException.class)};
ConstructorCallExpression init = ctorX(cNode);
if (AnnotatedNodeUtils.hasAnnotation(cNode, COMPILESTATIC_CLASSNODE)
&& cNode.getDeclaredConstructor(Parameter.EMPTY_ARRAY) == null) {
@@ -285,8 +285,8 @@ public class AutoCloneASTTransformation extends
AbstractASTTransformation {
private static void createClone(ClassNode cNode, List<FieldNode>
fieldNodes, List<String> excludes) {
final BlockStatement body = new BlockStatement();
- // def _result = super.clone() as cNode
- final Expression result = localVarX("_result");
+ // Type _result = (Type) super.clone()
+ final Expression result = localVarX("_result", cNode);
body.addStatement(declS(result, castX(cNode, callSuperX("clone"))));
for (FieldNode fieldNode : fieldNodes) {
diff --git
a/src/main/java/org/codehaus/groovy/transform/EqualsAndHashCodeASTTransformation.java
b/src/main/java/org/codehaus/groovy/transform/EqualsAndHashCodeASTTransformation.java
index bdb53ff1d4..b521d9cfa6 100644
---
a/src/main/java/org/codehaus/groovy/transform/EqualsAndHashCodeASTTransformation.java
+++
b/src/main/java/org/codehaus/groovy/transform/EqualsAndHashCodeASTTransformation.java
@@ -212,8 +212,8 @@ public class EqualsAndHashCodeASTTransformation extends
AbstractASTTransformatio
fList.addAll(getInstanceNonPropertyFields(cNode));
}
final BlockStatement body = new BlockStatement();
- // def _result = HashCodeHelper.initHash()
- final Expression result = localVarX("_result");
+ // int _result = HashCodeHelper.initHash()
+ final Expression result = localVarX("_result", ClassHelper.int_TYPE);
body.addStatement(declS(result, callX(HASHUTIL_TYPE, "initHash")));
for (PropertyNode pNode : pList) {
diff --git
a/src/main/java/org/codehaus/groovy/transform/LazyASTTransformation.java
b/src/main/java/org/codehaus/groovy/transform/LazyASTTransformation.java
index 12a4b6a763..acaf967101 100644
--- a/src/main/java/org/codehaus/groovy/transform/LazyASTTransformation.java
+++ b/src/main/java/org/codehaus/groovy/transform/LazyASTTransformation.java
@@ -32,7 +32,6 @@ import org.codehaus.groovy.ast.expr.ConstantExpression;
import org.codehaus.groovy.ast.expr.EmptyExpression;
import org.codehaus.groovy.ast.expr.Expression;
import org.codehaus.groovy.ast.expr.MethodCallExpression;
-import org.codehaus.groovy.ast.expr.VariableExpression;
import org.codehaus.groovy.ast.stmt.BlockStatement;
import org.codehaus.groovy.ast.stmt.Statement;
import org.codehaus.groovy.ast.stmt.SynchronizedStatement;
@@ -44,7 +43,6 @@ import java.lang.ref.SoftReference;
import static org.apache.groovy.ast.tools.ClassNodeUtils.addGeneratedMethod;
import static org.apache.groovy.util.BeanUtils.capitalize;
-import static org.codehaus.groovy.ast.ClassHelper.makeWithoutCaching;
import static org.codehaus.groovy.ast.tools.GeneralUtils.assignS;
import static org.codehaus.groovy.ast.tools.GeneralUtils.assignX;
import static org.codehaus.groovy.ast.tools.GeneralUtils.block;
@@ -64,7 +62,6 @@ import static
org.codehaus.groovy.ast.tools.GeneralUtils.propX;
import static org.codehaus.groovy.ast.tools.GeneralUtils.returnS;
import static org.codehaus.groovy.ast.tools.GeneralUtils.stmt;
import static org.codehaus.groovy.ast.tools.GeneralUtils.varX;
-import static org.codehaus.groovy.ast.ClassHelper.isPrimitiveBoolean;
import static org.objectweb.asm.Opcodes.ACC_FINAL;
import static org.objectweb.asm.Opcodes.ACC_PRIVATE;
import static org.objectweb.asm.Opcodes.ACC_PROTECTED;
@@ -78,7 +75,7 @@ import static org.objectweb.asm.Opcodes.ACC_SYNTHETIC;
@GroovyASTTransformation(phase = CompilePhase.SEMANTIC_ANALYSIS)
public class LazyASTTransformation extends AbstractASTTransformation {
- private static final ClassNode SOFT_REF =
makeWithoutCaching(SoftReference.class, false);
+ private static final ClassNode SOFT_REF =
ClassHelper.makeWithoutCaching(SoftReference.class, false);
@Override
public void visit(ASTNode[] nodes, SourceUnit source) {
@@ -150,18 +147,23 @@ public class LazyASTTransformation extends
AbstractASTTransformation {
}
private static void addDoubleCheckedLockingBody(BlockStatement body,
FieldNode fieldNode, Expression initExpr) {
- final Expression fieldExpr = varX(fieldNode);
- final VariableExpression localVar = localVarX(fieldNode.getName() +
"_local");
- body.addStatement(declS(localVar, fieldExpr));
+ ClassNode fieldType = fieldNode.getType();
+ if (ClassHelper.isPrimitiveType(fieldType)) {
+ fieldType = ClassHelper.getWrapper(fieldType);
+ }
+ final Expression localVar = localVarX(fieldNode.getName() + "_local",
fieldType);
+ final Expression theField = varX(fieldNode);
+
+ body.addStatement(declS(localVar, theField));
body.addStatement(ifElseS(
notNullX(localVar),
returnS(localVar),
new SynchronizedStatement(
syncTarget(fieldNode),
ifElseS(
- notNullX(fieldExpr),
- returnS(fieldExpr),
- returnS(assignX(fieldExpr, initExpr))
+ notNullX(theField),
+ returnS(theField),
+ returnS(assignX(theField, initExpr))
)
)
));
@@ -178,7 +180,7 @@ public class LazyASTTransformation extends
AbstractASTTransformation {
String propName = capitalize(fieldNode.getName().substring(1));
ClassNode declaringClass = fieldNode.getDeclaringClass();
addGeneratedMethodOrError(declaringClass, "get" + propName,
visibility, type, body, xform, fieldNode);
- if (isPrimitiveBoolean(type)) {
+ if (ClassHelper.isPrimitiveBoolean(type)) {
addGeneratedMethodOrError(declaringClass, "is" + propName,
visibility, type, stmt(callThisX("get" + propName)), xform, fieldNode);
}
// expect no setter
diff --git
a/src/main/java/org/codehaus/groovy/transform/ToStringASTTransformation.java
b/src/main/java/org/codehaus/groovy/transform/ToStringASTTransformation.java
index 217fbe3d51..cff3909f6e 100644
--- a/src/main/java/org/codehaus/groovy/transform/ToStringASTTransformation.java
+++ b/src/main/java/org/codehaus/groovy/transform/ToStringASTTransformation.java
@@ -216,14 +216,14 @@ public class ToStringASTTransformation extends
AbstractASTTransformation {
}
private static Expression calculateToStringStatements(ClassNode cNode,
boolean includeSuper, boolean includeFields, boolean includeSuperFields,
List<String> excludes, final List<String> includes, boolean includeNames,
boolean ignoreNulls, boolean includePackage, boolean includeSuperProperties,
boolean allProperties, BlockStatement body, boolean allNames, boolean pojo,
String[] delims, boolean useGetter) {
- // def _result = new StringBuilder()
- final Expression result = localVarX("_result");
+ // StringBuilder _result = new StringBuilder()
+ final Expression result = localVarX("_result", STRINGBUILDER_TYPE);
body.addStatement(declS(result, ctorX(STRINGBUILDER_TYPE)));
List<ToStringElement> elements = new ArrayList<>();
- // def $toStringFirst = true
- final VariableExpression first = localVarX("$toStringFirst");
- body.addStatement(declS(first, constX(Boolean.TRUE)));
+ // boolean $toStringFirst = true
+ final VariableExpression first = localVarX("$toStringFirst",
ClassHelper.boolean_TYPE);
+ body.addStatement(declS(first, ConstantExpression.PRIM_TRUE));
if (cNode.isEnum()) {
// <enum_name>(
@@ -301,7 +301,7 @@ public class ToStringASTTransformation extends
AbstractASTTransformation {
// if ($toStringFirst) $toStringFirst = false else result.append(", ")
body.addStatement(ifElseS(
first,
- assignS(first, ConstantExpression.FALSE),
+ assignS(first, ConstantExpression.PRIM_FALSE),
appendS(result, constX(delims[3]))));
}