You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@groovy.apache.org by em...@apache.org on 2022/12/05 15:11:16 UTC

[groovy] branch GROOVY_4_0_X updated: GROOVY-10861: bootstrap parameters directly passed

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

emilles pushed a commit to branch GROOVY_4_0_X
in repository https://gitbox.apache.org/repos/asf/groovy.git


The following commit(s) were added to refs/heads/GROOVY_4_0_X by this push:
     new e44a12db32 GROOVY-10861: bootstrap parameters directly passed
e44a12db32 is described below

commit e44a12db327ce0a2a3b571fb83b1d5a3ccd3734f
Author: Eric Milles <er...@thomsonreuters.com>
AuthorDate: Mon Dec 5 08:21:53 2022 -0600

    GROOVY-10861: bootstrap parameters directly passed
---
 .../asm/sc/AbstractFunctionalInterfaceWriter.java  | 27 ++++++++--------------
 .../classgen/asm/sc/StaticTypesLambdaWriter.java   | 10 ++++----
 ...StaticTypesMethodReferenceExpressionWriter.java | 24 ++++++++-----------
 3 files changed, 24 insertions(+), 37 deletions(-)

diff --git a/src/main/java/org/codehaus/groovy/classgen/asm/sc/AbstractFunctionalInterfaceWriter.java b/src/main/java/org/codehaus/groovy/classgen/asm/sc/AbstractFunctionalInterfaceWriter.java
index d264d19542..a6a5ba9f24 100644
--- a/src/main/java/org/codehaus/groovy/classgen/asm/sc/AbstractFunctionalInterfaceWriter.java
+++ b/src/main/java/org/codehaus/groovy/classgen/asm/sc/AbstractFunctionalInterfaceWriter.java
@@ -42,18 +42,16 @@ import static org.codehaus.groovy.transform.stc.StaticTypesMarker.PARAMETER_TYPE
  * @since 3.0.0
  */
 public interface AbstractFunctionalInterfaceWriter {
-    String ORIGINAL_PARAMETERS_WITH_EXACT_TYPE = "__ORIGINAL_PARAMETERS_WITH_EXACT_TYPE";
 
-    default ClassNode getFunctionalInterfaceType(Expression expression) {
+    default ClassNode getFunctionalInterfaceType(final Expression expression) {
         ClassNode type = expression.getNodeMetaData(PARAMETER_TYPE);
-
-        if (null == type) {
+        if (type == null) {
             type = expression.getNodeMetaData(INFERRED_FUNCTIONAL_INTERFACE_TYPE);
         }
         return type;
     }
 
-    default String createMethodDescriptor(MethodNode abstractMethodNode) {
+    default String createMethodDescriptor(final MethodNode abstractMethodNode) {
         return BytecodeHelper.getMethodDescriptor(
                 abstractMethodNode.getReturnType().getTypeClass(),
                 Arrays.stream(abstractMethodNode.getParameters())
@@ -62,7 +60,7 @@ public interface AbstractFunctionalInterfaceWriter {
         );
     }
 
-    default Handle createBootstrapMethod(boolean isInterface, boolean serializable) {
+    default Handle createBootstrapMethod(final boolean isInterface, final boolean serializable) {
         if (serializable) {
             return new Handle(
                     Opcodes.H_INVOKESTATIC,
@@ -82,7 +80,7 @@ public interface AbstractFunctionalInterfaceWriter {
         );
     }
 
-    default Object[] createBootstrapMethodArguments(final String abstractMethodDesc, final int insn, final ClassNode methodOwner, final MethodNode methodNode, final boolean serializable) {
+    default Object[] createBootstrapMethodArguments(final String abstractMethodDesc, final int insn, final ClassNode methodOwner, final MethodNode methodNode, final Parameter[] parameters, final boolean serializable) {
         Object[] arguments = !serializable ? new Object[3] : new Object[]{null, null, null, 5, 0};
 
         arguments[0] = Type.getType(abstractMethodDesc);
@@ -95,13 +93,12 @@ public interface AbstractFunctionalInterfaceWriter {
                 methodOwner.isInterface());
 
         arguments[2] = Type.getType(
-                BytecodeHelper.getMethodDescriptor(methodNode.getReturnType(),
-                (Parameter[]) methodNode.getNodeMetaData(ORIGINAL_PARAMETERS_WITH_EXACT_TYPE)));
+                BytecodeHelper.getMethodDescriptor(methodNode.getReturnType(), parameters));
 
         return arguments;
     }
 
-    default ClassNode convertParameterType(ClassNode targetType, ClassNode parameterType, ClassNode inferredType) {
+    default ClassNode convertParameterType(final ClassNode targetType, final ClassNode parameterType, final ClassNode inferredType) {
         if (!getWrapper(inferredType).isDerivedFrom(getWrapper(parameterType))) {
             throw new RuntimeParserException("The inferred type[" + inferredType.redirect() + "] is not compatible with the parameter type[" + parameterType.redirect() + "]", parameterType);
         }
@@ -136,7 +133,7 @@ public interface AbstractFunctionalInterfaceWriter {
      * @deprecated use {@link #convertParameterType(ClassNode, ClassNode, ClassNode)} instead
      */
     @Deprecated
-    default ClassNode convertParameterType(ClassNode parameterType, ClassNode inferredType) {
+    default ClassNode convertParameterType(final ClassNode parameterType, final ClassNode inferredType) {
         if (!ClassHelper.getWrapper(inferredType.redirect()).isDerivedFrom(ClassHelper.getWrapper(parameterType.redirect()))) {
             throw new RuntimeParserException("The inferred type[" + inferredType.redirect() + "] is not compatible with the parameter type[" + parameterType.redirect() + "]", parameterType);
         } else {
@@ -154,19 +151,15 @@ public interface AbstractFunctionalInterfaceWriter {
             } else {
                 type = inferredType;
             }
-
             return type;
         }
     }
 
-    default Parameter prependParameter(List<Parameter> methodParameterList, String parameterName, ClassNode parameterType) {
+    default Parameter prependParameter(final List<Parameter> methodParameterList, final String parameterName, final ClassNode parameterType) {
         Parameter parameter = new Parameter(parameterType, parameterName);
-
-        parameter.setOriginType(parameterType);
         parameter.setClosureSharedVariable(false);
-
+        parameter.setOriginType(parameterType);
         methodParameterList.add(0, parameter);
-
         return parameter;
     }
 }
diff --git a/src/main/java/org/codehaus/groovy/classgen/asm/sc/StaticTypesLambdaWriter.java b/src/main/java/org/codehaus/groovy/classgen/asm/sc/StaticTypesLambdaWriter.java
index 38afb25a93..9b9fb1d638 100644
--- a/src/main/java/org/codehaus/groovy/classgen/asm/sc/StaticTypesLambdaWriter.java
+++ b/src/main/java/org/codehaus/groovy/classgen/asm/sc/StaticTypesLambdaWriter.java
@@ -61,7 +61,6 @@ import static org.codehaus.groovy.ast.ClassHelper.long_TYPE;
 import static org.codehaus.groovy.ast.tools.ClosureUtils.getParametersSafe;
 import static org.codehaus.groovy.ast.tools.GeneralUtils.block;
 import static org.codehaus.groovy.ast.tools.GeneralUtils.classX;
-import static org.codehaus.groovy.ast.tools.GeneralUtils.cloneParams;
 import static org.codehaus.groovy.ast.tools.GeneralUtils.constX;
 import static org.codehaus.groovy.ast.tools.GeneralUtils.declS;
 import static org.codehaus.groovy.ast.tools.GeneralUtils.localVarX;
@@ -133,7 +132,7 @@ public class StaticTypesLambdaWriter extends LambdaWriter implements AbstractFun
                 abstractMethod.getName(),
                 createAbstractMethodDesc(functionalInterface.redirect(), lambdaClass),
                 createBootstrapMethod(enclosingClass.isInterface(), expression.isSerializable()),
-                createBootstrapMethodArguments(createMethodDescriptor(abstractMethod), H_INVOKEVIRTUAL, lambdaClass, lambdaMethod, expression.isSerializable())
+                createBootstrapMethodArguments(createMethodDescriptor(abstractMethod), H_INVOKEVIRTUAL, lambdaClass, lambdaMethod, lambdaMethod.getParameters(), expression.isSerializable())
         );
         if (expression.isSerializable()) {
             mv.visitTypeInsn(CHECKCAST, "java/io/Serializable");
@@ -276,6 +275,8 @@ public class StaticTypesLambdaWriter extends LambdaWriter implements AbstractFun
         Parameter[] localVariableParameters = getLambdaSharedVariables(expression);
         removeInitialValues(localVariableParameters);
 
+        expression.putNodeMetaData(LAMBDA_SHARED_VARIABLES, localVariableParameters);
+
         MethodNode doCallMethod = lambdaClass.addMethod(
                 "doCall",
                 ACC_PUBLIC,
@@ -284,15 +285,12 @@ public class StaticTypesLambdaWriter extends LambdaWriter implements AbstractFun
                 ClassNode.EMPTY_ARRAY,
                 expression.getCode()
         );
-        doCallMethod.putNodeMetaData(ORIGINAL_PARAMETERS_WITH_EXACT_TYPE, parametersWithExactType);
-        expression.putNodeMetaData(LAMBDA_SHARED_VARIABLES, localVariableParameters);
         doCallMethod.setSourcePosition(expression);
-
         return doCallMethod;
     }
 
     private Parameter[] createParametersWithExactType(final LambdaExpression expression, final MethodNode abstractMethod) {
-        Parameter[] targetParameters = cloneParams(abstractMethod.getParameters());
+        Parameter[] targetParameters = abstractMethod.getParameters();
         Parameter[] parameters = getParametersSafe(expression);
         for (int i = 0, n = parameters.length; i < n; i += 1) {
             Parameter targetParameter = targetParameters[i];
diff --git a/src/main/java/org/codehaus/groovy/classgen/asm/sc/StaticTypesMethodReferenceExpressionWriter.java b/src/main/java/org/codehaus/groovy/classgen/asm/sc/StaticTypesMethodReferenceExpressionWriter.java
index 3f1eb99bd5..c1804e74c1 100644
--- a/src/main/java/org/codehaus/groovy/classgen/asm/sc/StaticTypesMethodReferenceExpressionWriter.java
+++ b/src/main/java/org/codehaus/groovy/classgen/asm/sc/StaticTypesMethodReferenceExpressionWriter.java
@@ -165,20 +165,16 @@ public class StaticTypesMethodReferenceExpressionWriter extends MethodReferenceE
         String methodDesc = BytecodeHelper.getMethodDescriptor(functionalInterfaceType.redirect(),
                 isClassExpression ? Parameter.EMPTY_ARRAY : new Parameter[]{new Parameter(typeOrTargetRefType, "__METHODREF_EXPR_INSTANCE")});
 
-        methodRefMethod.putNodeMetaData(ORIGINAL_PARAMETERS_WITH_EXACT_TYPE, parametersWithExactType);
-        try {
-            Handle bootstrapMethod = createBootstrapMethod(classNode.isInterface(), false);
-            Object[] bootstrapArgs = createBootstrapMethodArguments(
-                    createMethodDescriptor(abstractMethod),
-                    referenceKind,
-                    methodRefMethod.getDeclaringClass(),
-                    methodRefMethod,
-                    false
-            );
-            controller.getMethodVisitor().visitInvokeDynamicInsn(methodName, methodDesc, bootstrapMethod, bootstrapArgs);
-        } finally {
-            methodRefMethod.removeNodeMetaData(ORIGINAL_PARAMETERS_WITH_EXACT_TYPE);
-        }
+        Handle bootstrapMethod = createBootstrapMethod(classNode.isInterface(), false);
+        Object[] bootstrapArgs = createBootstrapMethodArguments(
+                createMethodDescriptor(abstractMethod),
+                referenceKind,
+                methodRefMethod.getDeclaringClass(),
+                methodRefMethod,
+                parametersWithExactType,
+                false
+        );
+        controller.getMethodVisitor().visitInvokeDynamicInsn(methodName, methodDesc, bootstrapMethod, bootstrapArgs);
 
         if (isClassExpression) {
             controller.getOperandStack().push(functionalInterfaceType);