You are viewing a plain text version of this content. The canonical link for it is here.
Posted to bcel-dev@jakarta.apache.org by tc...@apache.org on 2006/03/15 12:33:43 UTC
svn commit: r386056 [25/28] - in /jakarta/bcel/trunk: examples/
examples/Mini/ src/java/org/apache/bcel/
src/java/org/apache/bcel/classfile/ src/java/org/apache/bcel/generic/
src/java/org/apache/bcel/util/ src/java/org/apache/bcel/verifier/
src/java/or...
Modified: jakarta/bcel/trunk/src/java/org/apache/bcel/util/ClassPath.java
URL: http://svn.apache.org/viewcvs/jakarta/bcel/trunk/src/java/org/apache/bcel/util/ClassPath.java?rev=386056&r1=386055&r2=386056&view=diff
==============================================================================
--- jakarta/bcel/trunk/src/java/org/apache/bcel/util/ClassPath.java (original)
+++ jakarta/bcel/trunk/src/java/org/apache/bcel/util/ClassPath.java Wed Mar 15 03:31:56 2006
@@ -13,10 +13,9 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*
- */
+ */
package org.apache.bcel.util;
-
import java.io.DataInputStream;
import java.io.File;
import java.io.FileInputStream;
@@ -40,312 +39,358 @@
* @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
*/
public class ClassPath implements Serializable {
- public static final ClassPath SYSTEM_CLASS_PATH = new ClassPath();
- private PathEntry[] paths;
- private String class_path;
+ public static final ClassPath SYSTEM_CLASS_PATH = new ClassPath();
+ private PathEntry[] paths;
+ private String class_path;
+
+
+ /**
+ * Search for classes in given path.
+ */
+ public ClassPath(String class_path) {
+ this.class_path = class_path;
+ List vec = new ArrayList();
+ for (StringTokenizer tok = new StringTokenizer(class_path, System
+ .getProperty("path.separator")); tok.hasMoreTokens();) {
+ String path = tok.nextToken();
+ if (!path.equals("")) {
+ File file = new File(path);
+ try {
+ if (file.exists()) {
+ if (file.isDirectory()) {
+ vec.add(new Dir(path));
+ } else {
+ vec.add(new Zip(new ZipFile(file)));
+ }
+ }
+ } catch (IOException e) {
+ System.err.println("CLASSPATH component " + file + ": " + e);
+ }
+ }
+ }
+ paths = new PathEntry[vec.size()];
+ vec.toArray(paths);
+ }
+
+
+ /**
+ * Search for classes in CLASSPATH.
+ * @deprecated Use SYSTEM_CLASS_PATH constant
+ */
+ public ClassPath() {
+ this(getClassPath());
+ }
+
+
+ /** @return used class path string
+ */
+ public String toString() {
+ return class_path;
+ }
+
+
+ public int hashCode() {
+ return class_path.hashCode();
+ }
+
+
+ public boolean equals( Object o ) {
+ if (o instanceof ClassPath) {
+ return class_path.equals(((ClassPath) o).class_path);
+ }
+ return false;
+ }
+
+
+ private static final void getPathComponents( String path, List list ) {
+ if (path != null) {
+ StringTokenizer tok = new StringTokenizer(path, File.pathSeparator);
+ while (tok.hasMoreTokens()) {
+ String name = tok.nextToken();
+ File file = new File(name);
+ if (file.exists()) {
+ list.add(name);
+ }
+ }
+ }
+ }
+
+
+ /** Checks for class path components in the following properties:
+ * "java.class.path", "sun.boot.class.path", "java.ext.dirs"
+ *
+ * @return class path as used by default by BCEL
+ */
+ public static final String getClassPath() {
+ String class_path = System.getProperty("java.class.path");
+ String boot_path = System.getProperty("sun.boot.class.path");
+ String ext_path = System.getProperty("java.ext.dirs");
+ List list = new ArrayList();
+ getPathComponents(class_path, list);
+ getPathComponents(boot_path, list);
+ List dirs = new ArrayList();
+ getPathComponents(ext_path, dirs);
+ for (Iterator e = dirs.iterator(); e.hasNext();) {
+ File ext_dir = new File((String) e.next());
+ String[] extensions = ext_dir.list(new FilenameFilter() {
+
+ public boolean accept( File dir, String name ) {
+ name = name.toLowerCase(Locale.ENGLISH);
+ return name.endsWith(".zip") || name.endsWith(".jar");
+ }
+ });
+ if (extensions != null) {
+ for (int i = 0; i < extensions.length; i++) {
+ list.add(ext_dir.getPath() + File.separatorChar + extensions[i]);
+ }
+ }
+ }
+ StringBuffer buf = new StringBuffer();
+ for (Iterator e = list.iterator(); e.hasNext();) {
+ buf.append((String) e.next());
+ if (e.hasNext()) {
+ buf.append(File.pathSeparatorChar);
+ }
+ }
+ return buf.toString().intern();
+ }
- /**
- * Search for classes in given path.
- */
- public ClassPath(String class_path) {
- this.class_path = class_path;
-
- List vec = new ArrayList();
-
- for(StringTokenizer tok=new StringTokenizer(class_path,
- System.getProperty("path.separator"));
- tok.hasMoreTokens();)
- {
- String path = tok.nextToken();
-
- if(!path.equals("")) {
- File file = new File(path);
-
- try {
- if(file.exists()) {
- if(file.isDirectory())
- vec.add(new Dir(path));
- else
- vec.add(new Zip(new ZipFile(file)));
- }
- } catch(IOException e) {
- System.err.println("CLASSPATH component " + file + ": " + e);
- }
- }
- }
-
- paths = new PathEntry[vec.size()];
- vec.toArray(paths);
- }
-
- /**
- * Search for classes in CLASSPATH.
- * @deprecated Use SYSTEM_CLASS_PATH constant
- */
- public ClassPath() {
- this(getClassPath());
- }
-
- /** @return used class path string
- */
- public String toString() {
- return class_path;
- }
-
- public int hashCode() {
- return class_path.hashCode();
- }
-
- public boolean equals(Object o) {
- if(o instanceof ClassPath) {
- return class_path.equals(((ClassPath)o).class_path);
- }
-
- return false;
- }
-
- private static final void getPathComponents(String path, List list) {
- if(path != null) {
- StringTokenizer tok = new StringTokenizer(path, File.pathSeparator);
-
- while(tok.hasMoreTokens()) {
- String name = tok.nextToken();
- File file = new File(name);
-
- if(file.exists())
- list.add(name);
- }
- }
- }
-
- /** Checks for class path components in the following properties:
- * "java.class.path", "sun.boot.class.path", "java.ext.dirs"
- *
- * @return class path as used by default by BCEL
- */
- public static final String getClassPath() {
- String class_path = System.getProperty("java.class.path");
- String boot_path = System.getProperty("sun.boot.class.path");
- String ext_path = System.getProperty("java.ext.dirs");
-
- List list = new ArrayList();
-
- getPathComponents(class_path, list);
- getPathComponents(boot_path, list);
-
- List dirs = new ArrayList();
- getPathComponents(ext_path, dirs);
-
- for(Iterator e = dirs.iterator(); e.hasNext(); ) {
- File ext_dir = new File((String)e.next());
- String[] extensions = ext_dir.list(new FilenameFilter() {
- public boolean accept(File dir, String name) {
- name = name.toLowerCase(Locale.ENGLISH);
- return name.endsWith(".zip") || name.endsWith(".jar");
- }
- });
-
- if(extensions != null)
- for(int i=0; i < extensions.length; i++)
- list.add(ext_dir.getPath() + File.separatorChar + extensions[i]);
- }
-
- StringBuffer buf = new StringBuffer();
-
- for(Iterator e = list.iterator(); e.hasNext(); ) {
- buf.append((String)e.next());
-
- if(e.hasNext())
- buf.append(File.pathSeparatorChar);
- }
-
- return buf.toString().intern();
- }
-
- /**
- * @param name fully qualified class name, e.g. java.lang.String
- * @return input stream for class
- */
- public InputStream getInputStream(String name) throws IOException {
- return getInputStream(name.replace('.','/'), ".class");
- }
-
- /**
- * Return stream for class or resource on CLASSPATH.
- *
- * @param name fully qualified file name, e.g. java/lang/String
- * @param suffix file name ends with suff, e.g. .java
- * @return input stream for file on class path
- */
- public InputStream getInputStream(String name, String suffix) throws IOException {
- InputStream is = null;
-
- try {
- is = getClass().getClassLoader().getResourceAsStream(name + suffix);
- } catch(Exception e) { }
-
- if(is != null)
- return is;
-
- return getClassFile(name, suffix).getInputStream();
- }
-
- /**
- * @param name fully qualified file name, e.g. java/lang/String
- * @param suffix file name ends with suff, e.g. .java
- * @return class file for the java class
- */
- public ClassFile getClassFile(String name, String suffix) throws IOException {
- for(int i=0; i < paths.length; i++) {
- ClassFile cf;
-
- if((cf = paths[i].getClassFile(name, suffix)) != null)
- return cf;
- }
-
- throw new IOException("Couldn't find: " + name + suffix);
- }
-
- /**
- * @param name fully qualified class name, e.g. java.lang.String
- * @return input stream for class
- */
- public ClassFile getClassFile(String name) throws IOException {
- return getClassFile(name, ".class");
- }
-
- /**
- * @param name fully qualified file name, e.g. java/lang/String
- * @param suffix file name ends with suffix, e.g. .java
- * @return byte array for file on class path
- */
- public byte[] getBytes(String name, String suffix) throws IOException {
- DataInputStream dis = null;
- try {
- InputStream is = getInputStream(name, suffix);
-
- if(is == null)
+
+ /**
+ * @param name fully qualified class name, e.g. java.lang.String
+ * @return input stream for class
+ */
+ public InputStream getInputStream( String name ) throws IOException {
+ return getInputStream(name.replace('.', '/'), ".class");
+ }
+
+
+ /**
+ * Return stream for class or resource on CLASSPATH.
+ *
+ * @param name fully qualified file name, e.g. java/lang/String
+ * @param suffix file name ends with suff, e.g. .java
+ * @return input stream for file on class path
+ */
+ public InputStream getInputStream( String name, String suffix ) throws IOException {
+ InputStream is = null;
+ try {
+ is = getClass().getClassLoader().getResourceAsStream(name + suffix);
+ } catch (Exception e) {
+ }
+ if (is != null) {
+ return is;
+ }
+ return getClassFile(name, suffix).getInputStream();
+ }
+
+
+ /**
+ * @param name fully qualified file name, e.g. java/lang/String
+ * @param suffix file name ends with suff, e.g. .java
+ * @return class file for the java class
+ */
+ public ClassFile getClassFile( String name, String suffix ) throws IOException {
+ for (int i = 0; i < paths.length; i++) {
+ ClassFile cf;
+ if ((cf = paths[i].getClassFile(name, suffix)) != null) {
+ return cf;
+ }
+ }
throw new IOException("Couldn't find: " + name + suffix);
+ }
+
+
+ /**
+ * @param name fully qualified class name, e.g. java.lang.String
+ * @return input stream for class
+ */
+ public ClassFile getClassFile( String name ) throws IOException {
+ return getClassFile(name, ".class");
+ }
- dis = new DataInputStream(is);
- byte[] bytes = new byte[is.available()];
- dis.readFully(bytes);
-
- return bytes;
- } finally {
- if (dis != null)
- dis.close();
- }
- }
-
- /**
- * @return byte array for class
- */
- public byte[] getBytes(String name) throws IOException {
- return getBytes(name, ".class");
- }
-
- /**
- * @param name name of file to search for, e.g. java/lang/String.java
- * @return full (canonical) path for file
- */
- public String getPath(String name) throws IOException {
- int index = name.lastIndexOf('.');
- String suffix = "";
-
- if(index > 0) {
- suffix = name.substring(index);
- name = name.substring(0, index);
- }
-
- return getPath(name, suffix);
- }
-
- /**
- * @param name name of file to search for, e.g. java/lang/String
- * @param suffix file name suffix, e.g. .java
- * @return full (canonical) path for file, if it exists
- */
- public String getPath(String name, String suffix) throws IOException {
- return getClassFile(name, suffix).getPath();
- }
-
- private static abstract class PathEntry implements Serializable {
- abstract ClassFile getClassFile(String name, String suffix) throws IOException;
- }
-
- /** Contains information about file/ZIP entry of the Java class.
- */
- public interface ClassFile {
- /** @return input stream for class file.
- */
- public abstract InputStream getInputStream() throws IOException;
-
- /** @return canonical path to class file.
- */
- public abstract String getPath();
-
- /** @return base path of found class, i.e. class is contained relative
- * to that path, which may either denote a directory, or zip file
- */
- public abstract String getBase();
-
- /** @return modification time of class file.
- */
- public abstract long getTime();
-
- /** @return size of class file.
- */
- public abstract long getSize();
- }
-
- private static class Dir extends PathEntry {
- private String dir;
-
- Dir(String d) { dir = d; }
-
- ClassFile getClassFile(String name, String suffix) throws IOException {
- final File file = new File(dir + File.separatorChar +
- name.replace('.', File.separatorChar) + suffix);
-
- return file.exists()? new ClassFile() {
- public InputStream getInputStream() throws IOException { return new FileInputStream(file); }
-
- public String getPath() { try {
- return file.getCanonicalPath();
- } catch(IOException e) { return null; }
-
- }
- public long getTime() { return file.lastModified(); }
- public long getSize() { return file.length(); }
- public String getBase() { return dir; }
-
- } : null;
- }
-
- public String toString() { return dir; }
- }
-
- private static class Zip extends PathEntry {
- private ZipFile zip;
-
- Zip(ZipFile z) { zip = z; }
-
- ClassFile getClassFile(String name, String suffix) throws IOException {
- final ZipEntry entry = zip.getEntry(name.replace('.', '/') + suffix);
-
- return (entry != null)? new ClassFile() {
- public InputStream getInputStream() throws IOException { return zip.getInputStream(entry); }
- public String getPath() { return entry.toString(); }
- public long getTime() { return entry.getTime(); }
- public long getSize() { return entry.getSize(); }
- public String getBase() {
- return zip.getName();
- }
- } : null;
+
+ /**
+ * @param name fully qualified file name, e.g. java/lang/String
+ * @param suffix file name ends with suffix, e.g. .java
+ * @return byte array for file on class path
+ */
+ public byte[] getBytes( String name, String suffix ) throws IOException {
+ DataInputStream dis = null;
+ try {
+ InputStream is = getInputStream(name, suffix);
+ if (is == null) {
+ throw new IOException("Couldn't find: " + name + suffix);
+ }
+ dis = new DataInputStream(is);
+ byte[] bytes = new byte[is.available()];
+ dis.readFully(bytes);
+ return bytes;
+ } finally {
+ if (dis != null) {
+ dis.close();
+ }
+ }
+ }
+
+
+ /**
+ * @return byte array for class
+ */
+ public byte[] getBytes( String name ) throws IOException {
+ return getBytes(name, ".class");
+ }
+
+
+ /**
+ * @param name name of file to search for, e.g. java/lang/String.java
+ * @return full (canonical) path for file
+ */
+ public String getPath( String name ) throws IOException {
+ int index = name.lastIndexOf('.');
+ String suffix = "";
+ if (index > 0) {
+ suffix = name.substring(index);
+ name = name.substring(0, index);
+ }
+ return getPath(name, suffix);
}
- }
-}
+ /**
+ * @param name name of file to search for, e.g. java/lang/String
+ * @param suffix file name suffix, e.g. .java
+ * @return full (canonical) path for file, if it exists
+ */
+ public String getPath( String name, String suffix ) throws IOException {
+ return getClassFile(name, suffix).getPath();
+ }
+
+ private static abstract class PathEntry implements Serializable {
+
+ abstract ClassFile getClassFile( String name, String suffix ) throws IOException;
+ }
+
+ /** Contains information about file/ZIP entry of the Java class.
+ */
+ public interface ClassFile {
+
+ /** @return input stream for class file.
+ */
+ public abstract InputStream getInputStream() throws IOException;
+
+
+ /** @return canonical path to class file.
+ */
+ public abstract String getPath();
+
+
+ /** @return base path of found class, i.e. class is contained relative
+ * to that path, which may either denote a directory, or zip file
+ */
+ public abstract String getBase();
+
+
+ /** @return modification time of class file.
+ */
+ public abstract long getTime();
+
+
+ /** @return size of class file.
+ */
+ public abstract long getSize();
+ }
+
+ private static class Dir extends PathEntry {
+
+ private String dir;
+
+
+ Dir(String d) {
+ dir = d;
+ }
+
+
+ ClassFile getClassFile( String name, String suffix ) throws IOException {
+ final File file = new File(dir + File.separatorChar
+ + name.replace('.', File.separatorChar) + suffix);
+ return file.exists() ? new ClassFile() {
+
+ public InputStream getInputStream() throws IOException {
+ return new FileInputStream(file);
+ }
+
+
+ public String getPath() {
+ try {
+ return file.getCanonicalPath();
+ } catch (IOException e) {
+ return null;
+ }
+ }
+
+
+ public long getTime() {
+ return file.lastModified();
+ }
+
+
+ public long getSize() {
+ return file.length();
+ }
+
+
+ public String getBase() {
+ return dir;
+ }
+ } : null;
+ }
+
+
+ public String toString() {
+ return dir;
+ }
+ }
+
+ private static class Zip extends PathEntry {
+
+ private ZipFile zip;
+
+
+ Zip(ZipFile z) {
+ zip = z;
+ }
+
+
+ ClassFile getClassFile( String name, String suffix ) throws IOException {
+ final ZipEntry entry = zip.getEntry(name.replace('.', '/') + suffix);
+ return (entry != null) ? new ClassFile() {
+
+ public InputStream getInputStream() throws IOException {
+ return zip.getInputStream(entry);
+ }
+
+
+ public String getPath() {
+ return entry.toString();
+ }
+
+
+ public long getTime() {
+ return entry.getTime();
+ }
+
+
+ public long getSize() {
+ return entry.getSize();
+ }
+
+
+ public String getBase() {
+ return zip.getName();
+ }
+ } : null;
+ }
+ }
+}
Modified: jakarta/bcel/trunk/src/java/org/apache/bcel/util/ClassQueue.java
URL: http://svn.apache.org/viewcvs/jakarta/bcel/trunk/src/java/org/apache/bcel/util/ClassQueue.java?rev=386056&r1=386055&r2=386056&view=diff
==============================================================================
--- jakarta/bcel/trunk/src/java/org/apache/bcel/util/ClassQueue.java (original)
+++ jakarta/bcel/trunk/src/java/org/apache/bcel/util/ClassQueue.java Wed Mar 15 03:31:56 2006
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*
- */
+ */
package org.apache.bcel.util;
import java.util.LinkedList;
@@ -25,19 +25,28 @@
*
* @version $Id$
* @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
-*/
+ */
public class ClassQueue implements java.io.Serializable {
- protected LinkedList vec = new LinkedList();
- public void enqueue(JavaClass clazz) { vec.addLast(clazz); }
+ protected LinkedList vec = new LinkedList();
- public JavaClass dequeue() {
- return (JavaClass)vec.removeFirst();
- }
- public boolean empty() { return vec.isEmpty(); }
+ public void enqueue( JavaClass clazz ) {
+ vec.addLast(clazz);
+ }
- public String toString() {
- return vec.toString();
- }
-}
+
+ public JavaClass dequeue() {
+ return (JavaClass) vec.removeFirst();
+ }
+
+
+ public boolean empty() {
+ return vec.isEmpty();
+ }
+
+
+ public String toString() {
+ return vec.toString();
+ }
+}
Modified: jakarta/bcel/trunk/src/java/org/apache/bcel/util/ClassSet.java
URL: http://svn.apache.org/viewcvs/jakarta/bcel/trunk/src/java/org/apache/bcel/util/ClassSet.java?rev=386056&r1=386055&r2=386056&view=diff
==============================================================================
--- jakarta/bcel/trunk/src/java/org/apache/bcel/util/ClassSet.java (original)
+++ jakarta/bcel/trunk/src/java/org/apache/bcel/util/ClassSet.java Wed Mar 15 03:31:56 2006
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*
- */
+ */
package org.apache.bcel.util;
import java.util.Collection;
@@ -29,32 +29,41 @@
* @version $Id$
* @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
* @see ClassStack
-*/
+ */
public class ClassSet implements java.io.Serializable {
- private Map _map = new HashMap();
- public boolean add(JavaClass clazz) {
- boolean result = false;
+ private Map _map = new HashMap();
- if(!_map.containsKey(clazz.getClassName())) {
- result = true;
- _map.put(clazz.getClassName(), clazz);
+
+ public boolean add( JavaClass clazz ) {
+ boolean result = false;
+ if (!_map.containsKey(clazz.getClassName())) {
+ result = true;
+ _map.put(clazz.getClassName(), clazz);
+ }
+ return result;
+ }
+
+
+ public void remove( JavaClass clazz ) {
+ _map.remove(clazz.getClassName());
+ }
+
+
+ public boolean empty() {
+ return _map.isEmpty();
}
- return result;
- }
- public void remove(JavaClass clazz) { _map.remove(clazz.getClassName()); }
- public boolean empty() { return _map.isEmpty(); }
+ public JavaClass[] toArray() {
+ Collection values = _map.values();
+ JavaClass[] classes = new JavaClass[values.size()];
+ values.toArray(classes);
+ return classes;
+ }
- public JavaClass[] toArray() {
- Collection values = _map.values();
- JavaClass[] classes = new JavaClass[values.size()];
- values.toArray(classes);
- return classes;
- }
-
- public String[] getClassNames() {
- return (String[])_map.keySet().toArray(new String[_map.keySet().size()]);
- }
-}
+
+ public String[] getClassNames() {
+ return (String[]) _map.keySet().toArray(new String[_map.keySet().size()]);
+ }
+}
Modified: jakarta/bcel/trunk/src/java/org/apache/bcel/util/ClassStack.java
URL: http://svn.apache.org/viewcvs/jakarta/bcel/trunk/src/java/org/apache/bcel/util/ClassStack.java?rev=386056&r1=386055&r2=386056&view=diff
==============================================================================
--- jakarta/bcel/trunk/src/java/org/apache/bcel/util/ClassStack.java (original)
+++ jakarta/bcel/trunk/src/java/org/apache/bcel/util/ClassStack.java Wed Mar 15 03:31:56 2006
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*
- */
+ */
package org.apache.bcel.util;
import java.util.Stack;
@@ -25,12 +25,28 @@
* @version $Id$
* @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
* @see Stack
-*/
+ */
public class ClassStack implements java.io.Serializable {
- private Stack stack = new Stack();
- public void push(JavaClass clazz) { stack.push(clazz); }
- public JavaClass pop() { return (JavaClass)stack.pop(); }
- public JavaClass top() { return (JavaClass)stack.peek(); }
- public boolean empty() { return stack.empty(); }
-}
+ private Stack stack = new Stack();
+
+
+ public void push( JavaClass clazz ) {
+ stack.push(clazz);
+ }
+
+
+ public JavaClass pop() {
+ return (JavaClass) stack.pop();
+ }
+
+
+ public JavaClass top() {
+ return (JavaClass) stack.peek();
+ }
+
+
+ public boolean empty() {
+ return stack.empty();
+ }
+}
Modified: jakarta/bcel/trunk/src/java/org/apache/bcel/util/ClassVector.java
URL: http://svn.apache.org/viewcvs/jakarta/bcel/trunk/src/java/org/apache/bcel/util/ClassVector.java?rev=386056&r1=386055&r2=386056&view=diff
==============================================================================
--- jakarta/bcel/trunk/src/java/org/apache/bcel/util/ClassVector.java (original)
+++ jakarta/bcel/trunk/src/java/org/apache/bcel/util/ClassVector.java Wed Mar 15 03:31:56 2006
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*
- */
+ */
package org.apache.bcel.util;
import java.util.ArrayList;
@@ -28,17 +28,30 @@
* @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
*
* @deprecated as of 5.1.1 - 7/17/2005
-*/
+ */
public class ClassVector implements java.io.Serializable {
- protected List vec = new ArrayList();
-
- public void addElement(JavaClass clazz) { vec.add(clazz); }
- public JavaClass elementAt(int index) { return (JavaClass)vec.get(index); }
- public void removeElementAt(int index) { vec.remove(index); }
-
- public JavaClass[] toArray() {
- JavaClass[] classes = new JavaClass[vec.size()];
- vec.toArray(classes);
- return classes;
- }
+
+ protected List vec = new ArrayList();
+
+
+ public void addElement( JavaClass clazz ) {
+ vec.add(clazz);
+ }
+
+
+ public JavaClass elementAt( int index ) {
+ return (JavaClass) vec.get(index);
+ }
+
+
+ public void removeElementAt( int index ) {
+ vec.remove(index);
+ }
+
+
+ public JavaClass[] toArray() {
+ JavaClass[] classes = new JavaClass[vec.size()];
+ vec.toArray(classes);
+ return classes;
+ }
}
Modified: jakarta/bcel/trunk/src/java/org/apache/bcel/util/CodeHTML.java
URL: http://svn.apache.org/viewcvs/jakarta/bcel/trunk/src/java/org/apache/bcel/util/CodeHTML.java?rev=386056&r1=386055&r2=386056&view=diff
==============================================================================
--- jakarta/bcel/trunk/src/java/org/apache/bcel/util/CodeHTML.java (original)
+++ jakarta/bcel/trunk/src/java/org/apache/bcel/util/CodeHTML.java Wed Mar 15 03:31:56 2006
@@ -13,10 +13,9 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*
- */
+ */
package org.apache.bcel.util;
-
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.PrintWriter;
@@ -42,555 +41,524 @@
*
*/
final class CodeHTML implements org.apache.bcel.Constants {
- private String class_name; // name of current class
- private Method[] methods; // Methods to print
- private PrintWriter file; // file to write to
- private BitSet goto_set;
- private ConstantPool constant_pool;
- private ConstantHTML constant_html;
- private static boolean wide=false;
-
- CodeHTML(String dir, String class_name,
- Method[] methods, ConstantPool constant_pool,
- ConstantHTML constant_html) throws IOException
- {
- this.class_name = class_name;
- this.methods = methods;
- this.constant_pool = constant_pool;
- this.constant_html = constant_html;
-
- file = new PrintWriter(new FileOutputStream(dir + class_name + "_code.html"));
- file.println("<HTML><BODY BGCOLOR=\"#C0C0C0\">");
-
- for(int i=0; i < methods.length; i++)
- writeMethod(methods[i], i);
-
- file.println("</BODY></HTML>");
- file.close();
- }
-
- /**
- * Disassemble a stream of byte codes and return the
- * string representation.
- *
- * @param stream data input stream
- * @return String representation of byte code
- */
- private final String codeToHTML(ByteSequence bytes, int method_number)
- throws IOException
- {
- short opcode = (short)bytes.readUnsignedByte();
- StringBuffer buf;
- String name, signature;
- int default_offset=0, low, high;
- int index, class_index, vindex, constant;
- int[] jump_table;
- int no_pad_bytes=0, offset;
-
- buf = new StringBuffer(256);
- buf.append("<TT>").append(OPCODE_NAMES[opcode]).append("</TT></TD><TD>");
-
- /* Special case: Skip (0-3) padding bytes, i.e., the
- * following bytes are 4-byte-aligned
- */
- if((opcode == TABLESWITCH) || (opcode == LOOKUPSWITCH)) {
- int remainder = bytes.getIndex() % 4;
- no_pad_bytes = (remainder == 0)? 0 : 4 - remainder;
-
- for(int i=0; i < no_pad_bytes; i++)
- bytes.readByte();
-
- // Both cases have a field default_offset in common
- default_offset = bytes.readInt();
- }
- switch(opcode) {
- case TABLESWITCH:
- low = bytes.readInt();
- high = bytes.readInt();
-
- offset = bytes.getIndex() - 12 - no_pad_bytes - 1;
- default_offset += offset;
-
- buf.append("<TABLE BORDER=1><TR>");
-
- // Print switch indices in first row (and default)
- jump_table = new int[high - low + 1];
- for(int i=0; i < jump_table.length; i++) {
- jump_table[i] = offset + bytes.readInt();
-
- buf.append("<TH>").append(low + i).append("</TH>");
- }
- buf.append("<TH>default</TH></TR>\n<TR>");
-
- // Print target and default indices in second row
- for(int i=0; i < jump_table.length; i++)
- buf.append("<TD><A HREF=\"#code").append(method_number).append("@")
- .append(jump_table[i]).append("\">").append(jump_table[i]).append("</A></TD>");
- buf.append("<TD><A HREF=\"#code").append(method_number).append("@")
- .append(default_offset).append("\">").append(default_offset).append("</A></TD></TR>\n</TABLE>\n");
-
- break;
-
- /* Lookup switch has variable length arguments.
- */
- case LOOKUPSWITCH:
- int npairs = bytes.readInt();
- offset = bytes.getIndex() - 8 - no_pad_bytes - 1;
- jump_table = new int[npairs];
- default_offset += offset;
-
- buf.append("<TABLE BORDER=1><TR>");
-
- // Print switch indices in first row (and default)
- for(int i=0; i < npairs; i++) {
- int match = bytes.readInt();
-
- jump_table[i] = offset + bytes.readInt();
- buf.append("<TH>").append(match).append("</TH>");
- }
- buf.append("<TH>default</TH></TR>\n<TR>");
-
- // Print target and default indices in second row
- for(int i=0; i < npairs; i++)
- buf.append("<TD><A HREF=\"#code").append(method_number).append("@")
- .append(jump_table[i]).append("\">").append(jump_table[i]).append("</A></TD>");
- buf.append("<TD><A HREF=\"#code").append(method_number).append("@")
- .append(default_offset).append("\">").append(default_offset).append("</A></TD></TR>\n</TABLE>\n");
- break;
-
- /* Two address bytes + offset from start of byte stream form the
- * jump target.
- */
- case GOTO: case IFEQ: case IFGE: case IFGT:
- case IFLE: case IFLT:
- case IFNE: case IFNONNULL: case IFNULL: case IF_ACMPEQ:
- case IF_ACMPNE: case IF_ICMPEQ: case IF_ICMPGE: case IF_ICMPGT:
- case IF_ICMPLE: case IF_ICMPLT: case IF_ICMPNE: case JSR:
-
- index = (int)(bytes.getIndex() + bytes.readShort() - 1);
-
- buf.append("<A HREF=\"#code").append(method_number).append("@").append(index).append("\">")
- .append(index).append("</A>");
- break;
-
- /* Same for 32-bit wide jumps
- */
- case GOTO_W: case JSR_W:
- int windex = bytes.getIndex() + bytes.readInt() - 1;
- buf.append("<A HREF=\"#code").append(method_number).append("@").append(windex).append("\">")
- .append(windex).append("</A>");
- break;
-
- /* Index byte references local variable (register)
- */
- case ALOAD: case ASTORE: case DLOAD: case DSTORE: case FLOAD:
- case FSTORE: case ILOAD: case ISTORE: case LLOAD: case LSTORE:
- case RET:
- if(wide) {
- vindex = bytes.readShort();
- wide=false; // Clear flag
- }
- else
- vindex = bytes.readUnsignedByte();
-
- buf.append("%").append(vindex);
- break;
-
- /*
- * Remember wide byte which is used to form a 16-bit address in the
- * following instruction. Relies on that the method is called again with
- * the following opcode.
- */
- case WIDE:
- wide = true;
- buf.append("(wide)");
- break;
-
- /* Array of basic type.
- */
- case NEWARRAY:
- buf.append("<FONT COLOR=\"#00FF00\">").append(TYPE_NAMES[bytes.readByte()]).append("</FONT>");
- break;
-
- /* Access object/class fields.
- */
- case GETFIELD: case GETSTATIC: case PUTFIELD: case PUTSTATIC:
- index = bytes.readShort();
- ConstantFieldref c1 = (ConstantFieldref)constant_pool.getConstant(index, CONSTANT_Fieldref);
-
- class_index = c1.getClassIndex();
- name = constant_pool.getConstantString(class_index, CONSTANT_Class);
- name = Utility.compactClassName(name, false);
-
- index = c1.getNameAndTypeIndex();
- String field_name = constant_pool.constantToString(index, CONSTANT_NameAndType);
-
- if(name.equals(class_name)) { // Local field
- buf.append("<A HREF=\"").append(class_name).append("_methods.html#field").append(field_name)
- .append("\" TARGET=Methods>").append(field_name).append("</A>\n");
- }
- else
- buf.append(constant_html.referenceConstant(class_index)).append(".").append(field_name);
-
- break;
-
- /* Operands are references to classes in constant pool
- */
- case CHECKCAST: case INSTANCEOF: case NEW:
- index = bytes.readShort();
- buf.append(constant_html.referenceConstant(index));
- break;
-
- /* Operands are references to methods in constant pool
- */
- case INVOKESPECIAL: case INVOKESTATIC: case INVOKEVIRTUAL: case INVOKEINTERFACE:
- int m_index = bytes.readShort();
- String str;
-
- if(opcode == INVOKEINTERFACE) { // Special treatment needed
- int nargs = bytes.readUnsignedByte(); // Redundant
- int reserved = bytes.readUnsignedByte(); // Reserved
-
- ConstantInterfaceMethodref c=(ConstantInterfaceMethodref)constant_pool.getConstant(m_index, CONSTANT_InterfaceMethodref);
-
- class_index = c.getClassIndex();
- str = constant_pool.constantToString(c);
- index = c.getNameAndTypeIndex();
- }
- else {
- ConstantMethodref c = (ConstantMethodref)constant_pool.getConstant(m_index, CONSTANT_Methodref);
- class_index = c.getClassIndex();
-
- str = constant_pool.constantToString(c);
- index = c.getNameAndTypeIndex();
- }
-
- name = Class2HTML.referenceClass(class_index);
- str = Class2HTML.toHTML(constant_pool.constantToString(constant_pool.getConstant(index, CONSTANT_NameAndType)));
-
- // Get signature, i.e., types
- ConstantNameAndType c2 = (ConstantNameAndType)constant_pool.
- getConstant(index, CONSTANT_NameAndType);
- signature = constant_pool.constantToString(c2.getSignatureIndex(),
- CONSTANT_Utf8);
- String[] args = Utility.methodSignatureArgumentTypes(signature, false);
- String type = Utility.methodSignatureReturnType(signature, false);
-
- buf.append(name).append(".<A HREF=\"").append(class_name).append("_cp.html#cp").append(m_index)
- .append("\" TARGET=ConstantPool>").append(str).append("</A>").append("(");
-
- // List arguments
- for(int i=0; i < args.length; i++) {
- buf.append(Class2HTML.referenceType(args[i]));
-
- if(i < args.length - 1)
- buf.append(", ");
- }
- // Attach return type
- buf.append("):").append(Class2HTML.referenceType(type));
-
- break;
-
- /* Operands are references to items in constant pool
- */
- case LDC_W: case LDC2_W:
- index = bytes.readShort();
-
- buf.append("<A HREF=\"").append(class_name).append("_cp.html#cp").append(index)
- .append("\" TARGET=\"ConstantPool\">")
- .append(Class2HTML.toHTML(constant_pool.constantToString(index,
- constant_pool.
- getConstant(index).getTag())))
- .append("</a>");
- break;
-
- case LDC:
- index = bytes.readUnsignedByte();
- buf.append("<A HREF=\"").append(class_name).append("_cp.html#cp").append(index)
- .append("\" TARGET=\"ConstantPool\">")
- .append(Class2HTML.toHTML(constant_pool.constantToString(index,
- constant_pool.
- getConstant(index).getTag())))
- .append("</a>");
- break;
-
- /* Array of references.
- */
- case ANEWARRAY:
- index = bytes.readShort();
-
- buf.append(constant_html.referenceConstant(index));
- break;
-
- /* Multidimensional array of references.
- */
- case MULTIANEWARRAY:
- index = bytes.readShort();
- int dimensions = bytes.readByte();
- buf.append(constant_html.referenceConstant(index)).append(":").append(dimensions).append("-dimensional");
- break;
-
- /* Increment local variable.
- */
- case IINC:
- if(wide) {
- vindex = bytes.readShort();
- constant = bytes.readShort();
- wide = false;
- }
- else {
- vindex = bytes.readUnsignedByte();
- constant = bytes.readByte();
- }
- buf.append("%").append(vindex).append(" ").append(constant);
- break;
-
- default:
- if(NO_OF_OPERANDS[opcode] > 0) {
- for(int i=0; i < TYPE_OF_OPERANDS[opcode].length; i++) {
- switch(TYPE_OF_OPERANDS[opcode][i]) {
- case T_BYTE:
- buf.append(bytes.readUnsignedByte());
- break;
-
- case T_SHORT: // Either branch or index
- buf.append(bytes.readShort());
- break;
-
- case T_INT:
- buf.append(bytes.readInt());
- break;
-
- default: // Never reached
- System.err.println("Unreachable default case reached!");
- System.exit(-1);
- }
- buf.append(" ");
- }
- }
+ private String class_name; // name of current class
+ private Method[] methods; // Methods to print
+ private PrintWriter file; // file to write to
+ private BitSet goto_set;
+ private ConstantPool constant_pool;
+ private ConstantHTML constant_html;
+ private static boolean wide = false;
+
+
+ CodeHTML(String dir, String class_name, Method[] methods, ConstantPool constant_pool,
+ ConstantHTML constant_html) throws IOException {
+ this.class_name = class_name;
+ this.methods = methods;
+ this.constant_pool = constant_pool;
+ this.constant_html = constant_html;
+ file = new PrintWriter(new FileOutputStream(dir + class_name + "_code.html"));
+ file.println("<HTML><BODY BGCOLOR=\"#C0C0C0\">");
+ for (int i = 0; i < methods.length; i++) {
+ writeMethod(methods[i], i);
+ }
+ file.println("</BODY></HTML>");
+ file.close();
}
- buf.append("</TD>");
- return buf.toString();
- }
-
- /**
- * Find all target addresses in code, so that they can be marked
- * with <A NAME = ...>. Target addresses are kept in an BitSet object.
- */
- private final void findGotos(ByteSequence bytes, Method method, Code code)
- throws IOException
- {
- int index;
- goto_set = new BitSet(bytes.available());
- int opcode;
- /* First get Code attribute from method and the exceptions handled
- * (try .. catch) in this method. We only need the line number here.
+ /**
+ * Disassemble a stream of byte codes and return the
+ * string representation.
+ *
+ * @param stream data input stream
+ * @return String representation of byte code
*/
-
- if(code != null) {
- CodeException[] ce = code.getExceptionTable();
- int len = ce.length;
-
- for(int i=0; i < len; i++) {
- goto_set.set(ce[i].getStartPC());
- goto_set.set(ce[i].getEndPC());
- goto_set.set(ce[i].getHandlerPC());
- }
-
- // Look for local variables and their range
- Attribute[] attributes = code.getAttributes();
- for(int i=0; i < attributes.length; i++) {
- if(attributes[i].getTag() == ATTR_LOCAL_VARIABLE_TABLE) {
- LocalVariable[] vars = ((LocalVariableTable)attributes[i]).getLocalVariableTable();
-
- for(int j=0; j < vars.length; j++) {
- int start = vars[j].getStartPC();
- int end = (int)(start + vars[j].getLength());
- goto_set.set(start);
- goto_set.set(end);
- }
- break;
- }
- }
- }
-
- // Get target addresses from GOTO, JSR, TABLESWITCH, etc.
- for(int i=0; bytes.available() > 0; i++) {
- opcode = bytes.readUnsignedByte();
- //System.out.println(OPCODE_NAMES[opcode]);
- switch(opcode) {
- case TABLESWITCH: case LOOKUPSWITCH:
- //bytes.readByte(); // Skip already read byte
-
- int remainder = bytes.getIndex() % 4;
- int no_pad_bytes = (remainder == 0)? 0 : 4 - remainder;
- int default_offset, offset;
-
- for(int j=0; j < no_pad_bytes; j++)
- bytes.readByte();
-
- // Both cases have a field default_offset in common
- default_offset = bytes.readInt();
-
- if(opcode == TABLESWITCH) {
- int low = bytes.readInt();
- int high = bytes.readInt();
-
- offset = bytes.getIndex() - 12 - no_pad_bytes - 1;
- default_offset += offset;
- goto_set.set(default_offset);
-
- for(int j=0; j < (high - low + 1); j++) {
- index = offset + bytes.readInt();
- goto_set.set(index);
- }
- }
- else { // LOOKUPSWITCH
- int npairs = bytes.readInt();
-
- offset = bytes.getIndex() - 8 - no_pad_bytes - 1;
- default_offset += offset;
- goto_set.set(default_offset);
-
- for(int j=0; j < npairs; j++) {
- int match = bytes.readInt();
-
- index = offset + bytes.readInt();
- goto_set.set(index);
- }
- }
- break;
-
- case GOTO: case IFEQ: case IFGE: case IFGT:
- case IFLE: case IFLT:
- case IFNE: case IFNONNULL: case IFNULL: case IF_ACMPEQ:
- case IF_ACMPNE: case IF_ICMPEQ: case IF_ICMPGE: case IF_ICMPGT:
- case IF_ICMPLE: case IF_ICMPLT: case IF_ICMPNE: case JSR:
- //bytes.readByte(); // Skip already read byte
- index = bytes.getIndex() + bytes.readShort() - 1;
-
- goto_set.set(index);
- break;
-
- case GOTO_W: case JSR_W:
- //bytes.readByte(); // Skip already read byte
- index = bytes.getIndex() + bytes.readInt() - 1;
- goto_set.set(index);
- break;
-
- default:
- bytes.unreadByte();
- codeToHTML(bytes, 0); // Ignore output
- }
+ private final String codeToHTML( ByteSequence bytes, int method_number ) throws IOException {
+ short opcode = (short) bytes.readUnsignedByte();
+ StringBuffer buf;
+ String name, signature;
+ int default_offset = 0, low, high;
+ int index, class_index, vindex, constant;
+ int[] jump_table;
+ int no_pad_bytes = 0, offset;
+ buf = new StringBuffer(256);
+ buf.append("<TT>").append(OPCODE_NAMES[opcode]).append("</TT></TD><TD>");
+ /* Special case: Skip (0-3) padding bytes, i.e., the
+ * following bytes are 4-byte-aligned
+ */
+ if ((opcode == TABLESWITCH) || (opcode == LOOKUPSWITCH)) {
+ int remainder = bytes.getIndex() % 4;
+ no_pad_bytes = (remainder == 0) ? 0 : 4 - remainder;
+ for (int i = 0; i < no_pad_bytes; i++) {
+ bytes.readByte();
+ }
+ // Both cases have a field default_offset in common
+ default_offset = bytes.readInt();
+ }
+ switch (opcode) {
+ case TABLESWITCH:
+ low = bytes.readInt();
+ high = bytes.readInt();
+ offset = bytes.getIndex() - 12 - no_pad_bytes - 1;
+ default_offset += offset;
+ buf.append("<TABLE BORDER=1><TR>");
+ // Print switch indices in first row (and default)
+ jump_table = new int[high - low + 1];
+ for (int i = 0; i < jump_table.length; i++) {
+ jump_table[i] = offset + bytes.readInt();
+ buf.append("<TH>").append(low + i).append("</TH>");
+ }
+ buf.append("<TH>default</TH></TR>\n<TR>");
+ // Print target and default indices in second row
+ for (int i = 0; i < jump_table.length; i++) {
+ buf.append("<TD><A HREF=\"#code").append(method_number).append("@").append(
+ jump_table[i]).append("\">").append(jump_table[i]).append("</A></TD>");
+ }
+ buf.append("<TD><A HREF=\"#code").append(method_number).append("@").append(
+ default_offset).append("\">").append(default_offset).append(
+ "</A></TD></TR>\n</TABLE>\n");
+ break;
+ /* Lookup switch has variable length arguments.
+ */
+ case LOOKUPSWITCH:
+ int npairs = bytes.readInt();
+ offset = bytes.getIndex() - 8 - no_pad_bytes - 1;
+ jump_table = new int[npairs];
+ default_offset += offset;
+ buf.append("<TABLE BORDER=1><TR>");
+ // Print switch indices in first row (and default)
+ for (int i = 0; i < npairs; i++) {
+ int match = bytes.readInt();
+ jump_table[i] = offset + bytes.readInt();
+ buf.append("<TH>").append(match).append("</TH>");
+ }
+ buf.append("<TH>default</TH></TR>\n<TR>");
+ // Print target and default indices in second row
+ for (int i = 0; i < npairs; i++) {
+ buf.append("<TD><A HREF=\"#code").append(method_number).append("@").append(
+ jump_table[i]).append("\">").append(jump_table[i]).append("</A></TD>");
+ }
+ buf.append("<TD><A HREF=\"#code").append(method_number).append("@").append(
+ default_offset).append("\">").append(default_offset).append(
+ "</A></TD></TR>\n</TABLE>\n");
+ break;
+ /* Two address bytes + offset from start of byte stream form the
+ * jump target.
+ */
+ case GOTO:
+ case IFEQ:
+ case IFGE:
+ case IFGT:
+ case IFLE:
+ case IFLT:
+ case IFNE:
+ case IFNONNULL:
+ case IFNULL:
+ case IF_ACMPEQ:
+ case IF_ACMPNE:
+ case IF_ICMPEQ:
+ case IF_ICMPGE:
+ case IF_ICMPGT:
+ case IF_ICMPLE:
+ case IF_ICMPLT:
+ case IF_ICMPNE:
+ case JSR:
+ index = (int) (bytes.getIndex() + bytes.readShort() - 1);
+ buf.append("<A HREF=\"#code").append(method_number).append("@").append(index)
+ .append("\">").append(index).append("</A>");
+ break;
+ /* Same for 32-bit wide jumps
+ */
+ case GOTO_W:
+ case JSR_W:
+ int windex = bytes.getIndex() + bytes.readInt() - 1;
+ buf.append("<A HREF=\"#code").append(method_number).append("@").append(windex)
+ .append("\">").append(windex).append("</A>");
+ break;
+ /* Index byte references local variable (register)
+ */
+ case ALOAD:
+ case ASTORE:
+ case DLOAD:
+ case DSTORE:
+ case FLOAD:
+ case FSTORE:
+ case ILOAD:
+ case ISTORE:
+ case LLOAD:
+ case LSTORE:
+ case RET:
+ if (wide) {
+ vindex = bytes.readShort();
+ wide = false; // Clear flag
+ } else {
+ vindex = bytes.readUnsignedByte();
+ }
+ buf.append("%").append(vindex);
+ break;
+ /*
+ * Remember wide byte which is used to form a 16-bit address in the
+ * following instruction. Relies on that the method is called again with
+ * the following opcode.
+ */
+ case WIDE:
+ wide = true;
+ buf.append("(wide)");
+ break;
+ /* Array of basic type.
+ */
+ case NEWARRAY:
+ buf.append("<FONT COLOR=\"#00FF00\">").append(TYPE_NAMES[bytes.readByte()]).append(
+ "</FONT>");
+ break;
+ /* Access object/class fields.
+ */
+ case GETFIELD:
+ case GETSTATIC:
+ case PUTFIELD:
+ case PUTSTATIC:
+ index = bytes.readShort();
+ ConstantFieldref c1 = (ConstantFieldref) constant_pool.getConstant(index,
+ CONSTANT_Fieldref);
+ class_index = c1.getClassIndex();
+ name = constant_pool.getConstantString(class_index, CONSTANT_Class);
+ name = Utility.compactClassName(name, false);
+ index = c1.getNameAndTypeIndex();
+ String field_name = constant_pool.constantToString(index, CONSTANT_NameAndType);
+ if (name.equals(class_name)) { // Local field
+ buf.append("<A HREF=\"").append(class_name).append("_methods.html#field")
+ .append(field_name).append("\" TARGET=Methods>").append(field_name)
+ .append("</A>\n");
+ } else {
+ buf.append(constant_html.referenceConstant(class_index)).append(".").append(
+ field_name);
+ }
+ break;
+ /* Operands are references to classes in constant pool
+ */
+ case CHECKCAST:
+ case INSTANCEOF:
+ case NEW:
+ index = bytes.readShort();
+ buf.append(constant_html.referenceConstant(index));
+ break;
+ /* Operands are references to methods in constant pool
+ */
+ case INVOKESPECIAL:
+ case INVOKESTATIC:
+ case INVOKEVIRTUAL:
+ case INVOKEINTERFACE:
+ int m_index = bytes.readShort();
+ String str;
+ if (opcode == INVOKEINTERFACE) { // Special treatment needed
+ int nargs = bytes.readUnsignedByte(); // Redundant
+ int reserved = bytes.readUnsignedByte(); // Reserved
+ ConstantInterfaceMethodref c = (ConstantInterfaceMethodref) constant_pool
+ .getConstant(m_index, CONSTANT_InterfaceMethodref);
+ class_index = c.getClassIndex();
+ str = constant_pool.constantToString(c);
+ index = c.getNameAndTypeIndex();
+ } else {
+ ConstantMethodref c = (ConstantMethodref) constant_pool.getConstant(m_index,
+ CONSTANT_Methodref);
+ class_index = c.getClassIndex();
+ str = constant_pool.constantToString(c);
+ index = c.getNameAndTypeIndex();
+ }
+ name = Class2HTML.referenceClass(class_index);
+ str = Class2HTML.toHTML(constant_pool.constantToString(constant_pool.getConstant(
+ index, CONSTANT_NameAndType)));
+ // Get signature, i.e., types
+ ConstantNameAndType c2 = (ConstantNameAndType) constant_pool.getConstant(index,
+ CONSTANT_NameAndType);
+ signature = constant_pool.constantToString(c2.getSignatureIndex(), CONSTANT_Utf8);
+ String[] args = Utility.methodSignatureArgumentTypes(signature, false);
+ String type = Utility.methodSignatureReturnType(signature, false);
+ buf.append(name).append(".<A HREF=\"").append(class_name).append("_cp.html#cp")
+ .append(m_index).append("\" TARGET=ConstantPool>").append(str).append(
+ "</A>").append("(");
+ // List arguments
+ for (int i = 0; i < args.length; i++) {
+ buf.append(Class2HTML.referenceType(args[i]));
+ if (i < args.length - 1) {
+ buf.append(", ");
+ }
+ }
+ // Attach return type
+ buf.append("):").append(Class2HTML.referenceType(type));
+ break;
+ /* Operands are references to items in constant pool
+ */
+ case LDC_W:
+ case LDC2_W:
+ index = bytes.readShort();
+ buf.append("<A HREF=\"").append(class_name).append("_cp.html#cp").append(index)
+ .append("\" TARGET=\"ConstantPool\">").append(
+ Class2HTML.toHTML(constant_pool.constantToString(index,
+ constant_pool.getConstant(index).getTag()))).append("</a>");
+ break;
+ case LDC:
+ index = bytes.readUnsignedByte();
+ buf.append("<A HREF=\"").append(class_name).append("_cp.html#cp").append(index)
+ .append("\" TARGET=\"ConstantPool\">").append(
+ Class2HTML.toHTML(constant_pool.constantToString(index,
+ constant_pool.getConstant(index).getTag()))).append("</a>");
+ break;
+ /* Array of references.
+ */
+ case ANEWARRAY:
+ index = bytes.readShort();
+ buf.append(constant_html.referenceConstant(index));
+ break;
+ /* Multidimensional array of references.
+ */
+ case MULTIANEWARRAY:
+ index = bytes.readShort();
+ int dimensions = bytes.readByte();
+ buf.append(constant_html.referenceConstant(index)).append(":").append(dimensions)
+ .append("-dimensional");
+ break;
+ /* Increment local variable.
+ */
+ case IINC:
+ if (wide) {
+ vindex = bytes.readShort();
+ constant = bytes.readShort();
+ wide = false;
+ } else {
+ vindex = bytes.readUnsignedByte();
+ constant = bytes.readByte();
+ }
+ buf.append("%").append(vindex).append(" ").append(constant);
+ break;
+ default:
+ if (NO_OF_OPERANDS[opcode] > 0) {
+ for (int i = 0; i < TYPE_OF_OPERANDS[opcode].length; i++) {
+ switch (TYPE_OF_OPERANDS[opcode][i]) {
+ case T_BYTE:
+ buf.append(bytes.readUnsignedByte());
+ break;
+ case T_SHORT: // Either branch or index
+ buf.append(bytes.readShort());
+ break;
+ case T_INT:
+ buf.append(bytes.readInt());
+ break;
+ default: // Never reached
+ System.err.println("Unreachable default case reached!");
+ System.exit(-1);
+ }
+ buf.append(" ");
+ }
+ }
+ }
+ buf.append("</TD>");
+ return buf.toString();
}
- }
- /**
- * Write a single method with the byte code associated with it.
- */
- private void writeMethod(Method method, int method_number)
- throws IOException
- {
- // Get raw signature
- String signature = method.getSignature();
- // Get array of strings containing the argument types
- String[] args = Utility.methodSignatureArgumentTypes(signature, false);
- // Get return type string
- String type = Utility.methodSignatureReturnType(signature, false);
- // Get method name
- String name = method.getName();
- String html_name = Class2HTML.toHTML(name);
- // Get method's access flags
- String access = Utility.accessToString(method.getAccessFlags());
- access = Utility.replace(access, " ", " ");
- // Get the method's attributes, the Code Attribute in particular
- Attribute[] attributes= method.getAttributes();
-
- file.print("<P><B><FONT COLOR=\"#FF0000\">" + access + "</FONT> " +
- "<A NAME=method" + method_number + ">" + Class2HTML.referenceType(type) +
- "</A> <A HREF=\"" + class_name + "_methods.html#method" + method_number +
- "\" TARGET=Methods>" + html_name + "</A>(");
-
- for(int i=0; i < args.length; i++) {
- file.print(Class2HTML.referenceType(args[i]));
- if(i < args.length - 1)
- file.print(", ");
- }
- file.println(")</B></P>");
-
- Code c=null;
- byte[] code=null;
-
- if(attributes.length > 0) {
- file.print("<H4>Attributes</H4><UL>\n");
- for(int i=0; i < attributes.length; i++) {
- byte tag = attributes[i].getTag();
-
- if(tag != ATTR_UNKNOWN)
- file.print("<LI><A HREF=\"" + class_name + "_attributes.html#method" + method_number + "@" + i +
- "\" TARGET=Attributes>" + ATTRIBUTE_NAMES[tag] + "</A></LI>\n");
- else
- file.print("<LI>" + attributes[i] + "</LI>");
-
- if(tag == ATTR_CODE) {
- c = (Code)attributes[i];
- Attribute[] attributes2 = c.getAttributes();
- code = c.getCode();
-
- file.print("<UL>");
- for(int j=0; j < attributes2.length; j++) {
- tag = attributes2[j].getTag();
- file.print("<LI><A HREF=\"" + class_name + "_attributes.html#" +
- "method" + method_number + "@" + i + "@" + j + "\" TARGET=Attributes>" +
- ATTRIBUTE_NAMES[tag] + "</A></LI>\n");
-
- }
- file.print("</UL>");
- }
- }
- file.println("</UL>");
+ /**
+ * Find all target addresses in code, so that they can be marked
+ * with <A NAME = ...>. Target addresses are kept in an BitSet object.
+ */
+ private final void findGotos( ByteSequence bytes, Method method, Code code ) throws IOException {
+ int index;
+ goto_set = new BitSet(bytes.available());
+ int opcode;
+ /* First get Code attribute from method and the exceptions handled
+ * (try .. catch) in this method. We only need the line number here.
+ */
+ if (code != null) {
+ CodeException[] ce = code.getExceptionTable();
+ int len = ce.length;
+ for (int i = 0; i < len; i++) {
+ goto_set.set(ce[i].getStartPC());
+ goto_set.set(ce[i].getEndPC());
+ goto_set.set(ce[i].getHandlerPC());
+ }
+ // Look for local variables and their range
+ Attribute[] attributes = code.getAttributes();
+ for (int i = 0; i < attributes.length; i++) {
+ if (attributes[i].getTag() == ATTR_LOCAL_VARIABLE_TABLE) {
+ LocalVariable[] vars = ((LocalVariableTable) attributes[i])
+ .getLocalVariableTable();
+ for (int j = 0; j < vars.length; j++) {
+ int start = vars[j].getStartPC();
+ int end = (int) (start + vars[j].getLength());
+ goto_set.set(start);
+ goto_set.set(end);
+ }
+ break;
+ }
+ }
+ }
+ // Get target addresses from GOTO, JSR, TABLESWITCH, etc.
+ for (int i = 0; bytes.available() > 0; i++) {
+ opcode = bytes.readUnsignedByte();
+ //System.out.println(OPCODE_NAMES[opcode]);
+ switch (opcode) {
+ case TABLESWITCH:
+ case LOOKUPSWITCH:
+ //bytes.readByte(); // Skip already read byte
+ int remainder = bytes.getIndex() % 4;
+ int no_pad_bytes = (remainder == 0) ? 0 : 4 - remainder;
+ int default_offset,
+ offset;
+ for (int j = 0; j < no_pad_bytes; j++) {
+ bytes.readByte();
+ }
+ // Both cases have a field default_offset in common
+ default_offset = bytes.readInt();
+ if (opcode == TABLESWITCH) {
+ int low = bytes.readInt();
+ int high = bytes.readInt();
+ offset = bytes.getIndex() - 12 - no_pad_bytes - 1;
+ default_offset += offset;
+ goto_set.set(default_offset);
+ for (int j = 0; j < (high - low + 1); j++) {
+ index = offset + bytes.readInt();
+ goto_set.set(index);
+ }
+ } else { // LOOKUPSWITCH
+ int npairs = bytes.readInt();
+ offset = bytes.getIndex() - 8 - no_pad_bytes - 1;
+ default_offset += offset;
+ goto_set.set(default_offset);
+ for (int j = 0; j < npairs; j++) {
+ int match = bytes.readInt();
+ index = offset + bytes.readInt();
+ goto_set.set(index);
+ }
+ }
+ break;
+ case GOTO:
+ case IFEQ:
+ case IFGE:
+ case IFGT:
+ case IFLE:
+ case IFLT:
+ case IFNE:
+ case IFNONNULL:
+ case IFNULL:
+ case IF_ACMPEQ:
+ case IF_ACMPNE:
+ case IF_ICMPEQ:
+ case IF_ICMPGE:
+ case IF_ICMPGT:
+ case IF_ICMPLE:
+ case IF_ICMPLT:
+ case IF_ICMPNE:
+ case JSR:
+ //bytes.readByte(); // Skip already read byte
+ index = bytes.getIndex() + bytes.readShort() - 1;
+ goto_set.set(index);
+ break;
+ case GOTO_W:
+ case JSR_W:
+ //bytes.readByte(); // Skip already read byte
+ index = bytes.getIndex() + bytes.readInt() - 1;
+ goto_set.set(index);
+ break;
+ default:
+ bytes.unreadByte();
+ codeToHTML(bytes, 0); // Ignore output
+ }
+ }
}
- if(code != null) { // No code, an abstract method, e.g.
- //System.out.println(name + "\n" + Utility.codeToString(code, constant_pool, 0, -1));
- // Print the byte code
- ByteSequence stream = new ByteSequence(code);
- stream.mark(stream.available());
- findGotos(stream, method, c);
- stream.reset();
-
- file.println("<TABLE BORDER=0><TR><TH ALIGN=LEFT>Byte<BR>offset</TH>" +
- "<TH ALIGN=LEFT>Instruction</TH><TH ALIGN=LEFT>Argument</TH>");
-
- for(int i=0; stream.available() > 0; i++) {
- int offset = stream.getIndex();
- String str = codeToHTML(stream, method_number);
- String anchor = "";
-
- /* Set an anchor mark if this line is targetted by a goto, jsr, etc.
- * Defining an anchor for every line is very inefficient!
- */
- if(goto_set.get(offset))
- anchor = "<A NAME=code" + method_number + "@" + offset + "></A>";
-
- String anchor2;
- if(stream.getIndex() == code.length) // last loop
- anchor2 = "<A NAME=code" + method_number + "@" + code.length + ">" + offset + "</A>";
- else
- anchor2 = "" + offset;
-
- file.println("<TR VALIGN=TOP><TD>" + anchor2 + "</TD><TD>" + anchor + str + "</TR>");
- }
-
- // Mark last line, may be targetted from Attributes window
- file.println("<TR><TD> </A></TD></TR>");
- file.println("</TABLE>");
+ /**
+ * Write a single method with the byte code associated with it.
+ */
+ private void writeMethod( Method method, int method_number ) throws IOException {
+ // Get raw signature
+ String signature = method.getSignature();
+ // Get array of strings containing the argument types
+ String[] args = Utility.methodSignatureArgumentTypes(signature, false);
+ // Get return type string
+ String type = Utility.methodSignatureReturnType(signature, false);
+ // Get method name
+ String name = method.getName();
+ String html_name = Class2HTML.toHTML(name);
+ // Get method's access flags
+ String access = Utility.accessToString(method.getAccessFlags());
+ access = Utility.replace(access, " ", " ");
+ // Get the method's attributes, the Code Attribute in particular
+ Attribute[] attributes = method.getAttributes();
+ file.print("<P><B><FONT COLOR=\"#FF0000\">" + access + "</FONT> " + "<A NAME=method"
+ + method_number + ">" + Class2HTML.referenceType(type) + "</A> <A HREF=\""
+ + class_name + "_methods.html#method" + method_number + "\" TARGET=Methods>"
+ + html_name + "</A>(");
+ for (int i = 0; i < args.length; i++) {
+ file.print(Class2HTML.referenceType(args[i]));
+ if (i < args.length - 1) {
+ file.print(", ");
+ }
+ }
+ file.println(")</B></P>");
+ Code c = null;
+ byte[] code = null;
+ if (attributes.length > 0) {
+ file.print("<H4>Attributes</H4><UL>\n");
+ for (int i = 0; i < attributes.length; i++) {
+ byte tag = attributes[i].getTag();
+ if (tag != ATTR_UNKNOWN) {
+ file.print("<LI><A HREF=\"" + class_name + "_attributes.html#method"
+ + method_number + "@" + i + "\" TARGET=Attributes>"
+ + ATTRIBUTE_NAMES[tag] + "</A></LI>\n");
+ } else {
+ file.print("<LI>" + attributes[i] + "</LI>");
+ }
+ if (tag == ATTR_CODE) {
+ c = (Code) attributes[i];
+ Attribute[] attributes2 = c.getAttributes();
+ code = c.getCode();
+ file.print("<UL>");
+ for (int j = 0; j < attributes2.length; j++) {
+ tag = attributes2[j].getTag();
+ file.print("<LI><A HREF=\"" + class_name + "_attributes.html#" + "method"
+ + method_number + "@" + i + "@" + j + "\" TARGET=Attributes>"
+ + ATTRIBUTE_NAMES[tag] + "</A></LI>\n");
+ }
+ file.print("</UL>");
+ }
+ }
+ file.println("</UL>");
+ }
+ if (code != null) { // No code, an abstract method, e.g.
+ //System.out.println(name + "\n" + Utility.codeToString(code, constant_pool, 0, -1));
+ // Print the byte code
+ ByteSequence stream = new ByteSequence(code);
+ stream.mark(stream.available());
+ findGotos(stream, method, c);
+ stream.reset();
+ file.println("<TABLE BORDER=0><TR><TH ALIGN=LEFT>Byte<BR>offset</TH>"
+ + "<TH ALIGN=LEFT>Instruction</TH><TH ALIGN=LEFT>Argument</TH>");
+ for (int i = 0; stream.available() > 0; i++) {
+ int offset = stream.getIndex();
+ String str = codeToHTML(stream, method_number);
+ String anchor = "";
+ /* Set an anchor mark if this line is targetted by a goto, jsr, etc.
+ * Defining an anchor for every line is very inefficient!
+ */
+ if (goto_set.get(offset)) {
+ anchor = "<A NAME=code" + method_number + "@" + offset + "></A>";
+ }
+ String anchor2;
+ if (stream.getIndex() == code.length) {
+ anchor2 = "<A NAME=code" + method_number + "@" + code.length + ">" + offset
+ + "</A>";
+ } else {
+ anchor2 = "" + offset;
+ }
+ file
+ .println("<TR VALIGN=TOP><TD>" + anchor2 + "</TD><TD>" + anchor + str
+ + "</TR>");
+ }
+ // Mark last line, may be targetted from Attributes window
+ file.println("<TR><TD> </A></TD></TR>");
+ file.println("</TABLE>");
+ }
}
-
- }
}
---------------------------------------------------------------------
To unsubscribe, e-mail: bcel-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: bcel-dev-help@jakarta.apache.org