groovy-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From sun...@apache.org
Subject groovy git commit: Create an instance for each lambda
Date Thu, 18 Jan 2018 01:34:21 GMT
Repository: groovy
Updated Branches:
  refs/heads/native-lambda 152b94d95 -> 7210193eb


Create an instance for each lambda


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

Branch: refs/heads/native-lambda
Commit: 7210193eba31d837fe4330adb094afd64c714d84
Parents: 152b94d
Author: sunlan <sunlan@apache.org>
Authored: Thu Jan 18 09:34:15 2018 +0800
Committer: sunlan <sunlan@apache.org>
Committed: Thu Jan 18 09:34:15 2018 +0800

----------------------------------------------------------------------
 .../asm/sc/StaticTypesLambdaWriter.java         | 78 +++++++++++++-------
 1 file changed, 52 insertions(+), 26 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/groovy/blob/7210193e/src/main/java/org/codehaus/groovy/classgen/asm/sc/StaticTypesLambdaWriter.java
----------------------------------------------------------------------
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 a88006c..0650684 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
@@ -58,15 +58,19 @@ import static org.codehaus.groovy.classgen.asm.sc.StaticInvocationWriter.PARAMET
 import static org.objectweb.asm.Opcodes.ACC_PUBLIC;
 import static org.objectweb.asm.Opcodes.ACC_STATIC;
 import static org.objectweb.asm.Opcodes.ALOAD;
