Browse Source

Performed some minor simplifications on the java writer, removed some duplicate code

Stan Hebben 6 years ago
parent
commit
47f68df4f8

+ 6
- 0
JavaBytecodeCompiler/src/main/java/org/openzen/zenscript/javabytecode/JavaClassInfo.java View File

5
  */
5
  */
6
 package org.openzen.zenscript.javabytecode;
6
 package org.openzen.zenscript.javabytecode;
7
 
7
 
8
+import org.objectweb.asm.Type;
9
+
8
 /**
10
 /**
9
  *
11
  *
10
  * @author Hoofdgebruiker
12
  * @author Hoofdgebruiker
11
  */
13
  */
12
 public class JavaClassInfo {
14
 public class JavaClassInfo {
15
+	public static JavaClassInfo get(Class<?> cls) {
16
+		return new JavaClassInfo(Type.getInternalName(cls));
17
+	}
18
+	
13
 	public final String internalClassName;
19
 	public final String internalClassName;
14
 	
20
 	
15
 	public JavaClassInfo(String internalClassName) {
21
 	public JavaClassInfo(String internalClassName) {

+ 38
- 39
JavaBytecodeCompiler/src/main/java/org/openzen/zenscript/javabytecode/JavaCompiler.java View File

17
 import static org.openzen.zenscript.codemodel.type.member.BuiltinTypeMembers.*;
17
 import static org.openzen.zenscript.codemodel.type.member.BuiltinTypeMembers.*;
18
 
18
 
19
 import org.openzen.zenscript.javabytecode.compiler.JavaClassWriter;
19
 import org.openzen.zenscript.javabytecode.compiler.JavaClassWriter;
20
+import org.openzen.zenscript.javabytecode.compiler.JavaScriptFile;
20
 import org.openzen.zenscript.javabytecode.compiler.definitions.JavaDefinitionVisitor;
21
 import org.openzen.zenscript.javabytecode.compiler.definitions.JavaDefinitionVisitor;
21
 import org.openzen.zenscript.javabytecode.compiler.JavaStatementVisitor;
22
 import org.openzen.zenscript.javabytecode.compiler.JavaStatementVisitor;
22
 import org.openzen.zenscript.javabytecode.compiler.JavaWriter;
23
 import org.openzen.zenscript.javabytecode.compiler.JavaWriter;
129
 	}
130
 	}
130
 	
131
 	
131
 	private final JavaModule target;
132
 	private final JavaModule target;
132
-	private final Map<String, JavaClassWriter> scriptBlocks = new HashMap<>();
133
+	private final Map<String, JavaScriptFile> scriptBlocks = new HashMap<>();
133
 	private final JavaClassWriter scriptsClassWriter;
134
 	private final JavaClassWriter scriptsClassWriter;
134
 	private int generatedScriptBlockCounter = 0;
135
 	private int generatedScriptBlockCounter = 0;
135
 	private boolean finished = false;
136
 	private boolean finished = false;
141
 	public JavaCompiler(boolean debug) {
142
 	public JavaCompiler(boolean debug) {
142
 		target = new JavaModule();
143
 		target = new JavaModule();
143
 		
144
 		
144
-		scriptsClassWriter = new JavaClassWriter(ClassWriter.COMPUTE_FRAMES, true);
145
+		scriptsClassWriter = new JavaClassWriter(ClassWriter.COMPUTE_FRAMES);
145
 		scriptsClassWriter.visit(Opcodes.V1_8, Opcodes.ACC_PUBLIC, "Scripts", null, "java/lang/Object", null);
146
 		scriptsClassWriter.visit(Opcodes.V1_8, Opcodes.ACC_PUBLIC, "Scripts", null, "java/lang/Object", null);
146
 	}
147
 	}
147
 	
148
 	
148
 	public void addDefinition(HighLevelDefinition definition) {
149
 	public void addDefinition(HighLevelDefinition definition) {
149
-		// convert definition into java class
150
-
151
-		final String methodName = definition.position.filename.substring(0, definition.position.filename.lastIndexOf('.')).replace("/", "_");
152
-
153
-
154
-		if(!scriptBlocks.containsKey(methodName)) {
155
-			JavaClassWriter scriptFileWriter = new JavaClassWriter(ClassWriter.COMPUTE_FRAMES);
156
-			scriptFileWriter.visit(Opcodes.V1_8, Opcodes.ACC_PUBLIC, methodName, null, "java/lang/Object", null);
157
-			scriptBlocks.put(methodName, scriptFileWriter);
158
-		}
159
-
160
-		target.register(definition.name, definition.accept(new JavaDefinitionVisitor(scriptBlocks.get(methodName))));
161
-
150
+		String className = getClassName(definition.position.filename);
151
+		JavaScriptFile scriptFile = getScriptFile(className);
152
+		target.register(definition.name, definition.accept(new JavaDefinitionVisitor(scriptFile.classWriter)));
162
 	}
153
 	}
163
 	
154
 	
164
 	public void addScriptBlock(ScriptBlock script) {
155
 	public void addScriptBlock(ScriptBlock script) {
165
 		final SourceFile sourceFile = script.getTag(SourceFile.class);
156
 		final SourceFile sourceFile = script.getTag(SourceFile.class);
166
-		final String methodName;
167
-		if (sourceFile == null) {
168
-			methodName = "generatedBlock" + (generatedScriptBlockCounter++);
169
-		} else {
170
-			// TODO: remove special characters
171
-			System.out.println("Writing script: " + sourceFile.filename);
172
-			methodName = sourceFile.filename.substring(0, sourceFile.filename.lastIndexOf('.')).replace("/", "_");
173
-		}
174
-
175
-		if(!scriptBlocks.containsKey(methodName)) {
176
-			JavaClassWriter scriptFileWriter = new JavaClassWriter(ClassWriter.COMPUTE_FRAMES, true);
177
-			scriptFileWriter.visit(Opcodes.V1_8, Opcodes.ACC_PUBLIC, methodName, null, "java/lang/Object", null);
178
-			scriptBlocks.put(methodName, scriptFileWriter);
179
-		}
157
+		final String className = getClassName(sourceFile == null ? null : sourceFile.filename);
158
+		JavaScriptFile scriptFile = getScriptFile(className);
180
 
159
 
181
 		// convert scripts into methods (add them to a Scripts class?)
160
 		// convert scripts into methods (add them to a Scripts class?)
182
 		// (TODO: can we break very long scripts into smaller methods? for the extreme scripts)
161
 		// (TODO: can we break very long scripts into smaller methods? for the extreme scripts)
183
-		final JavaClassWriter visitor = scriptBlocks.get(methodName);
184
-		visitor.hasRun = true;
185
-		JavaMethodInfo method = new JavaMethodInfo(new JavaClassInfo(methodName), "run", "()V", Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC);
162
+		final JavaClassWriter visitor = scriptFile.classWriter;
163
+		JavaMethodInfo method = new JavaMethodInfo(new JavaClassInfo(className), "run", "()V", Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC);
164
+		scriptFile.scriptMethods.add(method);
165
+		
186
 		final JavaStatementVisitor statementVisitor = new JavaStatementVisitor(new JavaWriter(visitor, method, null, null));
166
 		final JavaStatementVisitor statementVisitor = new JavaStatementVisitor(new JavaWriter(visitor, method, null, null));
187
 		statementVisitor.start();
167
 		statementVisitor.start();
188
 		for (Statement statement : script.statements) {
168
 		for (Statement statement : script.statements) {
192
 		statementVisitor.end();
172
 		statementVisitor.end();
193
 	}
173
 	}
194
 	
174
 	
175
+	private String getClassName(String filename) {
176
+		if (filename == null) {
177
+			return "generatedBlock" + (generatedScriptBlockCounter++);
178
+		} else {
179
+			// TODO: remove special characters
180
+			System.out.println("Writing script: " + filename);
181
+			return filename.substring(0, filename.lastIndexOf('.')).replace("/", "_");
182
+		}
183
+	}
184
+	
185
+	private JavaScriptFile getScriptFile(String className) {
186
+		if (!scriptBlocks.containsKey(className)) {
187
+			JavaClassWriter scriptFileWriter = new JavaClassWriter(ClassWriter.COMPUTE_FRAMES);
188
+			scriptFileWriter.visit(Opcodes.V1_8, Opcodes.ACC_PUBLIC, className, null, "java/lang/Object", null);
189
+			scriptBlocks.put(className, new JavaScriptFile(scriptFileWriter));
190
+		}
191
+		
192
+		return scriptBlocks.get(className);
193
+	}
194
+	
195
 	public JavaModule finish() {
195
 	public JavaModule finish() {
196
 		if (finished)
196
 		if (finished)
197
 			throw new IllegalStateException("Already finished!");
197
 			throw new IllegalStateException("Already finished!");
200
 		JavaMethodInfo runMethod = new JavaMethodInfo(new JavaClassInfo("Scripts"), "run", "()V", Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC);
200
 		JavaMethodInfo runMethod = new JavaMethodInfo(new JavaClassInfo("Scripts"), "run", "()V", Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC);
201
 		final JavaWriter runWriter = new JavaWriter(scriptsClassWriter, runMethod, null, null);
201
 		final JavaWriter runWriter = new JavaWriter(scriptsClassWriter, runMethod, null, null);
202
 		runWriter.start();
202
 		runWriter.start();
203
-		for (Map.Entry<String, JavaClassWriter> entry : scriptBlocks.entrySet()) {
204
-			final String owner = entry.getKey();
205
-			final JavaClassWriter classWriter = entry.getValue();
206
-			if(classWriter.hasRun)
207
-				runWriter.invokeStatic(owner, "run", "()V");
208
-			classWriter.visitEnd();
209
-			target.register(owner, classWriter.toByteArray());
203
+		for (Map.Entry<String, JavaScriptFile> entry : scriptBlocks.entrySet()) {
204
+			for (JavaMethodInfo method : entry.getValue().scriptMethods)
205
+				runWriter.invokeStatic(method);
206
+			
207
+			entry.getValue().classWriter.visitEnd();
208
+			target.register(entry.getKey(), entry.getValue().classWriter.toByteArray());
210
 		}
209
 		}
211
 		runWriter.ret();
210
 		runWriter.ret();
212
 		runWriter.end();
211
 		runWriter.end();

+ 12
- 0
JavaBytecodeCompiler/src/main/java/org/openzen/zenscript/javabytecode/JavaMethodInfo.java View File

6
 package org.openzen.zenscript.javabytecode;
6
 package org.openzen.zenscript.javabytecode;
7
 
7
 
8
 import org.objectweb.asm.Opcodes;
8
 import org.objectweb.asm.Opcodes;
9
+import org.objectweb.asm.Type;
9
 
10
 
10
 /**
11
 /**
11
  *
12
  *
12
  * @author Hoofdgebruiker
13
  * @author Hoofdgebruiker
13
  */
14
  */
14
 public class JavaMethodInfo {
15
 public class JavaMethodInfo {
16
+	public static JavaMethodInfo get(int modifiers, Class owner, String name, Class result, Class... arguments) {
17
+        StringBuilder descriptor = new StringBuilder();
18
+        descriptor.append('(');
19
+        for (Class argument : arguments) {
20
+            descriptor.append(Type.getDescriptor(argument));
21
+        }
22
+        descriptor.append(')');
23
+        descriptor.append(result == null ? 'V' : Type.getDescriptor(result));
24
+		return new JavaMethodInfo(new JavaClassInfo(Type.getInternalName(owner)), name, descriptor.toString(), modifiers);
25
+    }
26
+	
15
 	public final JavaClassInfo javaClass;
27
 	public final JavaClassInfo javaClass;
16
 	public final String name;
28
 	public final String name;
17
 	public final String descriptor;
29
 	public final String descriptor;

+ 0
- 9
JavaBytecodeCompiler/src/main/java/org/openzen/zenscript/javabytecode/compiler/JavaClassWriter.java View File

3
 import org.objectweb.asm.ClassWriter;
3
 import org.objectweb.asm.ClassWriter;
4
 
4
 
5
 public class JavaClassWriter extends ClassWriter {
5
 public class JavaClassWriter extends ClassWriter {
6
-
7
-    public boolean hasRun;
8
-
9
     public JavaClassWriter(int flags) {
6
     public JavaClassWriter(int flags) {
10
         super(flags);
7
         super(flags);
11
-        this.hasRun = false;
12
-    }
13
-
14
-    public JavaClassWriter(int flags, boolean hasRun) {
15
-        super(flags);
16
-        this.hasRun = hasRun;
17
     }
8
     }
18
 }
9
 }

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

13
 import org.openzen.zenscript.shared.CompileExceptionCode;
13
 import org.openzen.zenscript.shared.CompileExceptionCode;
14
 
14
 
15
 import java.util.Map;
15
 import java.util.Map;
16
+import org.objectweb.asm.Opcodes;
16
 
17
 
17
 public class JavaExpressionVisitor implements ExpressionVisitor<Void> {
18
 public class JavaExpressionVisitor implements ExpressionVisitor<Void> {
19
+	private static final JavaMethodInfo MAP_PUT = JavaMethodInfo.get(Opcodes.ACC_PUBLIC, Map.class, "put", Object.class, Object.class, Object.class);
20
+	
18
     private final JavaWriter javaWriter;
21
     private final JavaWriter javaWriter;
19
 	
22
 	
20
     public JavaExpressionVisitor(JavaWriter javaWriter) {
23
     public JavaExpressionVisitor(JavaWriter javaWriter) {
73
         final Type operatorType = Type.getType(CompareType.class);
76
         final Type operatorType = Type.getType(CompareType.class);
74
         javaWriter.getStaticField(operatorType.getInternalName(), expression.operator.name(), operatorType.getDescriptor());
77
         javaWriter.getStaticField(operatorType.getInternalName(), expression.operator.name(), operatorType.getDescriptor());
75
 
78
 
76
-        javaWriter.invokeStatic(ZenUtils.class, "compare", boolean.class, getForEquals(expression.left.type), getForEquals(expression.right.type), CompareType.class);
79
+		// TODO: should be implemented properly
80
+		JavaMethodInfo compareMethod = JavaMethodInfo.get(
81
+				0,
82
+				ZenUtils.class,
83
+				"compare",
84
+				boolean.class,
85
+				getForEquals(expression.left.type),
86
+				getForEquals(expression.right.type),
87
+				CompareType.class);
88
+        javaWriter.invokeStatic(compareMethod);
77
 
89
 
78
         return null;
90
         return null;
79
     }
91
     }
97
         }
109
         }
98
         //TODO: Test with actual static method
110
         //TODO: Test with actual static method
99
         final JavaMethodInfo info = expression.member.getTag(JavaMethodInfo.class);
111
         final JavaMethodInfo info = expression.member.getTag(JavaMethodInfo.class);
100
-        javaWriter.invokeStatic(info.javaClass.internalClassName, info.name, info.descriptor);
112
+        javaWriter.invokeStatic(info);
101
         return null;
113
         return null;
102
     }
114
     }
103
 
115
 
377
             javaWriter.dup();
389
             javaWriter.dup();
378
             expression.keys[i].accept(this);
390
             expression.keys[i].accept(this);
379
             expression.values[i].accept(this);
391
             expression.values[i].accept(this);
380
-            javaWriter.invokeInterface(Map.class, "put", Object.class, Object.class, Object.class);
392
+            javaWriter.invokeInterface(MAP_PUT);
381
             javaWriter.pop();
393
             javaWriter.pop();
382
         }
394
         }
383
         return null;
395
         return null;
537
         if (methodInfo == null)
549
         if (methodInfo == null)
538
             return false;
550
             return false;
539
         if (methodInfo.isStatic()) {
551
         if (methodInfo.isStatic()) {
540
-            getJavaWriter().invokeStatic(methodInfo.javaClass.internalClassName,
541
-                    methodInfo.name,
542
-                    methodInfo.descriptor);
552
+            getJavaWriter().invokeStatic(methodInfo);
543
         } else {
553
         } else {
544
-            getJavaWriter().invokeVirtual(methodInfo.javaClass.internalClassName,
545
-                    methodInfo.name,
546
-                    methodInfo.descriptor);
554
+            getJavaWriter().invokeVirtual(methodInfo);
547
         }
555
         }
548
         return true;
556
         return true;
549
     }
557
     }

+ 24
- 0
JavaBytecodeCompiler/src/main/java/org/openzen/zenscript/javabytecode/compiler/JavaScriptFile.java View File

1
+/*
2
+ * To change this license header, choose License Headers in Project Properties.
3
+ * To change this template file, choose Tools | Templates
4
+ * and open the template in the editor.
5
+ */
6
+package org.openzen.zenscript.javabytecode.compiler;
7
+
8
+import java.util.ArrayList;
9
+import java.util.List;
10
+import org.openzen.zenscript.javabytecode.JavaMethodInfo;
11
+
12
+/**
13
+ *
14
+ * @author Hoofdgebruiker
15
+ */
16
+public class JavaScriptFile {
17
+	public final JavaClassWriter classWriter;
18
+	public final List<JavaMethodInfo> scriptMethods;
19
+	
20
+	public JavaScriptFile(JavaClassWriter classWriter) {
21
+		this.classWriter = classWriter;
22
+		this.scriptMethods = new ArrayList<>();
23
+	}
24
+}

+ 26
- 76
JavaBytecodeCompiler/src/main/java/org/openzen/zenscript/javabytecode/compiler/JavaWriter.java View File

12
 import java.util.Map;
12
 import java.util.Map;
13
 
13
 
14
 import static org.objectweb.asm.Opcodes.*;
14
 import static org.objectweb.asm.Opcodes.*;
15
+import org.openzen.zenscript.javabytecode.JavaClassInfo;
15
 import org.openzen.zenscript.javabytecode.JavaMethodInfo;
16
 import org.openzen.zenscript.javabytecode.JavaMethodInfo;
16
 
17
 
17
 public class JavaWriter {
18
 public class JavaWriter {
19
+	private static final JavaClassInfo T_STRING = new JavaClassInfo("java/lang/String");
20
+	private static final JavaMethodInfo STRING_CONCAT = new JavaMethodInfo(
21
+			T_STRING,
22
+			"concat",
23
+			"(Ljava/lang/String;)Ljava/lang/String;",
24
+			Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC);
25
+	
18
 	public final JavaMethodInfo method;
26
 	public final JavaMethodInfo method;
19
 	
27
 	
20
     private final LocalVariablesSorter visitor;
28
     private final LocalVariablesSorter visitor;
719
 
727
 
720
         visitor.visitTypeInsn(INSTANCEOF, clsName);
728
         visitor.visitTypeInsn(INSTANCEOF, clsName);
721
     }
729
     }
722
-
723
-    public void invokeStatic(String owner, String name, String descriptor) {
724
-        if (debug)
725
-            System.out.println("invokeStatic " + owner + '.' + name + descriptor);
726
-
727
-        if (owner == null)
728
-            throw new IllegalArgumentException("owner cannot be null");
729
-        if (name == null)
730
-            throw new IllegalArgumentException("name cannot be null");
731
-        if (descriptor == null)
732
-            throw new IllegalArgumentException("descriptor cannot be null");
733
-
734
-        visitor.visitMethodInsn(INVOKESTATIC, owner, name, descriptor, false);
735
-    }
736
-
737
-    public void invokeStatic(Class owner, String name, Class result, Class... arguments) {
738
-        StringBuilder descriptor = new StringBuilder();
739
-        descriptor.append('(');
740
-        for (Class argument : arguments) {
741
-            descriptor.append(signature(argument));
742
-        }
743
-        descriptor.append(')');
744
-        descriptor.append(result == null ? 'V' : signature(result));
745
-
746
-        if (debug)
747
-            System.out.println("invokeStatic " + internal(owner) + '.' + name + descriptor);
748
-
749
-        visitor.visitMethodInsn(INVOKESTATIC, internal(owner), name, descriptor.toString(), false);
750
-    }
730
+	
731
+	public void invokeStatic(JavaMethodInfo method) {
732
+		visitor.visitMethodInsn(
733
+				INVOKESTATIC,
734
+				method.javaClass.internalClassName,
735
+				method.name,
736
+				method.descriptor,
737
+				false);
738
+	}
751
 
739
 
752
     public void invokeSpecial(String owner, String name, String descriptor) {
740
     public void invokeSpecial(String owner, String name, String descriptor) {
753
         if (debug)
741
         if (debug)
759
     public void invokeSpecial(Class owner, String name, String descriptor) {
747
     public void invokeSpecial(Class owner, String name, String descriptor) {
760
         invokeSpecial(Type.getInternalName(owner), name, descriptor);
748
         invokeSpecial(Type.getInternalName(owner), name, descriptor);
761
     }
749
     }
762
-
763
-    public void invoke(Class owner, String name, Class result, Class... arguments) {
764
-        if (owner.isInterface()) {
765
-            invokeInterface(owner, name, result, arguments);
766
-        } else {
767
-            invokeVirtual(owner, name, result, arguments);
768
-        }
769
-    }
770
-
771
-    public void invokeVirtual(String owner, String name, String descriptor) {
772
-        if (debug)
773
-            System.out.println("invokeVirtual " + owner + '.' + name + descriptor);
774
-
775
-        visitor.visitMethodInsn(INVOKEVIRTUAL, owner, name, descriptor, false);
776
-    }
777
-
778
-    public void invokeVirtual(Class owner, String name, Class result, Class... arguments) {
779
-        StringBuilder descriptor = new StringBuilder();
780
-        descriptor.append('(');
781
-        for (Class argument : arguments) {
782
-            descriptor.append(signature(argument));
783
-        }
784
-        descriptor.append(')');
785
-        descriptor.append(result == null ? 'V' : signature(result));
786
-
787
-        if (debug)
788
-            System.out.println("invokeVirtual " + owner + '.' + name + descriptor);
789
-
790
-        visitor.visitMethodInsn(INVOKEVIRTUAL, internal(owner), name, descriptor.toString(), false);
791
-    }
792
-
793
-    public void invokeInterface(String owner, String name, String descriptor) {
750
+	
751
+	public void invokeVirtual(JavaMethodInfo method) {
794
         if (debug)
752
         if (debug)
795
-            System.out.println("invokeInterface " + owner + '.' + name + descriptor);
796
-
797
-        visitor.visitMethodInsn(INVOKEINTERFACE, owner, name, descriptor, true);
798
-    }
753
+            System.out.println("invokeVirtual " + method.javaClass.internalClassName + '.' + method.name + method.descriptor);
799
 
754
 
800
-    public void invokeInterface(Class owner, String name, Class result, Class... arguments) {
801
-        StringBuilder descriptor = new StringBuilder();
802
-        descriptor.append('(');
803
-        for (Class argument : arguments) {
804
-            descriptor.append(signature(argument));
805
-        }
806
-        descriptor.append(')');
807
-        descriptor.append(result == null ? 'V' : signature(result));
755
+        visitor.visitMethodInsn(INVOKEVIRTUAL, method.javaClass.internalClassName, method.name, method.descriptor, false);
756
+	}
808
 
757
 
758
+    public void invokeInterface(JavaMethodInfo method) {
809
         if (debug)
759
         if (debug)
810
-            System.out.println("invokeInterface " + owner + '.' + name + descriptor);
760
+            System.out.println("invokeInterface " + method.javaClass.internalClassName + '.' + method.name + method.descriptor);
811
 
761
 
812
-        visitor.visitMethodInsn(INVOKEINTERFACE, internal(owner), name, descriptor.toString(), true);
762
+        visitor.visitMethodInsn(INVOKEINTERFACE, method.javaClass.internalClassName, method.name, method.descriptor, true);
813
     }
763
     }
814
 
764
 
815
     public void newObject(Class type) {
765
     public void newObject(Class type) {
1100
     }
1050
     }
1101
 
1051
 
1102
     public void stringAdd() {
1052
     public void stringAdd() {
1103
-        invokeVirtual("java/lang/String", "concat", "(Ljava/lang/String;)Ljava/lang/String;");
1053
+        invokeVirtual(STRING_CONCAT);
1104
     }
1054
     }
1105
 
1055
 
1106
     public Label getNamedLabel(String label) {
1056
     public Label getNamedLabel(String label) {

+ 19
- 4
JavaBytecodeCompiler/src/main/java/org/openzen/zenscript/javabytecode/compiler/definitions/JavaDefinitionVisitor.java View File

24
 import java.util.Iterator;
24
 import java.util.Iterator;
25
 
25
 
26
 public class JavaDefinitionVisitor implements DefinitionVisitor<byte[]> {
26
 public class JavaDefinitionVisitor implements DefinitionVisitor<byte[]> {
27
-
27
+	private static final JavaClassInfo T_CLASS = new JavaClassInfo("java/lang/Class");
28
+	private static final JavaMethodInfo CLASS_FORNAME = new JavaMethodInfo(
29
+			T_CLASS,
30
+			"forName",
31
+			"(Ljava/lang/String;)Ljava/lang/Class;",
32
+			Opcodes.ACC_STATIC | Opcodes.ACC_PUBLIC);
33
+	
34
+	private static final JavaClassInfo T_ENUM = new JavaClassInfo("java/lang/Enum");
35
+	private static final JavaMethodInfo ENUM_VALUEOF = new JavaMethodInfo(
36
+			T_ENUM,
37
+			"valueOf",
38
+			"(Ljava/lang/Class;Ljava/lang/String;)Ljava/lang/Enum;",
39
+			Opcodes.ACC_STATIC | Opcodes.ACC_PUBLIC);
28
 
40
 
29
     private final JavaClassWriter outerWriter;
41
     private final JavaClassWriter outerWriter;
30
 
42
 
169
 
181
 
170
         //Enum Stuff(required!)
182
         //Enum Stuff(required!)
171
         writer.visitField(Opcodes.ACC_STATIC | Opcodes.ACC_PRIVATE | Opcodes.ACC_FINAL | Opcodes.ACC_SYNTHETIC, "$VALUES", "[L" + definition.name + ";", null, null).visitEnd();
183
         writer.visitField(Opcodes.ACC_STATIC | Opcodes.ACC_PRIVATE | Opcodes.ACC_FINAL | Opcodes.ACC_SYNTHETIC, "$VALUES", "[L" + definition.name + ";", null, null).visitEnd();
184
+		
185
+		JavaClassInfo arrayClass = new JavaClassInfo("[L" + definition.name + ";");
186
+		JavaMethodInfo arrayClone = new JavaMethodInfo(arrayClass, "clone", "()Ljava/lang/Object;", Opcodes.ACC_PUBLIC);
172
 
187
 
173
 		JavaMethodInfo valuesMethodInfo = new JavaMethodInfo(toClass, "values", "()[L" + definition.name + ";", Opcodes.ACC_STATIC | Opcodes.ACC_PUBLIC);
188
 		JavaMethodInfo valuesMethodInfo = new JavaMethodInfo(toClass, "values", "()[L" + definition.name + ";", Opcodes.ACC_STATIC | Opcodes.ACC_PUBLIC);
174
         JavaWriter valuesWriter = new JavaWriter(writer, true, valuesMethodInfo, null, null);
189
         JavaWriter valuesWriter = new JavaWriter(writer, true, valuesMethodInfo, null, null);
175
         valuesWriter.start();
190
         valuesWriter.start();
176
         valuesWriter.getStaticField(definition.name, "$VALUES", "[L" + definition.name + ";");
191
         valuesWriter.getStaticField(definition.name, "$VALUES", "[L" + definition.name + ";");
177
-        valuesWriter.invokeVirtual("[L" + definition.name + ";", "clone", "()Ljava/lang/Object;");
192
+        valuesWriter.invokeVirtual(arrayClone);
178
         valuesWriter.checkCast("[L" + definition.name + ";");
193
         valuesWriter.checkCast("[L" + definition.name + ";");
179
         valuesWriter.returnObject();
194
         valuesWriter.returnObject();
180
         valuesWriter.end();
195
         valuesWriter.end();
182
 		JavaMethodInfo valueOfMethodInfo = new JavaMethodInfo(toClass, "valueOf", "(Ljava/lang/String;)L" + definition.name + ";", Opcodes.ACC_STATIC | Opcodes.ACC_PUBLIC);
197
 		JavaMethodInfo valueOfMethodInfo = new JavaMethodInfo(toClass, "valueOf", "(Ljava/lang/String;)L" + definition.name + ";", Opcodes.ACC_STATIC | Opcodes.ACC_PUBLIC);
183
         JavaWriter valueOfWriter = new JavaWriter(writer, true, valueOfMethodInfo, null, null);
198
         JavaWriter valueOfWriter = new JavaWriter(writer, true, valueOfMethodInfo, null, null);
184
         valueOfWriter.start();
199
         valueOfWriter.start();
185
-        valueOfWriter.invokeStatic("java/lang/Class", "forName", "(Ljava/lang/String;)Ljava/lang/Class;");
200
+        valueOfWriter.invokeStatic(CLASS_FORNAME);
186
         valueOfWriter.loadObject(0);
201
         valueOfWriter.loadObject(0);
187
-        valueOfWriter.invokeStatic("java/lang/Enum", "valueOf", "(Ljava/lang/Class;Ljava/lang/String;)Ljava/lang/Enum;");
202
+        valueOfWriter.invokeStatic(ENUM_VALUEOF);
188
         valueOfWriter.checkCast("L" + definition.name + ";");
203
         valueOfWriter.checkCast("L" + definition.name + ";");
189
         valueOfWriter.returnObject();
204
         valueOfWriter.returnObject();
190
         valueOfWriter.end();
205
         valueOfWriter.end();

+ 3
- 2
ScriptingExample/src/main/java/org/openzen/zenscript/scriptingexample/GlobalRegistry.java View File

47
 	
47
 	
48
 	public GlobalRegistry(ZSPackage globals) {
48
 	public GlobalRegistry(ZSPackage globals) {
49
 		JavaClassInfo jPrintStream = new JavaClassInfo("java/io/PrintStream");
49
 		JavaClassInfo jPrintStream = new JavaClassInfo("java/io/PrintStream");
50
-		PRINTSTREAM_PRINTLN.setTag(JavaMethodInfo.class, new JavaMethodInfo(jPrintStream, "println", "(Ljava/lang/String;)V", Opcodes.ACC_PUBLIC));
50
+		JavaMethodInfo printstreamPrintln = new JavaMethodInfo(jPrintStream, "println", "(Ljava/lang/String;)V", Opcodes.ACC_PUBLIC);
51
+		PRINTSTREAM_PRINTLN.setTag(JavaMethodInfo.class, printstreamPrintln);
51
 		
52
 		
52
 		JavaClassInfo jSystem = new JavaClassInfo("java/lang/System");
53
 		JavaClassInfo jSystem = new JavaClassInfo("java/lang/System");
53
 		SYSTEM_OUT.setTag(JavaFieldInfo.class, new JavaFieldInfo(jSystem, "out", "Ljava/io/PrintStream;"));
54
 		SYSTEM_OUT.setTag(JavaFieldInfo.class, new JavaFieldInfo(jSystem, "out", "Ljava/io/PrintStream;"));
54
 		
55
 		
55
 		PRINTLN.caller.setTag(JavaBytecodeImplementation.class, writer -> {
56
 		PRINTLN.caller.setTag(JavaBytecodeImplementation.class, writer -> {
56
 			writer.getField(System.class, "out", PrintStream.class);
57
 			writer.getField(System.class, "out", PrintStream.class);
57
-			writer.invokeVirtual("java/io/PrintStream", "println", "(Ljava/lang/String;)V");
58
+			writer.invokeVirtual(printstreamPrintln);
58
 		});
59
 		});
59
 	}
60
 	}
60
 	
61
 	

Loading…
Cancel
Save