diff options
Diffstat (limited to 'src/fjbg/ch/epfl')
33 files changed, 0 insertions, 7914 deletions
diff --git a/src/fjbg/ch/epfl/lamp/fjbg/FJBGContext.java b/src/fjbg/ch/epfl/lamp/fjbg/FJBGContext.java deleted file mode 100644 index 9856dc7311..0000000000 --- a/src/fjbg/ch/epfl/lamp/fjbg/FJBGContext.java +++ /dev/null @@ -1,195 +0,0 @@ -/* FJBG -- Fast Java Bytecode Generator - * Copyright 2002-2013 LAMP/EPFL - * @author Michel Schinz - */ - -package ch.epfl.lamp.fjbg; - -import java.io.DataInputStream; -import java.io.IOException; - -/** - * Context in which FJBG executes. Used both as a factory for most - * FJBG classes and as a repository for other factories. - * - * @author Michel Schinz - * @version 1.0 - */ - -public class FJBGContext { - /** Class file major version */ - final int MAJOR_VERSION; - - /** Class file minor version */ - final int MINOR_VERSION; - - public FJBGContext() { - this(45, 3); - } - - public FJBGContext(int major, int minor) { - MAJOR_VERSION = major; - MINOR_VERSION = minor; - } - - // Factory methods - ////////////////////////////////////////////////////////////////////// - - public JClass JClass(int accessFlags, - String name, - String superclassName, - String[] interfaceNames, - String sourceFileName) { - return new JClass(this, - accessFlags, - name, - superclassName, - interfaceNames, - sourceFileName); - } - - public JClass JClass(DataInputStream stream) - throws IOException { - return new JClass(this, stream); - } - - public JConstantPool JConstantPool() { - return new JConstantPool(this); - } - - public JConstantPool JConstantPool(DataInputStream stream) - throws IOException { - return new JConstantPool(this, stream); - } - - public JField JField(JClass owner, - int accessFlags, - String name, - JType type) { - return new JField(this, - owner, - accessFlags, - name, - type); - } - - public JField JField(JClass owner, DataInputStream stream) - throws IOException { - return new JField(this, owner, stream); - } - - public JMethod JMethod(JClass owner, - int accessFlags, - String name, - JType returnType, - JType[] argTypes, - String[] argNames) { - return new JMethod(this, - owner, - accessFlags, - name, - returnType, - argTypes, - argNames); - } - - public JMethod JMethod(JClass owner, - int accessFlags, - String name, - JMethodType type, - String[] argNames) { - return JMethod(owner, - accessFlags, - name, - type.getReturnType(), - type.getArgumentTypes(), - argNames); - } - - public JMethod JMethod(JClass owner, DataInputStream stream) - throws IOException { - return new JMethod(this, owner, stream); - } - - public JLocalVariable JLocalVariable(JMethod owner, - JType type, - String name, - int index) { - return new JLocalVariable(this, owner, type, name, index); - } - - public JCode JCode(JClass clazz, JMethod owner) { - return new JExtendedCode(this, clazz, owner); - } - - public JCode JCode(JClass clazz, JMethod owner, DataInputStream stream) - throws IOException { - return new JCode(this, clazz, owner, stream); - } - - public JAttributeFactory JAttributeFactory() { - return new JAttributeFactory(this); - } - - // Attributes - public JCodeAttribute JCodeAttribute(JClass clazz, JMethod owner) { - return new JCodeAttribute(this, clazz, owner); - } - - public JEnclosingMethodAttribute JEnclosingMethodAttribute(JClass clazz, - String className, - String methodName, - JType methodType) { - return new JEnclosingMethodAttribute(this, clazz, className, methodName, methodType); - } - - public JExceptionsAttribute JExceptionsAttribute(JClass clazz, - JMethod owner) { - return new JExceptionsAttribute(this, clazz, owner); - } - - public JLineNumberTableAttribute JLineNumberTableAttribute(JClass clazz, - JCode owner) { - return new JLineNumberTableAttribute(this, clazz, owner); - } - - public JLocalVariableTableAttribute JLocalVariableTableAttribute(JClass clazz, - JCode owner) { - return new JLocalVariableTableAttribute(this, clazz, owner); - } - - public JOtherAttribute JOtherAttribute(JClass clazz, - Object owner, - String name, - byte[] contents, - int length) { - return new JOtherAttribute(this, clazz, owner, name, contents, length); - } - - public JOtherAttribute JOtherAttribute(JClass clazz, - Object owner, - String name, - byte[] contents) { - return JOtherAttribute(clazz, owner, name, contents, contents.length); - } - - public JSourceFileAttribute JSourceFileAttribute(JClass clazz, - String sourceFileName) { - return new JSourceFileAttribute(this, clazz, sourceFileName); - } - - public JStackMapTableAttribute JStackMapTableAttribute(JClass clazz, - JCode owner) { - return new JStackMapTableAttribute(this, clazz, owner); - } - - /// Repository - ////////////////////////////////////////////////////////////////////// - - protected JAttributeFactory jAttributeFactory = null; - public JAttributeFactory getJAttributeFactory() { - if (jAttributeFactory == null) - jAttributeFactory = JAttributeFactory(); - return jAttributeFactory; - } -} diff --git a/src/fjbg/ch/epfl/lamp/fjbg/JAccessFlags.java b/src/fjbg/ch/epfl/lamp/fjbg/JAccessFlags.java deleted file mode 100644 index 01d8cc9a7e..0000000000 --- a/src/fjbg/ch/epfl/lamp/fjbg/JAccessFlags.java +++ /dev/null @@ -1,35 +0,0 @@ -/* FJBG -- Fast Java Bytecode Generator - * Copyright 2002-2013 LAMP/EPFL - * @author Michel Schinz - */ - -package ch.epfl.lamp.fjbg; - -/** - * Definition of access flags for fields, methods and classes. - * - * @author Michel Schinz - * @version 1.0 - */ - -public interface JAccessFlags { - public static int ACC_PUBLIC = 0x0001; - public static int ACC_PRIVATE = 0x0002; - public static int ACC_PROTECTED = 0x0004; - public static int ACC_STATIC = 0x0008; - public static int ACC_FINAL = 0x0010; - public static int ACC_SUPER = 0x0020; - public static int ACC_VOLATILE = 0x0040; - public static int ACC_TRANSIENT = 0x0080; - public static int ACC_NATIVE = 0x0100; - public static int ACC_INTERFACE = 0x0200; - public static int ACC_ABSTRACT = 0x0400; - public static int ACC_STRICT = 0x0800; - public static int ACC_SYNTHETIC = 0x1000; - public static int ACC_ANNOTATION= 0x2000; - public static int ACC_ENUM = 0x4000; - - // 1.5 specifics - public static int ACC_BRIDGE = 0x0040; - public static int ACC_VARARGS = 0x0080; -} diff --git a/src/fjbg/ch/epfl/lamp/fjbg/JArrayType.java b/src/fjbg/ch/epfl/lamp/fjbg/JArrayType.java deleted file mode 100644 index 61a04523ca..0000000000 --- a/src/fjbg/ch/epfl/lamp/fjbg/JArrayType.java +++ /dev/null @@ -1,62 +0,0 @@ -/* FJBG -- Fast Java Bytecode Generator - * Copyright 2002-2013 LAMP/EPFL - * @author Michel Schinz - */ - -package ch.epfl.lamp.fjbg; - -/** - * Types for Java arrays. - * - * @author Michel Schinz - * @version 1.0 - */ - -public class JArrayType extends JReferenceType { - protected final JType elementType; - protected String signature = null; - - public JArrayType(JType elementType) { - this.elementType = elementType; - } - - public int getSize() { return 1; } - - public String getSignature() { - if (signature == null) - signature = "[" + elementType.getSignature(); - return signature; - } - - public String getDescriptor() { - return getSignature(); - } - - public int getTag() { return T_ARRAY; } - - public JType getElementType() { return elementType; } - - public String toString() { - return elementType.toString() + "[]"; - } - - public boolean isArrayType() { return true; } - - public boolean isCompatibleWith(JType other) { - if (other instanceof JObjectType) - return (JObjectType)other == JObjectType.JAVA_LANG_OBJECT; - else if (other instanceof JArrayType) - return elementType.isCompatibleWith(((JArrayType)other).elementType); - else return other == JType.REFERENCE; - } - - public static JArrayType BOOLEAN = new JArrayType(JType.BOOLEAN); - public static JArrayType BYTE = new JArrayType(JType.BYTE); - public static JArrayType CHAR = new JArrayType(JType.CHAR); - public static JArrayType SHORT = new JArrayType(JType.SHORT); - public static JArrayType INT = new JArrayType(JType.INT); - public static JArrayType FLOAT = new JArrayType(JType.FLOAT); - public static JArrayType LONG = new JArrayType(JType.LONG); - public static JArrayType DOUBLE = new JArrayType(JType.DOUBLE); - public static JArrayType REFERENCE = new JArrayType(JType.REFERENCE); -} diff --git a/src/fjbg/ch/epfl/lamp/fjbg/JAttribute.java b/src/fjbg/ch/epfl/lamp/fjbg/JAttribute.java deleted file mode 100644 index 6a825beb18..0000000000 --- a/src/fjbg/ch/epfl/lamp/fjbg/JAttribute.java +++ /dev/null @@ -1,84 +0,0 @@ -/* FJBG -- Fast Java Bytecode Generator - * Copyright 2002-2013 LAMP/EPFL - * @author Michel Schinz - */ - -package ch.epfl.lamp.fjbg; - -import java.io.DataInputStream; -import java.io.DataOutputStream; -import java.io.IOException; -import java.util.*; - -/** - * Abstract superclass for attributes which can be attached to various - * parts of a class file. - * - * Attributes are used for classes (section 4.2), fields (section 4.6), - * methods (section 4.7) and the Code attribute (section 4.8.3). - * See sections 4.2 and later of the JVM specification. - * - * @author Michel Schinz - * @version 1.0 - */ - -public abstract class JAttribute { - protected final int nameIdx; - - static public void writeTo(List/*<JAttribute>*/ attrs, DataOutputStream stream) - throws IOException { - stream.writeShort(attrs.size()); - Iterator attrsIt = attrs.iterator(); - while (attrsIt.hasNext()) { - JAttribute attr = (JAttribute)attrsIt.next(); - attr.writeTo(stream); - } - } - - static public List/*<JAttribute>*/ readFrom(FJBGContext context, - JClass clazz, - Object owner, - DataInputStream stream) - throws IOException { - JAttributeFactory factory = context.getJAttributeFactory(); - int count = stream.readShort(); - ArrayList list = new ArrayList(count); - for (int i = 0; i < count; ++i) - list.add(factory.newInstance(clazz, owner, stream)); - return list; - } - - public JAttribute(FJBGContext context, JClass clazz) { - this.nameIdx = clazz.getConstantPool().addUtf8(getName()); - } - - public JAttribute(FJBGContext context, JClass clazz, String name) { - this.nameIdx = clazz.getConstantPool().addUtf8(name); - } - - abstract public String getName(); - - /** - * Write the attribute to a stream. - */ - public void writeTo(DataOutputStream stream) throws IOException { - int contentsSize = getSize(); - - stream.writeShort(nameIdx); - stream.writeInt(contentsSize); - int streamSizeBefore = stream.size(); - writeContentsTo(stream); - int streamSizeDiff = stream.size() - streamSizeBefore; - - assert contentsSize == streamSizeDiff - : "invalid size for attribute " + getName() - + " given: " + contentsSize - + " actual: " + streamSizeDiff; - } - - // Note: it is not legal to add data to the constant pool during - // the execution of any of the following two methods. - protected abstract int getSize(); - protected abstract void writeContentsTo(DataOutputStream stream) - throws IOException; -} diff --git a/src/fjbg/ch/epfl/lamp/fjbg/JAttributeFactory.java b/src/fjbg/ch/epfl/lamp/fjbg/JAttributeFactory.java deleted file mode 100644 index 33cdce2760..0000000000 --- a/src/fjbg/ch/epfl/lamp/fjbg/JAttributeFactory.java +++ /dev/null @@ -1,101 +0,0 @@ -/* FJBG -- Fast Java Bytecode Generator - * Copyright 2002-2013 LAMP/EPFL - * @author Michel Schinz - */ - -package ch.epfl.lamp.fjbg; - -import java.io.DataInputStream; -import java.io.IOException; -import java.lang.reflect.Constructor; -import java.lang.reflect.InvocationTargetException; -import java.util.HashMap; - -/** - * Extensible factory to build subclasses of JAttribute based on an - * attribute name. - * - * @author Michel Schinz - * @version 1.0 - */ - -public class JAttributeFactory { - protected FJBGContext context; - protected HashMap/*<String, Constructor>*/ constructors = new HashMap(); - - protected final static Class[] CONSTRUCTOR_ARGS = new Class[] { - FJBGContext.class, - JClass.class, - Object.class, - String.class, - int.class, - DataInputStream.class - }; - - protected final static Constructor defaultDefaultConstructor; - static { - try { - defaultDefaultConstructor = - JOtherAttribute.class.getConstructor(CONSTRUCTOR_ARGS); - } catch (NoSuchMethodException e) { - throw new RuntimeException(e); - } - } - - protected final Constructor defaultConstructor; - - public JAttributeFactory(FJBGContext context, - Constructor defaultConstructor) { - this.context = context; - this.defaultConstructor = defaultConstructor; - registerClass("Code", JCodeAttribute.class); - registerClass("ConstantValue", JConstantValueAttribute.class); - registerClass("EnclosingMethod", JEnclosingMethodAttribute.class); - registerClass("Exceptions", JExceptionsAttribute.class); - registerClass("InnerClasses", JInnerClassesAttribute.class); - registerClass("LineNumberTable", JLineNumberTableAttribute.class); - registerClass("LocalVariableTable", JLocalVariableTableAttribute.class); - registerClass("SourceFile", JSourceFileAttribute.class); - registerClass("StackMapTable", JStackMapTableAttribute.class); - } - - public JAttributeFactory(FJBGContext context) { - this(context, defaultDefaultConstructor); - } - - public void registerClass(String attributeName, - Class clazz) { - if (! JAttribute.class.isAssignableFrom(clazz)) - throw new IllegalArgumentException("Not a subclass of JAttribute: " - + clazz); - - try { - Constructor constr = clazz.getConstructor(CONSTRUCTOR_ARGS); - constructors.put(attributeName, constr); - } catch (NoSuchMethodException e) { - throw new IllegalArgumentException("No appropriate constructor for " - + clazz); - } - } - - public JAttribute newInstance(JClass clazz, - Object owner, - DataInputStream stream) - throws IOException { - String name = clazz.getConstantPool().lookupUtf8(stream.readShort()); - Integer size = new Integer(stream.readInt()); - Constructor constr = (Constructor)constructors.get(name); - if (constr == null) constr = defaultConstructor; - - Object[] args = new Object[] { context, clazz, owner, name, size, stream }; - try { - return (JAttribute)constr.newInstance(args); - } catch (InstantiationException e) { - throw new RuntimeException(e); - } catch (IllegalAccessException e) { - throw new RuntimeException(e); - } catch (InvocationTargetException e) { - throw new RuntimeException(e); - } - } -} diff --git a/src/fjbg/ch/epfl/lamp/fjbg/JClass.java b/src/fjbg/ch/epfl/lamp/fjbg/JClass.java deleted file mode 100644 index bb1538ec23..0000000000 --- a/src/fjbg/ch/epfl/lamp/fjbg/JClass.java +++ /dev/null @@ -1,420 +0,0 @@ -/* FJBG -- Fast Java Bytecode Generator - * Copyright 2002-2013 LAMP/EPFL - * @author Michel Schinz - */ - -package ch.epfl.lamp.fjbg; - -import java.util.*; -import java.io.*; - -/** - * Representation of a Java class. - * - * @author Michel Schinz, Stephane Micheloud - * @version 1.1 - */ -public class JClass extends JMember { - - /** Magic number for Java class files. */ - public final static int MAGIC_NUMBER = 0xCAFEBABE; - - protected final JAttributeFactory attributeFactory; - - protected final String superclassName; - protected final String[] interfaceNames; - protected final String sourceFileName; - protected final JConstantPool pool; - - public final static String[] NO_INTERFACES = new String[0]; - - protected final LinkedList/*<JMethod>*/ methods = new LinkedList(); - protected final LinkedList/*<JField>*/ fields = new LinkedList(); - - protected JInnerClassesAttribute innerClasses; - - protected int major; - protected int minor; - - /** - * Creates a new class with its access flags, name, superclass name, - * interfaces names and source file name initialized to a given value. - * The constructor also initializes the pool and adds a sourceFileName - * attribute to the class. - * @param accessFlags the int representing the access flags of the class. - * @param name the string representing the name of the class. - * @param superclassName the string representing the name of the class' - * superclass. - * @param interfaceNames the list of strings representing the names of the - * interfaces implemented by the class. - * @param sourceFileName name of the file from which the class was compiled. - */ - protected JClass(FJBGContext context, - int accessFlags, - String name, - String superclassName, - String[] interfaceNames, - String sourceFileName) { - super(context, accessFlags, name); - this.attributeFactory = context.getJAttributeFactory(); - - this.major = context.MAJOR_VERSION; - this.minor = context.MINOR_VERSION; - - this.superclassName = superclassName; - this.interfaceNames = interfaceNames; - this.sourceFileName = sourceFileName; - this.pool = context.JConstantPool(); - if (sourceFileName != null) - addAttribute(context.JSourceFileAttribute(this, sourceFileName)); - } - - protected JClass(FJBGContext context, DataInputStream stream) - throws IOException { - super(context); - this.attributeFactory = context.getJAttributeFactory(); - - int magic = stream.readInt(); - if (magic != MAGIC_NUMBER) - throw new IllegalArgumentException("invalid magic number: "+magic); - - minor = stream.readShort(); - major = stream.readShort(); - pool = context.JConstantPool(stream); - accessFlags = stream.readShort(); - - // This class, super class and interfaces - name = pool.lookupClass(stream.readShort()); - superclassName = pool.lookupClass(stream.readShort()); - interfaceNames = new String[stream.readShort()]; - for (int i = 0; i < interfaceNames.length; ++i) - interfaceNames[i] = pool.lookupClass(stream.readShort()); - - // Fields, methods and attributes - int fieldsCount = stream.readShort(); - for (int i = 0; i < fieldsCount; ++i) - addField(context.JField(this, stream)); - - int methodsCount = stream.readShort(); - for (int i = 0; i < methodsCount; ++i) - addMethod(context.JMethod(this, stream)); - - String fileName = null; - int attributesCount = stream.readShort(); - for (int i = 0; i < attributesCount; ++i) { - JAttribute attr = attributeFactory.newInstance(this, this, stream); - if (attr instanceof JSourceFileAttribute) - fileName = ((JSourceFileAttribute)attr).getFileName(); - else if (attr instanceof JInnerClassesAttribute) - innerClasses = (JInnerClassesAttribute)attr; - addAttribute(attr); - } - sourceFileName = fileName; - } - - /** - * Gets the name of the class' superclass. - * @return The string representing the name of the class' superclass. - */ - public String getSuperclassName() { return superclassName; } - - /** - * Gets the names of the interfaces implemented by the class. - * @return The array containing the string representations of the - * names of the interfaces implemented by the class. - */ - public String[] getInterfaceNames() { return interfaceNames; } - - /** - * Gets the source file name of this class. - * @return The string representing the source file name of this class. - */ - public String getSourceFileName() { return sourceFileName; } - - /** - * Gets the type of the objects that are instances of the class. - * @return The type of the instances of the class. - */ - public JType getType() { return new JObjectType(name); } - - public JClass getJClass() { return this; } - - public boolean isPublic() { - return (accessFlags & JAccessFlags.ACC_PUBLIC) != 0; - } - - public boolean isPrivate() { - return (accessFlags & JAccessFlags.ACC_PRIVATE) != 0; - } - - public boolean isProtected() { - return (accessFlags & JAccessFlags.ACC_PROTECTED) != 0; - } - - public boolean isStatic() { - return (accessFlags & JAccessFlags.ACC_STATIC) != 0; - } - - public boolean isFinal() { - return (accessFlags & JAccessFlags.ACC_FINAL) != 0; - } - - public boolean isAbstract() { - return (accessFlags & JAccessFlags.ACC_ABSTRACT) != 0; - } - - /** - * Gets the version number of the class. - * @param major The int representing the major part of the version number - * of the class. - * @param minor The int representing the minor part of the version number - * of the class. - */ - public void setVersion(int major, int minor) { - assert !frozen; - this.major = major; - this.minor = minor; - } - - /** - * Gets the major part of the number describing the version of the class. - * @return The int representing the major part of the version number of - * the class. - */ - public int getMajorVersion() { return major; } - - /** - * Gets the minor part of the number describing the version of the class. - * @return The int representing the minor part of the version number of - * the class. - */ - public int getMinorVersion() { return minor; } - - /** - * Gets the constant pool of the class. - * @return The constant pool of the class. - */ - public JConstantPool getConstantPool() { return pool; } - - public JInnerClassesAttribute getInnerClasses() { - if (innerClasses == null) { - innerClasses = new JInnerClassesAttribute(context, this); - addAttribute(innerClasses); - } - return innerClasses; - } - - /** - * Decides if the class is an interface. - * @return The boolean representing if the class is an interface or not. - */ - public boolean isInterface() { - return (accessFlags & JAccessFlags.ACC_INTERFACE) != 0; - } - - public void addField(JField field) { - assert !frozen; - fields.add(field); - } - - /** - * Create and add a new field to the class. - */ - public JField addNewField(int accessFlags, String name, JType type) { - assert !frozen; - JField f = context.JField(this, accessFlags, name, type); - addField(f); - return f; - } - - protected void addMethod(JMethod method) { - assert !frozen; - methods.add(method); - } - - /** - * Create and add a new method to the class. - */ - public JMethod addNewMethod(int accessFlags, - String name, - JType returnType, - JType[] argTypes, - String[] argNames) { - assert !frozen; - JMethod m = context.JMethod(this, - accessFlags, - name, - returnType, - argTypes, - argNames); - addMethod(m); - return m; - } - - /** - * Remove a previously-added method. This makes no attempt at - * minimising the constant pool by removing all constants which - * were used only by this method. - */ - public void removeMethod(JMethod m) { - assert !frozen; - methods.remove(m); - } - - public JField[] getFields() { - return (JField[])fields.toArray(new JField[fields.size()]); - } - - public JMethod[] getMethods() { - return (JMethod[])methods.toArray(new JMethod[methods.size()]); - } - - /** - * Freeze the contents of this class so that it can be written to - * a file. - */ - public void freeze() { - assert !frozen; - frozen = true; - } - - /** - * Writes the contents of the class to a file referenced by its name. - * @param fileName The name of the file in which the class must be written. - */ - public void writeTo(String fileName) throws IOException { - writeTo(new File(fileName)); - } - - /** - * Writes the contents of the class to a file. - * @param file The file in which the class must be written. - */ - public void writeTo(File file) throws IOException { - File parent = file.getParentFile(); - if (parent != null && !parent.isDirectory()) - if (!parent.mkdirs()) - throw new IOException("cannot create directory " + parent); - - FileOutputStream fStream = new FileOutputStream(file); - BufferedOutputStream bStream = new BufferedOutputStream(fStream); - DataOutputStream dStream = new DataOutputStream(bStream); - writeTo(dStream); - dStream.close(); - bStream.close(); - fStream.close(); - } - - /** - * Writes the contents of the class to a data stream. - * @param stream The data stream in which the class must be written. - */ - public void writeTo(DataOutputStream stream) throws IOException { - if (!frozen) freeze(); - - int thisClassIdx = pool.addClass(name); - int superClassIdx = pool.addClass(superclassName); - int[] interfacesIdx = new int[interfaceNames.length]; - - for (int i = 0; i < interfaceNames.length; ++i) - interfacesIdx[i] = pool.addClass(interfaceNames[i]); - - pool.freeze(); - - // Magic number. - stream.writeInt(MAGIC_NUMBER); - // Version - stream.writeShort(minor); - stream.writeShort(major); - // Constant pool - pool.writeTo(stream); - // Access flags - stream.writeShort(accessFlags); - - // This class, super class and interfaces - stream.writeShort(thisClassIdx); - stream.writeShort(superClassIdx); - stream.writeShort(interfacesIdx.length); - for (int i = 0; i < interfacesIdx.length; ++i) - stream.writeShort(interfacesIdx[i]); - - // Fields and methods - stream.writeShort(fields.size()); - Iterator fieldsIt = fields.iterator(); - while (fieldsIt.hasNext()) - ((JField)fieldsIt.next()).writeTo(stream); - - stream.writeShort(methods.size()); - Iterator methodsIt = methods.iterator(); - while (methodsIt.hasNext()) - ((JMethod)methodsIt.next()).writeTo(stream); - - // Attributes - JAttribute.writeTo(attributes, stream); - } - - // Follows javap output format for ClassFile. - /*@Override*/ public String toString() { - StringBuffer buf = new StringBuffer(); - if (sourceFileName != null) { - buf.append("Compiled from \""); - buf.append(sourceFileName); - buf.append("\"\n"); - } - buf.append(getMemberName()); - buf.append(toExternalName(getName())); - if (!isInterface()) { - buf.append(" extends "); - buf.append(toExternalName(getSuperclassName())); - } - if (interfaceNames.length > 0) { - if (isInterface()) buf.append(" extends "); - else buf.append(" implements "); - for (int i = 0; i < interfaceNames.length; ++i) { - if (i > 0) buf.append(","); - buf.append(toExternalName(interfaceNames[i])); - } - } - buf.append("\n"); - Iterator attrsIt = attributes.iterator(); - while (attrsIt.hasNext()) { - JAttribute attr = (JAttribute)attrsIt.next(); - buf.append(attr); - } - buf.append(" minor version: "); - buf.append(minor); - buf.append("\n major version: "); - buf.append(major); - buf.append("\n"); - buf.append(pool); - buf.append("\n{\n"); - JField[] jfields = getFields(); - for (int i = 0; i < jfields.length; ++i) { - if (i > 0) buf.append("\n"); - buf.append(jfields[i]); - } - buf.append("\n"); - JMethod[] jmethods = getMethods(); - for (int i = 0; i < jmethods.length; ++i) { - if (i > 0) buf.append("\n"); - buf.append(jmethods[i]); - } - buf.append("\n}\n"); - return buf.toString(); - } - - private String getMemberName() { - StringBuffer buf = new StringBuffer(); - if (isPublic()) buf.append("public "); - else if (isProtected()) buf.append("protected "); - else if (isPrivate()) buf.append("private "); - if (isInterface()) - buf.append("interface "); - else { - if (isAbstract()) buf.append("abstract "); - else if (isFinal()) buf.append("final "); - buf.append("class "); - } - return buf.toString(); - } -} diff --git a/src/fjbg/ch/epfl/lamp/fjbg/JCode.java b/src/fjbg/ch/epfl/lamp/fjbg/JCode.java deleted file mode 100644 index ab6934ab30..0000000000 --- a/src/fjbg/ch/epfl/lamp/fjbg/JCode.java +++ /dev/null @@ -1,1308 +0,0 @@ -/* FJBG -- Fast Java Bytecode Generator - * Copyright 2002-2013 LAMP/EPFL - * @author Michel Schinz - */ - -package ch.epfl.lamp.fjbg; - -import java.io.DataInputStream; -import java.io.DataOutputStream; -import java.io.IOException; -import java.util.*; - -import ch.epfl.lamp.util.ByteArray; - -/** - * List of instructions, to which Java byte-code instructions can be added. - * - * @author Michel Schinz, Thomas Friedli - * @version 1.0 - */ - -public class JCode { - protected boolean frozen = false; - - public static int MAX_CODE_SIZE = 65535; - - protected final FJBGContext context; - protected final JMethod owner; - - protected final ByteArray codeArray; - - protected final LinkedList/*<ExceptionHandler>*/ exceptionHandlers = - new LinkedList(); - - protected final JConstantPool pool; - - protected final ArrayList/*<OffsetToPatch>*/ offsetToPatch = - new ArrayList(); - - protected static int UNKNOWN_STACK_SIZE = Integer.MIN_VALUE; - protected int maxStackSize = UNKNOWN_STACK_SIZE; - protected int[] stackProduction = null; - protected int[] stackSizes; - - protected JCode(FJBGContext context, JClass clazz, JMethod owner) { - this.context = context; - this.pool = clazz.getConstantPool(); - this.owner = owner; - this.codeArray = new ByteArray(); - } - - protected JCode(FJBGContext context, - JClass clazz, - JMethod owner, - DataInputStream stream) - throws IOException { - this.context = context; - this.pool = clazz.getConstantPool(); - this.owner = owner; - owner.setCode(this); - int size = stream.readInt(); - if (size > MAX_CODE_SIZE) // section 4.10 - throw new Error("code size must be less than " + MAX_CODE_SIZE + ": " + size); - this.codeArray = new ByteArray(stream, size); - } - - /** - * Gets the program counter, which is defined as the address of the - * next instruction. - * @return The int representing the value of the program counter - */ - public int getPC() { - return codeArray.getSize(); - } - - /** - * Gets the size of the code - * @return The number of bytes of the code - */ - public int getSize() { - return codeArray.getSize(); - } - - /** - * Gets the method to which the code belongs - * @return The method to which the code belongs - */ - public JMethod getOwner() { - return owner; - } - - // Stack size - public int getMaxStackSize() { - if (maxStackSize == UNKNOWN_STACK_SIZE) - maxStackSize = computeMaxStackSize(); - return maxStackSize; - } - - // Freezing - ////////////////////////////////////////////////////////////////////// - - public static class CodeSizeTooBigException extends OffsetTooBigException { - public int codeSize; - - public CodeSizeTooBigException(int size) { - codeSize = size; - } - } - - public void freeze() throws OffsetTooBigException { - assert !frozen; - - if (getSize() > MAX_CODE_SIZE) throw new CodeSizeTooBigException(getSize()); - - patchAllOffset(); - codeArray.freeze(); - frozen = true; - } - - // Attributes - ////////////////////////////////////////////////////////////////////// - - protected final LinkedList/*<JAttribute>*/ attributes = new LinkedList(); - - public void addAttribute(JAttribute attr) { - attributes.add(attr); - } - - public List/*<JAttribute>*/ getAttributes() { - return attributes; - } - - // Emitting code - ////////////////////////////////////////////////////////////////////// - - public void emit(JOpcode opcode) { - setStackProduction(getPC(), opcode); - codeArray.addU1(opcode.code); - } - - public void emitNOP() { emit(JOpcode.NOP); } - - // Constant loading. - public void emitACONST_NULL() { emit(JOpcode.ACONST_NULL); } - public void emitICONST_M1() { emit(JOpcode.ICONST_M1); } - public void emitICONST_0() { emit(JOpcode.ICONST_0); } - public void emitICONST_1() { emit(JOpcode.ICONST_1); } - public void emitICONST_2() { emit(JOpcode.ICONST_2); } - public void emitICONST_3() { emit(JOpcode.ICONST_3); } - public void emitICONST_4() { emit(JOpcode.ICONST_4); } - public void emitICONST_5() { emit(JOpcode.ICONST_5); } - public void emitLCONST_0() { emit(JOpcode.LCONST_0); } - public void emitLCONST_1() { emit(JOpcode.LCONST_1); } - public void emitFCONST_0() { emit(JOpcode.FCONST_0); } - public void emitFCONST_1() { emit(JOpcode.FCONST_1); } - public void emitFCONST_2() { emit(JOpcode.FCONST_2); } - public void emitDCONST_0() { emit(JOpcode.DCONST_0); } - public void emitDCONST_1() { emit(JOpcode.DCONST_1); } - - public void emitBIPUSH(int b) { emitU1(JOpcode.BIPUSH, b); } - public void emitSIPUSH(int s) { emitU2(JOpcode.SIPUSH, s); } - public void emitLDC(int value) { - emitU1(JOpcode.LDC, pool.addInteger(value)); - } - public void emitLDC(float value) { - emitU1(JOpcode.LDC, pool.addFloat(value)); - } - public void emitLDC(String value) { - emitU1(JOpcode.LDC, pool.addString(value)); - } - public void emitLDC_W(int value) { - emitU1(JOpcode.LDC_W, pool.addInteger(value)); - } - public void emitLDC_W(float value) { - emitU1(JOpcode.LDC_W, pool.addFloat(value)); - } - public void emitLDC_W(String value) { - emitU1(JOpcode.LDC_W, pool.addString(value)); - } - public void emitLDC2_W(long value) { - emitU2(JOpcode.LDC2_W, pool.addLong(value)); - } - public void emitLDC2_W(double value) { - emitU2(JOpcode.LDC2_W, pool.addDouble(value)); - } - - // Loading variables. - public void emitILOAD(int index) { emitU1(JOpcode.ILOAD, index); } - public void emitLLOAD(int index) { emitU1(JOpcode.LLOAD, index); } - public void emitFLOAD(int index) { emitU1(JOpcode.FLOAD, index); } - public void emitDLOAD(int index) { emitU1(JOpcode.DLOAD, index); } - public void emitALOAD(int index) { emitU1(JOpcode.ALOAD, index); } - - public void emitILOAD_0() { emit(JOpcode.ILOAD_0); } - public void emitILOAD_1() { emit(JOpcode.ILOAD_1); } - public void emitILOAD_2() { emit(JOpcode.ILOAD_2); } - public void emitILOAD_3() { emit(JOpcode.ILOAD_3); } - public void emitLLOAD_0() { emit(JOpcode.LLOAD_0); } - public void emitLLOAD_1() { emit(JOpcode.LLOAD_1); } - public void emitLLOAD_2() { emit(JOpcode.LLOAD_2); } - public void emitLLOAD_3() { emit(JOpcode.LLOAD_3); } - public void emitFLOAD_0() { emit(JOpcode.FLOAD_0); } - public void emitFLOAD_1() { emit(JOpcode.FLOAD_1); } - public void emitFLOAD_2() { emit(JOpcode.FLOAD_2); } - public void emitFLOAD_3() { emit(JOpcode.FLOAD_3); } - public void emitDLOAD_0() { emit(JOpcode.DLOAD_0); } - public void emitDLOAD_1() { emit(JOpcode.DLOAD_1); } - public void emitDLOAD_2() { emit(JOpcode.DLOAD_2); } - public void emitDLOAD_3() { emit(JOpcode.DLOAD_3); } - public void emitALOAD_0() { emit(JOpcode.ALOAD_0); } - public void emitALOAD_1() { emit(JOpcode.ALOAD_1); } - public void emitALOAD_2() { emit(JOpcode.ALOAD_2); } - public void emitALOAD_3() { emit(JOpcode.ALOAD_3); } - - public void emitIALOAD() { emit(JOpcode.IALOAD); } - public void emitLALOAD() { emit(JOpcode.LALOAD); } - public void emitFALOAD() { emit(JOpcode.FALOAD); } - public void emitDALOAD() { emit(JOpcode.DALOAD); } - public void emitAALOAD() { emit(JOpcode.AALOAD); } - public void emitBALOAD() { emit(JOpcode.BALOAD); } - public void emitCALOAD() { emit(JOpcode.CALOAD); } - public void emitSALOAD() { emit(JOpcode.SALOAD); } - - // Storing variables. - public void emitISTORE(int index) { emitU1(JOpcode.ISTORE, index); } - public void emitLSTORE(int index) { emitU1(JOpcode.LSTORE, index); } - public void emitFSTORE(int index) { emitU1(JOpcode.FSTORE, index); } - public void emitDSTORE(int index) { emitU1(JOpcode.DSTORE, index); } - public void emitASTORE(int index) { emitU1(JOpcode.ASTORE, index); } - - public void emitISTORE_0() { emit(JOpcode.ISTORE_0); } - public void emitISTORE_1() { emit(JOpcode.ISTORE_1); } - public void emitISTORE_2() { emit(JOpcode.ISTORE_2); } - public void emitISTORE_3() { emit(JOpcode.ISTORE_3); } - public void emitLSTORE_0() { emit(JOpcode.LSTORE_0); } - public void emitLSTORE_1() { emit(JOpcode.LSTORE_1); } - public void emitLSTORE_2() { emit(JOpcode.LSTORE_2); } - public void emitLSTORE_3() { emit(JOpcode.LSTORE_3); } - public void emitFSTORE_0() { emit(JOpcode.FSTORE_0); } - public void emitFSTORE_1() { emit(JOpcode.FSTORE_1); } - public void emitFSTORE_2() { emit(JOpcode.FSTORE_2); } - public void emitFSTORE_3() { emit(JOpcode.FSTORE_3); } - public void emitDSTORE_0() { emit(JOpcode.DSTORE_0); } - public void emitDSTORE_1() { emit(JOpcode.DSTORE_1); } - public void emitDSTORE_2() { emit(JOpcode.DSTORE_2); } - public void emitDSTORE_3() { emit(JOpcode.DSTORE_3); } - public void emitASTORE_0() { emit(JOpcode.ASTORE_0); } - public void emitASTORE_1() { emit(JOpcode.ASTORE_1); } - public void emitASTORE_2() { emit(JOpcode.ASTORE_2); } - public void emitASTORE_3() { emit(JOpcode.ASTORE_3); } - - public void emitIASTORE() { emit(JOpcode.IASTORE); } - public void emitLASTORE() { emit(JOpcode.LASTORE); } - public void emitFASTORE() { emit(JOpcode.FASTORE); } - public void emitDASTORE() { emit(JOpcode.DASTORE); } - public void emitAASTORE() { emit(JOpcode.AASTORE); } - public void emitBASTORE() { emit(JOpcode.BASTORE); } - public void emitCASTORE() { emit(JOpcode.CASTORE); } - public void emitSASTORE() { emit(JOpcode.SASTORE); } - - // Stack manipulation. - public void emitPOP() { emit(JOpcode.POP); } - public void emitPOP2() { emit(JOpcode.POP2); } - public void emitDUP() { emit(JOpcode.DUP); } - public void emitDUP_X1() { emit(JOpcode.DUP_X1); } - public void emitDUP_X2() { emit(JOpcode.DUP_X2); } - public void emitDUP2() { emit(JOpcode.DUP2); } - public void emitDUP2_X1() { emit(JOpcode.DUP2_X1); } - public void emitDUP2_X2() { emit(JOpcode.DUP2_X2); } - public void emitSWAP() { emit(JOpcode.SWAP); } - - // Artithmetic and logic operations. - public void emitIADD() { emit(JOpcode.IADD); } - public void emitLADD() { emit(JOpcode.LADD); } - public void emitFADD() { emit(JOpcode.FADD); } - public void emitDADD() { emit(JOpcode.DADD); } - - public void emitISUB() { emit(JOpcode.ISUB); } - public void emitLSUB() { emit(JOpcode.LSUB); } - public void emitFSUB() { emit(JOpcode.FSUB); } - public void emitDSUB() { emit(JOpcode.DSUB); } - - public void emitIMUL() { emit(JOpcode.IMUL); } - public void emitLMUL() { emit(JOpcode.LMUL); } - public void emitFMUL() { emit(JOpcode.FMUL); } - public void emitDMUL() { emit(JOpcode.DMUL); } - - public void emitIDIV() { emit(JOpcode.IDIV); } - public void emitLDIV() { emit(JOpcode.LDIV); } - public void emitFDIV() { emit(JOpcode.FDIV); } - public void emitDDIV() { emit(JOpcode.DDIV); } - - public void emitIREM() { emit(JOpcode.IREM); } - public void emitLREM() { emit(JOpcode.LREM); } - public void emitFREM() { emit(JOpcode.FREM); } - public void emitDREM() { emit(JOpcode.DREM); } - - public void emitINEG() { emit(JOpcode.INEG); } - public void emitLNEG() { emit(JOpcode.LNEG); } - public void emitFNEG() { emit(JOpcode.FNEG); } - public void emitDNEG() { emit(JOpcode.DNEG); } - - public void emitISHL() { emit(JOpcode.ISHL); } - public void emitLSHL() { emit(JOpcode.LSHL); } - - public void emitISHR() { emit(JOpcode.ISHR); } - public void emitLSHR() { emit(JOpcode.LSHR); } - - public void emitIUSHR() { emit(JOpcode.IUSHR); } - public void emitLUSHR() { emit(JOpcode.LUSHR); } - - public void emitIAND() { emit(JOpcode.IAND); } - public void emitLAND() { emit(JOpcode.LAND); } - - public void emitIOR() { emit(JOpcode.IOR); } - public void emitLOR() { emit(JOpcode.LOR); } - - public void emitIXOR() { emit(JOpcode.IXOR); } - public void emitLXOR() { emit(JOpcode.LXOR); } - - public void emitIINC(int index, int increment) { - emitU1U1(JOpcode.IINC, index, increment); - } - - // (Numeric) type conversions. - public void emitI2L() { emit(JOpcode.I2L); } - public void emitI2F() { emit(JOpcode.I2F); } - public void emitI2D() { emit(JOpcode.I2D); } - public void emitL2I() { emit(JOpcode.L2I); } - public void emitL2F() { emit(JOpcode.L2F); } - public void emitL2D() { emit(JOpcode.L2D); } - public void emitF2I() { emit(JOpcode.F2I); } - public void emitF2L() { emit(JOpcode.F2L); } - public void emitF2D() { emit(JOpcode.F2D); } - public void emitD2I() { emit(JOpcode.D2I); } - public void emitD2L() { emit(JOpcode.D2L); } - public void emitD2F() { emit(JOpcode.D2F); } - public void emitI2B() { emit(JOpcode.I2B); } - public void emitI2C() { emit(JOpcode.I2C); } - public void emitI2S() { emit(JOpcode.I2S); } - - // Comparisons and tests. - public void emitLCMP() { emit(JOpcode.LCMP); } - public void emitFCMPL() { emit(JOpcode.FCMPL); } - public void emitFCMPG() { emit(JOpcode.FCMPG); } - public void emitDCMPL() { emit(JOpcode.DCMPL); } - public void emitDCMPG() { emit(JOpcode.DCMPG); } - - protected void emitGenericIF(JOpcode opcode, Label label) - throws OffsetTooBigException { - emitU2(opcode, label.getOffset16(getPC() + 1, getPC())); - } - - public void emitIFEQ(Label label) throws OffsetTooBigException { - emitGenericIF(JOpcode.IFEQ, label); - } - public void emitIFEQ(int targetPC) throws OffsetTooBigException { - emitU2(JOpcode.IFEQ, targetPC - getPC()); - } - public void emitIFEQ() { - emitU2(JOpcode.IFEQ, 0); - } - - public void emitIFNE(Label label) throws OffsetTooBigException { - emitGenericIF(JOpcode.IFNE, label); - } - public void emitIFNE(int targetPC) throws OffsetTooBigException { - emitU2(JOpcode.IFNE, targetPC - getPC()); - } - public void emitIFNE() { - emitU2(JOpcode.IFNE, 0); - } - - public void emitIFLT(Label label) throws OffsetTooBigException { - emitGenericIF(JOpcode.IFLT, label); - } - public void emitIFLT(int targetPC) throws OffsetTooBigException { - emitU2(JOpcode.IFLT, targetPC - getPC()); - } - public void emitIFLT() { - emitU2(JOpcode.IFLT, 0); - } - - public void emitIFGE(Label label) throws OffsetTooBigException { - emitGenericIF(JOpcode.IFGE, label); - } - public void emitIFGE(int targetPC) throws OffsetTooBigException { - emitU2(JOpcode.IFGE, targetPC - getPC()); - } - public void emitIFGE() { - emitU2(JOpcode.IFGE, 0); - } - - public void emitIFGT(Label label) throws OffsetTooBigException { - emitGenericIF(JOpcode.IFGT, label); - } - public void emitIFGT(int targetPC) throws OffsetTooBigException { - emitU2(JOpcode.IFGT, targetPC - getPC()); - } - public void emitIFGT() { - emitU2(JOpcode.IFGT, 0); - } - - public void emitIFLE(Label label) throws OffsetTooBigException { - emitGenericIF(JOpcode.IFLE, label); - } - public void emitIFLE(int targetPC) throws OffsetTooBigException { - emitU2(JOpcode.IFLE, targetPC - getPC()); - } - public void emitIFLE() { - emitU2(JOpcode.IFLE, 0); - } - - public void emitIF_ICMPEQ(Label label) throws OffsetTooBigException { - emitGenericIF(JOpcode.IF_ICMPEQ, label); - } - public void emitIF_ICMPEQ(int targetPC) throws OffsetTooBigException { - emitU2(JOpcode.IF_ICMPEQ, targetPC - getPC()); - } - public void emitIF_ICMPEQ() { - emitU2(JOpcode.IF_ICMPEQ, 0); - } - - public void emitIF_ICMPNE(Label label) throws OffsetTooBigException { - emitGenericIF(JOpcode.IF_ICMPNE, label); - } - public void emitIF_ICMPNE(int targetPC) throws OffsetTooBigException { - emitU2(JOpcode.IF_ICMPNE, targetPC - getPC()); - } - public void emitIF_ICMPNE() { - emitU2(JOpcode.IF_ICMPNE, 0); - } - - public void emitIF_ICMPLT(Label label) throws OffsetTooBigException { - emitGenericIF(JOpcode.IF_ICMPLT, label); - } - public void emitIF_ICMPLT(int targetPC) throws OffsetTooBigException { - emitU2(JOpcode.IF_ICMPLT, targetPC - getPC()); - } - public void emitIF_ICMPLT() { - emitU2(JOpcode.IF_ICMPLT, 0); - } - - public void emitIF_ICMPGE(Label label) throws OffsetTooBigException { - emitGenericIF(JOpcode.IF_ICMPGE, label); - } - public void emitIF_ICMPGE(int targetPC) throws OffsetTooBigException { - emitU2(JOpcode.IF_ICMPGE, targetPC - getPC()); - } - public void emitIF_ICMPGE() { - emitU2(JOpcode.IF_ICMPGE, 0); - } - - public void emitIF_ICMPGT(Label label) throws OffsetTooBigException { - emitGenericIF(JOpcode.IF_ICMPGT, label); - } - public void emitIF_ICMPGT(int targetPC) throws OffsetTooBigException { - emitU2(JOpcode.IF_ICMPGT, targetPC - getPC()); - } - public void emitIF_ICMPGT() { - emitU2(JOpcode.IF_ICMPGT, 0); - } - - public void emitIF_ICMPLE(Label label) throws OffsetTooBigException { - emitGenericIF(JOpcode.IF_ICMPLE, label); - } - public void emitIF_ICMPLE(int targetPC) throws OffsetTooBigException { - emitU2(JOpcode.IF_ICMPLE, targetPC - getPC()); - } - public void emitIF_ICMPLE() { - emitU2(JOpcode.IF_ICMPLE, 0); - } - - public void emitIF_ACMPEQ(Label label) throws OffsetTooBigException { - emitGenericIF(JOpcode.IF_ACMPEQ, label); - } - public void emitIF_ACMPEQ(int targetPC) throws OffsetTooBigException { - emitU2(JOpcode.IF_ACMPEQ, targetPC - getPC()); - } - public void emitIF_ACMPEQ() { - emitU2(JOpcode.IF_ACMPEQ, 0); - } - - public void emitIF_ACMPNE(Label label) throws OffsetTooBigException { - emitGenericIF(JOpcode.IF_ACMPNE, label); - } - public void emitIF_ACMPNE(int targetPC) throws OffsetTooBigException { - emitU2(JOpcode.IF_ACMPNE, targetPC - getPC()); - } - public void emitIF_ACMPNE() { - emitU2(JOpcode.IF_ACMPNE, 0); - } - - public void emitIFNULL(Label label) throws OffsetTooBigException { - emitGenericIF(JOpcode.IFNULL, label); - } - public void emitIFNULL(int targetPC) throws OffsetTooBigException { - emitU2(JOpcode.IFNULL, targetPC - getPC()); - } - public void emitIFNULL() { - emitU2(JOpcode.IFNULL, 0); - } - - public void emitIFNONNULL(Label label) throws OffsetTooBigException { - emitGenericIF(JOpcode.IFNONNULL, label); - } - public void emitIFNONNULL(int targetPC) throws OffsetTooBigException { - emitU2(JOpcode.IFNONNULL, targetPC - getPC()); - } - public void emitIFNONNULL() { - emitU2(JOpcode.IFNONNULL, 0); - } - - public void emitGOTO(Label label) throws OffsetTooBigException { - emitU2(JOpcode.GOTO, label.getOffset16(getPC() + 1, getPC())); - } - public void emitGOTO(int targetPC) throws OffsetTooBigException { - int offset = targetPC - getPC(); - checkOffset16(offset); - emitU2(JOpcode.GOTO, offset); - } - public void emitGOTO() { - emitU2(JOpcode.GOTO, 0); - } - - public void emitGOTO_W(Label label) { - emitU4(JOpcode.GOTO_W, label.getOffset32(getPC() + 1, getPC())); - } - public void emitGOTO_W(int targetPC) { - emitU4(JOpcode.GOTO_W, targetPC - getPC()); - } - public void emitGOTO_W() { - emitU4(JOpcode.GOTO_W, 0); - } - - public void emitJSR(Label label) throws OffsetTooBigException { - emitU2(JOpcode.JSR, label.getOffset16(getPC() + 1, getPC())); - } - public void emitJSR(int targetPC) { - emitU2(JOpcode.JSR, targetPC - getPC()); - } - public void emitJSR() { - emitU2(JOpcode.JSR, 0); - } - - public void emitJSR_W(Label label) { - emitU4(JOpcode.JSR_W, label.getOffset32(getPC() + 1, getPC())); - } - public void emitJSR_W(int targetPC) { - emitU4(JOpcode.JSR_W, targetPC - getPC()); - } - public void emitJSR_W() { - emitU4(JOpcode.JSR_W, 0); - } - - /* - public void emitRET(Label label) throws OffsetTooBigException { - emitU2(JOpcode.RET, label.getOffset16(getPC() + 1, getPC())); - } - public void emitRET(int targetPC) { - emitU1(JOpcode.RET, targetPC); - } - public void emitRET() { - emitU1(JOpcode.RET, 0); - } - */ - - public void emitRET(int index) { - emitU1(JOpcode.RET, index); - } - - public void emitRET(JLocalVariable var) { - emitRET(var.getIndex()); - } - - public void emitTABLESWITCH(int[] keys, - Label[] branches, - Label defaultBranch) { - assert keys.length == branches.length; - - int low = keys[0], high = keys[keys.length - 1]; - int instrPC = getPC(); - - setStackProduction(instrPC, JOpcode.TABLESWITCH); - codeArray.addU1(JOpcode.cTABLESWITCH); - while (getPC() % 4 != 0) codeArray.addU1(0); - - codeArray.addU4(defaultBranch.getOffset32(getPC(), instrPC)); - codeArray.addU4(low); - codeArray.addU4(high); - for (int i = 0; i < branches.length; i++) { - assert keys[i] == low + i; - codeArray.addU4(branches[i].getOffset32(getPC(), instrPC)); - } - } - - public void emitLOOKUPSWITCH(int[] keys, - Label[] branches, - Label defaultBranch) { - assert keys.length == branches.length; - - int instrPC = getPC(); - setStackProduction(getPC(), JOpcode.LOOKUPSWITCH); - codeArray.addU1(JOpcode.cLOOKUPSWITCH); - while (getPC() % 4 != 0) codeArray.addU1(0); - - codeArray.addU4(defaultBranch.getOffset32(getPC(), instrPC)); - codeArray.addU4(branches.length); - for (int i = 0; i < branches.length; i++) { - codeArray.addU4(keys[i]); - codeArray.addU4(branches[i].getOffset32(getPC(), instrPC)); - } - } - - public void emitIRETURN() { emit(JOpcode.IRETURN); } - public void emitLRETURN() { emit(JOpcode.LRETURN); } - public void emitFRETURN() { emit(JOpcode.FRETURN); } - public void emitDRETURN() { emit(JOpcode.DRETURN); } - public void emitARETURN() { emit(JOpcode.ARETURN); } - public void emitRETURN() { emit(JOpcode.RETURN); } - - // Field access - public void emitGETSTATIC(String className, String name, JType type) { - setStackProduction(getPC(), type.getSize()); - int index = pool.addFieldRef(className, name, type.getSignature()); - emitU2(JOpcode.GETSTATIC, index); - } - public void emitPUTSTATIC(String className, String name, JType type) { - setStackProduction(getPC(), -type.getSize()); - int index = pool.addFieldRef(className, name, type.getSignature()); - emitU2(JOpcode.PUTSTATIC, index); - } - public void emitGETFIELD(String className, String name, JType type) { - setStackProduction(getPC(), type.getSize() - 1); - int index = pool.addFieldRef(className, name, type.getSignature()); - emitU2(JOpcode.GETFIELD, index); - } - public void emitPUTFIELD(String className, String name, JType type) { - setStackProduction(getPC(), -(type.getSize() + 1)); - int index = pool.addFieldRef(className, name, type.getSignature()); - emitU2(JOpcode.PUTFIELD, index); - } - - // Method invocation - public void emitINVOKEVIRTUAL(String className, - String name, - JMethodType type) { - setStackProduction(getPC(), type.getProducedStack() - 1); - int index = - pool.addClassMethodRef(className, name, type.getSignature()); - emitU2(JOpcode.INVOKEVIRTUAL, index); - } - public void emitINVOKESPECIAL(String className, - String name, - JMethodType type) { - setStackProduction(getPC(), type.getProducedStack() - 1); - int index = - pool.addClassMethodRef(className, name, type.getSignature()); - emitU2(JOpcode.INVOKESPECIAL, index); - } - public void emitINVOKESTATIC(String className, - String name, - JMethodType type) { - setStackProduction(getPC(), type.getProducedStack()); - int index = - pool.addClassMethodRef(className, name, type.getSignature()); - emitU2(JOpcode.INVOKESTATIC, index); - } - public void emitINVOKEINTERFACE(String className, - String name, - JMethodType type) { - setStackProduction(getPC(), type.getProducedStack() - 1); - int index = - pool.addInterfaceMethodRef(className, name, type.getSignature()); - emitU2U1U1(JOpcode.INVOKEINTERFACE, index, type.getArgsSize() + 1, 0); - } - - // Object creation - public void emitNEW(String className) { - emitU2(JOpcode.NEW, pool.addClass(className)); - } - public void emitNEWARRAY(JType elemType) { - emitU1(JOpcode.NEWARRAY, elemType.getTag()); - } - public void emitANEWARRAY(JReferenceType elemType) { - emitU2(JOpcode.ANEWARRAY, pool.addDescriptor(elemType)); - } - public void emitMULTIANEWARRAY(JReferenceType elemType, int dimensions) { - setStackProduction(getPC(), -dimensions + 1); - emitU2U1(JOpcode.MULTIANEWARRAY, - pool.addDescriptor(elemType), - dimensions); - } - public void emitARRAYLENGTH() { emit(JOpcode.ARRAYLENGTH); } - - // Exception throwing - public void emitATHROW() { emit(JOpcode.ATHROW); } - - // Dynamic typing - public void emitCHECKCAST(JReferenceType type) { - emitU2(JOpcode.CHECKCAST, pool.addDescriptor(type)); - } - public void emitINSTANCEOF(JReferenceType type) { - emitU2(JOpcode.INSTANCEOF, pool.addDescriptor(type)); - } - - // Monitors - public void emitMONITORENTER() { emit(JOpcode.MONITORENTER); } - public void emitMONITOREXIT() { emit(JOpcode.MONITOREXIT); } - - // Wide variants - // FIXME setStackProd. will here raise an exception - public void emitWIDE(JOpcode opcode, int index) { - assert (opcode.code == JOpcode.cILOAD) - || (opcode.code == JOpcode.cLLOAD) - || (opcode.code == JOpcode.cFLOAD) - || (opcode.code == JOpcode.cDLOAD) - || (opcode.code == JOpcode.cALOAD) - || (opcode.code == JOpcode.cISTORE) - || (opcode.code == JOpcode.cLSTORE) - || (opcode.code == JOpcode.cFSTORE) - || (opcode.code == JOpcode.cDSTORE) - || (opcode.code == JOpcode.cASTORE) - || (opcode.code == JOpcode.cRET) - : "invalide opcode for WIDE: " + opcode; - - setStackProduction(getPC(), opcode); - codeArray.addU1(JOpcode.WIDE.code); - codeArray.addU1(opcode.code); - codeArray.addU2(index); - } - public void emitWIDE(JOpcode opcode, int index, int constant) { - assert opcode.code == JOpcode.cIINC - : "invalid opcode for WIDE: " + opcode; - - setStackProduction(getPC(), opcode); - codeArray.addU1(JOpcode.cWIDE); - codeArray.addU1(opcode.code); - codeArray.addU2(index); - codeArray.addU2(constant); - } - - protected void emitU1(JOpcode opcode, int i1) { - setStackProduction(getPC(), opcode); - codeArray.addU1(opcode.code); - codeArray.addU1(i1); - } - - protected void emitU1U1(JOpcode opcode, int i1, int i2) { - setStackProduction(getPC(), opcode); - codeArray.addU1(opcode.code); - codeArray.addU1(i1); - codeArray.addU1(i2); - } - - protected void emitU2(JOpcode opcode, int i1) { - setStackProduction(getPC(), opcode); - codeArray.addU1(opcode.code); - codeArray.addU2(i1); - } - - protected void emitU2U1(JOpcode opcode, int i1, int i2) { - setStackProduction(getPC(), opcode); - codeArray.addU1(opcode.code); - codeArray.addU2(i1); - codeArray.addU1(i2); - } - - protected void emitU2U1U1(JOpcode opcode, int i1, int i2, int i3) { - setStackProduction(getPC(), opcode); - codeArray.addU1(opcode.code); - codeArray.addU2(i1); - codeArray.addU1(i2); - codeArray.addU1(i3); - } - - protected void emitU4(JOpcode opcode, int i1) { - setStackProduction(getPC(), opcode); - codeArray.addU1(opcode.code); - codeArray.addU4(i1); - } - - protected int getU1(int sourcePos) { - return codeArray.getU1(sourcePos); - } - - protected int getU2(int sourcePos) { - return codeArray.getU2(sourcePos); - } - - protected int getU4(int sourcePos) { - return codeArray.getU4(sourcePos); - } - - protected int getS1(int sourcePos) { - return codeArray.getS1(sourcePos); - } - - protected int getS2(int sourcePos) { - return codeArray.getS2(sourcePos); - } - - protected int getS4(int sourcePos) { - return codeArray.getS4(sourcePos); - } - - // Stack size computation - ////////////////////////////////////////////////////////////////////// - - protected int getStackProduction(int pc) { - if (stackProduction == null || pc >= stackProduction.length) - return UNKNOWN_STACK_SIZE; - else - return stackProduction[pc]; - } - - protected void setStackProduction(int pc, int production) { - if (stackProduction == null) { - stackProduction = new int[256]; - Arrays.fill(stackProduction, UNKNOWN_STACK_SIZE); - } else { - while (pc >= stackProduction.length) { - int[] newStackProduction = new int[stackProduction.length * 2]; - System.arraycopy(stackProduction, 0, - newStackProduction, 0, - stackProduction.length); - Arrays.fill(newStackProduction, - stackProduction.length, - newStackProduction.length, - UNKNOWN_STACK_SIZE); - stackProduction = newStackProduction; - } - } - stackProduction[pc] = production; - } - - protected void setStackProduction(int pc, JOpcode opcode) { - // TODO we should instead check whether the opcode has known - // stack consumption/production. - if (getStackProduction(pc) == UNKNOWN_STACK_SIZE) -// && opcode.hasKnownProducedDataSize() -// && opcode.hasKnownConsumedDataSize()) - setStackProduction(pc, - opcode.getProducedDataSize() - - opcode.getConsumedDataSize()); - } - - protected int computeMaxStackSize() { - if (stackSizes == null) { - stackSizes = new int[getSize()]; - Arrays.fill(stackSizes, UNKNOWN_STACK_SIZE); - stackSizes[0] = 0; - } - int size = computeMaxStackSize(0, 0, 0); - - // compute stack sizes for exception handlers too - ExceptionHandler exh = null; - for (Iterator it = exceptionHandlers.iterator(); - it.hasNext();) { - exh = (ExceptionHandler)it.next(); - int exhSize = computeMaxStackSize(exh.getHandlerPC(), 1, 1); - if (size < exhSize) - size = exhSize; - } - - return size; - } - - protected int computeMaxStackSize(int pc, int stackSize, int maxStackSize) { - JCodeIterator iterator = new JCodeIterator(this, pc); - for (;;) { - int successors = iterator.getSuccessorCount(); - if (successors == 0) - return maxStackSize; - else { - assert stackProduction[iterator.getPC()] != UNKNOWN_STACK_SIZE - : "unknown stack production, pc=" + iterator.getPC() - + " in method " + owner.getName(); - stackSize += stackProduction[iterator.getPC()]; - if (stackSize > maxStackSize) - maxStackSize = stackSize; - int nextPC = -1; - for (int i = 0; i < successors; ++i) { - int succPC = iterator.getSuccessorPC(i); - assert succPC >= 0 && succPC < stackSizes.length - : iterator.getPC() + ": invalid pc: " + succPC - + " op: " + iterator.getOpcode(); - if (stackSizes[succPC] == UNKNOWN_STACK_SIZE) { - stackSizes[succPC] = stackSize; - if (nextPC == -1) - nextPC = succPC; - else - maxStackSize = computeMaxStackSize(succPC, - stackSize, - maxStackSize); - } - } - if (nextPC == -1) - return maxStackSize; - else - iterator.moveTo(nextPC); - } - } - } - - // Labels - ////////////////////////////////////////////////////////////////////// - - public static class OffsetTooBigException extends Exception { - public OffsetTooBigException() { super(); } - public OffsetTooBigException(String message) { super(message); } - } - - protected void checkOffset16(int offset) throws OffsetTooBigException { - if (offset < Short.MIN_VALUE || offset > Short.MAX_VALUE) - throw new OffsetTooBigException("offset too big to fit" - + " in 16 bits: " + offset); - } - - public class Label { - protected boolean anchored = false; - protected int targetPC = 0; - - public void anchorToNext() { - assert !anchored; - this.targetPC = getPC(); - anchored = true; - } - - public int getAnchor() { - assert anchored; - return targetPC; - } - - protected int getOffset16(int pc, int instrPC) - throws OffsetTooBigException { - if (anchored) { - int offset = targetPC - instrPC; - checkOffset16(offset); - return offset; - } else { - recordOffsetToPatch(pc, 16, instrPC, this); - return 0; - } - } - - protected int getOffset32(int pc, int instrPC) { - if (anchored) - return targetPC - instrPC; - else { - recordOffsetToPatch(pc, 32, instrPC, this); - return 0; - } - } - } - - public Label newLabel() { - return new Label(); - } - - public Label[] newLabels(int count) { - Label[] labels = new Label[count]; - for (int i = 0; i < labels.length; ++i) - labels[i] = newLabel(); - return labels; - } - - protected static class OffsetToPatch { - public final int pc; - public final int size; - public final int instrPC; - public final Label label; - - public OffsetToPatch(int pc, int size, int instrPC, Label label) { - this.pc = pc; - this.size = size; - this.instrPC = instrPC; - this.label = label; - } - } - - protected void recordOffsetToPatch(int offsetPC, - int size, - int instrPC, - Label label) { - offsetToPatch.add(new OffsetToPatch(offsetPC, size, instrPC, label)); - } - - protected void patchAllOffset() throws OffsetTooBigException { - Iterator offsetIt = offsetToPatch.iterator(); - while (offsetIt.hasNext()) { - OffsetToPatch offset = (OffsetToPatch)offsetIt.next(); - int offsetValue = offset.label.getAnchor() - offset.instrPC; - if (offset.size == 16) { - checkOffset16(offsetValue); - codeArray.putU2(offset.pc, offsetValue); - } else - codeArray.putU4(offset.pc, offsetValue); - } - } - - // Exception handling - ////////////////////////////////////////////////////////////////////// - - public class ExceptionHandler { - protected int startPC, endPC, handlerPC; - protected final String catchType; - protected final int catchTypeIndex; - - public void setStartPC(int pc) { - this.startPC = pc; - } - - public int getStartPC() { - return this.startPC; - } - - public void setEndPC(int pc) { - this.endPC = pc; - } - - public int getEndPC() { - return this.endPC; - } - - public void setHandlerPC(int pc) { - this.handlerPC = pc; - } - - public int getHandlerPC() { - return this.handlerPC; - } - - public ExceptionHandler(String catchType) { - this(0, 0, 0, catchType); - } - - public ExceptionHandler(int startPC, - int endPC, - int handlerPC, - String catchType) { - this.startPC = startPC; - this.endPC = endPC; - this.handlerPC = handlerPC; - this.catchType = catchType; - this.catchTypeIndex = (catchType == null - ? 0 - : pool.addClass(catchType)); - } - - public ExceptionHandler(DataInputStream stream) throws IOException { - this.startPC = stream.readShort(); - this.endPC = stream.readShort(); - this.handlerPC = stream.readShort(); - this.catchTypeIndex = stream.readShort(); - this.catchType = (catchTypeIndex == 0 - ? null - : pool.lookupClass(catchTypeIndex)); - } - - public void writeTo(DataOutputStream stream) throws IOException { - stream.writeShort(startPC); - stream.writeShort(endPC); - stream.writeShort(handlerPC); - stream.writeShort(catchTypeIndex); - } - - // Follows javap output format for exception handlers. - /*@Override*/public String toString() { - StringBuffer buf = new StringBuffer(" "); - if (startPC < 10) buf.append(" "); - buf.append(startPC); - buf.append(" "); - if (endPC < 10) buf.append(" "); - buf.append(endPC); - buf.append(" "); - buf.append(handlerPC); - buf.append(" "); - if (catchType != null) { - buf.append("Class "); - buf.append(catchType); - } - else - buf.append("any"); - return buf.toString(); - } - - } - - public void addExceptionHandler(ExceptionHandler handler) { - assert !frozen; - exceptionHandlers.add(handler); - } - - public void addExceptionHandler(int startPC, - int endPC, - int handlerPC, - String catchType) { - addExceptionHandler(new ExceptionHandler(startPC, - endPC, - handlerPC, - catchType)); - } - - public void addFinallyHandler(int startPC, int endPC, int handlerPC) { - assert !frozen; - addExceptionHandler(startPC, endPC, handlerPC, null); - } - - public List/*<ExceptionHandler>*/ getExceptionHandlers() { - return exceptionHandlers; - } - - // Line numbers - ////////////////////////////////////////////////////////////////////// - - protected int[] lineNumbers = null; - protected void ensureLineNumberCapacity(int endPC) { - assert !frozen; - if (lineNumbers == null) { - lineNumbers = new int[endPC]; - addAttribute(context.JLineNumberTableAttribute(owner.getOwner(), - this)); - } else if (lineNumbers.length < endPC) { - int[] newLN = new int[Math.max(endPC, lineNumbers.length * 2)]; - System.arraycopy(lineNumbers, 0, newLN, 0, lineNumbers.length); - lineNumbers = newLN; - } - } - - /** - * Set all line numbers in the interval [startPC, endPC) to - * line, overwriting existing line numbers. - */ - public void setLineNumber(int startPC, int endPC, int line) { - ensureLineNumberCapacity(endPC); - Arrays.fill(lineNumbers, startPC, endPC, line); - } - - public void setLineNumber(int instrPC, int line) { - setLineNumber(instrPC, instrPC + 1, line); - } - - /** Sets all non-filled line numbers in the interval [startPC, endPC) - * to 'line'. - */ - public void completeLineNumber(int startPC, int endPC, int line) { - ensureLineNumberCapacity(endPC); - for (int pc = startPC; pc < endPC; ++pc) - if (lineNumbers[pc] == 0) lineNumbers[pc] = line; - } - - public int[] getLineNumbers() { - assert frozen; - if (lineNumbers == null) return new int[0]; - else if (lineNumbers.length == getPC()) return lineNumbers; - else { - int[] trimmedLN = new int[getPC()]; - System.arraycopy(lineNumbers, 0, - trimmedLN, 0, - Math.min(lineNumbers.length, trimmedLN.length)); - return trimmedLN; - } - } - - // Output - ////////////////////////////////////////////////////////////////////// - - public void writeTo(DataOutputStream stream) throws IOException { - assert frozen; - stream.writeInt(getSize()); - codeArray.writeTo(stream); - } - - // Follows javap output format for opcodes. - /*@Override*/ public String toString() { - StringBuffer buf = new StringBuffer(); - JOpcode opcode = null; - int pc = 0, addr = 0; - while (pc < codeArray.getSize()) { - buf.append("\n "); - buf.append(pc); - buf.append(":\t"); - opcode = JOpcode.OPCODES[codeArray.getU1(pc)]; - buf.append(decode(opcode, pc)); - if (opcode.code == JOpcode.cTABLESWITCH || - opcode.code == JOpcode.cLOOKUPSWITCH) { - addr = ((pc / 4 + 1) + 1) * 4; // U4 aligned data - int low = codeArray.getU4(addr); - int high = codeArray.getU4(addr+4); - pc = addr + (2/*low+high*/ + (high - low + 1)/*targets*/) * 4; - } else - pc += opcode.getSize(); - } - if (exceptionHandlers.size() > 0) { - buf.append("\n Exception table:\n from to target type\n"); - Iterator it = exceptionHandlers.iterator(); - while (it.hasNext()) { - ExceptionHandler exh = (ExceptionHandler)it.next(); - buf.append(exh); - buf.append("\n"); - } - } - return buf.toString(); - } - - private String decode(JOpcode opcode, int pc) { - String ownerClassName = owner.getOwner().getName(); - int data, data2; - StringBuilder buf = new StringBuilder(); - buf.append(opcode.name.toLowerCase()); - switch (opcode.code) { - case JOpcode.cALOAD: case JOpcode.cASTORE: case JOpcode.cBIPUSH: - case JOpcode.cDLOAD: case JOpcode.cDSTORE: - case JOpcode.cFLOAD: case JOpcode.cFSTORE: - case JOpcode.cILOAD: case JOpcode.cISTORE: - case JOpcode.cLLOAD: case JOpcode.cLSTORE: - data = codeArray.getU1(pc+1); - buf.append("\t"); - buf.append(data); - break; - case JOpcode.cLDC: - data = codeArray.getU1(pc+1); - buf.append("\t#"); - buf.append(data); - buf.append("; "); - buf.append(pool.lookupEntry(data).toComment(ownerClassName)); - break; - case JOpcode.cNEWARRAY: - data = codeArray.getU1(pc+1); - buf.append(" "); - buf.append(JType.tagToString(data)); - break; - case JOpcode.cIINC: - data = codeArray.getU1(pc+1); - data2 = codeArray.getU1(pc+2); - buf.append("\t"); - buf.append(data); - buf.append(", "); - buf.append(data2); - break; - case JOpcode.cSIPUSH: - data = codeArray.getU2(pc+1); - buf.append("\t"); - buf.append(data); - break; - case JOpcode.cANEWARRAY: case JOpcode.cCHECKCAST: - case JOpcode.cGETFIELD: case JOpcode.cGETSTATIC: - case JOpcode.cINSTANCEOF: - case JOpcode.cINVOKESPECIAL: case JOpcode.cINVOKESTATIC: - case JOpcode.cINVOKEVIRTUAL: - case JOpcode.cLDC_W: case JOpcode.cLDC2_W: case JOpcode.cNEW: - case JOpcode.cPUTFIELD: case JOpcode.cPUTSTATIC: - data = codeArray.getU2(pc+1); - buf.append("\t#"); - buf.append(data); - buf.append("; "); - buf.append(pool.lookupEntry(data).toComment(ownerClassName)); - break; - case JOpcode.cIF_ACMPEQ: case JOpcode.cIF_ACMPNE: - case JOpcode.cIFEQ: case JOpcode.cIFGE: case JOpcode.cIFGT: - case JOpcode.cIFLE: case JOpcode.cIFLT: case JOpcode.cIFNE: - case JOpcode.cIFNONNULL: case JOpcode.cIFNULL: - case JOpcode.cIF_ICMPEQ: case JOpcode.cIF_ICMPGE: - case JOpcode.cIF_ICMPGT: case JOpcode.cIF_ICMPLE: - case JOpcode.cIF_ICMPLT: case JOpcode.cIF_ICMPNE: - data = codeArray.getU2(pc+1); // maybe S2 offset - buf.append("\t"); - buf.append(pc+data); - break; - case JOpcode.cGOTO: - data = codeArray.getS2(pc+1); // always S2 offset - buf.append("\t"); - buf.append(pc+data); - break; - case JOpcode.cINVOKEINTERFACE: - data = codeArray.getU2(pc+1); - data2 = codeArray.getU1(pc+3); - buf.append("\t#"); - buf.append(data); - buf.append(", "); - buf.append(data2); - buf.append("; "); - buf.append(pool.lookupEntry(data).toComment(ownerClassName)); - break; - case JOpcode.cTABLESWITCH: - buf.append("{ //"); - int addr = ((pc / 4 + 1) + 1) * 4; // U4 aligned data - int low = codeArray.getU4(addr); - int high = codeArray.getU4(addr+4); - buf.append(low); - buf.append(" to "); - buf.append(high); - for (int i = low; i <= high; ++i) { - buf.append("\n\t\t"); - buf.append(i); - buf.append(": "); - buf.append(pc+codeArray.getU4(addr+(i-1)*4)); - buf.append(";"); - } - buf.append("\n\t\tdefault: "); - buf.append(pc+codeArray.getU4(addr-4)); - buf.append(" }"); - default: - } - return buf.toString(); - } -} diff --git a/src/fjbg/ch/epfl/lamp/fjbg/JCodeAttribute.java b/src/fjbg/ch/epfl/lamp/fjbg/JCodeAttribute.java deleted file mode 100644 index 9f3fcf8c6a..0000000000 --- a/src/fjbg/ch/epfl/lamp/fjbg/JCodeAttribute.java +++ /dev/null @@ -1,125 +0,0 @@ -/* FJBG -- Fast Java Bytecode Generator - * Copyright 2002-2013 LAMP/EPFL - * @author Michel Schinz - */ - -package ch.epfl.lamp.fjbg; - -import java.io.DataInputStream; -import java.io.DataOutputStream; -import java.io.IOException; -import java.util.Iterator; -import java.util.List; - -/** - * Code attribute, containing code of methods. - * - * A Code attribute contains the JVM instructions and auxiliary information - * for a single method, instance initialization method, or class or interface - * initialization method. See section 4.8.3 of the JVM specification. - * - * @author Michel Schinz, Stephane Micheloud - * @version 1.1 - */ - -public class JCodeAttribute extends JAttribute { - protected final JCode code; - protected final JMethod owner; - protected static int UNKNOWN_STACK_SIZE = Integer.MIN_VALUE; - protected final int maxStackSize; - protected final int maxLocals; - - public JCodeAttribute(FJBGContext context, JClass clazz, JMethod owner) { - super(context, clazz); - this.owner = owner; - - this.maxStackSize = UNKNOWN_STACK_SIZE; - this.maxLocals = 0; // unknown - this.code = owner.getCode(); - - assert clazz == owner.getOwner(); - } - - public JCodeAttribute(FJBGContext context, - JClass clazz, - Object owner, - String name, - int size, - DataInputStream stream) - throws IOException { - super(context, clazz, name); - this.owner = (JMethod)owner; - - this.maxStackSize = stream.readShort(); - this.maxLocals = stream.readShort(); - this.code = context.JCode(clazz, (JMethod)owner, stream); - - int handlersCount = stream.readShort(); - for (int i = 0; i < handlersCount; ++i) - code.addExceptionHandler(code.new ExceptionHandler(stream)); - List/*<JAttribute>*/ attributes = - JAttribute.readFrom(context, clazz, code, stream); - Iterator attrIt = attributes.iterator(); - while (attrIt.hasNext()) - code.addAttribute((JAttribute)attrIt.next()); - - assert name.equals(getName()); - } - - public String getName() { return "Code"; } - - // Follows javap output format for Code attribute. - /*@Override*/ public String toString() { - StringBuffer buf = new StringBuffer(" Code:"); - buf.append("\n Stack="); - buf.append(maxStackSize); - buf.append(", Locals="); - buf.append(maxLocals); - buf.append(", Args_size="); - buf.append(owner.getArgsSize()); - buf.append(code); - buf.append("\n"); - Iterator it = code.getAttributes().iterator(); - while (it.hasNext()) { - JAttribute attr = (JAttribute)it.next(); - buf.append(attr); - buf.append("\n"); - } - return buf.toString(); - } - - protected int getSize() { - int handlersNum = code.getExceptionHandlers().size(); - - int attrsSize = 0; - Iterator attrsIt = code.getAttributes().iterator(); - while (attrsIt.hasNext()) { - JAttribute attr = (JAttribute)attrsIt.next(); - attrsSize += attr.getSize() + 6; - } - - return 2 // max stack - + 2 // max locals - + 4 // code size - + code.getSize() // code - + 2 // exception table size - + 8 * handlersNum // exception table - + 2 // attributes count - + attrsSize; // attributes - } - - protected void writeContentsTo(DataOutputStream stream) throws IOException { - List/*<ExceptionHandler>*/ handlers = code.getExceptionHandlers(); - - stream.writeShort(code.getMaxStackSize()); - stream.writeShort(owner.getMaxLocals()); - - code.writeTo(stream); - - stream.writeShort(handlers.size()); - Iterator handlerIt = handlers.iterator(); - while (handlerIt.hasNext()) - ((JCode.ExceptionHandler)handlerIt.next()).writeTo(stream); - JAttribute.writeTo(code.getAttributes(), stream); - } -} diff --git a/src/fjbg/ch/epfl/lamp/fjbg/JCodeIterator.java b/src/fjbg/ch/epfl/lamp/fjbg/JCodeIterator.java deleted file mode 100644 index d09dfd19a4..0000000000 --- a/src/fjbg/ch/epfl/lamp/fjbg/JCodeIterator.java +++ /dev/null @@ -1,377 +0,0 @@ -/* FJBG -- Fast Java Bytecode Generator - * Copyright 2002-2013 LAMP/EPFL - * @author Michel Schinz - */ - -package ch.epfl.lamp.fjbg; - -import ch.epfl.lamp.util.ByteArray; - -/** - * Iterator used to examine the contents of an instruction list. - * - * @author Michel Schinz, Thomas Friedli - * @version 1.0 - */ - -public class JCodeIterator { - protected final JCode code; - protected final JConstantPool pool; - protected final ByteArray codeArray; - - protected int pc; - protected JOpcode opcode; - - /** - * Creates a new code iterator with its instruction list - * and its pc initialized to a given value. - */ - public JCodeIterator(JCode code, int pc) { - this.code = code; - this.pool = code.getOwner().getOwner().getConstantPool(); - this.codeArray = code.codeArray; - this.pc = pc; - setOpcode(); - } - - public JCodeIterator(JCode code) { - this(code, 0); - } - - /** - * Get the current program counter. - * @return The current program counter. - */ - public int getPC() { return pc; } - - /** - * Searches the type of the instruction positionned at the - * current address and updates the current instruction. - */ - protected void setOpcode() { - // TODO : check if the current pc is the beginning - // of an instruction - opcode = isValid() ? JOpcode.OPCODES[codeArray.getU1(pc)] : null; - } - - /** - * Returns the opcode of the current instruction. - * @return The opcode of the current instruction. - */ - public JOpcode getOpcode() { - return opcode; - } - - /** - * Updates the program counter to an given value. - * @param pc The new value of the program counter. - */ - public void moveTo(int pc) { - this.pc = pc; - setOpcode(); - } - - /** - * Check the validity of the iterator. - * @return true iff the iterator points to a valid address. - */ - public boolean isValid() { - return pc < codeArray.getSize(); - } - - /** - * Updates the current instruction with the next one in the - * sense of their position in the code. - */ - public void moveToNext() { - moveTo(pc + getInstructionSize()); - } - - /** - * Updates the current instruction with a specific successor - * of it. - * @param succ The index of the wanted successor in the list of - * the successors of the current instruction. - */ - public void moveToSuccessor(int succ) { - moveTo(getSuccessorPC(succ)); - } - - /** - * Updates the current instruction with the one positionned - * at a given index relatively to the actual program counter - * @param offset The relative position of the instruction - * compared with the position of the current one - */ - public void moveRelatively(int offset) { - moveTo(pc + offset); - } - - /** - * Returns the size in bytes of the current instruction. - * @return The size in bytes of the current instruction. - */ - public int getInstructionSize() { - if (opcode.size != JOpcode.UNKNOWN) { - return opcode.size; - } else if (opcode == JOpcode.TABLESWITCH) { - int lowOffset = 1 + pad4(pc + 1) + 4; - int low = codeArray.getS4(pc + lowOffset); - int high = codeArray.getS4(pc + lowOffset + 4); - return lowOffset + 8 + 4 * (high - low + 1); - } else if (opcode == JOpcode.LOOKUPSWITCH) { - int npairsOffset = 1 + pad4(pc + 1) + 4; - int npairs = codeArray.getS4(pc + npairsOffset); - return npairsOffset + 4 + 8 * npairs; - } else if (opcode == JOpcode.WIDE) { - if (codeArray.getU1(pc + 1) == JOpcode.cIINC) - return 6; - else - return 4; - } else - throw new Error("Unknown size for instruction " + opcode); - } - - /** - * Returns the number of successors of the current instruction. - * @return The number of successors of the current instruction. - */ - public int getSuccessorCount() { - if (opcode.successorCount != JOpcode.UNKNOWN) { - return opcode.successorCount; - } else if (opcode == JOpcode.TABLESWITCH) { - int lowPos = pc + 1 + pad4(pc + 1) + 4; - return 1 // default case - + codeArray.getS4(lowPos + 4) // value of HIGH field - - codeArray.getS4(lowPos) + 1; // value of LOW field - } else if (opcode == JOpcode.LOOKUPSWITCH) { - int npairsPos = pc + 1 + pad4(pc + 1) + 4; - return 1 + codeArray.getS4(npairsPos); - } else - throw new Error("Unknown successors for instruction " + opcode); - } - - /** - * Returns the address of the successor of the current instruction - * given its index in the list of successors of the current - * instruction. - * @param index The index of the wanted successor in the list of - * the successors of the current instruction. - * @return The address of the specific successor. - */ - public int getSuccessorPC(int index) { - assert (index >= 0) && (index < getSuccessorCount()) : index; - - switch (opcode.jumpKind) { - case JOpcode.JMP_NEXT: - return pc + getInstructionSize(); - case JOpcode.JMP_ALWAYS_S2_OFFSET: - return pc + codeArray.getS2(pc + 1); - case JOpcode.JMP_ALWAYS_S4_OFFSET: - return pc + codeArray.getS4(pc + 1); - case JOpcode.JMP_MAYBE_S2_OFFSET: - if (index == 0) - return pc + getInstructionSize(); - else - return pc + codeArray.getS2(pc + 1); - case JOpcode.JMP_TABLE: { - int defaultPos = pc + 1 + pad4(pc + 1); - if (index == 0) - return pc + codeArray.getS4(defaultPos); - else - return pc + codeArray.getS4(defaultPos + 3*4 + 4 * (index - 1)); - } - case JOpcode.JMP_LOOKUP: { - int defaultPos = pc + 1 + pad4(pc + 1); - if (index == 0) - return pc + codeArray.getS4(defaultPos); - else - return pc + codeArray.getS4(defaultPos + 2*4 + 4 + 8 * (index - 1)); - } - default: - throw new Error(); - } - } - - /** - * Returns the total size of data words put on the stack by the current - * instruction. - * @return The total size of data words put on the stack by the current - * instruction. - */ - public int getProducedDataSize() { - if (opcode.getProducedDataTypes() == JOpcode.UNKNOWN_TYPE) { - switch (opcode.code) { - case JOpcode.cLDC: case JOpcode.cLDC_W: case JOpcode.cBALOAD: - return 1; - case JOpcode.cLDC2_W: case JOpcode.cDUP: case JOpcode.cSWAP: - return 2; - case JOpcode.cDUP_X1: - return 3; - case JOpcode.cDUP_X2: case JOpcode.cDUP2: - return 4; - case JOpcode.cDUP2_X1: - return 5; - case JOpcode.cDUP2_X2: - return 6; - case JOpcode.cGETSTATIC: case JOpcode.cGETFIELD: { - JConstantPool.FieldOrMethodRefEntry entry = - (JConstantPool.FieldOrMethodRefEntry) - pool.lookupEntry(codeArray.getU2(pc + 1)); - return JType.parseSignature(entry.getSignature()).getSize(); - } - case JOpcode.cWIDE : { - int op = codeArray.getU1(pc + 1); - if (op >= JOpcode.cILOAD && op <= JOpcode.cALOAD) { - JOpcode opcode2 = JOpcode.OPCODES[op]; - return JType.getTotalSize(opcode2.getProducedDataTypes()); - } else if (op >= JOpcode.cISTORE && op <= JOpcode.cASTORE) - return 0; - else return 0; // (IINC) - } - default : - throw new Error(opcode.toString()); - } - } else - return JType.getTotalSize(opcode.getProducedDataTypes()); - } - - /** - * Returns the total size of data words taken from the stack by the current - * instruction. - * @return The total size of data words taken from the stack by the current - * instruction. - */ - public int getConsumedDataSize() { - if (opcode.getConsumedDataTypes() != JOpcode.UNKNOWN_TYPE) - return JType.getTotalSize(opcode.getConsumedDataTypes()); - else { - switch (opcode.code) { - case JOpcode.cPOP: case JOpcode.cDUP: - return 1; - case JOpcode.cPOP2: case JOpcode.cSWAP: - case JOpcode.cDUP_X1: case JOpcode.cDUP2: - return 2; - case JOpcode.cDUP_X2: case JOpcode.cDUP2_X1: - return 3; - case JOpcode.cDUP2_X2: - return 4; - case JOpcode.cPUTSTATIC: case JOpcode.cPUTFIELD: { - JConstantPool.FieldOrMethodRefEntry entry = - (JConstantPool.FieldOrMethodRefEntry) - pool.lookupEntry(codeArray.getU2(pc + 1)); - return JType.parseSignature(entry.getSignature()).getSize(); - } - case JOpcode.cINVOKEVIRTUAL: case JOpcode.cINVOKESPECIAL: - case JOpcode.cINVOKESTATIC: case JOpcode.cINVOKEINTERFACE : { - JConstantPool.FieldOrMethodRefEntry entry = - (JConstantPool.FieldOrMethodRefEntry) - pool.lookupEntry(codeArray.getU2(pc + 1)); - JMethodType tp = (JMethodType) - JType.parseSignature(entry.getSignature()); - return tp.getArgsSize() - + (opcode == JOpcode.INVOKESTATIC ? 0 : 1); - } - case JOpcode.cWIDE : { - int op = codeArray.getU1(pc + 1); - if (op >= JOpcode.cILOAD && op <= JOpcode.cALOAD) - return 0; - else if (op >= JOpcode.cISTORE && op <= JOpcode.cASTORE) { - JOpcode opcode2 = JOpcode.OPCODES[op]; - return JType.getTotalSize(opcode2.getConsumedDataTypes()); - } else - return 0; // (IINC) - } - case JOpcode.cMULTIANEWARRAY : - return codeArray.getU1(pc + 3); - default: - throw new Error(opcode.toString()); - } - } - } - - /** - * Returns the number of data types put on the stack by the current - * instruction. - * @return The number of data types put on the stack by the current - * instruction. - */ - public int getProducedDataTypesNumber() { - if (opcode.getProducedDataTypes() != JOpcode.UNKNOWN_TYPE) - return opcode.getProducedDataTypes().length; - else { - switch (opcode.code) { - case JOpcode.cLDC: case JOpcode.cLDC_W: case JOpcode.cLDC2_W: - case JOpcode.cBALOAD: case JOpcode.cGETSTATIC: - case JOpcode.cGETFIELD: - return 1; - case JOpcode.cDUP: case JOpcode.cSWAP: - return 2; - case JOpcode.cDUP_X1: - return 3; - case JOpcode.cWIDE: { - int op = codeArray.getU1(pc + 1); - if (op >= JOpcode.cILOAD && op <= JOpcode.cALOAD) - return 1; - else if (op >= JOpcode.cISTORE && op <= JOpcode.cASTORE) - return 0; - else - return 0; // (IINC) - } - default: - throw new Error("JOpcode implementation error"); - } - } - } - - /** - * Returns the number of data types taken from the stack by the current - * instruction. - * @return The number of data types taken from the stack by the current - * instruction. - */ -// public int getConsumedDataTypesNumber() { -// if (opcode.getConsumedDataTypes() == JOpcode.UNKNOWN_TYPE) { -// switch (opcode.code) { -// case 87 : return 1; // POP -// case 88 : return 2; // POP2 -// case 89 : return 1; // DUP -// case 90 : return 2; // DUP_X1 -// case 91 : // DUP_X2 -// case 92 : // DUP2 -// case 93 : // DUP2_X1 -// case 94 : // DUP2_X2 -// throw new UnsupportedOperationException("Opcode " + opcode.name -// + " has a stack-dependant" -// + " data types consumption"); -// case 95 : return 2; // SWAP -// case 179 : return 1; // PUTSTATIC -// case 181 : return 1; // PUTFIELD -// case 182 : // INVOKEVIRTUAL -// case 183 : // INVOKESPECIAL -// case 185 : // INVOKEINTERFACE -// s = epool.getClassMethodRef(codeArray.getU2(pc + 1)).split(" ")[3]; -// return ((JMethodType)JType.parseSignature(s)).argTypes.length + 1; -// case 184 : // INVOKESTATIC -// s = epool.getClassMethodRef(codeArray.getU2(pc + 1)).split(" ")[3]; -// return ((JMethodType)JType.parseSignature(s)).argTypes.length; -// case 196 : // WIDE -// int op = codeArray.getU1(pc + 1); -// if (op >= 21 && op <= 25) return 0; // (xLOAD) -// else if (op >= 54 && op <= 58) // (xSTORE) -// return JOpcode.OPCODES[op].getConsumedDataTypes().length; -// else return 0; // (IINC) -// case 197 : return codeArray.getU1(pc + 3); // MULTIANEWARRAY -// default : throw new Error("JOpcode implementation error"); -// } -// } else return opcode.getConsumedDataTypes().length; -// } - - - // Return the number between 0 and 3 which, if added to the given - // value, would yield a multiple of 4. - protected int[] padding = { 0, 3, 2, 1 }; - protected int pad4(int value) { - return padding[value % 4]; - } -} diff --git a/src/fjbg/ch/epfl/lamp/fjbg/JConstantPool.java b/src/fjbg/ch/epfl/lamp/fjbg/JConstantPool.java deleted file mode 100644 index 9867e01b25..0000000000 --- a/src/fjbg/ch/epfl/lamp/fjbg/JConstantPool.java +++ /dev/null @@ -1,771 +0,0 @@ -/* FJBG -- Fast Java Bytecode Generator - * Copyright 2002-2013 LAMP/EPFL - * @author Michel Schinz - */ - -package ch.epfl.lamp.fjbg; - -import java.io.DataInputStream; -import java.io.DataOutputStream; -import java.io.IOException; -import java.util.HashMap; - -/** - * Constant pool, holding constants for a Java class file. - * - * @author Michel Schinz - * @version 2.0 - */ - -public class JConstantPool { - protected boolean frozen = false; - - protected HashMap/*<Entry,Integer>*/ entryToIndex = new HashMap(); - protected Entry[] indexToEntry; - protected int currIndex; - - public static final short CONSTANT_Utf8 = 1; - public static final short CONSTANT_Integer = 3; - public static final short CONSTANT_Float = 4; - public static final short CONSTANT_Long = 5; - public static final short CONSTANT_Double = 6; - public static final short CONSTANT_Class = 7; - public static final short CONSTANT_String = 8; - public static final short CONSTANT_Fieldref = 9; - public static final short CONSTANT_Methodref = 10; - public static final short CONSTANT_InterfaceMethodref = 11; - public static final short CONSTANT_NameAndType = 12; - - protected JConstantPool(FJBGContext context) { - indexToEntry = new Entry[8]; - currIndex = 1; - } - - protected JConstantPool(FJBGContext context, DataInputStream stream) - throws IOException { - int count = stream.readShort(); - indexToEntry = new EntryIndex[count]; - - currIndex = 1; - while (currIndex < count) { - EntryIndex e; - int tag = stream.readByte(); - - switch (tag) { - case CONSTANT_Utf8: - e = new Utf8Entry(stream); - // no duplicates - entryToIndex.put(e, new Integer(currIndex)); - break; - case CONSTANT_Integer: - e = new IntegerEntry(stream); - break; - case CONSTANT_Float: - e = new FloatEntry(stream); - break; - case CONSTANT_Long: - e = new LongEntry(stream); - break; - case CONSTANT_Double: - e = new DoubleEntry(stream); - break; - case CONSTANT_Class: - e = new DescriptorEntryIndex(stream); - break; - case CONSTANT_String: - e = new StringEntryIndex(stream); - break; - case CONSTANT_Fieldref: - case CONSTANT_Methodref: - case CONSTANT_InterfaceMethodref: - e = new FieldOrMethodRefEntryIndex(tag, stream); - break; - case CONSTANT_NameAndType: - e = new NameAndTypeEntryIndex(stream); - break; - default: - throw new IllegalArgumentException("unknown entry in pool: " + tag); - } - indexToEntry[currIndex] = e; - currIndex += e.getSize(); - } - } - - public void freeze() { frozen = true; } - - /** - * Returns a string representing the type of an entry - * knowing its tag - * @param tag The tag representing the type of the - * constant pool entry - */ - public String getEntryType(int tag) { - switch (tag) { - case CONSTANT_Utf8 : return "Utf8"; - case CONSTANT_Integer : return "Integer"; - case CONSTANT_Float : return "Float"; - case CONSTANT_Long : return "Long"; - case CONSTANT_Double : return "Double"; - case CONSTANT_Class : return "Class"; - case CONSTANT_String : return "String"; - case CONSTANT_Fieldref : return "Field"; - case CONSTANT_Methodref : return "Method"; - case CONSTANT_InterfaceMethodref : return "InterfaceMethod"; - case CONSTANT_NameAndType : return "NameAndType"; - default : throw new Error("invalid constant pool tag : " + tag); - } - } - - public int addClass(String className) { - return addDescriptor(className.replace('.', '/')); - } - - public int addDescriptor(JReferenceType type) { - return addDescriptor(type.getDescriptor()); - } - - protected int addDescriptor(String name) { - return addEntry(new DescriptorEntryValue(name)); - } - - public int addClassMethodRef(String className, - String methodName, - String signature) { - return addMethodRef(true, className, methodName, signature); - } - - public int addInterfaceMethodRef(String className, - String methodName, - String signature) { - return addMethodRef(false, className, methodName, signature); - } - - public int addMethodRef(boolean isClass, - String className, - String methodName, - String signature) { - return addEntry(new FieldOrMethodRefEntryValue(isClass - ? CONSTANT_Methodref - : CONSTANT_InterfaceMethodref, - className, - methodName, - signature)); - } - - public int addFieldRef(String className, - String fieldName, - String signature) { - return addEntry(new FieldOrMethodRefEntryValue(CONSTANT_Fieldref, - className, - fieldName, - signature)); - } - - public int addInteger(int value) { - return addEntry(new IntegerEntry(value)); - } - - public int addFloat(float value) { - return addEntry(new FloatEntry(value)); - } - - public int addLong(long value) { - return addEntry(new LongEntry(value)); - } - - public int addDouble(double value) { - return addEntry(new DoubleEntry(value)); - } - - public int addString(String value) { - return addEntry(new StringEntryValue(value)); - } - - public int addNameAndType(String name, String descriptor) { - return addEntry(new NameAndTypeEntryValue(name, descriptor)); - } - - public int addUtf8(String value) { - return addEntry(new Utf8Entry(value)); - } - - public int addUtf8(byte[] value) { - return addEntry(new Utf8Entry(value)); - } - - protected int addEntry(EntryValue e) { - assert !frozen; - Integer idx = (Integer)entryToIndex.get(e); - if (idx != null) - return idx.intValue(); - - e.addChildren(); - - int index = currIndex; - currIndex += e.getSize(); - - entryToIndex.put(e, new Integer(index)); - if (index >= indexToEntry.length) { - Entry[] newI2E = new Entry[indexToEntry.length * 2]; - System.arraycopy(indexToEntry, 0, newI2E, 0, indexToEntry.length); - indexToEntry = newI2E; - } - indexToEntry[index] = e; - return index; - } - - /// Lookup methods - ////////////////////////////////////////////////////////////////////// - - public Entry lookupEntry(int index) { - assert index > 0 && index < currIndex - : "invalid index: " + index; - assert indexToEntry[index] != null - : "invalid index (null contents): " + index; - return indexToEntry[index]; - } - - public String lookupClass(int index) { - DescriptorEntry entry = (DescriptorEntry)lookupEntry(index); - return entry.getValue(); - } - - public String lookupNameAndType(int index) { - NameAndTypeEntry entry = (NameAndTypeEntry)lookupEntry(index); - return entry.getName()+":"+entry.getDescriptor(); - } - - public String lookupUtf8(int index) { - Utf8Entry entry = (Utf8Entry)lookupEntry(index); - return entry.getValue(); - } - - /// Output - ////////////////////////////////////////////////////////////////////// - - public void writeTo(DataOutputStream stream) throws IOException { - if (! frozen) freeze(); - - stream.writeShort(currIndex); - for (int i = 0; i < currIndex; ++i) { - Entry entry = indexToEntry[i]; - if (entry != null) { - stream.writeByte(entry.getTag()); - entry.writeContentsTo(stream); - } - } - } - - // Follows javap output format for constant pool. - /*@Override*/ public String toString() { - StringBuffer buf = new StringBuffer(" Constant pool:"); - for (int i = 0; i < currIndex; ++i) { - Entry entry = indexToEntry[i]; - if (entry != null) { - if (i > 0) buf.append("\n"); - buf.append("const #"); - buf.append(i); - buf.append(" = "); - buf.append(entry); - } - } - buf.append("\n"); - return buf.toString(); - } - - /// Classes for the various kinds of entries - ////////////////////////////////////////////////////////////////////// - - public interface Entry { - public int getTag(); - - int getSize(); - void writeContentsTo(DataOutputStream stream) throws IOException; - String toComment(String ownerClassName); - } - - protected interface EntryValue extends Entry { - abstract void addChildren(); - } - - protected interface EntryIndex extends Entry { - abstract void fetchChildren(); - } - - abstract protected class ChildlessEntry implements EntryValue, EntryIndex { - public void addChildren() {} - public void fetchChildren() {} - } - - public class IntegerEntry extends ChildlessEntry implements Entry { - private final int value; - public IntegerEntry(int value) { this.value = value; } - public IntegerEntry(DataInputStream stream) throws IOException { - this(stream.readInt()); - } - - public int hashCode() { return value; } - public boolean equals(Object o) { - return o instanceof IntegerEntry && ((IntegerEntry)o).value == value; - } - - public int getTag() { return CONSTANT_Integer; } - public int getValue() { return value; } - - public int getSize() { return 1; } - public void writeContentsTo(DataOutputStream stream) throws IOException { - stream.writeInt(value); - } - /*@Override*/ public String toString() { - StringBuffer buf = new StringBuffer("int\t"); - buf.append(getValue()); - buf.append(";"); - return buf.toString(); - } - public String toComment(String ownerClassname) { - return "//int "+getValue(); - } - } - - public class FloatEntry extends ChildlessEntry implements Entry { - private final float value; - public FloatEntry(float value) { this.value = value; } - public FloatEntry(DataInputStream stream) throws IOException { - this(stream.readFloat()); - } - - public int hashCode() { return (int)value; } - public boolean equals(Object o) { - return o instanceof FloatEntry && ((FloatEntry)o).value == value; - } - - public int getTag() { return CONSTANT_Float; } - public float getValue() { return value; } - - public int getSize() { return 1; } - public void writeContentsTo(DataOutputStream stream) throws IOException { - stream.writeFloat(value); - } - /*@Override*/ public String toString() { - StringBuffer buf = new StringBuffer("float\t"); - buf.append(getValue()); - buf.append("f"); - return buf.toString(); - } - public String toComment(String ownerClassname) { - return "//float "+getValue()+"f"; - } - } - - public class LongEntry extends ChildlessEntry implements Entry { - private final long value; - public LongEntry(long value) { this.value = value; } - public LongEntry(DataInputStream stream) throws IOException { - this(stream.readLong()); - } - - public int hashCode() { return (int)value; } - public boolean equals(Object o) { - return o instanceof LongEntry && ((LongEntry)o).value == value; - } - - public int getTag() { return CONSTANT_Long; } - public long getValue() { return value; } - - public int getSize() { return 2; } - public void writeContentsTo(DataOutputStream stream) throws IOException { - stream.writeLong(value); - } - /*@Override*/ public String toString() { - StringBuffer buf = new StringBuffer("long\t"); - buf.append(getValue()); - buf.append("l;"); - return buf.toString(); - } - public String toComment(String ownerClassname) { - return "//long "+getValue()+"l"; - } - } - - public class DoubleEntry extends ChildlessEntry implements Entry { - private final double value; - public DoubleEntry(double value) { this.value = value; } - public DoubleEntry(DataInputStream stream) throws IOException { - this(stream.readDouble()); - } - - public int hashCode() { return (int)value; } - public boolean equals(Object o) { - return o instanceof DoubleEntry && ((DoubleEntry)o).value == value; - } - - public int getTag() { return CONSTANT_Double; } - public double getValue() { return value; } - - public int getSize() { return 2; } - public void writeContentsTo(DataOutputStream stream) throws IOException { - stream.writeDouble(value); - } - /*@Override*/ public String toString() { - StringBuffer buf = new StringBuffer("double\t"); - buf.append(getValue()); - return buf.toString(); - } - public String toComment(String ownerClassname) { - return "//double "+getValue(); - } - } - - public class Utf8Entry extends ChildlessEntry implements Entry { - private final String value; - private final byte[] bytes; - public Utf8Entry(String value) { - this.value = value.intern(); - this.bytes = null; - } - public Utf8Entry(DataInputStream stream) throws IOException { - this(stream.readUTF()); - } - public Utf8Entry(byte[] bytes) { - this.bytes = bytes; - this.value = null; - } - - public int hashCode() { - if (bytes != null) return bytes.hashCode(); - return value.hashCode(); - } - public boolean equals(Object o) { - boolean isEqual = o instanceof Utf8Entry; - if (bytes != null) { - isEqual = isEqual && ((Utf8Entry)o).bytes == bytes; - } - else { - isEqual = isEqual && ((Utf8Entry)o).value == value; - } - return isEqual; - } - - public int getTag() { return CONSTANT_Utf8; } - public String getValue() { return value; } - public byte[] getBytes() { return bytes; } - - public int getSize() { return 1; } - public void writeContentsTo(DataOutputStream stream) throws IOException { - if (bytes != null) { - if (bytes.length > 65535) { - throw new IOException("String literal of length " + bytes.length + " does not fit in Classfile"); - } - stream.writeShort(bytes.length); - stream.write(bytes); - } - else - stream.writeUTF(value); - } - // Follows javap output format for Utf8 pool entries. - public String toString() { return "Asciz\t"+escaped(getValue())+";"; } - public String toComment(String ownerClassname) { - return "//Asciz "+escaped(getValue()); - } - private String escaped(String s) { - return s.replace("\n", "\\n"); - } - } - - abstract public class StringEntry implements Entry { - protected String value; - protected int valueIndex; - - public int hashCode() { - assert value != null; - return value.hashCode(); - } - public boolean equals(Object o) { - return o instanceof StringEntry && ((StringEntry)o).value == value; - } - - public int getTag() { return CONSTANT_String; } - public String getValue() { return value; } - - public int getSize() { return 1; } - public void writeContentsTo(DataOutputStream stream) throws IOException { - stream.writeShort(valueIndex); - } - // Follows javap output format for String pool entries. - public String toString() { - return "String\t#"+valueIndex+";\t// "+escaped(getValue()); - } - public String toComment(String ownerClassname) { - return "//String "+escaped(getValue()); - } - private String escaped(String s) { - return s.replace("\n", "\\n"); - } - } - - public class StringEntryValue extends StringEntry implements EntryValue { - public StringEntryValue(String value) { - this.value = value.intern(); - } - public void addChildren() { - valueIndex = addUtf8(value); - } - } - - public class StringEntryIndex extends StringEntry implements EntryIndex { - public StringEntryIndex(int valueIndex) { - this.valueIndex = valueIndex; - } - public StringEntryIndex(DataInputStream stream) throws IOException { - this(stream.readShort()); - } - public String getValue() { - if (value == null) fetchChildren(); - return super.getValue(); - } - public void fetchChildren() { - value = lookupUtf8(valueIndex); - } - } - - abstract public class DescriptorEntry implements Entry { - protected String name; - protected int nameIndex; - - public int hashCode() { - assert name != null; - return name.hashCode(); - } - public boolean equals(Object o) { - return o instanceof DescriptorEntry && ((DescriptorEntry)o).name == name; - } - - public int getTag() { return CONSTANT_Class; } - public String getValue() { return name; } - - public int getSize() { return 1; } - public void writeContentsTo(DataOutputStream stream) throws IOException { - stream.writeShort(nameIndex); - } - // Follows javap output format for class pool entries. - public String toString() { - StringBuffer buf = new StringBuffer("class\t#"); - buf.append(nameIndex); - buf.append(";\t// "); - buf.append(getClassName()); - return buf.toString(); - } - public String toComment(String ownerClassname) { - return "//class "+getClassName(); - } - private String getClassName() { - StringBuffer buf = new StringBuffer(); - String value = getValue(); - if (value.startsWith("[")) buf.append("\""); - buf.append(value); - if (value.startsWith("[")) buf.append("\""); - return buf.toString(); - } - } - - protected class DescriptorEntryValue - extends DescriptorEntry - implements EntryValue { - public DescriptorEntryValue(String name) { this.name = name.intern(); } - public void addChildren() { - nameIndex = addUtf8(name); - } - } - - protected class DescriptorEntryIndex - extends DescriptorEntry - implements EntryIndex { - public DescriptorEntryIndex(int nameIndex) { this.nameIndex = nameIndex; } - public DescriptorEntryIndex(DataInputStream stream) throws IOException { - this(stream.readShort()); - } - public String getValue() { - if (name == null) fetchChildren(); - return super.getValue(); - } - public void fetchChildren() { - name = lookupUtf8(nameIndex); - } - } - - abstract public class FieldOrMethodRefEntry implements Entry { - private final int tag; - protected String className, thingName, signature; - protected int classIndex, nameAndTypeIndex; - - public FieldOrMethodRefEntry(int tag) { - assert tag == CONSTANT_Fieldref - || tag == CONSTANT_Methodref - || tag == CONSTANT_InterfaceMethodref; - - this.tag = tag; - } - - public int hashCode() { - return tag - + className.hashCode() - + thingName.hashCode() - + signature.hashCode(); - } - public boolean equals(Object o) { - return o instanceof FieldOrMethodRefEntry - && ((FieldOrMethodRefEntry)o).tag == tag - && ((FieldOrMethodRefEntry)o).className == className - && ((FieldOrMethodRefEntry)o).thingName == thingName - && ((FieldOrMethodRefEntry)o).signature == signature; - } - - public int getTag() { return tag; } - public String getClassName() { return className; } - public String getFieldOrMethodName() { return thingName; } - public String getSignature() { return signature; } - - public int getSize() { return 1; } - public void writeContentsTo(DataOutputStream stream) throws IOException { - stream.writeShort(classIndex); - stream.writeShort(nameAndTypeIndex); - } - // Follows javap output format for field/method pool entries. - public String toString() { - return getEntryType(tag)+"\t#"+classIndex+".#"+nameAndTypeIndex+ - ";\t// "+getName("")+":"+signature; - } - public String toComment(String ownerClassName) { - return "//"+getEntryType(tag)+" "+getName(ownerClassName)+":"+signature; - } - private String getName(String ownerClassName) { - String name = getFieldOrMethodName(); - if (JMethod.INSTANCE_CONSTRUCTOR_NAME.equals(name)) - name = "\""+name+"\""; - if (!getClassName().equals(ownerClassName)) - name = getClassName()+"."+name; - return name; - } - } - - protected class FieldOrMethodRefEntryValue - extends FieldOrMethodRefEntry - implements EntryValue { - public FieldOrMethodRefEntryValue(int tag, - String className, - String thingName, - String signature) { - super(tag); - this.className = className.intern(); - this.thingName = thingName.intern(); - this.signature = signature.intern(); - } - - public void addChildren() { - classIndex = addClass(className); - nameAndTypeIndex = addNameAndType(thingName, signature); - } - } - - protected class FieldOrMethodRefEntryIndex - extends FieldOrMethodRefEntry - implements EntryIndex { - public FieldOrMethodRefEntryIndex(int tag, - int classIndex, - int nameAndTypeIndex) { - super(tag); - this.classIndex = classIndex; - this.nameAndTypeIndex = nameAndTypeIndex; - } - public FieldOrMethodRefEntryIndex(int tag, DataInputStream stream) - throws IOException { - this(tag, stream.readShort(), stream.readShort()); - } - public String getClassName() { - if (className == null) fetchChildren(); - return super.getClassName(); - } - public String getFieldOrMethodName() { - if (thingName == null) fetchChildren(); - return super.getFieldOrMethodName(); - } - public String getSignature() { - if (signature == null) fetchChildren(); - return super.getSignature(); - } - public void fetchChildren() { - className = lookupClass(classIndex); - NameAndTypeEntry nat = (NameAndTypeEntry)lookupEntry(nameAndTypeIndex); - thingName = nat.getName(); - signature = nat.getDescriptor(); - } - } - - abstract public class NameAndTypeEntry implements Entry { - protected String name, descriptor; - protected int nameIndex, descriptorIndex; - - public int hashCode() { return name.hashCode() + descriptor.hashCode(); } - public boolean equals(Object o) { - return o instanceof NameAndTypeEntry - && ((NameAndTypeEntry)o).name == name - && ((NameAndTypeEntry)o).descriptor == descriptor; - } - - public int getTag() { return CONSTANT_NameAndType; } - public String getName() { return name; } - public String getDescriptor() { return descriptor; } - - public int getSize() { return 1; } - public void writeContentsTo(DataOutputStream stream) throws IOException { - stream.writeShort(nameIndex); - stream.writeShort(descriptorIndex); - } - // Follows javap output format for name/type pool entries. - public String toString() { - String natName = getName(); - if (JMethod.INSTANCE_CONSTRUCTOR_NAME.equals(natName)) - natName = "\""+natName+"\""; - return "NameAndType\t#"+nameIndex+":#"+descriptorIndex+ - ";// "+natName+":"+getDescriptor(); - } - public String toComment(String ownerClassname) { return ""; } - } - - protected class NameAndTypeEntryValue - extends NameAndTypeEntry - implements EntryValue { - public NameAndTypeEntryValue(String name, String descriptor) { - this.name = name.intern(); - this.descriptor = descriptor.intern(); - } - public void addChildren() { - nameIndex = addUtf8(name); - descriptorIndex = addUtf8(descriptor); - } - } - - protected class NameAndTypeEntryIndex - extends NameAndTypeEntry - implements EntryIndex { - public NameAndTypeEntryIndex(int nameIndex, int descriptorIndex) { - this.nameIndex = nameIndex; - this.descriptorIndex = descriptorIndex; - } - public NameAndTypeEntryIndex(DataInputStream stream) throws IOException { - this(stream.readShort(), stream.readShort()); - } - public String getName() { - if (name == null) fetchChildren(); - return super.getName(); - } - public String getDescriptor() { - if (descriptor == null) fetchChildren(); - return super.getDescriptor(); - } - public void fetchChildren() { - name = lookupUtf8(nameIndex); - descriptor = lookupUtf8(descriptorIndex); - } - } -} diff --git a/src/fjbg/ch/epfl/lamp/fjbg/JConstantValueAttribute.java b/src/fjbg/ch/epfl/lamp/fjbg/JConstantValueAttribute.java deleted file mode 100644 index 6ee05e43c7..0000000000 --- a/src/fjbg/ch/epfl/lamp/fjbg/JConstantValueAttribute.java +++ /dev/null @@ -1,69 +0,0 @@ -/* FJBG -- Fast Java Bytecode Generator - * Copyright 2002-2013 LAMP/EPFL - * @author Michel Schinz - */ - -package ch.epfl.lamp.fjbg; - -import java.io.DataInputStream; -import java.io.DataOutputStream; -import java.io.IOException; - -/** - * ConstantValue attribute representing the value of a constant field. - * - * There can be no more than one ConstantValue attribute in the attributes - * table of a given field_info structure.. See section 4.8.2 of the JVM - * specification. - * - * @author Stephane Micheloud - * @version 1.0 - */ - -public class JConstantValueAttribute extends JAttribute { - /** Constant pool of the current classfile. */ - private JConstantPool pool; - - protected int constantValueIndex; - - public JConstantValueAttribute(FJBGContext context, - JClass clazz, - JField field) { - super(context, clazz); - this.pool = clazz.pool; - - assert field.getOwner() == clazz; - } - - public JConstantValueAttribute(FJBGContext context, - JClass clazz, - Object owner, // JField - String name, - int size, - DataInputStream stream) - throws IOException { - super(context, clazz, name); - this.pool = clazz.pool; - - this.constantValueIndex = stream.readShort(); - - assert name.equals(getName()); - } - - public String getName() { return "ConstantValue"; } - - // Follows javap output format for ConstantValue attribute. - /*@Override*/ public String toString() { - StringBuffer buf = new StringBuffer(" Constant value: "); - buf.append(pool.lookupEntry(constantValueIndex)); - return buf.toString(); - } - - protected int getSize() { - return 2; // Short.SIZE - } - - protected void writeContentsTo(DataOutputStream stream) throws IOException { - stream.writeShort(constantValueIndex); - } -} diff --git a/src/fjbg/ch/epfl/lamp/fjbg/JEnclosingMethodAttribute.java b/src/fjbg/ch/epfl/lamp/fjbg/JEnclosingMethodAttribute.java deleted file mode 100644 index f663f00ae1..0000000000 --- a/src/fjbg/ch/epfl/lamp/fjbg/JEnclosingMethodAttribute.java +++ /dev/null @@ -1,83 +0,0 @@ -/* FJBG -- Fast Java Bytecode Generator - * Copyright 2002-2013 LAMP/EPFL - * @author Michel Schinz - */ - -package ch.epfl.lamp.fjbg; - -import java.io.DataInputStream; -import java.io.DataOutputStream; -import java.io.IOException; - -/** - * EclosingMethod attribute - - * A class must have an EnclosingMethod attribute if and only if it is a - * local class or an anonymous class. A class may have no more than one - * EnclosingMethod attribute. See section 4.8.6 of the JVM specification. - * - * @author Michel Schinz - * @version 1.0 - */ - -public class JEnclosingMethodAttribute extends JAttribute { - /** Constant pool of the current classfile. */ - private JConstantPool pool; - - protected final int classIdx; - protected final int nameAndTypeIdx; - - public JEnclosingMethodAttribute(FJBGContext context, - JClass clazz, - String className, - String methodName, - JType methodType) { - super(context, clazz); - this.pool = clazz.pool; - - this.classIdx = pool.addClass(className); - this.nameAndTypeIdx = pool.addNameAndType(methodName, methodType.getSignature()); - } - - public JEnclosingMethodAttribute(FJBGContext context, - JClass clazz, - Object owner, - String name, - int size, - DataInputStream stream) - throws IOException { - super(context, clazz, name); - this.pool = clazz.pool; - - this.classIdx = stream.readShort(); - this.nameAndTypeIdx = stream.readShort(); - - assert name.equals(getName()); - } - - public String getName() { return "EnclosingMethod"; } - - // Follows javap output format for EnclosingMethod attribute. - /*@Override*/ public String toString() { - StringBuffer buf = new StringBuffer(" EnclosingMethod:"); - buf.append("\n #"); - buf.append(classIdx); - if (nameAndTypeIdx != 0) { - buf.append(" of #"); - buf.append(nameAndTypeIdx); - } - buf.append(";\t// "); - buf.append(pool.lookupEntry(classIdx)); - buf.append("\n"); - return buf.toString(); - } - - protected int getSize() { - return 4; // 2 * Short.SIZE - } - - protected void writeContentsTo(DataOutputStream stream) throws IOException { - stream.writeShort(classIdx); - stream.writeShort(nameAndTypeIdx); - } -} diff --git a/src/fjbg/ch/epfl/lamp/fjbg/JExceptionsAttribute.java b/src/fjbg/ch/epfl/lamp/fjbg/JExceptionsAttribute.java deleted file mode 100644 index b91d0f2e93..0000000000 --- a/src/fjbg/ch/epfl/lamp/fjbg/JExceptionsAttribute.java +++ /dev/null @@ -1,90 +0,0 @@ -/* FJBG -- Fast Java Bytecode Generator - * Copyright 2002-2013 LAMP/EPFL - * @author Michel Schinz - */ - -package ch.epfl.lamp.fjbg; - -import java.io.DataInputStream; -import java.io.DataOutputStream; -import java.io.IOException; - -/** - * Exceptions attribute - - * This table is used by compilers to indicate which Exceptions a method - * is declared to throw. See section 2.6.4 of the JVM specification. - * - * @author Stephane Micheloud - * @version 1.0 - */ - -public class JExceptionsAttribute extends JAttribute { - /** Constant pool of the current classfile. */ - private JConstantPool pool; - - protected int[] indexTable; - protected int count; - - public JExceptionsAttribute(FJBGContext context, - JClass clazz, - JMethod owner) { - super(context, clazz); - this.pool = clazz.pool; - - this.count = 0; - this.indexTable = new int[8]; // some size > count - - assert clazz == owner.getOwner(); - } - - public JExceptionsAttribute(FJBGContext context, - JClass clazz, - Object owner, //JMethod - String name, - int size, - DataInputStream stream) - throws IOException { - super(context, clazz, name); - this.pool = clazz.pool; - - this.count = stream.readShort(); - this.indexTable = new int[count]; - for (int i = 0; i < count; ++i) - indexTable[i] = stream.readShort(); - - assert name.equals(getName()); - } - - public void addEntry(int classIndex) { - if (count >= indexTable.length) { - int[] newIT = new int[indexTable.length * 2]; - System.arraycopy(indexTable, 0, newIT, 0, indexTable.length); - indexTable = newIT; - } - indexTable[count++] = classIndex; - } - - public String getName() { return "Exceptions"; } - - // Follows javap output format for Exceptions attribute. - /*@Override*/ public String toString() { - StringBuffer buf = new StringBuffer(" Exceptions: "); - for (int i = 0; i < indexTable.length; ++i) { - buf.append("\n throws "); - buf.append(JClass.toExternalName(pool.lookupClass(indexTable[i]))); - } - buf.append("\n"); - return buf.toString(); - } - - protected int getSize() { - return 2 + indexTable.length * 2; - } - - protected void writeContentsTo(DataOutputStream stream) throws IOException { - stream.writeShort(count); - for (int i = 0; i < count; ++i) - stream.writeShort(indexTable[i]); - } -} diff --git a/src/fjbg/ch/epfl/lamp/fjbg/JExtendedCode.java b/src/fjbg/ch/epfl/lamp/fjbg/JExtendedCode.java deleted file mode 100644 index d82db8289f..0000000000 --- a/src/fjbg/ch/epfl/lamp/fjbg/JExtendedCode.java +++ /dev/null @@ -1,667 +0,0 @@ -/* FJBG -- Fast Java Bytecode Generator - * Copyright 2002-2013 LAMP/EPFL - * @author Michel Schinz - */ - -package ch.epfl.lamp.fjbg; - -/** - * Extended list of instructions, providing pseudo-instructions which - * are easier to use than the standard ones. - * - * @author Michel Schinz, Thomas Friedli - * @version 1.0 - */ - -public class JExtendedCode extends JCode { - public final static int COND_EQ = 0; - public final static int COND_NE = 1; - public final static int COND_LT = 2; - public final static int COND_GE = 3; - public final static int COND_GT = 4; - public final static int COND_LE = 5; - - private final JOpcode[] forbidden = new JOpcode[0]; - private final JOpcode[] nothingToDo = new JOpcode[0]; - - private final JOpcode[][][] typeConversions = { - { - /* T_BOOLEAN -> T_BOOLEAN */ nothingToDo, - /* T_BOOLEAN -> T_CHAR */ forbidden, - /* T_BOOLEAN -> T_FLOAT */ forbidden, - /* T_BOOLEAN -> T_DOUBLE */ forbidden, - /* T_BOOLEAN -> T_BYTE */ forbidden, - /* T_BOOLEAN -> T_SHORT */ forbidden, - /* T_BOOLEAN -> T_INT */ forbidden, - /* T_BOOLEAN -> T_LONG */ forbidden - }, - { - /* T_CHAR -> T_BOOLEAN */ forbidden, - /* T_CHAR -> T_CHAR */ nothingToDo, - /* T_CHAR -> T_FLOAT */ {JOpcode.I2F}, - /* T_CHAR -> T_DOUBLE */ {JOpcode.I2D}, - /* T_CHAR -> T_BYTE */ {JOpcode.I2B}, - /* T_CHAR -> T_SHORT */ {JOpcode.I2S}, - /* T_CHAR -> T_INT */ nothingToDo, - /* T_CHAR -> T_LONG */ {JOpcode.I2L} - }, - { - /* T_FLOAT -> T_BOOLEAN */ forbidden, - /* T_FLOAT -> T_CHAR */ {JOpcode.F2I, JOpcode.I2C}, - /* T_FLOAT -> T_FLOAT */ nothingToDo, - /* T_FLOAT -> T_DOUBLE */ {JOpcode.F2D}, - /* T_FLOAT -> T_BYTE */ {JOpcode.F2I, JOpcode.I2B}, - /* T_FLOAT -> T_SHORT */ {JOpcode.F2I, JOpcode.I2S}, - /* T_FLOAT -> T_INT */ {JOpcode.F2I}, - /* T_FLOAT -> T_LONG */ {JOpcode.F2L} - }, - { - /* T_DOUBLE -> T_BOOLEAN */ forbidden, - /* T_DOUBLE -> T_CHAR */ {JOpcode.D2I, JOpcode.I2C}, - /* T_DOUBLE -> T_FLOAT */ {JOpcode.D2F}, - /* T_DOUBLE -> T_DOUBLE */ nothingToDo, - /* T_DOUBLE -> T_BYTE */ {JOpcode.D2I, JOpcode.I2B}, - /* T_DOUBLE -> T_SHORT */ {JOpcode.D2I, JOpcode.I2S}, - /* T_DOUBLE -> T_INT */ {JOpcode.D2I}, - /* T_DOUBLE -> T_LONG */ {JOpcode.D2L} - }, - { - /* T_BYTE -> T_BOOLEAN */ forbidden, - /* T_BYTE -> T_CHAR */ {JOpcode.I2C}, - /* T_BYTE -> T_FLOAT */ {JOpcode.I2F}, - /* T_BYTE -> T_DOUBLE */ {JOpcode.I2D}, - /* T_BYTE -> T_BYTE */ nothingToDo, - /* T_BYTE -> T_SHORT */ nothingToDo, - /* T_BYTE -> T_INT */ nothingToDo, - /* T_BYTE -> T_LONG */ {JOpcode.I2L} - }, - { - /* T_SHORT -> T_BOOLEAN */ forbidden, - /* T_SHORT -> T_CHAR */ {JOpcode.I2C}, - /* T_SHORT -> T_FLOAT */ {JOpcode.I2F}, - /* T_SHORT -> T_DOUBLE */ {JOpcode.I2D}, - /* T_SHORT -> T_BYTE */ {JOpcode.I2B}, - /* T_SHORT -> T_SHORT */ nothingToDo, - /* T_SHORT -> T_INT */ nothingToDo, - /* T_SHORT -> T_LONG */ {JOpcode.I2L} - }, - { - /* T_INT -> T_BOOLEAN */ forbidden, - /* T_INT -> T_CHAR */ {JOpcode.I2C}, - /* T_INT -> T_FLOAT */ {JOpcode.I2F}, - /* T_INT -> T_DOUBLE */ {JOpcode.I2D}, - /* T_INT -> T_BYTE */ {JOpcode.I2B}, - /* T_INT -> T_SHORT */ {JOpcode.I2S}, - /* T_INT -> T_INT */ nothingToDo, - /* T_INT -> T_LONG */ {JOpcode.I2L} - }, - { - /* T_LONG -> T_BOOLEAN */ forbidden, - /* T_LONG -> T_CHAR */ {JOpcode.L2I, JOpcode.I2C}, - /* T_LONG -> T_FLOAT */ {JOpcode.L2F}, - /* T_LONG -> T_DOUBLE */ {JOpcode.L2D}, - /* T_LONG -> T_BYTE */ {JOpcode.L2I, JOpcode.I2B}, - /* T_LONG -> T_SHORT */ {JOpcode.L2I, JOpcode.I2S}, - /* T_LONG -> T_INT */ {JOpcode.L2I}, - /* T_LONG -> T_LONG */ nothingToDo - } - }; - - public JExtendedCode(FJBGContext context, - JClass clazz, - JMethod owner) { - super(context, clazz, owner); - } - - public void emitPUSH(boolean value) { emitPUSH(value ? 1 : 0); } - public void emitPUSH(Boolean value) { emitPUSH(value.booleanValue()); } - - public void emitPUSH(byte value) { - switch (value) { - case -1: emitICONST_M1(); break; - case 0: emitICONST_0(); break; - case 1: emitICONST_1(); break; - case 2: emitICONST_2(); break; - case 3: emitICONST_3(); break; - case 4: emitICONST_4(); break; - case 5: emitICONST_5(); break; - default: - emitBIPUSH(value); - } - } - public void emitPUSH(Byte value) { emitPUSH(value.byteValue()); } - - public void emitPUSH(short value) { - switch (value) { - case -1: emitICONST_M1(); break; - case 0: emitICONST_0(); break; - case 1: emitICONST_1(); break; - case 2: emitICONST_2(); break; - case 3: emitICONST_3(); break; - case 4: emitICONST_4(); break; - case 5: emitICONST_5(); break; - default: - if (value >= Byte.MIN_VALUE && value <= Byte.MAX_VALUE) - emitBIPUSH((byte)value); - else - emitSIPUSH(value); - } - } - public void emitPUSH(Short value) { emitPUSH(value.shortValue()); } - - // TODO check that we do the right thing here - public void emitPUSH(char value) { emitPUSH((int)value); } - public void emitPUSH(Character value) { emitPUSH(value.charValue()); } - - public void emitPUSH(int value) { - switch (value) { - case -1: emitICONST_M1(); break; - case 0: emitICONST_0(); break; - case 1: emitICONST_1(); break; - case 2: emitICONST_2(); break; - case 3: emitICONST_3(); break; - case 4: emitICONST_4(); break; - case 5: emitICONST_5(); break; - default: - if (value >= Byte.MIN_VALUE && value <= Byte.MAX_VALUE) - emitBIPUSH((byte)value); - else if (value >= Short.MIN_VALUE && value <= Short.MAX_VALUE) - emitSIPUSH((short)value); - else - emitPUSH_index(pool.addInteger(value)); - break; - } - } - public void emitPUSH(Integer value) { emitPUSH(value.intValue()); } - - public void emitPUSH(long value) { - if (value == 0L) - emitLCONST_0(); - else if (value == 1L) - emitLCONST_1(); - else - emitLDC2_W(value); - } - public void emitPUSH(Long value) { emitPUSH(value.longValue()); } - - private static final Float ZEROF = Float.valueOf(0f); - private static final Float ONEF = Float.valueOf(1f); - private static final Float TWOF = Float.valueOf(2f); - public void emitPUSH(Float value) { - if (ZEROF.equals(value)) - emitFCONST_0(); - else if (ONEF.equals(value)) - emitFCONST_1(); - else if (TWOF.equals(value)) - emitFCONST_2(); - else - emitPUSH_index(pool.addFloat(value.floatValue())); - } - public void emitPUSH(float value) { emitPUSH(Float.valueOf(value)); } - - private static final Double ZEROD = Double.valueOf(0d); - private static final Double ONED = Double.valueOf(1d); - public void emitPUSH(Double value) { - if (ZEROD.equals(value)) - emitDCONST_0(); - else if (ONED.equals(value)) - emitDCONST_1(); - else - emitLDC2_W(value.doubleValue()); - } - public void emitPUSH(double value) { emitPUSH(Double.valueOf(value)); } - - public void emitPUSH(String s) { - emitPUSH_index(pool.addString(s)); - } - - /** Pushes a class literal on the stack */ - public void emitPUSH(JReferenceType type) { - assert owner.owner.major >= 49; - emitPUSH_index(pool.addClass(type.getDescriptor())); - } - - protected void emitPUSH_index(int index) { - if (index <= 0xFF) - emitU1(JOpcode.LDC, index); - else - emitU2(JOpcode.LDC_W, index); - } - - public void emitLOAD(int index, JType type) { - JOpcode opcode; - - switch (type.getTag()) { - case JType.T_BOOLEAN: case JType.T_BYTE: case JType.T_CHAR: - case JType.T_SHORT: case JType.T_INT: - switch (index) { - case 0: emitILOAD_0(); return; - case 1: emitILOAD_1(); return; - case 2: emitILOAD_2(); return; - case 3: emitILOAD_3(); return; - default: opcode = JOpcode.ILOAD; - } break; - case JType.T_FLOAT: - switch (index) { - case 0: emitFLOAD_0(); return; - case 1: emitFLOAD_1(); return; - case 2: emitFLOAD_2(); return; - case 3: emitFLOAD_3(); return; - default: opcode = JOpcode.FLOAD; - } break; - case JType.T_LONG: - switch (index) { - case 0: emitLLOAD_0(); return; - case 1: emitLLOAD_1(); return; - case 2: emitLLOAD_2(); return; - case 3: emitLLOAD_3(); return; - default: opcode = JOpcode.LLOAD; - } break; - case JType.T_DOUBLE: - switch (index) { - case 0: emitDLOAD_0(); return; - case 1: emitDLOAD_1(); return; - case 2: emitDLOAD_2(); return; - case 3: emitDLOAD_3(); return; - default: opcode = JOpcode.DLOAD; - } break; - case JType.T_ARRAY: case JType.T_OBJECT: - switch (index) { - case 0: emitALOAD_0(); return; - case 1: emitALOAD_1(); return; - case 2: emitALOAD_2(); return; - case 3: emitALOAD_3(); return; - default: opcode = JOpcode.ALOAD; - } break; - default: - throw new IllegalArgumentException("invalid type for load "+type); - } - - if (index > 0xFF) - emitWIDE(opcode, index); - else - emitU1(opcode, index); - } - public void emitLOAD(JLocalVariable var) { - emitLOAD(var.index, var.type); - } - - public void emitSTORE(int index, JType type) { - JOpcode opcode; - - switch (type.getTag()) { - case JType.T_BOOLEAN: case JType.T_BYTE: case JType.T_CHAR: - case JType.T_SHORT: case JType.T_INT: - switch (index) { - case 0: emitISTORE_0(); return; - case 1: emitISTORE_1(); return; - case 2: emitISTORE_2(); return; - case 3: emitISTORE_3(); return; - default: opcode = JOpcode.ISTORE; - } break; - case JType.T_FLOAT: - switch (index) { - case 0: emitFSTORE_0(); return; - case 1: emitFSTORE_1(); return; - case 2: emitFSTORE_2(); return; - case 3: emitFSTORE_3(); return; - default: opcode = JOpcode.FSTORE; - } break; - case JType.T_LONG: - switch (index) { - case 0: emitLSTORE_0(); return; - case 1: emitLSTORE_1(); return; - case 2: emitLSTORE_2(); return; - case 3: emitLSTORE_3(); return; - default: opcode = JOpcode.LSTORE; - } break; - case JType.T_DOUBLE: - switch (index) { - case 0: emitDSTORE_0(); return; - case 1: emitDSTORE_1(); return; - case 2: emitDSTORE_2(); return; - case 3: emitDSTORE_3(); return; - default: opcode = JOpcode.DSTORE; - } break; - case JType.T_ARRAY: case JType.T_OBJECT: case JType.T_ADDRESS: - switch (index) { - case 0: emitASTORE_0(); return; - case 1: emitASTORE_1(); return; - case 2: emitASTORE_2(); return; - case 3: emitASTORE_3(); return; - default: opcode = JOpcode.ASTORE; - } break; - default: - throw new IllegalArgumentException("invalid type for store "+type); - } - - if (index > 0xFF) - emitWIDE(opcode, index); - else - emitU1(opcode, index); - } - public void emitSTORE(JLocalVariable var) { - emitSTORE(var.index, var.type); - } - - public void emitALOAD(JType type) { - switch (type.getTag()) { - case JType.T_BOOLEAN: - case JType.T_BYTE: - emitBALOAD(); - break; - case JType.T_CHAR: - emitCALOAD(); - break; - case JType.T_SHORT: - emitSALOAD(); - break; - case JType.T_INT: - emitIALOAD(); - break; - case JType.T_FLOAT: - emitFALOAD(); - break; - case JType.T_LONG: - emitLALOAD(); - break; - case JType.T_DOUBLE: - emitDALOAD(); - break; - case JType.T_ARRAY: - case JType.T_OBJECT: - emitAALOAD(); - break; - default: - throw new IllegalArgumentException("invalid type for aload " + type); - } - } - - public void emitASTORE(JType type) { - switch (type.getTag()) { - case JType.T_BOOLEAN: - case JType.T_BYTE: - emitBASTORE(); - break; - case JType.T_CHAR: - emitCASTORE(); - break; - case JType.T_SHORT: - emitSASTORE(); - break; - case JType.T_INT: - emitIASTORE(); - break; - case JType.T_FLOAT: - emitFASTORE(); - break; - case JType.T_LONG: - emitLASTORE(); - break; - case JType.T_DOUBLE: - emitDASTORE(); - break; - case JType.T_ARRAY: - case JType.T_OBJECT: - emitAASTORE(); - break; - default: - throw new IllegalArgumentException("invalid type for astore " + type); - } - } - - public void emitRETURN(JType type) { - if (type.isValueType()) { - switch (type.getTag()) { - case JType.T_BOOLEAN: - case JType.T_BYTE: - case JType.T_CHAR: - case JType.T_SHORT: - case JType.T_INT: - emitIRETURN(); - break; - case JType.T_FLOAT: - emitFRETURN(); - break; - case JType.T_LONG: - emitLRETURN(); - break; - case JType.T_DOUBLE: - emitDRETURN(); - break; - } - } else if (type.isArrayType() || type.isObjectType()) - emitARETURN(); - else if (type == JType.VOID) - emitRETURN(); - else - throw new IllegalArgumentException("invalid type for RETURN " + type); - } - - public void emitADD(JType type) { - switch (type.getTag()) { - case JType.T_BOOLEAN: case JType.T_BYTE: case JType.T_CHAR: - case JType.T_SHORT: case JType.T_INT: - emitIADD(); break; - case JType.T_FLOAT: - emitFADD(); break; - case JType.T_LONG: - emitLADD(); break; - case JType.T_DOUBLE: - emitDADD(); break; - } - } - - /** - * Emits a basic type conversion instruction choosen according to the - * types given in parameter. - * - * @param fromType The type of the value to be cast into another type. - * @param toType The type the value will be cast into. - */ - public void emitT2T(JType fromType, JType toType) { - assert fromType.getTag() >= JType.T_BOOLEAN - && fromType.getTag() <= JType.T_LONG - && toType.getTag() >= JType.T_BOOLEAN - && toType.getTag() <= JType.T_LONG; - - JOpcode[] conv = typeConversions[fromType.getTag() - 4][toType.getTag() - 4]; - if (conv == forbidden) { - throw new Error("inconvertible types : " + fromType.toString() - + " -> " + toType.toString()); - } else if (conv != nothingToDo) { - for (int i = 0; i < conv.length; i++) { - emit(conv[i]); - } - } - } - - public void emitIF(int cond, Label label) throws OffsetTooBigException { - assert cond >= COND_EQ && cond <= COND_LE; - emitU2(JOpcode.OPCODES[153 + cond], label.getOffset16(getPC() + 1, getPC())); - } - public void emitIF(int cond, int targetPC) throws OffsetTooBigException { - int offset = targetPC - getPC(); - emitU2(JOpcode.OPCODES[153 + cond], offset); - } - public void emitIF(int cond) throws OffsetTooBigException { - emitIF(cond, 0); - } - - public void emitIF_ICMP(int cond, Label label) throws OffsetTooBigException { - assert cond >= COND_EQ && cond <= COND_LE; - emitU2(JOpcode.OPCODES[159 + cond], label.getOffset16(getPC() + 1, getPC())); - } - public void emitIF_ICMP(int cond, int targetPC) throws OffsetTooBigException { - int offset = targetPC - getPC(); - emitU2(JOpcode.OPCODES[159 + cond], offset); - } - public void emitIF_ICMP(int cond) throws OffsetTooBigException { - emitIF_ICMP(cond, 0); - } - - public void emitIF_ACMP(int cond, Label label) throws OffsetTooBigException { - assert cond == COND_EQ || cond == COND_NE; - emitU2(JOpcode.OPCODES[165 + cond], label.getOffset16(getPC() + 1, getPC())); - } - public void emitIF_ACMP(int cond, int targetPC) throws OffsetTooBigException { - int offset = targetPC - getPC(); - emitU2(JOpcode.OPCODES[165 + cond], offset); - } - public void emitIF_ACMP(int cond) throws OffsetTooBigException { - emitIF_ACMP(cond, 0); - } - - public void emitGOTO_maybe_W(Label label, boolean defaultToWide) { - if (label.anchored) - emitGOTO_maybe_W(label.targetPC); - else { - if (defaultToWide) - emitGOTO_W(label); - else { - try { - emitGOTO(label); - } catch (OffsetTooBigException e) { - throw new Error(e); - } - } - } - } - - public void emitGOTO_maybe_W(int targetPC) { - int offset = targetPC - (getPC() + 1); - if (offset < Short.MIN_VALUE || offset > Short.MAX_VALUE) - emitGOTO_W(targetPC); - else { - try { - emitGOTO(targetPC); - } catch (OffsetTooBigException e) { - throw new Error(e); - } - } - } - - /** - * Emits a switch instruction choosen according to the caracteristics - * of the given list of keys and a default maxRate. - * - * @param keySets The array of all keys that must be compared to the - * value on stack. - * @param branches The labels representing the jump addresses linked - * with the corresponding keys. - * @param defaultBranch The label representing the default branch - * address. - */ - public void emitSWITCH(int[][] keySets, - Label[] branches, - Label defaultBranch, - double minDensity) { - assert keySets.length == branches.length; - - int flatSize = 0; - for (int i = 0; i < keySets.length; ++i) - flatSize += keySets[i].length; - - int[] flatKeys = new int[flatSize]; - Label[] flatBranches = new Label[flatSize]; - int flatI = 0; - for (int i = 0; i < keySets.length; ++i) { - Label branch = branches[i]; - int[] keys = keySets[i]; - for (int j = 0; j < keys.length; ++j) { - flatKeys[flatI] = keys[j]; - flatBranches[flatI] = branch; - } - ++flatI; - } - assert flatI == flatSize; - emitSWITCH(flatKeys, flatBranches, defaultBranch, minDensity); - } - - /** - * Emits a switch instruction choosen according to the caracteristics - * of the given list of keys and a given maxRate. - * - * @param keys The array of all keys that must be compared to the - * value on stack. - * @param branches The labels representing the jump addresses linked - * with the corresponding keys. - * @param defaultBranch The label representing the default branch - * address. - * @param minDensity The minimum density to use for TABLESWITCH. - */ - public void emitSWITCH(int[] keys, - Label[] branches, - Label defaultBranch, - double minDensity) { - assert keys.length == branches.length; - - //The special case for empty keys. It makes sense to allow - //empty keys and generate LOOKUPSWITCH with defaultBranch - //only. This is exactly what javac does for switch statement - //that has only a default case. - if (keys.length == 0) { - emitLOOKUPSWITCH(keys, branches, defaultBranch); - return; - } - //the rest of the code assumes that keys.length > 0 - - // sorting the tables - // FIXME use quicksort - for (int i = 1; i < keys.length; i++) { - for (int j = 1; j <= keys.length - i; j++) { - if (keys[j] < keys[j - 1]) { - int tmp = keys[j]; - keys[j] = keys[j - 1]; - keys[j - 1] = tmp; - - Label tmp_l = branches[j]; - branches[j] = branches[j - 1]; - branches[j - 1] = tmp_l; - } - } - } - - int keyMin = keys[0], keyMax = keys[keys.length - 1]; - /** Calculate in long to guard against overflow. */ - long keyRange = (long)keyMax - keyMin + 1; - if ((double)keys.length / (double)keyRange >= minDensity) { - // Keys are dense enough, use a table in which holes are - // filled with defaultBranch. - int[] newKeys = new int[(int)keyRange]; - Label[] newBranches = new Label[(int)keyRange]; - int oldPos = 0; - for (int i = 0; i < keyRange; ++i) { - int key = keyMin + i; - newKeys[i] = key; - if (keys[oldPos] == key) { - newBranches[i] = branches[oldPos]; - ++oldPos; - } else - newBranches[i] = defaultBranch; - } - assert oldPos == keys.length; - emitTABLESWITCH(newKeys, newBranches, defaultBranch); - } else - emitLOOKUPSWITCH(keys, branches, defaultBranch); - } - - /** - * Emits a method invocation instruction choosen according to - * the caracteristics of the given method. - * - * @param method The method to be invoked. - */ - public void emitINVOKE(JMethod method) { - String mName = method.getName(); - String cName = method.getOwner().getName(); - JMethodType mType = (JMethodType)method.getType(); - if (method.isStatic()) - emitINVOKESTATIC(cName, mName, mType); - else if (method.getOwner().isInterface()) - emitINVOKEINTERFACE(cName, mName, mType); - else - emitINVOKEVIRTUAL(cName, mName, mType); - } - -} diff --git a/src/fjbg/ch/epfl/lamp/fjbg/JField.java b/src/fjbg/ch/epfl/lamp/fjbg/JField.java deleted file mode 100644 index 29d826ba99..0000000000 --- a/src/fjbg/ch/epfl/lamp/fjbg/JField.java +++ /dev/null @@ -1,62 +0,0 @@ -/* FJBG -- Fast Java Bytecode Generator - * Copyright 2002-2013 LAMP/EPFL - * @author Michel Schinz - */ - -package ch.epfl.lamp.fjbg; - -import java.io.DataInputStream; -import java.io.IOException; - -/** - * Java class field. - * - * @author Michel Schinz - * @version 1.0 - */ - -public class JField extends JFieldOrMethod { - - protected JField(FJBGContext context, - JClass owner, - int accessFlags, - String name, - JType type) { - super(context, owner, accessFlags, name, type); - } - - protected JField(FJBGContext context, - JClass owner, - DataInputStream stream) - throws IOException { - super(context, owner, stream); - } - - // Follows javap output format for fields. - /*@Override*/ public String toString() { - StringBuffer buf = new StringBuffer(flagsToString()); - buf.append(toExternalName(getType())); - buf.append(" "); - buf.append(getName()); - buf.append(";\n"); - java.util.Iterator attrsIt = attributes.iterator(); - while (attrsIt.hasNext()) { - JAttribute attrs = (JAttribute)attrsIt.next(); - buf.append(attrs); - } - return buf.toString(); - } - - private String flagsToString() { - StringBuffer buf = new StringBuffer(); - if (isPublic()) buf.append("public "); - else if (isProtected()) buf.append("protected "); - else if (isPrivate()) buf.append("private "); - if (isStatic()) buf.append("static "); - else if (isTransient()) buf.append("transient "); - else if (isVolatile()) buf.append("volatile "); - if (isAbstract()) buf.append("abstract "); - else if (isFinal()) buf.append("final "); - return buf.toString(); - } -} diff --git a/src/fjbg/ch/epfl/lamp/fjbg/JFieldOrMethod.java b/src/fjbg/ch/epfl/lamp/fjbg/JFieldOrMethod.java deleted file mode 100644 index 794c0f13b5..0000000000 --- a/src/fjbg/ch/epfl/lamp/fjbg/JFieldOrMethod.java +++ /dev/null @@ -1,138 +0,0 @@ -/* FJBG -- Fast Java Bytecode Generator - * Copyright 2002-2013 LAMP/EPFL - * @author Michel Schinz - */ - -package ch.epfl.lamp.fjbg; - -import java.io.DataInputStream; -import java.io.DataOutputStream; -import java.io.IOException; - -/** - * Abstract superclass for a Java field or method. - * - * No two methods of fields in one class file may have the same name and - * descriptor. See sections 4.6 and 4.7 of the JVM specification. - * - * @author Michel Schinz - * @version 1.0 - */ - -abstract public class JFieldOrMethod extends JMember { - - protected final JClass owner; - protected final JType type; - - protected final int nameIndex, signatureIndex; - - protected JFieldOrMethod(FJBGContext context, - JClass owner, - int accessFlags, - String name, - JType type) { - super(context, accessFlags, name); - this.owner = owner; - this.type = type; - - nameIndex = owner.pool.addUtf8(name); - signatureIndex = owner.pool.addUtf8(type.getSignature()); - } - - protected JFieldOrMethod(FJBGContext context, - JClass owner, - DataInputStream stream) - throws IOException { - super(context); - this.owner = owner; - this.accessFlags = stream.readShort(); - this.nameIndex = stream.readShort(); - this.name = owner.pool.lookupUtf8(nameIndex); - this.signatureIndex = stream.readShort(); - this.type = JType.parseSignature(owner.pool.lookupUtf8(signatureIndex)); - this.attributes.addAll(JAttribute.readFrom(context, owner, this, stream)); - } - - public void freeze() throws JCode.OffsetTooBigException { - assert !frozen; - frozen = true; - } - - public JClass getOwner() { return owner; } - - public JType getType() { return type; } - - public JClass getJClass() { return owner; } - - public boolean isPublic() { - return (accessFlags & JAccessFlags.ACC_PUBLIC) != 0; - } - - public boolean isPrivate() { - return (accessFlags & JAccessFlags.ACC_PRIVATE) != 0; - } - - public boolean isProtected() { - return (accessFlags & JAccessFlags.ACC_PROTECTED) != 0; - } - - public boolean isStatic() { - return (accessFlags & JAccessFlags.ACC_STATIC) != 0; - } - - public boolean isFinal() { - return (accessFlags & JAccessFlags.ACC_FINAL) != 0; - } - - public boolean isSuper() { - return (accessFlags & JAccessFlags.ACC_SUPER) != 0; - } - - public boolean isVolatile() { - return (accessFlags & JAccessFlags.ACC_VOLATILE) != 0; - } - - public boolean isTransient() { - return (accessFlags & JAccessFlags.ACC_TRANSIENT) != 0; - } - - public boolean isNative() { - return (accessFlags & JAccessFlags.ACC_NATIVE) != 0; - } - - public boolean isInterface() { - return (accessFlags & JAccessFlags.ACC_INTERFACE) != 0; - } - - public boolean isAbstract() { - return (accessFlags & JAccessFlags.ACC_ABSTRACT) != 0; - } - - public boolean isStrict() { - return (accessFlags & JAccessFlags.ACC_STRICT) != 0; - } - - // 1.5 specifics - public boolean isBridge() { - return (accessFlags & JAccessFlags.ACC_BRIDGE) != 0; - } - - public boolean hasVarargs() { - return (accessFlags & JAccessFlags.ACC_VARARGS) != 0; - } - - public void writeTo(DataOutputStream stream) throws IOException { - if (! frozen) { - try { - freeze(); - } - catch (JCode.OffsetTooBigException e) { - throw new Error(e); - } - } - stream.writeShort(accessFlags); - stream.writeShort(nameIndex); - stream.writeShort(signatureIndex); - JAttribute.writeTo(getAttributes(), stream); - } -} diff --git a/src/fjbg/ch/epfl/lamp/fjbg/JInnerClassesAttribute.java b/src/fjbg/ch/epfl/lamp/fjbg/JInnerClassesAttribute.java deleted file mode 100644 index 1c1ced500d..0000000000 --- a/src/fjbg/ch/epfl/lamp/fjbg/JInnerClassesAttribute.java +++ /dev/null @@ -1,201 +0,0 @@ -/* FJBG -- Fast Java Bytecode Generator - * Copyright 2002-2013 LAMP/EPFL - * @author Michel Schinz - */ - -package ch.epfl.lamp.fjbg; - -import java.io.DataInputStream; -import java.io.DataOutputStream; -import java.io.IOException; -import java.util.Iterator; -import java.util.LinkedHashMap; -import java.util.Map; - -/** - * InnerClasses attribute. - * - * The ClassFile structure of a class/interface C must have exactly one - * InnerClasses attribute in its attributes table if the constant pool of C - * contains a CONSTANT_Class_info entry which represents a class or interface - * that is not a member of a package. See section 4.8.5 of the JVM Specification. - * - * @author Iulian Dragos, Stephane Micheloud - * @version 1.1 - */ -public class JInnerClassesAttribute extends JAttribute { - /** Constant pool of the current classfile. */ - private JConstantPool pool; - - /** InnerClass entries */ - private Map/*<String, Entry>*/ entries = new LinkedHashMap(); - - public JInnerClassesAttribute(FJBGContext context, JClass clazz) { - super(context, clazz); - this.pool = clazz.pool; - } - - public JInnerClassesAttribute(FJBGContext context, - JClass clazz, - Object owner, - String name, - int size, - DataInputStream stream) - throws IOException { - super(context, clazz, name); - this.pool = clazz.pool; - - String inner = null; - int count = stream.readShort(); - for (int i = 0; i < count; ++i) { - int innerIdx = stream.readShort(); - int outerIdx = stream.readShort(); - int nameIdx = stream.readShort(); - int flags = stream.readShort(); - inner = pool.lookupClass(innerIdx); - entries.put(inner, new Entry(innerIdx, outerIdx, nameIdx, flags)); - } - - assert name.equals(getName()); - } - - public void addEntry(String inner, String outer, String name, int flags) { - int innerIdx = pool.addClass(inner); - int outerIdx = 0; - if (outer != null) outerIdx = pool.addClass(outer); - int nameIdx = 0; - if (name != null) nameIdx = pool.addUtf8(name); - - Entry e = new Entry(innerIdx, outerIdx, nameIdx, flags); - - if (entries.containsKey(inner)) { - Entry other = (Entry) entries.get(inner); - assert other.outerInfo == e.outerInfo && other.originalName == e.originalName && other.innerFlags == e.innerFlags - : inner + " already declared as " + other; - } else - entries.put(inner, e); - } - - public String getName() { return "InnerClasses"; } - - // Follows javap output format for the InnerClass attribute. - /*@Override*/ public String toString() { - // Here we intentionally use "InnerClass" as javap :-( - StringBuffer buf = new StringBuffer(" InnerClass: "); - for (Iterator it = entries.values().iterator(); it.hasNext(); ) { - Entry e = (Entry)it.next(); - buf.append("\n "); - buf.append(e.innerFlagsToString()); - buf.append("#"); - if (e.originalName != 0) { - buf.append(e.originalName); - buf.append("= #"); - } - buf.append(e.innerInfo); - if (e.outerInfo != 0) { - buf.append(" of #"); - buf.append(e.outerInfo); - } - buf.append("; //"); - if (e.originalName != 0) { - buf.append(pool.lookupUtf8(e.originalName)); - buf.append("="); - } - buf.append("class "); - buf.append(pool.lookupClass(e.innerInfo)); - if (e.outerInfo != 0) { - buf.append(" of class "); - buf.append(pool.lookupClass(e.outerInfo)); - } - } - buf.append("\n"); - return buf.toString(); - } - - protected int getSize() { - return 2 + entries.size() * 8; - } - - protected void writeContentsTo(DataOutputStream stream) throws IOException { - stream.writeShort(entries.size()); - for (Iterator it = entries.values().iterator(); it.hasNext(); ) { - Entry e = (Entry)it.next(); - stream.writeShort(e.innerInfo); - stream.writeShort(e.outerInfo); - stream.writeShort(e.originalName); - stream.writeShort(e.innerFlags); - } - } - - /** An entry in the InnerClasses attribute, as defined by the JVM Spec. */ - private class Entry { - /** CONSTANT_Class_info index in the pool for the inner class (mangled). */ - int innerInfo; - - /** CONSTANT_Class_info index in the pool for the outer class (mangled). */ - int outerInfo; - - /** CONSTANT_Utf8_info index in the pool for the original name of the inner class. */ - int originalName; - - /** Short int for modifier flags. */ - int innerFlags; - - public Entry(int iI, int oI, int oN, int f) { - this.innerInfo = iI; - this.outerInfo = oI; - this.originalName = oN; - this.innerFlags = f; - } - - public Entry(String innerClass, String outerClass, String name, int flags) { - this(pool.addClass(innerClass), pool.addClass(outerClass), pool.addUtf8(name), flags); - } - - /** Two entries are equal if they refer to the same inner class. - * innerInfo represents a unique name (mangled). - */ - public boolean equals(Object other) { - if (other instanceof Entry) { - Entry otherEntry = (Entry) other; - return otherEntry.innerInfo == this.innerInfo; - } - return false; - } - - public String innerFlagsToString() { - StringBuffer buf = new StringBuffer(); - if (isPublic()) buf.append("public "); - else if (isProtected()) buf.append("protected "); - else if (isPrivate()) buf.append("private "); - //if (isStatic()) buf.append("static "); // as javap - if (isAbstract()) buf.append("abstract "); - else if (isFinal()) buf.append("final "); - return buf.toString(); - } - - private boolean isPublic() { - return (innerFlags & JAccessFlags.ACC_PUBLIC) != 0; - } - - private boolean isPrivate() { - return (innerFlags & JAccessFlags.ACC_PRIVATE) != 0; - } - - private boolean isProtected() { - return (innerFlags & JAccessFlags.ACC_PROTECTED) != 0; - } - - private boolean isStatic() { - return (innerFlags & JAccessFlags.ACC_STATIC) != 0; - } - - private boolean isFinal() { - return (innerFlags & JAccessFlags.ACC_FINAL) != 0; - } - - private boolean isAbstract() { - return (innerFlags & JAccessFlags.ACC_ABSTRACT) != 0; - } - } -} diff --git a/src/fjbg/ch/epfl/lamp/fjbg/JLabel.java b/src/fjbg/ch/epfl/lamp/fjbg/JLabel.java deleted file mode 100644 index 96f3b4ebef..0000000000 --- a/src/fjbg/ch/epfl/lamp/fjbg/JLabel.java +++ /dev/null @@ -1,30 +0,0 @@ -/* FJBG -- Fast Java Bytecode Generator - * Copyright 2002-2013 LAMP/EPFL - * @author Michel Schinz - */ - -package ch.epfl.lamp.fjbg; - -/** - * Labels which can be attached to instructions. - * - * @author Michel Schinz - * @version 1.0 - */ - -public class JLabel { - public final static int UNDEFINED_ANCHOR = -1; - protected int anchor = UNDEFINED_ANCHOR; - - public boolean isAnchored() { return anchor != UNDEFINED_ANCHOR; } - - public int getAnchor() { - assert isAnchored(); - return anchor; - } - - public void setAnchor(int anchor) { - assert !isAnchored(); - this.anchor = anchor; - } -} diff --git a/src/fjbg/ch/epfl/lamp/fjbg/JLineNumberTableAttribute.java b/src/fjbg/ch/epfl/lamp/fjbg/JLineNumberTableAttribute.java deleted file mode 100644 index f8c09b8ef8..0000000000 --- a/src/fjbg/ch/epfl/lamp/fjbg/JLineNumberTableAttribute.java +++ /dev/null @@ -1,121 +0,0 @@ -/* FJBG -- Fast Java Bytecode Generator - * Copyright 2002-2013 LAMP/EPFL - * @author Michel Schinz - */ - -package ch.epfl.lamp.fjbg; - -import java.io.DataInputStream; -import java.io.DataOutputStream; -import java.io.IOException; - -/** - * Attribute storing correspondance between instructions and source - * line numbers. - * - * @author Michel Schinz - * @version 1.0 - */ - -public class JLineNumberTableAttribute extends JAttribute { - protected final JCode code; - - public JLineNumberTableAttribute(FJBGContext context, - JClass clazz, - JCode owner) { - super(context, clazz); - this.code = owner; - - assert owner.getOwner().getOwner() == clazz; - } - - public JLineNumberTableAttribute(FJBGContext context, - JClass clazz, - Object owner, - String name, - int size, - DataInputStream stream) - throws IOException { - super(context, clazz, name); - this.code = (JCode)owner; - - int[] mapping = new int[code.getSize()]; - - int count = stream.readShort(); - for (int i = 0; i < count; ++i) { - int startPC = stream.readShort(); - int lineNum = stream.readShort(); - mapping[startPC] = lineNum; - } - - // Avoids duplication of LineNumberTable attribute - // (see method ensureLineNumberCapacity in class JCode). - assert code.lineNumbers == null; - code.lineNumbers = new int[0]; - - int lineNum = 0; - for (int pc = 0; pc < mapping.length; ++pc) { - if (mapping[pc] != 0) lineNum = mapping[pc]; - if (lineNum != 0) code.setLineNumber(pc, lineNum); - } - - assert name.equals(getName()); - } - - public String getName() { return "LineNumberTable"; } - - // Follows javap output format for LineNumberTable attribute. - /*@Override*/ public String toString() { - StringBuffer buf = new StringBuffer(" LineNumberTable: "); - int[] encoding = encode(); - for (int i = 0; i < encoding.length/2; ++i) { - buf.append("\n line "); - buf.append(encoding[i * 2 + 1]); - buf.append(": "); - buf.append(encoding[i * 2]); - } - buf.append("\n"); - return buf.toString(); - } - - protected int[] encoding; - protected int[] encode() { - if (encoding == null) { - int[] lineNumbers = code.getLineNumbers(); - int[] preEncoding = new int[lineNumbers.length * 2]; - int prevLineNum = 0; - - int i = 0; - for (int pc = 0; pc < lineNumbers.length; ++pc) { - int lineNum = lineNumbers[pc]; - if (lineNum != 0 & lineNum != prevLineNum) { - preEncoding[i++] = pc; - preEncoding[i++] = lineNum; - prevLineNum = lineNum; - } - } - if (i == preEncoding.length) - encoding = preEncoding; - else { - encoding = new int[i]; - System.arraycopy(preEncoding, 0, encoding, 0, i); - } - } - return encoding; - } - - protected int getSize() { - int[] encoding = encode(); - return 2 + encoding.length * 2; - } - - protected void writeContentsTo(DataOutputStream stream) throws IOException { - int[] encoding = encode(); - int entries = encoding.length / 2; - stream.writeShort(entries); - for (int i = 0; i < entries; ++i) { - stream.writeShort(encoding[i * 2]); - stream.writeShort(encoding[i * 2 + 1]); - } - } -} diff --git a/src/fjbg/ch/epfl/lamp/fjbg/JLocalVariable.java b/src/fjbg/ch/epfl/lamp/fjbg/JLocalVariable.java deleted file mode 100644 index af7980656f..0000000000 --- a/src/fjbg/ch/epfl/lamp/fjbg/JLocalVariable.java +++ /dev/null @@ -1,42 +0,0 @@ -/* FJBG -- Fast Java Bytecode Generator - * Copyright 2002-2013 LAMP/EPFL - * @author Michel Schinz - */ - -package ch.epfl.lamp.fjbg; - -/** - * Representation of a local variable or method argument. - * - * @author Michel Schinz - * @version 1.0 - */ - -public class JLocalVariable { - protected final JMethod owner; - protected final JType type; - protected final String name; - protected final int index; - - protected JLocalVariable(FJBGContext context, - JMethod owner, - JType type, - String name, - int index) { - this.owner = owner; - this.type = type; - this.name = name; - this.index = index; - - assert index < 0xFFFF : "index too big for local variable: " + index; - } - - public JMethod getOwner() { return owner; } - public int getIndex() { return index; } - public String getName() { return name; } - public JType getType() { return type; } - - /*@Override*/ public String toString() { - return "0\t"+type.getSize()+"\t"+index+"\t"+name+"\t"+type; - } -} diff --git a/src/fjbg/ch/epfl/lamp/fjbg/JLocalVariableTableAttribute.java b/src/fjbg/ch/epfl/lamp/fjbg/JLocalVariableTableAttribute.java deleted file mode 100644 index b277cc71c0..0000000000 --- a/src/fjbg/ch/epfl/lamp/fjbg/JLocalVariableTableAttribute.java +++ /dev/null @@ -1,167 +0,0 @@ -/* FJBG -- Fast Java Bytecode Generator - * Copyright 2002-2013 LAMP/EPFL - * @author Michel Schinz - */ - -package ch.epfl.lamp.fjbg; - -import java.io.DataInputStream; -import java.io.DataOutputStream; -import java.io.IOException; -import java.util.Iterator; -import java.util.LinkedList; - -import ch.epfl.lamp.fjbg.JConstantPool.*; - -/** - * Attribute storing local variables. - * - * @author Stephane Micheloud - * @version 1.0 - */ - -public class JLocalVariableTableAttribute extends JAttribute { - /** Constant pool of the current classfile. */ - private JConstantPool pool; - - protected final LinkedList/*<Entry>*/ entries = new LinkedList(); - protected int localVariableIndex = 0; - - public JLocalVariableTableAttribute(FJBGContext context, - JClass clazz, - JCode code) { - super(context, clazz); - this.pool = clazz.pool; - - assert code.getOwner().getOwner() == clazz; - } - - public JLocalVariableTableAttribute(FJBGContext context, - JClass clazz, - Object owner, - String name, - int size, - DataInputStream stream) - throws IOException { - super(context, clazz, name); - this.pool = clazz.pool; - - int count = stream.readShort(); - for (int i = 0; i < count; ++i) { - int startPc = stream.readShort(); - int length = stream.readShort(); - int nameIndex = stream.readShort(); - int descIndex = stream.readShort(); - int index = stream.readShort(); - addEntry(startPc, length, nameIndex, descIndex, index); - } - - assert name.equals(getName()); - } - - public void addEntry(int startPc, int length, int nameIndex, - int descIndex, int index) { - entries.add(new Entry(startPc, length, nameIndex, descIndex, index)); - } - - public void addEntry(int startPc, int length, String name, - String desc, int index) { - Entry e = new Entry(startPc, length, name, desc, index); - Entry other = getEntry(index); - if (other != null) { - assert other.nameIndex == e.nameIndex && other.descIndex == e.descIndex - : e + " already declared as " + other; - } else - entries.add(e); - } - - public void addEntry(int startPc, int length, String name, String desc) { - entries.add(new Entry(startPc, length, name, desc)); - } - - public String getName() { return "LocalVariableTable"; } - - // Follows javap output format for LocalVariableTable attribute. - /*@Override*/ public String toString() { - StringBuffer buf = new StringBuffer(" LocalVariableTable: "); - buf.append("\n Start Length Slot Name Signature"); - for (Iterator it = entries.iterator(); it.hasNext(); ) { - buf.append("\n "); - Entry e = (Entry)it.next(); - Utf8Entry name = (Utf8Entry)pool.lookupEntry(e.nameIndex); - Utf8Entry sig = (Utf8Entry)pool.lookupEntry(e.descIndex); - buf.append(e.startPc); - buf.append(" "); - buf.append(e.length); - buf.append(" "); - buf.append(e.index); - buf.append(" "); - buf.append(name.getValue()); - buf.append(" "); - buf.append(sig.getValue()); - } - buf.append("\n"); - return buf.toString(); - } - - public int getMaxLocals() { - return localVariableIndex; - } - - public int getSize() { - return 2 + entries.size() * 10; - } - - protected void writeContentsTo(DataOutputStream stream) throws IOException { - stream.writeShort(entries.size()); - for (Iterator it = entries.iterator(); it.hasNext(); ) { - Entry e = (Entry)it.next(); - stream.writeShort(e.startPc); - stream.writeShort(e.length); - stream.writeShort(e.nameIndex); - stream.writeShort(e.descIndex); - stream.writeShort(e.index); - } - } - - private Entry getEntry(int index) { - Entry e = null; - try { e = (Entry)entries.get(index); } catch (Exception ex) {} - return e; - } - - private class Entry { - int startPc; - int length; - int nameIndex; - int descIndex; - int index; - - public Entry(int startPc, int length, int nameIndex, int descIndex, int index) { - this.startPc = startPc; - this.length = length; - this.nameIndex = nameIndex; - this.descIndex = descIndex; - this.index = index; - localVariableIndex += length; - } - - public Entry(int startPc, int length, String name, String desc, int index) { - this(startPc, length, pool.addUtf8(name), pool.addUtf8(desc), index); - } - - public Entry(int startPc, int length, String name, String desc) { - this(startPc, length, pool.addUtf8(name), pool.addUtf8(desc), localVariableIndex); - } - - /** Two entries are equal if they refer to the same index. - */ - public boolean equals(Object other) { - if (other instanceof Entry) { - Entry otherEntry = (Entry) other; - return otherEntry.index == this.index; - } - return false; - } - } -} diff --git a/src/fjbg/ch/epfl/lamp/fjbg/JMember.java b/src/fjbg/ch/epfl/lamp/fjbg/JMember.java deleted file mode 100644 index 6356cc874d..0000000000 --- a/src/fjbg/ch/epfl/lamp/fjbg/JMember.java +++ /dev/null @@ -1,109 +0,0 @@ -/* FJBG -- Fast Java Bytecode Generator - * Copyright 2002-2013 LAMP/EPFL - * @author Michel Schinz - */ - -package ch.epfl.lamp.fjbg; - -import java.util.Iterator; -import java.util.LinkedList; -import java.util.List; - -/** - * Abstract superclass for a Java class, field or method. - * - * @author Nikolay Mihaylov - * @version 1.0 - */ - -abstract public class JMember { - - protected boolean frozen = false; - - protected final FJBGContext context; - - protected String name; - - protected int accessFlags; - - protected final List/*<JAttribute>*/ attributes = new LinkedList(); - - protected JMember(FJBGContext context) { this.context = context; } - - protected JMember(FJBGContext context, int accessFlags, String name) { - this(context); - this.name = name; - this.accessFlags = accessFlags; - } - - /** - * Gets the access flags of the class. - * @return The int representing the access flags of the class. - */ - public int getAccessFlags() { return accessFlags; } - - /** - * Gets the name of the member. - * @return The string representing the name of the member. - */ - public String getName() { return name; } - - /** - * Gets the type of the objects that are instances of the class. - * @return The type of the instances of the class. - */ - public abstract JType getType(); - - /** - * Gets the class corresponding to/owning this member - * @return The class owning this member or the class itself. - */ - public abstract JClass getJClass(); - - /** - * Gets the constant pool of the class. - * @return The constant pool of the class. - */ - public JConstantPool getConstantPool() { return getJClass().getConstantPool(); } - - public FJBGContext getContext() { return context; } - - /** - * Adds an attribute to the class. - * @param attr The attribute to be added. - */ - public void addAttribute(JAttribute attr) { - assert !frozen; - attributes.add(attr); - } - - /** - * Gets the list of all attributes of the class. - * @return The list of the attributes of the class representation. - */ - public List/*<JAttribute>*/ getAttributes() { - return attributes; - } - - /** - * Get the attribute with the given name, or null if it doesn't - * exist. - */ - public JAttribute getAttribute(String name) { - Iterator attrIt = getAttributes().iterator(); - while (attrIt.hasNext()) { - JAttribute attr = (JAttribute)attrIt.next(); - if (attr.getName().equals(name)) - return attr; - } - return null; - } - - protected static String toExternalName(String name) { - return name.replace('/', '.'); - } - - protected static String toExternalName(JType tpe) { - return tpe.toString().replace(':', '.'); - } -} diff --git a/src/fjbg/ch/epfl/lamp/fjbg/JMethod.java b/src/fjbg/ch/epfl/lamp/fjbg/JMethod.java deleted file mode 100644 index 01d58a45c7..0000000000 --- a/src/fjbg/ch/epfl/lamp/fjbg/JMethod.java +++ /dev/null @@ -1,199 +0,0 @@ -/* FJBG -- Fast Java Bytecode Generator - * Copyright 2002-2013 LAMP/EPFL - * @author Michel Schinz - */ - -package ch.epfl.lamp.fjbg; - -import java.io.DataInputStream; -import java.io.IOException; -import java.util.Iterator; -import java.util.LinkedList; -import java.util.List; - -/** - * Representation of a Java method. - * - * @author Michel Schinz - * @version 1.0 - */ - -public class JMethod extends JFieldOrMethod { - public final static String CLASS_CONSTRUCTOR_NAME = "<clinit>"; - public final static String INSTANCE_CONSTRUCTOR_NAME = "<init>"; - - protected /*final*/ JCode code; - protected final String[] argNames; - - protected final LinkedList/*<JLocalVariable>*/ localVariables = - new LinkedList(); - protected int localVariableIndex = 0; - - - protected JMethod(FJBGContext context, - JClass owner, - int accessFlags, - String name, - JType returnType, - JType[] argTypes, - String[] argNames) { - super(context, - owner, - accessFlags, - name, - new JMethodType(returnType, argTypes)); - this.argNames = argNames; - - assert argTypes.length == argNames.length; - - if (isAbstract() || isNative()) { - code = null; - } else { - code = context.JCode(owner, this); - addAttribute(context.JCodeAttribute(owner, this)); - - if (!isStatic()) - addNewLocalVariable(owner.getType(), "this"); - - for (int i = 0; i < argTypes.length; ++i) - addNewLocalVariable(argTypes[i], argNames[i]); - } - } - - protected JMethod(FJBGContext context, - JClass owner, - DataInputStream stream) - throws IOException { - super(context, owner, stream); - - assert isAbstract() || isNative() || code != null; - - int n = 0; - if (code != null) { - for (Iterator it = code.getAttributes().iterator(); it.hasNext(); ) { - JAttribute attr = (JAttribute)it.next(); - if (attr instanceof JLocalVariableTableAttribute) - n = ((JLocalVariableTableAttribute)attr).getMaxLocals(); - } - } - this.localVariableIndex = n; - - - JType[] argTypes = ((JMethodType)getType()).getArgumentTypes(); - argNames = new String[argTypes.length]; // TODO get from attribute - for (int i = 0; i < argNames.length; ++i) - argNames[i] = "v"+i; - } - - public void freeze() throws JCode.OffsetTooBigException { - if (code != null) code.freeze(); - super.freeze(); - } - - public JType getReturnType() { - return ((JMethodType)type).getReturnType(); - } - - public JType[] getArgumentTypes() { - return ((JMethodType)type).getArgumentTypes(); - } - - public int getArgsSize() { - int size = ((JMethodType)type).getArgsSize(); - if (!isStatic()) size += 1; // for this - return size; - } - - public String[] getArgumentNames() { - return argNames; - } - - public JCode getCode() { - assert !isAbstract(); - return code; - } - - // Invoked by the JCode constructor - protected void setCode(JCode code) { - assert null == this.code; - this.code = code; - } - - public JCodeIterator codeIterator() { - return new JCodeIterator(code); - } - - // Local variables - // FIXME : find a better management method for local variables - public JLocalVariable addNewLocalVariable(JType type, String name) { - assert !frozen; - JLocalVariable var = - context.JLocalVariable(this, type, name, localVariableIndex); - localVariableIndex += type.getSize(); - localVariables.add(var); - return var; - } - - public JLocalVariable getLocalVariable(int index) { - for (int i = 0; i < localVariables.size(); i++) { - if (((JLocalVariable)localVariables.get(i)).index == index) - return (JLocalVariable)localVariables.get(i); - } - return null; - } - - public JLocalVariable[] getLocalVariables() { - return (JLocalVariable[])localVariables - .toArray(new JLocalVariable[localVariables.size()]); - } - - - public int getMaxLocals() { - return localVariableIndex; - } - - // Follows javap output format for methods. - /*@Override*/ public String toString() { - StringBuffer buf = new StringBuffer(flagsToString()); - String name = getName(); - if (CLASS_CONSTRUCTOR_NAME.equals(name)) - buf.append("{}"); - else { - if (INSTANCE_CONSTRUCTOR_NAME.equals(name)) - name = getOwner().getName(); - else { - buf.append(toExternalName(getReturnType())); - buf.append(" "); - } - buf.append(toExternalName(name)); - buf.append("("); - JType[] ts = getArgumentTypes(); - for (int i = 0; i < ts.length; ++i) { - if (i > 0) buf.append(", "); - buf.append(toExternalName(ts[i])); - } - buf.append(")"); - } - buf.append(";\n"); - Iterator it = attributes.iterator(); - while(it.hasNext()) { - JAttribute attr = (JAttribute)it.next(); - buf.append(attr); - } - return buf.toString(); - } - - private String flagsToString() { - StringBuffer buf = new StringBuffer(); - if (isPublic()) buf.append("public "); - else if (isProtected()) buf.append("protected "); - else if (isPrivate()) buf.append("private "); - if (isBridge()) buf.append("<bridge> "); - if (hasVarargs()) buf.append("<varargs> "); - if (isStatic()) buf.append("static "); - else if (isNative()) buf.append("native "); - if (isAbstract()) buf.append("abstract "); - else if (isFinal()) buf.append("final "); - return buf.toString(); - } -} diff --git a/src/fjbg/ch/epfl/lamp/fjbg/JMethodType.java b/src/fjbg/ch/epfl/lamp/fjbg/JMethodType.java deleted file mode 100644 index cd3d71fd9c..0000000000 --- a/src/fjbg/ch/epfl/lamp/fjbg/JMethodType.java +++ /dev/null @@ -1,87 +0,0 @@ -/* FJBG -- Fast Java Bytecode Generator - * Copyright 2002-2013 LAMP/EPFL - * @author Michel Schinz - */ - -package ch.epfl.lamp.fjbg; - -/** - * Type for Java methods. These types do not really exist in Java, but - * are provided here because they are useful in several places. - * - * @author Michel Schinz - * @version 1.0 - */ - -public class JMethodType extends JType { - protected final JType returnType; - protected final JType[] argTypes; - protected String signature = null; - - public final static JMethodType ARGLESS_VOID_FUNCTION = - new JMethodType(JType.VOID, JType.EMPTY_ARRAY); - - public JMethodType(JType returnType, JType[] argTypes) { - this.returnType = returnType; - this.argTypes = argTypes; - } - - public JType getReturnType() { return returnType; } - public JType[] getArgumentTypes() { return argTypes; } - - public int getSize() { - throw new UnsupportedOperationException(); - } - - public String getSignature() { - if (signature == null) { - StringBuffer buf = new StringBuffer(); - buf.append('('); - for (int i = 0; i < argTypes.length; ++i) - buf.append(argTypes[i].getSignature()); - buf.append(')'); - buf.append(returnType.getSignature()); - signature = buf.toString(); - } - return signature; - } - - public int getTag() { return T_UNKNOWN; } - - public String toString() { - StringBuffer buf = new StringBuffer(); - buf.append('('); - for (int i = 0; i < argTypes.length; ++i) - buf.append(argTypes[i].toString()); - buf.append(')'); - buf.append(returnType.toString()); - return buf.toString(); - } - - public int getArgsSize() { - int size = 0; - for (int i = 0; i < argTypes.length; ++i) - size += argTypes[i].getSize(); - return size; - } - - public int getProducedStack() { - return returnType.getSize() - getArgsSize(); - } - - public boolean isCompatibleWith(JType other) { - return false; - } - public boolean equals(Object o) { - if (o instanceof JMethodType) - return ((JMethodType)o).getSignature().equals(this.getSignature()); - else - return false; - } - public int hashCode() { - if (signature == null) - return 0; - else - return signature.hashCode(); - } -} diff --git a/src/fjbg/ch/epfl/lamp/fjbg/JObjectType.java b/src/fjbg/ch/epfl/lamp/fjbg/JObjectType.java deleted file mode 100644 index 06db5b115a..0000000000 --- a/src/fjbg/ch/epfl/lamp/fjbg/JObjectType.java +++ /dev/null @@ -1,65 +0,0 @@ -/* FJBG -- Fast Java Bytecode Generator - * Copyright 2002-2013 LAMP/EPFL - * @author Michel Schinz - */ - -package ch.epfl.lamp.fjbg; - -/** - * Types for Java objects. - * - * @author Michel Schinz - * @version 1.0 - */ - -public class JObjectType extends JReferenceType { - protected final String name; - protected String signature = null; - - public final static JObjectType JAVA_LANG_OBJECT = - new JObjectType("java.lang.Object"); - public final static JObjectType JAVA_LANG_STRING = - new JObjectType("java.lang.String"); - public final static JObjectType CLONEABLE = - new JObjectType("Cloneable"); - public final static JObjectType JAVA_IO_SERIALIZABLE = - new JObjectType("java.io.Serializable"); - - public JObjectType(String name) { - this.name = name; - } - - public int getSize() { return 1; } - - public String getName() { return name; } - - public String getSignature() { - if (signature == null) - signature = "L" + name.replace('.','/') + ";"; - return signature; - } - - public String getDescriptor() { - return name.replace('.','/'); - } - - public int getTag() { return T_OBJECT; } - - public String toString() { return name; } - - public boolean isObjectType() { return true; } - - public boolean isCompatibleWith(JType other) { - return other instanceof JObjectType - || other == JType.REFERENCE; - } - public boolean equals(Object o) { - if (o instanceof JObjectType) - return ((JObjectType)o).getSignature().equals(this.getSignature()); - else - return false; - } - public int hashCode() { - return name.hashCode(); - } -} diff --git a/src/fjbg/ch/epfl/lamp/fjbg/JOpcode.java b/src/fjbg/ch/epfl/lamp/fjbg/JOpcode.java deleted file mode 100644 index cc68681a96..0000000000 --- a/src/fjbg/ch/epfl/lamp/fjbg/JOpcode.java +++ /dev/null @@ -1,1267 +0,0 @@ -/* FJBG -- Fast Java Bytecode Generator - * Copyright 2002-2013 LAMP/EPFL - * @author Michel Schinz - */ - -package ch.epfl.lamp.fjbg; - -/** - * Definition of opcodes for the JVM. - * - * @author Michel Schinz, Thomas Friedli - * @version 1.0 - */ - -public class JOpcode { - public final String name; - public final int code; - - // The following attributes can be (statically) unknown for some - // instructions, and are therefore not public. To know their value, - // functions have to be used (see JCodeIterator). - protected final int size; - protected final JType[] producedDataTypes; - protected final JType[] consumedDataTypes; - protected final int jumpKind; - protected final int successorCount; - - protected final static int UNKNOWN = Integer.MIN_VALUE; - - protected final static int JMP_NONE = 0; - protected final static int JMP_NEXT = 1; - protected final static int JMP_ALWAYS_S2_OFFSET = 2; - protected final static int JMP_ALWAYS_S4_OFFSET = 3; - protected final static int JMP_MAYBE_S2_OFFSET = 4; - protected final static int JMP_TABLE = 5; - protected final static int JMP_LOOKUP = 6; - - protected final static JType[] NO_DATA = new JType[0]; - - protected final static JType[] INT_TYPE = - new JType[] { JType.INT }; - protected final static JType[] FLOAT_TYPE = - new JType[] { JType.FLOAT }; - protected final static JType[] LONG_TYPE = - new JType[] { JType.LONG }; - protected final static JType[] DOUBLE_TYPE = - new JType[] { JType.DOUBLE }; - protected final static JType[] OBJECT_REF_TYPE = - new JType[] { JObjectType.JAVA_LANG_OBJECT }; - protected final static JType[] ARRAY_REF_TYPE = - new JType[] { new JArrayType(JType.VOID) }; - protected final static JType[] REFERENCE_TYPE = - new JType[] { JType.REFERENCE }; - protected final static JType[] ADDRESS_TYPE = - new JType[] { JType.ADDRESS }; - protected final static JType[] UNKNOWN_TYPE = - new JType[] { JType.UNKNOWN }; - - /// Instruction codes - public final static int cNOP = 0; - public final static int cACONST_NULL = 1; - public final static int cICONST_M1 = 2; - public final static int cICONST_0 = 3; - public final static int cICONST_1 = 4; - public final static int cICONST_2 = 5; - public final static int cICONST_3 = 6; - public final static int cICONST_4 = 7; - public final static int cICONST_5 = 8; - public final static int cLCONST_0 = 9; - public final static int cLCONST_1 = 10; - public final static int cFCONST_0 = 11; - public final static int cFCONST_1 = 12; - public final static int cFCONST_2 = 13; - public final static int cDCONST_0 = 14; - public final static int cDCONST_1 = 15; - public final static int cBIPUSH = 16; - public final static int cSIPUSH = 17; - public final static int cLDC = 18; - public final static int cLDC_W = 19; - public final static int cLDC2_W = 20; - public final static int cILOAD = 21; - public final static int cLLOAD = 22; - public final static int cFLOAD = 23; - public final static int cDLOAD = 24; - public final static int cALOAD = 25; - public final static int cILOAD_0 = 26; - public final static int cILOAD_1 = 27; - public final static int cILOAD_2 = 28; - public final static int cILOAD_3 = 29; - public final static int cLLOAD_0 = 30; - public final static int cLLOAD_1 = 31; - public final static int cLLOAD_2 = 32; - public final static int cLLOAD_3 = 33; - public final static int cFLOAD_0 = 34; - public final static int cFLOAD_1 = 35; - public final static int cFLOAD_2 = 36; - public final static int cFLOAD_3 = 37; - public final static int cDLOAD_0 = 38; - public final static int cDLOAD_1 = 39; - public final static int cDLOAD_2 = 40; - public final static int cDLOAD_3 = 41; - public final static int cALOAD_0 = 42; - public final static int cALOAD_1 = 43; - public final static int cALOAD_2 = 44; - public final static int cALOAD_3 = 45; - public final static int cIALOAD = 46; - public final static int cLALOAD = 47; - public final static int cFALOAD = 48; - public final static int cDALOAD = 49; - public final static int cAALOAD = 50; - public final static int cBALOAD = 51; - public final static int cCALOAD = 52; - public final static int cSALOAD = 53; - public final static int cISTORE = 54; - public final static int cLSTORE = 55; - public final static int cFSTORE = 56; - public final static int cDSTORE = 57; - public final static int cASTORE = 58; - public final static int cISTORE_0 = 59; - public final static int cISTORE_1 = 60; - public final static int cISTORE_2 = 61; - public final static int cISTORE_3 = 62; - public final static int cLSTORE_0 = 63; - public final static int cLSTORE_1 = 64; - public final static int cLSTORE_2 = 65; - public final static int cLSTORE_3 = 66; - public final static int cFSTORE_0 = 67; - public final static int cFSTORE_1 = 68; - public final static int cFSTORE_2 = 69; - public final static int cFSTORE_3 = 70; - public final static int cDSTORE_0 = 71; - public final static int cDSTORE_1 = 72; - public final static int cDSTORE_2 = 73; - public final static int cDSTORE_3 = 74; - public final static int cASTORE_0 = 75; - public final static int cASTORE_1 = 76; - public final static int cASTORE_2 = 77; - public final static int cASTORE_3 = 78; - public final static int cIASTORE = 79; - public final static int cLASTORE = 80; - public final static int cFASTORE = 81; - public final static int cDASTORE = 82; - public final static int cAASTORE = 83; - public final static int cBASTORE = 84; - public final static int cCASTORE = 85; - public final static int cSASTORE = 86; - public final static int cPOP = 87; - public final static int cPOP2 = 88; - public final static int cDUP = 89; - public final static int cDUP_X1 = 90; - public final static int cDUP_X2 = 91; - public final static int cDUP2 = 92; - public final static int cDUP2_X1 = 93; - public final static int cDUP2_X2 = 94; - public final static int cSWAP = 95; - public final static int cIADD = 96; - public final static int cLADD = 97; - public final static int cFADD = 98; - public final static int cDADD = 99; - public final static int cISUB = 100; - public final static int cLSUB = 101; - public final static int cFSUB = 102; - public final static int cDSUB = 103; - public final static int cIMUL = 104; - public final static int cLMUL = 105; - public final static int cFMUL = 106; - public final static int cDMUL = 107; - public final static int cIDIV = 108; - public final static int cLDIV = 109; - public final static int cFDIV = 110; - public final static int cDDIV = 111; - public final static int cIREM = 112; - public final static int cLREM = 113; - public final static int cFREM = 114; - public final static int cDREM = 115; - public final static int cINEG = 116; - public final static int cLNEG = 117; - public final static int cFNEG = 118; - public final static int cDNEG = 119; - public final static int cISHL = 120; - public final static int cLSHL = 121; - public final static int cISHR = 122; - public final static int cLSHR = 123; - public final static int cIUSHR = 124; - public final static int cLUSHR = 125; - public final static int cIAND = 126; - public final static int cLAND = 127; - public final static int cIOR = 128; - public final static int cLOR = 129; - public final static int cIXOR = 130; - public final static int cLXOR = 131; - public final static int cIINC = 132; - public final static int cI2L = 133; - public final static int cI2F = 134; - public final static int cI2D = 135; - public final static int cL2I = 136; - public final static int cL2F = 137; - public final static int cL2D = 138; - public final static int cF2I = 139; - public final static int cF2L = 140; - public final static int cF2D = 141; - public final static int cD2I = 142; - public final static int cD2L = 143; - public final static int cD2F = 144; - public final static int cI2B = 145; - public final static int cI2C = 146; - public final static int cI2S = 147; - public final static int cLCMP = 148; - public final static int cFCMPL = 149; - public final static int cFCMPG = 150; - public final static int cDCMPL = 151; - public final static int cDCMPG = 152; - public final static int cIFEQ = 153; - public final static int cIFNE = 154; - public final static int cIFLT = 155; - public final static int cIFGE = 156; - public final static int cIFGT = 157; - public final static int cIFLE = 158; - public final static int cIF_ICMPEQ = 159; - public final static int cIF_ICMPNE = 160; - public final static int cIF_ICMPLT = 161; - public final static int cIF_ICMPGE = 162; - public final static int cIF_ICMPGT = 163; - public final static int cIF_ICMPLE = 164; - public final static int cIF_ACMPEQ = 165; - public final static int cIF_ACMPNE = 166; - public final static int cGOTO = 167; - public final static int cJSR = 168; - public final static int cRET = 169; - public final static int cTABLESWITCH = 170; - public final static int cLOOKUPSWITCH = 171; - public final static int cIRETURN = 172; - public final static int cLRETURN = 173; - public final static int cFRETURN = 174; - public final static int cDRETURN = 175; - public final static int cARETURN = 176; - public final static int cRETURN = 177; - public final static int cGETSTATIC = 178; - public final static int cPUTSTATIC = 179; - public final static int cGETFIELD = 180; - public final static int cPUTFIELD = 181; - public final static int cINVOKEVIRTUAL = 182; - public final static int cINVOKESPECIAL = 183; - public final static int cINVOKESTATIC = 184; - public final static int cINVOKEINTERFACE = 185; - public final static int cNEW = 187; - public final static int cNEWARRAY = 188; - public final static int cANEWARRAY = 189; - public final static int cARRAYLENGTH = 190; - public final static int cATHROW = 191; - public final static int cCHECKCAST = 192; - public final static int cINSTANCEOF = 193; - public final static int cMONITORENTER = 194; - public final static int cMONITOREXIT = 195; - public final static int cWIDE = 196; - public final static int cMULTIANEWARRAY = 197; - public final static int cIFNULL = 198; - public final static int cIFNONNULL = 199; - public final static int cGOTO_W = 200; - public final static int cJSR_W = 201; - - // Objects representing instructions - public final static JOpcode NOP = - new JOpcode("NOP", cNOP, 1, NO_DATA, NO_DATA, JMP_NEXT); - public final static JOpcode ACONST_NULL = new JOpcode("ACONST_NULL", - cACONST_NULL, - 1, - REFERENCE_TYPE, - NO_DATA, - JMP_NEXT); - public final static JOpcode ICONST_M1 = - new JOpcode("ICONST_M1", cICONST_M1, 1, INT_TYPE, NO_DATA, JMP_NEXT); - public final static JOpcode ICONST_0 = - new JOpcode("ICONST_0", cICONST_0, 1, INT_TYPE, NO_DATA, JMP_NEXT); - public final static JOpcode ICONST_1 = - new JOpcode("ICONST_1", cICONST_1, 1, INT_TYPE, NO_DATA, JMP_NEXT); - public final static JOpcode ICONST_2 = - new JOpcode("ICONST_2", cICONST_2, 1, INT_TYPE, NO_DATA, JMP_NEXT); - public final static JOpcode ICONST_3 = - new JOpcode("ICONST_3", cICONST_3, 1, INT_TYPE, NO_DATA, JMP_NEXT); - public final static JOpcode ICONST_4 = - new JOpcode("ICONST_4", cICONST_4, 1, INT_TYPE, NO_DATA, JMP_NEXT); - public final static JOpcode ICONST_5 = - new JOpcode("ICONST_5", cICONST_5, 1, INT_TYPE, NO_DATA, JMP_NEXT); - public final static JOpcode LCONST_0 = - new JOpcode("LCONST_0", cLCONST_0, 1, LONG_TYPE, NO_DATA, JMP_NEXT); - public final static JOpcode LCONST_1 = - new JOpcode("LCONST_1", cLCONST_1, 1, LONG_TYPE, NO_DATA, JMP_NEXT); - public final static JOpcode FCONST_0 = - new JOpcode("FCONST_0", cFCONST_0, 1, FLOAT_TYPE, NO_DATA, JMP_NEXT); - public final static JOpcode FCONST_1 = - new JOpcode("FCONST_1", cFCONST_1, 1, FLOAT_TYPE, NO_DATA, JMP_NEXT); - public final static JOpcode FCONST_2 = - new JOpcode("FCONST_2", cFCONST_2, 1, FLOAT_TYPE, NO_DATA, JMP_NEXT); - public final static JOpcode DCONST_0 = - new JOpcode("DCONST_0", cDCONST_0, 1, DOUBLE_TYPE, NO_DATA, JMP_NEXT); - public final static JOpcode DCONST_1 = - new JOpcode("DCONST_1", cDCONST_1, 1, DOUBLE_TYPE, NO_DATA, JMP_NEXT); - public final static JOpcode BIPUSH = - new JOpcode("BIPUSH", cBIPUSH, 2, INT_TYPE, NO_DATA, JMP_NEXT); - public final static JOpcode SIPUSH = - new JOpcode("SIPUSH", cSIPUSH, 3, INT_TYPE, NO_DATA, JMP_NEXT); - public final static JOpcode LDC = - new JOpcode("LDC", cLDC, 2, UNKNOWN_TYPE, NO_DATA, JMP_NEXT); - public final static JOpcode LDC_W = - new JOpcode("LDC_W", cLDC_W, 3, UNKNOWN_TYPE, NO_DATA, JMP_NEXT); - public final static JOpcode LDC2_W = - new JOpcode("LDC2_W", cLDC2_W, 3, UNKNOWN_TYPE, NO_DATA, JMP_NEXT); - public final static JOpcode ILOAD = - new JOpcode("ILOAD", cILOAD, 2, INT_TYPE, NO_DATA, JMP_NEXT); - public final static JOpcode LLOAD = - new JOpcode("LLOAD", cLLOAD, 2, LONG_TYPE, NO_DATA, JMP_NEXT); - public final static JOpcode FLOAD = - new JOpcode("FLOAD", cFLOAD, 2, FLOAT_TYPE, NO_DATA, JMP_NEXT); - public final static JOpcode DLOAD = - new JOpcode("DLOAD", cDLOAD, 2, DOUBLE_TYPE, NO_DATA, JMP_NEXT); - public final static JOpcode ALOAD = - new JOpcode("ALOAD", cALOAD, 2, REFERENCE_TYPE, NO_DATA, JMP_NEXT); - public final static JOpcode ILOAD_0 = - new JOpcode("ILOAD_0", cILOAD_0, 1, INT_TYPE, NO_DATA, JMP_NEXT); - public final static JOpcode ILOAD_1 = - new JOpcode("ILOAD_1", cILOAD_1, 1, INT_TYPE, NO_DATA, JMP_NEXT); - public final static JOpcode ILOAD_2 = - new JOpcode("ILOAD_2", cILOAD_2, 1, INT_TYPE, NO_DATA, JMP_NEXT); - public final static JOpcode ILOAD_3 = - new JOpcode("ILOAD_3", cILOAD_3, 1, INT_TYPE, NO_DATA, JMP_NEXT); - public final static JOpcode LLOAD_0 = - new JOpcode("LLOAD_0", cLLOAD_0, 1, LONG_TYPE, NO_DATA, JMP_NEXT); - public final static JOpcode LLOAD_1 = - new JOpcode("LLOAD_1", cLLOAD_1, 1, LONG_TYPE, NO_DATA, JMP_NEXT); - public final static JOpcode LLOAD_2 = - new JOpcode("LLOAD_2", cLLOAD_2, 1, LONG_TYPE, NO_DATA, JMP_NEXT); - public final static JOpcode LLOAD_3 = - new JOpcode("LLOAD_3", cLLOAD_3, 1, LONG_TYPE, NO_DATA, JMP_NEXT); - public final static JOpcode FLOAD_0 = - new JOpcode("FLOAD_0", cFLOAD_0, 1, FLOAT_TYPE, NO_DATA, JMP_NEXT); - public final static JOpcode FLOAD_1 = - new JOpcode("FLOAD_1", cFLOAD_1, 1, FLOAT_TYPE, NO_DATA, JMP_NEXT); - public final static JOpcode FLOAD_2 = - new JOpcode("FLOAD_2", cFLOAD_2, 1, FLOAT_TYPE, NO_DATA, JMP_NEXT); - public final static JOpcode FLOAD_3 = - new JOpcode("FLOAD_3", cFLOAD_3, 1, FLOAT_TYPE, NO_DATA, JMP_NEXT); - public final static JOpcode DLOAD_0 = - new JOpcode("DLOAD_0", cDLOAD_0, 1, DOUBLE_TYPE, NO_DATA, JMP_NEXT); - public final static JOpcode DLOAD_1 = - new JOpcode("DLOAD_1", cDLOAD_1, 1, DOUBLE_TYPE, NO_DATA, JMP_NEXT); - public final static JOpcode DLOAD_2 = - new JOpcode("DLOAD_2", cDLOAD_2, 1, DOUBLE_TYPE, NO_DATA, JMP_NEXT); - public final static JOpcode DLOAD_3 = - new JOpcode("DLOAD_3", cDLOAD_3, 1, DOUBLE_TYPE, NO_DATA, JMP_NEXT); - public final static JOpcode ALOAD_0 = - new JOpcode("ALOAD_0", cALOAD_0, 1, REFERENCE_TYPE, NO_DATA, JMP_NEXT); - public final static JOpcode ALOAD_1 = - new JOpcode("ALOAD_1", cALOAD_1, 1, REFERENCE_TYPE, NO_DATA, JMP_NEXT); - public final static JOpcode ALOAD_2 = - new JOpcode("ALOAD_2", cALOAD_2, 1, REFERENCE_TYPE, NO_DATA, JMP_NEXT); - public final static JOpcode ALOAD_3 = - new JOpcode("ALOAD_3", cALOAD_3, 1, REFERENCE_TYPE, NO_DATA, JMP_NEXT); - public final static JOpcode IALOAD = - new JOpcode("IALOAD", - cIALOAD, - 1, - INT_TYPE, - new JType[] {JType.INT, JArrayType.INT}, - JMP_NEXT); - public final static JOpcode LALOAD = - new JOpcode("LALOAD", - cLALOAD, - 1, - LONG_TYPE, - new JType[] {JType.INT, JArrayType.LONG}, - JMP_NEXT); - public final static JOpcode FALOAD = - new JOpcode("FALOAD", - cFALOAD, - 1, - FLOAT_TYPE, - new JType[] {JType.INT, JArrayType.FLOAT}, - JMP_NEXT); - public final static JOpcode DALOAD = - new JOpcode("DALOAD", - cDALOAD, - 1, - DOUBLE_TYPE, - new JType[] {JType.INT, JArrayType.DOUBLE}, - JMP_NEXT); - public final static JOpcode AALOAD = - new JOpcode("AALOAD", - cAALOAD, - 1, - REFERENCE_TYPE, - new JType[] {JType.INT, JArrayType.REFERENCE}, - JMP_NEXT); - public final static JOpcode BALOAD = - new JOpcode("BALOAD", - cBALOAD, - 1, - INT_TYPE, - new JType[] {JType.INT, new JArrayType(JType.UNKNOWN)}, - JMP_NEXT); - public final static JOpcode CALOAD = - new JOpcode("CALOAD", - cCALOAD, - 1, - INT_TYPE, - new JType[] {JType.INT, JArrayType.CHAR}, - JMP_NEXT); - public final static JOpcode SALOAD = - new JOpcode("SALOAD", - cSALOAD, - 1, - INT_TYPE, - new JType[] {JType.INT, JArrayType.SHORT}, - JMP_NEXT); - public final static JOpcode ISTORE = - new JOpcode("ISTORE", cISTORE, 2, NO_DATA, INT_TYPE, JMP_NEXT); - public final static JOpcode LSTORE = - new JOpcode("LSTORE", cLSTORE, 2, NO_DATA, LONG_TYPE, JMP_NEXT); - public final static JOpcode FSTORE = - new JOpcode("FSTORE", cFSTORE, 2, NO_DATA, FLOAT_TYPE, JMP_NEXT); - public final static JOpcode DSTORE = - new JOpcode("DSTORE", cDSTORE, 2, NO_DATA, DOUBLE_TYPE, JMP_NEXT); - public final static JOpcode ASTORE = - new JOpcode("ASTORE", cASTORE, 2, NO_DATA, REFERENCE_TYPE, JMP_NEXT); - public final static JOpcode ISTORE_0 = - new JOpcode("ISTORE_0", cISTORE_0, 1, NO_DATA, INT_TYPE, JMP_NEXT); - public final static JOpcode ISTORE_1 = - new JOpcode("ISTORE_1", cISTORE_1, 1, NO_DATA, INT_TYPE, JMP_NEXT); - public final static JOpcode ISTORE_2 = - new JOpcode("ISTORE_2", cISTORE_2, 1, NO_DATA, INT_TYPE, JMP_NEXT); - public final static JOpcode ISTORE_3 = - new JOpcode("ISTORE_3", cISTORE_3, 1, NO_DATA, INT_TYPE, JMP_NEXT); - public final static JOpcode LSTORE_0 = - new JOpcode("LSTORE_0", cLSTORE_0, 1, NO_DATA, LONG_TYPE, JMP_NEXT); - public final static JOpcode LSTORE_1 = - new JOpcode("LSTORE_1", cLSTORE_1, 1, NO_DATA, LONG_TYPE, JMP_NEXT); - public final static JOpcode LSTORE_2 = - new JOpcode("LSTORE_2", cLSTORE_2, 1, NO_DATA, LONG_TYPE, JMP_NEXT); - public final static JOpcode LSTORE_3 = - new JOpcode("LSTORE_3", cLSTORE_3, 1, NO_DATA, LONG_TYPE, JMP_NEXT); - public final static JOpcode FSTORE_0 = - new JOpcode("FSTORE_0", cFSTORE_0, 1, NO_DATA, FLOAT_TYPE, JMP_NEXT); - public final static JOpcode FSTORE_1 = - new JOpcode("FSTORE_1", cFSTORE_1, 1, NO_DATA, FLOAT_TYPE, JMP_NEXT); - public final static JOpcode FSTORE_2 = - new JOpcode("FSTORE_2", cFSTORE_2, 1, NO_DATA, FLOAT_TYPE, JMP_NEXT); - public final static JOpcode FSTORE_3 = - new JOpcode("FSTORE_3", cFSTORE_3, 1, NO_DATA, FLOAT_TYPE, JMP_NEXT); - public final static JOpcode DSTORE_0 = - new JOpcode("DSTORE_0", cDSTORE_0, 1, NO_DATA, DOUBLE_TYPE, JMP_NEXT); - public final static JOpcode DSTORE_1 = - new JOpcode("DSTORE_1", cDSTORE_1, 1, NO_DATA, DOUBLE_TYPE, JMP_NEXT); - public final static JOpcode DSTORE_2 = - new JOpcode("DSTORE_2", cDSTORE_2, 1, NO_DATA, DOUBLE_TYPE, JMP_NEXT); - public final static JOpcode DSTORE_3 = - new JOpcode("DSTORE_3", cDSTORE_3, 1, NO_DATA, DOUBLE_TYPE, JMP_NEXT); - public final static JOpcode ASTORE_0 = new JOpcode("ASTORE_0", - cASTORE_0, - 1, - NO_DATA, - REFERENCE_TYPE, - JMP_NEXT); - public final static JOpcode ASTORE_1 = new JOpcode("ASTORE_1", - cASTORE_1, - 1, - NO_DATA, - REFERENCE_TYPE, - JMP_NEXT); - public final static JOpcode ASTORE_2 = new JOpcode("ASTORE_2", - cASTORE_2, - 1, - NO_DATA, - REFERENCE_TYPE, - JMP_NEXT); - public final static JOpcode ASTORE_3 = new JOpcode("ASTORE_3", - cASTORE_3, - 1, - NO_DATA, - REFERENCE_TYPE, - JMP_NEXT); - public final static JOpcode IASTORE = - new JOpcode("IASTORE", - cIASTORE, - 1, - NO_DATA, - new JType[] { JType.INT, - JType.INT, - JArrayType.INT}, - JMP_NEXT); - public final static JOpcode LASTORE = - new JOpcode("LASTORE", - cLASTORE, - 1, - NO_DATA, - new JType[] { JType.LONG, - JType.INT, - JArrayType.LONG}, - JMP_NEXT); - public final static JOpcode FASTORE = - new JOpcode("FASTORE", - cFASTORE, - 1, - NO_DATA, - new JType[] { JType.FLOAT, - JType.INT, - JArrayType.FLOAT}, - JMP_NEXT); - public final static JOpcode DASTORE = - new JOpcode("DASTORE", - cDASTORE, - 1, - NO_DATA, - new JType[] { JType.DOUBLE, - JType.INT, - JArrayType.DOUBLE}, - JMP_NEXT); - public final static JOpcode AASTORE = - new JOpcode("AASTORE", - cAASTORE, - 1, - NO_DATA, - new JType[] { JType.REFERENCE, - JType.INT, - JArrayType.REFERENCE}, - JMP_NEXT); - public final static JOpcode BASTORE = - new JOpcode("BASTORE", - cBASTORE, - 1, - NO_DATA, - new JType[] { JType.INT, - JType.INT, - new JArrayType(JType.UNKNOWN)}, - JMP_NEXT); - public final static JOpcode CASTORE = - new JOpcode("CASTORE", - cCASTORE, - 1, - NO_DATA, - new JType[] { JType.INT, - JType.INT, - JArrayType.CHAR}, - JMP_NEXT); - public final static JOpcode SASTORE = - new JOpcode("SASTORE", - cSASTORE, - 1, - NO_DATA, - new JType[] { JType.INT, - JType.INT, - JArrayType.SHORT}, - JMP_NEXT); - public final static JOpcode POP = - new JOpcode("POP", cPOP, 1, NO_DATA, UNKNOWN_TYPE, JMP_NEXT); - public final static JOpcode POP2 = - new JOpcode("POP2", cPOP2, 1, NO_DATA, UNKNOWN_TYPE, JMP_NEXT); - public final static JOpcode DUP = - new JOpcode("DUP", cDUP, 1, UNKNOWN_TYPE, UNKNOWN_TYPE, JMP_NEXT); - public final static JOpcode DUP_X1 = new JOpcode("DUP_X1", - cDUP_X1, - 1, - UNKNOWN_TYPE, - UNKNOWN_TYPE, - JMP_NEXT); - public final static JOpcode DUP_X2 = new JOpcode("DUP_X2", - cDUP_X2, - 1, - UNKNOWN_TYPE, - UNKNOWN_TYPE, - JMP_NEXT); - public final static JOpcode DUP2 = - new JOpcode("DUP2", cDUP2, 1, UNKNOWN_TYPE, UNKNOWN_TYPE, JMP_NEXT); - public final static JOpcode DUP2_X1 = new JOpcode("DUP2_X1", - cDUP2_X1, - 1, - UNKNOWN_TYPE, - UNKNOWN_TYPE, - JMP_NEXT); - public final static JOpcode DUP2_X2 = new JOpcode("DUP2_X2", - cDUP2_X2, - 1, - UNKNOWN_TYPE, - UNKNOWN_TYPE, - JMP_NEXT); - public final static JOpcode SWAP = - new JOpcode("SWAP", cSWAP, 1, UNKNOWN_TYPE, UNKNOWN_TYPE, JMP_NEXT); - public final static JOpcode IADD = - new JOpcode("IADD", - cIADD, - 1, - INT_TYPE, - new JType[] { JType.INT, JType.INT }, - JMP_NEXT); - public final static JOpcode LADD = - new JOpcode("LADD", - cLADD, - 1, - LONG_TYPE, - new JType[] { JType.LONG, JType.LONG }, - JMP_NEXT); - public final static JOpcode FADD = - new JOpcode("FADD", - cFADD, - 1, - FLOAT_TYPE, - new JType[] { JType.FLOAT, JType.FLOAT }, - JMP_NEXT); - public final static JOpcode DADD = - new JOpcode("DADD", - cDADD, - 1, - DOUBLE_TYPE, - new JType[] { JType.DOUBLE, JType.DOUBLE }, - JMP_NEXT); - public final static JOpcode ISUB = - new JOpcode("ISUB", - cISUB, - 1, - INT_TYPE, - new JType[] {JType.INT, JType.INT }, - JMP_NEXT); - public final static JOpcode LSUB = - new JOpcode("LSUB", - cLSUB, - 1, - LONG_TYPE, - new JType[] { JType.LONG, JType.LONG }, - JMP_NEXT); - public final static JOpcode FSUB = - new JOpcode("FSUB", - cFSUB, - 1, - FLOAT_TYPE, - new JType[] { JType.FLOAT, JType.FLOAT }, - JMP_NEXT); - public final static JOpcode DSUB = - new JOpcode("DSUB", - cDSUB, - 1, - DOUBLE_TYPE, - new JType[] { JType.DOUBLE, JType.DOUBLE }, - JMP_NEXT); - public final static JOpcode IMUL = - new JOpcode("IMUL", - cIMUL, - 1, - INT_TYPE, - new JType[] {JType.INT, JType.INT }, - JMP_NEXT); - public final static JOpcode LMUL = - new JOpcode("LMUL", - cLMUL, - 1, - LONG_TYPE, - new JType[] { JType.LONG, JType.LONG }, - JMP_NEXT); - public final static JOpcode FMUL = - new JOpcode("FMUL", - cFMUL, - 1, - FLOAT_TYPE, - new JType[] { JType.FLOAT, JType.FLOAT }, - JMP_NEXT); - public final static JOpcode DMUL = - new JOpcode("DMUL", - cDMUL, - 1, - DOUBLE_TYPE, - new JType[] { JType.DOUBLE, JType.DOUBLE }, - JMP_NEXT); - public final static JOpcode IDIV = - new JOpcode("IDIV", - cIDIV, - 1, - INT_TYPE, - new JType[] {JType.INT, JType.INT }, - JMP_NEXT); - public final static JOpcode LDIV = - new JOpcode("LDIV", - cLDIV, - 1, - LONG_TYPE, - new JType[] { JType.LONG, JType.LONG }, - JMP_NEXT); - public final static JOpcode FDIV = - new JOpcode("FDIV", - cFDIV, - 1, - FLOAT_TYPE, - new JType[] { JType.FLOAT, JType.FLOAT }, - JMP_NEXT); - public final static JOpcode DDIV = - new JOpcode("DDIV", - cDDIV, - 1, - DOUBLE_TYPE, - new JType[] { JType.DOUBLE, JType.DOUBLE }, - JMP_NEXT); - public final static JOpcode IREM = - new JOpcode("IREM", - cIREM, - 1, - INT_TYPE, - new JType[] {JType.INT, JType.INT }, - JMP_NEXT); - public final static JOpcode LREM = - new JOpcode("LREM", - cLREM, - 1, - LONG_TYPE, - new JType[] { JType.LONG, JType.LONG }, - JMP_NEXT); - public final static JOpcode FREM = - new JOpcode("FREM", - cFREM, - 1, - FLOAT_TYPE, - new JType[] { JType.FLOAT, JType.FLOAT }, - JMP_NEXT); - public final static JOpcode DREM = - new JOpcode("DREM", - cDREM, - 1, - DOUBLE_TYPE, - new JType[] { JType.DOUBLE, JType.DOUBLE }, - JMP_NEXT); - public final static JOpcode INEG = - new JOpcode("INEG", cINEG, 1, INT_TYPE, INT_TYPE, JMP_NEXT); - public final static JOpcode LNEG = - new JOpcode("LNEG", cLNEG, 1, LONG_TYPE, LONG_TYPE, JMP_NEXT); - public final static JOpcode FNEG = - new JOpcode("FNEG", cFNEG, 1, FLOAT_TYPE, FLOAT_TYPE, JMP_NEXT); - public final static JOpcode DNEG = - new JOpcode("DNEG", cDNEG, 1, DOUBLE_TYPE, DOUBLE_TYPE, JMP_NEXT); - public final static JOpcode ISHL = - new JOpcode("ISHL", cISHL, - 1, - INT_TYPE, - new JType[] { JType.INT, JType.INT }, - JMP_NEXT); - public final static JOpcode LSHL = - new JOpcode("LSHL", - cLSHL, - 1, - LONG_TYPE, - new JType [] { JType.INT, JType.LONG }, - JMP_NEXT); - public final static JOpcode ISHR = - new JOpcode("ISHR", - cISHR, - 1, - INT_TYPE, - new JType[] { JType.INT, JType.INT }, - JMP_NEXT); - public final static JOpcode LSHR = - new JOpcode("LSHR", - cLSHR, - 1, - LONG_TYPE, - new JType[] { JType.INT, JType.LONG }, - JMP_NEXT); - public final static JOpcode IUSHR = - new JOpcode("IUSHR", - cIUSHR, - 1, - INT_TYPE, - new JType[] { JType.INT, JType.INT }, - JMP_NEXT); - public final static JOpcode LUSHR = - new JOpcode("LUSHR", - cLUSHR, - 1, - LONG_TYPE, - new JType[] { JType.INT, JType.LONG }, - JMP_NEXT); - public final static JOpcode IAND = - new JOpcode("IAND", - cIAND, - 1, - INT_TYPE, - new JType[] { JType.INT, JType.INT }, - JMP_NEXT); - public final static JOpcode LAND = - new JOpcode("LAND", - cLAND, - 1, - LONG_TYPE, - new JType[] { JType.LONG, JType.LONG }, - JMP_NEXT); - public final static JOpcode IOR = - new JOpcode("IOR", - cIOR, - 1, - INT_TYPE, - new JType[] { JType.INT, JType.INT }, - JMP_NEXT); - public final static JOpcode LOR = - new JOpcode("LOR", - cLOR, - 1, - LONG_TYPE, - new JType[] { JType.LONG, JType.LONG }, - JMP_NEXT); - public final static JOpcode IXOR = - new JOpcode("IXOR", - cIXOR, - 1, - INT_TYPE, - new JType[] { JType.INT, JType.INT }, - JMP_NEXT); - public final static JOpcode LXOR = - new JOpcode("LXOR", - cLXOR, - 1, - LONG_TYPE, - new JType[] { JType.LONG, JType.LONG }, - JMP_NEXT); - public final static JOpcode IINC = - new JOpcode("IINC", cIINC, 3, NO_DATA, NO_DATA, JMP_NEXT); - public final static JOpcode I2L = - new JOpcode("I2L", cI2L, 1, LONG_TYPE, INT_TYPE, JMP_NEXT); - public final static JOpcode I2F = - new JOpcode("I2F", cI2F, 1, FLOAT_TYPE, INT_TYPE, JMP_NEXT); - public final static JOpcode I2D = - new JOpcode("I2D", cI2D, 1, DOUBLE_TYPE, INT_TYPE, JMP_NEXT); - public final static JOpcode L2I = - new JOpcode("L2I", cL2I, 1, INT_TYPE, LONG_TYPE, JMP_NEXT); - public final static JOpcode L2F = - new JOpcode("L2F", cL2F, 1, FLOAT_TYPE, LONG_TYPE, JMP_NEXT); - public final static JOpcode L2D = - new JOpcode("L2D", cL2D, 1, DOUBLE_TYPE, LONG_TYPE, JMP_NEXT); - public final static JOpcode F2I = - new JOpcode("F2I", cF2I, 1, INT_TYPE, FLOAT_TYPE, JMP_NEXT); - public final static JOpcode F2L = - new JOpcode("F2L", cF2L, 1, LONG_TYPE, FLOAT_TYPE, JMP_NEXT); - public final static JOpcode F2D = - new JOpcode("F2D", cF2D, 1, DOUBLE_TYPE, FLOAT_TYPE, JMP_NEXT); - public final static JOpcode D2I = - new JOpcode("D2I", cD2I, 1, INT_TYPE, DOUBLE_TYPE, JMP_NEXT); - public final static JOpcode D2L = - new JOpcode("D2L", cD2L, 1, LONG_TYPE, DOUBLE_TYPE, JMP_NEXT); - public final static JOpcode D2F = - new JOpcode("D2F", cD2F, 1, FLOAT_TYPE, DOUBLE_TYPE, JMP_NEXT); - public final static JOpcode I2B = - new JOpcode("I2B", cI2B, 1, INT_TYPE, INT_TYPE, JMP_NEXT); - public final static JOpcode I2C = - new JOpcode("I2C", cI2C, 1, INT_TYPE, INT_TYPE, JMP_NEXT); - public final static JOpcode I2S = - new JOpcode("I2S", cI2S, 1, INT_TYPE, INT_TYPE, JMP_NEXT); - public final static JOpcode LCMP = - new JOpcode("LCMP", - cLCMP, - 1, - INT_TYPE, - new JType[] { JType.LONG, JType.LONG }, - JMP_NEXT); - public final static JOpcode FCMPL = - new JOpcode("FCMPL", - cFCMPL, - 1, - INT_TYPE, - new JType[] { JType.FLOAT, JType.FLOAT }, - JMP_NEXT); - public final static JOpcode FCMPG = - new JOpcode("FCMPG", - cFCMPG, - 1, - INT_TYPE, - new JType[] { JType.FLOAT, JType.FLOAT }, - JMP_NEXT); - public final static JOpcode DCMPL = - new JOpcode("DCMPL", - cDCMPL, - 1, - INT_TYPE, - new JType[] { JType.LONG, JType.LONG }, - JMP_NEXT); - public final static JOpcode DCMPG = - new JOpcode("DCMPG", - cDCMPG, - 1, - INT_TYPE, - new JType[] { JType.DOUBLE, JType.DOUBLE }, - JMP_NEXT); - public final static JOpcode IFEQ = - new JOpcode("IFEQ", cIFEQ, 3, NO_DATA, INT_TYPE, JMP_MAYBE_S2_OFFSET); - public final static JOpcode IFNE = - new JOpcode("IFNE", cIFNE, 3, NO_DATA, INT_TYPE, JMP_MAYBE_S2_OFFSET); - public final static JOpcode IFLT = - new JOpcode("IFLT", cIFLT, 3, NO_DATA, INT_TYPE, JMP_MAYBE_S2_OFFSET); - public final static JOpcode IFGE = - new JOpcode("IFGE", cIFGE, 3, NO_DATA, INT_TYPE, JMP_MAYBE_S2_OFFSET); - public final static JOpcode IFGT = - new JOpcode("IFGT", cIFGT, 3, NO_DATA, INT_TYPE, JMP_MAYBE_S2_OFFSET); - public final static JOpcode IFLE = - new JOpcode("IFLE", cIFLE, 3, NO_DATA, INT_TYPE, JMP_MAYBE_S2_OFFSET); - public final static JOpcode IF_ICMPEQ = - new JOpcode("IF_ICMPEQ", - cIF_ICMPEQ, - 3, - NO_DATA, - new JType[] { JType.INT, JType.INT }, - JMP_MAYBE_S2_OFFSET); - public final static JOpcode IF_ICMPNE = - new JOpcode("IF_ICMPNE", - cIF_ICMPNE, - 3, - NO_DATA, - new JType[] { JType.INT, JType.INT }, - JMP_MAYBE_S2_OFFSET); - public final static JOpcode IF_ICMPLT = - new JOpcode("IF_ICMPLT", - cIF_ICMPLT, - 3, - NO_DATA, - new JType[] { JType.INT, JType.INT }, - JMP_MAYBE_S2_OFFSET); - public final static JOpcode IF_ICMPGE = - new JOpcode("IF_ICMPGE", - cIF_ICMPGE, - 3, - NO_DATA, - new JType[] { JType.INT, JType.INT }, - JMP_MAYBE_S2_OFFSET); - public final static JOpcode IF_ICMPGT = - new JOpcode("IF_ICMPGT", - cIF_ICMPGT, - 3, - NO_DATA, - new JType[] { JType.INT, JType.INT }, - JMP_MAYBE_S2_OFFSET); - public final static JOpcode IF_ICMPLE = - new JOpcode("IF_ICMPLE", - cIF_ICMPLE, - 3, - NO_DATA, - new JType[] { JType.INT, JType.INT }, - JMP_MAYBE_S2_OFFSET); - public final static JOpcode IF_ACMPEQ = - new JOpcode("IF_ACMPEQ", - cIF_ACMPEQ, - 3, - NO_DATA, - new JType[] { JType.REFERENCE, JType.REFERENCE }, - JMP_MAYBE_S2_OFFSET); - public final static JOpcode IF_ACMPNE = - new JOpcode("IF_ACMPNE", - cIF_ACMPNE, - 3, - NO_DATA, - new JType[] { JType.REFERENCE, JType.REFERENCE }, - JMP_MAYBE_S2_OFFSET); - public final static JOpcode GOTO = - new JOpcode("GOTO", cGOTO, 3, NO_DATA, NO_DATA, JMP_ALWAYS_S2_OFFSET); - public final static JOpcode JSR = - new JOpcode("JSR", cJSR, 3, ADDRESS_TYPE, NO_DATA, JMP_ALWAYS_S2_OFFSET); - public final static JOpcode RET = - new JOpcode("RET", cRET, 2, NO_DATA, NO_DATA, JMP_NONE); - public final static JOpcode TABLESWITCH = new JOpcode("TABLESWITCH", - cTABLESWITCH, - UNKNOWN, - NO_DATA, - INT_TYPE, - JMP_TABLE); - public final static JOpcode LOOKUPSWITCH = new JOpcode("LOOKUPSWITCH", - cLOOKUPSWITCH, - UNKNOWN, - NO_DATA, - INT_TYPE, - JMP_LOOKUP); - public final static JOpcode IRETURN = - new JOpcode("IRETURN", cIRETURN, 1, NO_DATA, INT_TYPE, JMP_NONE); - public final static JOpcode LRETURN = - new JOpcode("LRETURN", cLRETURN, 1, NO_DATA, LONG_TYPE, JMP_NONE); - public final static JOpcode FRETURN = - new JOpcode("FRETURN", cFRETURN, 1, NO_DATA, FLOAT_TYPE, JMP_NONE); - public final static JOpcode DRETURN = - new JOpcode("DRETURN", cDRETURN, 1, NO_DATA, DOUBLE_TYPE, JMP_NONE); - public final static JOpcode ARETURN = new JOpcode("ARETURN", - cARETURN, - 1, - NO_DATA, - OBJECT_REF_TYPE, - JMP_NONE); - public final static JOpcode RETURN = - new JOpcode("RETURN", cRETURN, 1, NO_DATA, NO_DATA, JMP_NONE); - public final static JOpcode GETSTATIC = new JOpcode("GETSTATIC", - cGETSTATIC, - 3, - UNKNOWN_TYPE, - NO_DATA, - JMP_NEXT); - public final static JOpcode PUTSTATIC = new JOpcode("PUTSTATIC", - cPUTSTATIC, - 3, - NO_DATA, - UNKNOWN_TYPE, - JMP_NEXT); - public final static JOpcode GETFIELD = new JOpcode("GETFIELD", - cGETFIELD, - 3, - UNKNOWN_TYPE, - OBJECT_REF_TYPE, - JMP_NEXT); - public final static JOpcode PUTFIELD = - new JOpcode("PUTFIELD", cPUTFIELD, 3, NO_DATA, UNKNOWN_TYPE, JMP_NEXT); - public final static JOpcode INVOKEVIRTUAL = new JOpcode("INVOKEVIRTUAL", - cINVOKEVIRTUAL, - 3, - NO_DATA, - UNKNOWN_TYPE, - JMP_NEXT); - public final static JOpcode INVOKESPECIAL = new JOpcode("INVOKESPECIAL", - cINVOKESPECIAL, - 3, - NO_DATA, - UNKNOWN_TYPE, - JMP_NEXT); - public final static JOpcode INVOKESTATIC = new JOpcode("INVOKESTATIC", - cINVOKESTATIC, - 3, - NO_DATA, - UNKNOWN_TYPE, - JMP_NEXT); - public final static JOpcode INVOKEINTERFACE = - new JOpcode("INVOKEINTERFACE", - cINVOKEINTERFACE, - 5, - NO_DATA, - UNKNOWN_TYPE, - JMP_NEXT); - public final static JOpcode NEW = - new JOpcode("NEW", cNEW, 3, OBJECT_REF_TYPE, NO_DATA, JMP_NEXT); - public final static JOpcode NEWARRAY = - new JOpcode("NEWARRAY", - cNEWARRAY, - 2, - ARRAY_REF_TYPE, - INT_TYPE, - JMP_NEXT); - public final static JOpcode ANEWARRAY = - new JOpcode("ANEWARRAY", - cANEWARRAY, - 3, - ARRAY_REF_TYPE, - INT_TYPE, - JMP_NEXT); - public final static JOpcode ARRAYLENGTH = new JOpcode("ARRAYLENGTH", - cARRAYLENGTH, - 1, - INT_TYPE, - ARRAY_REF_TYPE, - JMP_NEXT); - public final static JOpcode ATHROW = new JOpcode("ATHROW", - cATHROW, - 1, - OBJECT_REF_TYPE, - OBJECT_REF_TYPE, - JMP_NONE); - public final static JOpcode CHECKCAST = new JOpcode("CHECKCAST", - cCHECKCAST, - 3, - OBJECT_REF_TYPE, - OBJECT_REF_TYPE, - JMP_NEXT); - public final static JOpcode INSTANCEOF = new JOpcode("INSTANCEOF", - cINSTANCEOF, - 3, - INT_TYPE, - OBJECT_REF_TYPE, - JMP_NEXT); - public final static JOpcode MONITORENTER = new JOpcode("MONITORENTER", - cMONITORENTER, - 1, - NO_DATA, - OBJECT_REF_TYPE, - JMP_NEXT); - public final static JOpcode MONITOREXIT = new JOpcode("MONITOREXIT", - cMONITOREXIT, - 1, - NO_DATA, - OBJECT_REF_TYPE, - JMP_NEXT); - public final static JOpcode WIDE = new JOpcode("WIDE", - cWIDE, - UNKNOWN, - UNKNOWN_TYPE, - UNKNOWN_TYPE, - JMP_NEXT); - public final static JOpcode MULTIANEWARRAY = new JOpcode("MULTIANEWARRAY", - cMULTIANEWARRAY, - 4, - ARRAY_REF_TYPE, - UNKNOWN_TYPE, - JMP_NEXT); - public final static JOpcode IFNULL = new JOpcode("IFNULL", - cIFNULL, - 3, - NO_DATA, - REFERENCE_TYPE, - JMP_MAYBE_S2_OFFSET); - public final static JOpcode IFNONNULL = new JOpcode("IFNONNULL", - cIFNONNULL, - 3, - NO_DATA, - REFERENCE_TYPE, - JMP_MAYBE_S2_OFFSET); - public final static JOpcode GOTO_W = new JOpcode("GOTO_W", - cGOTO_W, - 5, - NO_DATA, - NO_DATA, - JMP_ALWAYS_S4_OFFSET); - public final static JOpcode JSR_W = - new JOpcode("JSR_W", cJSR_W, 5, ADDRESS_TYPE, NO_DATA, JMP_NEXT); - - public final static JOpcode[] OPCODES = { - NOP, ACONST_NULL, ICONST_M1, ICONST_0, ICONST_1, - ICONST_2, ICONST_3, ICONST_4, ICONST_5, LCONST_0, - LCONST_1, FCONST_0, FCONST_1, FCONST_2, DCONST_0, - DCONST_1, BIPUSH, SIPUSH, LDC, LDC_W, - LDC2_W, ILOAD, LLOAD, FLOAD, DLOAD, - ALOAD, ILOAD_0, ILOAD_1, ILOAD_2, ILOAD_3, - LLOAD_0, LLOAD_1, LLOAD_2, LLOAD_3, FLOAD_0, - FLOAD_1, FLOAD_2, FLOAD_3, DLOAD_0, DLOAD_1, - DLOAD_2, DLOAD_3, ALOAD_0, ALOAD_1, ALOAD_2, - ALOAD_3, IALOAD, LALOAD, FALOAD, DALOAD, - AALOAD, BALOAD, CALOAD, SALOAD, ISTORE, - LSTORE, FSTORE, DSTORE, ASTORE, ISTORE_0, - ISTORE_1, ISTORE_2, ISTORE_3, LSTORE_0, LSTORE_1, - LSTORE_2, LSTORE_3, FSTORE_0, FSTORE_1, FSTORE_2, - FSTORE_3, DSTORE_0, DSTORE_1, DSTORE_2, DSTORE_3, - ASTORE_0, ASTORE_1, ASTORE_2, ASTORE_3, IASTORE, - LASTORE, FASTORE, DASTORE, AASTORE, BASTORE, - CASTORE, SASTORE, POP, POP2, DUP, - DUP_X1, DUP_X2, DUP2, DUP2_X1, DUP2_X2, - SWAP, IADD, LADD, FADD, DADD, - ISUB, LSUB, FSUB, DSUB, IMUL, - LMUL, FMUL, DMUL, IDIV, LDIV, - FDIV, DDIV, IREM, LREM, FREM, - DREM, INEG, LNEG, FNEG, DNEG, - ISHL, LSHL, ISHR, LSHR, IUSHR, - LUSHR, IAND, LAND, IOR, LOR, - IXOR, LXOR, IINC, I2L, I2F, - I2D, L2I, L2F, L2D, F2I, - F2L, F2D, D2I, D2L, D2F, - I2B, I2C, I2S, LCMP, FCMPL, - FCMPG, DCMPL, DCMPG, IFEQ, IFNE, - IFLT, IFGE, IFGT, IFLE, IF_ICMPEQ, - IF_ICMPNE, IF_ICMPLT, IF_ICMPGE, IF_ICMPGT, IF_ICMPLE, - IF_ACMPEQ, IF_ACMPNE, GOTO, JSR, RET, - TABLESWITCH, LOOKUPSWITCH, IRETURN, LRETURN, FRETURN, - DRETURN, ARETURN, RETURN, GETSTATIC, PUTSTATIC, - GETFIELD, PUTFIELD, INVOKEVIRTUAL, INVOKESPECIAL, INVOKESTATIC, - INVOKEINTERFACE, null, NEW, NEWARRAY, ANEWARRAY, - ARRAYLENGTH, ATHROW, CHECKCAST, INSTANCEOF, MONITORENTER, - MONITOREXIT, WIDE, MULTIANEWARRAY, IFNULL, IFNONNULL, - GOTO_W, JSR_W - }; - - protected JOpcode(String name, - int code, - int size, - JType[] producedDataTypes, - JType[] consumedDataTypes, - int jumpKind) { - this.name = name; - this.code = code; - this.size = size; - this.producedDataTypes = producedDataTypes; - this.consumedDataTypes = consumedDataTypes; - this.jumpKind = jumpKind; - switch (jumpKind) { - case JMP_NONE: successorCount = 0; break; - case JMP_NEXT: successorCount = 1; break; - case JMP_ALWAYS_S2_OFFSET: successorCount = 1; break; - case JMP_ALWAYS_S4_OFFSET: successorCount = 1; break; - case JMP_MAYBE_S2_OFFSET: successorCount = 2; break; - case JMP_TABLE: successorCount = UNKNOWN; break; - case JMP_LOOKUP: successorCount = UNKNOWN; break; - default: successorCount = UNKNOWN; break; - } - } - - public String toString() { return name; } - protected int getSize() { return size; } - protected JType[] getProducedDataTypes() { return producedDataTypes; } - protected JType[] getConsumedDataTypes() { return consumedDataTypes; } - - protected int getProducedDataSize() { - if (producedDataTypes != UNKNOWN_TYPE) - return JType.getTotalSize(producedDataTypes); - else { - switch (code) { - case cLDC: case cLDC_W: case cBALOAD: - return 1; - case cLDC2_W: case cDUP: case cSWAP: - return 2; - case cDUP_X1: - return 3; - case cDUP_X2: case cDUP2: - return 4; - case cDUP2_X1: - return 5; - case cDUP2_X2: - return 6; - default: - throw new Error(this.toString()); - } - } - } - - protected int getConsumedDataSize() { - if (consumedDataTypes != UNKNOWN_TYPE) - return JType.getTotalSize(consumedDataTypes); - else { - switch (code) { - case cPOP: case cDUP: - return 1; - case cPOP2: case cDUP_X1: case cDUP2: case cSWAP: - return 2; - case cDUP_X2: case cDUP2_X1: - return 3; - case cDUP2_X2: - return 4; - default: - throw new Error(this.toString()); - } - } - } - - protected int getProducedDataTypesNumber() { - if (producedDataTypes != UNKNOWN_TYPE) - return producedDataTypes.length; - else { - switch (code) { - case cLDC: case cLDC_W: case cLDC2_W: case cBALOAD: - case cGETSTATIC: case cGETFIELD: - return 1; - case cDUP: case cSWAP: - return 2; - case cDUP_X2: case cDUP2: case cDUP2_X1: case cDUP2_X2: - return 2; - case cDUP_X1: - return 3; - default: - throw new Error(this.toString()); - } - } - } - - protected int getConsumedDataTypesNumber() { - if (consumedDataTypes != UNKNOWN_TYPE) - return consumedDataTypes.length; - else { - switch (code) { - case cPOP: case cDUP: case cPUTSTATIC: - return 1; - case cPUTFIELD: case cDUP_X1: case cDUP_X2: - case cDUP2: case cDUP2_X1: case cPOP2: case cSWAP: - return 2; - default: - throw new Error(this.toString()); - } - } - } -} diff --git a/src/fjbg/ch/epfl/lamp/fjbg/JOtherAttribute.java b/src/fjbg/ch/epfl/lamp/fjbg/JOtherAttribute.java deleted file mode 100644 index 50aa9d3636..0000000000 --- a/src/fjbg/ch/epfl/lamp/fjbg/JOtherAttribute.java +++ /dev/null @@ -1,77 +0,0 @@ -/* FJBG -- Fast Java Bytecode Generator - * Copyright 2002-2013 LAMP/EPFL - * @author Michel Schinz - */ - -package ch.epfl.lamp.fjbg; - -import java.io.DataInputStream; -import java.io.DataOutputStream; -import java.io.IOException; - -/** - * Attributes which are unknown to the JVM (or at least to this library). - * - * @author Michel Schinz - * @version 1.0 - */ - -public class JOtherAttribute extends JAttribute { - protected final String name; - protected final byte[] contents; - protected final int length; - - public JOtherAttribute(FJBGContext context, - JClass clazz, - Object owner, - String name, - byte[] contents, - int length) { - super(context, clazz, name); - this.name = name; - this.contents = contents; - this.length = length; - } - - public JOtherAttribute(FJBGContext context, - JClass clazz, - Object owner, - String name, - int size, - DataInputStream stream) - throws IOException { - super(context, clazz, name); - this.name = name; - this.contents = new byte[size]; - this.length = size; - - stream.read(contents, 0, length); - } - - public String getName() { return name; } - - // Follows javap output format for user-defined attributes. - /*@Override*/ public String toString() { - StringBuffer buf = new StringBuffer(" "); - buf.append(name); - buf.append(": length = 0x"); - buf.append(Integer.toHexString(length).toUpperCase()); - for (int i = 0; i < length; ++i) { - if (i % 16 == 0) buf.append("\n "); - buf.append(hexString(contents[i])); - buf.append(" "); - } - buf.append("\n"); - return buf.toString(); - } - - protected int getSize() { return length; } - - protected void writeContentsTo(DataOutputStream stream) throws IOException { - stream.write(contents, 0, length); - } - - private static final String hexString(int i) { - return ((0 <= i && i < 16) ? "0" : "")+Integer.toHexString(i).toUpperCase(); - } -} diff --git a/src/fjbg/ch/epfl/lamp/fjbg/JReferenceType.java b/src/fjbg/ch/epfl/lamp/fjbg/JReferenceType.java deleted file mode 100644 index 73d1026c04..0000000000 --- a/src/fjbg/ch/epfl/lamp/fjbg/JReferenceType.java +++ /dev/null @@ -1,19 +0,0 @@ -/* FJBG -- Fast Java Bytecode Generator - * Copyright 2002-2013 LAMP/EPFL - * @author Michel Schinz - */ - -package ch.epfl.lamp.fjbg; - -/** - * Types for Java references, i.e. arrays and objects. - * - * @author Michel Schinz - * @version 1.0 - */ - -abstract public class JReferenceType extends JType { - public boolean isReferenceType() { return true; } - - abstract public String getDescriptor(); -} diff --git a/src/fjbg/ch/epfl/lamp/fjbg/JSourceFileAttribute.java b/src/fjbg/ch/epfl/lamp/fjbg/JSourceFileAttribute.java deleted file mode 100644 index 3a17cb2c44..0000000000 --- a/src/fjbg/ch/epfl/lamp/fjbg/JSourceFileAttribute.java +++ /dev/null @@ -1,69 +0,0 @@ -/* FJBG -- Fast Java Bytecode Generator - * Copyright 2002-2013 LAMP/EPFL - * @author Michel Schinz - */ - -package ch.epfl.lamp.fjbg; - -import java.io.DataInputStream; -import java.io.DataOutputStream; -import java.io.IOException; - -/** - * Sourcefile attribute, which can be attached to class files to - * associate them with their source file. - * - * There can be no more than one SourceFile attribute in the attributes table - * of a given ClassFile structure. See section 4.8.9 of the JVM specification. - * - * @author Michel Schinz - * @version 1.0 - */ - -public class JSourceFileAttribute extends JAttribute { - protected final String sourceFileName; - protected final int sourceFileIndex; - - public JSourceFileAttribute(FJBGContext context, - JClass clazz, - String sourceFileName) { - super(context, clazz); - this.sourceFileName = sourceFileName; - this.sourceFileIndex = clazz.getConstantPool().addUtf8(sourceFileName); - } - - public JSourceFileAttribute(FJBGContext context, - JClass clazz, - Object owner, - String name, - int size, - DataInputStream stream) - throws IOException { - super(context, clazz, name); - - this.sourceFileIndex = stream.readShort(); - this.sourceFileName = clazz.getConstantPool().lookupUtf8(sourceFileIndex); - - assert name.equals(getName()); - } - - public String getName() { return "SourceFile"; } - - public String getFileName() { return sourceFileName; } - - // Follows javap output format for SourceFile attribute. - /*@Override*/ public String toString() { - StringBuffer buf = new StringBuffer(" SourceFile: \""); - buf.append(sourceFileName); - buf.append("\"\n"); - return buf.toString(); - } - - protected int getSize() { - return 2; // Short.SIZE - } - - protected void writeContentsTo(DataOutputStream stream) throws IOException { - stream.writeShort(sourceFileIndex); - } -} diff --git a/src/fjbg/ch/epfl/lamp/fjbg/JStackMapTableAttribute.java b/src/fjbg/ch/epfl/lamp/fjbg/JStackMapTableAttribute.java deleted file mode 100644 index 72a5484d40..0000000000 --- a/src/fjbg/ch/epfl/lamp/fjbg/JStackMapTableAttribute.java +++ /dev/null @@ -1,282 +0,0 @@ -/* FJBG -- Fast Java Bytecode Generator - * Copyright 2002-2013 LAMP/EPFL - * @author Michel Schinz - */ - -package ch.epfl.lamp.fjbg; - -import java.io.DataInputStream; -import java.io.DataOutputStream; -import java.io.IOException; -import java.util.ArrayList; -import java.util.Iterator; -import java.util.List; - -/** - * - * @author Stephane Micheloud - * @version 1.0 - */ - -public class JStackMapTableAttribute extends JAttribute { - /** Constant pool of the current classfile. */ - private JConstantPool pool; - - /** StackMapTable entries */ - protected final List/*<Frame>*/ entries = new ArrayList(); - protected int entriesSize = 0; - protected boolean usesU2; - - public JStackMapTableAttribute(FJBGContext context, - JClass clazz, - JCode code) { - super(context, clazz); - this.pool = clazz.pool; - - assert code.getOwner().getOwner() == clazz; - } - - public JStackMapTableAttribute(FJBGContext context, - JClass clazz, - Object owner, - String name, - int size, - DataInputStream stream) - throws IOException { - super(context, clazz, name); - this.pool = clazz.pool; - - int count = stream.readShort(); - this.usesU2 = count < 65536; - for (int i = 0; i < count; ++i) - this.entries.add(new Frame(stream)); - this.entriesSize = computeSize(); - - assert name.equals(getName()); - } - - public String getName() { return "StackMapTable"; } - - // Follows javap output format for StackMapTable attribute. - /*@Override*/ public String toString() { - Frame frame = null; - StringBuffer buf = new StringBuffer(" StackMapTable: number_of_entries = "); - buf.append(entries.size()); - Iterator it = entries.iterator(); - while (it.hasNext()) { - frame = (Frame)it.next(); - buf.append("\n frame_type = "); - buf.append(frame.tag); - buf.append(" /* "); - buf.append(getFrameType(frame.tag)); - buf.append(" */"); - if (frame.offsetDelta != -1) - buf.append("\n offset_delta = "+frame.offsetDelta); - if (frame.locals != null) - appendTypeInfoArray(buf, "locals", frame.locals); - if (frame.stackItems != null) - appendTypeInfoArray(buf, "stack", frame.stackItems); - } - buf.append("\n"); - return buf.toString(); - } - - protected int getSize() { - return entriesSize; - } - - protected void writeContentsTo(DataOutputStream stream) throws IOException { - stream.writeShort(entriesSize); - Iterator it = entries.iterator(); - while (it.hasNext()) { - Frame frame = (Frame)it.next(); - frame.writeContentsTo(stream); - } - } - - private class TypeInfo { - final int tag; - final int poolIndexOrOffset; // tag == 7 => poolIndex, tag = 8 => offset - private int bytes; - TypeInfo(DataInputStream stream) throws IOException { - int size = 1; - this.tag = stream.readByte(); - if (tag == 7) { // ITEM_Object; // 7 - poolIndexOrOffset = stream.readShort(); - size += 2; - } else if (tag == 8) { // ITEM_Uninitialized // 8 - poolIndexOrOffset = (usesU2) ? stream.readShort() : stream.readInt(); - size += (usesU2) ? 2 : 4; - } else - poolIndexOrOffset = -1; - this.bytes += size; - } - int getSize() { return bytes; } - void writeContentsTo(DataOutputStream stream) throws IOException { - stream.writeByte(tag); - if (tag == 7) { // ITEM_Object; // 7 - stream.writeShort(poolIndexOrOffset); - } else if (tag == 8) { // ITEM_Uninitialized // 8 - if (usesU2) stream.writeShort(poolIndexOrOffset); - else stream.writeInt(poolIndexOrOffset); - } - } - /*@Override*/ public String toString() { - switch (tag) { - case 0: // ITEM_Top - return "<top>"; - case 1: // ITEM_Integer - return "int"; - case 2: // ITEM_Float - return "float"; - case 3: // ITEM_Double - return "double"; - case 4: // ITEM_Long - return "long"; - case 5: // ITEM_Null - return "null"; - case 6: // ITEM_UninializedThis - return "this"; - case 7: // ITEM_Object - String name = pool.lookupClass(poolIndexOrOffset); - if (name.startsWith("[")) name = "\""+name+"\""; - return "class "+name; - case 8: // ITEM_Uninitialized - return "<uninitialized>"; - default: - return String.valueOf(tag); - } - } - } - - private class Frame { - final int tag; - int offsetDelta = -1; - TypeInfo[] stackItems = null; - TypeInfo[] locals = null; - private int bytes; - Frame(DataInputStream stream) throws IOException { - // The stack_map_frame structure consists of a one-byte tag - // followed by zero or more bytes. - this.tag = stream.readUnsignedByte(); - if (tag < 64) { // SAME; // 0-63 - //done - } else if (tag < 128) { // SAME_LOCALS_1_STACK_ITEM; // 64-127 - this.offsetDelta = tag - 64; - readStackItems(stream, 1); - } else if (tag < 248) { // reserved for future use. - assert false : "Tags in the range [128-247] are reserved for future use."; - } else if (tag < 251) { // CHOP; // 248-250 - int k = 251 - tag; - readOffsetDelta(stream); - } else if (tag == 251) { // SAME_FRAME_EXTENDED - readOffsetDelta(stream); - } else if (tag < 255) { // APPEND; // 252-254 - readOffsetDelta(stream); - readLocals(stream, tag - 251); - } else { // FULL_FRAME; // 255 - readOffsetDelta(stream); - readLocals(stream); - readStackItems(stream); - } - } - int getSize() { return bytes; } - void readOffsetDelta(DataInputStream stream) throws IOException { - this.offsetDelta = (usesU2) ? stream.readShort() : stream.readInt(); - this.bytes += (usesU2) ? 2 : 4; - } - int getOffsetDelta() { return offsetDelta; } - void readStackItems(DataInputStream stream, int k) throws IOException { - this.stackItems = new TypeInfo[k]; - for (int i = 0; i < k; ++i) { - stackItems[i] = new TypeInfo(stream); - this.bytes += stackItems[i].getSize(); - } - } - void readStackItems(DataInputStream stream) throws IOException { - int k = (usesU2) ? stream.readShort() : stream.readInt(); - this.bytes += (usesU2) ? 2 : 4; - readStackItems(stream, k); - } - void readLocals(DataInputStream stream, int k) throws IOException { - this.locals = new TypeInfo[k]; - for (int i = 0; i < k; ++i) { - locals[i] = new TypeInfo(stream); - this.bytes += locals[i].getSize(); - } - } - void readLocals(DataInputStream stream) throws IOException { - int k = (usesU2) ? stream.readShort() : stream.readInt(); - this.bytes += (usesU2) ? 2 : 4; - readLocals(stream, k); - } - void writeContentsTo(DataOutputStream stream) throws IOException { - stream.writeByte(tag); - if (tag < 64) { - //done - } else if (tag < 128) { // SAME; // 0-63 - assert stackItems.length == 1; - stackItems[0].writeContentsTo(stream); - } else if (tag < 248) { - assert false : "Tags in the range [128-247] are reserved for future use."; - } else if (tag < 251) { - if (usesU2) stream.writeShort(offsetDelta); - else stream.writeInt(offsetDelta); - } else if (tag == 251) { - if (usesU2) stream.writeShort(offsetDelta); - else stream.writeInt(offsetDelta); - } else if (tag < 255) { // APPEND; // 252-254 - if (usesU2) stream.writeShort(offsetDelta); - else stream.writeInt(offsetDelta); - for (int i = 0; i < locals.length; ++i) - locals[i].writeContentsTo(stream); - } else { - if (usesU2) stream.writeShort(offsetDelta); - else stream.writeInt(offsetDelta); - for (int i = 0; i < locals.length; ++i) - locals[i].writeContentsTo(stream); - for (int i = 0; i < stackItems.length; ++i) - stackItems[i].writeContentsTo(stream); - } - } - } - - private int computeSize() { - int size = (usesU2) ? 2 : 4; // number of frames - Iterator it = entries.iterator(); - while (it.hasNext()) { - Frame frame = (Frame)it.next(); - size += frame.getSize(); - } - return size; - } - - private static final String getFrameType(int tag) { - if (tag < 64) return "same"; - else if (tag < 128) return "same locals 1 stack item"; - else if (tag < 248) return "<reserved>"; - else if (tag < 251) return "chop"; - else if (tag == 251) return "same frame extended"; - else if (tag < 255) return "append"; - else return "full frame"; - } - - private static StringBuffer appendTypeInfoArray(StringBuffer buf, - String s, TypeInfo[] a) { - buf.append("\n "); - buf.append(s); - buf.append(" = "); - if (a.length > 0) { - buf.append("[ "); - for (int i = 0; i < a.length; ++i) { - if (i > 0) buf.append(", "); - buf.append(a[i]); - } - buf.append(" ]"); - } - else - buf.append("[]"); - return buf; - } - -} diff --git a/src/fjbg/ch/epfl/lamp/fjbg/JType.java b/src/fjbg/ch/epfl/lamp/fjbg/JType.java deleted file mode 100644 index 298a2b0565..0000000000 --- a/src/fjbg/ch/epfl/lamp/fjbg/JType.java +++ /dev/null @@ -1,316 +0,0 @@ -/* FJBG -- Fast Java Bytecode Generator - * Copyright 2002-2013 LAMP/EPFL - * @author Michel Schinz - */ - -package ch.epfl.lamp.fjbg; - -import java.io.IOException; -import java.io.StringReader; -import java.util.ArrayList; - -/** - * Representation of Java types. - * - * @version 1.0 - * @author Michel Schinz - */ - -abstract public class JType { - abstract public int getSize(); - abstract public String getSignature(); - abstract public int getTag(); - abstract public String toString(); - abstract public boolean isCompatibleWith(JType other); - - public boolean isValueType() { return false; } - public boolean isObjectType() { return false; } - public boolean isArrayType() { return false; } - public boolean isReferenceType() { return false; } - - // Tags for types. Taken from BCEL. - public static final int T_BOOLEAN = 4; - public static final int T_CHAR = 5; - public static final int T_FLOAT = 6; - public static final int T_DOUBLE = 7; - public static final int T_BYTE = 8; - public static final int T_SHORT = 9; - public static final int T_INT = 10; - public static final int T_LONG = 11; - public static final int T_VOID = 12; // Non-standard - public static final int T_ARRAY = 13; - public static final int T_OBJECT = 14; - public static final int T_UNKNOWN = 15; - public static final int T_ADDRESS = 16; - - public static final int T_REFERENCE = 17; // type compatible with references - - public static final JType[] EMPTY_ARRAY = new JType[0]; - - protected static JType parseSig(StringReader s) throws IOException { - int nextChar = s.read(); - if (nextChar == -1) throw new IllegalArgumentException(); - - switch ((char)nextChar) { - case 'V' : return VOID; - case 'Z' : return BOOLEAN; - case 'B' : return BYTE; - case 'C' : return CHAR; - case 'S' : return SHORT; - case 'I' : return INT; - case 'F' : return FLOAT; - case 'J' : return LONG; - case 'D' : return DOUBLE; - case 'L': { - StringBuffer className = new StringBuffer(); - for (;;) { - nextChar = s.read(); - if (nextChar == -1 || nextChar == ';') break; - className.append(nextChar == '/' ? ':' : ((char)nextChar)); - } - if (nextChar != ';') throw new IllegalArgumentException(); - return new JObjectType(className.toString()); - } - case '[': { - JType elemType = parseSig(s); - return new JArrayType(elemType); - } - case '(': { - ArrayList argTps = new ArrayList(); - for (;;) { - s.mark(1); - nextChar = s.read(); - if (nextChar == -1 || nextChar == ')') break; - s.reset(); - argTps.add(parseSig(s)); - } - if (nextChar != ')') throw new IllegalArgumentException("a"); - JType[] argTpsA = (JType[])argTps.toArray(new JType[argTps.size()]); - JType returnType = parseSig(s); - return new JMethodType(returnType, argTpsA); - } - default: - throw new IllegalArgumentException(); - } - } - - /** - * A signature is a string representing the generic type of a field or - * method, or generic type information for a class declaration. - * See section 4.4.4 of the JVM specification. - */ - public static JType parseSignature(String signature) { - try { - StringReader sigReader = new StringReader(signature); - JType parsed = parseSig(sigReader); - if (sigReader.read() != -1) - throw new IllegalArgumentException(); - return parsed; - } catch (IllegalArgumentException e) { - throw new IllegalArgumentException("invalid signature " + signature); - } catch (IOException e) { - throw new Error(e); - } - } - - public static int getTotalSize(JType[] types) { - int size = 0; - for (int i = 0; i < types.length; ++i) - size += types[i].getSize(); - return size; - } - - protected JType() {} - - public static JType VOID = new JType() { - public int getSize() { return 0; } - public String getSignature() { return "V"; } - public int getTag() { return T_VOID; } - public String toString() { return "void"; } - public boolean isCompatibleWith(JType other) { - throw new UnsupportedOperationException("type VOID is no real " - + "data type therefore " - + "cannot be assigned to " - + other.toString()); - } - }; - - public static JType BOOLEAN = new JType() { - public int getSize() { return 1; } - public String getSignature() { return "Z"; } - public int getTag() { return T_BOOLEAN; } - public String toString() { return "boolean"; } - public boolean isValueType() { return true; } - public boolean isCompatibleWith(JType other) { - return other == BOOLEAN - || other == INT - || other == BYTE - || other == CHAR - || other == SHORT; - } - }; - - public static JType BYTE = new JType() { - public int getSize() { return 1; } - public String getSignature() { return "B"; } - public int getTag() { return T_BYTE; } - public String toString() { return "byte"; } - public boolean isValueType() { return true; } - public boolean isCompatibleWith(JType other) { - return other == BOOLEAN - || other == INT - || other == BYTE - || other == CHAR - || other == SHORT; - } - }; - - public static JType CHAR = new JType() { - public int getSize() { return 1; } - public String getSignature() { return "C"; } - public int getTag() { return T_CHAR; } - public String toString() { return "char"; } - public boolean isValueType() { return true; } - public boolean isCompatibleWith(JType other) { - return other == BOOLEAN - || other == INT - || other == BYTE - || other == CHAR - || other == SHORT; - } - }; - - public static JType SHORT = new JType() { - public int getSize() { return 1; } - public String getSignature() { return "S"; } - public int getTag() { return T_SHORT; } - public String toString() { return "short"; } - public boolean isValueType() { return true; } - public boolean isCompatibleWith(JType other) { - return other == BOOLEAN - || other == INT - || other == BYTE - || other == CHAR - || other == SHORT; - } - }; - - public static JType INT = new JType() { - public int getSize() { return 1; } - public String getSignature() { return "I"; } - public int getTag() { return T_INT; } - public String toString() { return "int"; } - public boolean isValueType() { return true; } - public boolean isCompatibleWith(JType other) { - return other == BOOLEAN - || other == INT - || other == BYTE - || other == CHAR - || other == SHORT; - } - }; - - public static JType FLOAT = new JType() { - public int getSize() { return 1; } - public String getSignature() { return "F"; } - public int getTag() { return T_FLOAT; } - public String toString() { return "float"; } - public boolean isValueType() { return true; } - public boolean isCompatibleWith(JType other) { - return other == FLOAT; - } - }; - - public static JType LONG = new JType() { - public int getSize() { return 2; } - public String getSignature() { return "J"; } - public int getTag() { return T_LONG; } - public String toString() { return "long"; } - public boolean isValueType() { return true; } - public boolean isCompatibleWith(JType other) { - return other == LONG; - } - }; - - public static JType DOUBLE = new JType() { - public int getSize() { return 2; } - public String getSignature() { return "D"; } - public int getTag() { return T_DOUBLE; } - public String toString() { return "double"; } - public boolean isValueType() { return true; } - public boolean isCompatibleWith(JType other) { - return other == DOUBLE; - } - }; - - public static JType REFERENCE = new JType() { - public int getSize() { return 1; } - public String getSignature() { - throw new UnsupportedOperationException("type REFERENCE is no real " - + "data type and therefore " - + "has no signature"); - } - public int getTag() { return T_REFERENCE; } - public String toString() { return "<reference>"; } - public boolean isCompatibleWith(JType other) { - throw new UnsupportedOperationException("type REFERENCE is no real " - + "data type and therefore " - + "cannot be assigned to " - + other.toString()); - } - }; - - public static JType ADDRESS = new JType() { - public int getSize() { return 1; } - public String getSignature() { - throw new UnsupportedOperationException("type ADDRESS is no usable " - + "data type and therefore " - + "has no signature"); - } - public int getTag() { return T_ADDRESS; } - public String toString() { return "<address>"; } - public boolean isCompatibleWith(JType other) { - return other == ADDRESS; - } - }; - - public static JType UNKNOWN = new JType() { - public int getSize() { - throw new UnsupportedOperationException("type UNKNOWN is no real " - + "data type and therefore " - + "has no size"); - } - public String getSignature() { - throw new UnsupportedOperationException("type UNKNOWN is no real " - + "data type and therefore " - + "has no signature"); - } - public int getTag() { return T_UNKNOWN; } - public String toString() { return "<unknown>"; } - public boolean isCompatibleWith(JType other) { - throw new UnsupportedOperationException("type UNKNOWN is no real " - + "data type and therefore " - + "cannot be assigned to " - + other.toString()); - } - }; - - protected static String tagToString(int tag) { - switch (tag) { - case T_BOOLEAN : return "boolean"; - case T_CHAR : return "char"; - case T_FLOAT : return "float"; - case T_DOUBLE : return "double"; - case T_BYTE : return "byte"; - case T_SHORT : return "short"; - case T_INT : return "int"; - case T_LONG : return "long"; - case T_VOID : return "void"; // Non-standard - case T_ARRAY : return "[]"; - case T_OBJECT : return "Object"; - case T_UNKNOWN : return "<unknown>"; - case T_ADDRESS : return "<address>"; - default: return String.valueOf(tag); - } - } -} diff --git a/src/fjbg/ch/epfl/lamp/fjbg/Main.java b/src/fjbg/ch/epfl/lamp/fjbg/Main.java deleted file mode 100644 index 810ee7c400..0000000000 --- a/src/fjbg/ch/epfl/lamp/fjbg/Main.java +++ /dev/null @@ -1,131 +0,0 @@ -/* FJBG -- Fast Java Bytecode Generator - * Copyright 2002-2013 LAMP/EPFL - * @author Michel Schinz - */ - -package ch.epfl.lamp.fjbg; - -import java.io.DataInputStream; -import java.io.File; -import java.io.FileInputStream; -import java.io.InputStream; -import java.io.IOException; -import java.util.ArrayList; -import java.util.jar.JarFile; -import java.util.zip.ZipEntry; - -/** - * Main program entry to execute the FJBG reader from the command line. - * - * The reader prints out the decoded data in the same output format as - * javap, the Java bytecode disassembler of the Sun J2SE SDK. - * - * @author Stephane Micheloud - * @version 1.1 - */ - -public class Main { - private static final String PRODUCT_STRING = "Fast Java Bytecode Generator"; - private static final String VERSION_STRING = "version 1.1"; - - private static final int ACTION_USAGE = 0; - private static final int ACTION_DONE = 1; - private static final int ACTION_PROCEED = 2; - - private static String classPath = "."; - private static String[] classNames = null; - - public static void main(String[] args) { - switch (parseArgs(args)) { - case ACTION_USAGE: printUsage(); break; - case ACTION_PROCEED: processClasses(); break; - default: - } - } - - private static void processClasses() { - FJBGContext fjbgContext = new FJBGContext(49, 0); - if (classNames.length > 0) - try { - for (int i = 0; i < classNames.length; ++i) - processClass(fjbgContext, classNames[i]); - } catch (IOException e) { - System.err.println(e.getMessage()); - } - else - System.err.println( - "No classes were specified on the command line. Try -help."); - } - - private static void processClass(FJBGContext fjbgContext, String className) - throws IOException { - InputStream in = getInputStream(className); - JClass jclass = fjbgContext.JClass(new DataInputStream(in)); - System.out.println(jclass); - in.close(); - } - - private static InputStream getInputStream(String className) throws IOException { - String name = null; - String[] paths = classPath.split(File.pathSeparator); - for (int i = 0; i < paths.length; ++i) { - File parent = new File(paths[i]); - if (parent.isDirectory()) { - name = className.replace('.', File.separatorChar)+".class"; - File f = new File(parent, name); - if (f.isFile()) return new FileInputStream(f); - } else if (paths[i].endsWith(".jar")) { - JarFile f = new JarFile(parent); - name = className.replace('.', '/')+".class"; - ZipEntry e = f.getEntry(name); - if (e != null) return f.getInputStream(e); - } - } - throw new IOException("ERROR:Could not find "+className); - } - - private static int parseArgs(String[] args) { - ArrayList/*<String>*/ classes = new ArrayList(); - String arg = null; - int action = ACTION_USAGE; - int i = 0, n = args.length; - while (i < n) { - arg = args[i]; - if (arg.equals("-classpath") && (i+1) < n) { - classPath = args[i+1]; i += 2; - } else if (arg.equals("-cp") && (i+1) < n) { - classPath = args[i+1]; i += 2; - } else if (arg.equals("-help")) { - i = n+1; - //} else if (arg.equals("-v")) { - // verbose = true; i += 1; - } else if (arg.equals("-version")) { - System.err.println(PRODUCT_STRING+" "+VERSION_STRING); - action = ACTION_DONE; i = n+1; - } else if (arg.startsWith("-")) { - System.err.println("invalid flag: "+arg); - i = n+1; - } else { - classes.add(arg); i += 1; - } - } - if (i == n && i > 0) { - classNames = (String[])classes.toArray(new String[classes.size()]); - action = ACTION_PROCEED; - } - return action; - } - - private static void printUsage() { - System.out.println("Usage: fjbg <options> <classes>"); - System.out.println(); - System.out.println("where possible options include:"); - System.out.println(" -cp <path> Specify where to find user class files"); - System.out.println(" -classpath <path> Specify where to find user class files"); - System.out.println(" -help Print a synopsis of standard options"); - System.out.println(" -version Version information"); - System.out.println(); - System.exit(1); - } -} - diff --git a/src/fjbg/ch/epfl/lamp/util/ByteArray.java b/src/fjbg/ch/epfl/lamp/util/ByteArray.java deleted file mode 100644 index b852e1ac1f..0000000000 --- a/src/fjbg/ch/epfl/lamp/util/ByteArray.java +++ /dev/null @@ -1,145 +0,0 @@ -/* FJBG -- Fast Java Bytecode Generator - * Copyright 2002-2013 LAMP/EPFL - * @author Michel Schinz - */ - -package ch.epfl.lamp.util; - -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; - -/** - * Array of bytes. - * - * @author Michel Schinz - * @version 1.0 - */ - -public class ByteArray { - protected final static int BYTE_BLOCK_BITS = 8; - protected final static int BYTE_BLOCK_SIZE = 1 << BYTE_BLOCK_BITS; - protected final static int BYTE_BLOCK_MASK = BYTE_BLOCK_SIZE - 1; - - protected byte[][] data = new byte[][] { new byte[BYTE_BLOCK_SIZE] }; - protected int pos = 0; // The next free position. - - protected boolean frozen = false; - - public ByteArray() { } - - public ByteArray(InputStream stream, int size) throws IOException { - pos = size; - for (int i = 0; size > 0; ++i) { - int sizeToRead = Math.min(BYTE_BLOCK_SIZE, size); - stream.read(data[i], 0, sizeToRead); - - size -= sizeToRead; - if (size > 0) addNewBlock(); - } - } - - public void freeze() { frozen = true; } - - public int nextBytePosition() { - return pos; - } - - public int getSize() { - return pos; - } - - protected void addNewBlock() { - int nextBlockPos = pos >>> BYTE_BLOCK_BITS; - if (nextBlockPos == data.length) { - byte[][] newData = new byte[data.length * 2][]; - System.arraycopy(data, 0, newData, 0, data.length); - data = newData; - } - assert data[nextBlockPos] == null : pos + " " + nextBlockPos; - data[nextBlockPos] = new byte[BYTE_BLOCK_SIZE]; - } - - protected void addByte(int b) { - assert !frozen; - - if ((pos & BYTE_BLOCK_MASK) == 0 && pos > 0) - addNewBlock(); - int currPos = pos++; - data[currPos >>> BYTE_BLOCK_BITS][currPos & BYTE_BLOCK_MASK] = (byte)b; - } - - public void addU1(int i) { - assert i <= 0xFF : i; - addByte(i); - } - - public void addU2(int i) { - assert i <= 0xFFFF : i; - - addByte(i >>> 8); - addByte(i & 0xFF); - } - - public void addU4(int i) { - addByte(i >>> 24); - addByte((i >>> 16) & 0xFF); - addByte((i >>> 8) & 0xFF); - addByte(i & 0xFF); - } - - public void putByte(int targetPos, int b) { - assert !frozen; - assert targetPos < pos : targetPos + " >= " + pos; - - data[targetPos >>> BYTE_BLOCK_BITS][targetPos & BYTE_BLOCK_MASK] = (byte)b; - } - - public void putU2(int targetPos, int i) { - assert i < 0xFFFF : i; - putByte(targetPos, i >>> 8); - putByte(targetPos + 1, i & 0xFF); - } - - public void putU4(int targetPos, int i) { - putByte(targetPos, i >>> 24); - putByte(targetPos + 1, (i >>> 16) & 0xFF); - putByte(targetPos + 2, (i >>> 8) & 0xFF); - putByte(targetPos + 3, i & 0xFF); - } - - public int getU1(int sourcePos) { - assert sourcePos < pos : sourcePos + " >= " + pos; - return data[sourcePos >>> BYTE_BLOCK_BITS][sourcePos & BYTE_BLOCK_MASK] & 0xFF; - } - - public int getU2(int sourcePos) { - return (getU1(sourcePos) << 8) | getU1(sourcePos + 1); - } - - public int getU4(int sourcePos) { - return (getU2(sourcePos) << 16) | getU2(sourcePos + 2); - } - - public int getS1(int sourcePos) { - assert sourcePos < pos : sourcePos + " >= " + pos; - return data[sourcePos >>> BYTE_BLOCK_BITS][sourcePos & BYTE_BLOCK_MASK]; - } - - public int getS2(int sourcePos) { - return (getS1(sourcePos) << 8) | getU1(sourcePos + 1); - } - - public int getS4(int sourcePos) { - return (getS2(sourcePos) << 16) | getU2(sourcePos + 2); - } - - public void writeTo(OutputStream stream) throws IOException { - if (!frozen) freeze(); - - for (int i = 0; i < data.length && data[i] != null; ++i) { - int len = Math.min(BYTE_BLOCK_SIZE, pos - (i << BYTE_BLOCK_BITS)); - stream.write(data[i], 0, len); - } - } -} |