|
@@ -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)
|