浏览代码

Java Bytecode Array Constructor: Finished Projection function invocation

kindlich 5 年前
父节点
当前提交
6f95dd3ff9
找不到此签名对应的密钥

+ 4
- 4
JavaBytecodeCompiler/src/main/java/org/openzen/zenscript/javabytecode/compiler/ArrayInitializerHelper.java 查看文件

@@ -137,12 +137,12 @@ class ArrayInitializerHelper {
137 137
 	}
138 138
 
139 139
 	/**
140
-	 * Checks if an expression can be inlined
140
+	 * Checks if an expression can be inLined
141 141
 	 *
142 142
 	 * @param expression Expression to check for.
143
-	 * @return can expression be inlined
143
+	 * @return can expression be inLined
144 144
 	 */
145
-	static boolean canBeInlined(Expression expression) {
145
+	static boolean canBeInLined(Expression expression) {
146 146
 		while (expression instanceof StorageCastExpression)
147 147
 			expression = ((StorageCastExpression) expression).value;
148 148
 
@@ -162,7 +162,7 @@ class ArrayInitializerHelper {
162 162
 	 * @param currentArrayType  The current type of the array, reduced during the recursions of the functions
163 163
 	 * @param innermostFunction The function that will decide what to add to the array, needs to increase the stack size by one and may not touch the other stacks!
164 164
 	 */
165
-	private static void visitMultiDimArray(JavaWriter javaWriter, int[] sizeLocations, int[] counterLocations, int dim, Type currentArrayType, InnermostFunction innermostFunction) {
165
+	static void visitMultiDimArray(JavaWriter javaWriter, int[] sizeLocations, int[] counterLocations, int dim, Type currentArrayType, InnermostFunction innermostFunction) {
166 166
 		final Label begin = new Label();
167 167
 		final Label end = new Label();
168 168
 		javaWriter.label(begin);

+ 64
- 61
JavaBytecodeCompiler/src/main/java/org/openzen/zenscript/javabytecode/compiler/JavaExpressionVisitor.java 查看文件

@@ -8,7 +8,6 @@ import org.openzen.zenscript.codemodel.CompareType;
8 8
 import org.openzen.zenscript.codemodel.FunctionParameter;
9 9
 import org.openzen.zenscript.codemodel.expression.*;
10 10
 import org.openzen.zenscript.codemodel.expression.switchvalue.VariantOptionSwitchValue;
11
-import org.openzen.zenscript.codemodel.generic.TypeParameter;
12 11
 import org.openzen.zenscript.codemodel.member.ref.DefinitionMemberRef;
13 12
 import org.openzen.zenscript.codemodel.member.ref.FieldMemberRef;
14 13
 import org.openzen.zenscript.codemodel.statement.ReturnStatement;
@@ -1897,7 +1896,7 @@ public class JavaExpressionVisitor implements ExpressionVisitor<Void>, JavaNativ
1897 1896
 		final JavaWriter functionWriter;
1898 1897
 		
1899 1898
 		//Bridge method!!!
1900
-		if(!Objects.equals(methodInfo.descriptor, signature)) {
1899
+		if (!Objects.equals(methodInfo.descriptor, signature)) {
1901 1900
 			final JavaMethod bridgeMethodInfo = new JavaMethod(methodInfo.cls, methodInfo.kind, methodInfo.name, methodInfo.compile, methodInfo.descriptor, methodInfo.modifiers | JavaModifiers.BRIDGE | JavaModifiers.SYNTHETIC, methodInfo.genericResult, methodInfo.typeParameterArguments);
1902 1901
 			final JavaWriter bridgeWriter = new JavaWriter(expression.position, lambdaCW, bridgeMethodInfo, null, methodInfo.descriptor, null, "java/lang/Override");
1903 1902
 			bridgeWriter.start();
@@ -1909,7 +1908,9 @@ public class JavaExpressionVisitor implements ExpressionVisitor<Void>, JavaNativ
1909 1908
 				final FunctionParameter functionParameter = expression.header.parameters[i];
1910 1909
 				final Type type = context.getType(functionParameter.type);
1911 1910
 				bridgeWriter.load(type, i + 1);
1912
-				bridgeWriter.checkCast(type);
1911
+				if (!CompilerUtils.isPrimitive(functionParameter.type.type)) {
1912
+					bridgeWriter.checkCast(type);
1913
+				}
1913 1914
 			}
1914 1915
 			
1915 1916
 			bridgeWriter.invokeVirtual(new JavaMethod(JavaClass.fromInternalName(className, JavaClass.Kind.CLASS), methodInfo.kind, methodInfo.name, methodInfo.compile, signature, methodInfo.modifiers, methodInfo.genericResult));
@@ -3338,60 +3339,56 @@ public class JavaExpressionVisitor implements ExpressionVisitor<Void>, JavaNativ
3338 3339
 				return;
3339 3340
 			}
3340 3341
 			case ARRAY_CONSTRUCTOR_LAMBDA: {
3341
-				ArrayTypeID type = (ArrayTypeID) expression.type.type;
3342
-
3343
-				if (type.dimension == 1) {
3344
-					// array = new T[arguments[0]]
3345
-					// lambda = arguments[1]
3346
-					// for (int i = 0; i < array.length; i++)
3347
-					//    array[i] = lambda.invoke(i);
3348
-					//
3349
-					// NOTE: arguments[1] can be a FunctionExpression; this can be optimized by running it inline
3350
-					throw new UnsupportedOperationException("Not yet supported!");
3351
-				} else {
3352
-					// TODO: implement
3353
-					throw new UnsupportedOperationException("Not yet supported!");
3354
-				}
3342
+				
3343
+				//Labels
3344
+				final Label begin = new Label();
3345
+				final Label end = new Label();
3346
+				javaWriter.label(begin);
3347
+				
3348
+				final Type ASMElementType = context.getType(expression.type);
3349
+				final int dimension = ((ArrayTypeID) expression.type.type).dimension;
3350
+				final int[] arraySizes = ArrayInitializerHelper.getArraySizeLocationsFromConstructor(dimension, expression.arguments.arguments, this);
3351
+				ArrayInitializerHelper.visitMultiDimArray(javaWriter, arraySizes, new int[dimension], dimension, ASMElementType, (elementType, counterLocations) -> {
3352
+					expression.arguments.arguments[dimension].accept(this);
3353
+					for (int counterLocation : counterLocations) {
3354
+						javaWriter.loadInt(counterLocation);
3355
+					}
3356
+					javaWriter.invokeInterface(context.getFunctionalInterface(expression.arguments.arguments[dimension].type));
3357
+				});
3358
+				javaWriter.label(end);
3359
+				return;
3355 3360
 			}
3356 3361
 			case ARRAY_CONSTRUCTOR_PROJECTED: {
3357
-
3358
-
3359 3362
 				ArrayTypeID type = (ArrayTypeID) expression.type.type;
3360
-
3363
+				
3364
+				//Labels
3361 3365
 				final Label begin = new Label();
3362 3366
 				final Label end = new Label();
3363
-
3364 3367
 				javaWriter.label(begin);
3365
-				expression.arguments.arguments[0].accept(this); //Origin array
3368
+				
3369
+				//Origin Array
3370
+				expression.arguments.arguments[0].accept(this);
3366 3371
 				final Type originArrayType = context.getType(expression.arguments.arguments[0].type);
3367 3372
 				final int originArrayLocation = javaWriter.local(originArrayType);
3368 3373
 				javaWriter.storeObject(originArrayLocation);
3369 3374
 				Type destinationArrayType = context.getType(expression.type);
3370
-
3371
-
3372
-				final boolean canBeInlined = ArrayInitializerHelper.canBeInlined(expression.arguments.arguments[1]);
3373
-				final Type functionType;    //Only used if not inline able
3374
-				final int functionLocation; //Only used if not inline able
3375
-				if (!canBeInlined) {
3376
-					expression.arguments.arguments[1].accept(this); //Projection Function
3377
-					functionType = context.getType(expression.arguments.arguments[1].type);
3378
-					functionLocation = javaWriter.local(functionType);
3379
-					javaWriter.storeObject(functionLocation);
3380
-					javaWriter.addVariableInfo(new JavaLocalVariableInfo(functionType, functionLocation, begin, "projectionFunction", end));
3381
-				}
3382
-
3383
-				final int[] arraySizes = ArrayInitializerHelper.getArraySizeLocationsProjected(type.dimension, originArrayType, originArrayLocation, javaWriter);
3384
-				ArrayInitializerHelper.visitProjected(javaWriter, arraySizes, type.dimension, originArrayLocation, originArrayType, destinationArrayType,
3385
-						(elementType, counterLocations) -> {
3386
-							if (canBeInlined) {
3375
+				
3376
+				
3377
+				final boolean canBeInLined = ArrayInitializerHelper.canBeInLined(expression.arguments.arguments[1]);
3378
+				if (canBeInLined) {
3379
+					//We can inline, so do it
3380
+					final int[] arraySizes = ArrayInitializerHelper.getArraySizeLocationsProjected(type.dimension, originArrayType, originArrayLocation, javaWriter);
3381
+					final Type projectedElementType = Type.getType(originArrayType.getDescriptor().substring(type.dimension));
3382
+					ArrayInitializerHelper.visitProjected(javaWriter, arraySizes, type.dimension, originArrayLocation, originArrayType, destinationArrayType,
3383
+							(elementType, counterLocations) -> {
3387 3384
 								Label inlineBegin = new Label();
3388 3385
 								Label inlineEnd = new Label();
3389 3386
 								javaWriter.label(inlineBegin);
3390
-								final Type projectedElementType = Type.getType(originArrayType.getDescriptor().substring(type.dimension));
3387
+								
3391 3388
 								final int projectedElementLocal = javaWriter.local(projectedElementType);
3392 3389
 								javaWriter.store(projectedElementType, projectedElementLocal);
3393
-
3394
-
3390
+								
3391
+								
3395 3392
 								JavaExpressionVisitor visitor = new JavaExpressionVisitor(context, module, javaWriter) {
3396 3393
 									@Override
3397 3394
 									public Void visitGetFunctionParameter(GetFunctionParameterExpression expression) {
@@ -3399,40 +3396,46 @@ public class JavaExpressionVisitor implements ExpressionVisitor<Void>, JavaNativ
3399 3396
 										return null;
3400 3397
 									}
3401 3398
 								};
3402
-
3399
+								
3403 3400
 								Expression funcExpression = expression.arguments.arguments[1];
3404 3401
 								while (funcExpression instanceof StorageCastExpression) {
3405 3402
 									funcExpression = ((StorageCastExpression) funcExpression).value;
3406 3403
 								}
3407
-
3404
+								
3408 3405
 								if (funcExpression instanceof FunctionExpression && ((FunctionExpression) funcExpression).body instanceof ReturnStatement) {
3409 3406
 									((ReturnStatement) ((FunctionExpression) funcExpression).body).value.accept(visitor);
3410 3407
 									javaWriter.addVariableInfo(new JavaLocalVariableInfo(projectedElementType, projectedElementLocal, inlineBegin, ((FunctionExpression) funcExpression).header.parameters[0].name, inlineEnd));
3411 3408
 								} else throw new IllegalStateException("Trying to inline a non-inlineable expression");
3412
-
3413
-
3409
+								
3410
+								
3414 3411
 								javaWriter.label(inlineEnd);
3415
-							} else {
3412
+							});
3413
+				} else {
3414
+					//We cannot inline, so get a hold of the function expression and apply it to every
3415
+					expression.arguments.arguments[1].accept(this); //Projection Function
3416
+					final Type functionType = context.getType(expression.arguments.arguments[1].type);
3417
+					final int functionLocation = javaWriter.local(functionType);
3418
+					javaWriter.storeObject(functionLocation);
3419
+					javaWriter.addVariableInfo(new JavaLocalVariableInfo(functionType, functionLocation, begin, "projectionFunction", end));
3420
+					final int[] arraySizes = ArrayInitializerHelper.getArraySizeLocationsProjected(type.dimension, originArrayType, originArrayLocation, javaWriter);
3421
+					ArrayInitializerHelper.visitProjected(javaWriter, arraySizes, type.dimension, originArrayLocation, originArrayType, destinationArrayType,
3422
+							(elementType, counterLocations) -> {
3416 3423
 								//Apply function here
3417
-								//javaWriter.loadObject(functionLocation);
3418
-								//javaWriter.swap();
3419
-
3420
-								//TODO invoke?
3421
-								//javaWriter.invokeVirtual(new JavaMethod(JavaClass.fromInternalName("lambda1", JavaClass.Kind.CLASS), JavaMethod.Kind.INSTANCE, "accept", true, "(Ljava/lang/String;)Ljava/lang/String;", 0, false));
3422
-
3423
-								//FIXME Critical! Currently returning the same object!
3424
-								//throw new UnsupportedOperationException("Cannot use projection functions yet!");
3425
-							}
3426
-						});
3427
-
3428
-
3424
+								javaWriter.loadObject(functionLocation);
3425
+								javaWriter.swap();
3426
+								
3427
+								javaWriter.invokeInterface(context.getFunctionalInterface(expression.arguments.arguments[1].type));
3428
+							});
3429
+				}
3430
+				
3431
+				
3429 3432
 				javaWriter.label(end);
3430 3433
 				return;
3431
-
3434
+				
3432 3435
 			}
3433 3436
 			case ARRAY_CONSTRUCTOR_PROJECTED_INDEXED: {
3434 3437
 				ArrayTypeID type = (ArrayTypeID) expression.type.type;
3435
-
3438
+				
3436 3439
 				if (type.dimension == 1) {
3437 3440
 					// original = arguments[0] (this is an array)
3438 3441
 					// projector = arguments[1] (this is a lambda with 2 parameters)

正在加载...
取消
保存