|
@@ -3913,6 +3913,7 @@ public class JavaExpressionVisitor implements ExpressionVisitor<Void>, JavaNativ
|
3913
|
3913
|
// new Shared<T>(value)
|
3914
|
3914
|
javaWriter.newObject("zsynthetic/Shared");
|
3915
|
3915
|
javaWriter.dupX1();
|
|
3916
|
+ javaWriter.swap();
|
3916
|
3917
|
javaWriter.invokeSpecial(SHARED_INIT);
|
3917
|
3918
|
}
|
3918
|
3919
|
}
|
|
@@ -3921,73 +3922,82 @@ public class JavaExpressionVisitor implements ExpressionVisitor<Void>, JavaNativ
|
3921
|
3922
|
}
|
3922
|
3923
|
|
3923
|
3924
|
private void visitFunctionalInterfaceWrapping(StorageCastExpression expression, JavaFunctionalInterfaceStorageTag tag) {
|
|
3925
|
+
|
3924
|
3926
|
final Method functionalInterfaceMethod = tag.functionalInterfaceMethod;
|
3925
|
|
-
|
|
3927
|
+
|
|
3928
|
+ final JavaMethod wrappedMethod = context.getFunctionalInterface(expression.value.type);
|
3926
|
3929
|
final String wrappedSignature = context.getDescriptor(expression.type);
|
3927
|
|
- final String wrappedMethodName = "accept";
|
3928
|
3930
|
final String constructorDesc = "(" + wrappedSignature + ")V";
|
3929
|
3931
|
|
3930
|
3932
|
final String className = context.getLambdaCounter();
|
3931
|
|
- final String descriptor = Type.getMethodDescriptor(functionalInterfaceMethod);
|
3932
|
|
- //ddd
|
3933
|
3933
|
final String methodName = functionalInterfaceMethod.getName();
|
|
3934
|
+ final String methodDescriptor = Type.getMethodDescriptor(functionalInterfaceMethod);
|
3934
|
3935
|
final String[] interfaces = new String[]{Type.getInternalName(functionalInterfaceMethod.getDeclaringClass())};
|
3935
|
|
-
|
3936
|
|
- final FunctionParameter[] functionParameters = ((FunctionTypeID) expression.value.type.type).header.parameters;
|
3937
|
|
- final String wrappedMethodSig = context.getMethodDescriptor(((FunctionTypeID) expression.value.type.type).header);
|
3938
|
|
-
|
3939
|
|
-
|
3940
|
|
- javaWriter.newObject(className);
|
3941
|
|
- javaWriter.dupX1();
|
3942
|
|
- javaWriter.swap();
|
3943
|
|
- javaWriter.invokeSpecial(className, "<init>", constructorDesc);
|
3944
|
|
-
|
3945
|
|
-
|
3946
|
|
- final JavaMethod methodInfo = JavaMethod.getNativeVirtual(javaWriter.method.cls, methodName, descriptor);
|
|
3936
|
+
|
3947
|
3937
|
final ClassWriter lambdaCW = new JavaClassWriter(ClassWriter.COMPUTE_FRAMES);
|
3948
|
3938
|
lambdaCW.visit(Opcodes.V1_8, Opcodes.ACC_PUBLIC, className, null, "java/lang/Object", interfaces);
|
3949
|
|
-
|
3950
|
|
-
|
3951
|
|
- lambdaCW.visitField(Modifier.PRIVATE | Modifier.FINAL, "wrapped", wrappedSignature, null, null).visitEnd();
|
3952
|
|
-
|
3953
|
|
- final JavaWriter constructorWriter = new JavaWriter(expression.position, lambdaCW, JavaMethod.getConstructor(javaWriter.method.cls, constructorDesc, Opcodes.ACC_PUBLIC), null, null, null);
|
3954
|
|
- constructorWriter.start();
|
3955
|
|
- constructorWriter.loadObject(0);
|
3956
|
|
- constructorWriter.dup();
|
3957
|
|
- constructorWriter.invokeSpecial(Object.class, "<init>", "()V");
|
3958
|
|
-
|
3959
|
|
- constructorWriter.loadObject(1);
|
3960
|
|
- constructorWriter.putField(className, "wrapped", wrappedSignature);
|
3961
|
|
-
|
3962
|
|
- constructorWriter.ret();
|
3963
|
|
- constructorWriter.end();
|
3964
|
|
-
|
3965
|
|
-
|
3966
|
|
- final JavaWriter functionWriter = new JavaWriter(expression.position, lambdaCW, methodInfo, null, descriptor, null, "java/lang/Override");
|
3967
|
|
- functionWriter.start();
|
3968
|
|
-
|
3969
|
|
- //this.wrapped
|
3970
|
|
- functionWriter.loadObject(0);
|
3971
|
|
- functionWriter.getField(className, "wrapped", wrappedSignature);
|
3972
|
|
- for (int i = 0; i < functionParameters.length; i++) {
|
3973
|
|
- final FunctionParameter functionParameter = functionParameters[i];
|
3974
|
|
- functionWriter.load(context.getType(functionParameter.type), i + 1);
|
|
3939
|
+
|
|
3940
|
+ //The field storing the wrapped object
|
|
3941
|
+ {
|
|
3942
|
+ lambdaCW.visitField(Modifier.PRIVATE | Modifier.FINAL, "wrapped", wrappedSignature, null, null).visitEnd();
|
3975
|
3943
|
}
|
3976
|
|
-
|
3977
|
|
- functionWriter.invokeInterface(JavaMethod.getVirtual(JavaClass.fromInternalName(context.getInternalName(expression.type.type), JavaClass.Kind.INTERFACE), wrappedMethodName, wrappedMethodSig, 0));
|
3978
|
|
-
|
3979
|
|
- functionWriter.returnType(context.getType(((FunctionTypeID) expression.value.type.type).header.getReturnType()));
|
3980
|
|
-
|
3981
|
|
- functionWriter.ret();
|
3982
|
|
- functionWriter.end();
|
|
3944
|
+
|
|
3945
|
+ //Constructor
|
|
3946
|
+ {
|
|
3947
|
+ final JavaWriter constructorWriter = new JavaWriter(expression.position, lambdaCW, JavaMethod.getConstructor(javaWriter.method.cls, constructorDesc, Opcodes.ACC_PUBLIC), null, null, null);
|
|
3948
|
+ constructorWriter.start();
|
|
3949
|
+ constructorWriter.loadObject(0);
|
|
3950
|
+ constructorWriter.dup();
|
|
3951
|
+ constructorWriter.invokeSpecial(Object.class, "<init>", "()V");
|
|
3952
|
+
|
|
3953
|
+ constructorWriter.loadObject(1);
|
|
3954
|
+ constructorWriter.putField(className, "wrapped", wrappedSignature);
|
|
3955
|
+
|
|
3956
|
+ constructorWriter.ret();
|
|
3957
|
+ constructorWriter.end();
|
|
3958
|
+ }
|
|
3959
|
+
|
|
3960
|
+ //The actual method
|
|
3961
|
+ {
|
|
3962
|
+ final JavaWriter functionWriter = new JavaWriter(expression.position, lambdaCW, tag.method, null, methodDescriptor, null, "java/lang/Override");
|
|
3963
|
+ functionWriter.start();
|
|
3964
|
+
|
|
3965
|
+ //this.wrapped
|
|
3966
|
+ functionWriter.loadObject(0);
|
|
3967
|
+ functionWriter.getField(className, "wrapped", wrappedSignature);
|
|
3968
|
+
|
|
3969
|
+ //Load all function parameters
|
|
3970
|
+ {
|
|
3971
|
+ final Class<?>[] methodParameterTypes = functionalInterfaceMethod.getParameterTypes();
|
|
3972
|
+ for (int i = 0; i < methodParameterTypes.length; i++) {
|
|
3973
|
+ functionWriter.load(Type.getType(methodParameterTypes[i]), i + 1);
|
|
3974
|
+ }
|
|
3975
|
+ }
|
|
3976
|
+
|
|
3977
|
+ //Invokes the wrapped interface's method and returns the result
|
|
3978
|
+ functionWriter.invokeInterface(wrappedMethod);
|
|
3979
|
+ functionWriter.returnType(context.getType(((FunctionTypeID) expression.value.type.type).header.getReturnType()));
|
|
3980
|
+
|
|
3981
|
+ functionWriter.ret();
|
|
3982
|
+ functionWriter.end();
|
|
3983
|
+ }
|
|
3984
|
+
|
|
3985
|
+
|
3983
|
3986
|
lambdaCW.visitEnd();
|
3984
|
|
-
|
3985
|
3987
|
context.register(className, lambdaCW.toByteArray());
|
3986
|
|
-
|
3987
|
|
- try (FileOutputStream out = new FileOutputStream(className + ".class")) {
|
3988
|
|
- out.write(lambdaCW.toByteArray());
|
3989
|
|
- } catch (IOException e) {
|
3990
|
|
- e.printStackTrace();
|
|
3988
|
+
|
|
3989
|
+ javaWriter.newObject(className);
|
|
3990
|
+ javaWriter.dupX1();
|
|
3991
|
+ javaWriter.swap();
|
|
3992
|
+ javaWriter.invokeSpecial(className, "<init>", constructorDesc);
|
|
3993
|
+
|
|
3994
|
+ //Debug-only, remove later
|
|
3995
|
+ if(true) {
|
|
3996
|
+ try (FileOutputStream out = new FileOutputStream(className + ".class")) {
|
|
3997
|
+ out.write(lambdaCW.toByteArray());
|
|
3998
|
+ } catch (IOException e) {
|
|
3999
|
+ e.printStackTrace();
|
|
4000
|
+ }
|
3991
|
4001
|
}
|
3992
|
4002
|
}
|
3993
|
4003
|
|