Browse Source

Functional Interfaces Bytecode Step I

Directly using the lambda where the functional interface is requested works.
The lambda class will then directly implement the functionalInterface and not use a wrapper class
kindlich 6 years ago
parent
commit
476e1b350a
No known key found for this signature in database

+ 2
- 0
DrawableGui/src/main/java/org/openzen/drawablegui/live/MutableLiveBool.java View File

@@ -5,6 +5,8 @@
5 5
  */
6 6
 package org.openzen.drawablegui.live;
7 7
 
8
+import live.LiveBool;
9
+
8 10
 /**
9 11
  *
10 12
  * @author Hoofdgebruiker

+ 2
- 0
DrawableGui/src/main/java/org/openzen/drawablegui/live/MutableLiveString.java View File

@@ -5,6 +5,8 @@
5 5
  */
6 6
 package org.openzen.drawablegui.live;
7 7
 
8
+import live.LiveString;
9
+
8 10
 /**
9 11
  *
10 12
  * @author Hoofdgebruiker

+ 38
- 15
JavaBytecodeCompiler/src/main/java/org/openzen/zenscript/javabytecode/compiler/JavaExpressionVisitor.java View File

@@ -22,6 +22,7 @@ import org.openzen.zenscript.javashared.*;
22 22
 
23 23
 import java.io.FileOutputStream;
24 24
 import java.io.IOException;
25
+import java.lang.reflect.Method;
25 26
 import java.lang.reflect.Modifier;
26 27
 import java.util.Arrays;
27 28
 import java.util.Comparator;
@@ -1867,17 +1868,39 @@ public class JavaExpressionVisitor implements ExpressionVisitor<Void>, JavaNativ
1867 1868
             return null;
1868 1869
         }*/
1869 1870
 
1870
-		final String descriptor = context.getMethodDescriptor(expression.header);
1871
-		final String signature = context.getMethodSignature(expression.header);
1872
-		final String signature2 = context.getMethodDescriptor(expression.header);
1873
-		final String name = context.getLambdaCounter();
1874
-
1875
-		final JavaMethod methodInfo = JavaMethod.getNativeVirtual(javaWriter.method.cls, "accept", descriptor);
1871
+		final String descriptor;
1872
+		final String signature;
1873
+		final String[] interfaces;
1874
+		final String methodName;
1875
+		final String className = context.getLambdaCounter();
1876
+		
1877
+		{//Fill the info above
1878
+			final StorageTag actualStorage = expression.type.getActualStorage();
1879
+			if (actualStorage instanceof JavaFunctionalInterfaceStorageTag) {
1880
+				//Let's implement the functional Interface instead
1881
+				final Method functionalInterfaceMethod = ((JavaFunctionalInterfaceStorageTag) actualStorage).functionalInterfaceMethod;
1882
+				
1883
+				descriptor = Type.getMethodDescriptor(functionalInterfaceMethod);
1884
+				//Should be the same, should it not?
1885
+				signature = context.getMethodSignature(expression.header);
1886
+				interfaces = new String[]{Type.getInternalName(functionalInterfaceMethod.getDeclaringClass())};
1887
+				methodName = functionalInterfaceMethod.getName();
1888
+			} else {
1889
+				//Normal way, no casting to functional interface
1890
+				descriptor = context.getMethodDescriptor(expression.header);
1891
+				signature = context.getMethodSignature(expression.header);
1892
+				interfaces = new String[]{context.getInternalName(new FunctionTypeID(null, expression.header).stored(UniqueStorageTag.INSTANCE))};
1893
+				methodName = "accept";
1894
+			}
1895
+		}
1896
+		
1897
+		
1898
+		final JavaMethod methodInfo = JavaMethod.getNativeVirtual(javaWriter.method.cls, methodName, descriptor);
1876 1899
 		final ClassWriter lambdaCW = new JavaClassWriter(ClassWriter.COMPUTE_FRAMES);
1877
-		lambdaCW.visit(Opcodes.V1_8, Opcodes.ACC_PUBLIC, name, null, "java/lang/Object", new String[]{context.getInternalName(new FunctionTypeID(null, expression.header).stored(UniqueStorageTag.INSTANCE))});
1900
+		lambdaCW.visit(Opcodes.V1_8, Opcodes.ACC_PUBLIC, className, null, "java/lang/Object", interfaces);
1878 1901
 		final JavaWriter functionWriter = new JavaWriter(expression.position, lambdaCW, methodInfo, null, signature, null, "java/lang/Override");
1879 1902
 
1880
-		javaWriter.newObject(name);
1903
+		javaWriter.newObject(className);
1881 1904
 		javaWriter.dup();
