|
@@ -5,8 +5,10 @@ import org.objectweb.asm.Label;
|
5
|
5
|
import org.objectweb.asm.Opcodes;
|
6
|
6
|
import org.objectweb.asm.Type;
|
7
|
7
|
import org.openzen.zenscript.codemodel.CompareType;
|
|
8
|
+import org.openzen.zenscript.codemodel.FunctionParameter;
|
8
|
9
|
import org.openzen.zenscript.codemodel.expression.*;
|
9
|
10
|
import org.openzen.zenscript.codemodel.expression.switchvalue.VariantOptionSwitchValue;
|
|
11
|
+import org.openzen.zenscript.codemodel.generic.TypeParameter;
|
10
|
12
|
import org.openzen.zenscript.codemodel.member.ref.DefinitionMemberRef;
|
11
|
13
|
import org.openzen.zenscript.codemodel.member.ref.FieldMemberRef;
|
12
|
14
|
import org.openzen.zenscript.codemodel.statement.ReturnStatement;
|
|
@@ -3893,6 +3895,13 @@ public class JavaExpressionVisitor implements ExpressionVisitor<Void>, JavaNativ
|
3893
|
3895
|
@Override
|
3894
|
3896
|
public Void visitStorageCast(StorageCastExpression expression) {
|
3895
|
3897
|
expression.value.accept(this);
|
|
3898
|
+
|
|
3899
|
+ {
|
|
3900
|
+ final StorageTag specifiedStorage = expression.type.getSpecifiedStorage();
|
|
3901
|
+ if(specifiedStorage instanceof JavaFunctionalInterfaceStorageTag) {
|
|
3902
|
+ visitFunctionalInterfaceWrapping(expression, (JavaFunctionalInterfaceStorageTag) specifiedStorage);
|
|
3903
|
+ }
|
|
3904
|
+ }
|
3896
|
3905
|
|
3897
|
3906
|
if (expression.type.isDestructible()) { // only destructible types matter here; nondestructible types never need conversion
|
3898
|
3907
|
StorageTag fromTag = expression.value.type.getActualStorage();
|
|
@@ -3910,6 +3919,77 @@ public class JavaExpressionVisitor implements ExpressionVisitor<Void>, JavaNativ
|
3910
|
3919
|
|
3911
|
3920
|
return null;
|
3912
|
3921
|
}
|
|
3922
|
+
|
|
3923
|
+ private void visitFunctionalInterfaceWrapping(StorageCastExpression expression, JavaFunctionalInterfaceStorageTag tag) {
|
|
3924
|
+ final Method functionalInterfaceMethod = tag.functionalInterfaceMethod;
|
|
3925
|
+
|
|
3926
|
+ final String wrappedSignature = context.getDescriptor(expression.type);
|
|
3927
|
+ final String wrappedMethodName = "accept";
|
|
3928
|
+ final String constructorDesc = "(" + wrappedSignature + ")V";
|
|
3929
|
+
|
|
3930
|
+ final String className = context.getLambdaCounter();
|
|
3931
|
+ final String descriptor = Type.getMethodDescriptor(functionalInterfaceMethod);
|
|
3932
|
+ //ddd
|
|
3933
|
+ final String methodName = functionalInterfaceMethod.getName();
|
|
3934
|
+ 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);
|
|
3947
|
+ final ClassWriter lambdaCW = new JavaClassWriter(ClassWriter.COMPUTE_FRAMES);
|
|
3948
|
+ 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);
|
|
3975
|
+ }
|
|
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();
|
|
3983
|
+ lambdaCW.visitEnd();
|
|
3984
|
+
|
|
3985
|
+ 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();
|
|
3991
|
+ }
|
|
3992
|
+ }
|
3913
|
3993
|
|
3914
|
3994
|
@Override
|
3915
|
3995
|
public Void visitSupertypeCast(SupertypeCastExpression expression) {
|