Kaynağa Gözat

Better be save than sorry and commit before something happens again...

kindlich 6 yıl önce
ebeveyn
işleme
c754619684
Veri tabanında bu imza için bilinen anahtar bulunamadı

+ 23
- 0
JavaBytecodeCompiler/src/main/java/org/openzen/zenscript/javabytecode/compiler/CompilerUtils.java Dosyayı Görüntüle

@@ -3,6 +3,8 @@ package org.openzen.zenscript.javabytecode.compiler;
3 3
 import org.objectweb.asm.Type;
4 4
 import org.openzen.zenscript.codemodel.FunctionHeader;
5 5
 import org.openzen.zenscript.codemodel.FunctionParameter;
6
+import org.openzen.zenscript.codemodel.type.BasicTypeID;
7
+import org.openzen.zenscript.codemodel.type.ITypeID;
6 8
 
7 9
 public class CompilerUtils {
8 10
     public static String calcDesc(FunctionHeader header, boolean isEnum) {
@@ -25,4 +27,25 @@ public class CompilerUtils {
25 27
         signatureBuilder.append(")").append(header.returnType.accept(JavaTypeVisitor.INSTANCE).getDescriptor());
26 28
         return signatureBuilder.toString();
27 29
     }
30
+
31
+    public static boolean isPrimitive(ITypeID id) {
32
+        if(id instanceof BasicTypeID) {
33
+            switch ((BasicTypeID) id) {
34
+                case BOOL:
35
+                case BYTE:
36
+                case SBYTE:
37
+                case SHORT:
38
+                case USHORT:
39
+                case INT:
40
+                case UINT:
41
+                case LONG:
42
+                case ULONG:
43
+                case FLOAT:
44
+                case DOUBLE:
45
+                case CHAR:
46
+                    return true;
47
+            }
48
+        }
49
+        return false;
50
+    }
28 51
 }

+ 119
- 11
JavaBytecodeCompiler/src/main/java/org/openzen/zenscript/javabytecode/compiler/JavaExpressionVisitor.java Dosyayı Görüntüle

@@ -2,17 +2,16 @@ package org.openzen.zenscript.javabytecode.compiler;
2 2
 
3 3
 import org.objectweb.asm.Label;
4 4
 import org.objectweb.asm.Type;
5
-import org.openzen.zenscript.codemodel.definition.ZSPackage;
6
-import org.objectweb.asm.Type;
5
+import org.openzen.zenscript.codemodel.CompareType;
7 6
 import org.openzen.zenscript.codemodel.expression.*;
8 7
 import org.openzen.zenscript.codemodel.member.DefinitionMember;
9 8
 import org.openzen.zenscript.codemodel.type.DefinitionTypeID;
9
+import org.openzen.zenscript.codemodel.type.ITypeID;
10 10
 import org.openzen.zenscript.implementations.IntRange;
11 11
 import org.openzen.zenscript.javabytecode.*;
12 12
 import org.openzen.zenscript.shared.CompileException;
13 13
 import org.openzen.zenscript.shared.CompileExceptionCode;
14 14
 
15
-
16 15
 import java.util.Map;
17 16
 
18 17
 public class JavaExpressionVisitor implements ExpressionVisitor<Void> {
@@ -29,8 +28,34 @@ public class JavaExpressionVisitor implements ExpressionVisitor<Void> {
29 28
         this.isInit = isInit;
30 29
     }
31 30
 
31
+    private static Class<?> getForEquals(ITypeID id) {
32
+        if (CompilerUtils.isPrimitive(id))
33
+            return id.accept(JavaTypeClassVisitor.INSTANCE);
34
+        return Object.class;
35
+    }
36
+
32 37
     @Override
33 38
     public Void visitAndAnd(AndAndExpression expression) {
39
+        Label end = new Label();
40
+        Label onFalse = new Label();
41
+
42
+        expression.left.accept(this);
43
+
44
+        javaWriter.ifEQ(onFalse);
45
+        expression.right.accept(this);
46
+
47
+        // //these two calls are redundant but make decompiled code look better. Keep?
48
+        // javaWriter.ifEQ(onFalse);
49
+        // javaWriter.iConst1();
50
+
51
+        javaWriter.goTo(end);
52
+
53
+        javaWriter.label(onFalse);
54
+        javaWriter.iConst0();
55
+
56
+
57
+        javaWriter.label(end);
58
+
34 59
         return null;
35 60
     }
36 61
 
@@ -50,6 +75,12 @@ public class JavaExpressionVisitor implements ExpressionVisitor<Void> {
50 75
 
51 76
     @Override
52 77
     public Void visitCompare(BasicCompareExpression expression) {
78
+        expression.left.accept(this);
79
+        expression.right.accept(this);
80
+        javaWriter.constant(expression.operator.name());
81
+
82
+        javaWriter.invokeStatic(ZenUtils.class, "compare", boolean.class, getForEquals(expression.left.type), getForEquals(expression.right.type), String.class);
83
+
53 84
         return null;
54 85
     }
55 86
 
@@ -67,6 +98,12 @@ public class JavaExpressionVisitor implements ExpressionVisitor<Void> {
67 98
 
68 99
     @Override
69 100
     public Void visitCallStatic(CallStaticExpression expression) {
101
+        for (Expression argument : expression.arguments.arguments) {
102
+            argument.accept(this);
103
+        }
104
+        //TODO: Test with actual static method
105
+        final JavaMethodInfo info = expression.member.getTag(JavaMethodInfo.class);
106
+        javaWriter.invokeStatic(info.javaClass.internalClassName, info.name, info.signature);
70 107
         return null;
71 108
     }
72 109
 
@@ -95,34 +132,65 @@ public class JavaExpressionVisitor implements ExpressionVisitor<Void> {
95 132
     public Void visitCapturedThis(CapturedThisExpression expression) {
96 133
         return null;
97 134
     }
98
-	
99
-	@Override
135
+
136
+    @Override
100 137
     public Void visitCast(CastExpression expression) {
101
-		expression.target.accept(this);
138
+        expression.target.accept(this);
102 139
         if (!checkAndExecuteByteCodeImplementation(expression.member) && !checkAndExecuteMethodInfo(expression.member))
103 140
             throw new IllegalStateException("Call target has no method info!");
104
-		
141
+
105 142
         return null;
106
-	}
143
+    }
107 144
 
108 145
     @Override
109 146
     public Void visitCheckNull(CheckNullExpression expression) {
147
+        final Label end = new Label();
148
+        expression.value.accept(this);
149
+        javaWriter.dup();
150
+        javaWriter.ifNonNull(end);
151
+        javaWriter.pop();
152
+        javaWriter.newObject(NullPointerException.class);
153
+        javaWriter.dup();
154
+        javaWriter.constant("Tried to convert a null value to nonnull type " + expression.type.accept(JavaTypeClassVisitor.INSTANCE).getSimpleName());
155
+        javaWriter.invokeSpecial(NullPointerException.class, "<init>", "(Ljava/lang/String;)V");
156
+        javaWriter.aThrow();
157
+        javaWriter.label(end);
158
+
110 159
         return null;
111 160
     }
112 161
 
113 162
     @Override
114 163
     public Void visitCoalesce(CoalesceExpression expression) {
164
+        final Label end = new Label();
165
+        expression.left.accept(this);
166
+        javaWriter.dup();
167
+        javaWriter.ifNonNull(end);
168
+        javaWriter.pop();
169
+        expression.right.accept(this);
170
+        javaWriter.label(end);
115 171
         return null;
116 172
     }
117 173
 
118 174
     @Override
119 175
     public Void visitConditional(ConditionalExpression expression) {
176
+        final Label end = new Label();
177
+        final Label onElse = new Label();
178
+        expression.condition.accept(this);
179
+        javaWriter.ifEQ(onElse);
180
+        expression.ifThen.accept(this);
181
+        javaWriter.goTo(end);
182
+        javaWriter.label(onElse);
183
+        expression.ifElse.accept(this);
184
+        javaWriter.label(end);
120 185
         return null;
121 186
     }
122 187
 
123 188
     @Override
124 189
     public Void visitConstantBool(ConstantBoolExpression expression) {
125
-        getJavaWriter().constant(expression.value);
190
+        if (expression.value)
191
+            javaWriter.iConst1();
192
+        else
193
+            javaWriter.iConst0();
126 194
         return null;
127 195
     }
128 196
 
@@ -211,16 +279,29 @@ public class JavaExpressionVisitor implements ExpressionVisitor<Void> {
211 279
 
212 280
     @Override
213 281
     public Void visitConstructorSuperCall(ConstructorSuperCallExpression expression) {
282
+        javaWriter.loadObject(0);
283
+        for (Expression argument : expression.arguments.arguments) {
284
+            argument.accept(this);
285
+        }
286
+        //No super calls in enums possible, and that's already handled in the enum constructor itself.
287
+        javaWriter.invokeSpecial(expression.objectType.accept(JavaTypeClassVisitor.INSTANCE), "<init>", CompilerUtils.calcDesc(expression.constructor.header, false));
214 288
         return null;
215 289
     }
216 290
 
217 291
     @Override
218 292
     public Void visitEnumConstant(EnumConstantExpression expression) {
293
+        final Type type = expression.type.accept(JavaTypeVisitor.INSTANCE);
294
+        javaWriter.getStaticField(type.getInternalName(), expression.value.name, type.getDescriptor());
219 295
         return null;
220 296
     }
221 297
 
222 298
     @Override
223 299
     public Void visitEquals(EqualsExpression expression) {
300
+        expression.left.accept(this);
301
+        expression.right.accept(this);
302
+        javaWriter.constant(CompareType.EQ.name());
303
+        javaWriter.invokeStatic(ZenUtils.class, "compare", boolean.class, getForEquals(expression.left.type), getForEquals(expression.right.type), String.class);
304
+
224 305
         return null;
225 306
     }
226 307
 
@@ -231,6 +312,7 @@ public class JavaExpressionVisitor implements ExpressionVisitor<Void> {
231 312
 
232 313
     @Override
233 314
     public Void visitGenericCompare(GenericCompareExpression expression) {
315
+        //TODO: What am I supposed to do here?
234 316
         return null;
235 317
     }
236 318
 
@@ -286,7 +368,7 @@ public class JavaExpressionVisitor implements ExpressionVisitor<Void> {
286 368
 
287 369
     @Override
288 370
     public Void visitMakeConst(MakeConstExpression expression) {
289
-
371
+        //TODO: What am I supposed to do here?
290 372
         return null;
291 373
     }
292 374
 
@@ -308,7 +390,7 @@ public class JavaExpressionVisitor implements ExpressionVisitor<Void> {
308 390
     @Override
309 391
     public Void visitNew(NewExpression expression) {
310 392
         final String type;
311
-        if(expression.type instanceof DefinitionTypeID)
393
+        if (expression.type instanceof DefinitionTypeID)
312 394
             type = ((DefinitionTypeID) expression.type).definition.name;
313 395
         else
314 396
             type = Type.getDescriptor(expression.type.accept(JavaTypeClassVisitor.INSTANCE));
@@ -341,6 +423,26 @@ public class JavaExpressionVisitor implements ExpressionVisitor<Void> {
341 423
 
342 424
     @Override
343 425
     public Void visitOrOr(OrOrExpression expression) {
426
+        Label end = new Label();
427
+        Label onTrue = new Label();
428
+
429
+        expression.left.accept(this);
430
+
431
+        javaWriter.ifNE(onTrue);
432
+        expression.right.accept(this);
433
+
434
+        // //these two calls are redundant but make decompiled code look better. Keep?
435
+        // javaWriter.ifNE(onTrue);
436
+        // javaWriter.iConst0();
437
+
438
+        javaWriter.goTo(end);
439
+
440
+        javaWriter.label(onTrue);
441
+        javaWriter.iConst1();
442
+
443
+
444
+        javaWriter.label(end);
445
+
344 446
         return null;
345 447
     }
346 448
 
@@ -371,6 +473,10 @@ public class JavaExpressionVisitor implements ExpressionVisitor<Void> {
371 473
 
372 474
     @Override
373 475
     public Void visitSetFunctionParameter(SetFunctionParameterExpression expression) {
476
+        //TODO is static?
477
+        final boolean isStatic = false;
478
+        expression.value.accept(this);
479
+        javaWriter.store(expression.type.accept(JavaTypeVisitor.INSTANCE), isStatic ? expression.parameter.index : expression.parameter.index + 1);
374 480
         return null;
375 481
     }
376 482
 
@@ -422,6 +528,8 @@ public class JavaExpressionVisitor implements ExpressionVisitor<Void> {
422 528
 
423 529
     @Override
424 530
     public Void visitWrapOptional(WrapOptionalExpression expression) {
531
+        //TODO What am I supposed to do here?
532
+        expression.value.accept(this);
425 533
         return null;
426 534
     }
427 535
 

+ 1
- 1
JavaBytecodeCompiler/src/main/java/org/openzen/zenscript/javabytecode/compiler/JavaTypeClassVisitor.java Dosyayı Görüntüle

@@ -87,6 +87,6 @@ public class JavaTypeClassVisitor implements ITypeVisitor<Class> {
87 87
 
88 88
     @Override
89 89
     public Class visitOptional(OptionalTypeID optional) {
90
-        return null;
90
+        return optional.baseType.accept(this);
91 91
     }
92 92
 }

+ 4
- 0
JavaBytecodeCompiler/src/main/java/org/openzen/zenscript/javabytecode/compiler/JavaWriter.java Dosyayı Görüntüle

@@ -751,6 +751,10 @@ public class JavaWriter {
751 751
         visitor.visitMethodInsn(INVOKESPECIAL, owner, name, descriptor, false);
752 752
     }
753 753
 
754
+    public void invokeSpecial(Class owner, String name, String descriptor) {
755
+        invokeSpecial(Type.getInternalName(owner), name, descriptor);
756
+    }
757
+
754 758
     public void invoke(Class owner, String name, Class result, Class... arguments) {
755 759
         if (owner.isInterface()) {
756 760
             invokeInterface(owner, name, result, arguments);

+ 79
- 0
JavaBytecodeCompiler/src/main/java/org/openzen/zenscript/javabytecode/compiler/ZenUtils.java Dosyayı Görüntüle

@@ -0,0 +1,79 @@
1
+package org.openzen.zenscript.javabytecode.compiler;
2
+
3
+import org.openzen.zenscript.codemodel.CompareType;
4
+
5
+import java.util.Objects;
6
+
7
+public class ZenUtils {
8
+
9
+    // ###############
10
+    // ### Compare ###
11
+    // ###############
12
+
13
+    //TODO how to compare them?
14
+    public static boolean compare(Object a, Object b, String compareType) {
15
+        CompareType type = CompareType.valueOf(compareType);
16
+        if (type == CompareType.SAME || type == CompareType.NOTSAME) {
17
+            final boolean same = a == b;
18
+            return (type == CompareType.SAME) == same;
19
+        }
20
+
21
+        if (a instanceof Comparable)
22
+            return checkCompareReturn(((Comparable) a).compareTo(b), type);
23
+        return false;
24
+    }
25
+
26
+
27
+    public static boolean compare(boolean a, boolean b, String compareType) {
28
+        return checkCompareReturn(Boolean.compare(a, b), CompareType.valueOf(compareType));
29
+    }
30
+
31
+    public static boolean compare(int a, int b, String compareType) {
32
+        return checkCompareReturn(Integer.compare(a, b), CompareType.valueOf(compareType));
33
+    }
34
+
35
+    public static boolean compare(char a, char b, String compareType) {
36
+        return checkCompareReturn(Character.compare(a, b), CompareType.valueOf(compareType));
37
+    }
38
+
39
+    public static boolean compare(byte a, byte b, String compareType) {
40
+        return checkCompareReturn(Byte.compare(a, b), CompareType.valueOf(compareType));
41
+    }
42
+
43
+    public static boolean compare(short a, short b, String compareType) {
44
+        return checkCompareReturn(Short.compare(a, b), CompareType.valueOf(compareType));
45
+    }
46
+
47
+    public static boolean compare(long a, long b, String compareType) {
48
+        return checkCompareReturn(Long.compare(a, b), CompareType.valueOf(compareType));
49
+    }
50
+
51
+    public static boolean compare(float a, float b, String compareType) {
52
+        return checkCompareReturn(Float.compare(a, b), CompareType.valueOf(compareType));
53
+    }
54
+
55
+    public static boolean compare(double a, double b, String compareType) {
56
+        return checkCompareReturn(Double.compare(a, b), CompareType.valueOf(compareType));
57
+    }
58
+
59
+    private static boolean checkCompareReturn(int compareResult, CompareType type) {
60
+        switch (type) {
61
+            case LT:
62
+                return compareResult < 0;
63
+            case GT:
64
+                return compareResult > 0;
65
+            case EQ:
66
+            case SAME:
67
+                return compareResult == 0;
68
+            case NOTSAME:
69
+            case NE:
70
+                return compareResult != 0;
71
+            case LE:
72
+                return compareResult <= 0;
73
+            case GE:
74
+                return compareResult >= 0;
75
+            default:
76
+                return false;
77
+        }
78
+    }
79
+}

Loading…
İptal
Kaydet