diff --git a/pom.xml b/pom.xml index 2d81ee4da58e2e075f39b0f0834a493757931e4c..7ba0cd6f10e7d7f1e06bcde10ea3106c83b7ebd4 100644 --- a/pom.xml +++ b/pom.xml @@ -93,6 +93,11 @@ <groupId>junit</groupId> <artifactId>junit</artifactId> </dependency> + <dependency> + <groupId>org.apache.bcel</groupId> + <artifactId>bcel</artifactId> + <version>6.2</version> + </dependency> </dependencies> <build> diff --git a/src/main/java/com/aparapi/internal/model/ClassModel.java b/src/main/java/com/aparapi/internal/model/ClassModel.java index 8c3e982f373855d109909aa8468e78efd98673d7..bbbf9b470ebd167c65e2b9324f1385fe5a64cf2e 100644 --- a/src/main/java/com/aparapi/internal/model/ClassModel.java +++ b/src/main/java/com/aparapi/internal/model/ClassModel.java @@ -61,9 +61,14 @@ import com.aparapi.internal.model.ClassModel.AttributePool.*; import com.aparapi.internal.model.ClassModel.ConstantPool.*; import com.aparapi.internal.reader.*; import com.aparapi.internal.util.*; +import org.apache.bcel.Const; +import org.apache.bcel.Repository; +import org.apache.bcel.classfile.*; +import org.apache.bcel.classfile.Constant; import java.io.*; -import java.lang.reflect.*; +import java.lang.reflect.Field; +import java.lang.reflect.Method; import java.util.*; import java.util.logging.*; @@ -177,10 +182,14 @@ public class ClassModel { */ private ClassModel(Class<?> _class) throws ClassParseException { - - parse(_class); - - final Class<?> mySuper = _class.getSuperclass(); + clazz = _class; + try { + parse(_class); + } catch (ClassNotFoundException e) { + e.printStackTrace(); + } + + final Class<?> mySuper = _class.getSuperclass(); // Find better way to do this check // The java.lang.Object test is for unit test framework to succeed - should // not occur in normal use @@ -190,15 +199,19 @@ public class ClassModel { } } - ClassModel(InputStream _inputStream) throws ClassParseException { - - parse(_inputStream); - - } +// ClassModel(InputStream _inputStream) throws ClassParseException { +// +// parse(_inputStream); +// +// } ClassModel(Class<?> _clazz, byte[] _bytes) throws ClassParseException { clazz = _clazz; - parse(new ByteArrayInputStream(_bytes)); + try { + parse(clazz); + } catch (ClassNotFoundException e) { + e.printStackTrace(); + } } /** @@ -773,7 +786,7 @@ public class ClassModel { private final int slot; - public Entry(ByteReader _byteReader, int _slot, ConstantPoolType _constantPoolType) { + public Entry(int _slot, ConstantPoolType _constantPoolType) { constantPoolType = _constantPoolType; slot = _slot; } @@ -794,9 +807,9 @@ public class ClassModel { public class ClassEntry extends Entry{ private final int nameIndex; - public ClassEntry(ByteReader _byteReader, int _slot) { - super(_byteReader, _slot, ConstantPoolType.CLASS); - nameIndex = _byteReader.u2(); + public ClassEntry(int _nameIndex, int _slot) { + super(_slot, ConstantPoolType.CLASS); + nameIndex = _nameIndex; } public int getNameIndex() { @@ -811,9 +824,9 @@ public class ClassModel { public class DoubleEntry extends Entry{ private final double doubleValue; - public DoubleEntry(ByteReader _byteReader, int _slot) { - super(_byteReader, _slot, ConstantPoolType.DOUBLE); - doubleValue = _byteReader.d8(); + public DoubleEntry(double _doubleValue, int _slot) { + super(_slot, ConstantPoolType.DOUBLE); + doubleValue = _doubleValue; } public double getDoubleValue() { @@ -822,23 +835,23 @@ public class ClassModel { } public class EmptyEntry extends Entry{ - public EmptyEntry(ByteReader _byteReader, int _slot) { - super(_byteReader, _slot, ConstantPoolType.EMPTY); + public EmptyEntry(int _slot) { + super(_slot, ConstantPoolType.EMPTY); } } public class FieldEntry extends ReferenceEntry{ - public FieldEntry(ByteReader _byteReader, int _slot) { - super(_byteReader, _slot, ConstantPoolType.FIELD); + public FieldEntry(int _referenceClassIndex, int _nameAndTypeIndex, int _slot) { + super(_referenceClassIndex, _nameAndTypeIndex, _slot, ConstantPoolType.FIELD); } } public class FloatEntry extends Entry{ private final float floatValue; - public FloatEntry(ByteReader _byteReader, int _slot) { - super(_byteReader, _slot, ConstantPoolType.FLOAT); - floatValue = _byteReader.f4(); + public FloatEntry(float _floatVal, int _slot) { + super(_slot, ConstantPoolType.FLOAT); + floatValue = _floatVal; } public float getFloatValue() { @@ -849,9 +862,9 @@ public class ClassModel { public class IntegerEntry extends Entry{ private final int intValue; - public IntegerEntry(ByteReader _byteReader, int _slot) { - super(_byteReader, _slot, ConstantPoolType.INTEGER); - intValue = _byteReader.u4(); + public IntegerEntry(int val, int _slot) { + super(_slot, ConstantPoolType.INTEGER); + intValue = val; } public int getIntValue() { @@ -860,17 +873,17 @@ public class ClassModel { } public class InterfaceMethodEntry extends MethodReferenceEntry{ - InterfaceMethodEntry(ByteReader _byteReader, int _slot) { - super(_byteReader, _slot, ConstantPoolType.INTERFACEMETHOD); + InterfaceMethodEntry(int _referenceClassIndex, int _nameAndTypeIndex, int _slot) { + super(_referenceClassIndex, _nameAndTypeIndex, _slot, ConstantPoolType.INTERFACEMETHOD); } } public class LongEntry extends Entry{ private final long longValue; - public LongEntry(ByteReader _byteReader, int _slot) { - super(_byteReader, _slot, ConstantPoolType.LONG); - longValue = _byteReader.u8(); + public LongEntry(long val, int _slot) { + super(_slot, ConstantPoolType.LONG); + longValue = val; } public long getLongValue() { @@ -879,8 +892,8 @@ public class ClassModel { } public class MethodEntry extends MethodReferenceEntry{ - public MethodEntry(ByteReader _byteReader, int _slot) { - super(_byteReader, _slot, ConstantPoolType.METHOD); + public MethodEntry(int _referenceClassIndex, int _nameAndTypeIndex, int _slot) { + super(_referenceClassIndex, _nameAndTypeIndex, _slot, ConstantPoolType.METHOD); } @Override @@ -899,10 +912,10 @@ public class ClassModel { private final int nameIndex; - public NameAndTypeEntry(ByteReader _byteReader, int _slot) { - super(_byteReader, _slot, ConstantPoolType.NAMEANDTYPE); - nameIndex = _byteReader.u2(); - descriptorIndex = _byteReader.u2(); + public NameAndTypeEntry(int _nameIndex, int _descriptorIndex, int _slot) { + super(_slot, ConstantPoolType.NAMEANDTYPE); + nameIndex = _nameIndex; + descriptorIndex = _descriptorIndex; } public int getDescriptorIndex() { @@ -925,9 +938,9 @@ public class ClassModel { class MethodTypeEntry extends Entry{ private int descriptorIndex; - MethodTypeEntry(ByteReader _byteReader, int _slot) { - super(_byteReader, _slot, ConstantPoolType.METHODTYPE); - descriptorIndex = _byteReader.u2(); + MethodTypeEntry(int _descriptorIndex, int _slot) { + super(_slot, ConstantPoolType.METHODTYPE); + descriptorIndex = _descriptorIndex; } int getDescriptorIndex() { @@ -947,10 +960,10 @@ public class ClassModel { private int referenceIndex; - MethodHandleEntry(ByteReader _byteReader, int _slot) { - super(_byteReader, _slot, ConstantPoolType.METHODHANDLE); - referenceKind = _byteReader.u1(); - referenceIndex = _byteReader.u2(); + MethodHandleEntry(int _referenceKind, int _referenceIndex, int _slot) { + super(_slot, ConstantPoolType.METHODHANDLE); + referenceKind = _referenceKind; + referenceIndex = _referenceIndex; } int getReferenceIndex() { @@ -970,10 +983,10 @@ public class ClassModel { private int nameAndTypeIndex; - InvokeDynamicEntry(ByteReader _byteReader, int _slot) { - super(_byteReader, _slot, ConstantPoolType.INVOKEDYNAMIC); - bootstrapMethodAttrIndex = _byteReader.u2(); - nameAndTypeIndex = _byteReader.u2(); + InvokeDynamicEntry(int _bootstrapMethodAttrIndex, int _nameAndTypeIndex, int _slot) { + super(_slot, ConstantPoolType.INVOKEDYNAMIC); + bootstrapMethodAttrIndex = _bootstrapMethodAttrIndex; + nameAndTypeIndex = _nameAndTypeIndex; } int getBootstrapMethodAttrIndex() { @@ -1024,8 +1037,8 @@ public class ClassModel { } } - public MethodReferenceEntry(ByteReader byteReader, int slot, ConstantPoolType constantPoolType) { - super(byteReader, slot, constantPoolType); + public MethodReferenceEntry(int _referenceClassIndex, int _nameAndTypeIndex, int slot, ConstantPoolType constantPoolType) { + super(_referenceClassIndex, _nameAndTypeIndex, slot, constantPoolType); } @@ -1127,10 +1140,10 @@ public class ClassModel { protected int argCount = -1; - public ReferenceEntry(ByteReader _byteReader, int _slot, ConstantPoolType _constantPoolType) { - super(_byteReader, _slot, _constantPoolType); - referenceClassIndex = _byteReader.u2(); - nameAndTypeIndex = _byteReader.u2(); + public ReferenceEntry(int _referenceClassIndex, int _nameAndTypeIndex, int _slot, ConstantPoolType _constantPoolType) { + super(_slot, _constantPoolType); + referenceClassIndex = _referenceClassIndex; + nameAndTypeIndex = _nameAndTypeIndex; } public ClassEntry getClassEntry() { @@ -1193,9 +1206,9 @@ public class ClassModel { public class StringEntry extends Entry{ private final int utf8Index; - public StringEntry(ByteReader _byteReader, int _slot) { - super(_byteReader, _slot, ConstantPoolType.STRING); - utf8Index = _byteReader.u2(); + public StringEntry(int _utf8Index, int _slot) { + super(_slot, ConstantPoolType.STRING); + utf8Index = _utf8Index; } public int getUTF8Index() { @@ -1210,9 +1223,9 @@ public class ClassModel { public class UTF8Entry extends Entry{ private final String UTF8; - public UTF8Entry(ByteReader _byteReader, int _slot) { - super(_byteReader, _slot, ConstantPoolType.UTF8); - UTF8 = _byteReader.utf8(); + public UTF8Entry(String _utf8, int _slot) { + super(_slot, ConstantPoolType.UTF8); + UTF8 = _utf8; } public String getUTF8() { @@ -1220,62 +1233,81 @@ public class ClassModel { } } - public ConstantPool(ByteReader _byteReader) { - final int size = _byteReader.u2(); - add(new EmptyEntry(_byteReader, 0)); // slot 0 + public ConstantPool(JavaClass cls) { + org.apache.bcel.classfile.ConstantPool cp = cls.getConstantPool(); + final int size = cp.getLength(); + add(new EmptyEntry(0)); // slot 0 for (int i = 1; i < size; i++) { - final ConstantPoolType constantPoolType = ConstantPoolType.values()[_byteReader.u1()]; - - switch (constantPoolType) { - case UTF8: - add(new UTF8Entry(_byteReader, i)); - break; - case INTEGER: - add(new IntegerEntry(_byteReader, i)); - break; - case FLOAT: - add(new FloatEntry(_byteReader, i)); - break; - case LONG: - add(new LongEntry(_byteReader, i)); - i++;// Longs take two slots in the ConstantPool - add(new EmptyEntry(_byteReader, i)); - break; - case DOUBLE: - add(new DoubleEntry(_byteReader, i)); - i++; // Doubles take two slots in the ConstantPool - add(new EmptyEntry(_byteReader, i)); - break; - case CLASS: - add(new ClassEntry(_byteReader, i)); - break; - case STRING: - add(new StringEntry(_byteReader, i)); - break; - case FIELD: - add(new FieldEntry(_byteReader, i)); - break; - case METHOD: - add(new MethodEntry(_byteReader, i)); - break; - case INTERFACEMETHOD: - add(new InterfaceMethodEntry(_byteReader, i)); - break; - case NAMEANDTYPE: - add(new NameAndTypeEntry(_byteReader, i)); - break; - case METHODHANDLE: - add(new MethodHandleEntry(_byteReader, i)); - break; - case METHODTYPE: - add(new MethodTypeEntry(_byteReader, i)); - break; - case INVOKEDYNAMIC: - add(new InvokeDynamicEntry(_byteReader, i)); - break; - default: - System.out.printf("slot %04x unexpected Constant constantPoolType = %s\n", i, constantPoolType); + final Constant constant = cp.getConstant(i); + if (constant != null) { + final byte tag = constant.getTag(); + switch (tag) { + case Const.CONSTANT_Class: + final int ni = ((ConstantClass) constant).getNameIndex(); + add(new ClassEntry(ni, i)); + break; + case Const.CONSTANT_String: + final int si = ((ConstantString) constant).getStringIndex(); + add(new StringEntry(si, i)); + break; + case Const.CONSTANT_Utf8: + add(new UTF8Entry(((ConstantUtf8) constant).getBytes(), i)); + break; + case Const.CONSTANT_Double: + add(new DoubleEntry(((ConstantDouble) constant).getBytes(), i)); + break; + case Const.CONSTANT_Float: + add(new FloatEntry(((ConstantFloat) constant).getBytes(), i)); + break; + case Const.CONSTANT_Long: + add(new LongEntry(((ConstantLong) constant).getBytes(), i)); + break; + case Const.CONSTANT_Integer: + add(new IntegerEntry(((ConstantInteger) constant).getBytes(), i)); + break; + case Const.CONSTANT_NameAndType: + final int ntInd = ((ConstantNameAndType) constant).getNameIndex(); + final int siNT = ((ConstantNameAndType) constant).getSignatureIndex(); + add(new NameAndTypeEntry(ntInd, siNT, i)); + break; + case Const.CONSTANT_InterfaceMethodref: + final int refClassIndexIMR = ((ConstantCP) constant).getClassIndex(); + final int nameAndTypeIndIMR = ((ConstantCP) constant).getNameAndTypeIndex(); + add(new InterfaceMethodEntry(refClassIndexIMR, nameAndTypeIndIMR, i)); + break; + case Const.CONSTANT_Methodref: + final int refClassIndexM = ((ConstantCP) constant).getClassIndex(); + final int nameAndTypeIndM = ((ConstantCP) constant).getNameAndTypeIndex(); + add(new MethodEntry(refClassIndexM, nameAndTypeIndM, i)); + break; + case Const.CONSTANT_Fieldref: + final int refClassIndex = ((ConstantCP) constant).getClassIndex(); + final int nameAndTypeInd = ((ConstantCP) constant).getNameAndTypeIndex(); + add(new FieldEntry(refClassIndex, nameAndTypeInd, i)); + break; + case Const.CONSTANT_MethodHandle: + final ConstantMethodHandle cmh = (ConstantMethodHandle) constant; + final int refKind = cmh.getReferenceKind(); + final int refInd = cmh.getReferenceIndex(); + add(new MethodHandleEntry(refKind, refInd, i)); + break; + case Const.CONSTANT_MethodType: + final ConstantMethodType cmt = (ConstantMethodType) constant; + final int descInd = cmt.getDescriptorIndex(); + add(new MethodTypeEntry(descInd, i)); + break; + case Const.CONSTANT_InvokeDynamic: + final ConstantInvokeDynamic cid = (ConstantInvokeDynamic) constant; + final int bsMethAttInd = cid.getBootstrapMethodAttrIndex(); + final int ntIndID = cid.getNameAndTypeIndex(); + add(new InvokeDynamicEntry(bsMethAttInd, ntIndID, i)); + break; + default: + System.out.printf("slot %04x unexpected Constant constantPoolType = %s\n", i, constant); + } + } else { + add(new EmptyEntry(i)); } } } @@ -1595,11 +1627,11 @@ public class ClassModel { private final int start; - public ExceptionPoolEntry(ByteReader _byteReader) { - start = _byteReader.u2(); - end = _byteReader.u2(); - handler = _byteReader.u2(); - exceptionClassIndex = _byteReader.u2(); + public ExceptionPoolEntry(int _start, int _end, int _handler, int _exceptionClassIndex) { + start = _start; + end = _end; + handler = _handler; + exceptionClassIndex = _exceptionClassIndex; } public ConstantPool.ClassEntry getClassEntry() { @@ -1633,19 +1665,16 @@ public class ClassModel { private final int maxStack; - public CodeEntry(ByteReader _byteReader, int _nameIndex, int _length) { - super(_byteReader, _nameIndex, _length); - maxStack = _byteReader.u2(); - maxLocals = _byteReader.u2(); - final int codeLength = _byteReader.u4(); - code = _byteReader.bytes(codeLength); - final int exceptionTableLength = _byteReader.u2(); - - for (int i = 0; i < exceptionTableLength; i++) { - exceptionPoolEntries.add(new ExceptionPoolEntry(_byteReader)); + public CodeEntry(Code c) { + super(c.getNameIndex(), c.getLength()); + maxStack = c.getMaxStack(); + maxLocals = c.getMaxLocals(); + code = c.getCode(); + for (CodeException i : c.getExceptionTable()) { + exceptionPoolEntries.add(new ExceptionPoolEntry(i.getStartPC(), i.getEndPC(), i.getHandlerPC(), i.getCatchType())); } - codeEntryAttributePool = new AttributePool(_byteReader, getName()); + codeEntryAttributePool = new AttributePool(c.getAttributes(), getName()); } @Override @@ -1653,9 +1682,9 @@ public class ClassModel { return (codeEntryAttributePool); } - public LineNumberTableEntry getLineNumberTableEntry() { - return (codeEntryAttributePool.getLineNumberTableEntry()); - } +// public LineNumberTableEntry getLineNumberTableEntry() { +// return (codeEntryAttributePool.getLineNumberTableEntry()); +// } public int getMaxLocals() { return (maxLocals); @@ -1677,9 +1706,9 @@ public class ClassModel { public class ConstantValueEntry extends AttributePoolEntry{ private final int index; - public ConstantValueEntry(ByteReader _byteReader, int _nameIndex, int _length) { - super(_byteReader, _nameIndex, _length); - index = _byteReader.u2(); + public ConstantValueEntry(int _index, int _nameIndex, int _length) { + super(_nameIndex, _length); + index = _index; } public int getIndex() { @@ -1689,8 +1718,8 @@ public class ClassModel { } public class DeprecatedEntry extends AttributePoolEntry{ - public DeprecatedEntry(ByteReader _byteReader, int _nameIndex, int _length) { - super(_byteReader, _nameIndex, _length); + public DeprecatedEntry(int _nameIndex, int _length) { + super(_nameIndex, _length); } } @@ -1699,7 +1728,7 @@ public class ClassModel { protected int nameIndex; - public AttributePoolEntry(ByteReader _byteReader, int _nameIndex, int _length) { + public AttributePoolEntry(int _nameIndex, int _length) { nameIndex = _nameIndex; length = _length; } @@ -1728,8 +1757,8 @@ public class ClassModel { return (pool); } - public PoolEntry(ByteReader _byteReader, int _nameIndex, int _length) { - super(_byteReader, _nameIndex, _length); + public PoolEntry(int _nameIndex, int _length) { + super(_nameIndex, _length); } @Override @@ -1739,11 +1768,10 @@ public class ClassModel { } public class ExceptionEntry extends PoolEntry<Integer>{ - public ExceptionEntry(ByteReader _byteReader, int _nameIndex, int _length) { - super(_byteReader, _nameIndex, _length); - final int exceptionTableLength = _byteReader.u2(); - for (int i = 0; i < exceptionTableLength; i++) { - getPool().add(_byteReader.u2()); + public ExceptionEntry(int []_exceptionIndices, int _nameIndex, int _length) { + super(_nameIndex, _length); + for (int i : _exceptionIndices) { + getPool().add(i); } } } @@ -1758,11 +1786,11 @@ public class ClassModel { private final int outerIndex; - public InnerClassInfo(ByteReader _byteReader) { - innerIndex = _byteReader.u2(); - outerIndex = _byteReader.u2(); - innerNameIndex = _byteReader.u2(); - innerAccess = _byteReader.u2(); + public InnerClassInfo(int _innerIndex, int _outerIndex, int _innerNameIndex, int _innerAccess) { + innerIndex = _innerIndex; + outerIndex = _outerIndex; + innerNameIndex = _innerNameIndex; + innerAccess = _innerAccess; } public int getInnerAccess() { @@ -1782,11 +1810,10 @@ public class ClassModel { } } - public InnerClassesEntry(ByteReader _byteReader, int _nameIndex, int _length) { - super(_byteReader, _nameIndex, _length); - final int innerClassesTableLength = _byteReader.u2(); - for (int i = 0; i < innerClassesTableLength; i++) { - getPool().add(new InnerClassInfo(_byteReader)); + public InnerClassesEntry(InnerClass []_innerClasses, int _nameIndex, int _length) { + super(_nameIndex, _length); + for (InnerClass i : _innerClasses) { + getPool().add(new InnerClassInfo(i.getInnerClassIndex(), i.getOuterClassIndex(), i.getInnerNameIndex(), i.getInnerAccessFlags())); } } } @@ -1798,9 +1825,9 @@ public class ClassModel { private final int start; - public StartLineNumberPair(ByteReader _byteReader) { - start = _byteReader.u2(); - lineNumber = _byteReader.u2(); + public StartLineNumberPair(int _start, int _lineNumber) { + start = _start; + lineNumber = _lineNumber; } public int getLineNumber() { @@ -1812,11 +1839,10 @@ public class ClassModel { } } - public LineNumberTableEntry(ByteReader _byteReader, int _nameIndex, int _length) { - super(_byteReader, _nameIndex, _length); - final int lineNumberTableLength = _byteReader.u2(); - for (int i = 0; i < lineNumberTableLength; i++) { - getPool().add(new StartLineNumberPair(_byteReader)); + public LineNumberTableEntry(LineNumber []linums, int _nameIndex, int _length) { + super(_nameIndex, _length); + for (LineNumber i : linums) { + getPool().add(new StartLineNumberPair(i.getStartPC(), i.getLineNumber())); } } @@ -1850,10 +1876,10 @@ public class ClassModel { public class EnclosingMethodEntry extends AttributePoolEntry{ - public EnclosingMethodEntry(ByteReader _byteReader, int _nameIndex, int _length) { - super(_byteReader, _nameIndex, _length); - enclosingClassIndex = _byteReader.u2(); - enclosingMethodIndex = _byteReader.u2(); + public EnclosingMethodEntry(int _enclosingClassIndex, int _enclosingMethodIndex, int _nameIndex, int _length) { + super(_nameIndex, _length); + enclosingClassIndex = _enclosingClassIndex; + enclosingMethodIndex = _enclosingMethodIndex; } private final int enclosingClassIndex; @@ -1871,9 +1897,9 @@ public class ClassModel { public class SignatureEntry extends AttributePoolEntry{ - public SignatureEntry(ByteReader _byteReader, int _nameIndex, int _length) { - super(_byteReader, _nameIndex, _length); - signatureIndex = _byteReader.u2(); + public SignatureEntry(int _signatureIndex, int _nameIndex, int _length) { + super(_nameIndex, _length); + signatureIndex = _signatureIndex; } private final int signatureIndex; @@ -1897,12 +1923,12 @@ public class ClassModel { private final int variableIndex; - public RealLocalVariableInfo(ByteReader _byteReader) { - start = _byteReader.u2(); - usageLength = _byteReader.u2(); - variableNameIndex = _byteReader.u2(); - descriptorIndex = _byteReader.u2(); - variableIndex = _byteReader.u2(); + public RealLocalVariableInfo(int _start, int _usageLength, int _variableNameIndex, int _descriptorIndex, int _variableIndex) { + start = _start; + usageLength = _usageLength; + variableNameIndex = _variableNameIndex; + descriptorIndex = _descriptorIndex; + variableIndex = _variableIndex; } public int getDescriptorIndex() { @@ -1948,11 +1974,10 @@ public class ClassModel { } } - public RealLocalVariableTableEntry(ByteReader _byteReader, int _nameIndex, int _length) { - super(_byteReader, _nameIndex, _length); - final int localVariableTableLength = _byteReader.u2(); - for (int i = 0; i < localVariableTableLength; i++) { - getPool().add(new RealLocalVariableInfo(_byteReader)); + public RealLocalVariableTableEntry(LocalVariable []locals, int _nameIndex, int _length) { + super(_nameIndex, _length); + for (LocalVariable i : locals) { + getPool().add(new RealLocalVariableInfo(i.getStartPC(), i.getLength(), i.getNameIndex(), i.getSignatureIndex(), i.getIndex())); } } @@ -1990,19 +2015,19 @@ public class ClassModel { // http://docs.oracle.com/javase/specs/jvms/se7/html/jvms-4.html#jvms-4.7.21 class BootstrapMethod{ class BootstrapArgument{ - public BootstrapArgument(ByteReader _byteReader) { - argument = _byteReader.u2(); + public BootstrapArgument(int _argument) { + argument = _argument; } int argument;// u2; } - public BootstrapMethod(ByteReader _byteReader) { - bootstrapMethodRef = _byteReader.u2(); - numBootstrapArguments = _byteReader.u2(); + public BootstrapMethod(org.apache.bcel.classfile.BootstrapMethod m) { + bootstrapMethodRef = m.getBootstrapMethodRef(); + numBootstrapArguments = m.getNumBootstrapArguments(); bootstrapArguments = new BootstrapArgument[numBootstrapArguments]; for (int i = 0; i < numBootstrapArguments; i++) { - bootstrapArguments[i] = new BootstrapArgument(_byteReader); + bootstrapArguments[i] = new BootstrapArgument(m.getBootstrapArguments()[i]); } } @@ -2013,12 +2038,13 @@ public class ClassModel { BootstrapArgument bootstrapArguments[]; } - BootstrapMethodsEntry(ByteReader _byteReader, int _nameIndex, int _length) { - super(_byteReader, _nameIndex, _length); - numBootstrapMethods = _byteReader.u2(); + BootstrapMethodsEntry(org.apache.bcel.classfile.BootstrapMethod [] methods, int _nameIndex, int _length) { + super( _nameIndex, _length); bootstrapMethods = new BootstrapMethod[numBootstrapMethods]; - for (int i = 0; i < numBootstrapMethods; i++) { - bootstrapMethods[i] = new BootstrapMethod(_byteReader); + int i = 0; + for (org.apache.bcel.classfile.BootstrapMethod bm : methods) { + bootstrapMethods[i] = new BootstrapMethod(bm); + i += 1; } } @@ -2035,9 +2061,9 @@ public class ClassModel { public class OtherEntry extends AttributePoolEntry{ private final byte[] bytes; - public OtherEntry(ByteReader _byteReader, int _nameIndex, int _length) { - super(_byteReader, _nameIndex, _length); - bytes = _byteReader.bytes(_length); + public OtherEntry(byte []_bytes, int _nameIndex, int _length) { + super(_nameIndex, _length); + bytes = _bytes; } public byte[] getBytes() { @@ -2054,9 +2080,9 @@ public class ClassModel { class StackMapTableEntry extends AttributePoolEntry{ private byte[] bytes; - StackMapTableEntry(ByteReader _byteReader, int _nameIndex, int _length) { - super(_byteReader, _nameIndex, _length); - bytes = _byteReader.bytes(_length); + StackMapTableEntry(byte []_bytes, int _nameIndex, int _length) { + super(_nameIndex, _length); + bytes = _bytes; } byte[] getBytes() { @@ -2072,9 +2098,9 @@ public class ClassModel { public class LocalVariableTypeTableEntry extends AttributePoolEntry{ private byte[] bytes; - public LocalVariableTypeTableEntry(ByteReader _byteReader, int _nameIndex, int _length) { - super(_byteReader, _nameIndex, _length); - bytes = _byteReader.bytes(_length); + public LocalVariableTypeTableEntry(byte []_bytes, int _nameIndex, int _length) { + super(_nameIndex, _length); + bytes = _bytes; } public byte[] getBytes() { @@ -2090,9 +2116,9 @@ public class ClassModel { public class SourceFileEntry extends AttributePoolEntry{ private final int sourceFileIndex; - public SourceFileEntry(ByteReader _byteReader, int _nameIndex, int _length) { - super(_byteReader, _nameIndex, _length); - sourceFileIndex = _byteReader.u2(); + public SourceFileEntry(int _nameIndex, int _length, int _sourceFileIndex) { + super(_nameIndex, _length); + sourceFileIndex = _sourceFileIndex; } public int getSourceFileIndex() { @@ -2105,8 +2131,8 @@ public class ClassModel { } public class SyntheticEntry extends AttributePoolEntry{ - public SyntheticEntry(ByteReader _byteReader, int _nameIndex, int _length) { - super(_byteReader, _nameIndex, _length); + public SyntheticEntry(int _nameIndex, int _length) { + super(_nameIndex, _length); } } @@ -2132,9 +2158,9 @@ public class ClassModel { private final int constNameIndex; - public PrimitiveValue(int _tag, ByteReader _byteReader) { + public PrimitiveValue(int _tag, int _typeNameIndex) { super(_tag); - typeNameIndex = _byteReader.u2(); + typeNameIndex = _typeNameIndex; //constNameIndex = _byteReader.u2(); constNameIndex = 0; } @@ -2149,25 +2175,25 @@ public class ClassModel { } public class EnumValue extends Value{ - EnumValue(int _tag, ByteReader _byteReader) { + EnumValue(int _tag) { super(_tag); } } public class ArrayValue extends Value{ - ArrayValue(int _tag, ByteReader _byteReader) { + ArrayValue(int _tag) { super(_tag); } } public class ClassValue extends Value{ - ClassValue(int _tag, ByteReader _byteReader) { + ClassValue(int _tag) { super(_tag); } } public class AnnotationValue extends Value{ - AnnotationValue(int _tag, ByteReader _byteReader) { + AnnotationValue(int _tag) { super(_tag); } } @@ -2178,9 +2204,9 @@ public class ClassModel { @SuppressWarnings("unused") private Value value; - public ElementValuePair(ByteReader _byteReader) { - elementNameIndex = _byteReader.u2(); - final int tag = _byteReader.u1(); + public ElementValuePair(int _elementNameIndex, int _tag) { + elementNameIndex = _elementNameIndex; + final int tag = _tag; switch (tag) { case SIGC_BYTE: @@ -2192,19 +2218,19 @@ public class ClassModel { case SIGC_SHORT: case SIGC_BOOLEAN: case 's': // special for String - value = new PrimitiveValue(tag, _byteReader); + value = new PrimitiveValue(tag, _elementNameIndex); break; case 'e': // special for Enum - value = new EnumValue(tag, _byteReader); + value = new EnumValue(tag); break; case 'c': // special for class - value = new ClassValue(tag, _byteReader); + value = new ClassValue(tag); break; case '@': // special for Annotation - value = new AnnotationValue(tag, _byteReader); + value = new AnnotationValue(tag); break; case 'a': // special for array - value = new ArrayValue(tag, _byteReader); + value = new ArrayValue(tag); break; } } @@ -2212,12 +2238,14 @@ public class ClassModel { private final ElementValuePair[] elementValuePairs; - public AnnotationInfo(ByteReader _byteReader) { - typeIndex = _byteReader.u2(); - elementValuePairCount = _byteReader.u2(); + public AnnotationInfo(org.apache.bcel.classfile.ElementValuePair []pairs, int _typeIndex) { + typeIndex = _typeIndex; + elementValuePairCount = pairs.length; elementValuePairs = new ElementValuePair[elementValuePairCount]; - for (int i = 0; i < elementValuePairCount; i++) { - elementValuePairs[i] = new ElementValuePair(_byteReader); + int i = 0; + for (org.apache.bcel.classfile.ElementValuePair p : pairs) { + elementValuePairs[i] = new ElementValuePair(p.getNameIndex(), p.getValue().getElementValueType()); + i += 1; } } @@ -2230,11 +2258,10 @@ public class ClassModel { } } - public RuntimeAnnotationsEntry(ByteReader _byteReader, int _nameIndex, int _length) { - super(_byteReader, _nameIndex, _length); - final int localVariableTableLength = _byteReader.u2(); - for (int i = 0; i < localVariableTableLength; i++) { - getPool().add(new AnnotationInfo(_byteReader)); + public RuntimeAnnotationsEntry(AnnotationEntry []entries, int _nameIndex, int _length) { + super(_nameIndex, _length); + for (AnnotationEntry ae : entries) { + getPool().add(new AnnotationInfo(ae.getElementValuePairs(), ae.getAnnotationTypeIndex())); } } @@ -2264,9 +2291,9 @@ public class ClassModel { private final int constNameIndex; - public PrimitiveValue(int _tag, ByteReader _byteReader) { + public PrimitiveValue(int _tag, int _typeNameIndex) { super(_tag); - typeNameIndex = _byteReader.u2(); + typeNameIndex = _typeNameIndex; //constNameIndex = _byteReader.u2(); constNameIndex = 0; } @@ -2281,25 +2308,25 @@ public class ClassModel { } public class EnumValue extends Value{ - EnumValue(int _tag, ByteReader _byteReader) { + EnumValue(int _tag) { super(_tag); } } public class ArrayValue extends Value{ - ArrayValue(int _tag, ByteReader _byteReader) { + ArrayValue(int _tag) { super(_tag); } } public class ClassValue extends Value{ - ClassValue(int _tag, ByteReader _byteReader) { + ClassValue(int _tag) { super(_tag); } } public class AnnotationValue extends Value{ - AnnotationValue(int _tag, ByteReader _byteReader) { + AnnotationValue(int _tag) { super(_tag); } } @@ -2310,9 +2337,9 @@ public class ClassModel { @SuppressWarnings("unused") private Value value; - public ElementValuePair(ByteReader _byteReader) { - elementNameIndex = _byteReader.u2(); - final int tag = _byteReader.u1(); + public ElementValuePair(int _elementNameIndex, int _tag) { + elementNameIndex = _elementNameIndex; + final int tag = _tag; switch (tag) { case SIGC_BYTE: @@ -2324,19 +2351,19 @@ public class ClassModel { case SIGC_SHORT: case SIGC_BOOLEAN: case 's': // special for String - value = new PrimitiveValue(tag, _byteReader); + value = new PrimitiveValue(tag, _elementNameIndex); break; case 'e': // special for Enum - value = new EnumValue(tag, _byteReader); + value = new EnumValue(tag); break; case 'c': // special for class - value = new ClassValue(tag, _byteReader); + value = new ClassValue(tag); break; case '@': // special for Annotation - value = new AnnotationValue(tag, _byteReader); + value = new AnnotationValue(tag); break; case 'a': // special for array - value = new ArrayValue(tag, _byteReader); + value = new ArrayValue(tag); break; } } @@ -2344,13 +2371,15 @@ public class ClassModel { private final ElementValuePair[] elementValuePairs; - public AnnotationInfo(ByteReader _byteReader, int argumentIndex) { + public AnnotationInfo(int argumentIndex, int _typeIndex, org.apache.bcel.classfile.ElementValuePair []pairs) { methodArgumentIndex = argumentIndex; - typeIndex = _byteReader.u2(); - elementValuePairCount = _byteReader.u2(); + typeIndex = _typeIndex; + elementValuePairCount = pairs.length; elementValuePairs = new ElementValuePair[elementValuePairCount]; - for (int i = 0; i < elementValuePairCount; i++) { - elementValuePairs[i] = new ElementValuePair(_byteReader); + int i = 0; + for (org.apache.bcel.classfile.ElementValuePair p : pairs) { + elementValuePairs[i] = new ElementValuePair(p.getNameIndex(), p.getValue().getElementValueType()); + i += 1; } } @@ -2367,12 +2396,12 @@ public class ClassModel { } } - public ParameterInfo(ByteReader _byteReader, int argumentIndex) { + public ParameterInfo(int argumentIndex, AnnotationEntry []entries) { methodArgumentIndex = argumentIndex; - final int numberOfAnnotations = _byteReader.u2(); + final int numberOfAnnotations = entries.length; annotations = new ArrayList<AnnotationInfo>(numberOfAnnotations); - for (int i = 0; i < numberOfAnnotations; i++) { - annotations.add(new AnnotationInfo(_byteReader, argumentIndex)); + for (AnnotationEntry ae : entries) { + annotations.add(new AnnotationInfo(argumentIndex, ae.getAnnotationTypeIndex(), ae.getElementValuePairs())); } } @@ -2386,11 +2415,13 @@ public class ClassModel { } //See https://docs.oracle.com/javase/specs/jvms/se7/html/jvms-4.html#jvms-4.7.18 - public RuntimeParameterAnnotationsEntry(ByteReader _byteReader, int _nameIndex, int _length) { - super(_byteReader, _nameIndex, _length); - final int numberOfParameters = _byteReader.u1(); - for (int paramIndex = 0; paramIndex < numberOfParameters; paramIndex++) { - getPool().add(new ParameterInfo(_byteReader, paramIndex)); + public RuntimeParameterAnnotationsEntry(ParameterAnnotationEntry []entries, int _nameIndex, int _length) { + super(_nameIndex, _length); + final int numberOfParameters = entries.length; + int paramIndex = 0; + for (ParameterAnnotationEntry pae : entries) { + getPool().add(new ParameterInfo(paramIndex, pae.getAnnotationEntries())); + paramIndex += 1; } } } @@ -2453,70 +2484,84 @@ public class ClassModel { private final static String LOCALVARIABLETYPETABLE_TAG = "LocalVariableTypeTable"; - public AttributePool(ByteReader _byteReader, String name) { - final int attributeCount = _byteReader.u2(); + public AttributePool(Attribute []attributes, String name) { +// final int attributeCount = attributes.length; AttributePoolEntry entry = null; - for (int i = 0; i < attributeCount; i++) { - final int attributeNameIndex = _byteReader.u2(); - final int length = _byteReader.u4(); + for (final Attribute attr : attributes) { + final int attributeNameIndex = attr.getNameIndex(); + final int length = attr.getLength(); UTF8Entry utf8Entry = constantPool.getUTF8Entry(attributeNameIndex); if (utf8Entry == null) { throw new IllegalStateException("corrupted state reading attributes for " + name); } final String attributeName = utf8Entry.getUTF8(); if (attributeName.equals(LOCALVARIABLETABLE_TAG)) { - localVariableTableEntry = new RealLocalVariableTableEntry(_byteReader, attributeNameIndex, length); + final LocalVariableTable lvt = (LocalVariableTable) attr; + localVariableTableEntry = new RealLocalVariableTableEntry(lvt.getLocalVariableTable(), attributeNameIndex, length); entry = (RealLocalVariableTableEntry) localVariableTableEntry; } else if (attributeName.equals(CONSTANTVALUE_TAG)) { - entry = new ConstantValueEntry(_byteReader, attributeNameIndex, length); + final ConstantValue cv = (ConstantValue) attr; + entry = new ConstantValueEntry(cv.getConstantValueIndex(), attributeNameIndex, length); } else if (attributeName.equals(LINENUMBERTABLE_TAG)) { - lineNumberTableEntry = new LineNumberTableEntry(_byteReader, attributeNameIndex, length); + final LineNumberTable lnt = (LineNumberTable) attr; + lineNumberTableEntry = new LineNumberTableEntry(lnt.getLineNumberTable(), attributeNameIndex, length); entry = lineNumberTableEntry; } else if (attributeName.equals(SOURCEFILE_TAG)) { - sourceFileEntry = new SourceFileEntry(_byteReader, attributeNameIndex, length); + final SourceFile sf = (SourceFile) attr; + sourceFileEntry = new SourceFileEntry(attributeNameIndex, length, sf.getSourceFileIndex()); entry = sourceFileEntry; } else if (attributeName.equals(SYNTHETIC_TAG)) { - syntheticEntry = new SyntheticEntry(_byteReader, attributeNameIndex, length); + final Synthetic syn = (Synthetic) attr; + syntheticEntry = new SyntheticEntry(attributeNameIndex, length); entry = syntheticEntry; } else if (attributeName.equals(EXCEPTIONS_TAG)) { - exceptionEntry = new ExceptionEntry(_byteReader, attributeNameIndex, length); + final ExceptionTable et = (ExceptionTable) attr; + exceptionEntry = new ExceptionEntry(et.getExceptionIndexTable(), attributeNameIndex, length); entry = exceptionEntry; } else if (attributeName.equals(INNERCLASSES_TAG)) { - entry = new InnerClassesEntry(_byteReader, attributeNameIndex, length); + final InnerClasses ics = (InnerClasses) attr; + entry = new InnerClassesEntry(ics.getInnerClasses(), attributeNameIndex, length); } else if (attributeName.equals(DEPRECATED_TAG)) { - deprecatedEntry = new DeprecatedEntry(_byteReader, attributeNameIndex, length); + deprecatedEntry = new DeprecatedEntry(attributeNameIndex, length); entry = deprecatedEntry; } else if (attributeName.equals(CODE_TAG)) { - codeEntry = new CodeEntry(_byteReader, attributeNameIndex, length); + final Code c = (Code) attr; + codeEntry = new CodeEntry(c); entry = codeEntry; } else if (attributeName.equals(ENCLOSINGMETHOD_TAG)) { - enclosingMethodEntry = new EnclosingMethodEntry(_byteReader, attributeNameIndex, length); + final EnclosingMethod em = (EnclosingMethod) attr; + enclosingMethodEntry = new EnclosingMethodEntry(em.getEnclosingClassIndex(), em.getEnclosingMethodIndex(), attributeNameIndex, length); entry = enclosingMethodEntry; } else if (attributeName.equals(SIGNATURE_TAG)) { - entry = new SignatureEntry(_byteReader, attributeNameIndex, length); + final Signature sig = (Signature) attr; + entry = new SignatureEntry(sig.getSignatureIndex(), attributeNameIndex, length); } else if (attributeName.equals(RUNTIMEINVISIBLEANNOTATIONS_TAG)) { - runtimeInvisibleAnnotationsEntry = new RuntimeAnnotationsEntry(_byteReader, attributeNameIndex, length); + final RuntimeInvisibleAnnotations ria = (RuntimeInvisibleAnnotations) attr; + runtimeInvisibleAnnotationsEntry = new RuntimeAnnotationsEntry(ria.getAnnotationEntries(), attributeNameIndex, length); entry = runtimeInvisibleAnnotationsEntry; } else if (attributeName.equals(RUNTIMEVISIBLEANNOTATIONS_TAG)) { - runtimeVisibleAnnotationsEntry = new RuntimeAnnotationsEntry(_byteReader, attributeNameIndex, length); + final RuntimeVisibleAnnotations rva = (RuntimeVisibleAnnotations) attr; + runtimeVisibleAnnotationsEntry = new RuntimeAnnotationsEntry(rva.getAnnotationEntries(), attributeNameIndex, length); entry = runtimeVisibleAnnotationsEntry; } else if (attributeName.equals(RUNTIMEVISIBLEPARAMETERANNOTATIONS_TAG)) { - runtimeVisibleParameterAnnotationsEntry = new RuntimeParameterAnnotationsEntry(_byteReader, attributeNameIndex, length); - entry = runtimeVisibleParameterAnnotationsEntry; + final RuntimeVisibleParameterAnnotations rvpa = (RuntimeVisibleParameterAnnotations) attr; + runtimeVisibleParameterAnnotationsEntry = new RuntimeParameterAnnotationsEntry(rvpa.getParameterAnnotationEntries(), attributeNameIndex, length); + entry = runtimeVisibleParameterAnnotationsEntry; } else if (attributeName.equals(BOOTSTRAPMETHODS_TAG)) { - bootstrapMethodsEntry = new BootstrapMethodsEntry(_byteReader, attributeNameIndex, length); + final BootstrapMethods methds = (BootstrapMethods) attr; + bootstrapMethodsEntry = new BootstrapMethodsEntry(methds.getBootstrapMethods(), attributeNameIndex, length); entry = bootstrapMethodsEntry; // http://docs.oracle.com/javase/specs/jvms/se7/html/jvms-4.html#jvms-4.7.21 } else if (attributeName.equals(STACKMAPTABLE_TAG)) { // http://docs.oracle.com/javase/specs/jvms/se7/html/jvms-4.html#jvms-4.7.4 - entry = new StackMapTableEntry(_byteReader, attributeNameIndex, length); + entry = new StackMapTableEntry(null, attributeNameIndex, length); } else if (attributeName.equals(LOCALVARIABLETYPETABLE_TAG)) { // http://docs.oracle.com/javase/specs/jvms/se7/html/jvms-4.html#jvms-4.7.14 - entry = new LocalVariableTypeTableEntry(_byteReader, attributeNameIndex, length); + entry = new LocalVariableTypeTableEntry(null, attributeNameIndex, length); } else { logger.warning("Found unexpected Attribute (name = " + attributeName + ")"); - entry = new OtherEntry(_byteReader, attributeNameIndex, length); + entry = new OtherEntry(null, attributeNameIndex, length); } attributePoolEntries.add(entry); @@ -2582,12 +2627,12 @@ public class ClassModel { private final int nameIndex; - public ClassModelField(ByteReader _byteReader, int _index) { + public ClassModelField(org.apache.bcel.classfile.Field f, int _fieldAccessFlags, int _nameIndex, int _descriptorIndex, int _index) { index = _index; - fieldAccessFlags = _byteReader.u2(); - nameIndex = _byteReader.u2(); - descriptorIndex = _byteReader.u2(); - fieldAttributePool = new AttributePool(_byteReader, getName()); + fieldAccessFlags = _fieldAccessFlags; + nameIndex = _nameIndex; + descriptorIndex = _descriptorIndex; + fieldAttributePool = new AttributePool(f.getAttributes(), getName()); } public int getAccessFlags() { @@ -2652,13 +2697,13 @@ public class ClassModel { private final CodeEntry codeEntry; - public ClassModelMethod(ByteReader _byteReader, int _index) { + public ClassModelMethod(org.apache.bcel.classfile.Method method, int _index) { index = _index; - methodAccessFlags = _byteReader.u2(); - nameIndex = _byteReader.u2(); - descriptorIndex = _byteReader.u2(); - methodAttributePool = new AttributePool(_byteReader, getName()); - codeEntry = methodAttributePool.getCodeEntry(); + methodAccessFlags = method.getAccessFlags(); + nameIndex = method.getNameIndex(); + descriptorIndex = method.getSignatureIndex(); + methodAttributePool = new AttributePool(method.getAttributes(), getName()); + codeEntry = methodAttributePool.codeEntry; } public int getAccessFlags() { @@ -2745,8 +2790,8 @@ public class ClassModel { public class ClassModelInterface { private final int interfaceIndex; - ClassModelInterface(ByteReader _byteReader) { - interfaceIndex = _byteReader.u2(); + ClassModelInterface(int _interfaceIndex) { + interfaceIndex = _interfaceIndex; } ConstantPool.ClassEntry getClassEntry() { @@ -2761,69 +2806,70 @@ public class ClassModel { private Class<?> clazz; - /** - * We extract the class's classloader and name and delegate to private parse method. - * @param _class The class we wish to model - * @throws ClassParseException - */ - public void parse(Class<?> _class) throws ClassParseException { - - clazz = _class; - //It is needed to load AtomicInteger class and Should also fix Issue #6 - NPE while getting Math.class - ClassLoader loader = _class.getClassLoader(); - if (loader == null) { - loader = ClassLoader.getSystemClassLoader().getParent(); - } - parse(loader, _class.getName()); - } - - /** - * Populate this model by parsing a given classfile from the given classloader. - * - * We create a ByteReader (wrapper around the bytes representing the classfile) and pass it to local inner classes to handle the various sections of the class file. - * - * @see ByteReader - * @see <a href="http://java.sun.com/docs/books/jvms/second_edition/ClassFileFormat-Java5.pdf">Java 5 Class File Format</a> - * @param _classLoader The classloader to access the classfile - * @param _className The name of the class to load (we convert '.' to '/' and append ".class" so you don't have to). - * @throws ClassParseException - */ - private void parse(ClassLoader _classLoader, String _className) throws ClassParseException { - - parse(_classLoader.getResourceAsStream(_className.replace('.', '/') + ".class")); - } - - void parse(InputStream _inputStream) throws ClassParseException { - - ByteReader byteReader = new ByteReader(_inputStream); - magic = byteReader.u4(); - minorVersion = byteReader.u2(); - majorVersion = byteReader.u2(); - constantPool = new ConstantPool(byteReader); - - accessFlags = byteReader.u2(); - thisClassConstantPoolIndex = byteReader.u2(); - superClassConstantPoolIndex = byteReader.u2(); - - final int interfaceCount = byteReader.u2(); - for (int i = 0; i < interfaceCount; i++) { - final ClassModelInterface iface = new ClassModelInterface(byteReader); +// /** +// * We extract the class's classloader and name and delegate to private parse method. +// * @param _class The class we wish to model +// * @throws ClassParseException +// */ +// public void parse(Class<?> _class) throws ClassParseException, ClassNotFoundException { +// +// clazz = _class; +// //It is needed to load AtomicInteger class and Should also fix Issue #6 - NPE while getting Math.class +// ClassLoader loader = _class.getClassLoader(); +// if (loader == null) { +// loader = ClassLoader.getSystemClassLoader().getParent(); +// } +// parse(loader, _class.getName()); +// } +// +// /** +// * Populate this model by parsing a given classfile from the given classloader. +// * +// * We create a ByteReader (wrapper around the bytes representing the classfile) and pass it to local inner classes to handle the various sections of the class file. +// * +// * @see ByteReader +// * @see <a href="http://java.sun.com/docs/books/jvms/second_edition/ClassFileFormat-Java5.pdf">Java 5 Class File Format</a> +// * @param _classLoader The classloader to access the classfile +// * @param _className The name of the class to load (we convert '.' to '/' and append ".class" so you don't have to). +// * @throws ClassParseException +// */ +// private void parse(ClassLoader _classLoader, String _className) throws ClassParseException, ClassNotFoundException { +// +// parse(_className.replace('.', '/') + ".class"); +// } + + void parse(Class<?> _class) throws ClassParseException, ClassNotFoundException { + JavaClass cls = Repository.lookupClass(_class); +// ByteReader byteReader = new ByteReader(_inputStream); + magic = 0xCAFEBABE; + minorVersion = cls.getMinor(); + majorVersion = cls.getMajor(); + constantPool = new ConstantPool(cls); + + accessFlags = cls.getAccessFlags(); + thisClassConstantPoolIndex = cls.getClassNameIndex(); + superClassConstantPoolIndex = cls.getSuperClass().getClassNameIndex(); + + for (int i : cls.getInterfaceIndices()) { + final ClassModelInterface iface = new ClassModelInterface(i); interfaces.add(iface); } - final int fieldCount = byteReader.u2(); - for (int i = 0; i < fieldCount; i++) { - final ClassModelField field = new ClassModelField(byteReader, i); + int i = 0; + for (org.apache.bcel.classfile.Field f : cls.getFields()) { + final ClassModelField field = new ClassModelField(f, f.getAccessFlags(), f.getNameIndex(), f.getSignatureIndex(), i); fields.add(field); + i += 1; } - final int methodPoolLength = byteReader.u2(); - for (int i = 0; i < methodPoolLength; i++) { - final ClassModelMethod method = new ClassModelMethod(byteReader, i); + i = 0; + for (org.apache.bcel.classfile.Method m : cls.getMethods()) { + final ClassModelMethod method = new ClassModelMethod(m, i); methods.add(method); + i += 1; } - attributePool = new AttributePool(byteReader, Reflection.getSimpleName(getClassWeAreModelling())); + attributePool = new AttributePool(cls.getAttributes(), Reflection.getSimpleName(getClassWeAreModelling())); } public int getMagic() {