NameAndTypeKey nt = (NameAndTypeKey) e2.key();
Type t = Type.instance(nt.type);
if(t == null) throw new ClassFile.ClassReadExn("invalid type descriptor");
- return new FieldRef((Type.Class)e1.key(), nt.name, t);
+ return ((Type.Class)e1.key()).field(nt.name, t);
}
case 10: case 11: {
NameAndTypeKey nt = (NameAndTypeKey) e2.key();
if (e1.key() == null) throw new Error(e1.tag + " => " + e1.key());
- return new MethodRef((Type.Class)e1.key(), "methodname", Type.VOID, new Type[0]); // FIXME FIXME
+ return ((Type.Class)e1.key()).method("methodname", Type.VOID, new Type[0]); // FIXME FIXME
}
case 12: {
return new NameAndTypeKey(((Utf8Ent)e1).s, ((Utf8Ent)e2).s);
ce.e1 = addUtf8(key.name);
ce.e2 = addUtf8(key.type);
ent = ce;
- } else if(o instanceof MemberRef) {
- MemberRef key = (MemberRef) o;
- int tag = invokeInterface ? 11 : o instanceof FieldRef ? 9 : o instanceof MethodRef ? 10 : 0;
+ } else if(o instanceof Type.Class.Member) {
+ Type.Class.Member key = (Type.Class.Member) o;
+ int tag = invokeInterface ? 11 : o instanceof Type.Class.Field ? 9 : o instanceof Type.Class.Method ? 10 : 0;
if(tag == 0) throw new Error("should never happen");
CPRefEnt ce = new CPRefEnt(tag);
- ce.e1 = add(key.klass);
+ ce.e1 = add(key.getDeclaringClass());
ce.e2 = addNameAndType(key.name, key.getDescriptor());
ent = ce;
} else {
switch(tag) {
case 7: // Object Type
case 8: // String
- case 9: // FieldRef
- case 10: // MethodRef
+ case 9: // Type.Class.Field
+ case 10: // Type.Class.Method
case 11: // Instance Method Ref
case 12: // NameAndType
{
if ((flags & ACC_TRANSIENT) != 0) ret += "transient ";
return ret;
}
-
+
+ public Type.Class getType() { return thisType; }
public String toString() { StringBuffer sb = new StringBuffer(); toString(sb); return sb.toString(); }
public void toString(StringBuffer sb) {
sb.append(flagsToString(flags));
int numFields = i.readShort();
for(int j=0; j<numFields; j++) fields.add(new FieldGen(cp, i));
int numMethods = i.readShort();
- for(int j=0; j<numMethods; j++) methods.add(new MethodGen(cp, i));
+ for(int j=0; j<numMethods; j++) methods.add(new MethodGen(cp, i, this));
attributes = new AttrGen(cp, i);
sourceFile = (String)attributes.get("SourceFile");
}
+++ /dev/null
-package org.ibex.classgen;
-
-/** This class represents Field references. It is used as an argument to the
-GETFIELD, PUTFIELD, GETSTATIC, and PUTSTATCI bytecodes
-@see CGConst#GETFIELD
-@see CGConst#PUTFIELD
-@see CGConst#GETSTATIC
-@see CGConst#PUTSTATIC
-*/
-public class FieldRef extends MemberRef {
- /** Create a reference to field <i>name</i> of class <i>c</i> with the type <i>t</i> */
- public final Type type;
- public FieldRef(Type.Class c, String name, Type t) { super(c, name); this.type = t; }
- public String getDescriptor() { return name; }
-}
-
+++ /dev/null
-package org.ibex.classgen;
-
-import java.util.*;
-import java.io.*;
-
-/** A class representing a field or method reference. This is used as an argument to the INVOKE*, GET*, and PUT* bytecodes
- @see MethodRef
- @see FieldRef
- @see MethodRef.I
- @see FieldRef
-*/
-public abstract class MemberRef {
- public final Type.Class klass;
- public final String name;
-
- MemberRef(Type.Class klass, String name) {
- this.klass = klass;
- this.name = name;
- }
- public abstract String getDescriptor();
- public boolean equals(Object o_) {
- if(!(o_ instanceof MemberRef)) return false;
- MemberRef o = (MemberRef) o_;
- return o.klass.equals(klass) && o.name.equals(name) && o.getDescriptor().equals(getDescriptor());
- }
- public int hashCode() { return klass.hashCode() ^ name.hashCode() ^ getDescriptor().hashCode(); }
-}
-
private static final int NO_CODE = -1;
private static final int FINISHED = -2;
-
+
+ private final ClassFile owner;
private final CPGen cp;
private final String name;
private final Type ret;
// FIXME: attrs, body
}
- MethodGen(CPGen cp, DataInput in) throws IOException {
+ MethodGen(CPGen cp, DataInput in, ClassFile owner) throws IOException {
this.cp = cp;
+ this.owner = owner;
flags = in.readShort();
name = cp.getUtf8ByIndex(in.readShort());
String descriptor = cp.getUtf8ByIndex(in.readShort());
this.ret = ret;
this.args = args;
this.flags = flags;
+ this.owner = owner;
attrs = new ClassFile.AttrGen(cp);
codeAttrs = new ClassFile.AttrGen(cp);
cp.addUtf8(name);
- cp.addUtf8(getDescriptor());
+ cp.addUtf8(owner.getType().method(name, ret, args).getDescriptor());
if((owner.flags & ACC_INTERFACE) != 0 || (flags & (ACC_ABSTRACT|ACC_NATIVE)) != 0) size = capacity = -1;
maxLocals = Math.max(args.length + (flags&ACC_STATIC)==0 ? 1 : 0, 4);
}
- /** Returns the descriptor string for this method */
- public String getDescriptor() { return new MethodRef(null, name, ret, args).getDescriptor(); }
-
private class ExnTableEnt {
public int start;
public int end;
void dump(DataOutput o) throws IOException {
o.writeShort(flags);
o.writeShort(cp.getUtf8Index(name));
- o.writeShort(cp.getUtf8Index(getDescriptor()));
+ o.writeShort(cp.getUtf8Index(owner.getType().method(name, ret, args).getDescriptor()));
o.writeShort(attrs.size());
attrs.dump(o);
}
+++ /dev/null
-package org.ibex.classgen;
-
-/** This class represents Method references. It is used as an argument to the
- INVOKESTATIC, INVOKEVIRTUAL, INVOKESPEICAL, and INVOKEINTERFACE bytecodes
- @see CGConst#INVOKESTATIC
- @see CGConst#INVOKEVIRTUAL
- @see CGConst#INVOKESPECIAL
- @see CGConst#INVOKEINTERFACE
-*/
-public class MethodRef extends MemberRef {
-
- final Type[] argTypes;
- final Type returnType;
-
- /** Create a reference to method <i>name</i> of class <i>c</i> with the return type <i>ret</i> and the
- arguments <i>args</i> */
- public MethodRef(Type.Class c, String name, Type returnType, Type[] argTypes) {
- super(c, name);
- this.argTypes = argTypes;
- this.returnType = returnType;
- }
-
- public String getDescriptor() {
- StringBuffer sb = new StringBuffer(argTypes.length*4);
- sb.append("(");
- for(int i=0;i<argTypes.length;i++) sb.append(argTypes[i].getDescriptor());
- sb.append(")");
- sb.append(returnType.getDescriptor());
- return sb.toString();
- }
-}
for(int i=0;st.hasMoreTokens();i++) a[i] = st.nextToken();
return a;
}
+
+ public Method method(String name, Type returnType, Type[] argTypes) { return new Method(name, returnType, argTypes); }
+ public Field field(String name, Type type) { return new Field(name, type); }
+
+ public abstract class Member {
+ public final String name;
+ private Member(String name) { this.name = name; }
+ public Type.Class getDeclaringClass() { return Type.Class.this; }
+ public abstract String getDescriptor();
+ public boolean equals(Object o_) {
+ if(!(o_ instanceof Member)) return false;
+ Member o = (Member) o_;
+ return o.getDeclaringClass().equals(getDeclaringClass()) &&
+ o.name.equals(name) &&
+ o.getDescriptor().equals(getDescriptor());
+ }
+ public int hashCode() { return getDeclaringClass().hashCode() ^ name.hashCode() ^ getDescriptor().hashCode(); }
+ }
+
+ public class Field extends Member {
+ /** Create a reference to field <i>name</i> of class <i>c</i> with the type <i>t</i> */
+ public final Type type;
+ private Field(String name, Type t) { super(name); this.type = t; }
+ public String getDescriptor() { return name; }
+ }
+
+ public class Method extends Member {
+ final Type[] argTypes;
+ final Type returnType;
+ private Method(String name, Type returnType, Type[] argTypes) {
+ super(name);
+ this.argTypes = argTypes;
+ this.returnType = returnType;
+ }
+ public String getDescriptor() {
+ StringBuffer sb = new StringBuffer(argTypes.length*4);
+ sb.append("(");
+ for(int i=0;i<argTypes.length;i++) sb.append(argTypes[i].getDescriptor());
+ sb.append(")");
+ sb.append(returnType.getDescriptor());
+ return sb.toString();
+ }
+ }
+
}
public static class Array extends Type.Ref {