1882 1905
 
1883 1906
 		final String constructorDesc = calcFunctionSignature(expression.closure);
@@ -1898,12 +1921,12 @@ public class JavaExpressionVisitor implements ExpressionVisitor<Void>, JavaNativ
1898 1921
 			capture.accept(this);
1899 1922
 
1900 1923
 			constructorWriter.load(type, i);
1901
-			constructorWriter.putField(name, "captured" + i, type.getDescriptor());
1924
+			constructorWriter.putField(className, "captured" + i, type.getDescriptor());
1902 1925
 		}
1903 1926
 
1904 1927
 		constructorWriter.pop();
1905 1928
 
1906
-		javaWriter.invokeSpecial(name, "<init>", constructorDesc);
1929
+		javaWriter.invokeSpecial(className, "<init>", constructorDesc);
1907 1930
 
1908 1931
 		constructorWriter.ret();
1909 1932
 		constructorWriter.end();
@@ -1917,7 +1940,7 @@ public class JavaExpressionVisitor implements ExpressionVisitor<Void>, JavaNativ
1917 1940
 			public Void visitGetLocalVariable(GetLocalVariableExpression varExpression) {
1918 1941
 				final int position = calculateMemberPosition(varExpression, expression);
1919 1942
 				functionWriter.loadObject(0);
1920
-				functionWriter.getField(name, "captured" + position, context.getDescriptor(varExpression.variable.type));
1943
+				functionWriter.getField(className, "captured" + position, context.getDescriptor(varExpression.variable.type));
1921 1944
 				return null;
1922 1945
 			}
1923 1946
 
@@ -1925,7 +1948,7 @@ public class JavaExpressionVisitor implements ExpressionVisitor<Void>, JavaNativ
1925 1948
 			public Void visitCapturedParameter(CapturedParameterExpression varExpression) {
1926 1949
 				final int position = calculateMemberPosition(varExpression, expression);
1927 1950
 				functionWriter.loadObject(0);
1928
-				functionWriter.getField(name, "captured" + position, context.getDescriptor(varExpression.parameter.type));
1951
+				functionWriter.getField(className, "captured" + position, context.getDescriptor(varExpression.parameter.type));
1929 1952
 				return null;
1930 1953
 			}
1931 1954
 		});
@@ -1936,9 +1959,9 @@ public class JavaExpressionVisitor implements ExpressionVisitor<Void>, JavaNativ
1936 1959
 		functionWriter.end();
1937 1960
 		lambdaCW.visitEnd();
1938 1961
 
1939
-		context.register(name, lambdaCW.toByteArray());
1962
+		context.register(className, lambdaCW.toByteArray());
1940 1963
 
1941
-		try (FileOutputStream out = new FileOutputStream(name + ".class")) {
1964
+		try (FileOutputStream out = new FileOutputStream(className + ".class")) {
1942 1965
 			out.write(lambdaCW.toByteArray());
1943 1966
 		} catch (IOException e) {
1944 1967
 			e.printStackTrace();
@@ -3880,7 +3903,7 @@ public class JavaExpressionVisitor implements ExpressionVisitor<Void>, JavaNativ
3880 3903
 			} else if (fromTag == UniqueStorageTag.INSTANCE && JavaTypeUtils.isShared(toTag)) {
3881 3904
 				// new Shared<T>(value)
3882 3905
 				javaWriter.newObject("zsynthetic/Shared");
3883
-				javaWriter.dup();
3906
+				javaWriter.dupX1();
3884 3907
 				javaWriter.invokeSpecial(SHARED_INIT);
3885 3908
 			}
3886 3909
 		}

+ 2
- 2
JavaShared/src/main/java/org/openzen/zenscript/javashared/JavaFunctionalInterfaceStorageTag.java View File

@@ -14,10 +14,10 @@ import org.openzen.zenscript.codemodel.type.storage.StorageType;
14 14
 import org.openzen.zenscript.codemodel.type.storage.UniqueStorageTag;
15 15
 
16 16
 public class JavaFunctionalInterfaceStorageTag implements StorageTag {
17
-	public final Method funtionalInterfaceMethod;
17
+	public final Method functionalInterfaceMethod;
18 18
 	
19 19
 	public JavaFunctionalInterfaceStorageTag(Method functionalInterfaceMethod) {
20
-		this.funtionalInterfaceMethod = functionalInterfaceMethod;
20
+		this.functionalInterfaceMethod = functionalInterfaceMethod;
21 21
 	}
22 22
 
23 23
 	@Override

Loading…
Cancel
Save