+import static org.objectweb.asm.Opcodes.DUP;
+import static org.objectweb.asm.Opcodes.INVOKESPECIAL;
+import static org.objectweb.asm.Opcodes.NEW;
 
 /**
  * Writer responsible for generating lambda classes in statically compiled mode.
  */
 public class StaticTypesLambdaWriter extends LambdaWriter {
-    public static final String DO_CALL = "doCall";
-    public static final String ORIGINAL_PARAMETERS_WITH_EXACT_TYPE = "__ORIGINAL_PARAMETERS_WITH_EXACT_TYPE";
-    public static final String LAMBDA_SHARED_VARIABLES = "__LAMBDA_SHARED_VARIABLES";
-    public static final String THIS = "__this";
+    private static final String DO_CALL = "doCall";
+    private static final String ORIGINAL_PARAMETERS_WITH_EXACT_TYPE = "__ORIGINAL_PARAMETERS_WITH_EXACT_TYPE";
+    private static final String LAMBDA_SHARED_VARIABLES = "__LAMBDA_SHARED_VARIABLES";
+    private static final String ENCLOSING_THIS = "__enclosing_this";
+    private static final String LAMBDA_THIS = "__lambda_this";
     private StaticTypesClosureWriter staticTypesClosureWriter;
     private WriterController controller;
     private WriterControllerFactory factory;
@@ -106,26 +110,43 @@ public class StaticTypesLambdaWriter extends LambdaWriter {
         ClassNode lambdaClassNode = getOrAddLambdaClass(expression, ACC_PUBLIC | (isInterface
? ACC_STATIC : 0));
         MethodNode syntheticLambdaMethodNode = lambdaClassNode.getMethods(DO_CALL).get(0);
 
+        newAndLoadGroovyLambdaInstance(lambdaClassNode);
+        loadEnclosingClassInstance();
+        Parameter[] lambdaSharedVariableParameters = loadSharedVariables(syntheticLambdaMethodNode);
+
         MethodVisitor mv = controller.getMethodVisitor();
+        OperandStack operandStack = controller.getOperandStack();
+
+        mv.visitInvokeDynamicInsn(
+                abstractMethodNode.getName(),
+                createAbstractMethodDesc(syntheticLambdaMethodNode, parameterType, lambdaClassNode),
+                createBootstrapMethod(isInterface),
+                createBootstrapMethodArguments(abstractMethodDesc, lambdaClassNode, syntheticLambdaMethodNode)
+        );
+        operandStack.replace(parameterType.redirect(), lambdaSharedVariableParameters.length
+ 1);
+    }
 
+    private void loadEnclosingClassInstance() {
+        MethodVisitor mv = controller.getMethodVisitor();
         OperandStack operandStack = controller.getOperandStack();
 
         if (controller.getMethodNode().isStatic()) {
             operandStack.pushConstant(ConstantExpression.NULL);
         } else {
             mv.visitVarInsn(ALOAD, 0);
-            operandStack.push(classNode);
+            operandStack.push(controller.getClassNode());
         }
+    }
 
-        Parameter[] lambdaSharedVariableParameters = loadSharedVariables(syntheticLambdaMethodNode);
+    private void newAndLoadGroovyLambdaInstance(ClassNode lambdaClassNode) {
+        MethodVisitor mv = controller.getMethodVisitor();
+        String lambdaClassInternalName = BytecodeHelper.getClassInternalName(lambdaClassNode);
+        mv.visitTypeInsn(NEW, lambdaClassInternalName);
+        mv.visitInsn(DUP);
 
-        mv.visitInvokeDynamicInsn(
-                abstractMethodNode.getName(),
-                createAbstractMethodDesc(syntheticLambdaMethodNode, parameterType),
-                createBootstrapMethod(isInterface),
-                createBootstrapMethodArguments(abstractMethodDesc, lambdaClassNode, syntheticLambdaMethodNode)
-        );
-        operandStack.replace(parameterType.redirect(), lambdaSharedVariableParameters.length
+ 1);
+        Parameter[] lambdaClassConstructorParameters = Parameter.EMPTY_ARRAY;
+        mv.visitMethodInsn(INVOKESPECIAL, lambdaClassInternalName, "<init>", BytecodeHelper.getMethodDescriptor(ClassHelper.VOID_TYPE,
lambdaClassConstructorParameters), lambdaClassNode.isInterface());
+        controller.getOperandStack().replace(ClassHelper.LAMBDA_TYPE, lambdaClassConstructorParameters.length);
     }
 
     private Parameter[] loadSharedVariables(MethodNode syntheticLambdaMethodNode) {
@@ -143,13 +164,15 @@ public class StaticTypesLambdaWriter extends LambdaWriter {
             BytecodeVariable variable = compileStack.getVariable(parameterName, true);
             operandStack.loadOrStoreVariable(variable, false);
         }
+
         return lambdaSharedVariableParameters;
     }
 
-    private String createAbstractMethodDesc(MethodNode syntheticLambdaMethodNode, ClassNode
parameterType) {
+    private String createAbstractMethodDesc(MethodNode syntheticLambdaMethodNode, ClassNode
parameterType, ClassNode lambdaClassNode) {
         List<Parameter> lambdaSharedVariableList = new LinkedList<Parameter>(Arrays.asList(syntheticLambdaMethodNode.getNodeMetaData(LAMBDA_SHARED_VARIABLES)));
 
-        prependThis(lambdaSharedVariableList);
+        prependEnclosingThis(lambdaSharedVariableList);
+        prependParameter(lambdaSharedVariableList, LAMBDA_THIS, lambdaClassNode);
 
         return BytecodeHelper.getMethodDescriptor(parameterType.redirect(), lambdaSharedVariableList.toArray(Parameter.EMPTY_ARRAY));
     }
@@ -168,11 +191,11 @@ public class StaticTypesLambdaWriter extends LambdaWriter {
         return new Object[]{
                 Type.getType(abstractMethodDesc),
                 new Handle(
-                        Opcodes.H_INVOKESTATIC,
+                        Opcodes.H_INVOKEVIRTUAL,
                         lambdaClassNode.getName(),
                         syntheticLambdaMethodNode.getName(),
                         BytecodeHelper.getMethodDescriptor(syntheticLambdaMethodNode),
-                        false
+                        lambdaClassNode.isInterface()
                 ),
                 Type.getType(BytecodeHelper.getMethodDescriptor(syntheticLambdaMethodNode.getReturnType(),
syntheticLambdaMethodNode.getNodeMetaData(ORIGINAL_PARAMETERS_WITH_EXACT_TYPE)))
         };
@@ -245,12 +268,12 @@ public class StaticTypesLambdaWriter extends LambdaWriter {
 
         List<Parameter> methodParameterList = new LinkedList<Parameter>(Arrays.asList(methodParameters));
 
-        Parameter thisParameter = prependThis(methodParameterList);
+        Parameter thisParameter = prependEnclosingThis(methodParameterList);
 
         MethodNode methodNode =
                 answer.addMethod(
                         DO_CALL,
-                        Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC | Opcodes.ACC_SYNTHETIC,
+                        Opcodes.ACC_PUBLIC | Opcodes.ACC_SYNTHETIC,
                         returnType,
                         methodParameterList.toArray(Parameter.EMPTY_ARRAY),
                         ClassNode.EMPTY_ARRAY,
@@ -263,16 +286,19 @@ public class StaticTypesLambdaWriter extends LambdaWriter {
         new TransformationVisitor(methodNode, thisParameter).visitMethod(methodNode);
     }
 
-    private Parameter prependThis(List<Parameter> methodParameterList) {
-        ClassNode classNode = controller.getClassNode().getPlainNodeReference();
+    private Parameter prependEnclosingThis(List<Parameter> methodParameterList) {
+        return prependParameter(methodParameterList, ENCLOSING_THIS, controller.getClassNode().getPlainNodeReference());
+    }
+
+    private Parameter prependParameter(List<Parameter> methodParameterList, String
parameterName, ClassNode parameterType) {
+        Parameter parameter = new Parameter(parameterType, parameterName);
 
-        Parameter thisParameter = new Parameter(classNode, THIS);
-        thisParameter.setOriginType(classNode);
-        thisParameter.setClosureSharedVariable(false);
+        parameter.setOriginType(parameterType);
+        parameter.setClosureSharedVariable(false);
 
-        methodParameterList.add(0, thisParameter);
+        methodParameterList.add(0, parameter);
 
-        return thisParameter;
+        return parameter;
     }
 
     private Parameter[] createParametersWithExactType(LambdaExpression expression) {


Mime
View raw message