From: <njn...@us...> - 2009-05-12 03:11:46
|
Revision: 8300 http://x10.svn.sourceforge.net/x10/?rev=8300&view=rev Author: njnystrom Date: 2009-05-12 03:11:38 +0000 (Tue, 12 May 2009) Log Message: ----------- First cut at Sn code. Added Paths: ----------- trunk/.classpath trunk/.project trunk/bin/ trunk/bin/x10/ trunk/bin/x10/sncode/ trunk/bin/x10/sncode/ByteBuffer.class trunk/bin/x10/sncode/ClassEditor$1.class trunk/bin/x10/sncode/ClassEditor$2.class trunk/bin/x10/sncode/ClassEditor$3.class trunk/bin/x10/sncode/ClassEditor$4.class trunk/bin/x10/sncode/ClassEditor$5.class trunk/bin/x10/sncode/ClassEditor.class trunk/bin/x10/sncode/ConstantPool$CWClass.class trunk/bin/x10/sncode/ConstantPool$CWItem.class trunk/bin/x10/sncode/ConstantPool$CWNameAndType.class trunk/bin/x10/sncode/ConstantPool$CWRef.class trunk/bin/x10/sncode/ConstantPool$CWString.class trunk/bin/x10/sncode/ConstantPool.class trunk/bin/x10/sncode/ConstantPoolParser.class trunk/bin/x10/sncode/Constraint$Constant.class trunk/bin/x10/sncode/Constraint$Field.class trunk/bin/x10/sncode/Constraint$Formula.class trunk/bin/x10/sncode/Constraint$Term.class trunk/bin/x10/sncode/Constraint$Var.class trunk/bin/x10/sncode/Constraint.class trunk/bin/x10/sncode/ConstraintReader.class trunk/bin/x10/sncode/ConstructorEditor.class trunk/bin/x10/sncode/Container$Mapper.class trunk/bin/x10/sncode/Container.class trunk/bin/x10/sncode/FieldEditor.class trunk/bin/x10/sncode/InvalidClassFileException.class trunk/bin/x10/sncode/MethodEditor.class trunk/bin/x10/sncode/Pair.class trunk/bin/x10/sncode/SnConstants.class trunk/bin/x10/sncode/SnFile$1.class trunk/bin/x10/sncode/SnFile.class trunk/bin/x10/sncode/Tree$Branch.class trunk/bin/x10/sncode/Tree$Leaf.class trunk/bin/x10/sncode/Tree.class trunk/bin/x10/sncode/Type$AnnotatedType.class trunk/bin/x10/sncode/Type$ConstrainedType.class trunk/bin/x10/sncode/Type$FunType.class trunk/bin/x10/sncode/Type$ParamType.class trunk/bin/x10/sncode/Type$RefType.class trunk/bin/x10/sncode/Type$ScopedType.class trunk/bin/x10/sncode/Type$StructType.class trunk/bin/x10/sncode/Type$VoidType.class trunk/bin/x10/sncode/Type.class trunk/bin/x10/sncode/TypedefEditor.class trunk/bin/x10/sncode/test/ trunk/bin/x10/sncode/test/ClassFileTest.class trunk/bin/x10/sncode/test/TypeTest.class trunk/src/ trunk/src/x10/ trunk/src/x10/sncode/ trunk/src/x10/sncode/ByteBuffer.java trunk/src/x10/sncode/ClassEditor.java trunk/src/x10/sncode/ConstantPool.java trunk/src/x10/sncode/ConstantPoolParser.java trunk/src/x10/sncode/Constraint.java trunk/src/x10/sncode/ConstraintReader.java trunk/src/x10/sncode/ConstructorEditor.java trunk/src/x10/sncode/Container.java trunk/src/x10/sncode/FieldEditor.java trunk/src/x10/sncode/InvalidClassFileException.java trunk/src/x10/sncode/MethodEditor.java trunk/src/x10/sncode/Pair.java trunk/src/x10/sncode/SnConstants.java trunk/src/x10/sncode/SnFile.java trunk/src/x10/sncode/Tree.java trunk/src/x10/sncode/Type.java trunk/src/x10/sncode/TypedefEditor.java trunk/src/x10/sncode/test/ trunk/src/x10/sncode/test/ClassFileTest.java trunk/src/x10/sncode/test/TypeTest.java Added: trunk/.classpath =================================================================== --- trunk/.classpath (rev 0) +++ trunk/.classpath 2009-05-12 03:11:38 UTC (rev 8300) @@ -0,0 +1,7 @@ +<?xml version="1.0" encoding="UTF-8"?> +<classpath> + <classpathentry kind="src" path="src"/> + <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/> + <classpathentry kind="con" path="org.eclipse.jdt.junit.JUNIT_CONTAINER/3"/> + <classpathentry kind="output" path="bin"/> +</classpath> Added: trunk/.project =================================================================== --- trunk/.project (rev 0) +++ trunk/.project 2009-05-12 03:11:38 UTC (rev 8300) @@ -0,0 +1,17 @@ +<?xml version="1.0" encoding="UTF-8"?> +<projectDescription> + <name>x10.sncode</name> + <comment></comment> + <projects> + </projects> + <buildSpec> + <buildCommand> + <name>org.eclipse.jdt.core.javabuilder</name> + <arguments> + </arguments> + </buildCommand> + </buildSpec> + <natures> + <nature>org.eclipse.jdt.core.javanature</nature> + </natures> +</projectDescription> Added: trunk/bin/x10/sncode/ByteBuffer.class =================================================================== (Binary files differ) Property changes on: trunk/bin/x10/sncode/ByteBuffer.class ___________________________________________________________________ Added: svn:mime-type + application/octet-stream Added: trunk/bin/x10/sncode/ClassEditor$1.class =================================================================== (Binary files differ) Property changes on: trunk/bin/x10/sncode/ClassEditor$1.class ___________________________________________________________________ Added: svn:mime-type + application/octet-stream Added: trunk/bin/x10/sncode/ClassEditor$2.class =================================================================== (Binary files differ) Property changes on: trunk/bin/x10/sncode/ClassEditor$2.class ___________________________________________________________________ Added: svn:mime-type + application/octet-stream Added: trunk/bin/x10/sncode/ClassEditor$3.class =================================================================== (Binary files differ) Property changes on: trunk/bin/x10/sncode/ClassEditor$3.class ___________________________________________________________________ Added: svn:mime-type + application/octet-stream Added: trunk/bin/x10/sncode/ClassEditor$4.class =================================================================== (Binary files differ) Property changes on: trunk/bin/x10/sncode/ClassEditor$4.class ___________________________________________________________________ Added: svn:mime-type + application/octet-stream Added: trunk/bin/x10/sncode/ClassEditor$5.class =================================================================== (Binary files differ) Property changes on: trunk/bin/x10/sncode/ClassEditor$5.class ___________________________________________________________________ Added: svn:mime-type + application/octet-stream Added: trunk/bin/x10/sncode/ClassEditor.class =================================================================== (Binary files differ) Property changes on: trunk/bin/x10/sncode/ClassEditor.class ___________________________________________________________________ Added: svn:mime-type + application/octet-stream Added: trunk/bin/x10/sncode/ConstantPool$CWClass.class =================================================================== (Binary files differ) Property changes on: trunk/bin/x10/sncode/ConstantPool$CWClass.class ___________________________________________________________________ Added: svn:mime-type + application/octet-stream Added: trunk/bin/x10/sncode/ConstantPool$CWItem.class =================================================================== (Binary files differ) Property changes on: trunk/bin/x10/sncode/ConstantPool$CWItem.class ___________________________________________________________________ Added: svn:mime-type + application/octet-stream Added: trunk/bin/x10/sncode/ConstantPool$CWNameAndType.class =================================================================== (Binary files differ) Property changes on: trunk/bin/x10/sncode/ConstantPool$CWNameAndType.class ___________________________________________________________________ Added: svn:mime-type + application/octet-stream Added: trunk/bin/x10/sncode/ConstantPool$CWRef.class =================================================================== (Binary files differ) Property changes on: trunk/bin/x10/sncode/ConstantPool$CWRef.class ___________________________________________________________________ Added: svn:mime-type + application/octet-stream Added: trunk/bin/x10/sncode/ConstantPool$CWString.class =================================================================== (Binary files differ) Property changes on: trunk/bin/x10/sncode/ConstantPool$CWString.class ___________________________________________________________________ Added: svn:mime-type + application/octet-stream Added: trunk/bin/x10/sncode/ConstantPool.class =================================================================== (Binary files differ) Property changes on: trunk/bin/x10/sncode/ConstantPool.class ___________________________________________________________________ Added: svn:mime-type + application/octet-stream Added: trunk/bin/x10/sncode/ConstantPoolParser.class =================================================================== (Binary files differ) Property changes on: trunk/bin/x10/sncode/ConstantPoolParser.class ___________________________________________________________________ Added: svn:mime-type + application/octet-stream Added: trunk/bin/x10/sncode/Constraint$Constant.class =================================================================== (Binary files differ) Property changes on: trunk/bin/x10/sncode/Constraint$Constant.class ___________________________________________________________________ Added: svn:mime-type + application/octet-stream Added: trunk/bin/x10/sncode/Constraint$Field.class =================================================================== (Binary files differ) Property changes on: trunk/bin/x10/sncode/Constraint$Field.class ___________________________________________________________________ Added: svn:mime-type + application/octet-stream Added: trunk/bin/x10/sncode/Constraint$Formula.class =================================================================== (Binary files differ) Property changes on: trunk/bin/x10/sncode/Constraint$Formula.class ___________________________________________________________________ Added: svn:mime-type + application/octet-stream Added: trunk/bin/x10/sncode/Constraint$Term.class =================================================================== (Binary files differ) Property changes on: trunk/bin/x10/sncode/Constraint$Term.class ___________________________________________________________________ Added: svn:mime-type + application/octet-stream Added: trunk/bin/x10/sncode/Constraint$Var.class =================================================================== (Binary files differ) Property changes on: trunk/bin/x10/sncode/Constraint$Var.class ___________________________________________________________________ Added: svn:mime-type + application/octet-stream Added: trunk/bin/x10/sncode/Constraint.class =================================================================== (Binary files differ) Property changes on: trunk/bin/x10/sncode/Constraint.class ___________________________________________________________________ Added: svn:mime-type + application/octet-stream Added: trunk/bin/x10/sncode/ConstraintReader.class =================================================================== (Binary files differ) Property changes on: trunk/bin/x10/sncode/ConstraintReader.class ___________________________________________________________________ Added: svn:mime-type + application/octet-stream Added: trunk/bin/x10/sncode/ConstructorEditor.class =================================================================== (Binary files differ) Property changes on: trunk/bin/x10/sncode/ConstructorEditor.class ___________________________________________________________________ Added: svn:mime-type + application/octet-stream Added: trunk/bin/x10/sncode/Container$Mapper.class =================================================================== (Binary files differ) Property changes on: trunk/bin/x10/sncode/Container$Mapper.class ___________________________________________________________________ Added: svn:mime-type + application/octet-stream Added: trunk/bin/x10/sncode/Container.class =================================================================== (Binary files differ) Property changes on: trunk/bin/x10/sncode/Container.class ___________________________________________________________________ Added: svn:mime-type + application/octet-stream Added: trunk/bin/x10/sncode/FieldEditor.class =================================================================== (Binary files differ) Property changes on: trunk/bin/x10/sncode/FieldEditor.class ___________________________________________________________________ Added: svn:mime-type + application/octet-stream Added: trunk/bin/x10/sncode/InvalidClassFileException.class =================================================================== (Binary files differ) Property changes on: trunk/bin/x10/sncode/InvalidClassFileException.class ___________________________________________________________________ Added: svn:mime-type + application/octet-stream Added: trunk/bin/x10/sncode/MethodEditor.class =================================================================== (Binary files differ) Property changes on: trunk/bin/x10/sncode/MethodEditor.class ___________________________________________________________________ Added: svn:mime-type + application/octet-stream Added: trunk/bin/x10/sncode/Pair.class =================================================================== (Binary files differ) Property changes on: trunk/bin/x10/sncode/Pair.class ___________________________________________________________________ Added: svn:mime-type + application/octet-stream Added: trunk/bin/x10/sncode/SnConstants.class =================================================================== (Binary files differ) Property changes on: trunk/bin/x10/sncode/SnConstants.class ___________________________________________________________________ Added: svn:mime-type + application/octet-stream Added: trunk/bin/x10/sncode/SnFile$1.class =================================================================== (Binary files differ) Property changes on: trunk/bin/x10/sncode/SnFile$1.class ___________________________________________________________________ Added: svn:mime-type + application/octet-stream Added: trunk/bin/x10/sncode/SnFile.class =================================================================== (Binary files differ) Property changes on: trunk/bin/x10/sncode/SnFile.class ___________________________________________________________________ Added: svn:mime-type + application/octet-stream Added: trunk/bin/x10/sncode/Tree$Branch.class =================================================================== (Binary files differ) Property changes on: trunk/bin/x10/sncode/Tree$Branch.class ___________________________________________________________________ Added: svn:mime-type + application/octet-stream Added: trunk/bin/x10/sncode/Tree$Leaf.class =================================================================== (Binary files differ) Property changes on: trunk/bin/x10/sncode/Tree$Leaf.class ___________________________________________________________________ Added: svn:mime-type + application/octet-stream Added: trunk/bin/x10/sncode/Tree.class =================================================================== (Binary files differ) Property changes on: trunk/bin/x10/sncode/Tree.class ___________________________________________________________________ Added: svn:mime-type + application/octet-stream Added: trunk/bin/x10/sncode/Type$AnnotatedType.class =================================================================== (Binary files differ) Property changes on: trunk/bin/x10/sncode/Type$AnnotatedType.class ___________________________________________________________________ Added: svn:mime-type + application/octet-stream Added: trunk/bin/x10/sncode/Type$ConstrainedType.class =================================================================== (Binary files differ) Property changes on: trunk/bin/x10/sncode/Type$ConstrainedType.class ___________________________________________________________________ Added: svn:mime-type + application/octet-stream Added: trunk/bin/x10/sncode/Type$FunType.class =================================================================== (Binary files differ) Property changes on: trunk/bin/x10/sncode/Type$FunType.class ___________________________________________________________________ Added: svn:mime-type + application/octet-stream Added: trunk/bin/x10/sncode/Type$ParamType.class =================================================================== (Binary files differ) Property changes on: trunk/bin/x10/sncode/Type$ParamType.class ___________________________________________________________________ Added: svn:mime-type + application/octet-stream Added: trunk/bin/x10/sncode/Type$RefType.class =================================================================== (Binary files differ) Property changes on: trunk/bin/x10/sncode/Type$RefType.class ___________________________________________________________________ Added: svn:mime-type + application/octet-stream Added: trunk/bin/x10/sncode/Type$ScopedType.class =================================================================== (Binary files differ) Property changes on: trunk/bin/x10/sncode/Type$ScopedType.class ___________________________________________________________________ Added: svn:mime-type + application/octet-stream Added: trunk/bin/x10/sncode/Type$StructType.class =================================================================== (Binary files differ) Property changes on: trunk/bin/x10/sncode/Type$StructType.class ___________________________________________________________________ Added: svn:mime-type + application/octet-stream Added: trunk/bin/x10/sncode/Type$VoidType.class =================================================================== (Binary files differ) Property changes on: trunk/bin/x10/sncode/Type$VoidType.class ___________________________________________________________________ Added: svn:mime-type + application/octet-stream Added: trunk/bin/x10/sncode/Type.class =================================================================== (Binary files differ) Property changes on: trunk/bin/x10/sncode/Type.class ___________________________________________________________________ Added: svn:mime-type + application/octet-stream Added: trunk/bin/x10/sncode/TypedefEditor.class =================================================================== (Binary files differ) Property changes on: trunk/bin/x10/sncode/TypedefEditor.class ___________________________________________________________________ Added: svn:mime-type + application/octet-stream Added: trunk/bin/x10/sncode/test/ClassFileTest.class =================================================================== (Binary files differ) Property changes on: trunk/bin/x10/sncode/test/ClassFileTest.class ___________________________________________________________________ Added: svn:mime-type + application/octet-stream Added: trunk/bin/x10/sncode/test/TypeTest.class =================================================================== (Binary files differ) Property changes on: trunk/bin/x10/sncode/test/TypeTest.class ___________________________________________________________________ Added: svn:mime-type + application/octet-stream Added: trunk/src/x10/sncode/ByteBuffer.java =================================================================== --- trunk/src/x10/sncode/ByteBuffer.java (rev 0) +++ trunk/src/x10/sncode/ByteBuffer.java 2009-05-12 03:11:38 UTC (rev 8300) @@ -0,0 +1,532 @@ +package x10.sncode; + +public class ByteBuffer { + byte[] buf; + int offset; + int buflen; + + public ByteBuffer(byte[] buf) { + this.buf = buf; + this.offset = 0; + this.buflen = buf.length; + } + + public ByteBuffer() { + this(64); + } + + public ByteBuffer(int size) { + this.buf = new byte[size]; + this.offset = 0; + this.buflen = 0; + } + + public String toString() { + StringBuilder sb = new StringBuilder(); + for (int i = 0; i < buflen; i++) { + byte b = buf[i]; + if (b == '\\') + sb.append("\\\\"); + else if (Character.isWhitespace((char) b) || (b >= 33 && b <= 126)) + sb.append((char) b); + else { + sb.append("\\x"); + String x = Integer.toHexString(b & 0xff); + for (int j = x.length(); j < 2; j++) + sb.append("0"); + sb.append(x); + } + } + return sb.toString(); + } + + int offset() { + return offset; + } + + void skip(int n) { + this.offset += n; + } + + public void seek(int n) { + this.offset = n; + } + + void reserve(int size) { + if (buf == null) { + buf = new byte[size]; + } + else if (size > buf.length) { + byte[] newBuf = new byte[Math.max(buf.length * 2, size)]; + System.arraycopy(buf, 0, newBuf, 0, buf.length); + buf = newBuf; + } + } + + /** + * Set the 4 bytes at offset 'offset' in 'buf' to the signed 32-bit value in + * v. + */ + void addInt(int v) { + setInt(offset, v); + offset += 4; + } + + /** + * Set the 4 bytes at offset 'offset' in 'buf' to the signed 32-bit value in + * v. + */ + void setInt(int offset, int v) { + reserve(offset + 4); + buf[offset++] = (byte) (v >> 24); + buf[offset++] = (byte) (v >> 16); + buf[offset++] = (byte) (v >> 8); + buf[offset++] = (byte) v; + buflen = Math.max(offset, buflen); + } + + void setLong(int offset, long v) { + reserve(offset + 8); + setInt(offset, (int) (v >> 32)); + setInt(offset + 4, (int) v); + } + + /** + * Set the 8 bytes at offset 'offset' in 'buf' to the signed 64-bit value in + * v. + */ + public void addLong(long v) { + setLong(offset, v); + offset += 8; + } + + /** + * Set the 4 bytes at offset 'offset' in 'buf' to the float value in v. + */ + public void addFloat(float v) { + addInt(Float.floatToIntBits(v)); + } + + /** + * Set the 4 bytes at offset 'offset' in 'buf' to the float value in v. + */ + public void setFloat(int offset, float v) { + setInt(offset, Float.floatToIntBits(v)); + } + + /** + * Set the 8 bytes at offset 'offset' in 'buf' to the double value in v. + */ + public void addDouble(double v) throws IllegalArgumentException { + addLong(Double.doubleToRawLongBits(v)); + } + + /** + * Set the 8 bytes at offset 'offset' in 'buf' to the double value in v. + */ + public void setDouble(int offset, double v) throws IllegalArgumentException { + setLong(offset, Double.doubleToRawLongBits(v)); + } + + /** + * Set the 2 bytes at offset 'offset' in 'buf' to the unsigned 16-bit value + * in v. + * + * @throws IllegalArgumentException + * if buf is null + */ + public void setUShort(int offset, int v) throws IllegalArgumentException { + reserve(offset + 2); + buf[offset++] = (byte) (v >> 8); + buf[offset++] = (byte) v; + buflen = Math.max(offset, buflen); + } + + /** + * Set the 2 bytes at offset 'offset' in 'buf' to the unsigned 16-bit value + * in v. + * + * @throws IllegalArgumentException + * if buf is null + */ + public void addUShort(int v) throws IllegalArgumentException { + setUShort(offset, v); + offset += 2; + } + + /** + * Set the 2 bytes at offset 'offset' in 'buf' to the unsigned 16-bit value + * in v. + * + * @throws IllegalArgumentException + * if buf is null + */ + public void setUByte(int offset, int v) throws IllegalArgumentException { + reserve(offset + 1); + buf[offset++] = (byte) v; + buflen = Math.max(offset, buflen); + } + + /** + * Set the 2 bytes at offset 'offset' in 'buf' to the unsigned 16-bit value + * in v. + * + * @throws IllegalArgumentException + * if buf is null + */ + public void addUByte(int v) { + setUByte(offset, v); + offset++; + } + + public byte[] getBytes() { + if (buf.length == buflen) { + return buf; + } + else { + byte[] b = new byte[buflen]; + System.arraycopy(buf, 0, b, 0, buflen); + return b; + } + } + + public byte[] getBytes(int i, int len) throws InvalidClassFileException { + if (i < 0 || i + len > buflen) + throw new InvalidClassFileException(i, "cannot get raw bytes"); + byte[] b = new byte[len]; + System.arraycopy(buf, i, b, 0, len); + return b; + } + + public void addBytes(byte[] bytes) { + reserve(offset + bytes.length); + System.arraycopy(bytes, 0, buf, offset, bytes.length); + offset += bytes.length; + buflen = Math.max(offset, buflen); + } + + public void setBytes(int offset, byte[] bytes) { + reserve(offset + bytes.length); + System.arraycopy(bytes, 0, buf, offset, bytes.length); + buflen = Math.max(offset, buflen); + } + + public void addBytes(byte[] bytes, int boff, int blen) { + reserve(offset + blen); + System.arraycopy(bytes, boff, buf, offset, blen); + offset += blen; + buflen = Math.max(offset, buflen); + } + + public void setBytes(int offset, byte[] bytes, int boff, int blen) { + reserve(offset + blen); + System.arraycopy(bytes, boff, buf, offset, blen); + buflen = Math.max(offset, buflen); + } + + /** + * Set the 2 bytes at offset 'offset' in 'buf' to the unsigned 16-bit value + * in v. + * + * @throws IllegalArgumentException + * if buf is null + */ + public void setByte(int offset, int v) throws IllegalArgumentException { + setUByte(offset, v); + } + + /** + * Set the 2 bytes at offset 'offset' in 'buf' to the unsigned 16-bit value + * in v. + * + * @throws IllegalArgumentException + * if buf is null + */ + public void addByte(int v) { + addUByte(v); + } + + public void checkLength(int size) throws InvalidClassFileException { + if (size > buflen || size > buf.length) + throw new InvalidClassFileException(size, "Out of range."); + } + + public long getLong() throws InvalidClassFileException { + long result = getLong(offset); + offset += 8; + return result; + } + + public int getInt() throws InvalidClassFileException { + int result = getInt(offset); + offset += 4; + return result; + } + + public float getFloat() throws InvalidClassFileException { + int result = getInt(); + return Float.intBitsToFloat(result); + } + + public float getFloat(int offset) throws InvalidClassFileException { + int result = getInt(offset); + return Float.intBitsToFloat(result); + } + + public double getDouble() throws InvalidClassFileException { + long result = getLong(); + return Double.longBitsToDouble(result); + } + + public double getDouble(int offset) throws InvalidClassFileException { + long result = getLong(offset); + return Double.longBitsToDouble(result); + } + + /** + * @return the signed 32-bit value at offset i in the class data + * @throws InvalidClassFileException + */ + public int getInt(int offset) throws InvalidClassFileException { + checkLength(offset + 4); + return (buf[offset] << 24) + ((buf[offset + 1] & 0xFF) << 16) + ((buf[offset + 2] & 0xFF) << 8) + (buf[offset + 3] & 0xFF); + } + + /** + * @return the signed 64-bit value at offset i in the class data + * @throws InvalidClassFileException + */ + public long getLong(int offset) throws InvalidClassFileException { + checkLength(offset + 8); + int r1 = getInt(offset); + int r2 = getInt(offset + 4); + return ((long) r1 << 32) | (r2 & 0xFFFFFFFFL); + } + + public String getUtf8() throws InvalidClassFileException { + int count = getInt(offset); + String s = getUtf8(offset + 4, count); + offset += 4; + offset += count; + return s; + } + + public String getUtf8(int offset) throws InvalidClassFileException { + int count = getInt(offset); + return getUtf8(offset + 4, count); + } + + private InvalidClassFileException invalidUtf8(int offset) { + return new InvalidClassFileException(offset, "Invalid Java Utf8 string."); + } + + /** + * @return the value of the Utf8 string at constant pool item i + */ + private String getUtf8(int offset, int count) throws InvalidClassFileException { + int end = count + offset; + StringBuilder buf = new StringBuilder(count); + offset += 4; + while (offset < end) { + byte x = getByte(offset); + if ((x & 0x80) == 0) { + if (x == 0) { + throw invalidUtf8(offset); + } + buf.append((char) x); + offset++; + } + else if ((x & 0xE0) == 0xC0) { + if (offset + 1 >= end) { + throw invalidUtf8(offset); + } + byte y = getByte(offset + 1); + if ((y & 0xC0) != 0x80) { + throw invalidUtf8(offset); + } + buf.append((char) (((x & 0x1F) << 6) + (y & 0x3F))); + offset += 2; + } + else if ((x & 0xF0) == 0xE0) { + if (offset + 2 >= end) { + throw invalidUtf8(offset); + } + byte y = getByte(offset + 1); + byte z = getByte(offset + 2); + if ((y & 0xC0) != 0x80 || (z & 0xC0) != 0x80) { + throw invalidUtf8(offset); + } + buf.append((char) (((x & 0x0F) << 12) + ((y & 0x3F) << 6) + (z & 0x3F))); + offset += 3; + } + else { + throw invalidUtf8(offset); + } + } + return buf.toString(); + } + + public String getUtf8ToDelimiter(int offset, String delims) throws InvalidClassFileException { + int i = offset(); + String s = getUtf8ToDelimiter(delims); + seek(i); + return s; + } + + public String getUtf8ToDelimiter(String delims) throws InvalidClassFileException { + StringBuilder buf = new StringBuilder(); + while (offset < buflen && offset < this.buf.length) { + byte x = getByte(offset); + if ((x & 0x80) == 0) { + if (x == 0) { + throw invalidUtf8(offset); + } + buf.append((char) x); + offset++; + } + else if ((x & 0xE0) == 0xC0) { + byte y = getByte(offset + 1); + if ((y & 0xC0) != 0x80) { + throw invalidUtf8(offset); + } + buf.append((char) (((x & 0x1F) << 6) + (y & 0x3F))); + offset += 2; + } + else if ((x & 0xF0) == 0xE0) { + byte y = getByte(offset + 1); + byte z = getByte(offset + 2); + if ((y & 0xC0) != 0x80 || (z & 0xC0) != 0x80) { + throw invalidUtf8(offset); + } + buf.append((char) (((x & 0x0F) << 12) + ((y & 0x3F) << 6) + (z & 0x3F))); + offset += 3; + } + else { + throw invalidUtf8(offset); + } + + char c = buf.charAt(buf.length() - 1); + + if (delims.indexOf(c) >= 0) + break; + } + + return buf.toString(); + } + + public int getUShort() throws InvalidClassFileException { + int result = getUShort(offset); + offset += 2; + return result; + } + + /** + * @return the unsigned 16-bit value at offset i in the class data + * @throws InvalidClassFileException + */ + public int getUShort(int offset) throws InvalidClassFileException { + checkLength(offset + 2); + return ((buf[offset] & 0xFF) << 8) + (buf[offset + 1] & 0xFF); + } + + /** + * @return the signed 16-bit value at offset i in the class data + * @throws InvalidClassFileException + */ + public short getShort(int i) throws InvalidClassFileException { + checkLength(i + 2); + return (short) ((buf[i] << 8) + (buf[i + 1] & 0xFF)); + } + + /** + * @return the signed 8-bit value at offset i in the class data + * @throws InvalidClassFileException + */ + public byte getByte(int i) throws InvalidClassFileException { + checkLength(i + 1); + return buf[i]; + } + + /** + * @return the signed 8-bit value at offset i in the class data + * @throws InvalidClassFileException + */ + public byte getByte() throws InvalidClassFileException { + byte result = getByte(offset); + offset++; + return result; + } + + /** + * @return the unsigned 8-bit value at offset i in the class data + * @throws InvalidClassFileException + */ + public int getUByte(int i) throws InvalidClassFileException { + checkLength(i + 1); + return buf[i] & 0xFF; + } + + public void setCPIndex(int offset, int i) { + setInt(offset, i); + } + + public void addCPIndex(int i) { + addInt(i); + } + + public int getCPIndex(int i) throws InvalidClassFileException { + return getInt(i); + } + + public int getCPIndex() throws InvalidClassFileException { + return getInt(); + } + + public void setLength(int offset, int i) { + setInt(offset, i); + } + + public void addLength(int i) { + addInt(i); + } + + public int getLength(int i) throws InvalidClassFileException { + return getInt(i); + } + + public int getLength() throws InvalidClassFileException { + return getInt(); + } + + public void setCount(int offset, int i) { + setInt(offset, i); + } + + public void addCount(int i) { + addInt(i); + } + + public int getCount(int i) throws InvalidClassFileException { + return getInt(i); + } + + public int getCount() throws InvalidClassFileException { + return getInt(); + } + + public void getAttributeOffsets(int[] offsets) throws InvalidClassFileException { + int count = offsets.length - 1; + + for (int i = 0; i < count; i++) { + offsets[i] = offset(); + int nameIndex = getCPIndex(); // unused + int payloadLen = getLength(); + if (payloadLen < 0) { + throw new InvalidClassFileException(offset(), "negative attribute length: " + payloadLen); + } + skip(payloadLen); + } + + offsets[count] = offset(); + } +} Added: trunk/src/x10/sncode/ClassEditor.java =================================================================== --- trunk/src/x10/sncode/ClassEditor.java (rev 0) +++ trunk/src/x10/sncode/ClassEditor.java 2009-05-12 03:11:38 UTC (rev 8300) @@ -0,0 +1,232 @@ +/******************************************************************************* + * Copyright (c) 2002,2006 IBM Corporation. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package x10.sncode; + +import java.util.AbstractList; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.Iterator; +import java.util.List; + +/** + * This is the core class for reading class file data. + * + * ClassReader performs lazy parsing, and thus most of the methods can throw an + * InvalidClassFileException. + */ +public final class ClassEditor extends Container implements SnConstants { + /** List of fields */ + List<FieldEditor> fields; + /** List of methods */ + List<MethodEditor> methods; + /** List of constructors */ + List<ConstructorEditor> constructors; + /** List of typedefs */ + List<TypedefEditor> typedefs; + /** List of member classes */ + List<ClassEditor> memberClasses; + + List<Tree> attributes; + + String className; + Type superClass; + + List<Type> interfaces; + List<Type> typeFormals; + List<Type> typeActuals; + List<Constraint> typeActualConstraints; + + Constraint classInvariant; + + public ClassEditor() { + interfaces = new ArrayList<Type>(0); + typeFormals = new ArrayList<Type>(0); + typeActuals = new ArrayList<Type>(0); + typeActualConstraints = new ArrayList<Constraint>(0); + + fields = new ArrayList<FieldEditor>(1); + methods = new ArrayList<MethodEditor>(1); + constructors = new ArrayList<ConstructorEditor>(1); + typedefs = new ArrayList<TypedefEditor>(1); + memberClasses = new ArrayList<ClassEditor>(1); + attributes = new ArrayList<Tree>(1); + } + + public String getName() { + return className; + } + + public void setName(String s) { + className = s; + } + + public void setSuperClass(Type t) { + superClass = t; + } + + public Type getSuperClass() throws InvalidClassFileException { + return superClass; + } + + public void addInterface(Type t) { + interfaces.add(t); + } + + public List<Type> getInterfaces() { + return interfaces; + } + + public void addTypeFormal(Type t) { + typeFormals.add(t); + } + + public List<Type> getTypeFormals() { + return typeFormals; + } + + public void addTypeActual(Type t) { + typeActuals.add(t); + } + + public List<Type> getTypeActuals() { + return typeActuals; + } + + public void addTypeActualConstraint(Constraint c) { + typeActualConstraints.add(c); + } + + public List<Constraint> getTypeActualConstraints() { + return typeActualConstraints; + } + + Constraint getClassInvariant() { + return classInvariant; + } + + void setClassInvariant(Constraint t) { + classInvariant = t; + } + + List<FieldEditor> fields() { + return fields; + } + + public List<MethodEditor> methods() { + return methods; + } + + List<ConstructorEditor> constructors() { + return constructors; + } + + List<TypedefEditor> typedefs() { + return typedefs; + } + + List<ClassEditor> memberClasses() { + return memberClasses; + } + + List toList(Object o) throws InvalidClassFileException { + if (o instanceof Object[]) + return Arrays.asList((Object[]) o); + throw new InvalidClassFileException(0, "bad array " + o); + } + + public void readFrom(final SnFile sn, Tree tree) throws InvalidClassFileException { + className = (String) tree.find("Name"); + typeFormals = (List) toList(tree.find("TypeFormals")); + typeActuals = (List) toList(tree.find("TypeActuals")); + typeActualConstraints = (List) toList(tree.find("TypeActualConstraints")); + classInvariant = (Constraint) tree.find("ClassInvariant"); + superClass = (Type) tree.find("SuperClass"); + interfaces = (List<Type>) toList(tree.find("Interfaces")); + + typedefs = mapList(tree.findAll("Typedef"), new Mapper<Tree, TypedefEditor, InvalidClassFileException>() { + TypedefEditor map(Tree t) throws InvalidClassFileException { + TypedefEditor e = new TypedefEditor(); + e.readFrom(sn, t); + return e; + } + }); + fields = mapList(tree.findAll("Field"), new Mapper<Tree, FieldEditor, InvalidClassFileException>() { + FieldEditor map(Tree t) throws InvalidClassFileException { + FieldEditor e = new FieldEditor(); + e.readFrom(sn, t); + return e; + } + }); + methods = mapList(tree.findAll("Method"), new Mapper<Tree, MethodEditor, InvalidClassFileException>() { + MethodEditor map(Tree t) throws InvalidClassFileException { + MethodEditor e = new MethodEditor(); + e.readFrom(sn, t); + return e; + } + }); + constructors = mapList(tree.findAll("Constructor"), new Mapper<Tree, ConstructorEditor, InvalidClassFileException>() { + ConstructorEditor map(Tree t) throws InvalidClassFileException { + ConstructorEditor e = new ConstructorEditor(); + e.readFrom(sn, t); + return e; + } + }); + memberClasses = mapList(tree.findAll("Class"), new Mapper<Tree, ClassEditor, InvalidClassFileException>() { + ClassEditor map(Tree t) throws InvalidClassFileException { + ClassEditor e = new ClassEditor(); + e.readFrom(sn, t); + return e; + } + }); + + String[] keys = new String[] { "Name", "TypeFormals", "TypeActuals", "TypeActualConstraints", "ClassInvariant", + "SuperClass", "Interfaces", "Field", "Method", "Constructor", "Typedef", "Class" }; + + attributes = new ArrayList<Tree>(tree.getChildren().size()); + for (Iterator<Tree> i = tree.getChildren().iterator(); i.hasNext();) { + Tree ti = i.next(); + if (Arrays.asList(keys).contains(ti.key)) + ; + else + attributes.add(ti); + } + } + + public Tree makeTree() { + Tree.Branch t = new Tree.Branch("Class", new Tree.Leaf("Name", className), + new Tree.Leaf("TypeFormals", SnFile.nonnull(typeFormals).toArray(new Type[0])), + new Tree.Leaf("TypeActuals", SnFile.nonnull(typeActuals).toArray(new Type[0])), + new Tree.Leaf("TypeActualConstraints", SnFile.nonnull(typeActualConstraints).toArray(new Constraint[0])), + new Tree.Leaf("ClassInvariant", classInvariant), new Tree.Leaf("SuperClass", superClass), + new Tree.Leaf("Interfaces", SnFile.nonnull(interfaces).toArray(new Type[0]))); + for (FieldEditor f : fields) { + t.add(f.makeTree()); + } + for (MethodEditor m : methods) { + t.add(m.makeTree()); + } + for (ConstructorEditor c : constructors) { + t.add(c.makeTree()); + } + for (TypedefEditor d : typedefs) { + t.add(d.makeTree()); + } + for (ClassEditor c : memberClasses) { + t.add(c.makeTree()); + } + for (Tree a : attributes) { + t.add(a); + } + return t; + } + +} Added: trunk/src/x10/sncode/ConstantPool.java =================================================================== --- trunk/src/x10/sncode/ConstantPool.java (rev 0) +++ trunk/src/x10/sncode/ConstantPool.java 2009-05-12 03:11:38 UTC (rev 8300) @@ -0,0 +1,723 @@ +/******************************************************************************* + * Copyright (c) 2002,2006 IBM Corporation. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package x10.sncode; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * This class formats and writes class data into JVM format. + */ +public final class ConstantPool implements SnConstants { + /** Inverted CP. Map from objects to index into the CP. */ + Map<Object, Integer> inverseMap = new HashMap<Object, Integer>(1); + + /** List of new CP entries added since last clearing of the list. */ + List<Object> cpItems = new ArrayList<Object>(1); + + /** + * Create a blank Sn editor with no members. + */ + public ConstantPool() { + inverseMap = new HashMap<Object, Integer>(); + cpItems = new ArrayList<Object>(); + cpItems.add(null); + } + + /** + * Copy a constant pool from some ClassReader into this class. This must be + * done before any entries are allocated in this ClassWriter's constant + * pool, and it can only be done once. If and only if this is done, it is + * safe to copy "raw" fields, methods and attributes from the ClassReader + * into this class, because the constant pool references in those fields, + * methods and attributes are guaranteed to point to the same constant pool + * items in this new class. + */ + public void setRawCP(ConstantPoolParser cp) throws InvalidClassFileException, IllegalArgumentException { + if (cp == null) { + throw new IllegalArgumentException(); + } + + cpItems.clear(); + + // item 0 + cpItems.add(null); + + int nextCPIndex = cp.getItemCount(); + + for (int i = 1; i < nextCPIndex; i++) { + byte t = cp.getItemType(i); + switch (t) { + case CONSTANT_Array: + addCPEntry(cp.getCPArray(i)); + break; + case CONSTANT_String: + addCPString(cp.getCPString(i)); + break; + case CONSTANT_Class: + addCPClass(cp.getCPClass(i)); + break; + case CONSTANT_FieldRef: + addCPFieldRef(cp.getCPRefClass(i), cp.getCPRefName(i), cp.getCPRefType(i)); + break; + case CONSTANT_MethodRef: + addCPMethodRef(cp.getCPRefClass(i), cp.getCPRefName(i), cp.getCPRefType(i)); + break; + case CONSTANT_NameAndType: + addCPNameAndType(cp.getCPNATName(i), cp.getCPNATType(i)); + break; + case CONSTANT_Integer: + addCPInt(cp.getCPInt(i)); + break; + case CONSTANT_Float: + addCPFloat(cp.getCPFloat(i)); + break; + case CONSTANT_Long: + addCPLong(cp.getCPLong(i)); + break; + case CONSTANT_Double: + addCPDouble(cp.getCPDouble(i)); + break; + case CONSTANT_Utf8: + addCPUtf8(cp.getCPUtf8(i)); + break; + case CONSTANT_Constraint: + addCPConstraint(cp.getCPConstraint(i)); + break; + case CONSTANT_Type: + addCPType(cp.getCPType(i)); + break; + case CONSTANT_ByteArray: + addCPBytes(cp.getCPBytes(i)); + break; + } + } + } + + public int addCPEntry(Object o) { + if (inverseMap == null) { + throw new IllegalArgumentException("Cannot add a new constant pool entry during makeBytes() processing!"); + } + + if (o == null) + return 0; + + Integer i = inverseMap.get(o); + if (i != null) { + return i.intValue(); + } + else { + int index = cpItems.size(); + i = new Integer(index); + inverseMap.put(o, i); + cpItems.add(o); + return index; + } + } + + /** + * Add a Utf8 string to the constant pool if necessary. + * + * @return the index of a constant pool item with the right value + */ + public int addCPUtf8(String s) { + return addCPEntry(s); + } + + /** + * Add a Utf8 string to the constant pool if necessary. + * + * @return the index of a constant pool item with the right value + */ + public int addCPConstraint(Constraint s) { + return addCPEntry(s); + } + + /** + * Add an Integer to the constant pool if necessary. + * + * @return the index of a constant pool item with the right value + */ + public int addCPInt(int i) { + return addCPEntry(new Integer(i)); + } + + /** + * Add a Float to the constant pool if necessary. + * + * @return the index of a constant pool item with the right value + */ + public int addCPFloat(float f) { + return addCPEntry(new Float(f)); + } + + /** + * Add a Float to the constant pool if necessary. + * + * @return the index of a constant pool item with the right value + */ + public int addCPBytes(byte[] b) { + return addCPEntry(b); + } + + /** + * Add a Long to the constant pool if necessary. + * + * @return the index of a constant pool item with the right value + */ + public int addCPLong(long l) { + return addCPEntry(new Long(l)); + } + + /** + * Add a Double to the constant pool if necessary. + * + * @return the index of a constant pool item with the right value + */ + public int addCPDouble(double d) { + return addCPEntry(new Double(d)); + } + + /** + * Add a String to the constant pool if necessary. + * + * @return the index of a constant pool item with the right value + */ + public int addCPString(String s) { + return addCPEntry(new CWString(s)); + } + + /** + * Add a Class to the constant pool if necessary. + * + * @param s + * the class name, in JVM format (e.g., java/lang/Object) + * @return the index of a constant pool item with the right value + */ + public int addCPClass(String s) { + if (s == null) { + throw new IllegalArgumentException("null s: " + s); + } + return addCPEntry(new CWClass(s)); + } + + /** + * Add a Type to the constant pool if necessary. + * + * @param s + * the class name, in JVM format (e.g., java/lang/Object) + * @return the index of a constant pool item with the right value + */ + public int addCPType(String s) { + if (s == null) { + throw new IllegalArgumentException("null s: " + s); + } + try { + return addCPEntry(Type.parse(s)); + } + catch (InvalidClassFileException e) { + throw new IllegalArgumentException(e); + } + } + + /** + * Add a Type to the constant pool if necessary. + * + * @param s + * the class name, in JVM format (e.g., java/lang/Object) + * @return the index of a constant pool item with the right value + */ + public int addCPType(Type s) { + if (s == null) { + throw new IllegalArgumentException("null s: " + s); + } + return addCPEntry(s); + } + + /** + * Add a FieldRef to the constant pool if necessary. + * + * @param c + * the class name, in JVM format (e.g., java/lang/Object) + * @param n + * the field name + * @param t + * the field type, in JVM format (e.g., I, Z, or + * Ljava/lang/Object;) + * @return the index of a constant pool item with the right value + */ + public int addCPFieldRef(String c, String n, String t) { + return addCPEntry(new CWRef(CONSTANT_FieldRef, c, n, t)); + } + + /** + * Add a MethodRef to the constant pool if necessary. + * + * @param c + * the class name, in JVM format (e.g., java/lang/Object) + * @param n + * the method name + * @param t + * the method type, in JVM format (e.g., V(ILjava/lang/Object;) ) + * @return the index of a constant pool item with the right value + */ + public int addCPMethodRef(String c, String n, String t) { + return addCPEntry(new CWRef(CONSTANT_MethodRef, c, n, t)); + } + + /** + * Add a NameAndType to the constant pool if necessary. + * + * @param n + * the name + * @param t + * the type, in JVM format + * @return the index of a constant pool item with the right value + */ + public int addCPNameAndType(String n, String t) { + return addCPEntry(new CWNameAndType(n, t)); + } + + void copyInto(ByteBuffer w) { + int countOffset = w.offset(); + + // Reserve a place for the number of entries. + w.addInt(0); + + // BE CAREFUL: the newCPEntries array grows during this loop. + for (int i = 1; i < cpItems.size(); i++) { + Object o = getCPEntry(i); + + w.addInt(0xdeadbeef); + + if (o instanceof CWItem) { + CWItem item = (CWItem) o; + byte t = item.getType(); + switch (t) { + case CONSTANT_Class: + w.addByte(t); + w.addInt(addCPUtf8(((CWClass) item).name)); + break; + case CONSTANT_String: + w.addByte(t); + w.addInt(addCPUtf8(((CWString) item).str)); + break; + case CONSTANT_NameAndType: { + CWNameAndType nat = (CWNameAndType) item; + w.addByte(t); + w.addInt(addCPUtf8(nat.name)); + w.addInt(addCPType(nat.type)); + break; + } + case CONSTANT_MethodRef: + case CONSTANT_FieldRef: { + CWRef ref = (CWRef) item; + w.addByte(t); + w.addInt(addCPClass(ref.container)); + w.addInt(addCPNameAndType(ref.name, ref.type)); + break; + } + default: + throw new Error("Invalid type: " + t); + } + } + else if (o instanceof String) { + String s = (String) o; + + w.addByte(CONSTANT_Utf8); + int lenOffset = w.offset(); + w.addInt(0); + + int startOffset = w.offset(); + + for (int j = 0; j < s.length(); j++) { + char ch = s.charAt(j); + if (ch == 0) { + w.addUShort(0xC080); + } + else if (ch < 0x80) { + w.addByte((byte) ch); + } + else if (ch < 0x800) { + w.addByte((byte) ((ch >> 6) | 0xC0)); + w.addByte((byte) ((ch & 0x3F) | 0x80)); + } + else { + w.addByte((byte) ((ch >> 12) | 0xE0)); + w.addByte((byte) (((ch >> 6) & 0x3F) | 0x80)); + w.addByte((byte) ((ch & 0x3F) | 0x80)); + } + } + int bytes = w.offset() - startOffset; + w.setInt(lenOffset, bytes); + } + else if (o instanceof Integer) { + w.addByte(CONSTANT_Integer); + w.addInt(((Integer) o).intValue()); + } + else if (o instanceof Long) { + w.addByte(CONSTANT_Long); + w.addLong(((Long) o).longValue()); + } + else if (o instanceof Float) { + w.addByte(CONSTANT_Float); + w.addFloat(((Float) o).floatValue()); + } + else if (o instanceof Double) { + w.addByte(CONSTANT_Double); + w.addDouble(((Double) o).doubleValue()); + } + else if (o instanceof byte[]) { + w.addByte(CONSTANT_ByteArray); + w.addLength(((byte[]) o).length); + w.addBytes((byte[]) o); + } + else if (o instanceof Object[]) { + w.addByte(CONSTANT_Array); + Object[] a = (Object[]) o; + w.addLength(a.length*CP_INDEX_SIZE); + for (int k = 0; k < a.length; k++) { + w.addCPIndex(addCPEntry(a[k])); + } + } + else if (o instanceof int[]) { + w.addByte(CONSTANT_Array); + int[] a = (int[]) o; + w.addLength(a.length*CP_INDEX_SIZE); + for (int k = 0; k < a.length; k++) { + w.addCPIndex(addCPEntry(a[k])); + } + } + else if (o instanceof long[]) { + w.addByte(CONSTANT_Array); + long[] a = (long[]) o; + w.addLength(a.length*CP_INDEX_SIZE); + for (int k = 0; k < a.length; k++) { + w.addCPIndex(addCPEntry(a[k])); + } + } + else if (o instanceof float[]) { + w.addByte(CONSTANT_Array); + float[] a = (float[]) o; + w.addLength(a.length*CP_INDEX_SIZE); + for (int k = 0; k < a.length; k++) { + w.addCPIndex(addCPEntry(a[k])); + } + } + else if (o instanceof double[]) { + w.addByte(CONSTANT_Array); + double[] a = (double[]) o; + w.addLength(a.length*CP_INDEX_SIZE); + for (int k = 0; k < a.length; k++) { + w.addCPIndex(addCPEntry(a[k])); + } + } + else if (o instanceof Constraint) { + Constraint c = (Constraint) o; + w.addByte(CONSTANT_Constraint); + c.write(w); + } + else if (o instanceof Type) { + Type c = (Type) o; + w.addByte(CONSTANT_Type); + c.writeInto(this, w); + } + else { + throw new IllegalArgumentException("bad cp item " + o + " at " + i); + } + } + + // go back and write the count + w.setInt(countOffset, cpItems.size()); + } + + /** + * @return the number of constant pool items (maximum item index plus one) + */ + public int getItemCount() { + return cpItems.size(); + } + + public Object getCPEntry(int i) { + return cpItems.get(i); + } + + /** + * @return the type of constant pool item i, or 0 if i is an unused constant + * pool item + */ + public byte getItemType(int i) throws IllegalArgumentException { + Object o = getCPEntry(i); + if (o == null) + return CONSTANT_Null; + if (o instanceof String) + return CONSTANT_Utf8; + if (o instanceof Integer) + return CONSTANT_Integer; + if (o instanceof Long) + return CONSTANT_Long; + if (o instanceof Float) + return CONSTANT_Float; + if (o instanceof Double) + return CONSTANT_Double; + if (o instanceof byte[]) + return CONSTANT_ByteArray; + if (o instanceof Object[]) + return CONSTANT_Array; + if (o instanceof CWItem) + return ((CWItem) o).getType(); + throw new IllegalArgumentException("bad constant at " + i); + } + + /** + * @return the name of the Class at constant pool item i, in JVM format + * (e.g., java/lang/Object) + */ + public String getCPClass(int i) { + return ((CWClass) getCPEntry(i)).name; + }... [truncated message content] |