Permalink
Browse files

Create eclipse project and import existing code.

git-svn-id: https://elmar.ips.cs.tu-bs.de/svn/arden2bytecode/trunk@2 20415b1c-3eea-de11-af57-000476a39db3
  • Loading branch information...
dgrunwald committed Dec 17, 2009
1 parent ddd60fe commit 390640c476c5b417d6b21b3c59ce3f1869b77c0b
View
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+ <classpathentry kind="src" path="src"/>
+ <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6"/>
+ <classpathentry kind="output" path="bin"/>
+</classpath>
View
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>arden2bytecode</name>
+ <comment></comment>
+ <projects>
+ </projects>
+ <buildSpec>
+ <buildCommand>
+ <name>org.eclipse.jdt.core.javabuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ </buildSpec>
+ <natures>
+ <nature>org.eclipse.jdt.core.javanature</nature>
+ </natures>
+</projectDescription>
@@ -0,0 +1,12 @@
+#Thu Dec 17 13:52:46 CET 2009
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6
+org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
+org.eclipse.jdt.core.compiler.compliance=1.6
+org.eclipse.jdt.core.compiler.debug.lineNumber=generate
+org.eclipse.jdt.core.compiler.debug.localVariable=generate
+org.eclipse.jdt.core.compiler.debug.sourceFile=generate
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.source=1.6
@@ -0,0 +1,24 @@
+package arden.codegenerator;
+
+/**
+ * Diese Exception tritt auf, wenn eines der Limits des Class-File-Formates zu
+ * überschreiten.
+ *
+ * @author daniel
+ *
+ */
+public class ClassFileLimitExceededException extends RuntimeException {
+
+ private static final long serialVersionUID = -8632386917620523076L;
+
+ public ClassFileLimitExceededException() {
+ }
+
+ public ClassFileLimitExceededException(String message) {
+ super(message);
+ }
+
+ public ClassFileLimitExceededException(Exception inner) {
+ super(inner);
+ }
+}
@@ -0,0 +1,152 @@
+package arden.codegenerator;
+
+import java.io.DataOutput;
+import java.io.DataOutputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.lang.reflect.Modifier;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Class for writing .class files
+ *
+ * @author daniel
+ *
+ */
+public class ClassFileWriter {
+ ConstantPool pool = new ConstantPool();
+
+ int this_class;
+ int super_class;
+
+ /** Creates a new ClassFileWriter for writing the specified class */
+ public ClassFileWriter(String className, Class<?> superClass) {
+ if (className == null)
+ throw new IllegalArgumentException();
+ this_class = pool.getClassByJavaName(className.replace('.', '/'));
+ super_class = pool.getClass(superClass);
+ }
+
+ class AttributeInfo {
+ int nameIndex;
+ byte[] data;
+
+ public AttributeInfo(String name) {
+ nameIndex = pool.getUtf8(name);
+ }
+
+ void save(DataOutput output) throws IOException {
+ output.writeShort(nameIndex);
+ output.writeInt(data.length);
+ output.write(data);
+ }
+ }
+
+ class FieldInfo {
+ short access_flags;
+ int name_index;
+ int descriptor_index;
+
+ FieldInfo(String name, Class<?> type, int modifiers) {
+ access_flags = (short) modifiers;
+ name_index = pool.getUtf8(name);
+ descriptor_index = pool.getUtf8(ConstantPool.createFieldDescriptor(type));
+ }
+
+ void save(DataOutput output) throws IOException {
+ output.writeShort(access_flags);
+ output.writeShort(name_index);
+ output.writeShort(descriptor_index);
+ output.writeShort(0); // attributes_count
+ }
+ }
+
+ List<FieldInfo> fields = new ArrayList<FieldInfo>();
+
+ /** Declares a new field in the class */
+ public FieldReference declareField(String name, Class<?> type, int modifiers) {
+ if (fields.size() >= 65534)
+ throw new ClassFileLimitExceededException("Too many fields.");
+ fields.add(new FieldInfo(name, type, modifiers));
+ return pool.createFieldref(this_class, name, type);
+ }
+
+ class MethodInfo {
+ short access_flags;
+ int name_index;
+ int descriptor_index;
+ MethodWriter writer;
+ AttributeInfo codeAttribute;
+
+ MethodInfo(String name, int modifiers, Class<?>[] parameters, Class<?> returnType) {
+ writer = new MethodWriter(pool, (modifiers & Modifier.STATIC) != Modifier.STATIC);
+ access_flags = (short) modifiers;
+ name_index = pool.getUtf8(name);
+ descriptor_index = pool.getUtf8(ConstantPool.createMethodDescriptor(parameters, returnType));
+ codeAttribute = new AttributeInfo("Code");
+ }
+
+ void save(DataOutput output) throws IOException {
+ output.writeShort(access_flags);
+ output.writeShort(name_index);
+ output.writeShort(descriptor_index);
+ output.writeShort(1); // attributes_count
+ codeAttribute.data = writer.getCodeAttributeData();
+ codeAttribute.save(output);
+ }
+ }
+
+ static final String JAVA_CONSTRUCTOR_NAME = "<init>";
+ static final String JAVA_STATIC_INITIALIZER_NAME = "<clinit>";
+
+ List<MethodInfo> methods = new ArrayList<MethodInfo>();
+
+ /** Creates a new method in the class */
+ public MethodWriter createMethod(String name, int modifiers, Class<?>[] parameters, Class<?> returnType) {
+ if (methods.size() >= 65534)
+ throw new ClassFileLimitExceededException("Too many methods.");
+ MethodInfo info = new MethodInfo(name, modifiers, parameters, returnType);
+ methods.add(info);
+ info.writer.enableLineNumberTable();
+ return info.writer;
+ }
+
+ public MethodWriter createConstructor(int modifiers, Class<?>[] parameters) {
+ return createMethod(JAVA_CONSTRUCTOR_NAME, modifiers, parameters, Void.TYPE);
+ }
+
+ public MethodWriter createStaticInitializer() {
+ return createMethod(JAVA_STATIC_INITIALIZER_NAME, Modifier.PUBLIC | Modifier.STATIC, new Class<?>[0], Void.TYPE);
+ }
+
+ /** Saves the class file to disk */
+ public void save(String filename) throws IOException {
+ DataOutputStream s = new DataOutputStream(
+ new FileOutputStream(filename));
+ try {
+ save(s);
+ } finally {
+ s.close();
+ }
+ }
+
+ /** Saves the class file */
+ public void save(DataOutput output) throws IOException {
+ output.writeInt(0xCAFEBABE); // magic
+ output.writeShort(0x00); // minor_version
+ output.writeShort(0x32); // major_version
+ pool.save(output);
+ output.writeShort(0x0021); // ACC_SUPER | ACC_PUBLIC
+ output.writeShort(this_class);
+ output.writeShort(super_class);
+ output.writeShort(0); // interfaces_count
+ output.writeShort(fields.size()); // fields_count
+ for (FieldInfo info : fields)
+ info.save(output);
+ output.writeShort(methods.size()); // methods_count
+ for (MethodInfo info : methods)
+ info.save(output);
+ output.writeShort(0); // attributes_count
+ }
+}
Oops, something went wrong.

0 comments on commit 390640c

Please sign in to comment.