[Proxool-cvs] proxool/src/java/org/logicalcobwebs/asm Attribute.java,NONE,1.1 ByteVector.java,NONE,1
UNMAINTAINED!
Brought to you by:
billhorsman
Update of /cvsroot/proxool/proxool/src/java/org/logicalcobwebs/asm In directory sc8-pr-cvs1:/tmp/cvs-serv22981/src/java/org/logicalcobwebs/asm Added Files: Attribute.java ByteVector.java ClassAdapter.java ClassReader.java ClassVisitor.java ClassWriter.java CodeAdapter.java CodeVisitor.java CodeWriter.java Constants.java Edge.java Item.java Label.java Type.java package.html Log Message: Repackaged ASM project --- NEW FILE: Attribute.java --- /*** * ASM: a very small and fast Java bytecode manipulation framework * Copyright (c) 2000,2002,2003 INRIA, France Telecom * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the copyright holders nor the names of its * contributors may be used to endorse or promote products derived from * this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF * THE POSSIBILITY OF SUCH DAMAGE. * * Contact: Eri...@rd... * * Author: Eric Bruneton */ package org.logicalcobwebs.asm; /** * A non standard class, field, method or code attribute. */ public class Attribute { /** * The type of this attribute. */ public String type; /** * The byte array that contains the value of this attribute. <i>The content of * this array must not be modified, although the array itself can be changed * (i.e. attr.b[...] = ...; is forbidden, but attr.b = ...; is allowed)</i>. */ public byte[] b; /** * Index of the first byte of this attribute in {@link #b b}. */ public int off; /** * Length of this attributes, in bytes. */ public int len; /** * The next attribute in this attribute list. May be <tt>null</tt>. */ public Attribute next; /** * Constructs a new {@link Attribute}. * * @param type the type of the attribute. * @param b byte array that contains the value of the attribute. * @param off index of the first byte of the attribute in <tt>b</tt>. * @param len length of the attributes, in bytes. */ public Attribute ( final String type, final byte[] b, final int off, final int len) { this.type = type; this.b = b; this.off = off; this.len = len; } /** * Constructs a new empty attribute. * * @param type the type of the attribute. */ public Attribute (final String type) { this(type, null, 0, 0); } /** * Returns the length of the attribute list that begins with this attribute. * * @return the length of the attribute list that begins with this attribute. */ final int getCount () { int count = 0; Attribute attr = this; while (attr != null) { count += 1; attr = attr.next; } return count; } /** * Returns the size of all the attributes in this attribute list. * * @param cw the class writer to be used to convert the attributes into byte * arrays, with the {@link ClassWriter#writeAttribute writeAttribute} * method. * @return the size of all the attributes in this attribute list. This size * includes the size of the attribute headers. */ final int getSize (final ClassWriter cw) { int size = 0; Attribute attr = this; while (attr != null) { cw.newUTF8(attr.type); size += cw.writeAttribute(attr).length + 6; attr = attr.next; } return size; } /** * Writes all the attributes of this attribute list in the given byte vector. * * @param cw the class writer to be used to convert the attributes into byte * arrays, with the {@link ClassWriter#writeAttribute writeAttribute} * method. * @param out where the attributes must be written. */ final void put (final ClassWriter cw, final ByteVector out) { Attribute attr = this; while (attr != null) { byte[] b = cw.writeAttribute(attr); out.put2(cw.newUTF8(attr.type)).put4(b.length); out.putByteArray(b, 0, b.length); attr = attr.next; } } } --- NEW FILE: ByteVector.java --- /*** * ASM: a very small and fast Java bytecode manipulation framework * Copyright (c) 2000,2002,2003 INRIA, France Telecom * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the copyright holders nor the names of its * contributors may be used to endorse or promote products derived from * this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF * THE POSSIBILITY OF SUCH DAMAGE. * * Contact: Eri...@rd... * * Author: Eric Bruneton */ package org.logicalcobwebs.asm; /** * A dynamically extensible vector of bytes. This class is roughly equivalent to * a DataOutputStream on top of a ByteArrayOutputStream, but is more efficient. */ final class ByteVector { /** * The content of this vector. */ byte[] data; /** * Actual number of bytes in this vector. */ int length; /** * Constructs a new {@link ByteVector ByteVector} with a default initial size. */ public ByteVector () { data = new byte[64]; } /** * Constructs a new {@link ByteVector ByteVector} with the given initial size. * * @param initialSize the initial size of the byte vector to be constructed. */ public ByteVector (final int initialSize) { data = new byte[initialSize]; } /** * Puts a byte into this byte vector. The byte vector is automatically * enlarged if necessary. * * @param b a byte. * @return this byte vector. */ public ByteVector put1 (final int b) { int length = this.length; if (length + 1 > data.length) { enlarge(1); } data[length++] = (byte)b; this.length = length; return this; } /** * Puts two bytes into this byte vector. The byte vector is automatically * enlarged if necessary. * * @param b1 a byte. * @param b2 another byte. * @return this byte vector. */ public ByteVector put11 (final int b1, final int b2) { int length = this.length; if (length + 2 > data.length) { enlarge(2); } byte[] data = this.data; data[length++] = (byte)b1; data[length++] = (byte)b2; this.length = length; return this; } /** * Puts a short into this byte vector. The byte vector is automatically * enlarged if necessary. * * @param s a short. * @return this byte vector. */ public ByteVector put2 (final int s) { int length = this.length; if (length + 2 > data.length) { enlarge(2); } byte[] data = this.data; data[length++] = (byte)(s >>> 8); data[length++] = (byte)s; this.length = length; return this; } /** * Puts a byte and a short into this byte vector. The byte vector is * automatically enlarged if necessary. * * @param b a byte. * @param s a short. * @return this byte vector. */ public ByteVector put12 (final int b, final int s) { int length = this.length; if (length + 3 > data.length) { enlarge(3); } byte[] data = this.data; data[length++] = (byte)b; data[length++] = (byte)(s >>> 8); data[length++] = (byte)s; this.length = length; return this; } /** * Puts an int into this byte vector. The byte vector is automatically * enlarged if necessary. * * @param i an int. * @return this byte vector. */ public ByteVector put4 (final int i) { int length = this.length; if (length + 4 > data.length) { enlarge(4); } byte[] data = this.data; data[length++] = (byte)(i >>> 24); data[length++] = (byte)(i >>> 16); data[length++] = (byte)(i >>> 8); data[length++] = (byte)i; this.length = length; return this; } /** * Puts a long into this byte vector. The byte vector is automatically * enlarged if necessary. * * @param l a long. * @return this byte vector. */ public ByteVector put8 (final long l) { int length = this.length; if (length + 8 > data.length) { enlarge(8); } byte[] data = this.data; int i = (int)(l >>> 32); data[length++] = (byte)(i >>> 24); data[length++] = (byte)(i >>> 16); data[length++] = (byte)(i >>> 8); data[length++] = (byte)i; i = (int)l; data[length++] = (byte)(i >>> 24); data[length++] = (byte)(i >>> 16); data[length++] = (byte)(i >>> 8); data[length++] = (byte)i; this.length = length; return this; } /** * Puts a String in UTF format into this byte vector. The byte vector is * automatically enlarged if necessary. * * @param s a String. * @return this byte vector. */ public ByteVector putUTF (final String s) { int charLength = s.length(); int byteLength = 0; for (int i = 0; i < charLength; ++i) { char c = s.charAt(i); if (c >= '\001' && c <= '\177') { byteLength++; } else if (c > '\u07FF') { byteLength += 3; } else { byteLength += 2; } } if (byteLength > 65535) { throw new IllegalArgumentException(); } int length = this.length; if (length + 2 + byteLength > data.length) { enlarge(2 + byteLength); } byte[] data = this.data; data[length++] = (byte)(byteLength >>> 8); data[length++] = (byte)(byteLength); for (int i = 0; i < charLength; ++i) { char c = s.charAt(i); if (c >= '\001' && c <= '\177') { data[length++] = (byte)c; } else if (c > '\u07FF') { data[length++] = (byte)(0xE0 | c >> 12 & 0xF); data[length++] = (byte)(0x80 | c >> 6 & 0x3F); data[length++] = (byte)(0x80 | c & 0x3F); } else { data[length++] = (byte)(0xC0 | c >> 6 & 0x1F); data[length++] = (byte)(0x80 | c & 0x3F); } } this.length = length; return this; } /** * Puts an array of bytes into this byte vector. The byte vector is * automatically enlarged if necessary. * * @param b an array of bytes. May be <tt>null</tt> to put <tt>len</tt> null * bytes into this byte vector. * @param off index of the fist byte of b that must be copied. * @param len number of bytes of b that must be copied. * @return this byte vector. */ public ByteVector putByteArray ( final byte[] b, final int off, final int len) { if (length + len > data.length) { enlarge(len); } if (b != null) { System.arraycopy(b, off, data, length, len); } length += len; return this; } /** * Enlarge this byte vector so that it can receive n more bytes. * * @param size number of additional bytes that this byte vector should be * able to receive. */ private void enlarge (final int size) { int length1 = 2 * data.length; int length2 = length + size; byte[] newData = new byte[length1 > length2 ? length1 : length2]; System.arraycopy(data, 0, newData, 0, length); data = newData; } } --- NEW FILE: ClassAdapter.java --- /*** * ASM: a very small and fast Java bytecode manipulation framework * Copyright (c) 2000,2002,2003 INRIA, France Telecom * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the copyright holders nor the names of its * contributors may be used to endorse or promote products derived from * this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF * THE POSSIBILITY OF SUCH DAMAGE. * * Contact: Eri...@rd... * * Author: Eric Bruneton */ package org.logicalcobwebs.asm; /** * An empty {@link ClassVisitor ClassVisitor} that delegates to another {@link * ClassVisitor ClassVisitor}. This class can be used as a super class to * quickly implement usefull class adapter classes, just by overriding the * necessary methods. */ public class ClassAdapter implements ClassVisitor { /** * The {@link ClassVisitor ClassVisitor} to which this adapter delegates * calls. */ protected ClassVisitor cv; /** * Constructs a new {@link ClassAdapter ClassAdapter} object. * * @param cv the class visitor to which this adapter must delegate calls. */ public ClassAdapter (final ClassVisitor cv) { this.cv = cv; } public void visit ( final int access, final String name, final String superName, final String[] interfaces, final String sourceFile) { cv.visit(access, name, superName, interfaces, sourceFile); } public void visitInnerClass ( final String name, final String outerName, final String innerName, final int access) { cv.visitInnerClass(name, outerName, innerName, access); } public void visitField ( final int access, final String name, final String desc, final Object value, final Attribute attrs) { cv.visitField(access, name, desc, value, attrs); } public CodeVisitor visitMethod ( final int access, final String name, final String desc, final String[] exceptions, final Attribute attrs) { return new CodeAdapter(cv.visitMethod(access, name, desc, exceptions, attrs)); } public void visitAttribute (final Attribute attr) { cv.visitAttribute(attr); } public void visitEnd () { cv.visitEnd(); } } --- NEW FILE: ClassReader.java --- /*** * ASM: a very small and fast Java bytecode manipulation framework * Copyright (c) 2000,2002,2003 INRIA, France Telecom * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the copyright holders nor the names of its * contributors may be used to endorse or promote products derived from * this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF * THE POSSIBILITY OF SUCH DAMAGE. * * Contact: Eri...@rd... * * Author: Eric Bruneton */ package org.logicalcobwebs.asm; import java.io.InputStream; import java.io.IOException; /** * A Java class parser to make a {@link ClassVisitor ClassVisitor} visit an * existing class. This class parses a byte array conforming to the Java class * file format and calls the appropriate visit methods of a given class visitor * for each field, method and bytecode instruction encountered. */ public class ClassReader { /** * The class to be parsed. <i>The content of this array must not be * modified.</i> */ protected final byte[] b; /** * The start index of each constant pool item in {@link #b b}, plus one. The * one byte offset skips the constant pool item tag that indicates its type. */ private int[] items; /** * The String objects corresponding to the CONSTANT_Utf8 items. This cache * avoids multiple parsing of a given CONSTANT_Utf8 constant pool item, which * GREATLY improves performances (by a factor 2 to 3). This caching strategy * could be extended to all constant pool items, but its benefit would not be * so great for these items (because they are much less expensive to parse * than CONSTANT_Utf8 items). */ private String[] strings; /** * Maximum length of the strings contained in the constant pool of the class. */ private int maxStringLength; /** * Start index of the class header information (access, name...) in {@link #b * b}. */ private int header; // -------------------------------------------------------------------------- // Constructors // -------------------------------------------------------------------------- /** * Constructs a new {@link ClassReader ClassReader} object. * * @param b the bytecode of the class to be read. */ public ClassReader (final byte[] b) { this(b, 0, b.length); } /** * Constructs a new {@link ClassReader ClassReader} object. * * @param b the bytecode of the class to be read. * @param off the start offset of the class data. * @param len the length of the class data. */ public ClassReader (final byte[] b, final int off, final int len) { this.b = b; // parses the constant pool items = new int[readUnsignedShort(off + 8)]; strings = new String[items.length]; int max = 0; int index = off + 10; for (int i = 1; i < items.length; ++i) { items[i] = index + 1; int tag = b[index]; int size; switch (tag) { case ClassWriter.FIELD: case ClassWriter.METH: case ClassWriter.IMETH: case ClassWriter.INT: case ClassWriter.FLOAT: case ClassWriter.NAME_TYPE: size = 5; break; case ClassWriter.LONG: case ClassWriter.DOUBLE: size = 9; ++i; break; case ClassWriter.UTF8: size = 3 + readUnsignedShort(index + 1); max = (size > max ? size : max); break; //case ClassWriter.CLASS: //case ClassWriter.STR: default: size = 3; break; } index += size; } maxStringLength = max; // the class header information starts just after the constant pool header = index; } /** * Constructs a new {@link ClassReader ClassReader} object. * * @param is an input stream from which to read the class. * @throws IOException if a problem occurs during reading. */ public ClassReader (final InputStream is) throws IOException { this(readClass(is)); } /** * Constructs a new {@link ClassReader ClassReader} object. * * @param name the fully qualified name of the class to be read. * @throws IOException if an exception occurs during reading. */ public ClassReader (final String name) throws IOException { this((ClassReader.class.getClassLoader() == null ? ClassLoader.getSystemClassLoader() : ClassReader.class.getClassLoader()) .getSystemResourceAsStream(name.replace('.','/') + ".class")); } /** * Reads the bytecode of a class. * * @param is an input stream from which to read the class. * @return the bytecode read from the given input stream. * @throws IOException if a problem occurs during reading. */ private static byte[] readClass (final InputStream is) throws IOException { if (is == null) { throw new IOException("Class not found"); } byte[] b = new byte[is.available()]; int len = 0; while (true) { int n = is.read(b, len, b.length - len); if (n == -1) { if (len < b.length) { byte[] c = new byte[len]; System.arraycopy(b, 0, c, 0, len); b = c; } return b; } else { len += n; if (len == b.length) { byte[] c = new byte[b.length + 1000]; System.arraycopy(b, 0, c, 0, len); b = c; } } } } // -------------------------------------------------------------------------- // Public methods // -------------------------------------------------------------------------- /** * Makes the given visitor visit the Java class of this {@link ClassReader * ClassReader}. This class is the one specified in the constructor (see * {@link #ClassReader ClassReader}). * * @param classVisitor the visitor that must visit this class. * @param skipDebug <tt>true</tt> if the debug information of the class must * not be visited. In this case the {@link CodeVisitor#visitLocalVariable * visitLocalVariable} and {@link CodeVisitor#visitLineNumber * visitLineNumber} methods will not be called. */ public void accept ( final ClassVisitor classVisitor, final boolean skipDebug) { byte[] b = this.b; // the bytecode array char[] c = new char[maxStringLength]; // buffer used to read strings int i, j, k; // loop variables int u, v, w; // indexes in b Attribute attr; // visits the header u = header; int access = readUnsignedShort(u); String className = readClass(u + 2, c); v = items[readUnsignedShort(u + 4)]; String superClassName = v == 0 ? null : readUTF8(v, c); String[] implementedItfs = new String[readUnsignedShort(u + 6)]; String sourceFile = null; Attribute clattrs = null; w = 0; u += 8; for (i = 0; i < implementedItfs.length; ++i) { implementedItfs[i] = readClass(u, c); u += 2; } // skips fields and methods v = u; i = readUnsignedShort(v); v += 2; for ( ; i > 0; --i) { j = readUnsignedShort(v + 6); v += 8; for ( ; j > 0; --j) { v += 6 + readInt(v + 2); } } i = readUnsignedShort(v); v += 2; for ( ; i > 0; --i) { j = readUnsignedShort(v + 6); v += 8; for ( ; j > 0; --j) { v += 6 + readInt(v + 2); } } // reads the class's attributes i = readUnsignedShort(v); v += 2; for ( ; i > 0; --i) { String attrName = readUTF8(v, c); if (attrName.equals("SourceFile")) { sourceFile = readUTF8(v + 6, c); } else if (attrName.equals("Deprecated")) { access |= Constants.ACC_DEPRECATED; } else if (attrName.equals("InnerClasses")) { w = v + 6; } else { attr = readAttribute(attrName, v + 6, readInt(v + 2), c); attr.next = clattrs; clattrs = attr; } v += 6 + readInt(v + 2); } // calls the visit method classVisitor.visit( access, className, superClassName, implementedItfs, sourceFile); // visits the inner classes info if (w != 0) { i = readUnsignedShort(w); w += 2; for ( ; i > 0; --i) { classVisitor.visitInnerClass( readUnsignedShort(w) == 0 ? null : readClass(w, c), readUnsignedShort(w + 2) == 0 ? null : readClass(w + 2, c), readUnsignedShort(w + 4) == 0 ? null : readUTF8(w + 4, c), readUnsignedShort(w + 6)); w += 8; } } // visits the fields i = readUnsignedShort(u); u += 2; for ( ; i > 0; --i) { access = readUnsignedShort(u); String fieldName = readUTF8(u + 2, c); String fieldDesc = readUTF8(u + 4, c); Attribute fattrs = null; // visits the field's attributes and looks for a ConstantValue attribute int fieldValueItem = 0; j = readUnsignedShort(u + 6); u += 8; for ( ; j > 0; --j) { String attrName = readUTF8(u, c); if (attrName.equals("ConstantValue")) { fieldValueItem = readUnsignedShort(u + 6); } else if (attrName.equals("Synthetic")) { access |= Constants.ACC_SYNTHETIC; } else if (attrName.equals("Deprecated")) { access |= Constants.ACC_DEPRECATED; } else { attr = readAttribute(attrName, u + 6, readInt(u + 2), c); attr.next = fattrs; fattrs = attr; } u += 6 + readInt(u + 2); } // reads the field's value, if any Object value = (fieldValueItem == 0 ? null : readConst(fieldValueItem, c)); // visits the field classVisitor.visitField(access, fieldName, fieldDesc, value, fattrs); } // visits the methods i = readUnsignedShort(u); u += 2; for ( ; i > 0; --i) { access = readUnsignedShort(u); String methName = readUTF8(u + 2, c); String methDesc = readUTF8(u + 4, c); Attribute mattrs = null; v = 0; w = 0; // looks for Code and Exceptions attributes j = readUnsignedShort(u + 6); u += 8; for ( ; j > 0; --j) { String attrName = readUTF8(u, c); u += 2; int attrSize = readInt(u); u += 4; if (attrName.equals("Code")) { v = u; } else if (attrName.equals("Exceptions")) { w = u; } else if (attrName.equals("Synthetic")) { access |= Constants.ACC_SYNTHETIC; } else if (attrName.equals("Deprecated")) { access |= Constants.ACC_DEPRECATED; } else { attr = readAttribute(attrName, u, attrSize, c); attr.next = mattrs; mattrs = attr; } u += attrSize; } // reads declared exceptions String[] exceptions; if (w == 0) { exceptions = null; } else { exceptions = new String[readUnsignedShort(w)]; w += 2; for (j = 0; j < exceptions.length; ++j) { exceptions[j] = readClass(w, c); w += 2; } } // visits the method's code, if any CodeVisitor cv; cv = classVisitor.visitMethod( access, methName, methDesc, exceptions, mattrs); if (cv != null && v != 0) { int maxStack = readUnsignedShort(v); int maxLocals = readUnsignedShort(v + 2); int codeLength = readInt(v + 4); Attribute cattrs = null; v += 8; int codeStart = v; int codeEnd = v + codeLength; // 1st phase: finds the labels int label; Label[] labels = new Label[codeLength + 1]; while (v < codeEnd) { int opcode = b[v] & 0xFF; switch (ClassWriter.TYPE[opcode]) { case ClassWriter.NOARG_INSN: case ClassWriter.IMPLVAR_INSN: v += 1; break; case ClassWriter.LABEL_INSN: label = v - codeStart + readShort(v + 1); if (labels[label] == null) { labels[label] = new Label(); } v += 3; break; case ClassWriter.LABELW_INSN: label = v - codeStart + readInt(v + 1); if (labels[label] == null) { labels[label] = new Label(); } v += 5; break; case ClassWriter.WIDE_INSN: opcode = b[v + 1] & 0xFF; if (opcode == Constants.IINC) { v += 6; } else { v += 4; } break; case ClassWriter.TABL_INSN: // skips 0 to 3 padding bytes w = v - codeStart; v = v + 4 - (w & 3); // reads instruction label = w + readInt(v); v += 4; if (labels[label] == null) { labels[label] = new Label(); } j = readInt(v); v += 4; j = readInt(v) - j + 1; v += 4; for ( ; j > 0; --j) { label = w + readInt(v); v += 4; if (labels[label] == null) { labels[label] = new Label(); } } break; case ClassWriter.LOOK_INSN: // skips 0 to 3 padding bytes w = v - codeStart; v = v + 4 - (w & 3); // reads instruction label = w + readInt(v); v += 4; if (labels[label] == null) { labels[label] = new Label(); } j = readInt(v); v += 4; for ( ; j > 0; --j) { v += 4; // skips key label = w + readInt(v); v += 4; if (labels[label] == null) { labels[label] = new Label(); } } break; case ClassWriter.VAR_INSN: case ClassWriter.SBYTE_INSN: case ClassWriter.LDC_INSN: v += 2; break; case ClassWriter.SHORT_INSN: case ClassWriter.LDCW_INSN: case ClassWriter.FIELDORMETH_INSN: case ClassWriter.TYPE_INSN: case ClassWriter.IINC_INSN: v += 3; break; case ClassWriter.ITFMETH_INSN: v += 5; break; // case MANA_INSN: default: v += 4; break; } } // parses the try catch entries j = readUnsignedShort(v); v += 2; for ( ; j > 0; --j) { label = readUnsignedShort(v); if (labels[label] == null) { labels[label] = new Label(); } label = readUnsignedShort(v + 2); if (labels[label] == null) { labels[label] = new Label(); } label = readUnsignedShort(v + 4); if (labels[label] == null) { labels[label] = new Label(); } v += 8; } if (!skipDebug) { // parses the local variable and line number tables j = readUnsignedShort(v); v += 2; for ( ; j > 0; --j) { String attrName = readUTF8(v, c); if (attrName.equals("LocalVariableTable")) { k = readUnsignedShort(v + 6); w = v + 8; for ( ; k > 0; --k) { label = readUnsignedShort(w); if (labels[label] == null) { labels[label] = new Label(); } label += readUnsignedShort(w + 2); if (labels[label] == null) { labels[label] = new Label(); } w += 10; } } else if (attrName.equals("LineNumberTable")) { k = readUnsignedShort(v + 6); w = v + 8; for ( ; k > 0; --k) { label = readUnsignedShort(w); if (labels[label] == null) { labels[label] = new Label(); } w += 4; } } else { attr = readAttribute(attrName, v + 6, readInt(v + 2), c); attr.next = cattrs; cattrs = attr; } v += 6 + readInt(v + 2); } } // 2nd phase: visits each instruction v = codeStart; Label l; while (v < codeEnd) { w = v - codeStart; l = labels[w]; if (l != null) { cv.visitLabel(l); } int opcode = b[v] & 0xFF; switch (ClassWriter.TYPE[opcode]) { case ClassWriter.NOARG_INSN: cv.visitInsn(opcode); v += 1; break; case ClassWriter.IMPLVAR_INSN: if (opcode > Constants.ISTORE) { opcode -= 59; //ISTORE_0 cv.visitVarInsn(Constants.ISTORE + (opcode >> 2), opcode & 0x3); } else { opcode -= 26; //ILOAD_0 cv.visitVarInsn(Constants.ILOAD + (opcode >> 2), opcode & 0x3); } v += 1; break; case ClassWriter.LABEL_INSN: cv.visitJumpInsn(opcode, labels[w + readShort(v + 1)]); v += 3; break; case ClassWriter.LABELW_INSN: cv.visitJumpInsn(opcode, labels[w + readInt(v + 1)]); v += 5; break; case ClassWriter.WIDE_INSN: opcode = b[v + 1] & 0xFF; if (opcode == Constants.IINC) { cv.visitIincInsn(readUnsignedShort(v + 2), readShort(v + 4)); v += 6; } else { cv.visitVarInsn(opcode, readUnsignedShort(v + 2)); v += 4; } break; case ClassWriter.TABL_INSN: // skips 0 to 3 padding bytes v = v + 4 - (w & 3); // reads instruction label = w + readInt(v); v += 4; int min = readInt(v); v += 4; int max = readInt(v); v += 4; Label[] table = new Label[max - min + 1]; for (j = 0; j < table.length; ++j) { table[j] = labels[w + readInt(v)]; v += 4; } cv.visitTableSwitchInsn(min, max, labels[label], table); break; case ClassWriter.LOOK_INSN: // skips 0 to 3 padding bytes v = v + 4 - (w & 3); // reads instruction label = w + readInt(v); v += 4; j = readInt(v); v += 4; int[] keys = new int[j]; Label[] values = new Label[j]; for (j = 0; j < keys.length; ++j) { keys[j] = readInt(v); v += 4; values[j] = labels[w + readInt(v)]; v += 4; } cv.visitLookupSwitchInsn(labels[label], keys, values); break; case ClassWriter.VAR_INSN: cv.visitVarInsn(opcode, b[v + 1] & 0xFF); v += 2; break; case ClassWriter.SBYTE_INSN: cv.visitIntInsn(opcode, b[v + 1]); v += 2; break; case ClassWriter.SHORT_INSN: cv.visitIntInsn(opcode, readShort(v + 1)); v += 3; break; case ClassWriter.LDC_INSN: cv.visitLdcInsn(readConst(b[v + 1] & 0xFF, c)); v += 2; break; case ClassWriter.LDCW_INSN: cv.visitLdcInsn(readConst(readUnsignedShort(v + 1), c)); v += 3; break; case ClassWriter.FIELDORMETH_INSN: case ClassWriter.ITFMETH_INSN: int cpIndex = items[readUnsignedShort(v + 1)]; String iowner = readClass(cpIndex, c); cpIndex = items[readUnsignedShort(cpIndex + 2)]; String iname = readUTF8(cpIndex, c); String idesc = readUTF8(cpIndex + 2, c); if (opcode < Constants.INVOKEVIRTUAL) { cv.visitFieldInsn(opcode, iowner, iname, idesc); } else { cv.visitMethodInsn(opcode, iowner, iname, idesc); } if (opcode == Constants.INVOKEINTERFACE) { v += 5; } else { v += 3; } break; case ClassWriter.TYPE_INSN: cv.visitTypeInsn(opcode, readClass(v + 1, c)); v += 3; break; case ClassWriter.IINC_INSN: cv.visitIincInsn(b[v + 1] & 0xFF, b[v + 2]); v += 3; break; // case MANA_INSN: default: cv.visitMultiANewArrayInsn(readClass(v + 1, c), b[v + 3] & 0xFF); v += 4; break; } } l = labels[codeEnd - codeStart]; if (l != null) { cv.visitLabel(l); } // visits the try catch entries j = readUnsignedShort(v); v += 2; for ( ; j > 0; --j) { Label start = labels[readUnsignedShort(v)]; Label end = labels[readUnsignedShort(v + 2)]; Label handler = labels[readUnsignedShort(v + 4)]; int type = readUnsignedShort(v + 6); if (type == 0) { cv.visitTryCatchBlock(start, end, handler, null); } else { cv.visitTryCatchBlock(start, end, handler, readUTF8(items[type], c)); } v += 8; } if (!skipDebug) { // visits the local variable and line number tables j = readUnsignedShort(v); v += 2; for ( ; j > 0; --j) { String attrName = readUTF8(v, c); if (attrName.equals("LocalVariableTable")) { k = readUnsignedShort(v + 6); w = v + 8; for ( ; k > 0; --k) { label = readUnsignedShort(w); Label start = labels[label]; label += readUnsignedShort(w + 2); Label end = labels[label]; cv.visitLocalVariable( readUTF8(w + 4, c), readUTF8(w + 6, c), start, end, readUnsignedShort(w + 8)); w += 10; } } else if (attrName.equals("LineNumberTable")) { k = readUnsignedShort(v + 6); w = v + 8; for ( ; k > 0; --k) { cv.visitLineNumber( readUnsignedShort(w + 2), labels[readUnsignedShort(w)]); w += 4; } } v += 6 + readInt(v + 2); } } // visits the code attributes while (cattrs != null) { cv.visitAttribute(cattrs); cattrs = cattrs.next; } // visits the max stack and max locals values cv.visitMaxs(maxStack, maxLocals); } } // visits the class attributes while (clattrs != null) { classVisitor.visitAttribute(clattrs); clattrs = clattrs.next; } // visits the end of the class classVisitor.visitEnd(); } // -------------------------------------------------------------------------- // Utility methods: low level parsing // -------------------------------------------------------------------------- /** * Reads an unsigned short value in {@link #b b}. * * @param index the start index of the value to be read in {@link #b b}. * @return the read value. */ protected int readUnsignedShort (final int index) { byte[] b = this.b; return ((b[index] & 0xFF) << 8) | (b[index + 1] & 0xFF); } /** * Reads a signed short value in {@link #b b}. * * @param index the start index of the value to be read in {@link #b b}. * @return the read value. */ protected short readShort (final int index) { byte[] b = this.b; return (short)(((b[index] & 0xFF) << 8) | (b[index + 1] & 0xFF)); } /** * Reads a signed int value in {@link #b b}. * * @param index the start index of the value to be read in {@link #b b}. * @return the read value. */ protected int readInt (final int index) { byte[] b = this.b; return ((b[index] & 0xFF) << 24) | ((b[index + 1] & 0xFF) << 16) | ((b[index + 2] & 0xFF) << 8) | (b[index + 3] & 0xFF); } /** * Reads a signed long value in {@link #b b}. * * @param index the start index of the value to be read in {@link #b b}. * @return the read value. */ protected long readLong (final int index) { long l1 = readInt(index); long l0 = readInt(index + 4) & 0xFFFFFFFFL; return (l1 << 32) | l0; } /** * Reads an UTF8 constant pool item in {@link #b b}. * * @param index the start index of an unsigned short value in {@link #b b}, * whose value is the index of an UTF8 constant pool item. * @param buf buffer to be used to read the item. This buffer must be * sufficiently large. It is not automatically resized. * @return the String corresponding to the specified UTF8 item. */ protected String readUTF8 (int index, final char[] buf) { // consults cache int item = readUnsignedShort(index); String s = strings[item]; if (s != null) { return s; } // computes the start index of the CONSTANT_Utf8 item in b index = items[item]; // reads the length of the string (in bytes, not characters) int utfLen = readUnsignedShort(index); index += 2; // parses the string bytes int endIndex = index + utfLen; byte[] b = this.b; int strLen = 0; int c, d, e; while (index < endIndex) { c = b[index++] & 0xFF; switch (c >> 4) { case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 7: // 0xxxxxxx buf[strLen++] = (char)c; break; case 12: case 13: // 110x xxxx 10xx xxxx d = b[index++]; buf[strLen++] = (char)(((c & 0x1F) << 6) | (d & 0x3F)); break; default: // 1110 xxxx 10xx xxxx 10xx xxxx d = b[index++]; e = b[index++]; buf[strLen++] = (char)(((c & 0x0F) << 12) | ((d & 0x3F) << 6) | (e & 0x3F)); break; } } s = new String(buf, 0, strLen); strings[item] = s; return s; } /** * Reads a class constant pool item in {@link #b b}. * * @param index the start index of an unsigned short value in {@link #b b}, * whose value is the index of a class constant pool item. * @param buf buffer to be used to read the item. This buffer must be * sufficiently large. It is not automatically resized. * @return the String corresponding to the specified class item. */ protected String readClass (final int index, final char[] buf) { // computes the start index of the CONSTANT_Class item in b // and reads the CONSTANT_Utf8 item designated by // the first two bytes of this CONSTANT_Class item return readUTF8(items[readUnsignedShort(index)], buf); } /** * Reads a numeric or string constant pool item in {@link #b b}. * * @param item the index of a constant pool item. * @param buf buffer to be used to read the item. This buffer must be * sufficiently large. It is not automatically resized. * @return the {@link java.lang.Integer Integer}, {@link java.lang.Float * Float}, {@link java.lang.Long Long}, {@link java.lang.Double Double} * or {@link String String} corresponding to the given constant pool * item. */ protected Object readConst (final int item, final char[] buf) { int index = items[item]; switch (b[index - 1]) { case ClassWriter.INT: return new Integer(readInt(index)); case ClassWriter.FLOAT: return new Float(Float.intBitsToFloat(readInt(index))); case ClassWriter.LONG: return new Long(readLong(index)); case ClassWriter.DOUBLE: return new Double(Double.longBitsToDouble(readLong(index))); //case ClassWriter.STR: default: return readUTF8(index, buf); } } /** * Reads an attribute in {@link #b b}. The default implementation of this * method returns instances of the {@link Attribute} class for all attributes. * * @param type the type of the attribute. * @param off the first byte of the attribute's content in {@link #b b}. The * 6 attribute header bytes, containing the type and the length of the * attribute, are not taken into account here (they have already been * read). * @param len the length of the attribute's content. * @param buf buffer to be used to call {@link #readUTF8 readUTF8}, {@link * #readClass readClass} or {@link #readConst readConst}. * @return the attribute that has been read. */ protected Attribute readAttribute ( final String type, final int off, final int len, final char[] buf) { return new Attribute(type, b, off, len); } } --- NEW FILE: ClassVisitor.java --- /*** * ASM: a very small and fast Java bytecode manipulation framework * Copyright (c) 2000,2002,2003 INRIA, France Telecom * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the copyright holders nor the names of its * contributors may be used to endorse or promote products derived from * this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF * THE POSSIBILITY OF SUCH DAMAGE. * * Contact: Eri...@rd... * * Author: Eric Bruneton */ package org.logicalcobwebs.asm; /** * A visitor to visit a Java class. The methods of this interface must be called * in the following order: <tt>visit</tt> (<tt>visitField</tt> | * <tt>visitMethod</tt> | <tt>visitInnerClass</tt> | <tt>visitAttribute</tt>)* * <tt>visitEnd</tt>. */ public interface ClassVisitor { /** * Visits the header of the class. * * @param access the class's access flags (see {@link Constants}). This * parameter also indicates if the class is deprecated. * @param name the internal name of the class (see {@link Type#getInternalName * getInternalName}). * @param superName the internal of name of the super class (see {@link * Type#getInternalName getInternalName}). For interfaces, the super * class is {@link Object}. May be <tt>null</tt>, but only for the {@link * Object java.lang.Object} class. * @param interfaces the internal names of the class's interfaces (see {@link * Type#getInternalName getInternalName}). May be <tt>null</tt>. * @param sourceFile the name of the source file from which this class was * compiled. May be <tt>null</tt>. */ void visit ( int access, String name, String superName, String[] interfaces, String sourceFile); /** * Visits information about an inner class. This inner class is not * necessarily a member of the class being visited. * * @param name the internal name of an inner class (see {@link * Type#getInternalName getInternalName}). * @param outerName the internal name of the class to which the inner class * belongs (see {@link Type#getInternalName getInternalName}). May be * <tt>null</tt>. * @param innerName the (simple) name of the inner class inside its enclosing * class. May be <tt>null</tt> for anonymous inner classes. * @param access the access flags of the inner class as originally declared * in the enclosing class. */ void visitInnerClass ( String name, String outerName, String innerName, int access); /** * Visits a field of the class. * * @param access the field's access flags (see {@link Constants}). This * parameter also indicates if the field is synthetic and/or deprecated. * @param name the field's name. * @param desc the field's descriptor (see {@link Type Type}). * @param value the field's initial value. This parameter, which may be * <tt>null</tt> if the field does not have an initial value, must be an * {@link java.lang.Integer Integer}, a {@link java.lang.Float Float}, a * {@link java.lang.Long Long}, a {@link java.lang.Double Double} or a * {@link String String}. <i>This parameter is only used for static * fields</i>. Its value is ignored for non static fields, which must be * initialized through bytecode instructions in constructors or methods. * @param attrs the non standard method attributes, linked together by their * <tt>next</tt> field. May be <tt>null</tt>. */ void visitField ( int access, String name, String desc, Object value, Attribute attrs); /** * Visits a method of the class. This method <i>must</i> return a new * {@link CodeVisitor CodeVisitor} instance (or <tt>null</tt>) each time it * is called, i.e., it should not return a previously returned visitor. * * @param access the method's access flags (see {@link Constants}). This * parameter also indicates if the method is synthetic and/or deprecated. * @param name the method's name. * @param desc the method's descriptor (see {@link Type Type}). * @param exceptions the internal names of the method's exception * classes (see {@link Type#getInternalName getInternalName}). May be * <tt>null</tt>. * @param attrs the non standard method attributes, linked together by their * <tt>next</tt> field. May be <tt>null</tt>. * @return an object to visit the byte code of the method, or <tt>null</tt> if * this class visitor is not interested in visiting the code of this * method. */ CodeVisitor visitMethod ( int access, String name, String desc, String[] exceptions, Attribute attrs); /** * Visits a non standard attribute of the class. This method must visit only * the first attribute in the given attribute list. * * @param attr a non standard class attribute. Must not be <tt>null</tt>. */ void visitAttribute (Attribute attr); /** * Visits the end of the class. This method, which is the last one to be * called, is used to inform the visitor that all the fields and methods of * the class have been visited. */ void visitEnd (); } --- NEW FILE: ClassWriter.java --- /*** * ASM: a very small and fast Java bytecode manipulation framework * Copyright (c) 2000,2002,2003 INRIA, France Telecom * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the copyright holders nor the names of its * contributors may be used to endorse or promote products derived from * this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE [...985 lines suppressed...] /** * Converts the content of the given attribute to a byte array. * * @param attr the attribute that must be converted to a byte array. * @return a byte array containing the content of the given attribute (and * this content only, i.e. the 6 attribute header bytes must not be * included in the returned array). */ protected byte[] writeAttribute (final Attribute attr) { if (attr.b == null) { throw new IllegalArgumentException( "Unsupported attribute type: " + attr.type); } else { byte[] b = new byte[attr.len]; System.arraycopy(attr.b, attr.off, b, 0, attr.len); return b; } } } --- NEW FILE: CodeAdapter.java --- /*** * ASM: a very small and fast Java bytecode manipulation framework * Copyright (c) 2000,2002,2003 INRIA, France Telecom * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the copyright holders nor the names of its * contributors may be used to endorse or promote products derived from * this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF * THE POSSIBILITY OF SUCH DAMAGE. * * Contact: Eri...@rd... * * Author: Eric Bruneton */ package org.logicalcobwebs.asm; /** * An empty {@link CodeVisitor CodeVisitor} that delegates to another {@link * CodeVisitor CodeVisitor}. This class can be used as a super class to quickly * implement usefull code adapter classes, just by overriding the necessary * methods. */ public class CodeAdapter implements CodeVisitor { /** * The {@link CodeVisitor CodeVisitor} to which this adapter delegates calls. */ protected CodeVisitor cv; /** * Constructs a new {@link CodeAdapter CodeAdapter} object. * * @param cv the code visitor to which this adapter must delegate calls. */ public CodeAdapter (final CodeVisitor cv) { this.cv = cv; } public void visitInsn (final int opcode) { cv.visitInsn(opcode); } public void visitIntInsn (final int opcode, final int operand) { cv.visitIntInsn(opcode, operand); } public void visitVarInsn (final int opcode, final int var) { cv.visitVarInsn(opcode, var); } public void visitTypeInsn (final int opcode, final String desc) { cv.visitTypeInsn(opcode, desc); } public void visitFieldInsn ( final int opcode, final String owner, final String name, final String desc) { cv.visitFieldInsn(opcode, owner, name, desc); } public void visitMethodInsn ( final int opcode, final String owner, final String name, final String desc) { cv.visitMethodInsn(opcode, owner, name, desc); } public void visitJumpInsn (final int opcode, final Label label) { cv.visitJumpInsn(opcode, label); } public void visitLabel (final Label label) { cv.visitLabel(label); } public void visitLdcInsn (final Object cst) { cv.visitLdcInsn(cst); } public void visitIincInsn (final int var, final int increment) { cv.visitIincInsn(var, increment); } public void visitTableSwitchInsn ( final int min, final int max, final Label dflt, final Label labels[]) { cv.visitTableSwitchInsn(min, max, dflt, labels); } public void visitLookupSwitchInsn ( final Label dflt, final int keys[], final Label labels[]) { cv.visitLookupSwitchInsn(dflt, keys, labels); } public void visitMultiANewArrayInsn (final String desc, final int dims) { cv.visitMultiANewArrayInsn(desc, dims); } public void visitTryCatchBlock ( final Label start, final Label end, final Label handler, final String type) { cv.visitTryCatchBlock(start, end, handler, type); } public void visitMaxs (final int maxStack, final int maxLocals) { cv.visitMaxs(maxStack, maxLocals); } public void visitLocalVariable ( final String name, final String desc, final Label start, final Label end, final int index) { cv.visitLocalVariable(name, desc, start, end, index); } public void visitLineNumber (final int line, final Label start) { cv.visitLineNumber(line, start); } public void visitAttribute (final Attribute attr) { cv.visitAttribute(attr); } } --- NEW FILE: CodeVisitor.java --- /*** * ASM: a very small and fast Java bytecode manipulation framework * Copyri... [truncated message content] |