Repository: groovy Updated Branches: refs/heads/native-lambda fb8e3d10b -> 8616d8967
Fix loading local variables for invokedynamic Project: http://git-wip-us.apache.org/repos/asf/groovy/repo Commit: http://git-wip-us.apache.org/repos/asf/groovy/commit/8616d896 Tree: http://git-wip-us.apache.org/repos/asf/groovy/tree/8616d896 Diff: http://git-wip-us.apache.org/repos/asf/groovy/diff/8616d896 Branch: refs/heads/native-lambda Commit: 8616d8967d847026102de999e50deaae1bdfc444 Parents: fb8e3d1 Author: sunlan <[email protected]> Authored: Tue Jan 16 11:14:47 2018 +0800 Committer: sunlan <[email protected]> Committed: Tue Jan 16 11:14:47 2018 +0800 ---------------------------------------------------------------------- .../asm/sc/StaticTypesLambdaWriter.java | 39 +++++++++++++------- src/test/groovy/transform/stc/LambdaTest.groovy | 22 ++++------- 2 files changed, 33 insertions(+), 28 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/groovy/blob/8616d896/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 99c0215..cbc6d31 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 @@ -31,6 +31,8 @@ import org.codehaus.groovy.ast.expr.Expression; import org.codehaus.groovy.ast.expr.LambdaExpression; import org.codehaus.groovy.ast.expr.VariableExpression; import org.codehaus.groovy.classgen.asm.BytecodeHelper; +import org.codehaus.groovy.classgen.asm.BytecodeVariable; +import org.codehaus.groovy.classgen.asm.CompileStack; import org.codehaus.groovy.classgen.asm.LambdaWriter; import org.codehaus.groovy.classgen.asm.OperandStack; import org.codehaus.groovy.classgen.asm.WriterController; @@ -51,7 +53,7 @@ import java.util.stream.Stream; import static org.codehaus.groovy.classgen.asm.sc.StaticInvocationWriter.PARAMETER_TYPE; import static org.objectweb.asm.Opcodes.ACC_PUBLIC; -import static org.objectweb.asm.Opcodes.ALOAD; +import static org.objectweb.asm.Opcodes.ACC_STATIC; /** * Writer responsible for generating lambda classes in statically compiled mode. @@ -95,26 +97,37 @@ public class StaticTypesLambdaWriter extends LambdaWriter { MethodNode abstractMethodNode = abstractMethodNodeList.get(0); String abstractMethodDesc = createMethodDescriptor(abstractMethodNode); - ClassNode lambdaClassNode = getOrAddLambdaClass(expression, ACC_PUBLIC); + ClassNode lambdaClassNode = getOrAddLambdaClass(expression, ACC_PUBLIC | (controller.getClassNode().isInterface() ? ACC_STATIC : 0)); MethodNode syntheticLambdaMethodNode = lambdaClassNode.getMethods(DO_CALL).get(0); MethodVisitor mv = controller.getMethodVisitor(); - OperandStack operandStack = controller.getOperandStack(); + Parameter[] lambdaSharedVariableParameters = loadSharedVariables(syntheticLambdaMethodNode); - Parameter[] lambdaSharedVariableParameters = syntheticLambdaMethodNode.getNodeMetaData(LAMBDA_SHARED_VARIABLES); - for (int i = 0; i < lambdaSharedVariableParameters.length; i++) { - mv.visitVarInsn(ALOAD, i); - operandStack.doGroovyCast(lambdaSharedVariableParameters[i].getType().redirect()); -// operandStack.push(lambdaSharedVariableParameters[i].getType().redirect()); - } - - operandStack.push(parameterType.redirect()); mv.visitInvokeDynamicInsn( abstractMethodNode.getName(), createAbstractMethodDesc(syntheticLambdaMethodNode, parameterType), createBootstrapMethod(), createBootstrapMethodArguments(abstractMethodDesc, lambdaClassNode, syntheticLambdaMethodNode) ); + controller.getOperandStack().replace(parameterType.redirect(), lambdaSharedVariableParameters.length); + } + + private Parameter[] loadSharedVariables(MethodNode syntheticLambdaMethodNode) { + OperandStack operandStack = controller.getOperandStack(); + CompileStack compileStack = controller.getCompileStack(); + + Parameter[] lambdaSharedVariableParameters = syntheticLambdaMethodNode.getNodeMetaData(LAMBDA_SHARED_VARIABLES); + for (Parameter parameter : lambdaSharedVariableParameters) { + String parameterName = parameter.getName(); +// loadReference(parameterName, controller); +// if (parameter.getNodeMetaData(LambdaWriter.UseExistingReference.class)==null) { +// parameter.setNodeMetaData(LambdaWriter.UseExistingReference.class,Boolean.TRUE); +// } + + BytecodeVariable variable = compileStack.getVariable(parameterName, true); + operandStack.loadOrStoreVariable(variable, false); + } + return lambdaSharedVariableParameters; } private String createAbstractMethodDesc(MethodNode syntheticLambdaMethodNode, ClassNode parameterType) { @@ -211,14 +224,14 @@ public class StaticTypesLambdaWriter extends LambdaWriter { ClassNode returnType = expression.getNodeMetaData(StaticTypesMarker.INFERRED_RETURN_TYPE); //abstractMethodNode.getReturnType(); Parameter[] localVariableParameters = getLambdaSharedVariables(expression); removeInitialValues(localVariableParameters); - Parameter[] methodParameter = Stream.concat(Arrays.stream(localVariableParameters), Arrays.stream(parametersWithExactType)).toArray(Parameter[]::new); + Parameter[] methodParameters = Stream.concat(Arrays.stream(localVariableParameters), Arrays.stream(parametersWithExactType)).toArray(Parameter[]::new); MethodNode methodNode = answer.addMethod( DO_CALL, Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC | Opcodes.ACC_SYNTHETIC, returnType, - methodParameter, + methodParameters, ClassNode.EMPTY_ARRAY, expression.getCode() ); http://git-wip-us.apache.org/repos/asf/groovy/blob/8616d896/src/test/groovy/transform/stc/LambdaTest.groovy ---------------------------------------------------------------------- diff --git a/src/test/groovy/transform/stc/LambdaTest.groovy b/src/test/groovy/transform/stc/LambdaTest.groovy index dbd789a..f12eeda 100644 --- a/src/test/groovy/transform/stc/LambdaTest.groovy +++ b/src/test/groovy/transform/stc/LambdaTest.groovy @@ -55,7 +55,7 @@ class LambdaTest extends GroovyTestCase { } /** - * Depends on https://issues.apache.org/jira/browse/GROOVY-8445 + * Depends on fixing https://issues.apache.org/jira/browse/GROOVY-8445 */ void testBinaryOperator() { if (true) return @@ -136,7 +136,7 @@ TestScript0.groovy: 13: [Static type checking] - Cannot find matching method jav } /** - * Depends on https://issues.apache.org/jira/browse/GROOVY-8445 + * Depends on fixing https://issues.apache.org/jira/browse/GROOVY-8445 */ void testUnaryOperator() { if (true) return @@ -196,13 +196,6 @@ TestScript0.groovy: 14: [Static type checking] - Cannot find matching method jav } void testFunctionWithLocalVariables() { - if (true) return - - // FIXME - /* What we expect is '#1', '#2', '#3' -[groovy.lang.Reference@46d63dbb1, groovy.lang.Reference@46d63dbb2, groovy.lang.Reference@46d63dbb3] - */ - assertScript ''' import groovy.transform.CompileStatic import java.util.stream.Collectors @@ -222,9 +215,8 @@ TestScript0.groovy: 14: [Static type checking] - Cannot find matching method jav ''' } - /* - void testLabs() { + void testFunctionWithLocalVariables2() { assertScript ''' import groovy.transform.CompileStatic import java.util.stream.Collectors @@ -233,15 +225,15 @@ TestScript0.groovy: 14: [Static type checking] - Cannot find matching method jav @CompileStatic public class Test1 { public static void main(String[] args) { - p(); + new Test1().p(); } - public static void p() { + public void p() { String x = "#" - System.out.println(Stream.of(1, 2, 3).map(e -> x + e).collect(Collectors.toList())); + Integer y = 23 + assert ['23#1', '23#2', '23#3'] == Stream.of(1, 2, 3).map(e -> '' + y + x + e).collect(Collectors.toList()) } } ''' } - */ }
