diff --git a/src/org/apache/bcel/ExceptionConstants.java b/src/org/apache/bcel/ExceptionConstants.java index e42aa58..c316ef0 100644 --- a/src/org/apache/bcel/ExceptionConstants.java +++ b/src/org/apache/bcel/ExceptionConstants.java @@ -26,51 +26,51 @@ public interface ExceptionConstants { /** The mother of all exceptions */ - public static final Class THROWABLE = Throwable.class; + public static final Class THROWABLE = Throwable.class; /** Super class of any run-time exception */ - public static final Class RUNTIME_EXCEPTION = RuntimeException.class; + public static final Class RUNTIME_EXCEPTION = RuntimeException.class; /** Super class of any linking exception (aka Linkage Error) */ - public static final Class LINKING_EXCEPTION = LinkageError.class; + public static final Class LINKING_EXCEPTION = LinkageError.class; /** Linking Exceptions */ - public static final Class CLASS_CIRCULARITY_ERROR = ClassCircularityError.class; - public static final Class CLASS_FORMAT_ERROR = ClassFormatError.class; - public static final Class EXCEPTION_IN_INITIALIZER_ERROR = ExceptionInInitializerError.class; - public static final Class INCOMPATIBLE_CLASS_CHANGE_ERROR = IncompatibleClassChangeError.class; - public static final Class ABSTRACT_METHOD_ERROR = AbstractMethodError.class; - public static final Class ILLEGAL_ACCESS_ERROR = IllegalAccessError.class; - public static final Class INSTANTIATION_ERROR = InstantiationError.class; - public static final Class NO_SUCH_FIELD_ERROR = NoSuchFieldError.class; - public static final Class NO_SUCH_METHOD_ERROR = NoSuchMethodError.class; - public static final Class NO_CLASS_DEF_FOUND_ERROR = NoClassDefFoundError.class; - public static final Class UNSATISFIED_LINK_ERROR = UnsatisfiedLinkError.class; - public static final Class VERIFY_ERROR = VerifyError.class; + public static final Class CLASS_CIRCULARITY_ERROR = ClassCircularityError.class; + public static final Class CLASS_FORMAT_ERROR = ClassFormatError.class; + public static final Class EXCEPTION_IN_INITIALIZER_ERROR = ExceptionInInitializerError.class; + public static final Class INCOMPATIBLE_CLASS_CHANGE_ERROR = IncompatibleClassChangeError.class; + public static final Class ABSTRACT_METHOD_ERROR = AbstractMethodError.class; + public static final Class ILLEGAL_ACCESS_ERROR = IllegalAccessError.class; + public static final Class INSTANTIATION_ERROR = InstantiationError.class; + public static final Class NO_SUCH_FIELD_ERROR = NoSuchFieldError.class; + public static final Class NO_SUCH_METHOD_ERROR = NoSuchMethodError.class; + public static final Class NO_CLASS_DEF_FOUND_ERROR = NoClassDefFoundError.class; + public static final Class UNSATISFIED_LINK_ERROR = UnsatisfiedLinkError.class; + public static final Class VERIFY_ERROR = VerifyError.class; /* UnsupportedClassVersionError is new in JDK 1.2 */ //public static final Class UnsupportedClassVersionError = UnsupportedClassVersionError.class; /** Run-Time Exceptions */ - public static final Class NULL_POINTER_EXCEPTION = NullPointerException.class; - public static final Class ARRAY_INDEX_OUT_OF_BOUNDS_EXCEPTION = ArrayIndexOutOfBoundsException.class; - public static final Class ARITHMETIC_EXCEPTION = ArithmeticException.class; - public static final Class NEGATIVE_ARRAY_SIZE_EXCEPTION = NegativeArraySizeException.class; - public static final Class CLASS_CAST_EXCEPTION = ClassCastException.class; - public static final Class ILLEGAL_MONITOR_STATE = IllegalMonitorStateException.class; + public static final Class NULL_POINTER_EXCEPTION = NullPointerException.class; + public static final Class ARRAY_INDEX_OUT_OF_BOUNDS_EXCEPTION = ArrayIndexOutOfBoundsException.class; + public static final Class ARITHMETIC_EXCEPTION = ArithmeticException.class; + public static final Class NEGATIVE_ARRAY_SIZE_EXCEPTION = NegativeArraySizeException.class; + public static final Class CLASS_CAST_EXCEPTION = ClassCastException.class; + public static final Class ILLEGAL_MONITOR_STATE = IllegalMonitorStateException.class; /** Pre-defined exception arrays according to chapters 5.1-5.4 of the Java Virtual * Machine Specification */ - public static final Class[] EXCS_CLASS_AND_INTERFACE_RESOLUTION = { + public static final Class[] EXCS_CLASS_AND_INTERFACE_RESOLUTION = { NO_CLASS_DEF_FOUND_ERROR, CLASS_FORMAT_ERROR, VERIFY_ERROR, ABSTRACT_METHOD_ERROR, EXCEPTION_IN_INITIALIZER_ERROR, ILLEGAL_ACCESS_ERROR }; // Chapter 5.1 - public static final Class[] EXCS_FIELD_AND_METHOD_RESOLUTION = { + public static final Class[] EXCS_FIELD_AND_METHOD_RESOLUTION = { NO_SUCH_FIELD_ERROR, ILLEGAL_ACCESS_ERROR, NO_SUCH_METHOD_ERROR }; // Chapter 5.2 - public static final Class[] EXCS_INTERFACE_METHOD_RESOLUTION = new Class[0]; // Chapter 5.3 (as below) - public static final Class[] EXCS_STRING_RESOLUTION = new Class[0]; + public static final Class[] EXCS_INTERFACE_METHOD_RESOLUTION = new Class[0]; // Chapter 5.3 (as below) + public static final Class[] EXCS_STRING_RESOLUTION = new Class[0]; // Chapter 5.4 (no errors but the ones that _always_ could happen! How stupid.) - public static final Class[] EXCS_ARRAY_EXCEPTION = { + public static final Class[] EXCS_ARRAY_EXCEPTION = { NULL_POINTER_EXCEPTION, ARRAY_INDEX_OUT_OF_BOUNDS_EXCEPTION }; } diff --git a/src/org/apache/bcel/Repository.java b/src/org/apache/bcel/Repository.java index 3dcb3f3..97da781 100644 --- a/src/org/apache/bcel/Repository.java +++ b/src/org/apache/bcel/Repository.java @@ -70,7 +70,7 @@ public abstract class Repository { * @throws ClassNotFoundException if the class could not be found or * parsed correctly */ - public static JavaClass lookupClass( Class clazz ) throws ClassNotFoundException { + public static JavaClass lookupClass( Class clazz ) throws ClassNotFoundException { return _repository.loadClass(clazz); } diff --git a/src/org/apache/bcel/classfile/JavaClass.java b/src/org/apache/bcel/classfile/JavaClass.java index b2985cb..de8d91d 100644 --- a/src/org/apache/bcel/classfile/JavaClass.java +++ b/src/org/apache/bcel/classfile/JavaClass.java @@ -27,6 +27,7 @@ import java.util.List; import java.util.Set; import java.util.StringTokenizer; import java.util.TreeSet; + import org.apache.bcel.Constants; import org.apache.bcel.generic.Type; import org.apache.bcel.util.BCELComparator; @@ -45,9 +46,13 @@ import org.apache.bcel.util.SyntheticRepository; * @see org.apache.bcel.generic.ClassGen * @author M. Dahm */ -public class JavaClass extends AccessFlags implements Cloneable, Node, Comparable { +public class JavaClass extends AccessFlags implements Cloneable, Node, Comparable { - private String file_name; + /** + * + */ + private static final long serialVersionUID = 1L; + private String file_name; private String package_name; private String source_file_name = ""; private int class_name_index; @@ -770,7 +775,7 @@ public class JavaClass extends AccessFlags implements Cloneable, Node, Comparabl */ public JavaClass[] getSuperClasses() throws ClassNotFoundException { JavaClass clazz = this; - List allSuperClasses = new ArrayList(); + List allSuperClasses = new ArrayList(); for (clazz = clazz.getSuperClass(); clazz != null; clazz = clazz.getSuperClass()) { allSuperClasses.add(clazz); } @@ -796,7 +801,7 @@ public class JavaClass extends AccessFlags implements Cloneable, Node, Comparabl */ public JavaClass[] getAllInterfaces() throws ClassNotFoundException { ClassQueue queue = new ClassQueue(); - Set allInterfaces = new TreeSet(); + Set allInterfaces = new TreeSet(); queue.enqueue(this); while (!queue.empty()) { JavaClass clazz = queue.dequeue(); diff --git a/src/org/apache/bcel/util/AttributeHTML.java b/src/org/apache/bcel/util/AttributeHTML.java deleted file mode 100644 index 6b0441d..0000000 --- a/src/org/apache/bcel/util/AttributeHTML.java +++ /dev/null @@ -1,211 +0,0 @@ -/* - * Copyright 2000-2004 The Apache Software Foundation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * 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; -import org.apache.bcel.classfile.Attribute; -import org.apache.bcel.classfile.Code; -import org.apache.bcel.classfile.CodeException; -import org.apache.bcel.classfile.ConstantPool; -import org.apache.bcel.classfile.ConstantUtf8; -import org.apache.bcel.classfile.ConstantValue; -import org.apache.bcel.classfile.ExceptionTable; -import org.apache.bcel.classfile.InnerClass; -import org.apache.bcel.classfile.InnerClasses; -import org.apache.bcel.classfile.LineNumber; -import org.apache.bcel.classfile.LineNumberTable; -import org.apache.bcel.classfile.LocalVariable; -import org.apache.bcel.classfile.LocalVariableTable; -import org.apache.bcel.classfile.SourceFile; -import org.apache.bcel.classfile.Utility; - -/** - * Convert found attributes into HTML file. - * - * @version $Id: AttributeHTML.java 386056 2006-03-15 11:31:56Z tcurdt $ - * @author M. Dahm - * - */ -final class AttributeHTML implements org.apache.bcel.Constants { - - private String class_name; // name of current class - private PrintWriter file; // file to write to - private int attr_count = 0; - private ConstantHTML constant_html; - private ConstantPool constant_pool; - - - AttributeHTML(String dir, String class_name, ConstantPool constant_pool, - ConstantHTML constant_html) throws IOException { - this.class_name = class_name; - this.constant_pool = constant_pool; - this.constant_html = constant_html; - file = new PrintWriter(new FileOutputStream(dir + class_name + "_attributes.html")); - file.println(""); - } - - - private final String codeLink( int link, int method_number ) { - return "" + link + ""; - } - - - final void close() { - file.println("
"); - file.close(); - } - - - final void writeAttribute( Attribute attribute, String anchor ) throws IOException { - writeAttribute(attribute, anchor, 0); - } - - - final void writeAttribute( Attribute attribute, String anchor, int method_number ) - throws IOException { - byte tag = attribute.getTag(); - int index; - if (tag == ATTR_UNKNOWN) { - return; - } - attr_count++; // Increment number of attributes found so far - if (attr_count % 2 == 0) { - file.print(""); - } else { - file.print(""); - } - file.println("

" + attr_count + " " + ATTRIBUTE_NAMES[tag] - + "

"); - /* Handle different attributes - */ - switch (tag) { - case ATTR_CODE: - Code c = (Code) attribute; - // Some directly printable values - file.print("
  • Maximum stack size = " + c.getMaxStack() - + "
  • \n
  • Number of local variables = " + c.getMaxLocals() - + "
  • \n
  • Byte code
\n"); - // Get handled exceptions and list them - CodeException[] ce = c.getExceptionTable(); - int len = ce.length; - if (len > 0) { - file.print("

Exceptions handled

    "); - for (int i = 0; i < len; i++) { - int catch_type = ce[i].getCatchType(); // Index in constant pool - file.print("
  • "); - if (catch_type != 0) { - file.print(constant_html.referenceConstant(catch_type)); // Create Link to _cp.html - } else { - file.print("Any Exception"); - } - file.print("
    (Ranging from lines " - + codeLink(ce[i].getStartPC(), method_number) + " to " - + codeLink(ce[i].getEndPC(), method_number) + ", handled at line " - + codeLink(ce[i].getHandlerPC(), method_number) + ")
  • "); - } - file.print("
"); - } - break; - case ATTR_CONSTANT_VALUE: - index = ((ConstantValue) attribute).getConstantValueIndex(); - // Reference _cp.html - file.print("\n"); - break; - case ATTR_SOURCE_FILE: - index = ((SourceFile) attribute).getSourceFileIndex(); - // Reference _cp.html - file.print("\n"); - break; - case ATTR_EXCEPTIONS: - // List thrown exceptions - int[] indices = ((ExceptionTable) attribute).getExceptionIndexTable(); - file.print("\n"); - break; - case ATTR_LINE_NUMBER_TABLE: - LineNumber[] line_numbers = ((LineNumberTable) attribute).getLineNumberTable(); - // List line number pairs - file.print("

"); - for (int i = 0; i < line_numbers.length; i++) { - file.print("(" + line_numbers[i].getStartPC() + ", " - + line_numbers[i].getLineNumber() + ")"); - if (i < line_numbers.length - 1) { - file.print(", "); // breakable - } - } - break; - case ATTR_LOCAL_VARIABLE_TABLE: - LocalVariable[] vars = ((LocalVariableTable) attribute).getLocalVariableTable(); - // List name, range and type - file.print("

    "); - for (int i = 0; i < vars.length; i++) { - index = vars[i].getSignatureIndex(); - String signature = ((ConstantUtf8) constant_pool.getConstant(index, - CONSTANT_Utf8)).getBytes(); - signature = Utility.signatureToString(signature, false); - int start = vars[i].getStartPC(); - int end = (start + vars[i].getLength()); - file.println("
  • " + Class2HTML.referenceType(signature) + " " - + vars[i].getName() + " in slot %" + vars[i].getIndex() - + "
    Valid from lines " + "" - + start + " to " + "" + end + "
  • "); - } - file.print("
\n"); - break; - case ATTR_INNER_CLASSES: - InnerClass[] classes = ((InnerClasses) attribute).getInnerClasses(); - // List inner classes - file.print("
    "); - for (int i = 0; i < classes.length; i++) { - String name, access; - index = classes[i].getInnerNameIndex(); - if (index > 0) { - name = ((ConstantUtf8) constant_pool.getConstant(index, CONSTANT_Utf8)) - .getBytes(); - } else { - name = "<anonymous>"; - } - access = Utility.accessToString(classes[i].getInnerAccessFlags()); - file.print("
  • " + access + " " - + constant_html.referenceConstant(classes[i].getInnerClassIndex()) - + " in class " - + constant_html.referenceConstant(classes[i].getOuterClassIndex()) - + " named " + name + "
  • \n"); - } - file.print("
\n"); - break; - default: // Such as Unknown attribute or Deprecated - file.print("

" + attribute.toString()); - } - file.println(""); - file.flush(); - } -} diff --git a/src/org/apache/bcel/util/BCELFactory.java b/src/org/apache/bcel/util/BCELFactory.java index 2704a57..73ae23c 100644 --- a/src/org/apache/bcel/util/BCELFactory.java +++ b/src/org/apache/bcel/util/BCELFactory.java @@ -76,7 +76,7 @@ class BCELFactory extends EmptyVisitor { _out = out; } - private Map branch_map = new HashMap(); // Map + private Map branch_map = new HashMap(); // Map public void start() { @@ -239,7 +239,7 @@ class BCELFactory extends EmptyVisitor { } // Memorize BranchInstructions that need an update - private List branches = new ArrayList(); + private List branches = new ArrayList(); public void visitBranchInstruction( BranchInstruction bi ) { @@ -294,7 +294,7 @@ class BCELFactory extends EmptyVisitor { private void updateBranchTargets() { - for (Iterator i = branches.iterator(); i.hasNext();) { + for (Iterator i = branches.iterator(); i.hasNext();) { BranchInstruction bi = (BranchInstruction) i.next(); BranchHandle bh = (BranchHandle) branch_map.get(bi); int pos = bh.getPosition(); diff --git a/src/org/apache/bcel/util/Class2HTML.java b/src/org/apache/bcel/util/Class2HTML.java deleted file mode 100644 index 8439249..0000000 --- a/src/org/apache/bcel/util/Class2HTML.java +++ /dev/null @@ -1,231 +0,0 @@ -/* - * Copyright 2000-2004 The Apache Software Foundation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ -package org.apache.bcel.util; - -import java.io.File; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.PrintWriter; -import org.apache.bcel.Constants; -import org.apache.bcel.classfile.Attribute; -import org.apache.bcel.classfile.ClassParser; -import org.apache.bcel.classfile.ConstantPool; -import org.apache.bcel.classfile.JavaClass; -import org.apache.bcel.classfile.Method; -import org.apache.bcel.classfile.Utility; - -/** - * Read class file(s) and convert them into HTML files. - * - * Given a JavaClass object "class" that is in package "package" five files - * will be created in the specified directory. - * - *

    - *
  1. "package"."class".html as the main file which defines the frames for - * the following subfiles. - *
  2. "package"."class"_attributes.html contains all (known) attributes found in the file - *
  3. "package"."class"_cp.html contains the constant pool - *
  4. "package"."class"_code.html contains the byte code - *
  5. "package"."class"_methods.html contains references to all methods and fields of the class - *
- * - * All subfiles reference each other appropiately, e.g. clicking on a - * method in the Method's frame will jump to the appropiate method in - * the Code frame. - * - * @version $Id: Class2HTML.java 386056 2006-03-15 11:31:56Z tcurdt $ - * @author M. Dahm - */ -public class Class2HTML implements Constants { - - private JavaClass java_class; // current class object - private String dir; - private static String class_package; // name of package, unclean to make it static, but ... - private static String class_name; // name of current class, dito - private static ConstantPool constant_pool; - - - /** - * Write contents of the given JavaClass into HTML files. - * - * @param java_class The class to write - * @param dir The directory to put the files in - */ - public Class2HTML(JavaClass java_class, String dir) throws IOException { - Method[] methods = java_class.getMethods(); - this.java_class = java_class; - this.dir = dir; - class_name = java_class.getClassName(); // Remember full name - constant_pool = java_class.getConstantPool(); - // Get package name by tacking off everything after the last `.' - int index = class_name.lastIndexOf('.'); - if (index > -1) { - class_package = class_name.substring(0, index); - } else { - class_package = ""; // default package - } - ConstantHTML constant_html = new ConstantHTML(dir, class_name, class_package, methods, - constant_pool); - /* Attributes can't be written in one step, so we just open a file - * which will be written consequently. - */ - AttributeHTML attribute_html = new AttributeHTML(dir, class_name, constant_pool, - constant_html); - MethodHTML method_html = new MethodHTML(dir, class_name, methods, java_class.getFields(), - constant_html, attribute_html); - // Write main file (with frames, yuk) - writeMainHTML(attribute_html); - new CodeHTML(dir, class_name, methods, constant_pool, constant_html); - attribute_html.close(); - } - - - public static void main( String argv[] ) { - String[] file_name = new String[argv.length]; - int files = 0; - ClassParser parser = null; - JavaClass java_class = null; - String zip_file = null; - char sep = System.getProperty("file.separator").toCharArray()[0]; - String dir = "." + sep; // Where to store HTML files - try { - /* Parse command line arguments. - */ - for (int i = 0; i < argv.length; i++) { - if (argv[i].charAt(0) == '-') { // command line switch - if (argv[i].equals("-d")) { // Specify target directory, default `. - dir = argv[++i]; - if (!dir.endsWith("" + sep)) { - dir = dir + sep; - } - new File(dir).mkdirs(); // Create target directory if necessary - } else if (argv[i].equals("-zip")) { - zip_file = argv[++i]; - } else { - System.out.println("Unknown option " + argv[i]); - } - } else { - file_name[files++] = argv[i]; - } - } - if (files == 0) { - System.err.println("Class2HTML: No input files specified."); - } else { // Loop through files ... - for (int i = 0; i < files; i++) { - System.out.print("Processing " + file_name[i] + "..."); - if (zip_file == null) { - parser = new ClassParser(file_name[i]); // Create parser object from file - } else { - parser = new ClassParser(zip_file, file_name[i]); // Create parser object from zip file - } - java_class = parser.parse(); - new Class2HTML(java_class, dir); - System.out.println("Done."); - } - } - } catch (Exception e) { - System.out.println(e); - e.printStackTrace(System.out); - } - } - - - /** - * Utility method that converts a class reference in the constant pool, - * i.e., an index to a string. - */ - static String referenceClass( int index ) { - String str = constant_pool.getConstantString(index, CONSTANT_Class); - str = Utility.compactClassName(str); - str = Utility.compactClassName(str, class_package + ".", true); - return "" + str - + ""; - } - - - static final String referenceType( String type ) { - String short_type = Utility.compactClassName(type); - short_type = Utility.compactClassName(short_type, class_package + ".", true); - int index = type.indexOf('['); // Type is an array? - String base_type = type; - if (index > -1) { - base_type = type.substring(0, index); // Tack of the `[' - } - // test for basic type - if (base_type.equals("int") || base_type.equals("short") || base_type.equals("boolean") - || base_type.equals("void") || base_type.equals("char") || base_type.equals("byte") - || base_type.equals("long") || base_type.equals("double") - || base_type.equals("float")) { - return "" + type + ""; - } else { - return "" + short_type + ""; - } - } - - - static String toHTML( String str ) { - StringBuffer buf = new StringBuffer(); - try { // Filter any characters HTML doesn't like such as < and > in particular - for (int i = 0; i < str.length(); i++) { - char ch; - switch (ch = str.charAt(i)) { - case '<': - buf.append("<"); - break; - case '>': - buf.append(">"); - break; - case '\n': - buf.append("\\n"); - break; - case '\r': - buf.append("\\r"); - break; - default: - buf.append(ch); - } - } - } catch (StringIndexOutOfBoundsException e) { - } // Never occurs - return buf.toString(); - } - - - private void writeMainHTML( AttributeHTML attribute_html ) throws IOException { - PrintWriter file = new PrintWriter(new FileOutputStream(dir + class_name + ".html")); - Attribute[] attributes = java_class.getAttributes(); - file.println("\n" + "Documentation for " + class_name + "" - + "\n" + "\n" - + "\n" + "\n" - + "\n" + "\n" - + "\n" + "\n" - + "\n" - + ""); - file.close(); - for (int i = 0; i < attributes.length; i++) { - attribute_html.writeAttribute(attributes[i], "class" + i); - } - } -} diff --git a/src/org/apache/bcel/util/ClassLoader.java b/src/org/apache/bcel/util/ClassLoader.java deleted file mode 100644 index 13bc041..0000000 --- a/src/org/apache/bcel/util/ClassLoader.java +++ /dev/null @@ -1,184 +0,0 @@ -/* - * Copyright 2000-2004 The Apache Software Foundation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ -package org.apache.bcel.util; - -import java.io.ByteArrayInputStream; -import java.util.Hashtable; -import org.apache.bcel.Constants; -import org.apache.bcel.classfile.ClassParser; -import org.apache.bcel.classfile.ConstantClass; -import org.apache.bcel.classfile.ConstantPool; -import org.apache.bcel.classfile.ConstantUtf8; -import org.apache.bcel.classfile.JavaClass; -import org.apache.bcel.classfile.Utility; - -/** - *

Drop in replacement for the standard class loader of the JVM. You can use it - * in conjunction with the JavaWrapper to dynamically modify/create classes - * as they're requested.

- * - *

This class loader recognizes special requests in a distinct - * format, i.e., when the name of the requested class contains with - * "$$BCEL$$" it calls the createClass() method with that name - * (everything bevor the $$BCEL$$ is considered to be the package - * name. You can subclass the class loader and override that - * method. "Normal" classes class can be modified by overriding the - * modifyClass() method which is called just before defineClass().

- * - *

There may be a number of packages where you have to use the - * default class loader (which may also be faster). You can define the - * set of packages where to use the system class loader in the - * constructor. The default value contains "java.", "sun.", - * "javax."

- * - * @version $Id: ClassLoader.java 386056 2006-03-15 11:31:56Z tcurdt $ - * @author M. Dahm - * @see JavaWrapper - * @see ClassPath - */ -public class ClassLoader extends java.lang.ClassLoader { - - public static final String[] DEFAULT_IGNORED_PACKAGES = { - "java.", "javax.", "sun." - }; - private Hashtable classes = new Hashtable(); // Hashtable is synchronized thus thread-safe - private String[] ignored_packages; - private Repository repository = SyntheticRepository.getInstance(); - - - /** Ignored packages are by default ( "java.", "sun.", - * "javax."), i.e. loaded by system class loader - */ - public ClassLoader() { - this(DEFAULT_IGNORED_PACKAGES); - } - - - /** @param deferTo delegate class loader to use for ignored packages - */ - public ClassLoader(java.lang.ClassLoader deferTo) { - super(deferTo); - this.ignored_packages = DEFAULT_IGNORED_PACKAGES; - this.repository = new ClassLoaderRepository(deferTo); - } - - - /** @param ignored_packages classes contained in these packages will be loaded - * with the system class loader - */ - public ClassLoader(String[] ignored_packages) { - this.ignored_packages = ignored_packages; - } - - - /** @param ignored_packages classes contained in these packages will be loaded - * with the system class loader - * @param deferTo delegate class loader to use for ignored packages - */ - public ClassLoader(java.lang.ClassLoader deferTo, String[] ignored_packages) { - this(ignored_packages); - this.repository = new ClassLoaderRepository(deferTo); - } - - - protected Class loadClass( String class_name, boolean resolve ) throws ClassNotFoundException { - Class cl = null; - /* First try: lookup hash table. - */ - if ((cl = (Class) classes.get(class_name)) == null) { - /* Second try: Load system class using system class loader. You better - * don't mess around with them. - */ - for (int i = 0; i < ignored_packages.length; i++) { - if (class_name.startsWith(ignored_packages[i])) { - cl = getParent().loadClass(class_name); - break; - } - } - if (cl == null) { - JavaClass clazz = null; - /* Third try: Special request? - */ - if (class_name.indexOf("$$BCEL$$") >= 0) { - clazz = createClass(class_name); - } else { // Fourth try: Load classes via repository - if ((clazz = repository.loadClass(class_name)) != null) { - clazz = modifyClass(clazz); - } else { - throw new ClassNotFoundException(class_name); - } - } - if (clazz != null) { - byte[] bytes = clazz.getBytes(); - cl = defineClass(class_name, bytes, 0, bytes.length); - } else { - cl = Class.forName(class_name); - } - } - if (resolve) { - resolveClass(cl); - } - } - classes.put(class_name, cl); - return cl; - } - - - /** Override this method if you want to alter a class before it gets actually - * loaded. Does nothing by default. - */ - protected JavaClass modifyClass( JavaClass clazz ) { - return clazz; - } - - - /** - * Override this method to create you own classes on the fly. The - * name contains the special token $$BCEL$$. Everything before that - * token is consddered to be a package name. You can encode you own - * arguments into the subsequent string. You must regard however not - * to use any "illegal" characters, i.e., characters that may not - * appear in a Java class name too
- * - * The default implementation interprets the string as a encoded compressed - * Java class, unpacks and decodes it with the Utility.decode() method, and - * parses the resulting byte array and returns the resulting JavaClass object. - * - * @param class_name compressed byte code with "$$BCEL$$" in it - */ - protected JavaClass createClass( String class_name ) { - int index = class_name.indexOf("$$BCEL$$"); - String real_name = class_name.substring(index + 8); - JavaClass clazz = null; - try { - byte[] bytes = Utility.decode(real_name, true); - ClassParser parser = new ClassParser(new ByteArrayInputStream(bytes), "foo"); - clazz = parser.parse(); - } catch (Throwable e) { - e.printStackTrace(); - return null; - } - // Adapt the class name to the passed value - ConstantPool cp = clazz.getConstantPool(); - ConstantClass cl = (ConstantClass) cp.getConstant(clazz.getClassNameIndex(), - Constants.CONSTANT_Class); - ConstantUtf8 name = (ConstantUtf8) cp.getConstant(cl.getNameIndex(), - Constants.CONSTANT_Utf8); - name.setBytes(class_name.replace('.', '/')); - return clazz; - } -} diff --git a/src/org/apache/bcel/util/ClassLoaderRepository.java b/src/org/apache/bcel/util/ClassLoaderRepository.java deleted file mode 100644 index 75e8c63..0000000 --- a/src/org/apache/bcel/util/ClassLoaderRepository.java +++ /dev/null @@ -1,121 +0,0 @@ -/* - * Copyright 2000-2004 The Apache Software Foundation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ -package org.apache.bcel.util; - -import java.io.IOException; -import java.io.InputStream; -import java.util.HashMap; -import java.util.Map; -import org.apache.bcel.classfile.ClassParser; -import org.apache.bcel.classfile.JavaClass; - -/** - * The repository maintains information about which classes have - * been loaded. - * - * It loads its data from the ClassLoader implementation - * passed into its constructor. - * - * @see org.apache.bcel.Repository - * - * @version $Id: ClassLoaderRepository.java 386056 2006-03-15 11:31:56Z tcurdt $ - * @author M. Dahm - * @author David Dixon-Peugh - */ -public class ClassLoaderRepository implements Repository { - - private java.lang.ClassLoader loader; - private Map loadedClasses = new HashMap(); // CLASSNAME X JAVACLASS - - - public ClassLoaderRepository(java.lang.ClassLoader loader) { - this.loader = loader; - } - - - /** - * Store a new JavaClass into this Repository. - */ - public void storeClass( JavaClass clazz ) { - loadedClasses.put(clazz.getClassName(), clazz); - clazz.setRepository(this); - } - - - /** - * Remove class from repository - */ - public void removeClass( JavaClass clazz ) { - loadedClasses.remove(clazz.getClassName()); - } - - - /** - * Find an already defined JavaClass. - */ - public JavaClass findClass( String className ) { - if (loadedClasses.containsKey(className)) { - return (JavaClass) loadedClasses.get(className); - } else { - return null; - } - } - - - /** - * Lookup a JavaClass object from the Class Name provided. - */ - public JavaClass loadClass( String className ) throws ClassNotFoundException { - String classFile = className.replace('.', '/'); - JavaClass RC = findClass(className); - if (RC != null) { - return RC; - } - try { - InputStream is = loader.getResourceAsStream(classFile + ".class"); - if (is == null) { - throw new ClassNotFoundException(className + " not found."); - } - ClassParser parser = new ClassParser(is, className); - RC = parser.parse(); - storeClass(RC); - return RC; - } catch (IOException e) { - throw new ClassNotFoundException(e.toString()); - } - } - - - public JavaClass loadClass( Class clazz ) throws ClassNotFoundException { - return loadClass(clazz.getName()); - } - - - /** Clear all entries from cache. - */ - public void clear() { - loadedClasses.clear(); - } - - - /* - * @return null - */ - public ClassPath getClassPath() { - return null; - } -} diff --git a/src/org/apache/bcel/util/ClassPath.java b/src/org/apache/bcel/util/ClassPath.java index 17d4ed1..2950df0 100644 --- a/src/org/apache/bcel/util/ClassPath.java +++ b/src/org/apache/bcel/util/ClassPath.java @@ -40,7 +40,11 @@ import java.util.zip.ZipFile; */ public class ClassPath implements Serializable { - public static final ClassPath SYSTEM_CLASS_PATH = new ClassPath(); + /** + * + */ + private static final long serialVersionUID = 1L; + public static final ClassPath SYSTEM_CLASS_PATH = new ClassPath(); private PathEntry[] paths; private String class_path; @@ -50,7 +54,7 @@ public class ClassPath implements Serializable { */ public ClassPath(String class_path) { this.class_path = class_path; - List vec = new ArrayList(); + List vec = new ArrayList(); for (StringTokenizer tok = new StringTokenizer(class_path, System .getProperty("path.separator")); tok.hasMoreTokens();) { String path = tok.nextToken(); @@ -103,7 +107,7 @@ public class ClassPath implements Serializable { } - private static final void getPathComponents( String path, List list ) { + private static final void getPathComponents( String path, List list ) { if (path != null) { StringTokenizer tok = new StringTokenizer(path, File.pathSeparator); while (tok.hasMoreTokens()) { @@ -126,12 +130,12 @@ public class ClassPath implements Serializable { 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(); + List list = new ArrayList(); getPathComponents(class_path, list); getPathComponents(boot_path, list); - List dirs = new ArrayList(); + List dirs = new ArrayList(); getPathComponents(ext_path, dirs); - for (Iterator e = dirs.iterator(); e.hasNext();) { + for (Iterator e = dirs.iterator(); e.hasNext();) { File ext_dir = new File((String) e.next()); String[] extensions = ext_dir.list(new FilenameFilter() { @@ -147,7 +151,7 @@ public class ClassPath implements Serializable { } } StringBuffer buf = new StringBuffer(); - for (Iterator e = list.iterator(); e.hasNext();) { + for (Iterator e = list.iterator(); e.hasNext();) { buf.append((String) e.next()); if (e.hasNext()) { buf.append(File.pathSeparatorChar); @@ -269,7 +273,12 @@ public class ClassPath implements Serializable { private static abstract class PathEntry implements Serializable { - abstract ClassFile getClassFile( String name, String suffix ) throws IOException; + /** + * + */ + private static final long serialVersionUID = 1L; + + abstract ClassFile getClassFile( String name, String suffix ) throws IOException; } /** Contains information about file/ZIP entry of the Java class. @@ -304,7 +313,11 @@ public class ClassPath implements Serializable { private static class Dir extends PathEntry { - private String dir; + /** + * + */ + private static final long serialVersionUID = 1L; + private String dir; Dir(String d) { @@ -355,7 +368,11 @@ public class ClassPath implements Serializable { private static class Zip extends PathEntry { - private ZipFile zip; + /** + * + */ + private static final long serialVersionUID = 1L; + private ZipFile zip; Zip(ZipFile z) { diff --git a/src/org/apache/bcel/util/ClassQueue.java b/src/org/apache/bcel/util/ClassQueue.java index 64dba0f..04391be 100644 --- a/src/org/apache/bcel/util/ClassQueue.java +++ b/src/org/apache/bcel/util/ClassQueue.java @@ -28,7 +28,11 @@ import org.apache.bcel.classfile.JavaClass; */ public class ClassQueue implements java.io.Serializable { - protected LinkedList vec = new LinkedList(); + /** + * + */ + private static final long serialVersionUID = 1L; + protected LinkedList vec = new LinkedList(); public void enqueue( JavaClass clazz ) { diff --git a/src/org/apache/bcel/util/ClassSet.java b/src/org/apache/bcel/util/ClassSet.java deleted file mode 100644 index 21774fd..0000000 --- a/src/org/apache/bcel/util/ClassSet.java +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Copyright 2000-2004 The Apache Software Foundation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ -package org.apache.bcel.util; - -import java.util.Collection; -import java.util.HashMap; -import java.util.Map; -import org.apache.bcel.classfile.JavaClass; - -/** - * Utility class implementing a (typesafe) set of JavaClass objects. - * Since JavaClass has no equals() method, the name of the class is - * used for comparison. - * - * @version $Id: ClassSet.java 386056 2006-03-15 11:31:56Z tcurdt $ - * @author M. Dahm - * @see ClassStack - */ -public class ClassSet implements java.io.Serializable { - - private Map _map = new HashMap(); - - - 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(); - } - - - 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()]); - } -} diff --git a/src/org/apache/bcel/util/ClassStack.java b/src/org/apache/bcel/util/ClassStack.java deleted file mode 100644 index a6c3411..0000000 --- a/src/org/apache/bcel/util/ClassStack.java +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright 2000-2004 The Apache Software Foundation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ -package org.apache.bcel.util; - -import java.util.Stack; -import org.apache.bcel.classfile.JavaClass; - -/** - * Utility class implementing a (typesafe) stack of JavaClass objects. - * - * @version $Id: ClassStack.java 386056 2006-03-15 11:31:56Z tcurdt $ - * @author M. Dahm - * @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(); - } -} diff --git a/src/org/apache/bcel/util/ClassVector.java b/src/org/apache/bcel/util/ClassVector.java deleted file mode 100644 index 8ac922a..0000000 --- a/src/org/apache/bcel/util/ClassVector.java +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright 2000-2004 The Apache Software Foundation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ -package org.apache.bcel.util; - -import java.util.ArrayList; -import java.util.List; -import org.apache.bcel.classfile.JavaClass; - -/** - * Utility class implementing a (typesafe) collection of JavaClass - * objects. Contains the most important methods of a Vector. - * - * @version $Id: ClassVector.java 386056 2006-03-15 11:31:56Z tcurdt $ - * @author M. Dahm - * - * @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; - } -} diff --git a/src/org/apache/bcel/util/CodeHTML.java b/src/org/apache/bcel/util/CodeHTML.java deleted file mode 100644 index 4b44011..0000000 --- a/src/org/apache/bcel/util/CodeHTML.java +++ /dev/null @@ -1,564 +0,0 @@ -/* - * Copyright 2000-2004 The Apache Software Foundation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * 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; -import java.util.BitSet; -import org.apache.bcel.classfile.Attribute; -import org.apache.bcel.classfile.Code; -import org.apache.bcel.classfile.CodeException; -import org.apache.bcel.classfile.ConstantFieldref; -import org.apache.bcel.classfile.ConstantInterfaceMethodref; -import org.apache.bcel.classfile.ConstantMethodref; -import org.apache.bcel.classfile.ConstantNameAndType; -import org.apache.bcel.classfile.ConstantPool; -import org.apache.bcel.classfile.LocalVariable; -import org.apache.bcel.classfile.LocalVariableTable; -import org.apache.bcel.classfile.Method; -import org.apache.bcel.classfile.Utility; - -/** - * Convert code into HTML file. - * - * @version $Id: CodeHTML.java 386056 2006-03-15 11:31:56Z tcurdt $ - * @author M. Dahm - * - */ -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(""); - for (int i = 0; i < methods.length; i++) { - writeMethod(methods[i], i); - } - file.println(""); - 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("").append(OPCODE_NAMES[opcode]).append(""); - /* 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(""); - // 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(""); - } - buf.append("\n"); - // Print target and default indices in second row - for (int i = 0; i < jump_table.length; i++) { - buf.append(""); - } - buf.append("\n
").append(low + i).append("default
").append(jump_table[i]).append("").append(default_offset).append( - "
\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(""); - // 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(""); - } - buf.append("\n"); - // Print target and default indices in second row - for (int i = 0; i < npairs; i++) { - buf.append(""); - } - buf.append("\n
").append(match).append("default
").append(jump_table[i]).append("").append(default_offset).append( - "
\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("").append(index).append(""); - break; - /* Same for 32-bit wide jumps - */ - case GOTO_W: - case JSR_W: - int windex = bytes.getIndex() + bytes.readInt() - 1; - buf.append("").append(windex).append(""); - 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("").append(TYPE_NAMES[bytes.readByte()]).append( - ""); - 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("").append(field_name) - .append("\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(".").append(str).append( - "").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("").append( - Class2HTML.toHTML(constant_pool.constantToString(index, - constant_pool.getConstant(index).getTag()))).append(""); - break; - case LDC: - index = bytes.readUnsignedByte(); - buf.append("").append( - Class2HTML.toHTML(constant_pool.constantToString(index, - constant_pool.getConstant(index).getTag()))).append(""); - 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(""); - 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. - */ - 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 - } - } - } - - - /** - * 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("

" + access + " " + "" + Class2HTML.referenceType(type) + " " - + html_name + "("); - for (int i = 0; i < args.length; i++) { - file.print(Class2HTML.referenceType(args[i])); - if (i < args.length - 1) { - file.print(", "); - } - } - file.println(")

"); - Code c = null; - byte[] code = null; - if (attributes.length > 0) { - file.print("

Attributes

    \n"); - for (int i = 0; i < attributes.length; i++) { - byte tag = attributes[i].getTag(); - if (tag != ATTR_UNKNOWN) { - file.print("
  • " - + ATTRIBUTE_NAMES[tag] + "
  • \n"); - } else { - file.print("
  • " + attributes[i] + "
  • "); - } - if (tag == ATTR_CODE) { - c = (Code) attributes[i]; - Attribute[] attributes2 = c.getAttributes(); - code = c.getCode(); - file.print("
      "); - for (int j = 0; j < attributes2.length; j++) { - tag = attributes2[j].getTag(); - file.print("
    • " - + ATTRIBUTE_NAMES[tag] + "
    • \n"); - } - file.print("
    "); - } - } - file.println("
"); - } - 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("" - + ""); - 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 = ""; - } - String anchor2; - if (stream.getIndex() == code.length) { - anchor2 = "" + offset - + ""; - } else { - anchor2 = "" + offset; - } - file - .println(""); - } - // Mark last line, may be targetted from Attributes window - file.println(""); - file.println("
Byte
offset
InstructionArgument
" + anchor2 + "" + anchor + str - + "
"); - } - } -} diff --git a/src/org/apache/bcel/util/ConstantHTML.java b/src/org/apache/bcel/util/ConstantHTML.java deleted file mode 100644 index f543bf4..0000000 --- a/src/org/apache/bcel/util/ConstantHTML.java +++ /dev/null @@ -1,234 +0,0 @@ -/* - * Copyright 2000-2004 The Apache Software Foundation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * 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; -import org.apache.bcel.classfile.Constant; -import org.apache.bcel.classfile.ConstantClass; -import org.apache.bcel.classfile.ConstantFieldref; -import org.apache.bcel.classfile.ConstantInterfaceMethodref; -import org.apache.bcel.classfile.ConstantMethodref; -import org.apache.bcel.classfile.ConstantNameAndType; -import org.apache.bcel.classfile.ConstantPool; -import org.apache.bcel.classfile.ConstantString; -import org.apache.bcel.classfile.Method; -import org.apache.bcel.classfile.Utility; - -/** - * Convert constant pool into HTML file. - * - * @version $Id: ConstantHTML.java 386056 2006-03-15 11:31:56Z tcurdt $ - * @author M. Dahm - * - */ -final class ConstantHTML implements org.apache.bcel.Constants { - - private String class_name; // name of current class - private String class_package; // name of package - private ConstantPool constant_pool; // reference to constant pool - private PrintWriter file; // file to write to - private String[] constant_ref; // String to return for cp[i] - private Constant[] constants; // The constants in the cp - private Method[] methods; - - - ConstantHTML(String dir, String class_name, String class_package, Method[] methods, - ConstantPool constant_pool) throws IOException { - this.class_name = class_name; - this.class_package = class_package; - this.constant_pool = constant_pool; - this.methods = methods; - constants = constant_pool.getConstantPool(); - file = new PrintWriter(new FileOutputStream(dir + class_name + "_cp.html")); - constant_ref = new String[constants.length]; - constant_ref[0] = "<unknown>"; - file.println(""); - // Loop through constants, constants[0] is reserved - for (int i = 1; i < constants.length; i++) { - if (i % 2 == 0) { - file.print("\n"); - } - file.println("
"); - } else { - file.print("
"); - } - if (constants[i] != null) { - writeConstant(i); - } - file.print("
"); - file.close(); - } - - - String referenceConstant( int index ) { - return constant_ref[index]; - } - - - private void writeConstant( int index ) { - byte tag = constants[index].getTag(); - int class_index, name_index; - String ref; - // The header is always the same - file.println("

" + index + " " + CONSTANT_NAMES[tag] - + "

"); - /* For every constant type get the needed parameters and print them appropiately - */ - switch (tag) { - case CONSTANT_InterfaceMethodref: - case CONSTANT_Methodref: - // Get class_index and name_and_type_index, depending on type - if (tag == CONSTANT_Methodref) { - ConstantMethodref c = (ConstantMethodref) constant_pool.getConstant(index, - CONSTANT_Methodref); - class_index = c.getClassIndex(); - name_index = c.getNameAndTypeIndex(); - } else { - ConstantInterfaceMethodref c1 = (ConstantInterfaceMethodref) constant_pool - .getConstant(index, CONSTANT_InterfaceMethodref); - class_index = c1.getClassIndex(); - name_index = c1.getNameAndTypeIndex(); - } - // Get method name and its class - String method_name = constant_pool.constantToString(name_index, - CONSTANT_NameAndType); - String html_method_name = Class2HTML.toHTML(method_name); - // Partially compacted class name, i.e., / -> . - String method_class = constant_pool.constantToString(class_index, CONSTANT_Class); - String short_method_class = Utility.compactClassName(method_class); // I.e., remove java.lang. - short_method_class = Utility.compactClassName(method_class); // I.e., remove java.lang. - short_method_class = Utility.compactClassName(short_method_class, class_package - + ".", true); // Remove class package prefix - // Get method signature - ConstantNameAndType c2 = (ConstantNameAndType) constant_pool.getConstant( - name_index, CONSTANT_NameAndType); - String signature = constant_pool.constantToString(c2.getSignatureIndex(), - CONSTANT_Utf8); - // Get array of strings containing the argument types - String[] args = Utility.methodSignatureArgumentTypes(signature, false); - // Get return type string - String type = Utility.methodSignatureReturnType(signature, false); - String ret_type = Class2HTML.referenceType(type); - StringBuffer buf = new StringBuffer("("); - for (int i = 0; i < args.length; i++) { - buf.append(Class2HTML.referenceType(args[i])); - if (i < args.length - 1) { - buf.append(", "); - } - } - buf.append(")"); - String arg_types = buf.toString(); - if (method_class.equals(class_name)) { - ref = "" - + html_method_name + ""; - } else { - ref = "" - + short_method_class + "." + html_method_name; - } - constant_ref[index] = ret_type + " " + short_method_class - + "." + html_method_name + " " + arg_types; - file.println("

" + ret_type + " " + ref + arg_types - + " \n

"); - break; - case CONSTANT_Fieldref: - // Get class_index and name_and_type_index - ConstantFieldref c3 = (ConstantFieldref) constant_pool.getConstant(index, - CONSTANT_Fieldref); - class_index = c3.getClassIndex(); - name_index = c3.getNameAndTypeIndex(); - // Get method name and its class (compacted) - String field_class = constant_pool.constantToString(class_index, CONSTANT_Class); - String short_field_class = Utility.compactClassName(field_class); // I.e., remove java.lang. - short_field_class = Utility.compactClassName(short_field_class, - class_package + ".", true); // Remove class package prefix - String field_name = constant_pool - .constantToString(name_index, CONSTANT_NameAndType); - if (field_class.equals(class_name)) { - ref = "" + field_name + ""; - } else { - ref = "" + short_field_class - + "." + field_name + "\n"; - } - constant_ref[index] = "" + short_field_class + "." - + field_name + ""; - file.println("

" + ref + "
\n" + "

"); - break; - case CONSTANT_Class: - ConstantClass c4 = (ConstantClass) constant_pool.getConstant(index, CONSTANT_Class); - name_index = c4.getNameIndex(); - String class_name2 = constant_pool.constantToString(index, tag); // / -> . - String short_class_name = Utility.compactClassName(class_name2); // I.e., remove java.lang. - short_class_name = Utility.compactClassName(short_class_name, class_package + ".", - true); // Remove class package prefix - ref = "" + short_class_name - + ""; - constant_ref[index] = "" + short_class_name + ""; - file.println("

" + ref + "

\n"); - break; - case CONSTANT_String: - ConstantString c5 = (ConstantString) constant_pool.getConstant(index, - CONSTANT_String); - name_index = c5.getStringIndex(); - String str = Class2HTML.toHTML(constant_pool.constantToString(index, tag)); - file.println("

" + str + "

\n"); - break; - case CONSTANT_NameAndType: - ConstantNameAndType c6 = (ConstantNameAndType) constant_pool.getConstant(index, - CONSTANT_NameAndType); - name_index = c6.getNameIndex(); - int signature_index = c6.getSignatureIndex(); - file.println("

" - + Class2HTML.toHTML(constant_pool.constantToString(index, tag)) - + "

\n"); - break; - default: - file - .println("

" - + Class2HTML.toHTML(constant_pool.constantToString(index, tag)) - + "\n"); - } // switch - } - - - private final int getMethodNumber( String str ) { - for (int i = 0; i < methods.length; i++) { - String cmp = methods[i].getName() + methods[i].getSignature(); - if (cmp.equals(str)) { - return i; - } - } - return -1; - } -} diff --git a/src/org/apache/bcel/util/InstructionFinder.java b/src/org/apache/bcel/util/InstructionFinder.java deleted file mode 100644 index 79982bf..0000000 --- a/src/org/apache/bcel/util/InstructionFinder.java +++ /dev/null @@ -1,472 +0,0 @@ -/* - * Copyright 2000-2004 The Apache Software Foundation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ -package org.apache.bcel.util; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.Iterator; -import java.util.List; -import java.util.Locale; -import java.util.Map; -import java.util.regex.Matcher; -import java.util.regex.Pattern; -import org.apache.bcel.Constants; -import org.apache.bcel.generic.ClassGenException; -import org.apache.bcel.generic.Instruction; -import org.apache.bcel.generic.InstructionHandle; -import org.apache.bcel.generic.InstructionList; - -/** - * InstructionFinder is a tool to search for given instructions patterns, i.e., - * match sequences of instructions in an instruction list via regular - * expressions. This can be used, e.g., in order to implement a peep hole - * optimizer that looks for code patterns and replaces them with faster - * equivalents. - * - *

- * This class internally uses the - * Regexp package to search for regular expressions. - * - * A typical application would look like this: - * - *

- * 
- *  
- *   InstructionFinder f   = new InstructionFinder(il);
- *   String            pat = "IfInstruction ICONST_0 GOTO ICONST_1 NOP (IFEQ|IFNE)";
- *   
- *   for(Iterator i = f.search(pat, constraint); i.hasNext(); ) {
- *   InstructionHandle[] match = (InstructionHandle[])i.next();
- *   ...
- *   il.delete(match[1], match[5]);
- *   ...
- *   }
- *   
- *  
- * 
- * - * @version $Id: InstructionFinder.java 386056 2006-03-15 11:31:56Z tcurdt $ - * @author M. Dahm - * @see Instruction - * @see InstructionList - */ -public class InstructionFinder { - - private static final int OFFSET = 32767; // char + OFFSET is - // outside of - // LATIN-1 - private static final int NO_OPCODES = 256; // Potential number, - // some are not used - private static final Map map = new HashMap(); // Map - private InstructionList il; - private String il_string; // instruction list - // as string - private InstructionHandle[] handles; // map instruction - - - // list to array - /** - * @param il - * instruction list to search for given patterns - */ - public InstructionFinder(InstructionList il) { - this.il = il; - reread(); - } - - - /** - * Reread the instruction list, e.g., after you've altered the list upon a - * match. - */ - public final void reread() { - int size = il.getLength(); - char[] buf = new char[size]; // Create a string with length equal to il - // length - handles = il.getInstructionHandles(); - // Map opcodes to characters - for (int i = 0; i < size; i++) { - buf[i] = makeChar(handles[i].getInstruction().getOpcode()); - } - il_string = new String(buf); - } - - - /** - * Map symbolic instruction names like "getfield" to a single character. - * - * @param pattern - * instruction pattern in lower case - * @return encoded string for a pattern such as "BranchInstruction". - */ - private static final String mapName( String pattern ) { - String result = (String) map.get(pattern); - if (result != null) { - return result; - } - for (short i = 0; i < NO_OPCODES; i++) { - if (pattern.equals(Constants.OPCODE_NAMES[i])) { - return "" + makeChar(i); - } - } - throw new RuntimeException("Instruction unknown: " + pattern); - } - - - /** - * Replace symbolic names of instructions with the appropiate character and - * remove all white space from string. Meta characters such as +, * are - * ignored. - * - * @param pattern - * The pattern to compile - * @return translated regular expression string - */ - private static final String compilePattern( String pattern ) { - //Bug: 38787 - Instructions are assumed to be english, to avoid odd Locale issues - String lower = pattern.toLowerCase(Locale.ENGLISH); - StringBuffer buf = new StringBuffer(); - int size = pattern.length(); - for (int i = 0; i < size; i++) { - char ch = lower.charAt(i); - if (Character.isLetterOrDigit(ch)) { - StringBuffer name = new StringBuffer(); - while ((Character.isLetterOrDigit(ch) || ch == '_') && i < size) { - name.append(ch); - if (++i < size) { - ch = lower.charAt(i); - } else { - break; - } - } - i--; - buf.append(mapName(name.toString())); - } else if (!Character.isWhitespace(ch)) { - buf.append(ch); - } - } - return buf.toString(); - } - - - /** - * @return the matched piece of code as an array of instruction (handles) - */ - private InstructionHandle[] getMatch( int matched_from, int match_length ) { - InstructionHandle[] match = new InstructionHandle[match_length]; - System.arraycopy(handles, matched_from, match, 0, match_length); - return match; - } - - - /** - * Search for the given pattern in the instruction list. You can search for - * any valid opcode via its symbolic name, e.g. "istore". You can also use a - * super class or an interface name to match a whole set of instructions, e.g. - * "BranchInstruction" or "LoadInstruction". "istore" is also an alias for all - * "istore_x" instructions. Additional aliases are "if" for "ifxx", "if_icmp" - * for "if_icmpxx", "if_acmp" for "if_acmpxx". - * - * Consecutive instruction names must be separated by white space which will - * be removed during the compilation of the pattern. - * - * For the rest the usual pattern matching rules for regular expressions - * apply. - *

- * Example pattern: - * - *

-     * search("BranchInstruction NOP ((IfInstruction|GOTO)+ ISTORE Instruction)*");
-     * 
- * - *

- * If you alter the instruction list upon a match such that other matching - * areas are affected, you should call reread() to update the finder and call - * search() again, because the matches are cached. - * - * @param pattern - * the instruction pattern to search for, where case is ignored - * @param from - * where to start the search in the instruction list - * @param constraint - * optional CodeConstraint to check the found code pattern for - * user-defined constraints - * @return iterator of matches where e.nextElement() returns an array of - * instruction handles describing the matched area - */ - public final Iterator search( String pattern, InstructionHandle from, CodeConstraint constraint ) { - String search = compilePattern(pattern); - int start = -1; - for (int i = 0; i < handles.length; i++) { - if (handles[i] == from) { - start = i; // Where to start search from (index) - break; - } - } - if (start == -1) { - throw new ClassGenException("Instruction handle " + from - + " not found in instruction list."); - } - Pattern regex = Pattern.compile(search); - List matches = new ArrayList(); - Matcher matcher = regex.matcher(il_string); - while (start < il_string.length() && matcher.find(start)) { - int startExpr = matcher.start(); - int endExpr = matcher.end(); - int lenExpr = (endExpr - startExpr) + 1; - InstructionHandle[] match = getMatch(startExpr, lenExpr); - if ((constraint == null) || constraint.checkCode(match)) { - matches.add(match); - } - start = endExpr; - } - return matches.iterator(); - } - - - /** - * Start search beginning from the start of the given instruction list. - * - * @param pattern - * the instruction pattern to search for, where case is ignored - * @return iterator of matches where e.nextElement() returns an array of - * instruction handles describing the matched area - */ - public final Iterator search( String pattern ) { - return search(pattern, il.getStart(), null); - } - - - /** - * Start search beginning from `from'. - * - * @param pattern - * the instruction pattern to search for, where case is ignored - * @param from - * where to start the search in the instruction list - * @return iterator of matches where e.nextElement() returns an array of - * instruction handles describing the matched area - */ - public final Iterator search( String pattern, InstructionHandle from ) { - return search(pattern, from, null); - } - - - /** - * Start search beginning from the start of the given instruction list. Check - * found matches with the constraint object. - * - * @param pattern - * the instruction pattern to search for, case is ignored - * @param constraint - * constraints to be checked on matching code - * @return instruction handle or `null' if the match failed - */ - public final Iterator search( String pattern, CodeConstraint constraint ) { - return search(pattern, il.getStart(), constraint); - } - - - /** - * Convert opcode number to char. - */ - private static final char makeChar( short opcode ) { - return (char) (opcode + OFFSET); - } - - - /** - * @return the inquired instruction list - */ - public final InstructionList getInstructionList() { - return il; - } - - /** - * Code patterns found may be checked using an additional user-defined - * constraint object whether they really match the needed criterion. I.e., - * check constraints that can not expressed with regular expressions. - * - */ - public static interface CodeConstraint { - - /** - * @param match - * array of instructions matching the requested pattern - * @return true if the matched area is really useful - */ - public boolean checkCode( InstructionHandle[] match ); - } - - // Initialize pattern map - static { - map - .put( - "arithmeticinstruction", - "(irem|lrem|iand|ior|ineg|isub|lneg|fneg|fmul|ldiv|fadd|lxor|frem|idiv|land|ixor|ishr|fsub|lshl|fdiv|iadd|lor|dmul|lsub|ishl|imul|lmul|lushr|dneg|iushr|lshr|ddiv|drem|dadd|ladd|dsub)"); - map.put("invokeinstruction", "(invokevirtual|invokeinterface|invokestatic|invokespecial)"); - map - .put( - "arrayinstruction", - "(baload|aastore|saload|caload|fastore|lastore|iaload|castore|iastore|aaload|bastore|sastore|faload|laload|daload|dastore)"); - map.put("gotoinstruction", "(goto|goto_w)"); - map.put("conversioninstruction", - "(d2l|l2d|i2s|d2i|l2i|i2b|l2f|d2f|f2i|i2d|i2l|f2d|i2c|f2l|i2f)"); - map.put("localvariableinstruction", - "(fstore|iinc|lload|dstore|dload|iload|aload|astore|istore|fload|lstore)"); - map.put("loadinstruction", "(fload|dload|lload|iload|aload)"); - map.put("fieldinstruction", "(getfield|putstatic|getstatic|putfield)"); - map - .put( - "cpinstruction", - "(ldc2_w|invokeinterface|multianewarray|putstatic|instanceof|getstatic|checkcast|getfield|invokespecial|ldc_w|invokestatic|invokevirtual|putfield|ldc|new|anewarray)"); - map.put("stackinstruction", "(dup2|swap|dup2_x2|pop|pop2|dup|dup2_x1|dup_x2|dup_x1)"); - map - .put( - "branchinstruction", - "(ifle|if_acmpne|if_icmpeq|if_acmpeq|ifnonnull|goto_w|iflt|ifnull|if_icmpne|tableswitch|if_icmple|ifeq|if_icmplt|jsr_w|if_icmpgt|ifgt|jsr|goto|ifne|ifge|lookupswitch|if_icmpge)"); - map.put("returninstruction", "(lreturn|ireturn|freturn|dreturn|areturn|return)"); - map.put("storeinstruction", "(istore|fstore|dstore|astore|lstore)"); - map.put("select", "(tableswitch|lookupswitch)"); - map - .put( - "ifinstruction", - "(ifeq|ifgt|if_icmpne|if_icmpeq|ifge|ifnull|ifne|if_icmple|if_icmpge|if_acmpeq|if_icmplt|if_acmpne|ifnonnull|iflt|if_icmpgt|ifle)"); - map.put("jsrinstruction", "(jsr|jsr_w)"); - map.put("variablelengthinstruction", "(tableswitch|jsr|goto|lookupswitch)"); - map.put("unconditionalbranch", "(goto|jsr|jsr_w|athrow|goto_w)"); - map.put("constantpushinstruction", "(dconst|bipush|sipush|fconst|iconst|lconst)"); - map - .put( - "typedinstruction", - "(imul|lsub|aload|fload|lor|new|aaload|fcmpg|iand|iaload|lrem|idiv|d2l|isub|dcmpg|dastore|ret|f2d|f2i|drem|iinc|i2c|checkcast|frem|lreturn|astore|lushr|daload|dneg|fastore|istore|lshl|ldiv|lstore|areturn|ishr|ldc_w|invokeinterface|aastore|lxor|ishl|l2d|i2f|return|faload|sipush|iushr|caload|instanceof|invokespecial|putfield|fmul|ireturn|laload|d2f|lneg|ixor|i2l|fdiv|lastore|multianewarray|i2b|getstatic|i2d|putstatic|fcmpl|saload|ladd|irem|dload|jsr_w|dconst|dcmpl|fsub|freturn|ldc|aconst_null|castore|lmul|ldc2_w|dadd|iconst|f2l|ddiv|dstore|land|jsr|anewarray|dmul|bipush|dsub|sastore|d2i|i2s|lshr|iadd|l2i|lload|bastore|fstore|fneg|iload|fadd|baload|fconst|ior|ineg|dreturn|l2f|lconst|getfield|invokevirtual|invokestatic|iastore)"); - map.put("popinstruction", "(fstore|dstore|pop|pop2|astore|putstatic|istore|lstore)"); - map.put("allocationinstruction", "(multianewarray|new|anewarray|newarray)"); - map - .put( - "indexedinstruction", - "(lload|lstore|fload|ldc2_w|invokeinterface|multianewarray|astore|dload|putstatic|instanceof|getstatic|checkcast|getfield|invokespecial|dstore|istore|iinc|ldc_w|ret|fstore|invokestatic|iload|putfield|invokevirtual|ldc|new|aload|anewarray)"); - map - .put( - "pushinstruction", - "(dup|lload|dup2|bipush|fload|ldc2_w|sipush|lconst|fconst|dload|getstatic|ldc_w|aconst_null|dconst|iload|ldc|iconst|aload)"); - map - .put( - "stackproducer", - "(imul|lsub|aload|fload|lor|new|aaload|fcmpg|iand|iaload|lrem|idiv|d2l|isub|dcmpg|dup|f2d|f2i|drem|i2c|checkcast|frem|lushr|daload|dneg|lshl|ldiv|ishr|ldc_w|invokeinterface|lxor|ishl|l2d|i2f|faload|sipush|iushr|caload|instanceof|invokespecial|fmul|laload|d2f|lneg|ixor|i2l|fdiv|getstatic|i2b|swap|i2d|dup2|fcmpl|saload|ladd|irem|dload|jsr_w|dconst|dcmpl|fsub|ldc|arraylength|aconst_null|tableswitch|lmul|ldc2_w|iconst|dadd|f2l|ddiv|land|jsr|anewarray|dmul|bipush|dsub|d2i|newarray|i2s|lshr|iadd|lload|l2i|fneg|iload|fadd|baload|fconst|lookupswitch|ior|ineg|lconst|l2f|getfield|invokevirtual|invokestatic)"); - map - .put( - "stackconsumer", - "(imul|lsub|lor|iflt|fcmpg|if_icmpgt|iand|ifeq|if_icmplt|lrem|ifnonnull|idiv|d2l|isub|dcmpg|dastore|if_icmpeq|f2d|f2i|drem|i2c|checkcast|frem|lreturn|astore|lushr|pop2|monitorexit|dneg|fastore|istore|lshl|ldiv|lstore|areturn|if_icmpge|ishr|monitorenter|invokeinterface|aastore|lxor|ishl|l2d|i2f|return|iushr|instanceof|invokespecial|fmul|ireturn|d2f|lneg|ixor|pop|i2l|ifnull|fdiv|lastore|i2b|if_acmpeq|ifge|swap|i2d|putstatic|fcmpl|ladd|irem|dcmpl|fsub|freturn|ifgt|castore|lmul|dadd|f2l|ddiv|dstore|land|if_icmpne|if_acmpne|dmul|dsub|sastore|ifle|d2i|i2s|lshr|iadd|l2i|bastore|fstore|fneg|fadd|ior|ineg|ifne|dreturn|l2f|if_icmple|getfield|invokevirtual|invokestatic|iastore)"); - map - .put( - "exceptionthrower", - "(irem|lrem|laload|putstatic|baload|dastore|areturn|getstatic|ldiv|anewarray|iastore|castore|idiv|saload|lastore|fastore|putfield|lreturn|caload|getfield|return|aastore|freturn|newarray|instanceof|multianewarray|athrow|faload|iaload|aaload|dreturn|monitorenter|checkcast|bastore|arraylength|new|invokevirtual|sastore|ldc_w|ireturn|invokespecial|monitorexit|invokeinterface|ldc|invokestatic|daload)"); - map - .put( - "loadclass", - "(multianewarray|invokeinterface|instanceof|invokespecial|putfield|checkcast|putstatic|invokevirtual|new|getstatic|invokestatic|getfield|anewarray)"); - map - .put( - "instructiontargeter", - "(ifle|if_acmpne|if_icmpeq|if_acmpeq|ifnonnull|goto_w|iflt|ifnull|if_icmpne|tableswitch|if_icmple|ifeq|if_icmplt|jsr_w|if_icmpgt|ifgt|jsr|goto|ifne|ifge|lookupswitch|if_icmpge)"); - // Some aliases - map.put("if_icmp", "(if_icmpne|if_icmpeq|if_icmple|if_icmpge|if_icmplt|if_icmpgt)"); - map.put("if_acmp", "(if_acmpeq|if_acmpne)"); - map.put("if", "(ifeq|ifne|iflt|ifge|ifgt|ifle)"); - // Precompile some aliases first - map.put("iconst", precompile(Constants.ICONST_0, Constants.ICONST_5, Constants.ICONST_M1)); - map.put("lconst", new String(new char[] { - '(', makeChar(Constants.LCONST_0), '|', makeChar(Constants.LCONST_1), ')' - })); - map.put("dconst", new String(new char[] { - '(', makeChar(Constants.DCONST_0), '|', makeChar(Constants.DCONST_1), ')' - })); - map.put("fconst", new String(new char[] { - '(', makeChar(Constants.FCONST_0), '|', makeChar(Constants.FCONST_1), ')' - })); - map.put("iload", precompile(Constants.ILOAD_0, Constants.ILOAD_3, Constants.ILOAD)); - map.put("dload", precompile(Constants.DLOAD_0, Constants.DLOAD_3, Constants.DLOAD)); - map.put("fload", precompile(Constants.FLOAD_0, Constants.FLOAD_3, Constants.FLOAD)); - map.put("aload", precompile(Constants.ALOAD_0, Constants.ALOAD_3, Constants.ALOAD)); - map.put("istore", precompile(Constants.ISTORE_0, Constants.ISTORE_3, Constants.ISTORE)); - map.put("dstore", precompile(Constants.DSTORE_0, Constants.DSTORE_3, Constants.DSTORE)); - map.put("fstore", precompile(Constants.FSTORE_0, Constants.FSTORE_3, Constants.FSTORE)); - map.put("astore", precompile(Constants.ASTORE_0, Constants.ASTORE_3, Constants.ASTORE)); - // Compile strings - for (Iterator i = map.keySet().iterator(); i.hasNext();) { - String key = (String) i.next(); - String value = (String) map.get(key); - char ch = value.charAt(1); // Omit already precompiled patterns - if (ch < OFFSET) { - map.put(key, compilePattern(value)); // precompile all patterns - } - } - // Add instruction alias to match anything - StringBuffer buf = new StringBuffer("("); - for (short i = 0; i < NO_OPCODES; i++) { - if (Constants.NO_OF_OPERANDS[i] != Constants.UNDEFINED) { // Not an - // invalid - // opcode - buf.append(makeChar(i)); - if (i < NO_OPCODES - 1) { - buf.append('|'); - } - } - } - buf.append(')'); - map.put("instruction", buf.toString()); - } - - - private static String precompile( short from, short to, short extra ) { - StringBuffer buf = new StringBuffer("("); - for (short i = from; i <= to; i++) { - buf.append(makeChar(i)); - buf.append('|'); - } - buf.append(makeChar(extra)); - buf.append(")"); - return buf.toString(); - } - - - /* - * Internal debugging routines. - */ - private static final String pattern2string( String pattern ) { - return pattern2string(pattern, true); - } - - - private static final String pattern2string( String pattern, boolean make_string ) { - StringBuffer buf = new StringBuffer(); - for (int i = 0; i < pattern.length(); i++) { - char ch = pattern.charAt(i); - if (ch >= OFFSET) { - if (make_string) { - buf.append(Constants.OPCODE_NAMES[ch - OFFSET]); - } else { - buf.append((ch - OFFSET)); - } - } else { - buf.append(ch); - } - } - return buf.toString(); - } -} diff --git a/src/org/apache/bcel/util/JavaWrapper.java b/src/org/apache/bcel/util/JavaWrapper.java deleted file mode 100644 index fb36b07..0000000 --- a/src/org/apache/bcel/util/JavaWrapper.java +++ /dev/null @@ -1,117 +0,0 @@ -/* - * Copyright 2000-2004 The Apache Software Foundation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ -package org.apache.bcel.util; - -import java.lang.reflect.Method; -import java.lang.reflect.Modifier; - -/** - * Java interpreter replacement, i.e., wrapper that uses its own ClassLoader - * to modify/generate classes as they're requested. You can take this as a template - * for your own applications.
- * Call this wrapper with - *

java org.apache.bcel.util.JavaWrapper <real.class.name> [arguments]
- *

- * To use your own class loader you can set the "bcel.classloader" system property - * which defaults to "org.apache.bcel.util.ClassLoader", e.g., with - *

java org.apache.bcel.util.JavaWrapper -Dbcel.classloader=foo.MyLoader <real.class.name> [arguments]
- *

- * - * @version $Id: JavaWrapper.java 386056 2006-03-15 11:31:56Z tcurdt $ - * @author M. Dahm - * @see ClassLoader - */ -public class JavaWrapper { - - private java.lang.ClassLoader loader; - - - private static java.lang.ClassLoader getClassLoader() { - String s = System.getProperty("bcel.classloader"); - if ((s == null) || "".equals(s)) { - s = "org.apache.bcel.util.ClassLoader"; - } - try { - return (java.lang.ClassLoader) Class.forName(s).newInstance(); - } catch (Exception e) { - throw new RuntimeException(e.toString()); - } - } - - - public JavaWrapper(java.lang.ClassLoader loader) { - this.loader = loader; - } - - - public JavaWrapper() { - this(getClassLoader()); - } - - - /** Runs the main method of the given class with the arguments passed in argv - * - * @param class_name the fully qualified class name - * @param argv the arguments just as you would pass them directly - */ - public void runMain( String class_name, String[] argv ) throws ClassNotFoundException { - Class cl = loader.loadClass(class_name); - Method method = null; - try { - method = cl.getMethod("main", new Class[] { - argv.getClass() - }); - /* Method main is sane ? - */ - int m = method.getModifiers(); - Class r = method.getReturnType(); - if (!(Modifier.isPublic(m) && Modifier.isStatic(m)) || Modifier.isAbstract(m) - || (r != Void.TYPE)) { - throw new NoSuchMethodException(); - } - } catch (NoSuchMethodException no) { - System.out.println("In class " + class_name - + ": public static void main(String[] argv) is not defined"); - return; - } - try { - method.invoke(null, new Object[] { - argv - }); - } catch (Exception ex) { - ex.printStackTrace(); - } - } - - - /** Default main method used as wrapper, expects the fully qualified class name - * of the real class as the first argument. - */ - public static void main( String[] argv ) throws Exception { - /* Expects class name as first argument, other arguments are by-passed. - */ - if (argv.length == 0) { - System.out.println("Missing class name."); - return; - } - String class_name = argv[0]; - String[] new_argv = new String[argv.length - 1]; - System.arraycopy(argv, 1, new_argv, 0, new_argv.length); - JavaWrapper wrapper = new JavaWrapper(); - wrapper.runMain(class_name, new_argv); - } -} diff --git a/src/org/apache/bcel/util/MethodHTML.java b/src/org/apache/bcel/util/MethodHTML.java deleted file mode 100644 index efaa6a1..0000000 --- a/src/org/apache/bcel/util/MethodHTML.java +++ /dev/null @@ -1,156 +0,0 @@ -/* - * Copyright 2000-2004 The Apache Software Foundation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * 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; -import org.apache.bcel.classfile.Attribute; -import org.apache.bcel.classfile.Code; -import org.apache.bcel.classfile.ConstantValue; -import org.apache.bcel.classfile.ExceptionTable; -import org.apache.bcel.classfile.Field; -import org.apache.bcel.classfile.Method; -import org.apache.bcel.classfile.Utility; - -/** - * Convert methods and fields into HTML file. - * - * @version $Id: MethodHTML.java 386056 2006-03-15 11:31:56Z tcurdt $ - * @author M. Dahm - * - */ -final class MethodHTML implements org.apache.bcel.Constants { - - private String class_name; // name of current class - private PrintWriter file; // file to write to - private ConstantHTML constant_html; - private AttributeHTML attribute_html; - - - MethodHTML(String dir, String class_name, Method[] methods, Field[] fields, - ConstantHTML constant_html, AttributeHTML attribute_html) throws IOException { - this.class_name = class_name; - this.attribute_html = attribute_html; - this.constant_html = constant_html; - file = new PrintWriter(new FileOutputStream(dir + class_name + "_methods.html")); - file.println(""); - file.println("" - + ""); - for (int i = 0; i < fields.length; i++) { - writeField(fields[i]); - } - file.println("
Access flagsTypeField name
"); - file.println("" - + "" - + ""); - for (int i = 0; i < methods.length; i++) { - writeMethod(methods[i], i); - } - file.println("
Access flagsReturn typeMethod nameArguments
"); - file.close(); - } - - - /** - * Print field of class. - * - * @param field field to print - * @exception java.io.IOException - */ - private void writeField( Field field ) throws IOException { - String type = Utility.signatureToString(field.getSignature()); - String name = field.getName(); - String access = Utility.accessToString(field.getAccessFlags()); - Attribute[] attributes; - access = Utility.replace(access, " ", " "); - file.print("" + access + "\n" - + Class2HTML.referenceType(type) + "" + name - + ""); - attributes = field.getAttributes(); - // Write them to the Attributes.html file with anchor "[]" - for (int i = 0; i < attributes.length; i++) { - attribute_html.writeAttribute(attributes[i], name + "@" + i); - } - for (int i = 0; i < attributes.length; i++) { - if (attributes[i].getTag() == ATTR_CONSTANT_VALUE) { // Default value - String str = ((ConstantValue) attributes[i]).toString(); - // Reference attribute in _attributes.html - file.print("= " + str + "\n"); - break; - } - } - file.println(""); - } - - - private final 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(), html_name; - // Get method's access flags - String access = Utility.accessToString(method.getAccessFlags()); - // Get the method's attributes, the Code Attribute in particular - Attribute[] attributes = method.getAttributes(); - /* HTML doesn't like names like and spaces are places to break - * lines. Both we don't want... - */ - access = Utility.replace(access, " ", " "); - html_name = Class2HTML.toHTML(name); - file.print("" + access + ""); - file.print("" + Class2HTML.referenceType(type) + "" + "" + html_name - + "\n("); - for (int i = 0; i < args.length; i++) { - file.print(Class2HTML.referenceType(args[i])); - if (i < args.length - 1) { - file.print(", "); - } - } - file.print(")"); - // Check for thrown exceptions - for (int i = 0; i < attributes.length; i++) { - attribute_html.writeAttribute(attributes[i], "method" + method_number + "@" + i, - method_number); - byte tag = attributes[i].getTag(); - if (tag == ATTR_EXCEPTIONS) { - file.print("throws"); - int[] exceptions = ((ExceptionTable) attributes[i]).getExceptionIndexTable(); - for (int j = 0; j < exceptions.length; j++) { - file.print(constant_html.referenceConstant(exceptions[j])); - if (j < exceptions.length - 1) { - file.print(", "); - } - } - file.println(""); - } else if (tag == ATTR_CODE) { - Attribute[] c_a = ((Code) attributes[i]).getAttributes(); - for (int j = 0; j < c_a.length; j++) { - attribute_html.writeAttribute(c_a[j], "method" + method_number + "@" + i + "@" - + j, method_number); - } - } - } - } -} diff --git a/src/org/apache/bcel/util/Repository.java b/src/org/apache/bcel/util/Repository.java index 868cf07..306fe35 100644 --- a/src/org/apache/bcel/util/Repository.java +++ b/src/org/apache/bcel/util/Repository.java @@ -59,7 +59,7 @@ public interface Repository extends java.io.Serializable { /** * Find the JavaClass instance for the given run-time class object */ - public JavaClass loadClass( Class clazz ) throws java.lang.ClassNotFoundException; + public JavaClass loadClass( Class clazz ) throws java.lang.ClassNotFoundException; /** Clear all entries from cache. diff --git a/src/org/apache/bcel/util/SyntheticRepository.java b/src/org/apache/bcel/util/SyntheticRepository.java index 65b2a51..b0da8b2 100644 --- a/src/org/apache/bcel/util/SyntheticRepository.java +++ b/src/org/apache/bcel/util/SyntheticRepository.java @@ -21,6 +21,7 @@ import java.io.InputStream; import java.lang.ref.SoftReference; import java.util.HashMap; import java.util.Map; + import org.apache.bcel.classfile.ClassParser; import org.apache.bcel.classfile.JavaClass; @@ -47,10 +48,13 @@ import org.apache.bcel.classfile.JavaClass; */ public class SyntheticRepository implements Repository { - private static final String DEFAULT_PATH = ClassPath.getClassPath(); - private static Map _instances = new HashMap(); // CLASSPATH X REPOSITORY + /** + * + */ + private static final long serialVersionUID = 1L; + private static Map _instances = new HashMap(); // CLASSPATH X REPOSITORY private ClassPath _path = null; - private Map _loadedClasses = new HashMap(); // CLASSNAME X JAVACLASS + private Map> _loadedClasses = new HashMap>(); // CLASSNAME X JAVACLASS private SyntheticRepository(ClassPath path) { @@ -77,7 +81,7 @@ public class SyntheticRepository implements Repository { * Store a new JavaClass instance into this Repository. */ public void storeClass( JavaClass clazz ) { - _loadedClasses.put(clazz.getClassName(), new SoftReference(clazz)); + _loadedClasses.put(clazz.getClassName(), new SoftReference(clazz)); clazz.setRepository(this); } @@ -94,7 +98,7 @@ public class SyntheticRepository implements Repository { * Find an already defined (cached) JavaClass object by name. */ public JavaClass findClass( String className ) { - SoftReference ref = (SoftReference) _loadedClasses.get(className); + SoftReference ref = (SoftReference) _loadedClasses.get(className); if (ref == null) { return null; } @@ -144,7 +148,7 @@ public class SyntheticRepository implements Repository { * @throws ClassNotFoundException if the class is not in the * Repository, and its representation could not be found */ - public JavaClass loadClass( Class clazz ) throws ClassNotFoundException { + public JavaClass loadClass( Class clazz ) throws ClassNotFoundException { String className = clazz.getName(); JavaClass repositoryClass = findClass(className); if (repositoryClass != null) { diff --git a/src/org/apache/bcel/verifier/GraphicalVerifier.java b/src/org/apache/bcel/verifier/GraphicalVerifier.java deleted file mode 100644 index dceaeba..0000000 --- a/src/org/apache/bcel/verifier/GraphicalVerifier.java +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Copyright 2000-2004 The Apache Software Foundation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ -package org.apache.bcel.verifier; - -import java.awt.Dimension; -import java.awt.Toolkit; -import javax.swing.UIManager; -import org.apache.bcel.generic.Type; - -/** - * A graphical user interface application demonstrating JustIce. - * - * @version $Id: GraphicalVerifier.java 386056 2006-03-15 11:31:56Z tcurdt $ - * @author Enver Haase - */ -public class GraphicalVerifier { - - boolean packFrame = false; - - - /** Constructor. */ - public GraphicalVerifier() { - VerifierAppFrame frame = new VerifierAppFrame(); - if (packFrame) { - frame.pack(); - } else { - frame.validate(); - } - //Das Fenster zentrieren - Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize(); - Dimension frameSize = frame.getSize(); - if (frameSize.height > screenSize.height) { - frameSize.height = screenSize.height; - } - if (frameSize.width > screenSize.width) { - frameSize.width = screenSize.width; - } - frame.setLocation((screenSize.width - frameSize.width) / 2, - (screenSize.height - frameSize.height) / 2); - frame.setVisible(true); - frame.classNamesJList.setModel(new VerifierFactoryListModel()); - VerifierFactory.getVerifier(Type.OBJECT.getClassName()); // Fill list with java.lang.Object - frame.classNamesJList.setSelectedIndex(0); // default, will verify java.lang.Object - } - - - /** Main method. */ - public static void main( String[] args ) { - try { - UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); - } catch (Exception e) { - e.printStackTrace(); - } - new GraphicalVerifier(); - } -} diff --git a/src/org/apache/bcel/verifier/NativeVerifier.java b/src/org/apache/bcel/verifier/NativeVerifier.java deleted file mode 100644 index 9870656..0000000 --- a/src/org/apache/bcel/verifier/NativeVerifier.java +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Copyright 2000-2004 The Apache Software Foundation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ -package org.apache.bcel.verifier; - -/** - * The NativeVerifier class implements a main(String[] args) method that's - * roughly compatible to the one in the Verifier class, but that uses the - * JVM's internal verifier for its class file verification. - * This can be used for comparison runs between the JVM-internal verifier - * and JustIce. - * - * @version $Id: NativeVerifier.java 386056 2006-03-15 11:31:56Z tcurdt $ - * @author Enver Haase - */ -public abstract class NativeVerifier { - - /** - * This class must not be instantiated. - */ - private NativeVerifier() { - } - - - /** - * Works only on the first argument. - */ - public static void main( String[] args ) { - if (args.length != 1) { - System.out.println("Verifier front-end: need exactly one argument."); - System.exit(1); - } - int dotclasspos = args[0].lastIndexOf(".class"); - if (dotclasspos != -1) { - args[0] = args[0].substring(0, dotclasspos); - } - args[0] = args[0].replace('/', '.'); - //System.out.println(args[0]); - try { - Class.forName(args[0]); - } catch (ExceptionInInitializerError eiie) { //subclass of LinkageError! - System.out.println("NativeVerifier: ExceptionInInitializerError encountered on '" - + args[0] + "'."); - System.out.println(eiie); - System.exit(1); - } catch (LinkageError le) { - System.out.println("NativeVerifier: LinkageError encountered on '" + args[0] + "'."); - System.out.println(le); - System.exit(1); - } catch (ClassNotFoundException cnfe) { - System.out.println("NativeVerifier: FILE NOT FOUND: '" + args[0] + "'."); - System.exit(1); - } catch (Throwable t) { - System.out.println("NativeVerifier: Unspecified verification error on'" + args[0] - + "'."); - System.exit(1); - } - System.out.println("NativeVerifier: Class file '" + args[0] + "' seems to be okay."); - System.exit(0); - } -} diff --git a/src/org/apache/bcel/verifier/PassVerifier.java b/src/org/apache/bcel/verifier/PassVerifier.java deleted file mode 100644 index b47e5fc..0000000 --- a/src/org/apache/bcel/verifier/PassVerifier.java +++ /dev/null @@ -1,105 +0,0 @@ -/* - * Copyright 2000-2004 The Apache Software Foundation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ -package org.apache.bcel.verifier; - -import java.util.ArrayList; -import java.util.List; - -/** - * A PassVerifier actually verifies a class file; it is instantiated - * by a Verifier. - * The verification should conform with a certain pass as described - * in The Java Virtual Machine Specification, 2nd edition. - * This book describes four passes. Pass one means loading the - * class and verifying a few static constraints. Pass two actually - * verifies some other constraints that could enforce loading in - * referenced class files. Pass three is the first pass that actually - * checks constraints in the code array of a method in the class file; - * it has two parts with the first verifying static constraints and - * the second part verifying structural constraints (where a data flow - * analysis is used for). The fourth pass, finally, performs checks - * that can only be done at run-time. - * JustIce does not have a run-time pass, but certain constraints that - * are usually delayed until run-time for performance reasons are also - * checked during the second part of pass three. - * PassVerifier instances perform caching. - * That means, if you really want a new verification run of a certain - * pass you must use a new instance of a given PassVerifier. - * - * @version $Id: PassVerifier.java 386056 2006-03-15 11:31:56Z tcurdt $ - * @author Enver Haase - * @see org.apache.bcel.verifier.Verifier - * @see #verify() - */ -public abstract class PassVerifier { - - /** The (warning) messages. */ - private List messages = new ArrayList(); //Type of elements: String - /** The VerificationResult cache. */ - private VerificationResult verificationResult = null; - - - /** - * This method runs a verification pass conforming to the - * Java Virtual Machine Specification, 2nd edition, on a - * class file. - * PassVerifier instances perform caching; - * i.e. if the verify() method once determined a VerificationResult, - * then this result may be returned after every invocation of this - * method instead of running the verification pass anew; likewise with - * the result of getMessages(). - * - * @see #getMessages() - * @see #addMessage(String) - */ - public VerificationResult verify() { - if (verificationResult == null) { - verificationResult = do_verify(); - } - return verificationResult; - } - - - /** Does the real verification work, uncached. */ - public abstract VerificationResult do_verify(); - - - /** - * This method adds a (warning) message to the message pool of this - * PassVerifier. This method is normally only internally used by - * BCEL's class file verifier "JustIce" and should not be used from - * the outside. - * - * @see #getMessages() - */ - public void addMessage( String message ) { - messages.add(message); - } - - - /** - * Returns the (warning) messages that this PassVerifier accumulated - * during its do_verify()ing work. - * - * @see #addMessage(String) - * @see #do_verify() - */ - public String[] getMessages() { - verify(); // create messages if not already done (cached!) - return (String[]) messages.toArray(new String[messages.size()]); - } -} diff --git a/src/org/apache/bcel/verifier/TransitiveHull.java b/src/org/apache/bcel/verifier/TransitiveHull.java deleted file mode 100644 index db11cc2..0000000 --- a/src/org/apache/bcel/verifier/TransitiveHull.java +++ /dev/null @@ -1,104 +0,0 @@ -/* - * Copyright 2000-2004 The Apache Software Foundation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ -package org.apache.bcel.verifier; - -import org.apache.bcel.Repository; -import org.apache.bcel.classfile.JavaClass; - -/** - * This class has a main method implementing a demonstration program - * of how to use the VerifierFactoryObserver. It transitively verifies - * all class files encountered; this may take up a lot of time and, - * more notably, memory. - * - * @version $Id: TransitiveHull.java 386056 2006-03-15 11:31:56Z tcurdt $ - * @author Enver Haase - */ -public class TransitiveHull implements VerifierFactoryObserver { - - /** Used for indentation. */ - private int indent = 0; - - - /** Not publicly instantiable. */ - private TransitiveHull() { - } - - - /* Implementing VerifierFactoryObserver. */ - public void update( String classname ) { - System.gc(); // avoid swapping if possible. - for (int i = 0; i < indent; i++) { - System.out.print(" "); - } - System.out.println(classname); - indent += 1; - Verifier v = VerifierFactory.getVerifier(classname); - VerificationResult vr; - vr = v.doPass1(); - if (vr != VerificationResult.VR_OK) { - System.out.println("Pass 1:\n" + vr); - } - vr = v.doPass2(); - if (vr != VerificationResult.VR_OK) { - System.out.println("Pass 2:\n" + vr); - } - if (vr == VerificationResult.VR_OK) { - try { - JavaClass jc = Repository.lookupClass(v.getClassName()); - for (int i = 0; i < jc.getMethods().length; i++) { - vr = v.doPass3a(i); - if (vr != VerificationResult.VR_OK) { - System.out.println(v.getClassName() + ", Pass 3a, method " + i + " ['" - + jc.getMethods()[i] + "']:\n" + vr); - } - vr = v.doPass3b(i); - if (vr != VerificationResult.VR_OK) { - System.out.println(v.getClassName() + ", Pass 3b, method " + i + " ['" - + jc.getMethods()[i] + "']:\n" + vr); - } - } - } catch (ClassNotFoundException e) { - System.err.println("Could not find class " + v.getClassName() + " in Repository"); - } - } - indent -= 1; - } - - - /** - * This method implements a demonstration program - * of how to use the VerifierFactoryObserver. It transitively verifies - * all class files encountered; this may take up a lot of time and, - * more notably, memory. - */ - public static void main( String[] args ) { - if (args.length != 1) { - System.out.println("Need exactly one argument: The root class to verify."); - System.exit(1); - } - int dotclasspos = args[0].lastIndexOf(".class"); - if (dotclasspos != -1) { - args[0] = args[0].substring(0, dotclasspos); - } - args[0] = args[0].replace('/', '.'); - TransitiveHull th = new TransitiveHull(); - VerifierFactory.attach(th); - VerifierFactory.getVerifier(args[0]); // the observer is called back and does the actual trick. - VerifierFactory.detach(th); - } -} diff --git a/src/org/apache/bcel/verifier/VerificationResult.java b/src/org/apache/bcel/verifier/VerificationResult.java deleted file mode 100644 index 0643a44..0000000 --- a/src/org/apache/bcel/verifier/VerificationResult.java +++ /dev/null @@ -1,115 +0,0 @@ -/* - * Copyright 2000-2004 The Apache Software Foundation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ -package org.apache.bcel.verifier; - -/** - * A VerificationResult is what a PassVerifier returns - * after verifying. - * - * @version $Id: VerificationResult.java 386056 2006-03-15 11:31:56Z tcurdt $ - * @author Enver Haase - * - */ -public class VerificationResult { - - /** - * Constant to indicate verification has not been tried yet. - * This happens if some earlier verification pass did not return VERIFIED_OK. - */ - public static final int VERIFIED_NOTYET = 0; - /** Constant to indicate verification was passed. */ - public static final int VERIFIED_OK = 1; - /** Constant to indicate verfication failed. */ - public static final int VERIFIED_REJECTED = 2; - /** - * This string is the canonical message for verifications that have not been tried yet. - * This happens if some earlier verification pass did not return VERIFIED_OK. - */ - private static final String VERIFIED_NOTYET_MSG = "Not yet verified."; - /** This string is the canonical message for passed verification passes. */ - private static final String VERIFIED_OK_MSG = "Passed verification."; - /** - * Canonical VerificationResult for not-yet-tried verifications. - * This happens if some earlier verification pass did not return VERIFIED_OK. - */ - public static final VerificationResult VR_NOTYET = new VerificationResult(VERIFIED_NOTYET, - VERIFIED_NOTYET_MSG); - /** Canonical VerificationResult for passed verifications. */ - public static final VerificationResult VR_OK = new VerificationResult(VERIFIED_OK, - VERIFIED_OK_MSG); - /** The numeric status. */ - private int numeric; - /** The detailed message. */ - private String detailMessage; - - - /** The usual constructor. */ - public VerificationResult(int status, String message) { - numeric = status; - detailMessage = message; - } - - - /** Returns one one the VERIFIED_OK, VERIFIED_NOTYET, VERIFIED_REJECTED constants. */ - public int getStatus() { - return numeric; - } - - - /** Returns a detailed message. */ - public String getMessage() { - return detailMessage; - } - - - /** @return a hash code value for the object. - */ - public int hashCode() { - return numeric ^ detailMessage.hashCode(); - } - - - /** - * Returns if two VerificationResult instances are equal. - */ - public boolean equals( Object o ) { - if (!(o instanceof VerificationResult)) { - return false; - } - VerificationResult other = (VerificationResult) o; - return ((other.numeric == this.numeric) && (other.detailMessage.equals(this.detailMessage))); - } - - - /** - * Returns a String representation of the VerificationResult. - */ - public String toString() { - String ret = ""; - if (numeric == VERIFIED_NOTYET) { - ret = "VERIFIED_NOTYET"; - } - if (numeric == VERIFIED_OK) { - ret = "VERIFIED_OK"; - } - if (numeric == VERIFIED_REJECTED) { - ret = "VERIFIED_REJECTED"; - } - ret += "\n" + detailMessage + "\n"; - return ret; - } -} diff --git a/src/org/apache/bcel/verifier/Verifier.java b/src/org/apache/bcel/verifier/Verifier.java deleted file mode 100644 index 89b2ef8..0000000 --- a/src/org/apache/bcel/verifier/Verifier.java +++ /dev/null @@ -1,248 +0,0 @@ -/* - * Copyright 2000-2004 The Apache Software Foundation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ -package org.apache.bcel.verifier; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.Iterator; -import java.util.Map; -import org.apache.bcel.classfile.JavaClass; -import org.apache.bcel.verifier.statics.Pass1Verifier; -import org.apache.bcel.verifier.statics.Pass2Verifier; -import org.apache.bcel.verifier.statics.Pass3aVerifier; -import org.apache.bcel.verifier.structurals.Pass3bVerifier; - -/** - * A Verifier instance is there to verify a class file according to The Java Virtual - * Machine Specification, 2nd Edition. - * - * Pass-3b-verification includes pass-3a-verification; - * pass-3a-verification includes pass-2-verification; - * pass-2-verification includes pass-1-verification. - * - * A Verifier creates PassVerifier instances to perform the actual verification. - * Verifier instances are usually generated by the VerifierFactory. - * - * @version $Id: Verifier.java 386056 2006-03-15 11:31:56Z tcurdt $ - * @author Enver Haase - * @see org.apache.bcel.verifier.VerifierFactory - * @see org.apache.bcel.verifier.PassVerifier - */ -public class Verifier { - - /** - * The name of the class this verifier operates on. - */ - private final String classname; - /** A Pass1Verifier for this Verifier instance. */ - private Pass1Verifier p1v; - /** A Pass2Verifier for this Verifier instance. */ - private Pass2Verifier p2v; - /** The Pass3aVerifiers for this Verifier instance. Key: Interned string specifying the method number. */ - private Map p3avs = new HashMap(); - /** The Pass3bVerifiers for this Verifier instance. Key: Interned string specifying the method number. */ - private Map p3bvs = new HashMap(); - - - /** Returns the VerificationResult for the given pass. */ - public VerificationResult doPass1() { - if (p1v == null) { - p1v = new Pass1Verifier(this); - } - return p1v.verify(); - } - - - /** Returns the VerificationResult for the given pass. */ - public VerificationResult doPass2() { - if (p2v == null) { - p2v = new Pass2Verifier(this); - } - return p2v.verify(); - } - - - /** Returns the VerificationResult for the given pass. */ - public VerificationResult doPass3a( int method_no ) { - String key = Integer.toString(method_no); - Pass3aVerifier p3av; - p3av = (Pass3aVerifier) (p3avs.get(key)); - if (p3avs.get(key) == null) { - p3av = new Pass3aVerifier(this, method_no); - p3avs.put(key, p3av); - } - return p3av.verify(); - } - - - /** Returns the VerificationResult for the given pass. */ - public VerificationResult doPass3b( int method_no ) { - String key = Integer.toString(method_no); - Pass3bVerifier p3bv; - p3bv = (Pass3bVerifier) (p3bvs.get(key)); - if (p3bvs.get(key) == null) { - p3bv = new Pass3bVerifier(this, method_no); - p3bvs.put(key, p3bv); - } - return p3bv.verify(); - } - - - /** - * Instantiation is done by the VerifierFactory. - * - * @see VerifierFactory - */ - Verifier(String fully_qualified_classname) { - classname = fully_qualified_classname; - flush(); - } - - - /** - * Returns the name of the class this verifier operates on. - * This is particularly interesting when this verifier was created - * recursively by another Verifier and you got a reference to this - * Verifier by the getVerifiers() method of the VerifierFactory. - * @see VerifierFactory - */ - public final String getClassName() { - return classname; - } - - - /** - * Forget everything known about the class file; that means, really - * start a new verification of a possibly different class file from - * BCEL's repository. - * - */ - public void flush() { - p1v = null; - p2v = null; - p3avs.clear(); - p3bvs.clear(); - } - - - /** - * This returns all the (warning) messages collected during verification. - * A prefix shows from which verifying pass a message originates. - */ - public String[] getMessages() throws ClassNotFoundException { - ArrayList messages = new ArrayList(); - if (p1v != null) { - String[] p1m = p1v.getMessages(); - for (int i = 0; i < p1m.length; i++) { - messages.add("Pass 1: " + p1m[i]); - } - } - if (p2v != null) { - String[] p2m = p2v.getMessages(); - for (int i = 0; i < p2m.length; i++) { - messages.add("Pass 2: " + p2m[i]); - } - } - Iterator p3as = p3avs.values().iterator(); - while (p3as.hasNext()) { - Pass3aVerifier pv = (Pass3aVerifier) p3as.next(); - String[] p3am = pv.getMessages(); - int meth = pv.getMethodNo(); - for (int i = 0; i < p3am.length; i++) { - messages.add("Pass 3a, method " + meth + " ('" - + org.apache.bcel.Repository.lookupClass(classname).getMethods()[meth] - + "'): " + p3am[i]); - } - } - Iterator p3bs = p3bvs.values().iterator(); - while (p3bs.hasNext()) { - Pass3bVerifier pv = (Pass3bVerifier) p3bs.next(); - String[] p3bm = pv.getMessages(); - int meth = pv.getMethodNo(); - for (int i = 0; i < p3bm.length; i++) { - messages.add("Pass 3b, method " + meth + " ('" - + org.apache.bcel.Repository.lookupClass(classname).getMethods()[meth] - + "'): " + p3bm[i]); - } - } - String[] ret = new String[messages.size()]; - for (int i = 0; i < messages.size(); i++) { - ret[i] = (String) messages.get(i); - } - return ret; - } - - - /** - * Verifies class files. - * This is a simple demonstration of how the API of BCEL's - * class file verifier "JustIce" may be used. - * You should supply command-line arguments which are - * fully qualified namea of the classes to verify. These class files - * must be somewhere in your CLASSPATH (refer to Sun's - * documentation for questions about this) or you must have put the classes - * into the BCEL Repository yourself (via 'addClass(JavaClass)'). - */ - public static void main( String[] args ) { - System.out - .println("JustIce by Enver Haase, (C) 2001-2002.\n\n\n"); - for (int k = 0; k < args.length; k++) { - try { - if (args[k].endsWith(".class")) { - int dotclasspos = args[k].lastIndexOf(".class"); - if (dotclasspos != -1) { - args[k] = args[k].substring(0, dotclasspos); - } - } - args[k] = args[k].replace('/', '.'); - System.out.println("Now verifying: " + args[k] + "\n"); - Verifier v = VerifierFactory.getVerifier(args[k]); - VerificationResult vr; - vr = v.doPass1(); - System.out.println("Pass 1:\n" + vr); - vr = v.doPass2(); - System.out.println("Pass 2:\n" + vr); - if (vr == VerificationResult.VR_OK) { - JavaClass jc = org.apache.bcel.Repository.lookupClass(args[k]); - for (int i = 0; i < jc.getMethods().length; i++) { - vr = v.doPass3a(i); - System.out.println("Pass 3a, method number " + i + " ['" - + jc.getMethods()[i] + "']:\n" + vr); - vr = v.doPass3b(i); - System.out.println("Pass 3b, method number " + i + " ['" - + jc.getMethods()[i] + "']:\n" + vr); - } - } - System.out.println("Warnings:"); - String[] warnings = v.getMessages(); - if (warnings.length == 0) { - System.out.println(""); - } - for (int j = 0; j < warnings.length; j++) { - System.out.println(warnings[j]); - } - System.out.println("\n"); - // avoid swapping. - v.flush(); - org.apache.bcel.Repository.clearCache(); - System.gc(); - } catch (ClassNotFoundException e) { - e.printStackTrace(); - } - } - } -} diff --git a/src/org/apache/bcel/verifier/VerifierAppFrame.java b/src/org/apache/bcel/verifier/VerifierAppFrame.java deleted file mode 100644 index b9bd55c..0000000 --- a/src/org/apache/bcel/verifier/VerifierAppFrame.java +++ /dev/null @@ -1,396 +0,0 @@ -/* - * Copyright 2000-2004 The Apache Software Foundation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ -package org.apache.bcel.verifier; - -import java.awt.AWTEvent; -import java.awt.CardLayout; -import java.awt.Color; -import java.awt.Dimension; -import java.awt.GridLayout; -import java.awt.event.ActionEvent; -import java.awt.event.WindowEvent; -import javax.swing.BorderFactory; -import javax.swing.JFrame; -import javax.swing.JList; -import javax.swing.JMenu; -import javax.swing.JMenuBar; -import javax.swing.JMenuItem; -import javax.swing.JOptionPane; -import javax.swing.JPanel; -import javax.swing.JScrollPane; -import javax.swing.JSplitPane; -import javax.swing.JTextPane; -import javax.swing.ListSelectionModel; -import javax.swing.event.ListSelectionEvent; -import org.apache.bcel.Repository; -import org.apache.bcel.classfile.JavaClass; - -/** - * This class implements a machine-generated frame for use with - * the GraphicalVerfifier. - * - * @version $Id: VerifierAppFrame.java 386056 2006-03-15 11:31:56Z tcurdt $ - * @author Enver Haase - * @see GraphicalVerifier - */ -public class VerifierAppFrame extends JFrame { - - JPanel contentPane; - JSplitPane jSplitPane1 = new JSplitPane(); - JPanel jPanel1 = new JPanel(); - JPanel jPanel2 = new JPanel(); - JSplitPane jSplitPane2 = new JSplitPane(); - JPanel jPanel3 = new JPanel(); - JList classNamesJList = new JList(); - GridLayout gridLayout1 = new GridLayout(); - JPanel messagesPanel = new JPanel(); - GridLayout gridLayout2 = new GridLayout(); - JMenuBar jMenuBar1 = new JMenuBar(); - JMenu jMenu1 = new JMenu(); - JScrollPane jScrollPane1 = new JScrollPane(); - JScrollPane messagesScrollPane = new JScrollPane(); - JScrollPane jScrollPane3 = new JScrollPane(); - GridLayout gridLayout4 = new GridLayout(); - JScrollPane jScrollPane4 = new JScrollPane(); - CardLayout cardLayout1 = new CardLayout(); - private String JUSTICE_VERSION = "JustIce by Enver Haase"; - private String current_class; - GridLayout gridLayout3 = new GridLayout(); - JTextPane pass1TextPane = new JTextPane(); - JTextPane pass2TextPane = new JTextPane(); - JTextPane messagesTextPane = new JTextPane(); - JMenuItem newFileMenuItem = new JMenuItem(); - JSplitPane jSplitPane3 = new JSplitPane(); - JSplitPane jSplitPane4 = new JSplitPane(); - JScrollPane jScrollPane2 = new JScrollPane(); - JScrollPane jScrollPane5 = new JScrollPane(); - JScrollPane jScrollPane6 = new JScrollPane(); - JScrollPane jScrollPane7 = new JScrollPane(); - JList pass3aJList = new JList(); - JList pass3bJList = new JList(); - JTextPane pass3aTextPane = new JTextPane(); - JTextPane pass3bTextPane = new JTextPane(); - JMenu jMenu2 = new JMenu(); - JMenuItem whatisMenuItem = new JMenuItem(); - JMenuItem aboutMenuItem = new JMenuItem(); - - - /** Constructor. */ - public VerifierAppFrame() { - enableEvents(AWTEvent.WINDOW_EVENT_MASK); - try { - jbInit(); - } catch (Exception e) { - e.printStackTrace(); - } - } - - - /** Initizalization of the components. */ - private void jbInit() throws Exception { - //setIconImage(Toolkit.getDefaultToolkit().createImage(Frame1.class.getResource("[Ihr Symbol]"))); - contentPane = (JPanel) this.getContentPane(); - contentPane.setLayout(cardLayout1); - this.setJMenuBar(jMenuBar1); - this.setSize(new Dimension(708, 451)); - this.setTitle("JustIce"); - jPanel1.setMinimumSize(new Dimension(100, 100)); - jPanel1.setPreferredSize(new Dimension(100, 100)); - jPanel1.setLayout(gridLayout1); - jSplitPane2.setOrientation(JSplitPane.VERTICAL_SPLIT); - jPanel2.setLayout(gridLayout2); - jPanel3.setMinimumSize(new Dimension(200, 100)); - jPanel3.setPreferredSize(new Dimension(400, 400)); - jPanel3.setLayout(gridLayout4); - messagesPanel.setMinimumSize(new Dimension(100, 100)); - messagesPanel.setLayout(gridLayout3); - jPanel2.setMinimumSize(new Dimension(200, 100)); - jMenu1.setText("File"); - jScrollPane1.getViewport().setBackground(Color.red); - messagesScrollPane.getViewport().setBackground(Color.red); - messagesScrollPane.setPreferredSize(new Dimension(10, 10)); - classNamesJList.addListSelectionListener(new javax.swing.event.ListSelectionListener() { - - public void valueChanged( ListSelectionEvent e ) { - classNamesJList_valueChanged(e); - } - }); - classNamesJList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); - jScrollPane3.setBorder(BorderFactory.createLineBorder(Color.black)); - jScrollPane3.setPreferredSize(new Dimension(100, 100)); - gridLayout4.setRows(4); - gridLayout4.setColumns(1); - gridLayout4.setHgap(1); - jScrollPane4.setBorder(BorderFactory.createLineBorder(Color.black)); - jScrollPane4.setPreferredSize(new Dimension(100, 100)); - pass1TextPane.setBorder(BorderFactory.createRaisedBevelBorder()); - pass1TextPane.setToolTipText(""); - pass1TextPane.setEditable(false); - pass2TextPane.setBorder(BorderFactory.createRaisedBevelBorder()); - pass2TextPane.setEditable(false); - messagesTextPane.setBorder(BorderFactory.createRaisedBevelBorder()); - messagesTextPane.setEditable(false); - newFileMenuItem.setText("New..."); - newFileMenuItem.setAccelerator(javax.swing.KeyStroke.getKeyStroke(78, - java.awt.event.KeyEvent.CTRL_MASK, true)); - newFileMenuItem.addActionListener(new java.awt.event.ActionListener() { - - public void actionPerformed( ActionEvent e ) { - newFileMenuItem_actionPerformed(e); - } - }); - pass3aTextPane.setEditable(false); - pass3bTextPane.setEditable(false); - pass3aJList.addListSelectionListener(new javax.swing.event.ListSelectionListener() { - - public void valueChanged( ListSelectionEvent e ) { - pass3aJList_valueChanged(e); - } - }); - pass3bJList.addListSelectionListener(new javax.swing.event.ListSelectionListener() { - - public void valueChanged( ListSelectionEvent e ) { - pass3bJList_valueChanged(e); - } - }); - jMenu2.setText("Help"); - whatisMenuItem.setText("What is..."); - whatisMenuItem.addActionListener(new java.awt.event.ActionListener() { - - public void actionPerformed( ActionEvent e ) { - whatisMenuItem_actionPerformed(e); - } - }); - aboutMenuItem.setText("About"); - aboutMenuItem.addActionListener(new java.awt.event.ActionListener() { - - public void actionPerformed( ActionEvent e ) { - aboutMenuItem_actionPerformed(e); - } - }); - jSplitPane2.add(messagesPanel, JSplitPane.BOTTOM); - messagesPanel.add(messagesScrollPane, null); - messagesScrollPane.getViewport().add(messagesTextPane, null); - jSplitPane2.add(jPanel3, JSplitPane.TOP); - jPanel3.add(jScrollPane3, null); - jScrollPane3.getViewport().add(pass1TextPane, null); - jPanel3.add(jScrollPane4, null); - jPanel3.add(jSplitPane3, null); - jSplitPane3.add(jScrollPane2, JSplitPane.LEFT); - jScrollPane2.getViewport().add(pass3aJList, null); - jSplitPane3.add(jScrollPane5, JSplitPane.RIGHT); - jScrollPane5.getViewport().add(pass3aTextPane, null); - jPanel3.add(jSplitPane4, null); - jSplitPane4.add(jScrollPane6, JSplitPane.LEFT); - jScrollPane6.getViewport().add(pass3bJList, null); - jSplitPane4.add(jScrollPane7, JSplitPane.RIGHT); - jScrollPane7.getViewport().add(pass3bTextPane, null); - jScrollPane4.getViewport().add(pass2TextPane, null); - jSplitPane1.add(jPanel2, JSplitPane.TOP); - jPanel2.add(jScrollPane1, null); - jSplitPane1.add(jPanel1, JSplitPane.BOTTOM); - jPanel1.add(jSplitPane2, null); - jScrollPane1.getViewport().add(classNamesJList, null); - jMenuBar1.add(jMenu1); - jMenuBar1.add(jMenu2); - contentPane.add(jSplitPane1, "jSplitPane1"); - jMenu1.add(newFileMenuItem); - jMenu2.add(whatisMenuItem); - jMenu2.add(aboutMenuItem); - jSplitPane2.setDividerLocation(300); - jSplitPane3.setDividerLocation(150); - jSplitPane4.setDividerLocation(150); - } - - - /** Overridden to stop the application on a closing window. */ - protected void processWindowEvent( WindowEvent e ) { - super.processWindowEvent(e); - if (e.getID() == WindowEvent.WINDOW_CLOSING) { - System.exit(0); - } - } - - - synchronized void classNamesJList_valueChanged( ListSelectionEvent e ) { - if (e.getValueIsAdjusting()) { - return; - } - current_class = classNamesJList.getSelectedValue().toString(); - try { - verify(); - } catch (ClassNotFoundException ex) { - // FIXME: report the error using the GUI - ex.printStackTrace(); - } - classNamesJList.setSelectedValue(current_class, true); - } - - - private void verify() throws ClassNotFoundException { - setTitle("PLEASE WAIT"); - Verifier v = VerifierFactory.getVerifier(current_class); - v.flush(); // Don't cache the verification result for this class. - VerificationResult vr; - vr = v.doPass1(); - if (vr.getStatus() == VerificationResult.VERIFIED_REJECTED) { - pass1TextPane.setText(vr.getMessage()); - pass1TextPane.setBackground(Color.red); - pass2TextPane.setText(""); - pass2TextPane.setBackground(Color.yellow); - pass3aTextPane.setText(""); - pass3aJList.setListData(new Object[0]); - pass3aTextPane.setBackground(Color.yellow); - pass3bTextPane.setText(""); - pass3bJList.setListData(new Object[0]); - pass3bTextPane.setBackground(Color.yellow); - } else { // Must be VERIFIED_OK, Pass 1 does not know VERIFIED_NOTYET - pass1TextPane.setBackground(Color.green); - pass1TextPane.setText(vr.getMessage()); - vr = v.doPass2(); - if (vr.getStatus() == VerificationResult.VERIFIED_REJECTED) { - pass2TextPane.setText(vr.getMessage()); - pass2TextPane.setBackground(Color.red); - pass3aTextPane.setText(""); - pass3aTextPane.setBackground(Color.yellow); - pass3aJList.setListData(new Object[0]); - pass3bTextPane.setText(""); - pass3bTextPane.setBackground(Color.yellow); - pass3bJList.setListData(new Object[0]); - } else { // must be Verified_OK, because Pass1 was OK (cannot be Verified_NOTYET). - pass2TextPane.setText(vr.getMessage()); - pass2TextPane.setBackground(Color.green); - JavaClass jc = Repository.lookupClass(current_class); - /* - boolean all3aok = true; - boolean all3bok = true; - String all3amsg = ""; - String all3bmsg = ""; - */ - String[] methodnames = new String[jc.getMethods().length]; - for (int i = 0; i < jc.getMethods().length; i++) { - methodnames[i] = jc.getMethods()[i].toString().replace('\n', ' ').replace('\t', - ' '); - } - pass3aJList.setListData(methodnames); - pass3aJList.setSelectionInterval(0, jc.getMethods().length - 1); - pass3bJList.setListData(methodnames); - pass3bJList.setSelectionInterval(0, jc.getMethods().length - 1); - } - } - String[] msgs = v.getMessages(); - messagesTextPane.setBackground(msgs.length == 0 ? Color.green : Color.yellow); - String allmsgs = ""; - for (int i = 0; i < msgs.length; i++) { - msgs[i] = msgs[i].replace('\n', ' '); - allmsgs += msgs[i] + "\n\n"; - } - messagesTextPane.setText(allmsgs); - setTitle(current_class + " - " + JUSTICE_VERSION); - } - - - void newFileMenuItem_actionPerformed( ActionEvent e ) { - String classname = JOptionPane - .showInputDialog("Please enter the fully qualified name of a class or interface to verify:"); - if ((classname == null) || (classname.equals(""))) { - return; - } - VerifierFactory.getVerifier(classname); // let observers do the rest. - classNamesJList.setSelectedValue(classname, true); - } - - - synchronized void pass3aJList_valueChanged( ListSelectionEvent e ) { - if (e.getValueIsAdjusting()) { - return; - } - Verifier v = VerifierFactory.getVerifier(current_class); - String all3amsg = ""; - boolean all3aok = true; - boolean rejected = false; - for (int i = 0; i < pass3aJList.getModel().getSize(); i++) { - if (pass3aJList.isSelectedIndex(i)) { - VerificationResult vr = v.doPass3a(i); - if (vr.getStatus() == VerificationResult.VERIFIED_REJECTED) { - all3aok = false; - rejected = true; - } - JavaClass jc = null; - try { - jc = Repository.lookupClass(v.getClassName()); - all3amsg += "Method '" + jc.getMethods()[i] + "': " - + vr.getMessage().replace('\n', ' ') + "\n\n"; - } catch (ClassNotFoundException ex) { - // FIXME: handle the error - ex.printStackTrace(); - } - } - } - pass3aTextPane.setText(all3amsg); - pass3aTextPane.setBackground(all3aok ? Color.green : (rejected ? Color.red : Color.yellow)); - } - - - synchronized void pass3bJList_valueChanged( ListSelectionEvent e ) { - if (e.getValueIsAdjusting()) { - return; - } - Verifier v = VerifierFactory.getVerifier(current_class); - String all3bmsg = ""; - boolean all3bok = true; - boolean rejected = false; - for (int i = 0; i < pass3bJList.getModel().getSize(); i++) { - if (pass3bJList.isSelectedIndex(i)) { - VerificationResult vr = v.doPass3b(i); - if (vr.getStatus() == VerificationResult.VERIFIED_REJECTED) { - all3bok = false; - rejected = true; - } - JavaClass jc = null; - try { - jc = Repository.lookupClass(v.getClassName()); - all3bmsg += "Method '" + jc.getMethods()[i] + "': " - + vr.getMessage().replace('\n', ' ') + "\n\n"; - } catch (ClassNotFoundException ex) { - // FIXME: handle the error - ex.printStackTrace(); - } - } - } - pass3bTextPane.setText(all3bmsg); - pass3bTextPane.setBackground(all3bok ? Color.green : (rejected ? Color.red : Color.yellow)); - } - - - void aboutMenuItem_actionPerformed( ActionEvent e ) { - JOptionPane - .showMessageDialog( - this, - "JustIce is a Java class file verifier.\nIt was implemented by Enver Haase in 2001, 2002.\n", - JUSTICE_VERSION, JOptionPane.INFORMATION_MESSAGE); - } - - - void whatisMenuItem_actionPerformed( ActionEvent e ) { - JOptionPane - .showMessageDialog( - this, - "The upper four boxes to the right reflect verification passes according to The Java Virtual Machine Specification.\nThese are (in that order): Pass one, Pass two, Pass three (before data flow analysis), Pass three (data flow analysis).\nThe bottom box to the right shows (warning) messages; warnings do not cause a class to be rejected.", - JUSTICE_VERSION, JOptionPane.INFORMATION_MESSAGE); - } -} diff --git a/src/org/apache/bcel/verifier/VerifierFactory.java b/src/org/apache/bcel/verifier/VerifierFactory.java deleted file mode 100644 index bb9f0bb..0000000 --- a/src/org/apache/bcel/verifier/VerifierFactory.java +++ /dev/null @@ -1,110 +0,0 @@ -/* - * Copyright 2000-2004 The Apache Software Foundation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ -package org.apache.bcel.verifier; - -import java.util.HashMap; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.Vector; - -/** - * This class produces instances of the Verifier class. Its purpose is to make - * sure that they are singleton instances with respect to the class name they - * operate on. That means, for every class (represented by a unique fully qualified - * class name) there is exactly one Verifier. - * - * @version $Id: VerifierFactory.java 386056 2006-03-15 11:31:56Z tcurdt $ - * @author Enver Haase - * @see org.apache.bcel.verifier.Verifier - */ -public class VerifierFactory { - - /** - * The HashMap that holds the data about the already-constructed Verifier instances. - */ - private static Map hashMap = new HashMap(); - /** - * The VerifierFactoryObserver instances that observe the VerifierFactory. - */ - private static List observers = new Vector(); - - - /** - * The VerifierFactory is not instantiable. - */ - private VerifierFactory() { - } - - - /** - * Returns the (only) verifier responsible for the class with the given name. - * Possibly a new Verifier object is transparently created. - * @return the (only) verifier responsible for the class with the given name. - */ - public static Verifier getVerifier( String fully_qualified_classname ) { - Verifier v = (Verifier) (hashMap.get(fully_qualified_classname)); - if (v == null) { - v = new Verifier(fully_qualified_classname); - hashMap.put(fully_qualified_classname, v); - notify(fully_qualified_classname); - } - return v; - } - - - /** - * Notifies the observers of a newly generated Verifier. - */ - private static void notify( String fully_qualified_classname ) { - // notify the observers - Iterator i = observers.iterator(); - while (i.hasNext()) { - VerifierFactoryObserver vfo = (VerifierFactoryObserver) i.next(); - vfo.update(fully_qualified_classname); - } - } - - - /** - * Returns all Verifier instances created so far. - * This is useful when a Verifier recursively lets - * the VerifierFactory create other Verifier instances - * and if you want to verify the transitive hull of - * referenced class files. - */ - public static Verifier[] getVerifiers() { - Verifier[] vs = new Verifier[hashMap.values().size()]; - return (Verifier[]) (hashMap.values().toArray(vs)); // Because vs is big enough, vs is used to store the values into and returned! - } - - - /** - * Adds the VerifierFactoryObserver o to the list of observers. - */ - public static void attach( VerifierFactoryObserver o ) { - observers.add(o); - } - - - /** - * Removes the VerifierFactoryObserver o from the list of observers. - */ - public static void detach( VerifierFactoryObserver o ) { - observers.remove(o); - } -} diff --git a/src/org/apache/bcel/verifier/VerifierFactoryListModel.java b/src/org/apache/bcel/verifier/VerifierFactoryListModel.java deleted file mode 100644 index 1eb9bbf..0000000 --- a/src/org/apache/bcel/verifier/VerifierFactoryListModel.java +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Copyright 2000-2004 The Apache Software Foundation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ -package org.apache.bcel.verifier; - -import javax.swing.event.ListDataEvent; - -/** - * This class implements an adapter; it implements both a Swing ListModel and - * a VerifierFactoryObserver. - * - * @version $Id: VerifierFactoryListModel.java 386056 2006-03-15 11:31:56Z tcurdt $ - * @author Enver Haase - */ -public class VerifierFactoryListModel implements org.apache.bcel.verifier.VerifierFactoryObserver, - javax.swing.ListModel { - - private java.util.ArrayList listeners = new java.util.ArrayList(); - private java.util.TreeSet cache = new java.util.TreeSet(); - - - public VerifierFactoryListModel() { - VerifierFactory.attach(this); - update(null); // fill cache. - } - - - public synchronized void update( String s ) { - int size = listeners.size(); - Verifier[] verifiers = VerifierFactory.getVerifiers(); - int num_of_verifiers = verifiers.length; - cache.clear(); - for (int i = 0; i < num_of_verifiers; i++) { - cache.add(verifiers[i].getClassName()); - } - for (int i = 0; i < size; i++) { - ListDataEvent e = new ListDataEvent(this, ListDataEvent.CONTENTS_CHANGED, 0, - num_of_verifiers - 1); - ((javax.swing.event.ListDataListener) (listeners.get(i))).contentsChanged(e); - } - } - - - public synchronized void addListDataListener( javax.swing.event.ListDataListener l ) { - listeners.add(l); - } - - - public synchronized void removeListDataListener( javax.swing.event.ListDataListener l ) { - listeners.remove(l); - } - - - public synchronized int getSize() { - return cache.size(); - } - - - public synchronized Object getElementAt( int index ) { - return (cache.toArray())[index]; - } -} diff --git a/src/org/apache/bcel/verifier/VerifierFactoryObserver.java b/src/org/apache/bcel/verifier/VerifierFactoryObserver.java deleted file mode 100644 index 70dcc0f..0000000 --- a/src/org/apache/bcel/verifier/VerifierFactoryObserver.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright 2000-2004 The Apache Software Foundation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ -package org.apache.bcel.verifier; - -/** - * VerifierFactoryObserver instances are notified when new Verifier - * instances are created. - * - * @version $Id: VerifierFactoryObserver.java 386056 2006-03-15 11:31:56Z tcurdt $ - * @author Enver Haase - * - * @see VerifierFactory#getVerifier(String) - * @see VerifierFactory#getVerifiers() - * @see VerifierFactory#attach(VerifierFactoryObserver) - * @see VerifierFactory#detach(VerifierFactoryObserver) - */ -public interface VerifierFactoryObserver { - - /** - * VerifierFactoryObserver instances are notified invoking this method. - * The String argument is the fully qualified class name of a class a - * new Verifier instance created by the VerifierFactory operates on. - */ - public void update( String s ); -} diff --git a/src/org/apache/bcel/verifier/VerifyDialog.java b/src/org/apache/bcel/verifier/VerifyDialog.java deleted file mode 100644 index 4a89f51..0000000 --- a/src/org/apache/bcel/verifier/VerifyDialog.java +++ /dev/null @@ -1,553 +0,0 @@ -/* - * Copyright 2000-2004 The Apache Software Foundation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ -package org.apache.bcel.verifier; - -import java.awt.Color; -import org.apache.bcel.Repository; -import org.apache.bcel.classfile.JavaClass; - -/** - * A class for simple graphical class file verification. - * Use the main(String []) method with fully qualified - * class names as arguments to use it as a stand-alone - * application. - * Use the VerifyDialog(String) constructor to use this - * class in your application. - * [This class was created using VisualAge for Java, - * but it does not work under VAJ itself (Version 3.02 JDK 1.2)] - * @version $Id: VerifyDialog.java 386056 2006-03-15 11:31:56Z tcurdt $ - * @author Enver Haase - * @see #main(String[]) - * @see #VerifyDialog(String) - */ -public class VerifyDialog extends javax.swing.JDialog { - - /** Machine-generated. */ - private javax.swing.JPanel ivjJDialogContentPane = null; - /** Machine-generated. */ - private javax.swing.JPanel ivjPass1Panel = null; - /** Machine-generated. */ - private javax.swing.JPanel ivjPass2Panel = null; - /** Machine-generated. */ - private javax.swing.JPanel ivjPass3Panel = null; - /** Machine-generated. */ - private javax.swing.JButton ivjPass1Button = null; - /** Machine-generated. */ - private javax.swing.JButton ivjPass2Button = null; - /** Machine-generated. */ - private javax.swing.JButton ivjPass3Button = null; - /** Machine-generated. */ - IvjEventHandler ivjEventHandler = new IvjEventHandler(); - /** - * The class to verify. Default set to 'java.lang.Object' - * in case this class is instantiated via one of the many - * machine-generated constructors. - */ - private String class_name = "java.lang.Object"; - /** - * This field is here to count the number of open VerifyDialog - * instances so the JVM can be exited afer every Dialog had been - * closed. - */ - private static int classes_to_verify; - - /** Machine-generated. */ - class IvjEventHandler implements java.awt.event.ActionListener { - - public void actionPerformed( java.awt.event.ActionEvent e ) { - if (e.getSource() == VerifyDialog.this.getPass1Button()) { - connEtoC1(e); - } - if (e.getSource() == VerifyDialog.this.getPass2Button()) { - connEtoC2(e); - } - if (e.getSource() == VerifyDialog.this.getPass3Button()) { - connEtoC3(e); - } - if (e.getSource() == VerifyDialog.this.getFlushButton()) { - connEtoC4(e); - } - }; - }; - - /** Machine-generated. */ - private javax.swing.JButton ivjFlushButton = null; - - - /** Machine-generated. */ - public VerifyDialog() { - super(); - initialize(); - } - - - /** Machine-generated. */ - public VerifyDialog(java.awt.Dialog owner) { - super(owner); - } - - - /** Machine-generated. */ - public VerifyDialog(java.awt.Dialog owner, String title) { - super(owner, title); - } - - - /** Machine-generated. */ - public VerifyDialog(java.awt.Dialog owner, String title, boolean modal) { - super(owner, title, modal); - } - - - /** Machine-generated. */ - public VerifyDialog(java.awt.Dialog owner, boolean modal) { - super(owner, modal); - } - - - /** Machine-generated. */ - public VerifyDialog(java.awt.Frame owner) { - super(owner); - } - - - /** Machine-generated. */ - public VerifyDialog(java.awt.Frame owner, String title) { - super(owner, title); - } - - - /** Machine-generated. */ - public VerifyDialog(java.awt.Frame owner, String title, boolean modal) { - super(owner, title, modal); - } - - - /** Machine-generated. */ - public VerifyDialog(java.awt.Frame owner, boolean modal) { - super(owner, modal); - } - - - /** - * Use this constructor if you want a possibility to verify other - * class files than java.lang.Object. - * @param fully_qualified_class_name java.lang.String - */ - public VerifyDialog(String fully_qualified_class_name) { - super(); - int dotclasspos = fully_qualified_class_name.lastIndexOf(".class"); - if (dotclasspos != -1) { - fully_qualified_class_name = fully_qualified_class_name.substring(0, dotclasspos); - } - fully_qualified_class_name = fully_qualified_class_name.replace('/', '.'); - class_name = fully_qualified_class_name; - initialize(); - } - - - /** Machine-generated. */ - private void connEtoC1( java.awt.event.ActionEvent arg1 ) { - try { - // user code begin {1} - // user code end - this.pass1Button_ActionPerformed(arg1); - // user code begin {2} - // user code end - } catch (java.lang.Throwable ivjExc) { - // user code begin {3} - // user code end - handleException(ivjExc); - } - } - - - /** Machine-generated. */ - private void connEtoC2( java.awt.event.ActionEvent arg1 ) { - try { - // user code begin {1} - // user code end - this.pass2Button_ActionPerformed(arg1); - // user code begin {2} - // user code end - } catch (java.lang.Throwable ivjExc) { - // user code begin {3} - // user code end - handleException(ivjExc); - } - } - - - /** Machine-generated. */ - private void connEtoC3( java.awt.event.ActionEvent arg1 ) { - try { - // user code begin {1} - // user code end - this.pass4Button_ActionPerformed(arg1); - // user code begin {2} - // user code end - } catch (java.lang.Throwable ivjExc) { - // user code begin {3} - // user code end - handleException(ivjExc); - } - } - - - /** Machine-generated. */ - private void connEtoC4( java.awt.event.ActionEvent arg1 ) { - try { - // user code begin {1} - // user code end - this.flushButton_ActionPerformed(arg1); - // user code begin {2} - // user code end - } catch (java.lang.Throwable ivjExc) { - // user code begin {3} - // user code end - handleException(ivjExc); - } - } - - - /** Machine-generated. */ - public void flushButton_ActionPerformed( java.awt.event.ActionEvent actionEvent ) { - VerifierFactory.getVerifier(class_name).flush(); - Repository.removeClass(class_name); // Make sure it will be reloaded. - getPass1Panel().setBackground(Color.gray); - getPass1Panel().repaint(); - getPass2Panel().setBackground(Color.gray); - getPass2Panel().repaint(); - getPass3Panel().setBackground(Color.gray); - getPass3Panel().repaint(); - } - - - /** Machine-generated. */ - private javax.swing.JButton getFlushButton() { - if (ivjFlushButton == null) { - try { - ivjFlushButton = new javax.swing.JButton(); - ivjFlushButton.setName("FlushButton"); - ivjFlushButton.setText("Flush: Forget old verification results"); - ivjFlushButton.setBackground(java.awt.SystemColor.controlHighlight); - ivjFlushButton.setBounds(60, 215, 300, 30); - ivjFlushButton.setForeground(java.awt.Color.red); - ivjFlushButton.setActionCommand("FlushButton"); - // user code begin {1} - // user code end - } catch (java.lang.Throwable ivjExc) { - // user code begin {2} - // user code end - handleException(ivjExc); - } - } - return ivjFlushButton; - } - - - /** Machine-generated. */ - private javax.swing.JPanel getJDialogContentPane() { - if (ivjJDialogContentPane == null) { - try { - ivjJDialogContentPane = new javax.swing.JPanel(); - ivjJDialogContentPane.setName("JDialogContentPane"); - ivjJDialogContentPane.setLayout(null); - getJDialogContentPane().add(getPass1Panel(), getPass1Panel().getName()); - getJDialogContentPane().add(getPass3Panel(), getPass3Panel().getName()); - getJDialogContentPane().add(getPass2Panel(), getPass2Panel().getName()); - getJDialogContentPane().add(getPass1Button(), getPass1Button().getName()); - getJDialogContentPane().add(getPass2Button(), getPass2Button().getName()); - getJDialogContentPane().add(getPass3Button(), getPass3Button().getName()); - getJDialogContentPane().add(getFlushButton(), getFlushButton().getName()); - // user code begin {1} - // user code end - } catch (java.lang.Throwable ivjExc) { - // user code begin {2} - // user code end - handleException(ivjExc); - } - } - return ivjJDialogContentPane; - } - - - /** Machine-generated. */ - private javax.swing.JButton getPass1Button() { - if (ivjPass1Button == null) { - try { - ivjPass1Button = new javax.swing.JButton(); - ivjPass1Button.setName("Pass1Button"); - ivjPass1Button.setText("Pass1: Verify binary layout of .class file"); - ivjPass1Button.setBackground(java.awt.SystemColor.controlHighlight); - ivjPass1Button.setBounds(100, 40, 300, 30); - ivjPass1Button.setActionCommand("Button1"); - // user code begin {1} - // user code end - } catch (java.lang.Throwable ivjExc) { - // user code begin {2} - // user code end - handleException(ivjExc); - } - } - return ivjPass1Button; - } - - - /** Machine-generated. */ - private javax.swing.JPanel getPass1Panel() { - if (ivjPass1Panel == null) { - try { - ivjPass1Panel = new javax.swing.JPanel(); - ivjPass1Panel.setName("Pass1Panel"); - ivjPass1Panel.setLayout(null); - ivjPass1Panel.setBackground(java.awt.SystemColor.controlShadow); - ivjPass1Panel.setBounds(30, 30, 50, 50); - // user code begin {1} - // user code end - } catch (java.lang.Throwable ivjExc) { - // user code begin {2} - // user code end - handleException(ivjExc); - } - } - return ivjPass1Panel; - } - - - /** Machine-generated. */ - private javax.swing.JButton getPass2Button() { - if (ivjPass2Button == null) { - try { - ivjPass2Button = new javax.swing.JButton(); - ivjPass2Button.setName("Pass2Button"); - ivjPass2Button.setText("Pass 2: Verify static .class file constraints"); - ivjPass2Button.setBackground(java.awt.SystemColor.controlHighlight); - ivjPass2Button.setBounds(100, 100, 300, 30); - ivjPass2Button.setActionCommand("Button2"); - // user code begin {1} - // user code end - } catch (java.lang.Throwable ivjExc) { - // user code begin {2} - // user code end - handleException(ivjExc); - } - } - return ivjPass2Button; - } - - - /** Machine-generated. */ - private javax.swing.JPanel getPass2Panel() { - if (ivjPass2Panel == null) { - try { - ivjPass2Panel = new javax.swing.JPanel(); - ivjPass2Panel.setName("Pass2Panel"); - ivjPass2Panel.setLayout(null); - ivjPass2Panel.setBackground(java.awt.SystemColor.controlShadow); - ivjPass2Panel.setBounds(30, 90, 50, 50); - // user code begin {1} - // user code end - } catch (java.lang.Throwable ivjExc) { - // user code begin {2} - // user code end - handleException(ivjExc); - } - } - return ivjPass2Panel; - } - - - /** Machine-generated. */ - private javax.swing.JButton getPass3Button() { - if (ivjPass3Button == null) { - try { - ivjPass3Button = new javax.swing.JButton(); - ivjPass3Button.setName("Pass3Button"); - ivjPass3Button.setText("Passes 3a+3b: Verify code arrays"); - ivjPass3Button.setBackground(java.awt.SystemColor.controlHighlight); - ivjPass3Button.setBounds(100, 160, 300, 30); - ivjPass3Button.setActionCommand("Button2"); - // user code begin {1} - // user code end - } catch (java.lang.Throwable ivjExc) { - // user code begin {2} - // user code end - handleException(ivjExc); - } - } - return ivjPass3Button; - } - - - /** Machine-generated. */ - private javax.swing.JPanel getPass3Panel() { - if (ivjPass3Panel == null) { - try { - ivjPass3Panel = new javax.swing.JPanel(); - ivjPass3Panel.setName("Pass3Panel"); - ivjPass3Panel.setLayout(null); - ivjPass3Panel.setBackground(java.awt.SystemColor.controlShadow); - ivjPass3Panel.setBounds(30, 150, 50, 50); - // user code begin {1} - // user code end - } catch (java.lang.Throwable ivjExc) { - // user code begin {2} - // user code end - handleException(ivjExc); - } - } - return ivjPass3Panel; - } - - - /** Machine-generated. */ - private void handleException( java.lang.Throwable exception ) { - /* Uncomment the following lines to print uncaught exceptions to stdout */ - System.out.println("--------- UNCAUGHT EXCEPTION ---------"); - exception.printStackTrace(System.out); - } - - - /** Machine-generated. */ - private void initConnections() throws java.lang.Exception { - // user code begin {1} - // user code end - getPass1Button().addActionListener(ivjEventHandler); - getPass2Button().addActionListener(ivjEventHandler); - getPass3Button().addActionListener(ivjEventHandler); - getFlushButton().addActionListener(ivjEventHandler); - } - - - /** Machine-generated. */ - private void initialize() { - try { - // user code begin {1} - // user code end - setName("VerifyDialog"); - setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE); - setSize(430, 280); - setVisible(true); - setModal(true); - setResizable(false); - setContentPane(getJDialogContentPane()); - initConnections(); - } catch (java.lang.Throwable ivjExc) { - handleException(ivjExc); - } - // user code begin {2} - setTitle("'" + class_name + "' verification - JustIce / BCEL"); - // user code end - } - - - /** - * Verifies one or more class files. - * Verification results are presented graphically: Red means 'rejected', - * green means 'passed' while yellow means 'could not be verified yet'. - * @param args java.lang.String[] fully qualified names of classes to verify. - */ - public static void main( java.lang.String[] args ) { - classes_to_verify = args.length; - for (int i = 0; i < args.length; i++) { - try { - VerifyDialog aVerifyDialog; - aVerifyDialog = new VerifyDialog(args[i]); - aVerifyDialog.setModal(true); - aVerifyDialog.addWindowListener(new java.awt.event.WindowAdapter() { - - public void windowClosing( java.awt.event.WindowEvent e ) { - classes_to_verify--; - if (classes_to_verify == 0) { - System.exit(0); - } - }; - }); - aVerifyDialog.setVisible(true); - } catch (Throwable exception) { - System.err.println("Exception occurred in main() of javax.swing.JDialog"); - exception.printStackTrace(System.out); - } - } - } - - - /** Machine-generated. */ - public void pass1Button_ActionPerformed( java.awt.event.ActionEvent actionEvent ) { - Verifier v = VerifierFactory.getVerifier(class_name); - VerificationResult vr = v.doPass1(); - if (vr.getStatus() == VerificationResult.VERIFIED_OK) { - getPass1Panel().setBackground(Color.green); - getPass1Panel().repaint(); - } - if (vr.getStatus() == VerificationResult.VERIFIED_REJECTED) { - getPass1Panel().setBackground(Color.red); - getPass1Panel().repaint(); - } - } - - - /** Machine-generated. */ - public void pass2Button_ActionPerformed( java.awt.event.ActionEvent actionEvent ) { - pass1Button_ActionPerformed(actionEvent); - Verifier v = VerifierFactory.getVerifier(class_name); - VerificationResult vr = v.doPass2(); - if (vr.getStatus() == VerificationResult.VERIFIED_OK) { - getPass2Panel().setBackground(Color.green); - getPass2Panel().repaint(); - } - if (vr.getStatus() == VerificationResult.VERIFIED_NOTYET) { - getPass2Panel().setBackground(Color.yellow); - getPass2Panel().repaint(); - } - if (vr.getStatus() == VerificationResult.VERIFIED_REJECTED) { - getPass2Panel().setBackground(Color.red); - getPass2Panel().repaint(); - } - } - - - /** Machine-generated. */ - public void pass4Button_ActionPerformed( java.awt.event.ActionEvent actionEvent ) { - pass2Button_ActionPerformed(actionEvent); - Color color = Color.green; - Verifier v = VerifierFactory.getVerifier(class_name); - VerificationResult vr = v.doPass2(); - if (vr.getStatus() == VerificationResult.VERIFIED_OK) { - JavaClass jc = null; - try { - jc = Repository.lookupClass(class_name); - int nr = jc.getMethods().length; - for (int i = 0; i < nr; i++) { - vr = v.doPass3b(i); - if (vr.getStatus() != VerificationResult.VERIFIED_OK) { - color = Color.red; - break; - } - } - } catch (ClassNotFoundException ex) { - // FIXME: report the error - ex.printStackTrace(); - } - } else { - color = Color.yellow; - } - getPass3Panel().setBackground(color); - getPass3Panel().repaint(); - } -} diff --git a/src/org/apache/bcel/verifier/exc/AssertionViolatedException.java b/src/org/apache/bcel/verifier/exc/AssertionViolatedException.java deleted file mode 100644 index 6aea937..0000000 --- a/src/org/apache/bcel/verifier/exc/AssertionViolatedException.java +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Copyright 2000-2004 The Apache Software Foundation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ -package org.apache.bcel.verifier.exc; - - -/** - * Instances of this class should never be thrown. When such an instance is thrown, - * this is due to an INTERNAL ERROR of BCEL's class file verifier "JustIce". - * - * @version $Id: AssertionViolatedException.java 386056 2006-03-15 11:31:56Z tcurdt $ - * @author Enver Haase - */ -public final class AssertionViolatedException extends RuntimeException{ - /** The error message. */ - private String detailMessage; - /** Constructs a new AssertionViolatedException with null as its error message string. */ - public AssertionViolatedException(){ - super(); - } - /** - * Constructs a new AssertionViolatedException with the specified error message preceded - * by "INTERNAL ERROR: ". - */ - public AssertionViolatedException(String message){ - super(message = "INTERNAL ERROR: "+message); // Thanks to Java, the constructor call here must be first. - detailMessage=message; - } - /** Extends the error message with a string before ("pre") and after ("post") the - 'old' error message. All of these three strings are allowed to be null, and null - is always replaced by the empty string (""). In particular, after invoking this - method, the error message of this object can no longer be null. - */ - public void extendMessage(String pre, String post){ - if (pre == null) { - pre=""; - } - if (detailMessage == null) { - detailMessage=""; - } - if (post == null) { - post=""; - } - detailMessage = pre+detailMessage+post; - } - /** - * Returns the error message string of this AssertionViolatedException object. - * @return the error message string of this AssertionViolatedException. - */ - public String getMessage(){ - return detailMessage; - } - - /** - * DO NOT USE. It's for experimental testing during development only. - */ - public static void main(String[] args){ - AssertionViolatedException ave = new AssertionViolatedException("Oops!"); - ave.extendMessage("\nFOUND:\n\t","\nExiting!!\n"); - throw ave; - } - -} diff --git a/src/org/apache/bcel/verifier/exc/ClassConstraintException.java b/src/org/apache/bcel/verifier/exc/ClassConstraintException.java deleted file mode 100644 index 3230d89..0000000 --- a/src/org/apache/bcel/verifier/exc/ClassConstraintException.java +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright 2000-2004 The Apache Software Foundation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ -package org.apache.bcel.verifier.exc; - - -/** - * Instances of this class are thrown by BCEL's class file verifier "JustIce" - * when a class file to verify does not pass the verification pass 2 as described - * in the Java Virtual Machine specification, 2nd edition. - * - * @version $Id: ClassConstraintException.java 371539 2006-01-23 14:08:00Z tcurdt $ - * @author Enver Haase - */ -public class ClassConstraintException extends VerificationException{ - /** - * Constructs a new ClassConstraintException with null as its error message string. - */ - public ClassConstraintException(){ - super(); - } - - /** - * Constructs a new ClassConstraintException with the specified error message. - */ - public ClassConstraintException(String message){ - super (message); - } -} diff --git a/src/org/apache/bcel/verifier/exc/CodeConstraintException.java b/src/org/apache/bcel/verifier/exc/CodeConstraintException.java deleted file mode 100644 index 82d1b2f..0000000 --- a/src/org/apache/bcel/verifier/exc/CodeConstraintException.java +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright 2000-2004 The Apache Software Foundation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ -package org.apache.bcel.verifier.exc; - -/** - * Instances of this class are thrown by BCEL's class file verifier "JustIce" when - * a class file does not pass the verification pass 3. Note that the pass 3 used by - * "JustIce" involves verification that is usually delayed to pass 4. - * - * @version $Id: CodeConstraintException.java 371539 2006-01-23 14:08:00Z tcurdt $ - * @author Enver Haase - */ -public abstract class CodeConstraintException extends VerificationException{ - /** - * Constructs a new CodeConstraintException with null as its error message string. - */ - CodeConstraintException(){ - super(); - } - /** - * Constructs a new CodeConstraintException with the specified error message. - */ - CodeConstraintException(String message){ - super(message); - } -} diff --git a/src/org/apache/bcel/verifier/exc/InvalidMethodException.java b/src/org/apache/bcel/verifier/exc/InvalidMethodException.java deleted file mode 100644 index 548afab..0000000 --- a/src/org/apache/bcel/verifier/exc/InvalidMethodException.java +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright 2000-2004 The Apache Software Foundation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ -package org.apache.bcel.verifier.exc; - -/** - * Instances of this class are thrown by BCEL's class file verifier "JustIce" - * when the verification of a method is requested that does not exist. - * - * @version $Id: InvalidMethodException.java 371539 2006-01-23 14:08:00Z tcurdt $ - * @author Enver Haase - */ -public class InvalidMethodException extends RuntimeException{ - - /** Constructs an InvalidMethodException with the specified detail message. */ - public InvalidMethodException(String message){ - super(message); - } -} diff --git a/src/org/apache/bcel/verifier/exc/LinkingConstraintException.java b/src/org/apache/bcel/verifier/exc/LinkingConstraintException.java deleted file mode 100644 index 63cee55..0000000 --- a/src/org/apache/bcel/verifier/exc/LinkingConstraintException.java +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright 2000-2004 The Apache Software Foundation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ -package org.apache.bcel.verifier.exc; - -/** - * Instances of this class are thrown by BCEL's class file verifier "JustIce" when - * a class file to verify does not pass the verification pass 3 because of a violation - * of a constraint that is usually only verified at run-time (pass 4). - * The Java Virtual Machine Specification, 2nd edition, states that certain constraints - * are usually verified at run-time for performance reasons (the verification of those - * constraints requires loading in and recursively verifying referenced classes) that - * conceptually belong to pass 3; to be precise, that conceptually belong to the - * data flow analysis of pass 3 (called pass 3b in JustIce). - * These are the checks necessary for resolution: Compare pages 142-143 ("4.9.1 The - * Verification Process") and pages 50-51 ("2.17.3 Linking: Verification, Preparation, - * and Resolution") of the above mentioned book. - * TODO: At this time, this class is not used in JustIce. - * - * @version $Id: LinkingConstraintException.java 371539 2006-01-23 14:08:00Z tcurdt $ - * @author Enver Haase - */ -public class LinkingConstraintException extends StructuralCodeConstraintException{ -} diff --git a/src/org/apache/bcel/verifier/exc/LoadingException.java b/src/org/apache/bcel/verifier/exc/LoadingException.java deleted file mode 100644 index 7d9d769..0000000 --- a/src/org/apache/bcel/verifier/exc/LoadingException.java +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright 2000-2004 The Apache Software Foundation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ -package org.apache.bcel.verifier.exc; - - -/** - * When loading a class file, BCEL will throw an instance of LoadingException if - * the class file is malformed; so it is not conforming to the "Pass 1" verification - * process as described in the Java Virtual Machine specification, 2nd. edition. - * @version $Id: LoadingException.java 371539 2006-01-23 14:08:00Z tcurdt $ - * @author Enver Haase - */ -public class LoadingException extends VerifierConstraintViolatedException{ - - /** - * Constructs a new LoadingException with null as its error message string. - */ - public LoadingException(){ - super(); - } - - /** - * Constructs a new LoadingException with the specified error message. - */ - public LoadingException(String message){ - super (message); - } -} diff --git a/src/org/apache/bcel/verifier/exc/LocalVariableInfoInconsistentException.java b/src/org/apache/bcel/verifier/exc/LocalVariableInfoInconsistentException.java deleted file mode 100644 index ca5fa5d..0000000 --- a/src/org/apache/bcel/verifier/exc/LocalVariableInfoInconsistentException.java +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright 2000-2004 The Apache Software Foundation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ -package org.apache.bcel.verifier.exc; - - -/** - * A LocalVariableInfoInconsistentException instance is thrown by - * the LocalVariableInfo class when it detects that the information - * it holds is inconsistent; this is normally due to inconsistent - * LocalVariableTable entries in the Code attribute of a certain - * Method object. - * - * @version $Id: LocalVariableInfoInconsistentException.java 371539 2006-01-23 14:08:00Z tcurdt $ - * @author Enver Haase - */ -public class LocalVariableInfoInconsistentException extends ClassConstraintException{ - /** - * Constructs a new LocalVariableInfoInconsistentException with null as its error message string. - */ - public LocalVariableInfoInconsistentException(){ - super(); - } - - /** - * Constructs a new LocalVariableInfoInconsistentException with the specified error message. - */ - public LocalVariableInfoInconsistentException(String message){ - super (message); - } -} diff --git a/src/org/apache/bcel/verifier/exc/StaticCodeConstraintException.java b/src/org/apache/bcel/verifier/exc/StaticCodeConstraintException.java deleted file mode 100644 index ca4859b..0000000 --- a/src/org/apache/bcel/verifier/exc/StaticCodeConstraintException.java +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright 2000-2004 The Apache Software Foundation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ -package org.apache.bcel.verifier.exc; - - -/** - * Instances of this class are thrown by BCEL's class file verifier "JustIce" when - * a class file to verify does not pass the verification pass 3 because of a violation - * of a static constraint as described in the Java Virtual Machine Specification, - * 2nd edition, 4.8.1, pages 133-137. The static constraints checking part of pass 3 - * is called pass 3a in JustIce. - * - * @version $Id: StaticCodeConstraintException.java 371539 2006-01-23 14:08:00Z tcurdt $ - * @author Enver Haase - */ -public abstract class StaticCodeConstraintException extends CodeConstraintException{ - public StaticCodeConstraintException(String message){ - super(message); - } -} diff --git a/src/org/apache/bcel/verifier/exc/StaticCodeInstructionConstraintException.java b/src/org/apache/bcel/verifier/exc/StaticCodeInstructionConstraintException.java deleted file mode 100644 index ce733ea..0000000 --- a/src/org/apache/bcel/verifier/exc/StaticCodeInstructionConstraintException.java +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright 2000-2004 The Apache Software Foundation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ -package org.apache.bcel.verifier.exc; - - -/** - * Instances of this class are thrown by BCEL's class file verifier "JustIce" when - * a class file to verify does not pass the verification pass 3 because of a violation - * of a static constraint as described in the Java Virtual Machine Specification, - * Second edition, 4.8.1, pages 133-137. The static constraints checking part of pass 3 - * is called pass 3a in JustIce. - * Static constraints on the instructions in the code array are checked early in - * pass 3a and are described on page 134 in the Java Virtual Machine Specification, - * Second Edition. - * - * @version $Id: StaticCodeInstructionConstraintException.java 371539 2006-01-23 14:08:00Z tcurdt $ - * @author Enver Haase - */ -public class StaticCodeInstructionConstraintException extends StaticCodeConstraintException{ - public StaticCodeInstructionConstraintException(String message){ - super(message); - } -} diff --git a/src/org/apache/bcel/verifier/exc/StaticCodeInstructionOperandConstraintException.java b/src/org/apache/bcel/verifier/exc/StaticCodeInstructionOperandConstraintException.java deleted file mode 100644 index 25afb89..0000000 --- a/src/org/apache/bcel/verifier/exc/StaticCodeInstructionOperandConstraintException.java +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright 2000-2004 The Apache Software Foundation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ -package org.apache.bcel.verifier.exc; - - -/** - * Instances of this class are thrown by BCEL's class file verifier "JustIce" when - * a class file to verify does not pass the verification pass 3 because of a violation - * of a static constraint as described in the Java Virtual Machine Specification, - * Second edition, 4.8.1, pages 133-137. The static constraints checking part of pass 3 - * is called pass 3a in JustIce. - * Static constraints on the operands of instructions in the code array are checked late in - * pass 3a and are described on page 134-137 in the Java Virtual Machine Specification, - * Second Edition. - * - * @version $Id: StaticCodeInstructionOperandConstraintException.java 371539 2006-01-23 14:08:00Z tcurdt $ - * @author Enver Haase - */ -public class StaticCodeInstructionOperandConstraintException extends StaticCodeConstraintException{ - public StaticCodeInstructionOperandConstraintException(String message){ - super(message); - } -} diff --git a/src/org/apache/bcel/verifier/exc/StructuralCodeConstraintException.java b/src/org/apache/bcel/verifier/exc/StructuralCodeConstraintException.java deleted file mode 100644 index 0cfbe99..0000000 --- a/src/org/apache/bcel/verifier/exc/StructuralCodeConstraintException.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright 2000-2004 The Apache Software Foundation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ -package org.apache.bcel.verifier.exc; - -/** - * Instances of this class are thrown by BCEL's class file verifier "JustIce" when - * a class file to verify does not pass the verification pass 3 because of a violation - * of a structural constraint as described in the Java Virtual Machine Specification, - * 2nd edition, 4.8.2, pages 137-139. - * Note that the notion of a "structural" constraint is somewhat misleading. Structural - * constraints are constraints on relationships between Java virtual machine instructions. - * These are the constraints where data-flow analysis is needed to verify if they hold. - * The data flow analysis of pass 3 is called pass 3b in JustIce. - * - * @version $Id: StructuralCodeConstraintException.java 371539 2006-01-23 14:08:00Z tcurdt $ - * @author Enver Haase - */ -public class StructuralCodeConstraintException extends CodeConstraintException{ - /** - * Constructs a new StructuralCodeConstraintException with the specified error message. - */ - public StructuralCodeConstraintException(String message){ - super(message); - } - /** - * Constructs a new StructuralCodeConstraintException with null as its error message string. - */ - public StructuralCodeConstraintException(){ - super(); - } -} diff --git a/src/org/apache/bcel/verifier/exc/Utility.java b/src/org/apache/bcel/verifier/exc/Utility.java deleted file mode 100644 index ac0b999..0000000 --- a/src/org/apache/bcel/verifier/exc/Utility.java +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright 2000-2004 The Apache Software Foundation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ -package org.apache.bcel.verifier.exc; - - -import java.io.PrintWriter; -import java.io.StringWriter; - -/** - * A utility class providing convenience methods concerning Throwable instances. - * @version $Id: Utility.java 371539 2006-01-23 14:08:00Z tcurdt $ - * @author Enver Haase - * @see java.lang.Throwable - */ -public final class Utility{ - /** This class is not instantiable. */ - private Utility(){} - - /** This method returns the stack trace of a Throwable instance as a String. */ - public static String getStackTrace(Throwable t){ - StringWriter sw = new StringWriter(); - PrintWriter pw = new PrintWriter(sw); - t.printStackTrace(pw); - return sw.toString(); - } -} diff --git a/src/org/apache/bcel/verifier/exc/VerificationException.java b/src/org/apache/bcel/verifier/exc/VerificationException.java deleted file mode 100644 index 241c519..0000000 --- a/src/org/apache/bcel/verifier/exc/VerificationException.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright 2000-2004 The Apache Software Foundation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ -package org.apache.bcel.verifier.exc; - - -/** - * Instances of this class are thrown by BCEL's class file verifier "JustIce" when a - * class file to verify does not pass one of the verification passes 2 or 3. - * Note that the pass 3 used by "JustIce" involves verification that is usually - * delayed to pass 4. - * The name of this class is justified by the Java Virtual Machine Specification, 2nd - * edition, page 164, 5.4.1 where verification as a part of the linking process is - * defined to be the verification happening in passes 2 and 3. - * - * @version $Id: VerificationException.java 371539 2006-01-23 14:08:00Z tcurdt $ - * @author Enver Haase - */ -public abstract class VerificationException extends VerifierConstraintViolatedException{ - /** - * Constructs a new VerificationException with null as its error message string. - */ - VerificationException(){ - super(); - } - /** - * Constructs a new VerificationException with the specified error message. - */ - VerificationException(String message){ - super(message); - } -} diff --git a/src/org/apache/bcel/verifier/exc/VerifierConstraintViolatedException.java b/src/org/apache/bcel/verifier/exc/VerifierConstraintViolatedException.java deleted file mode 100644 index cdb2d54..0000000 --- a/src/org/apache/bcel/verifier/exc/VerifierConstraintViolatedException.java +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Copyright 2000-2004 The Apache Software Foundation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ -package org.apache.bcel.verifier.exc; - - -/** - * Instances of this class are thrown by BCEL's class file verifier "JustIce" - * whenever - * verification proves that some constraint of a class file (as stated in the - * Java Virtual Machine Specification, Edition 2) is violated. - * This is roughly equivalent to the VerifyError the JVM-internal verifiers - * throw. - * - * @version $Id: VerifierConstraintViolatedException.java 386056 2006-03-15 11:31:56Z tcurdt $ - * @author Enver Haase - */ -public abstract class VerifierConstraintViolatedException extends RuntimeException{ - // /** The name of the offending class that did not pass the verifier. */ - // String name_of_offending_class; - - /** The specified error message. */ - private String detailMessage; - /** - * Constructs a new VerifierConstraintViolatedException with null as its error message string. - */ - VerifierConstraintViolatedException(){ - super(); - } - /** - * Constructs a new VerifierConstraintViolatedException with the specified error message. - */ - VerifierConstraintViolatedException(String message){ - super(message); // Not that important - detailMessage = message; - } - - - /** Extends the error message with a string before ("pre") and after ("post") the - 'old' error message. All of these three strings are allowed to be null, and null - is always replaced by the empty string (""). In particular, after invoking this - method, the error message of this object can no longer be null. - */ - public void extendMessage(String pre, String post){ - if (pre == null) { - pre=""; - } - if (detailMessage == null) { - detailMessage=""; - } - if (post == null) { - post=""; - } - detailMessage = pre+detailMessage+post; - } - /** - * Returns the error message string of this VerifierConstraintViolatedException object. - * @return the error message string of this VerifierConstraintViolatedException. - */ - public String getMessage(){ - return detailMessage; - } -} diff --git a/src/org/apache/bcel/verifier/exc/package.html b/src/org/apache/bcel/verifier/exc/package.html deleted file mode 100644 index fc22276..0000000 --- a/src/org/apache/bcel/verifier/exc/package.html +++ /dev/null @@ -1,17 +0,0 @@ - - - - - - - -Exception classes used by JustIce, mostly used internally. You don't need to bother with them. - -

Package Specification

- -Contained in this package are Exception classes for use with the JustIce verifier. - - - diff --git a/src/org/apache/bcel/verifier/package.html b/src/org/apache/bcel/verifier/package.html deleted file mode 100644 index 9f31ef5..0000000 --- a/src/org/apache/bcel/verifier/package.html +++ /dev/null @@ -1,18 +0,0 @@ - - - - - - - -BCEL's verifier JustIce is there to help you dump correct Java class files created or modified with BCEL. - -

Package Specification

- -This is the top-level package of the JustIce verifier. To actually use it, have a look at the VerifierFactory and -Verifier classes. - - - diff --git a/src/org/apache/bcel/verifier/statics/DOUBLE_Upper.java b/src/org/apache/bcel/verifier/statics/DOUBLE_Upper.java deleted file mode 100644 index 2a104b3..0000000 --- a/src/org/apache/bcel/verifier/statics/DOUBLE_Upper.java +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright 2000-2004 The Apache Software Foundation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ -package org.apache.bcel.verifier.statics; - - -import org.apache.bcel.Constants; -import org.apache.bcel.generic.Type; - -/** - * This class represents the upper half of a DOUBLE variable. - * @version $Id: DOUBLE_Upper.java 371539 2006-01-23 14:08:00Z tcurdt $ - * @author Enver Haase - */ -public final class DOUBLE_Upper extends Type{ - - /** The one and only instance of this class. */ - private static DOUBLE_Upper singleInstance = new DOUBLE_Upper(); - - /** The constructor; this class must not be instantiated from the outside. */ - private DOUBLE_Upper(){ - super(Constants.T_UNKNOWN, "Long_Upper"); - } - - /** Use this method to get the single instance of this class. */ - public static DOUBLE_Upper theInstance(){ - return singleInstance; - } -} diff --git a/src/org/apache/bcel/verifier/statics/IntList.java b/src/org/apache/bcel/verifier/statics/IntList.java deleted file mode 100644 index 5a4a9d2..0000000 --- a/src/org/apache/bcel/verifier/statics/IntList.java +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright 2000-2004 The Apache Software Foundation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ -package org.apache.bcel.verifier.statics; - - -import java.util.ArrayList; -import java.util.List; - -/** - * A small utility class representing a set of basic int values. - * - * @version $Id: IntList.java 386056 2006-03-15 11:31:56Z tcurdt $ - * @author Enver Haase - */ -public class IntList{ - /** The int are stored as Integer objects here. */ - private List theList; - /** This constructor creates an empty list. */ - IntList(){ - theList = new ArrayList(); - } - /** Adds an element to the list. */ - void add(int i){ - theList.add(new Integer(i)); - } - /** Checks if the specified int is already in the list. */ - boolean contains(int i){ - Integer[] ints = new Integer[theList.size()]; - theList.toArray(ints); - for (int j=0; j= localVariableInfos.length){ - throw new AssertionViolatedException("Slot number for local variable information out of range."); - } - return localVariableInfos[slot]; - } - - /** - * Adds information about the local variable in slot 'slot'. Automatically - * adds information for slot+1 if 't' is Type.LONG or Type.DOUBLE. - * @throws LocalVariableInfoInconsistentException if the new information conflicts - * with already gathered information. - */ - public void add(int slot, String name, int startpc, int length, Type t) throws LocalVariableInfoInconsistentException{ - // The add operation on LocalVariableInfo may throw the '...Inconsistent...' exception, we don't throw it explicitely here. - - if (slot < 0 || slot >= localVariableInfos.length){ - throw new AssertionViolatedException("Slot number for local variable information out of range."); - } - - localVariableInfos[slot].add(name, startpc, length, t); - if (t == Type.LONG) { - localVariableInfos[slot+1].add(name, startpc, length, LONG_Upper.theInstance()); - } - if (t == Type.DOUBLE) { - localVariableInfos[slot+1].add(name, startpc, length, DOUBLE_Upper.theInstance()); - } - } -} diff --git a/src/org/apache/bcel/verifier/statics/Pass1Verifier.java b/src/org/apache/bcel/verifier/statics/Pass1Verifier.java deleted file mode 100644 index 5952589..0000000 --- a/src/org/apache/bcel/verifier/statics/Pass1Verifier.java +++ /dev/null @@ -1,185 +0,0 @@ -/* - * Copyright 2000-2004 The Apache Software Foundation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ -package org.apache.bcel.verifier.statics; - - -import org.apache.bcel.Repository; -import org.apache.bcel.classfile.ClassFormatException; -import org.apache.bcel.classfile.JavaClass; -import org.apache.bcel.verifier.PassVerifier; -import org.apache.bcel.verifier.VerificationResult; -import org.apache.bcel.verifier.Verifier; -import org.apache.bcel.verifier.exc.LoadingException; -import org.apache.bcel.verifier.exc.Utility; - -/** - * This PassVerifier verifies a class file according to pass 1 as - * described in The Java Virtual Machine Specification, 2nd edition. - * More detailed information is to be found at the do_verify() method's - * documentation. - * - * @version $Id: Pass1Verifier.java 371539 2006-01-23 14:08:00Z tcurdt $ - * @author Enver Haase - * @see #do_verify() - */ -public final class Pass1Verifier extends PassVerifier{ - /** - * DON'T USE THIS EVEN PRIVATELY! USE getJavaClass() INSTEAD. - * @see #getJavaClass() - */ - private JavaClass jc; - - /** - * The Verifier that created this. - */ - private Verifier myOwner; - - /** Used to load in and return the myOwner-matching JavaClass object when needed. Avoids loading in a class file when it's not really needed! */ - private JavaClass getJavaClass(){ - if (jc == null){ - try { - jc = Repository.lookupClass(myOwner.getClassName()); - } catch (ClassNotFoundException e) { - // FIXME: currently, Pass1Verifier treats jc == null as a special - // case, so we don't need to do anything here. A better solution - // would be to simply throw the ClassNotFoundException - // out of this method. - } - } - return jc; - } - - /** - * Should only be instantiated by a Verifier. - * - * @see org.apache.bcel.verifier.Verifier - */ - public Pass1Verifier(Verifier owner){ - myOwner = owner; - } - - /** - * Pass-one verification basically means loading in a class file. - * The Java Virtual Machine Specification is not too precise about - * what makes the difference between passes one and two. - * The answer is that only pass one is performed on a class file as - * long as its resolution is not requested; whereas pass two and - * pass three are performed during the resolution process. - * Only four constraints to be checked are explicitely stated by - * The Java Virtual Machine Specification, 2nd edition: - *
    - *
  • The first four bytes must contain the right magic number (0xCAFEBABE). - *
  • All recognized attributes must be of the proper length. - *
  • The class file must not be truncated or have extra bytes at the end. - *
  • The constant pool must not contain any superficially unrecognizable information. - *
- * A more in-depth documentation of what pass one should do was written by - * Philip W. L. Fong: - *
    - *
  • the file should not be truncated. - *
  • the file should not have extra bytes at the end. - *
  • all variable-length structures should be well-formatted: - *
      - *
    • there should only be constant_pool_count-1 many entries in the constant pool. - *
    • all constant pool entries should have size the same as indicated by their type tag. - *
    • there are exactly interfaces_count many entries in the interfaces array of the class file. - *
    • there are exactly fields_count many entries in the fields array of the class file. - *
    • there are exactly methods_count many entries in the methods array of the class file. - *
    • there are exactly attributes_count many entries in the attributes array of the class file, fields, methods, and code attribute. - *
    • there should be exactly attribute_length many bytes in each attribute. Inconsistency between attribute_length and the actually size of the attribute content should be uncovered. For example, in an Exceptions attribute, the actual number of exceptions as required by the number_of_exceptions field might yeild an attribute size that doesn't match the attribute_length. Such an anomaly should be detected. - *
    • all attributes should have proper length. In particular, under certain context (e.g. while parsing method_info), recognizable attributes (e.g. "Code" attribute) should have correct format (e.g. attribute_length is 2). - *
    - *
  • Also, certain constant values are checked for validity: - *
      - *
    • The magic number should be 0xCAFEBABE. - *
    • The major and minor version numbers are valid. - *
    • All the constant pool type tags are recognizable. - *
    • All undocumented access flags are masked off before use. Strictly speaking, this is not really a check. - *
    • The field this_class should point to a string that represents a legal non-array class name, and this name should be the same as the class file being loaded. - *
    • the field super_class should point to a string that represents a legal non-array class name. - *
    • Because some of the above checks require cross referencing the constant pool entries, guards are set up to make sure that the referenced entries are of the right type and the indices are within the legal range (0 < index < constant_pool_count). - *
    - *
  • Extra checks done in pass 1: - *
      - *
    • the constant values of static fields should have the same type as the fields. - *
    • the number of words in a parameter list does not exceed 255 and locals_max. - *
    • the name and signature of fields and methods are verified to be of legal format. - *
    - *
- * (From the Paper The Mysterious Pass One, first draft, September 2, 1997.) - *
- * However, most of this is done by parsing a class file or generating a class file into BCEL's internal data structure. - * Therefore, all that is really done here is look up the class file from BCEL's repository. - * This is also motivated by the fact that some omitted things - * (like the check for extra bytes at the end of the class file) are handy when actually using BCEL to repair a class file (otherwise you would not be - * able to load it into BCEL). - * - * @see org.apache.bcel.Repository - */ - public VerificationResult do_verify(){ - JavaClass jc; - try{ - jc = getJavaClass(); //loads in the class file if not already done. - - if (jc != null){ - /* If we find more constraints to check, we should do this in an own method. */ - if (! myOwner.getClassName().equals(jc.getClassName())){ - // This should maybe caught by BCEL: In case of renamed .class files we get wrong - // JavaClass objects here. - throw new LoadingException("Wrong name: the internal name of the .class file '"+jc.getClassName()+"' does not match the file's name '"+myOwner.getClassName()+"'."); - } - } - - } - catch(LoadingException e){ - return new VerificationResult(VerificationResult.VERIFIED_REJECTED, e.getMessage()); - } - catch(ClassFormatException e){ - return new VerificationResult(VerificationResult.VERIFIED_REJECTED, e.getMessage()); - } - catch(RuntimeException e){ - // BCEL does not catch every possible RuntimeException; e.g. if - // a constant pool index is referenced that does not exist. - return new VerificationResult(VerificationResult.VERIFIED_REJECTED, "Parsing via BCEL did not succeed. "+e.getClass().getName()+" occured:\n"+Utility.getStackTrace(e)); - } - - if (jc != null){ - return VerificationResult.VR_OK; - } - else{ - //TODO: Maybe change Repository's behaviour to throw a LoadingException instead of just returning "null" - // if a class file cannot be found or in another way be looked up. - return new VerificationResult(VerificationResult.VERIFIED_REJECTED, "Repository.lookup() failed. FILE NOT FOUND?"); - } - } - - /** - * Currently this returns an empty array of String. - * One could parse the error messages of BCEL - * (written to java.lang.System.err) when loading - * a class file such as detecting unknown attributes - * or trailing garbage at the end of a class file. - * However, Markus Dahm does not like the idea so this - * method is currently useless and therefore marked as - * TODO. - */ - public String[] getMessages(){ - // This method is only here to override the javadoc-comment. - return super.getMessages(); - } - -} diff --git a/src/org/apache/bcel/verifier/statics/Pass2Verifier.java b/src/org/apache/bcel/verifier/statics/Pass2Verifier.java deleted file mode 100644 index 4294229..0000000 --- a/src/org/apache/bcel/verifier/statics/Pass2Verifier.java +++ /dev/null @@ -1,1444 +0,0 @@ -/* - * Copyright 2000-2004 The Apache Software Foundation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ -package org.apache.bcel.verifier.statics; - - -import java.util.HashMap; -import java.util.HashSet; -import java.util.Locale; -import java.util.Map; -import java.util.Set; -import org.apache.bcel.Constants; -import org.apache.bcel.Repository; -import org.apache.bcel.classfile.Attribute; -import org.apache.bcel.classfile.ClassFormatException; -import org.apache.bcel.classfile.Code; -import org.apache.bcel.classfile.CodeException; -import org.apache.bcel.classfile.Constant; -import org.apache.bcel.classfile.ConstantClass; -import org.apache.bcel.classfile.ConstantDouble; -import org.apache.bcel.classfile.ConstantFieldref; -import org.apache.bcel.classfile.ConstantFloat; -import org.apache.bcel.classfile.ConstantInteger; -import org.apache.bcel.classfile.ConstantInterfaceMethodref; -import org.apache.bcel.classfile.ConstantLong; -import org.apache.bcel.classfile.ConstantMethodref; -import org.apache.bcel.classfile.ConstantNameAndType; -import org.apache.bcel.classfile.ConstantPool; -import org.apache.bcel.classfile.ConstantString; -import org.apache.bcel.classfile.ConstantUtf8; -import org.apache.bcel.classfile.ConstantValue; -import org.apache.bcel.classfile.Deprecated; -import org.apache.bcel.classfile.DescendingVisitor; -import org.apache.bcel.classfile.EmptyVisitor; -import org.apache.bcel.classfile.ExceptionTable; -import org.apache.bcel.classfile.Field; -import org.apache.bcel.classfile.InnerClass; -import org.apache.bcel.classfile.InnerClasses; -import org.apache.bcel.classfile.JavaClass; -import org.apache.bcel.classfile.LineNumber; -import org.apache.bcel.classfile.LineNumberTable; -import org.apache.bcel.classfile.LocalVariable; -import org.apache.bcel.classfile.LocalVariableTable; -import org.apache.bcel.classfile.Method; -import org.apache.bcel.classfile.Node; -import org.apache.bcel.classfile.SourceFile; -import org.apache.bcel.classfile.Synthetic; -import org.apache.bcel.classfile.Unknown; -import org.apache.bcel.classfile.Visitor; -import org.apache.bcel.generic.ArrayType; -import org.apache.bcel.generic.ObjectType; -import org.apache.bcel.generic.Type; -import org.apache.bcel.verifier.PassVerifier; -import org.apache.bcel.verifier.VerificationResult; -import org.apache.bcel.verifier.Verifier; -import org.apache.bcel.verifier.VerifierFactory; -import org.apache.bcel.verifier.exc.AssertionViolatedException; -import org.apache.bcel.verifier.exc.ClassConstraintException; -import org.apache.bcel.verifier.exc.LocalVariableInfoInconsistentException; - -/** - * This PassVerifier verifies a class file according to - * pass 2 as described in The Java Virtual Machine - * Specification, 2nd edition. - * More detailed information is to be found at the do_verify() - * method's documentation. - * - * @version $Id: Pass2Verifier.java 386056 2006-03-15 11:31:56Z tcurdt $ - * @author Enver Haase - * @see #do_verify() - */ -public final class Pass2Verifier extends PassVerifier implements Constants{ - - /** - * The LocalVariableInfo instances used by Pass3bVerifier. - * localVariablesInfos[i] denotes the information for the - * local variables of method number i in the - * JavaClass this verifier operates on. - */ - private LocalVariablesInfo[] localVariablesInfos; - - /** The Verifier that created this. */ - private Verifier myOwner; - - /** - * Should only be instantiated by a Verifier. - * - * @see Verifier - */ - public Pass2Verifier(Verifier owner){ - myOwner = owner; - } - - /** - * Returns a LocalVariablesInfo object containing information - * about the usage of the local variables in the Code attribute - * of the said method or null if the class file this - * Pass2Verifier operates on could not be pass-2-verified correctly. - * The method number method_nr is the method you get using - * Repository.lookupClass(myOwner.getClassname()).getMethods()[method_nr];. - * You should not add own information. Leave that to JustIce. - */ - public LocalVariablesInfo getLocalVariablesInfo(int method_nr){ - if (this.verify() != VerificationResult.VR_OK) { - return null; // It's cached, don't worry. - } - if (method_nr < 0 || method_nr >= localVariablesInfos.length){ - throw new AssertionViolatedException("Method number out of range."); - } - return localVariablesInfos[method_nr]; - } - - /** - * Pass 2 is the pass where static properties of the - * class file are checked without looking into "Code" - * arrays of methods. - * This verification pass is usually invoked when - * a class is resolved; and it may be possible that - * this verification pass has to load in other classes - * such as superclasses or implemented interfaces. - * Therefore, Pass 1 is run on them.
- * Note that most referenced classes are not loaded - * in for verification or for an existance check by this - * pass; only the syntactical correctness of their names - * and descriptors (a.k.a. signatures) is checked.
- * Very few checks that conceptually belong here - * are delayed until pass 3a in JustIce. JustIce does - * not only check for syntactical correctness but also - * for semantical sanity - therefore it needs access to - * the "Code" array of methods in a few cases. Please - * see the pass 3a documentation, too. - * - * @see org.apache.bcel.verifier.statics.Pass3aVerifier - */ - public VerificationResult do_verify(){ - try { - VerificationResult vr1 = myOwner.doPass1(); - if (vr1.equals(VerificationResult.VR_OK)){ - - // For every method, we could have information about the local variables out of LocalVariableTable attributes of - // the Code attributes. - localVariablesInfos = new LocalVariablesInfo[Repository.lookupClass(myOwner.getClassName()).getMethods().length]; - - VerificationResult vr = VerificationResult.VR_OK; // default. - try{ - constant_pool_entries_satisfy_static_constraints(); - field_and_method_refs_are_valid(); - every_class_has_an_accessible_superclass(); - final_methods_are_not_overridden(); - } - catch (ClassConstraintException cce){ - vr = new VerificationResult(VerificationResult.VERIFIED_REJECTED, cce.getMessage()); - } - return vr; - } else { - return VerificationResult.VR_NOTYET; - } - - } catch (ClassNotFoundException e) { - // FIXME: this might not be the best way to handle missing classes. - throw new AssertionViolatedException("Missing class: " + e.toString()); - } - } - - /** - * Ensures that every class has a super class and that - * final classes are not subclassed. - * This means, the class this Pass2Verifier operates - * on has proper super classes (transitively) up to - * java.lang.Object. - * The reason for really loading (and Pass1-verifying) - * all of those classes here is that we need them in - * Pass2 anyway to verify no final methods are overridden - * (that could be declared anywhere in the ancestor hierarchy). - * - * @throws ClassConstraintException otherwise. - */ - private void every_class_has_an_accessible_superclass(){ - try { - Set hs = new HashSet(); // save class names to detect circular inheritance - JavaClass jc = Repository.lookupClass(myOwner.getClassName()); - int supidx = -1; - - while (supidx != 0){ - supidx = jc.getSuperclassNameIndex(); - - if (supidx == 0){ - if (jc != Repository.lookupClass(Type.OBJECT.getClassName())){ - throw new ClassConstraintException("Superclass of '"+jc.getClassName()+"' missing but not "+Type.OBJECT.getClassName()+" itself!"); - } - } - else{ - String supername = jc.getSuperclassName(); - if (! hs.add(supername)){ // If supername already is in the list - throw new ClassConstraintException("Circular superclass hierarchy detected."); - } - Verifier v = VerifierFactory.getVerifier(supername); - VerificationResult vr = v.doPass1(); - - if (vr != VerificationResult.VR_OK){ - throw new ClassConstraintException("Could not load in ancestor class '"+supername+"'."); - } - jc = Repository.lookupClass(supername); - - if (jc.isFinal()){ - throw new ClassConstraintException("Ancestor class '"+supername+"' has the FINAL access modifier and must therefore not be subclassed."); - } - } - } - - } catch (ClassNotFoundException e) { - // FIXME: this might not be the best way to handle missing classes. - throw new AssertionViolatedException("Missing class: " + e.toString()); - } - } - - /** - * Ensures that final methods are not overridden. - * Precondition to run this method: - * constant_pool_entries_satisfy_static_constraints() and - * every_class_has_an_accessible_superclass() have to be invoked before - * (in that order). - * - * @throws ClassConstraintException otherwise. - * @see #constant_pool_entries_satisfy_static_constraints() - * @see #every_class_has_an_accessible_superclass() - */ - private void final_methods_are_not_overridden(){ - try { - Map hashmap = new HashMap(); - JavaClass jc = Repository.lookupClass(myOwner.getClassName()); - - int supidx = -1; - while (supidx != 0){ - supidx = jc.getSuperclassNameIndex(); - - Method[] methods = jc.getMethods(); - for (int i=0; i= cplen)){ - throw new ClassConstraintException("Invalid index '"+index+"' used by '"+tostring(referrer)+"'."); - } - Constant c = cp.getConstant(index); - if (! shouldbe.isInstance(c)){ - /* String isnot = shouldbe.toString().substring(shouldbe.toString().lastIndexOf(".")+1); //Cut all before last "." */ - throw new ClassCastException("Illegal constant '"+tostring(c)+"' at index '"+index+"'. '"+tostring(referrer)+"' expects a '"+shouldbe+"'."); - } - } - /////////////////////////////////////// - // ClassFile structure (vmspec2 4.1) // - /////////////////////////////////////// - public void visitJavaClass(JavaClass obj){ - Attribute[] atts = obj.getAttributes(); - boolean foundSourceFile = false; - boolean foundInnerClasses = false; - - // Is there an InnerClass referenced? - // This is a costly check; existing verifiers don't do it! - boolean hasInnerClass = new InnerClassDetector(jc).innerClassReferenced(); - - for (int i=0; i 1){ - throw new ClassConstraintException("Field '"+tostring(obj)+"' must only have at most one of its ACC_PRIVATE, ACC_PROTECTED, ACC_PUBLIC modifiers set."); - } - - if (obj.isFinal() && obj.isVolatile()){ - throw new ClassConstraintException("Field '"+tostring(obj)+"' must only have at most one of its ACC_FINAL, ACC_VOLATILE modifiers set."); - } - } - else{ // isInterface! - if (!obj.isPublic()){ - throw new ClassConstraintException("Interface field '"+tostring(obj)+"' must have the ACC_PUBLIC modifier set but hasn't!"); - } - if (!obj.isStatic()){ - throw new ClassConstraintException("Interface field '"+tostring(obj)+"' must have the ACC_STATIC modifier set but hasn't!"); - } - if (!obj.isFinal()){ - throw new ClassConstraintException("Interface field '"+tostring(obj)+"' must have the ACC_FINAL modifier set but hasn't!"); - } - } - - if ((obj.getAccessFlags() & ~(ACC_PUBLIC|ACC_PRIVATE|ACC_PROTECTED|ACC_STATIC|ACC_FINAL|ACC_VOLATILE|ACC_TRANSIENT)) > 0){ - addMessage("Field '"+tostring(obj)+"' has access flag(s) other than ACC_PUBLIC, ACC_PRIVATE, ACC_PROTECTED, ACC_STATIC, ACC_FINAL, ACC_VOLATILE, ACC_TRANSIENT set (ignored)."); - } - - checkIndex(obj, obj.getNameIndex(), CONST_Utf8); - - String name = obj.getName(); - if (! validFieldName(name)){ - throw new ClassConstraintException("Field '"+tostring(obj)+"' has illegal name '"+obj.getName()+"'."); - } - - // A descriptor is often named signature in BCEL - checkIndex(obj, obj.getSignatureIndex(), CONST_Utf8); - - String sig = ((ConstantUtf8) (cp.getConstant(obj.getSignatureIndex()))).getBytes(); // Field or Method signature(=descriptor) - - try{ - Type.getType(sig); /* Don't need the return value */ - } - catch (ClassFormatException cfe){ - throw new ClassConstraintException("Illegal descriptor (==signature) '"+sig+"' used by '"+tostring(obj)+"'."); - } - - String nameanddesc = (name+sig); - if (field_names_and_desc.contains(nameanddesc)){ - throw new ClassConstraintException("No two fields (like '"+tostring(obj)+"') are allowed have same names and descriptors!"); - } - if (field_names.contains(name)){ - addMessage("More than one field of name '"+name+"' detected (but with different type descriptors). This is very unusual."); - } - field_names_and_desc.add(nameanddesc); - field_names.add(name); - - Attribute[] atts = obj.getAttributes(); - for (int i=0; i 1){ - throw new ClassConstraintException("Method '"+tostring(obj)+"' must only have at most one of its ACC_PRIVATE, ACC_PROTECTED, ACC_PUBLIC modifiers set."); - } - - if (obj.isAbstract()){ - if (obj.isFinal()) { - throw new ClassConstraintException("Abstract method '"+tostring(obj)+"' must not have the ACC_FINAL modifier set."); - } - if (obj.isNative()) { - throw new ClassConstraintException("Abstract method '"+tostring(obj)+"' must not have the ACC_NATIVE modifier set."); - } - if (obj.isPrivate()) { - throw new ClassConstraintException("Abstract method '"+tostring(obj)+"' must not have the ACC_PRIVATE modifier set."); - } - if (obj.isStatic()) { - throw new ClassConstraintException("Abstract method '"+tostring(obj)+"' must not have the ACC_STATIC modifier set."); - } - if (obj.isStrictfp()) { - throw new ClassConstraintException("Abstract method '"+tostring(obj)+"' must not have the ACC_STRICT modifier set."); - } - if (obj.isSynchronized()) { - throw new ClassConstraintException("Abstract method '"+tostring(obj)+"' must not have the ACC_SYNCHRONIZED modifier set."); - } - } - } - else{ // isInterface! - if (!name.equals(STATIC_INITIALIZER_NAME)){//vmspec2, p.116, 2nd paragraph - if (!obj.isPublic()){ - throw new ClassConstraintException("Interface method '"+tostring(obj)+"' must have the ACC_PUBLIC modifier set but hasn't!"); - } - if (!obj.isAbstract()){ - throw new ClassConstraintException("Interface method '"+tostring(obj)+"' must have the ACC_STATIC modifier set but hasn't!"); - } - if ( obj.isPrivate() || - obj.isProtected() || - obj.isStatic() || - obj.isFinal() || - obj.isSynchronized() || - obj.isNative() || - obj.isStrictfp() ){ - throw new ClassConstraintException("Interface method '"+tostring(obj)+"' must not have any of the ACC_PRIVATE, ACC_PROTECTED, ACC_STATIC, ACC_FINAL, ACC_SYNCHRONIZED, ACC_NATIVE, ACC_ABSTRACT, ACC_STRICT modifiers set."); - } - } - } - - // A specific instance initialization method... (vmspec2,Page 116). - if (name.equals(CONSTRUCTOR_NAME)){ - //..may have at most one of ACC_PRIVATE, ACC_PROTECTED, ACC_PUBLIC set: is checked above. - //..may also have ACC_STRICT set, but none of the other flags in table 4.5 (vmspec2, page 115) - if ( obj.isStatic() || - obj.isFinal() || - obj.isSynchronized() || - obj.isNative() || - obj.isAbstract() ){ - throw new ClassConstraintException("Instance initialization method '"+tostring(obj)+"' must not have any of the ACC_STATIC, ACC_FINAL, ACC_SYNCHRONIZED, ACC_NATIVE, ACC_ABSTRACT modifiers set."); - } - } - - // Class and interface initialization methods... - if (name.equals(STATIC_INITIALIZER_NAME)){ - if ((obj.getAccessFlags() & (~ACC_STRICT)) > 0){ - addMessage("Class or interface initialization method '"+tostring(obj)+"' has superfluous access modifier(s) set: everything but ACC_STRICT is ignored."); - } - if (obj.isAbstract()){ - throw new ClassConstraintException("Class or interface initialization method '"+tostring(obj)+"' must not be abstract. This contradicts the Java Language Specification, Second Edition (which omits this constraint) but is common practice of existing verifiers."); - } - } - - if ((obj.getAccessFlags() & ~(ACC_PUBLIC|ACC_PRIVATE|ACC_PROTECTED|ACC_STATIC|ACC_FINAL|ACC_SYNCHRONIZED|ACC_NATIVE|ACC_ABSTRACT|ACC_STRICT)) > 0){ - addMessage("Method '"+tostring(obj)+"' has access flag(s) other than ACC_PUBLIC, ACC_PRIVATE, ACC_PROTECTED, ACC_STATIC, ACC_FINAL, ACC_SYNCHRONIZED, ACC_NATIVE, ACC_ABSTRACT, ACC_STRICT set (ignored)."); - } - - String nameanddesc = (name+sig); - if (method_names_and_desc.contains(nameanddesc)){ - throw new ClassConstraintException("No two methods (like '"+tostring(obj)+"') are allowed have same names and desciptors!"); - } - method_names_and_desc.add(nameanddesc); - - Attribute[] atts = obj.getAttributes(); - int num_code_atts = 0; - for (int i=0; i= cplen)){ - throw new ClassConstraintException("Invalid index '"+index+"' used by '"+tostring(obj)+"'."); - } - Constant c = cp.getConstant(index); - - if (CONST_Long.isInstance(c) && field_type.equals(Type.LONG)){ - return; - } - if (CONST_Float.isInstance(c) && field_type.equals(Type.FLOAT)){ - return; - } - if (CONST_Double.isInstance(c) && field_type.equals(Type.DOUBLE)){ - return; - } - if (CONST_Integer.isInstance(c) && (field_type.equals(Type.INT) || field_type.equals(Type.SHORT) || field_type.equals(Type.CHAR) || field_type.equals(Type.BYTE) || field_type.equals(Type.BOOLEAN))){ - return; - } - if (CONST_String.isInstance(c) && field_type.equals(Type.STRING)){ - return; - } - - throw new ClassConstraintException("Illegal type of ConstantValue '"+obj+"' embedding Constant '"+c+"'. It is referenced by field '"+tostring(f)+"' expecting a different type: '"+field_type+"'."); - } - } - // SYNTHETIC: see above - // DEPRECATED: see above - ///////////////////////////////////////////////////////// - // method_info-structure-ATTRIBUTES (vmspec2 4.6, 4.7) // - ///////////////////////////////////////////////////////// - public void visitCode(Code obj){//vmspec2 4.7.3 - try { - // No code attribute allowed for native or abstract methods: see visitMethod(Method). - // Code array constraints are checked in Pass3 (3a and 3b). - - checkIndex(obj, obj.getNameIndex(), CONST_Utf8); - - String name = ((ConstantUtf8) cp.getConstant(obj.getNameIndex())).getBytes(); - if (! name.equals("Code")){ - throw new ClassConstraintException("The Code attribute '"+tostring(obj)+"' is not correctly named 'Code' but '"+name+"'."); - } - - Method m = null; // satisfy compiler - if (!(carrier.predecessor() instanceof Method)){ - addMessage("Code attribute '"+tostring(obj)+"' is not declared in a method_info structure but in '"+carrier.predecessor()+"'. Ignored."); - return; - } - else{ - m = (Method) carrier.predecessor(); // we can assume this method was visited before; - // i.e. the data consistency was verified. - } - - if (obj.getCode().length == 0){ - throw new ClassConstraintException("Code array of Code attribute '"+tostring(obj)+"' (method '"+m+"') must not be empty."); - } - - //In JustIce, the check for correct offsets into the code array is delayed to Pass 3a. - CodeException[] exc_table = obj.getExceptionTable(); - for (int i=0; i= code.getMaxLocals()){ - throw new ClassConstraintException("LocalVariableTable attribute '"+tostring(lvt)+"' references a LocalVariable '"+tostring(localvariables[i])+"' with an index that exceeds the surrounding Code attribute's max_locals value of '"+code.getMaxLocals()+"'."); - } - - try{ - localVariablesInfos[method_number].add(localindex, localname, localvariables[i].getStartPC(), localvariables[i].getLength(), t); - } - catch(LocalVariableInfoInconsistentException lviie){ - throw new ClassConstraintException("Conflicting information in LocalVariableTable '"+tostring(lvt)+"' found in Code attribute '"+tostring(obj)+"' (method '"+tostring(m)+"'). "+lviie.getMessage()); - } - }// for all local variables localvariables[i] in the LocalVariableTable attribute atts[a] END - - num_of_lvt_attribs++; - if (num_of_lvt_attribs > obj.getMaxLocals()){ - throw new ClassConstraintException("Number of LocalVariableTable attributes of Code attribute '"+tostring(obj)+"' (method '"+tostring(m)+"') exceeds number of local variable slots '"+obj.getMaxLocals()+"' ('There may be no more than one LocalVariableTable attribute per local variable in the Code attribute.')."); - } - }// if atts[a] instanceof LocalVariableTable END - }// for all attributes atts[a] END - - } catch (ClassNotFoundException e) { - // FIXME: this might not be the best way to handle missing classes. - throw new AssertionViolatedException("Missing class: " + e.toString()); - } - - }// visitCode(Code) END - - public void visitExceptionTable(ExceptionTable obj){//vmspec2 4.7.4 - try { - // incorrectly named, it's the Exceptions attribute (vmspec2 4.7.4) - checkIndex(obj, obj.getNameIndex(), CONST_Utf8); - - String name = ((ConstantUtf8) cp.getConstant(obj.getNameIndex())).getBytes(); - if (! name.equals("Exceptions")){ - throw new ClassConstraintException("The Exceptions attribute '"+tostring(obj)+"' is not correctly named 'Exceptions' but '"+name+"'."); - } - - int[] exc_indices = obj.getExceptionIndexTable(); - - for (int i=0; iPrecondition: index-style cross referencing in the constant - * pool must be valid. Simply invoke constant_pool_entries_satisfy_static_constraints() - * before. - * - * @throws ClassConstraintException otherwise. - * @see #constant_pool_entries_satisfy_static_constraints() - */ - private void field_and_method_refs_are_valid(){ - try { - JavaClass jc = Repository.lookupClass(myOwner.getClassName()); - DescendingVisitor v = new DescendingVisitor(jc, new FAMRAV_Visitor(jc)); - v.visit(); - - } catch (ClassNotFoundException e) { - // FIXME: this might not be the best way to handle missing classes. - throw new AssertionViolatedException("Missing class: " + e.toString()); - } - } - - /** - * A Visitor class that ensures the ConstantCP-subclassed entries - * of the constant pool are valid. - * Precondition: index-style cross referencing in the constant - * pool must be valid. - * - * @see #constant_pool_entries_satisfy_static_constraints() - * @see org.apache.bcel.classfile.ConstantCP - */ - private class FAMRAV_Visitor extends EmptyVisitor implements Visitor{ - private final ConstantPool cp; // ==jc.getConstantPool() -- only here to save typing work. - private FAMRAV_Visitor(JavaClass _jc){ - cp = _jc.getConstantPool(); - } - - public void visitConstantFieldref(ConstantFieldref obj){ - if (obj.getTag() != Constants.CONSTANT_Fieldref){ - throw new ClassConstraintException("ConstantFieldref '"+tostring(obj)+"' has wrong tag!"); - } - int name_and_type_index = obj.getNameAndTypeIndex(); - ConstantNameAndType cnat = (ConstantNameAndType) (cp.getConstant(name_and_type_index)); - String name = ((ConstantUtf8) (cp.getConstant(cnat.getNameIndex()))).getBytes(); // Field or Method name - if (!validFieldName(name)){ - throw new ClassConstraintException("Invalid field name '"+name+"' referenced by '"+tostring(obj)+"'."); - } - - int class_index = obj.getClassIndex(); - ConstantClass cc = (ConstantClass) (cp.getConstant(class_index)); - String className = ((ConstantUtf8) (cp.getConstant(cc.getNameIndex()))).getBytes(); // Class Name in internal form - if (! validClassName(className)){ - throw new ClassConstraintException("Illegal class name '"+className+"' used by '"+tostring(obj)+"'."); - } - - String sig = ((ConstantUtf8) (cp.getConstant(cnat.getSignatureIndex()))).getBytes(); // Field or Method signature(=descriptor) - - try{ - Type.getType(sig); /* Don't need the return value */ - } - catch (ClassFormatException cfe){ - throw new ClassConstraintException("Illegal descriptor (==signature) '"+sig+"' used by '"+tostring(obj)+"'."); - } - } - - public void visitConstantMethodref(ConstantMethodref obj){ - if (obj.getTag() != Constants.CONSTANT_Methodref){ - throw new ClassConstraintException("ConstantMethodref '"+tostring(obj)+"' has wrong tag!"); - } - int name_and_type_index = obj.getNameAndTypeIndex(); - ConstantNameAndType cnat = (ConstantNameAndType) (cp.getConstant(name_and_type_index)); - String name = ((ConstantUtf8) (cp.getConstant(cnat.getNameIndex()))).getBytes(); // Field or Method name - if (!validClassMethodName(name)){ - throw new ClassConstraintException("Invalid (non-interface) method name '"+name+"' referenced by '"+tostring(obj)+"'."); - } - - int class_index = obj.getClassIndex(); - ConstantClass cc = (ConstantClass) (cp.getConstant(class_index)); - String className = ((ConstantUtf8) (cp.getConstant(cc.getNameIndex()))).getBytes(); // Class Name in internal form - if (! validClassName(className)){ - throw new ClassConstraintException("Illegal class name '"+className+"' used by '"+tostring(obj)+"'."); - } - - String sig = ((ConstantUtf8) (cp.getConstant(cnat.getSignatureIndex()))).getBytes(); // Field or Method signature(=descriptor) - - try{ - Type t = Type.getReturnType(sig); - if ( name.equals(CONSTRUCTOR_NAME) && (t != Type.VOID) ){ - throw new ClassConstraintException("Instance initialization method must have VOID return type."); - } - } - catch (ClassFormatException cfe){ - throw new ClassConstraintException("Illegal descriptor (==signature) '"+sig+"' used by '"+tostring(obj)+"'."); - } - } - - public void visitConstantInterfaceMethodref(ConstantInterfaceMethodref obj){ - if (obj.getTag() != Constants.CONSTANT_InterfaceMethodref){ - throw new ClassConstraintException("ConstantInterfaceMethodref '"+tostring(obj)+"' has wrong tag!"); - } - int name_and_type_index = obj.getNameAndTypeIndex(); - ConstantNameAndType cnat = (ConstantNameAndType) (cp.getConstant(name_and_type_index)); - String name = ((ConstantUtf8) (cp.getConstant(cnat.getNameIndex()))).getBytes(); // Field or Method name - if (!validInterfaceMethodName(name)){ - throw new ClassConstraintException("Invalid (interface) method name '"+name+"' referenced by '"+tostring(obj)+"'."); - } - - int class_index = obj.getClassIndex(); - ConstantClass cc = (ConstantClass) (cp.getConstant(class_index)); - String className = ((ConstantUtf8) (cp.getConstant(cc.getNameIndex()))).getBytes(); // Class Name in internal form - if (! validClassName(className)){ - throw new ClassConstraintException("Illegal class name '"+className+"' used by '"+tostring(obj)+"'."); - } - - String sig = ((ConstantUtf8) (cp.getConstant(cnat.getSignatureIndex()))).getBytes(); // Field or Method signature(=descriptor) - - try{ - Type t = Type.getReturnType(sig); - if ( name.equals(STATIC_INITIALIZER_NAME) && (t != Type.VOID) ){ - addMessage("Class or interface initialization method '"+STATIC_INITIALIZER_NAME+"' usually has VOID return type instead of '"+t+"'. Note this is really not a requirement of The Java Virtual Machine Specification, Second Edition."); - } - } - catch (ClassFormatException cfe){ - throw new ClassConstraintException("Illegal descriptor (==signature) '"+sig+"' used by '"+tostring(obj)+"'."); - } - - } - - } - - /** - * This method returns true if and only if the supplied String - * represents a valid Java class name. - */ - private static final boolean validClassName(String name){ - /* - * TODO: implement. - * Are there any restrictions? - */ - return true; - } - /** - * This method returns true if and only if the supplied String - * represents a valid method name. - * This is basically the same as a valid identifier name in the - * Java programming language, but the special name for - * the instance initialization method is allowed and the special name - * for the class/interface initialization method may be allowed. - */ - private static boolean validMethodName(String name, boolean allowStaticInit){ - if (validJavaLangMethodName(name)) { - return true; - } - - if (allowStaticInit){ - return (name.equals(CONSTRUCTOR_NAME) || name.equals(STATIC_INITIALIZER_NAME)); - } - else{ - return name.equals(CONSTRUCTOR_NAME); - } - } - - /** - * This method returns true if and only if the supplied String - * represents a valid method name that may be referenced by - * ConstantMethodref objects. - */ - private static boolean validClassMethodName(String name){ - return validMethodName(name, false); - } - - /** - * This method returns true if and only if the supplied String - * represents a valid Java programming language method name stored as a simple - * (non-qualified) name. - * Conforming to: The Java Virtual Machine Specification, Second Edition, 2.7, 2.7.1, 2.2. - */ - private static boolean validJavaLangMethodName(String name){ - if (!Character.isJavaIdentifierStart(name.charAt(0))) { - return false; - } - - for (int i=1; i, thanks! - } - - // vmspec2 2.7, vmspec2 2.2 - if (!Character.isJavaIdentifierStart(name.charAt(0))) { - return false; - } - - for (int i=1; i= methods.length){ - throw new InvalidMethodException("METHOD DOES NOT EXIST!"); - } - Method method = methods[method_no]; - code = method.getCode(); - - // No Code? Nothing to verify! - if ( method.isAbstract() || method.isNative() ){ // IF mg HAS NO CODE (static constraint of Pass 2) - return VerificationResult.VR_OK; - } - - // TODO: - // We want a very sophisticated code examination here with good explanations - // on where to look for an illegal instruction or such. - // Only after that we should try to build an InstructionList and throw an - // AssertionViolatedException if after our examination InstructionList building - // still fails. - // That examination should be implemented in a byte-oriented way, i.e. look for - // an instruction, make sure its validity, count its length, find the next - // instruction and so on. - try{ - instructionList = new InstructionList(method.getCode().getCode()); - } - catch(RuntimeException re){ - return new VerificationResult(VerificationResult.VERIFIED_REJECTED, "Bad bytecode in the code array of the Code attribute of method '"+method+"'."); - } - - instructionList.setPositions(true); - - // Start verification. - VerificationResult vr = VerificationResult.VR_OK; //default - try{ - delayedPass2Checks(); - } - catch(ClassConstraintException cce){ - vr = new VerificationResult(VerificationResult.VERIFIED_REJECTED, cce.getMessage()); - return vr; - } - try{ - pass3StaticInstructionChecks(); - pass3StaticInstructionOperandsChecks(); - } - catch(StaticCodeConstraintException scce){ - vr = new VerificationResult(VerificationResult.VERIFIED_REJECTED, scce.getMessage()); - } - catch(ClassCastException cce){ - vr = new VerificationResult(VerificationResult.VERIFIED_REJECTED, "Class Cast Exception: " + cce.getMessage()); - } - return vr; - } - else{ //did not pass Pass 2. - return VerificationResult.VR_NOTYET; - } - } catch (ClassNotFoundException e) { - // FIXME: maybe not the best way to handle this - throw new AssertionViolatedException("Missing class: " + e.toString()); - } - } - - /** - * These are the checks that could be done in pass 2 but are delayed to pass 3 - * for performance reasons. Also, these checks need access to the code array - * of the Code attribute of a Method so it's okay to perform them here. - * Also see the description of the do_verify() method. - * - * @throws ClassConstraintException if the verification fails. - * @see #do_verify() - */ - private void delayedPass2Checks(){ - - int[] instructionPositions = instructionList.getInstructionPositions(); - int codeLength = code.getCode().length; - - ///////////////////// - // LineNumberTable // - ///////////////////// - LineNumberTable lnt = code.getLineNumberTable(); - if (lnt != null){ - LineNumber[] lineNumbers = lnt.getLineNumberTable(); - IntList offsets = new IntList(); - lineNumber_loop: for (int i=0; i < lineNumbers.length; i++){ // may appear in any order. - for (int j=0; j < instructionPositions.length; j++){ - // TODO: Make this a binary search! The instructionPositions array is naturally ordered! - int offset = lineNumbers[i].getStartPC(); - if (instructionPositions[j] == offset){ - if (offsets.contains(offset)){ - addMessage("LineNumberTable attribute '"+code.getLineNumberTable()+"' refers to the same code offset ('"+offset+"') more than once which is violating the semantics [but is sometimes produced by IBM's 'jikes' compiler]."); - } - else{ - offsets.add(offset); - } - continue lineNumber_loop; - } - } - throw new ClassConstraintException("Code attribute '"+code+"' has a LineNumberTable attribute '"+code.getLineNumberTable()+"' referring to a code offset ('"+lineNumbers[i].getStartPC()+"') that does not exist."); - } - } - - /////////////////////////// - // LocalVariableTable(s) // - /////////////////////////// - /* We cannot use code.getLocalVariableTable() because there could be more - than only one. This is a bug in BCEL. */ - Attribute[] atts = code.getAttributes(); - for (int a=0; a= endpc){ - throw new ClassConstraintException("Code attribute '"+code+"' has an exception_table entry '"+exceptionTable[i]+"' that has its start_pc ('"+startpc+"') not smaller than its end_pc ('"+endpc+"')."); - } - if (!contains(instructionPositions, startpc)){ - throw new ClassConstraintException("Code attribute '"+code+"' has an exception_table entry '"+exceptionTable[i]+"' that has a non-existant bytecode offset as its start_pc ('"+startpc+"')."); - } - if ( (!contains(instructionPositions, endpc)) && (endpc != codeLength)){ - throw new ClassConstraintException("Code attribute '"+code+"' has an exception_table entry '"+exceptionTable[i]+"' that has a non-existant bytecode offset as its end_pc ('"+startpc+"') [that is also not equal to code_length ('"+codeLength+"')]."); - } - if (!contains(instructionPositions, handlerpc)){ - throw new ClassConstraintException("Code attribute '"+code+"' has an exception_table entry '"+exceptionTable[i]+"' that has a non-existant bytecode offset as its handler_pc ('"+handlerpc+"')."); - } - } - } - - /** - * These are the checks if constraints are satisfied which are described in the - * Java Virtual Machine Specification, Second Edition as Static Constraints on - * the instructions of Java Virtual Machine Code (chapter 4.8.1). - * - * @throws StaticCodeConstraintException if the verification fails. - */ - private void pass3StaticInstructionChecks(){ - - // Code array must not be empty: - // Enforced in pass 2 (also stated in the static constraints of the Code - // array in vmspec2), together with pass 1 (reading code_length bytes and - // interpreting them as code[]). So this must not be checked again here. - - if (! (code.getCode().length < 65536)){// contradicts vmspec2 page 152 ("Limitations"), but is on page 134. - throw new StaticCodeInstructionConstraintException("Code array in code attribute '"+code+"' too big: must be smaller than 65536 bytes."); - } - - // First opcode at offset 0: okay, that's clear. Nothing to do. - - // Only instances of the instructions documented in Section 6.4 may appear in - // the code array. - - // For BCEL's sake, we cannot handle WIDE stuff, but hopefully BCEL does its job right :) - - // The last byte of the last instruction in the code array must be the byte at index - // code_length-1 : See the do_verify() comments. We actually don't iterate through the - // byte array, but use an InstructionList so we cannot check for this. But BCEL does - // things right, so it's implicitly okay. - - // TODO: Check how BCEL handles (and will handle) instructions like IMPDEP1, IMPDEP2, - // BREAKPOINT... that BCEL knows about but which are illegal anyway. - // We currently go the safe way here. - InstructionHandle ih = instructionList.getStart(); - while (ih != null){ - Instruction i = ih.getInstruction(); - if (i instanceof IMPDEP1){ - throw new StaticCodeInstructionConstraintException("IMPDEP1 must not be in the code, it is an illegal instruction for _internal_ JVM use!"); - } - if (i instanceof IMPDEP2){ - throw new StaticCodeInstructionConstraintException("IMPDEP2 must not be in the code, it is an illegal instruction for _internal_ JVM use!"); - } - if (i instanceof BREAKPOINT){ - throw new StaticCodeInstructionConstraintException("BREAKPOINT must not be in the code, it is an illegal instruction for _internal_ JVM use!"); - } - ih = ih.getNext(); - } - - // The original verifier seems to do this check here, too. - // An unreachable last instruction may also not fall through the - // end of the code, which is stupid -- but with the original - // verifier's subroutine semantics one cannot predict reachability. - Instruction last = instructionList.getEnd().getInstruction(); - if (! ((last instanceof ReturnInstruction) || - (last instanceof RET) || - (last instanceof GotoInstruction) || - (last instanceof ATHROW) )) { - throw new StaticCodeInstructionConstraintException("Execution must not fall off the bottom of the code array. This constraint is enforced statically as some existing verifiers do - so it may be a false alarm if the last instruction is not reachable."); - } - } - - /** - * These are the checks for the satisfaction of constraints which are described in the - * Java Virtual Machine Specification, Second Edition as Static Constraints on - * the operands of instructions of Java Virtual Machine Code (chapter 4.8.1). - * BCEL parses the code array to create an InstructionList and therefore has to check - * some of these constraints. Additional checks are also implemented here. - * - * @throws StaticCodeConstraintException if the verification fails. - */ - private void pass3StaticInstructionOperandsChecks(){ - try { - // When building up the InstructionList, BCEL has already done all those checks - // mentioned in The Java Virtual Machine Specification, Second Edition, as - // "static constraints on the operands of instructions in the code array". - // TODO: see the do_verify() comments. Maybe we should really work on the - // byte array first to give more comprehensive messages. - // TODO: Review Exception API, possibly build in some "offending instruction" thing - // when we're ready to insulate the offending instruction by doing the - // above thing. - - // TODO: Implement as much as possible here. BCEL does _not_ check everything. - - ConstantPoolGen cpg = new ConstantPoolGen(Repository.lookupClass(myOwner.getClassName()).getConstantPool()); - InstOperandConstraintVisitor v = new InstOperandConstraintVisitor(cpg); - - // Checks for the things BCEL does _not_ handle itself. - InstructionHandle ih = instructionList.getStart(); - while (ih != null){ - Instruction i = ih.getInstruction(); - - // An "own" constraint, due to JustIce's new definition of what "subroutine" means. - if (i instanceof JsrInstruction){ - InstructionHandle target = ((JsrInstruction) i).getTarget(); - if (target == instructionList.getStart()){ - throw new StaticCodeInstructionOperandConstraintException("Due to JustIce's clear definition of subroutines, no JSR or JSR_W may have a top-level instruction (such as the very first instruction, which is targeted by instruction '"+ih+"' as its target."); - } - if (!(target.getInstruction() instanceof ASTORE)){ - throw new StaticCodeInstructionOperandConstraintException("Due to JustIce's clear definition of subroutines, no JSR or JSR_W may target anything else than an ASTORE instruction. Instruction '"+ih+"' targets '"+target+"'."); - } - } - - // vmspec2, page 134-137 - ih.accept(v); - - ih = ih.getNext(); - } - - } catch (ClassNotFoundException e) { - // FIXME: maybe not the best way to handle this - throw new AssertionViolatedException("Missing class: " + e.toString()); - } - } - - /** A small utility method returning if a given int i is in the given int[] ints. */ - private static boolean contains(int[] ints, int i){ - for (int j=0; j= cpg.getSize()){ - constraintViolated(i, "Illegal constant pool index '"+idx+"'."); - } - } - - /////////////////////////////////////////////////////////// - // The Java Virtual Machine Specification, pages 134-137 // - /////////////////////////////////////////////////////////// - /** - * Assures the generic preconditions of a LoadClass instance. - * The referenced class is loaded and pass2-verified. - */ - public void visitLoadClass(LoadClass o){ - ObjectType t = o.getLoadClassType(cpg); - if (t != null){// null means "no class is loaded" - Verifier v = VerifierFactory.getVerifier(t.getClassName()); - VerificationResult vr = v.doPass1(); - if (vr.getStatus() != VerificationResult.VERIFIED_OK){ - constraintViolated((Instruction) o, "Class '"+o.getLoadClassType(cpg).getClassName()+"' is referenced, but cannot be loaded: '"+vr+"'."); - } - } - } - - // The target of each jump and branch instruction [...] must be the opcode [...] - // BCEL _DOES_ handle this. - - // tableswitch: BCEL will do it, supposedly. - - // lookupswitch: BCEL will do it, supposedly. - - /** Checks if the constraints of operands of the said instruction(s) are satisfied. */ - // LDC and LDC_W (LDC_W is a subclass of LDC in BCEL's model) - public void visitLDC(LDC o){ - indexValid(o, o.getIndex()); - Constant c = cpg.getConstant(o.getIndex()); - if (c instanceof ConstantClass){ - addMessage("Operand of LDC or LDC_W is CONSTANT_Class '"+c+"' - this is only supported in JDK 1.5 and higher."); - } - else{ - if (! ( (c instanceof ConstantInteger) || - (c instanceof ConstantFloat) || - (c instanceof ConstantString) ) ){ - constraintViolated(o, "Operand of LDC or LDC_W must be one of CONSTANT_Integer, CONSTANT_Float or CONSTANT_String, but is '"+c+"'."); - } - } - } - - /** Checks if the constraints of operands of the said instruction(s) are satisfied. */ - // LDC2_W - public void visitLDC2_W(LDC2_W o){ - indexValid(o, o.getIndex()); - Constant c = cpg.getConstant(o.getIndex()); - if (! ( (c instanceof ConstantLong) || - (c instanceof ConstantDouble) ) ){ - constraintViolated(o, "Operand of LDC2_W must be CONSTANT_Long or CONSTANT_Double, but is '"+c+"'."); - } - try{ - indexValid(o, o.getIndex()+1); - } - catch(StaticCodeInstructionOperandConstraintException e){ - throw new AssertionViolatedException("OOPS: Does not BCEL handle that? LDC2_W operand has a problem."); - } - } - - /** Checks if the constraints of operands of the said instruction(s) are satisfied. */ - //getfield, putfield, getstatic, putstatic - public void visitFieldInstruction(FieldInstruction o){ - try { - indexValid(o, o.getIndex()); - Constant c = cpg.getConstant(o.getIndex()); - if (! (c instanceof ConstantFieldref)){ - constraintViolated(o, "Indexing a constant that's not a CONSTANT_Fieldref but a '"+c+"'."); - } - - String field_name = o.getFieldName(cpg); - - JavaClass jc = Repository.lookupClass(o.getClassType(cpg).getClassName()); - Field[] fields = jc.getFields(); - Field f = null; - for (int i=0; i or - ConstantNameAndType cnat = (ConstantNameAndType) (cpg.getConstant(((ConstantInterfaceMethodref)c).getNameAndTypeIndex())); - String name = ((ConstantUtf8) (cpg.getConstant(cnat.getNameIndex()))).getBytes(); - if (name.equals(Constants.CONSTRUCTOR_NAME)){ - constraintViolated(o, "Method to invoke must not be '"+Constants.CONSTRUCTOR_NAME+"'."); - } - if (name.equals(Constants.STATIC_INITIALIZER_NAME)){ - constraintViolated(o, "Method to invoke must not be '"+Constants.STATIC_INITIALIZER_NAME+"'."); - } - } - - // The LoadClassType is the method-declaring class, so we have to check the other types. - - Type t = o.getReturnType(cpg); - if (t instanceof ArrayType){ - t = ((ArrayType) t).getBasicType(); - } - if (t instanceof ObjectType){ - Verifier v = VerifierFactory.getVerifier(((ObjectType) t).getClassName()); - VerificationResult vr = v.doPass2(); - if (vr.getStatus() != VerificationResult.VERIFIED_OK){ - constraintViolated(o, "Return type class/interface could not be verified successfully: '"+vr.getMessage()+"'."); - } - } - - Type[] ts = o.getArgumentTypes(cpg); - for (int i=0; i= 255){ - constraintViolated(o, "Not allowed to create an array with more than 255 dimensions."); - } - } - } - - /** Checks if the constraints of operands of the said instruction(s) are satisfied. */ - public void visitNEWARRAY(NEWARRAY o){ - byte t = o.getTypecode(); - if (! ( (t == Constants.T_BOOLEAN) || - (t == Constants.T_CHAR) || - (t == Constants.T_FLOAT) || - (t == Constants.T_DOUBLE) || - (t == Constants.T_BYTE) || - (t == Constants.T_SHORT) || - (t == Constants.T_INT) || - (t == Constants.T_LONG) ) ){ - constraintViolated(o, "Illegal type code '+t+' for 'atype' operand."); - } - } - - /** Checks if the constraints of operands of the said instruction(s) are satisfied. */ - public void visitILOAD(ILOAD o){ - int idx = o.getIndex(); - if (idx < 0){ - constraintViolated(o, "Index '"+idx+"' must be non-negative."); - } - else{ - int maxminus1 = max_locals()-1; - if (idx > maxminus1){ - constraintViolated(o, "Index '"+idx+"' must not be greater than max_locals-1 '"+maxminus1+"'."); - } - } - } - - /** Checks if the constraints of operands of the said instruction(s) are satisfied. */ - public void visitFLOAD(FLOAD o){ - int idx = o.getIndex(); - if (idx < 0){ - constraintViolated(o, "Index '"+idx+"' must be non-negative."); - } - else{ - int maxminus1 = max_locals()-1; - if (idx > maxminus1){ - constraintViolated(o, "Index '"+idx+"' must not be greater than max_locals-1 '"+maxminus1+"'."); - } - } - } - - /** Checks if the constraints of operands of the said instruction(s) are satisfied. */ - public void visitALOAD(ALOAD o){ - int idx = o.getIndex(); - if (idx < 0){ - constraintViolated(o, "Index '"+idx+"' must be non-negative."); - } - else{ - int maxminus1 = max_locals()-1; - if (idx > maxminus1){ - constraintViolated(o, "Index '"+idx+"' must not be greater than max_locals-1 '"+maxminus1+"'."); - } - } - } - - /** Checks if the constraints of operands of the said instruction(s) are satisfied. */ - public void visitISTORE(ISTORE o){ - int idx = o.getIndex(); - if (idx < 0){ - constraintViolated(o, "Index '"+idx+"' must be non-negative."); - } - else{ - int maxminus1 = max_locals()-1; - if (idx > maxminus1){ - constraintViolated(o, "Index '"+idx+"' must not be greater than max_locals-1 '"+maxminus1+"'."); - } - } - } - - /** Checks if the constraints of operands of the said instruction(s) are satisfied. */ - public void visitFSTORE(FSTORE o){ - int idx = o.getIndex(); - if (idx < 0){ - constraintViolated(o, "Index '"+idx+"' must be non-negative."); - } - else{ - int maxminus1 = max_locals()-1; - if (idx > maxminus1){ - constraintViolated(o, "Index '"+idx+"' must not be greater than max_locals-1 '"+maxminus1+"'."); - } - } - } - - /** Checks if the constraints of operands of the said instruction(s) are satisfied. */ - public void visitASTORE(ASTORE o){ - int idx = o.getIndex(); - if (idx < 0){ - constraintViolated(o, "Index '"+idx+"' must be non-negative."); - } - else{ - int maxminus1 = max_locals()-1; - if (idx > maxminus1){ - constraintViolated(o, "Index '"+idx+"' must not be greater than max_locals-1 '"+maxminus1+"'."); - } - } - } - - /** Checks if the constraints of operands of the said instruction(s) are satisfied. */ - public void visitIINC(IINC o){ - int idx = o.getIndex(); - if (idx < 0){ - constraintViolated(o, "Index '"+idx+"' must be non-negative."); - } - else{ - int maxminus1 = max_locals()-1; - if (idx > maxminus1){ - constraintViolated(o, "Index '"+idx+"' must not be greater than max_locals-1 '"+maxminus1+"'."); - } - } - } - - /** Checks if the constraints of operands of the said instruction(s) are satisfied. */ - public void visitRET(RET o){ - int idx = o.getIndex(); - if (idx < 0){ - constraintViolated(o, "Index '"+idx+"' must be non-negative."); - } - else{ - int maxminus1 = max_locals()-1; - if (idx > maxminus1){ - constraintViolated(o, "Index '"+idx+"' must not be greater than max_locals-1 '"+maxminus1+"'."); - } - } - } - - /** Checks if the constraints of operands of the said instruction(s) are satisfied. */ - public void visitLLOAD(LLOAD o){ - int idx = o.getIndex(); - if (idx < 0){ - constraintViolated(o, "Index '"+idx+"' must be non-negative. [Constraint by JustIce as an analogon to the single-slot xLOAD/xSTORE instructions; may not happen anyway.]"); - } - else{ - int maxminus2 = max_locals()-2; - if (idx > maxminus2){ - constraintViolated(o, "Index '"+idx+"' must not be greater than max_locals-2 '"+maxminus2+"'."); - } - } - } - - /** Checks if the constraints of operands of the said instruction(s) are satisfied. */ - public void visitDLOAD(DLOAD o){ - int idx = o.getIndex(); - if (idx < 0){ - constraintViolated(o, "Index '"+idx+"' must be non-negative. [Constraint by JustIce as an analogon to the single-slot xLOAD/xSTORE instructions; may not happen anyway.]"); - } - else{ - int maxminus2 = max_locals()-2; - if (idx > maxminus2){ - constraintViolated(o, "Index '"+idx+"' must not be greater than max_locals-2 '"+maxminus2+"'."); - } - } - } - - /** Checks if the constraints of operands of the said instruction(s) are satisfied. */ - public void visitLSTORE(LSTORE o){ - int idx = o.getIndex(); - if (idx < 0){ - constraintViolated(o, "Index '"+idx+"' must be non-negative. [Constraint by JustIce as an analogon to the single-slot xLOAD/xSTORE instructions; may not happen anyway.]"); - } - else{ - int maxminus2 = max_locals()-2; - if (idx > maxminus2){ - constraintViolated(o, "Index '"+idx+"' must not be greater than max_locals-2 '"+maxminus2+"'."); - } - } - } - - /** Checks if the constraints of operands of the said instruction(s) are satisfied. */ - public void visitDSTORE(DSTORE o){ - int idx = o.getIndex(); - if (idx < 0){ - constraintViolated(o, "Index '"+idx+"' must be non-negative. [Constraint by JustIce as an analogon to the single-slot xLOAD/xSTORE instructions; may not happen anyway.]"); - } - else{ - int maxminus2 = max_locals()-2; - if (idx > maxminus2){ - constraintViolated(o, "Index '"+idx+"' must not be greater than max_locals-2 '"+maxminus2+"'."); - } - } - } - - /** Checks if the constraints of operands of the said instruction(s) are satisfied. */ - public void visitLOOKUPSWITCH(LOOKUPSWITCH o){ - int[] matchs = o.getMatchs(); - int max = Integer.MIN_VALUE; - for (int i=0; i= "low". We cannot check this, as BCEL hides - // it from us. - } - - /** Checks if the constraints of operands of the said instruction(s) are satisfied. */ - public void visitPUTSTATIC(PUTSTATIC o){ - try { - String field_name = o.getFieldName(cpg); - JavaClass jc = Repository.lookupClass(o.getClassType(cpg).getClassName()); - Field[] fields = jc.getFields(); - Field f = null; - for (int i=0; i. - if ((!(jc.isClass())) && (!(meth_name.equals(Constants.STATIC_INITIALIZER_NAME)))){ - constraintViolated(o, "Interface field '"+f+"' must be set in a '"+Constants.STATIC_INITIALIZER_NAME+"' method."); - } - } catch (ClassNotFoundException e) { - // FIXME: maybe not the best way to handle this - throw new AssertionViolatedException("Missing class: " + e.toString()); - } - } - - /** Checks if the constraints of operands of the said instruction(s) are satisfied. */ - public void visitGETSTATIC(GETSTATIC o){ - try { - String field_name = o.getFieldName(cpg); - JavaClass jc = Repository.lookupClass(o.getClassType(cpg).getClassName()); - Field[] fields = jc.getFields(); - Field f = null; - for (int i=0; iaccept() Visitor - * instances) have toString() methods that were not designed to be robust, - * this gap is closed by this class. - * When performing class file verification, it may be useful to output which - * entity (e.g. a Code instance) is not satisfying the verifier's - * constraints, but in this case it could be possible for the toString() - * method to throw a RuntimeException. - * A (new StringRepresentation(Node n)).toString() never throws any exception. - * Note that this class also serves as a placeholder for more sophisticated message - * handling in future versions of JustIce. - * - * @version $Id: StringRepresentation.java 386056 2006-03-15 11:31:56Z tcurdt $ - * @author Enver Haase - */ -public class StringRepresentation extends org.apache.bcel.classfile.EmptyVisitor implements Visitor { - /** The string representation, created by a visitXXX() method, output by toString(). */ - private String tostring; - /** The node we ask for its string representation. Not really needed; only for debug output. */ - private Node n; - - /** - * Creates a new StringRepresentation object which is the representation of n. - * - * @see #toString() - */ - public StringRepresentation(Node n) { - this.n = n; - n.accept(this); // assign a string representation to field 'tostring' if we know n's class. - } - - /** - * Returns the String representation. - */ - public String toString() { -// The run-time check below is needed because we don't want to omit inheritance -// of "EmptyVisitor" and provide a thousand empty methods. -// However, in terms of performance this would be a better idea. -// If some new "Node" is defined in BCEL (such as some concrete "Attribute"), we -// want to know that this class has also to be adapted. - if (tostring == null) { - throw new AssertionViolatedException("Please adapt '" + getClass() + "' to deal with objects of class '" + n.getClass() + "'."); - } - return tostring; - } - - /** - * Returns the String representation of the Node object obj; - * this is obj.toString() if it does not throw any RuntimeException, - * or else it is a string derived only from obj's class name. - */ - private String toString(Node obj) { - String ret; - try { - ret = obj.toString(); - } - catch (RuntimeException e) { // including ClassFormatException, trying to convert the "signature" of a ReturnaddressType LocalVariable (shouldn't occur, but people do crazy things) - String s = obj.getClass().getName(); - s = s.substring(s.lastIndexOf(".") + 1); - ret = "<<" + s + ">>"; - } - return ret; - } - - //////////////////////////////// - // Visitor methods start here // - //////////////////////////////// - // We don't of course need to call some default implementation: - // e.g. we could also simply output "Code" instead of a possibly - // lengthy Code attribute's toString(). - public void visitCode(Code obj) { - //tostring = toString(obj); - tostring = ""; // We don't need real code outputs. - } - - public void visitCodeException(CodeException obj) { - tostring = toString(obj); - } - - public void visitConstantClass(ConstantClass obj) { - tostring = toString(obj); - } - - public void visitConstantDouble(ConstantDouble obj) { - tostring = toString(obj); - } - - public void visitConstantFieldref(ConstantFieldref obj) { - tostring = toString(obj); - } - - public void visitConstantFloat(ConstantFloat obj) { - tostring = toString(obj); - } - - public void visitConstantInteger(ConstantInteger obj) { - tostring = toString(obj); - } - - public void visitConstantInterfaceMethodref(ConstantInterfaceMethodref obj) { - tostring = toString(obj); - } - - public void visitConstantLong(ConstantLong obj) { - tostring = toString(obj); - } - - public void visitConstantMethodref(ConstantMethodref obj) { - tostring = toString(obj); - } - - public void visitConstantNameAndType(ConstantNameAndType obj) { - tostring = toString(obj); - } - - public void visitConstantPool(ConstantPool obj) { - tostring = toString(obj); - } - - public void visitConstantString(ConstantString obj) { - tostring = toString(obj); - } - - public void visitConstantUtf8(ConstantUtf8 obj) { - tostring = toString(obj); - } - - public void visitConstantValue(ConstantValue obj) { - tostring = toString(obj); - } - - public void visitDeprecated(Deprecated obj) { - tostring = toString(obj); - } - - public void visitExceptionTable(ExceptionTable obj) { - tostring = toString(obj); - } - - public void visitField(Field obj) { - tostring = toString(obj); - } - - public void visitInnerClass(InnerClass obj) { - tostring = toString(obj); - } - - public void visitInnerClasses(InnerClasses obj) { - tostring = toString(obj); - } - - public void visitJavaClass(JavaClass obj) { - tostring = toString(obj); - } - - public void visitLineNumber(LineNumber obj) { - tostring = toString(obj); - } - - public void visitLineNumberTable(LineNumberTable obj) { - tostring = ""; - } - - public void visitLocalVariable(LocalVariable obj) { - tostring = toString(obj); - } - - public void visitLocalVariableTable(LocalVariableTable obj) { - tostring = ""; - } - - public void visitMethod(Method obj) { - tostring = toString(obj); - } - - public void visitSignature(Signature obj) { - tostring = toString(obj); - } - - public void visitSourceFile(SourceFile obj) { - tostring = toString(obj); - } - - public void visitStackMap(StackMap obj) { - tostring = toString(obj); - } - - public void visitSynthetic(Synthetic obj) { - tostring = toString(obj); - } - - public void visitUnknown(Unknown obj) { - tostring = toString(obj); - } -} diff --git a/src/org/apache/bcel/verifier/statics/package.html b/src/org/apache/bcel/verifier/statics/package.html deleted file mode 100644 index e805897..0000000 --- a/src/org/apache/bcel/verifier/statics/package.html +++ /dev/null @@ -1,19 +0,0 @@ - - - - - - - -Provides PassVerifier classes used internally by JustIce. You don't need to bother with them. - -

Package Specification

- -Contained in this package are PassVerifier classes for use with the JustIce verifier. -Only the passes performing what Sun calls 'static constraints' have PassVerifier classes -here. - - - diff --git a/src/org/apache/bcel/verifier/structurals/ControlFlowGraph.java b/src/org/apache/bcel/verifier/structurals/ControlFlowGraph.java deleted file mode 100644 index 93c6405..0000000 --- a/src/org/apache/bcel/verifier/structurals/ControlFlowGraph.java +++ /dev/null @@ -1,460 +0,0 @@ -/* - * Copyright 2000-2004 The Apache Software Foundation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ -package org.apache.bcel.verifier.structurals; - - -import java.util.ArrayList; -import java.util.Hashtable; -import java.util.Map; -import org.apache.bcel.generic.ATHROW; -import org.apache.bcel.generic.BranchInstruction; -import org.apache.bcel.generic.GotoInstruction; -import org.apache.bcel.generic.Instruction; -import org.apache.bcel.generic.InstructionHandle; -import org.apache.bcel.generic.JsrInstruction; -import org.apache.bcel.generic.MethodGen; -import org.apache.bcel.generic.RET; -import org.apache.bcel.generic.ReturnInstruction; -import org.apache.bcel.generic.Select; -import org.apache.bcel.verifier.exc.AssertionViolatedException; -import org.apache.bcel.verifier.exc.StructuralCodeConstraintException; - -/** - * This class represents a control flow graph of a method. - * - * @version $Id: ControlFlowGraph.java 386056 2006-03-15 11:31:56Z tcurdt $ - * @author Enver Haase - */ -public class ControlFlowGraph{ - - /** - * Objects of this class represent a node in a ControlFlowGraph. - * These nodes are instructions, not basic blocks. - */ - private class InstructionContextImpl implements InstructionContext{ - - /** - * The TAG field is here for external temporary flagging, such - * as graph colouring. - * - * @see #getTag() - * @see #setTag(int) - */ - private int TAG; - - /** - * The InstructionHandle this InstructionContext is wrapped around. - */ - private InstructionHandle instruction; - - /** - * The 'incoming' execution Frames. - */ - private Map inFrames; // key: the last-executed JSR - - /** - * The 'outgoing' execution Frames. - */ - private Map outFrames; // key: the last-executed JSR - - /** - * The 'execution predecessors' - a list of type InstructionContext - * of those instances that have been execute()d before in that order. - */ - private ArrayList executionPredecessors = null; // Type: InstructionContext - - /** - * Creates an InstructionHandleImpl object from an InstructionHandle. - * Creation of one per InstructionHandle suffices. Don't create more. - */ - public InstructionContextImpl(InstructionHandle inst){ - if (inst == null) { - throw new AssertionViolatedException("Cannot instantiate InstructionContextImpl from NULL."); - } - - instruction = inst; - inFrames = new java.util.HashMap(); - outFrames = new java.util.HashMap(); - } - - /* Satisfies InstructionContext.getTag(). */ - public int getTag(){ - return TAG; - } - - /* Satisfies InstructionContext.setTag(int). */ - public void setTag(int tag){ - TAG = tag; - } - - /** - * Returns the exception handlers of this instruction. - */ - public ExceptionHandler[] getExceptionHandlers(){ - return exceptionhandlers.getExceptionHandlers(getInstruction()); - } - - /** - * Returns a clone of the "outgoing" frame situation with respect to the given ExecutionChain. - */ - public Frame getOutFrame(ArrayList execChain){ - executionPredecessors = execChain; - - Frame org; - - InstructionContext jsr = lastExecutionJSR(); - - org = (Frame) outFrames.get(jsr); - - if (org == null){ - throw new AssertionViolatedException("outFrame not set! This:\n"+this+"\nExecutionChain: "+getExecutionChain()+"\nOutFrames: '"+outFrames+"'."); - } - return org.getClone(); - } - - public Frame getInFrame() { - Frame org; - - InstructionContext jsr = lastExecutionJSR(); - - org = (Frame) inFrames.get(jsr); - - if (org == null){ - throw new AssertionViolatedException("inFrame not set! This:\n"+this+"\nInFrames: '"+inFrames+"'."); - } - return org.getClone(); - } - - /** - * "Merges in" (vmspec2, page 146) the "incoming" frame situation; - * executes the instructions symbolically - * and therefore calculates the "outgoing" frame situation. - * Returns: True iff the "incoming" frame situation changed after - * merging with "inFrame". - * The execPreds ArrayList must contain the InstructionContext - * objects executed so far in the correct order. This is just - * one execution path [out of many]. This is needed to correctly - * "merge" in the special case of a RET's successor. - * The InstConstraintVisitor and ExecutionVisitor instances - * must be set up correctly. - * @return true - if and only if the "outgoing" frame situation - * changed from the one before execute()ing. - */ - public boolean execute(Frame inFrame, ArrayList execPreds, InstConstraintVisitor icv, ExecutionVisitor ev){ - - executionPredecessors = (ArrayList) execPreds.clone(); - - //sanity check - if ( (lastExecutionJSR() == null) && (subroutines.subroutineOf(getInstruction()) != subroutines.getTopLevel() ) ){ - throw new AssertionViolatedException("Huh?! Am I '"+this+"' part of a subroutine or not?"); - } - if ( (lastExecutionJSR() != null) && (subroutines.subroutineOf(getInstruction()) == subroutines.getTopLevel() ) ){ - throw new AssertionViolatedException("Huh?! Am I '"+this+"' part of a subroutine or not?"); - } - - Frame inF = (Frame) inFrames.get(lastExecutionJSR()); - if (inF == null){// no incoming frame was set, so set it. - inFrames.put(lastExecutionJSR(), inFrame); - inF = inFrame; - } - else{// if there was an "old" inFrame - if (inF.equals(inFrame)){ //shortcut: no need to merge equal frames. - return false; - } - if (! mergeInFrames(inFrame)){ - return false; - } - } - - // Now we're sure the inFrame has changed! - - // new inFrame is already merged in, see above. - Frame workingFrame = inF.getClone(); - - try{ - // This verifies the InstructionConstraint for the current - // instruction, but does not modify the workingFrame object. -//InstConstraintVisitor icv = InstConstraintVisitor.getInstance(VerifierFactory.getVerifier(method_gen.getClassName())); - icv.setFrame(workingFrame); - getInstruction().accept(icv); - } - catch(StructuralCodeConstraintException ce){ - ce.extendMessage("","\nInstructionHandle: "+getInstruction()+"\n"); - ce.extendMessage("","\nExecution Frame:\n"+workingFrame); - extendMessageWithFlow(ce); - throw ce; - } - - // This executes the Instruction. - // Therefore the workingFrame object is modified. -//ExecutionVisitor ev = ExecutionVisitor.getInstance(VerifierFactory.getVerifier(method_gen.getClassName())); - ev.setFrame(workingFrame); - getInstruction().accept(ev); - //getInstruction().accept(ExecutionVisitor.withFrame(workingFrame)); - outFrames.put(lastExecutionJSR(), workingFrame); - - return true; // new inFrame was different from old inFrame so merging them - // yielded a different this.inFrame. - } - - /** - * Returns a simple String representation of this InstructionContext. - */ - public String toString(){ - //TODO: Put information in the brackets, e.g. - // Is this an ExceptionHandler? Is this a RET? Is this the start of - // a subroutine? - String ret = getInstruction().toString(false)+"\t[InstructionContext]"; - return ret; - } - - /** - * Does the actual merging (vmspec2, page 146). - * Returns true IFF this.inFrame was changed in course of merging with inFrame. - */ - private boolean mergeInFrames(Frame inFrame){ - // TODO: Can be performance-improved. - Frame inF = (Frame) inFrames.get(lastExecutionJSR()); - OperandStack oldstack = inF.getStack().getClone(); - LocalVariables oldlocals = inF.getLocals().getClone(); - try{ - inF.getStack().merge(inFrame.getStack()); - inF.getLocals().merge(inFrame.getLocals()); - } - catch (StructuralCodeConstraintException sce){ - extendMessageWithFlow(sce); - throw sce; - } - if ( oldstack.equals(inF.getStack()) && - oldlocals.equals(inF.getLocals()) ){ - return false; - } - else{ - return true; - } - } - - /** - * Returns the control flow execution chain. This is built - * while execute(Frame, ArrayList)-ing the code represented - * by the surrounding ControlFlowGraph. - */ - private String getExecutionChain(){ - String s = this.toString(); - for (int i=executionPredecessors.size()-1; i>=0; i--){ - s = executionPredecessors.get(i)+"\n" + s; - } - return s; - } - - - /** - * Extends the StructuralCodeConstraintException ("e") object with an at-the-end-extended message. - * This extended message will then reflect the execution flow needed to get to the constraint - * violation that triggered the throwing of the "e" object. - */ - private void extendMessageWithFlow(StructuralCodeConstraintException e){ - String s = "Execution flow:\n"; - e.extendMessage("", s+getExecutionChain()); - } - - /* - * Fulfils the contract of InstructionContext.getInstruction(). - */ - public InstructionHandle getInstruction(){ - return instruction; - } - - /** - * Returns the InstructionContextImpl with an JSR/JSR_W - * that was last in the ExecutionChain, without - * a corresponding RET, i.e. - * we were called by this one. - * Returns null if we were called from the top level. - */ - private InstructionContextImpl lastExecutionJSR(){ - - int size = executionPredecessors.size(); - int retcount = 0; - - for (int i=size-1; i>=0; i--){ - InstructionContextImpl current = (InstructionContextImpl) (executionPredecessors.get(i)); - Instruction currentlast = current.getInstruction().getInstruction(); - if (currentlast instanceof RET) { - retcount++; - } - if (currentlast instanceof JsrInstruction){ - retcount--; - if (retcount == -1) { - return current; - } - } - } - return null; - } - - /* Satisfies InstructionContext.getSuccessors(). */ - public InstructionContext[] getSuccessors(){ - return contextsOf(_getSuccessors()); - } - - /** - * A utility method that calculates the successors of a given InstructionHandle - * That means, a RET does have successors as defined here. - * A JsrInstruction has its target as its successor - * (opposed to its physical successor) as defined here. - */ -// TODO: implement caching! - private InstructionHandle[] _getSuccessors(){ - final InstructionHandle[] empty = new InstructionHandle[0]; - final InstructionHandle[] single = new InstructionHandle[1]; - final InstructionHandle[] pair = new InstructionHandle[2]; - - Instruction inst = getInstruction().getInstruction(); - - if (inst instanceof RET){ - Subroutine s = subroutines.subroutineOf(getInstruction()); - if (s==null){ //return empty; // RET in dead code. "empty" would be the correct answer, but we know something about the surrounding project... - throw new AssertionViolatedException("Asking for successors of a RET in dead code?!"); - } - -//TODO: remove. Only JustIce must not use it, but foreign users of the ControlFlowGraph -// will want it. Thanks Johannes Wust. -//throw new AssertionViolatedException("DID YOU REALLY WANT TO ASK FOR RET'S SUCCS?"); - - InstructionHandle[] jsrs = s.getEnteringJsrInstructions(); - InstructionHandle[] ret = new InstructionHandle[jsrs.length]; - for (int i=0; i(NOT ORDERED!). - */ - public InstructionContext[] getInstructionContexts(){ - InstructionContext[] ret = new InstructionContext[instructionContexts.values().size()]; - return (InstructionContext[]) instructionContexts.values().toArray(ret); - } - - /** - * Returns true, if and only if the said instruction is not reachable; that means, - * if it is not part of this ControlFlowGraph. - */ - public boolean isDead(InstructionHandle i){ - return subroutines.subroutineOf(i) == null; - } -} diff --git a/src/org/apache/bcel/verifier/structurals/ExceptionHandler.java b/src/org/apache/bcel/verifier/structurals/ExceptionHandler.java deleted file mode 100644 index 4f04d1d..0000000 --- a/src/org/apache/bcel/verifier/structurals/ExceptionHandler.java +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright 2000-2004 The Apache Software Foundation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ -package org.apache.bcel.verifier.structurals; - - -import org.apache.bcel.generic.InstructionHandle; -import org.apache.bcel.generic.ObjectType; - -/** - * This class represents an exception handler; that is, an ObjectType - * representing a subclass of java.lang.Throwable and the instruction - * the handler starts off (represented by an InstructionContext). - * - * @version $Id: ExceptionHandler.java 371539 2006-01-23 14:08:00Z tcurdt $ - * @author Enver Haase - */ -public class ExceptionHandler{ - /** The type of the exception to catch. NULL means ANY. */ - private ObjectType catchtype; - - /** The InstructionHandle where the handling begins. */ - private InstructionHandle handlerpc; - - /** Leave instance creation to JustIce. */ - ExceptionHandler(ObjectType catch_type, InstructionHandle handler_pc){ - catchtype = catch_type; - handlerpc = handler_pc; - } - - /** - * Returns the type of the exception that's handled. 'null' means 'ANY'. - */ - public ObjectType getExceptionType(){ - return catchtype; - } - - /** - * Returns the InstructionHandle where the handler starts off. - */ - public InstructionHandle getHandlerStart(){ - return handlerpc; - } -} diff --git a/src/org/apache/bcel/verifier/structurals/ExceptionHandlers.java b/src/org/apache/bcel/verifier/structurals/ExceptionHandlers.java deleted file mode 100644 index b847834..0000000 --- a/src/org/apache/bcel/verifier/structurals/ExceptionHandlers.java +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Copyright 2000-2004 The Apache Software Foundation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ -package org.apache.bcel.verifier.structurals; - - -import java.util.HashSet; -import java.util.Hashtable; -import java.util.Set; -import org.apache.bcel.generic.CodeExceptionGen; -import org.apache.bcel.generic.InstructionHandle; -import org.apache.bcel.generic.MethodGen; - -/** - * This class allows easy access to ExceptionHandler objects. - * - * @version $Id: ExceptionHandlers.java 386056 2006-03-15 11:31:56Z tcurdt $ - * @author Enver Haase - */ -public class ExceptionHandlers{ - /** - * The ExceptionHandler instances. - * Key: InstructionHandle objects, Values: HashSet instances. - */ - private Hashtable exceptionhandlers; - - /** - * Constructor. Creates a new ExceptionHandlers instance. - */ - public ExceptionHandlers(MethodGen mg){ - exceptionhandlers = new Hashtable(); - CodeExceptionGen[] cegs = mg.getExceptionHandlers(); - for (int i=0; iConventions: - * - * Type.VOID will never be pushed onto the stack. Type.DOUBLE and Type.LONG - * that would normally take up two stack slots (like Double_HIGH and - * Double_LOW) are represented by a simple single Type.DOUBLE or Type.LONG - * object on the stack here. - * If a two-slot type is stored into a local variable, the next variable - * is given the type Type.UNKNOWN. - * - * @version $Id: ExecutionVisitor.java 386056 2006-03-15 11:31:56Z tcurdt $ - * @author Enver Haase - * @see #visitDSTORE(DSTORE o) - * @see InstConstraintVisitor - */ -public class ExecutionVisitor extends EmptyVisitor implements Visitor{ - - /** - * The executionframe we're operating on. - */ - private Frame frame = null; - - /** - * The ConstantPoolGen we're working with. - * @see #setConstantPoolGen(ConstantPoolGen) - */ - private ConstantPoolGen cpg = null; - - /** - * Constructor. Constructs a new instance of this class. - */ - public ExecutionVisitor(){} - - /** - * The OperandStack from the current Frame we're operating on. - * @see #setFrame(Frame) - */ - private OperandStack stack(){ - return frame.getStack(); - } - - /** - * The LocalVariables from the current Frame we're operating on. - * @see #setFrame(Frame) - */ - private LocalVariables locals(){ - return frame.getLocals(); - } - - /** - * Sets the ConstantPoolGen needed for symbolic execution. - */ - public void setConstantPoolGen(ConstantPoolGen cpg){ - this.cpg = cpg; - } - - /** - * The only method granting access to the single instance of - * the ExecutionVisitor class. Before actively using this - * instance, SET THE ConstantPoolGen FIRST. - * @see #setConstantPoolGen(ConstantPoolGen) - */ - public void setFrame(Frame f){ - this.frame = f; - } - - ///** Symbolically executes the corresponding Java Virtual Machine instruction. */ - //public void visitWIDE(WIDE o){ - // The WIDE instruction is modelled as a flag - // of the embedded instructions in BCEL. - // Therefore BCEL checks for possible errors - // when parsing in the .class file: We don't - // have even the possibilty to care for WIDE - // here. - //} - - /** Symbolically executes the corresponding Java Virtual Machine instruction. */ - public void visitAALOAD(AALOAD o){ - stack().pop(); // pop the index int -//System.out.print(stack().peek()); - Type t = stack().pop(); // Pop Array type - if (t == Type.NULL){ - stack().push(Type.NULL); - } // Do nothing stackwise --- a NullPointerException is thrown at Run-Time - else{ - ArrayType at = (ArrayType) t; - stack().push(at.getElementType()); - } - } - /** Symbolically executes the corresponding Java Virtual Machine instruction. */ - public void visitAASTORE(AASTORE o){ - stack().pop(); - stack().pop(); - stack().pop(); - } - /** Symbolically executes the corresponding Java Virtual Machine instruction. */ - public void visitACONST_NULL(ACONST_NULL o){ - stack().push(Type.NULL); - } - /** Symbolically executes the corresponding Java Virtual Machine instruction. */ - public void visitALOAD(ALOAD o){ - stack().push(locals().get(o.getIndex())); - } - /** Symbolically executes the corresponding Java Virtual Machine instruction. */ - public void visitANEWARRAY(ANEWARRAY o){ - stack().pop(); //count - stack().push( new ArrayType(o.getType(cpg), 1) ); - } - /** Symbolically executes the corresponding Java Virtual Machine instruction. */ - public void visitARETURN(ARETURN o){ - stack().pop(); - } - /** Symbolically executes the corresponding Java Virtual Machine instruction. */ - public void visitARRAYLENGTH(ARRAYLENGTH o){ - stack().pop(); - stack().push(Type.INT); - } - - /** Symbolically executes the corresponding Java Virtual Machine instruction. */ - public void visitASTORE(ASTORE o){ - locals().set(o.getIndex(), stack().pop()); - //System.err.println("TODO-DEBUG: set LV '"+o.getIndex()+"' to '"+locals().get(o.getIndex())+"'."); - } - - /** Symbolically executes the corresponding Java Virtual Machine instruction. */ - public void visitATHROW(ATHROW o){ - Type t = stack().pop(); - stack().clear(); - if (t.equals(Type.NULL)) { - stack().push(Type.getType("Ljava/lang/NullPointerException;")); - } else { - stack().push(t); - } - } - - /** Symbolically executes the corresponding Java Virtual Machine instruction. */ - public void visitBALOAD(BALOAD o){ - stack().pop(); - stack().pop(); - stack().push(Type.INT); - } - - /** Symbolically executes the corresponding Java Virtual Machine instruction. */ - public void visitBASTORE(BASTORE o){ - stack().pop(); - stack().pop(); - stack().pop(); - } - - /** Symbolically executes the corresponding Java Virtual Machine instruction. */ - public void visitBIPUSH(BIPUSH o){ - stack().push(Type.INT); - } - - /** Symbolically executes the corresponding Java Virtual Machine instruction. */ - public void visitCALOAD(CALOAD o){ - stack().pop(); - stack().pop(); - stack().push(Type.INT); - } - /** Symbolically executes the corresponding Java Virtual Machine instruction. */ - public void visitCASTORE(CASTORE o){ - stack().pop(); - stack().pop(); - stack().pop(); - } - /** Symbolically executes the corresponding Java Virtual Machine instruction. */ - public void visitCHECKCAST(CHECKCAST o){ - // It's possibly wrong to do so, but SUN's - // ByteCode verifier seems to do (only) this, too. - // TODO: One could use a sophisticated analysis here to check - // if a type cannot possibly be cated to another and by - // so doing predict the ClassCastException at run-time. - stack().pop(); - stack().push(o.getType(cpg)); - } - - /** Symbolically executes the corresponding Java Virtual Machine instruction. */ - public void visitD2F(D2F o){ - stack().pop(); - stack().push(Type.FLOAT); - } - /** Symbolically executes the corresponding Java Virtual Machine instruction. */ - public void visitD2I(D2I o){ - stack().pop(); - stack().push(Type.INT); - } - /** Symbolically executes the corresponding Java Virtual Machine instruction. */ - public void visitD2L(D2L o){ - stack().pop(); - stack().push(Type.LONG); - } - /** Symbolically executes the corresponding Java Virtual Machine instruction. */ - public void visitDADD(DADD o){ - stack().pop(); - stack().pop(); - stack().push(Type.DOUBLE); - } - /** Symbolically executes the corresponding Java Virtual Machine instruction. */ - public void visitDALOAD(DALOAD o){ - stack().pop(); - stack().pop(); - stack().push(Type.DOUBLE); - } - /** Symbolically executes the corresponding Java Virtual Machine instruction. */ - public void visitDASTORE(DASTORE o){ - stack().pop(); - stack().pop(); - stack().pop(); - } - /** Symbolically executes the corresponding Java Virtual Machine instruction. */ - public void visitDCMPG(DCMPG o){ - stack().pop(); - stack().pop(); - stack().push(Type.INT); - } - /** Symbolically executes the corresponding Java Virtual Machine instruction. */ - public void visitDCMPL(DCMPL o){ - stack().pop(); - stack().pop(); - stack().push(Type.INT); - } - /** Symbolically executes the corresponding Java Virtual Machine instruction. */ - public void visitDCONST(DCONST o){ - stack().push(Type.DOUBLE); - } - /** Symbolically executes the corresponding Java Virtual Machine instruction. */ - public void visitDDIV(DDIV o){ - stack().pop(); - stack().pop(); - stack().push(Type.DOUBLE); - } - /** Symbolically executes the corresponding Java Virtual Machine instruction. */ - public void visitDLOAD(DLOAD o){ - stack().push(Type.DOUBLE); - } - /** Symbolically executes the corresponding Java Virtual Machine instruction. */ - public void visitDMUL(DMUL o){ - stack().pop(); - stack().pop(); - stack().push(Type.DOUBLE); - } - /** Symbolically executes the corresponding Java Virtual Machine instruction. */ - public void visitDNEG(DNEG o){ - stack().pop(); - stack().push(Type.DOUBLE); - } - /** Symbolically executes the corresponding Java Virtual Machine instruction. */ - public void visitDREM(DREM o){ - stack().pop(); - stack().pop(); - stack().push(Type.DOUBLE); - } - /** Symbolically executes the corresponding Java Virtual Machine instruction. */ - public void visitDRETURN(DRETURN o){ - stack().pop(); - } - /** Symbolically executes the corresponding Java Virtual Machine instruction. */ - public void visitDSTORE(DSTORE o){ - locals().set(o.getIndex(), stack().pop()); - locals().set(o.getIndex()+1, Type.UNKNOWN); - } - /** Symbolically executes the corresponding Java Virtual Machine instruction. */ - public void visitDSUB(DSUB o){ - stack().pop(); - stack().pop(); - stack().push(Type.DOUBLE); - } - /** Symbolically executes the corresponding Java Virtual Machine instruction. */ - public void visitDUP(DUP o){ - Type t = stack().pop(); - stack().push(t); - stack().push(t); - } - /** Symbolically executes the corresponding Java Virtual Machine instruction. */ - public void visitDUP_X1(DUP_X1 o){ - Type w1 = stack().pop(); - Type w2 = stack().pop(); - stack().push(w1); - stack().push(w2); - stack().push(w1); - } - /** Symbolically executes the corresponding Java Virtual Machine instruction. */ - public void visitDUP_X2(DUP_X2 o){ - Type w1 = stack().pop(); - Type w2 = stack().pop(); - if (w2.getSize() == 2){ - stack().push(w1); - stack().push(w2); - stack().push(w1); - } - else{ - Type w3 = stack().pop(); - stack().push(w1); - stack().push(w3); - stack().push(w2); - stack().push(w1); - } - } - /** Symbolically executes the corresponding Java Virtual Machine instruction. */ - public void visitDUP2(DUP2 o){ - Type t = stack().pop(); - if (t.getSize() == 2){ - stack().push(t); - stack().push(t); - } - else{ // t.getSize() is 1 - Type u = stack().pop(); - stack().push(u); - stack().push(t); - stack().push(u); - stack().push(t); - } - } - /** Symbolically executes the corresponding Java Virtual Machine instruction. */ - public void visitDUP2_X1(DUP2_X1 o){ - Type t = stack().pop(); - if (t.getSize() == 2){ - Type u = stack().pop(); - stack().push(t); - stack().push(u); - stack().push(t); - } - else{ //t.getSize() is1 - Type u = stack().pop(); - Type v = stack().pop(); - stack().push(u); - stack().push(t); - stack().push(v); - stack().push(u); - stack().push(t); - } - } - /** Symbolically executes the corresponding Java Virtual Machine instruction. */ - public void visitDUP2_X2(DUP2_X2 o){ - Type t = stack().pop(); - if (t.getSize() == 2){ - Type u = stack().pop(); - if (u.getSize() == 2){ - stack().push(t); - stack().push(u); - stack().push(t); - }else{ - Type v = stack().pop(); - stack().push(t); - stack().push(v); - stack().push(u); - stack().push(t); - } - } - else{ //t.getSize() is 1 - Type u = stack().pop(); - Type v = stack().pop(); - if (v.getSize() == 2){ - stack().push(u); - stack().push(t); - stack().push(v); - stack().push(u); - stack().push(t); - }else{ - Type w = stack().pop(); - stack().push(u); - stack().push(t); - stack().push(w); - stack().push(v); - stack().push(u); - stack().push(t); - } - } - } - /** Symbolically executes the corresponding Java Virtual Machine instruction. */ - public void visitF2D(F2D o){ - stack().pop(); - stack().push(Type.DOUBLE); - } - /** Symbolically executes the corresponding Java Virtual Machine instruction. */ - public void visitF2I(F2I o){ - stack().pop(); - stack().push(Type.INT); - } - /** Symbolically executes the corresponding Java Virtual Machine instruction. */ - public void visitF2L(F2L o){ - stack().pop(); - stack().push(Type.LONG); - } - /** Symbolically executes the corresponding Java Virtual Machine instruction. */ - public void visitFADD(FADD o){ - stack().pop(); - stack().pop(); - stack().push(Type.FLOAT); - } - /** Symbolically executes the corresponding Java Virtual Machine instruction. */ - public void visitFALOAD(FALOAD o){ - stack().pop(); - stack().pop(); - stack().push(Type.FLOAT); - } - /** Symbolically executes the corresponding Java Virtual Machine instruction. */ - public void visitFASTORE(FASTORE o){ - stack().pop(); - stack().pop(); - stack().pop(); - } - /** Symbolically executes the corresponding Java Virtual Machine instruction. */ - public void visitFCMPG(FCMPG o){ - stack().pop(); - stack().pop(); - stack().push(Type.INT); - } - /** Symbolically executes the corresponding Java Virtual Machine instruction. */ - public void visitFCMPL(FCMPL o){ - stack().pop(); - stack().pop(); - stack().push(Type.INT); - } - /** Symbolically executes the corresponding Java Virtual Machine instruction. */ - public void visitFCONST(FCONST o){ - stack().push(Type.FLOAT); - } - /** Symbolically executes the corresponding Java Virtual Machine instruction. */ - public void visitFDIV(FDIV o){ - stack().pop(); - stack().pop(); - stack().push(Type.FLOAT); - } - /** Symbolically executes the corresponding Java Virtual Machine instruction. */ - public void visitFLOAD(FLOAD o){ - stack().push(Type.FLOAT); - } - /** Symbolically executes the corresponding Java Virtual Machine instruction. */ - public void visitFMUL(FMUL o){ - stack().pop(); - stack().pop(); - stack().push(Type.FLOAT); - } - /** Symbolically executes the corresponding Java Virtual Machine instruction. */ - public void visitFNEG(FNEG o){ - stack().pop(); - stack().push(Type.FLOAT); - } - /** Symbolically executes the corresponding Java Virtual Machine instruction. */ - public void visitFREM(FREM o){ - stack().pop(); - stack().pop(); - stack().push(Type.FLOAT); - } - /** Symbolically executes the corresponding Java Virtual Machine instruction. */ - public void visitFRETURN(FRETURN o){ - stack().pop(); - } - /** Symbolically executes the corresponding Java Virtual Machine instruction. */ - public void visitFSTORE(FSTORE o){ - locals().set(o.getIndex(), stack().pop()); - } - /** Symbolically executes the corresponding Java Virtual Machine instruction. */ - public void visitFSUB(FSUB o){ - stack().pop(); - stack().pop(); - stack().push(Type.FLOAT); - } - /** Symbolically executes the corresponding Java Virtual Machine instruction. */ - public void visitGETFIELD(GETFIELD o){ - stack().pop(); - Type t = o.getFieldType(cpg); - if ( t.equals(Type.BOOLEAN) || - t.equals(Type.CHAR) || - t.equals(Type.BYTE) || - t.equals(Type.SHORT) ) { - t = Type.INT; - } - stack().push(t); - } - /** Symbolically executes the corresponding Java Virtual Machine instruction. */ - public void visitGETSTATIC(GETSTATIC o){ - Type t = o.getFieldType(cpg); - if ( t.equals(Type.BOOLEAN) || - t.equals(Type.CHAR) || - t.equals(Type.BYTE) || - t.equals(Type.SHORT) ) { - t = Type.INT; - } - stack().push(t); - } - /** Symbolically executes the corresponding Java Virtual Machine instruction. */ - public void visitGOTO(GOTO o){ - // no stack changes. - } - /** Symbolically executes the corresponding Java Virtual Machine instruction. */ - public void visitGOTO_W(GOTO_W o){ - // no stack changes. - } - /** Symbolically executes the corresponding Java Virtual Machine instruction. */ - public void visitI2B(I2B o){ - stack().pop(); - stack().push(Type.INT); - } - /** Symbolically executes the corresponding Java Virtual Machine instruction. */ - public void visitI2C(I2C o){ - stack().pop(); - stack().push(Type.INT); - } - /** Symbolically executes the corresponding Java Virtual Machine instruction. */ - public void visitI2D(I2D o){ - stack().pop(); - stack().push(Type.DOUBLE); - } - /** Symbolically executes the corresponding Java Virtual Machine instruction. */ - public void visitI2F(I2F o){ - stack().pop(); - stack().push(Type.FLOAT); - } - /** Symbolically executes the corresponding Java Virtual Machine instruction. */ - public void visitI2L(I2L o){ - stack().pop(); - stack().push(Type.LONG); - } - /** Symbolically executes the corresponding Java Virtual Machine instruction. */ - public void visitI2S(I2S o){ - stack().pop(); - stack().push(Type.INT); - } - /** Symbolically executes the corresponding Java Virtual Machine instruction. */ - public void visitIADD(IADD o){ - stack().pop(); - stack().pop(); - stack().push(Type.INT); - } - /** Symbolically executes the corresponding Java Virtual Machine instruction. */ - public void visitIALOAD(IALOAD o){ - stack().pop(); - stack().pop(); - stack().push(Type.INT); - } - /** Symbolically executes the corresponding Java Virtual Machine instruction. */ - public void visitIAND(IAND o){ - stack().pop(); - stack().pop(); - stack().push(Type.INT); - } - /** Symbolically executes the corresponding Java Virtual Machine instruction. */ - public void visitIASTORE(IASTORE o){ - stack().pop(); - stack().pop(); - stack().pop(); - } - /** Symbolically executes the corresponding Java Virtual Machine instruction. */ - public void visitICONST(ICONST o){ - stack().push(Type.INT); - } - /** Symbolically executes the corresponding Java Virtual Machine instruction. */ - public void visitIDIV(IDIV o){ - stack().pop(); - stack().pop(); - stack().push(Type.INT); - } - /** Symbolically executes the corresponding Java Virtual Machine instruction. */ - public void visitIF_ACMPEQ(IF_ACMPEQ o){ - stack().pop(); - stack().pop(); - } - /** Symbolically executes the corresponding Java Virtual Machine instruction. */ - public void visitIF_ACMPNE(IF_ACMPNE o){ - stack().pop(); - stack().pop(); - } - /** Symbolically executes the corresponding Java Virtual Machine instruction. */ - public void visitIF_ICMPEQ(IF_ICMPEQ o){ - stack().pop(); - stack().pop(); - } - /** Symbolically executes the corresponding Java Virtual Machine instruction. */ - public void visitIF_ICMPGE(IF_ICMPGE o){ - stack().pop(); - stack().pop(); - } - /** Symbolically executes the corresponding Java Virtual Machine instruction. */ - public void visitIF_ICMPGT(IF_ICMPGT o){ - stack().pop(); - stack().pop(); - } - /** Symbolically executes the corresponding Java Virtual Machine instruction. */ - public void visitIF_ICMPLE(IF_ICMPLE o){ - stack().pop(); - stack().pop(); - } - /** Symbolically executes the corresponding Java Virtual Machine instruction. */ - public void visitIF_ICMPLT(IF_ICMPLT o){ - stack().pop(); - stack().pop(); - } - /** Symbolically executes the corresponding Java Virtual Machine instruction. */ - public void visitIF_ICMPNE(IF_ICMPNE o){ - stack().pop(); - stack().pop(); - } - /** Symbolically executes the corresponding Java Virtual Machine instruction. */ - public void visitIFEQ(IFEQ o){ - stack().pop(); - } - /** Symbolically executes the corresponding Java Virtual Machine instruction. */ - public void visitIFGE(IFGE o){ - stack().pop(); - } - /** Symbolically executes the corresponding Java Virtual Machine instruction. */ - public void visitIFGT(IFGT o){ - stack().pop(); - } - /** Symbolically executes the corresponding Java Virtual Machine instruction. */ - public void visitIFLE(IFLE o){ - stack().pop(); - } - /** Symbolically executes the corresponding Java Virtual Machine instruction. */ - public void visitIFLT(IFLT o){ - stack().pop(); - } - /** Symbolically executes the corresponding Java Virtual Machine instruction. */ - public void visitIFNE(IFNE o){ - stack().pop(); - } - /** Symbolically executes the corresponding Java Virtual Machine instruction. */ - public void visitIFNONNULL(IFNONNULL o){ - stack().pop(); - } - /** Symbolically executes the corresponding Java Virtual Machine instruction. */ - public void visitIFNULL(IFNULL o){ - stack().pop(); - } - /** Symbolically executes the corresponding Java Virtual Machine instruction. */ - public void visitIINC(IINC o){ - // stack is not changed. - } - /** Symbolically executes the corresponding Java Virtual Machine instruction. */ - public void visitILOAD(ILOAD o){ - stack().push(Type.INT); - } - /** Symbolically executes the corresponding Java Virtual Machine instruction. */ - public void visitIMUL(IMUL o){ - stack().pop(); - stack().pop(); - stack().push(Type.INT); - } - /** Symbolically executes the corresponding Java Virtual Machine instruction. */ - public void visitINEG(INEG o){ - stack().pop(); - stack().push(Type.INT); - } - /** Symbolically executes the corresponding Java Virtual Machine instruction. */ - public void visitINSTANCEOF(INSTANCEOF o){ - stack().pop(); - stack().push(Type.INT); - } - /** Symbolically executes the corresponding Java Virtual Machine instruction. */ - public void visitINVOKEINTERFACE(INVOKEINTERFACE o){ - stack().pop(); //objectref - for (int i=0; i stack().slotsUsed()){ - constraintViolated((Instruction) o, "Cannot consume "+consume+" stack slots: only "+stack().slotsUsed()+" slot(s) left on stack!\nStack:\n"+stack()); - } - - int produce = o.produceStack(cpg) - ((Instruction) o).consumeStack(cpg); // Stack values are always consumed first; then produced. - if ( produce + stack().slotsUsed() > stack().maxStack() ){ - constraintViolated((Instruction) o, "Cannot produce "+produce+" stack slots: only "+(stack().maxStack()-stack().slotsUsed())+" free stack slot(s) left.\nStack:\n"+stack()); - } - } - - /***************************************************************/ - /* "generic"visitXXXX methods where XXXX is an interface */ - /* therefore, we don't know the order of visiting; but we know */ - /* these methods are called before the visitYYYY methods below */ - /***************************************************************/ - - /** - * Assures the generic preconditions of a LoadClass instance. - * The referenced class is loaded and pass2-verified. - */ - public void visitLoadClass(LoadClass o){ - ObjectType t = o.getLoadClassType(cpg); - if (t != null){// null means "no class is loaded" - Verifier v = VerifierFactory.getVerifier(t.getClassName()); - VerificationResult vr = v.doPass2(); - if (vr.getStatus() != VerificationResult.VERIFIED_OK){ - constraintViolated((Instruction) o, "Class '"+o.getLoadClassType(cpg).getClassName()+"' is referenced, but cannot be loaded and resolved: '"+vr+"'."); - } - } - } - - /** - * Ensures the general preconditions of a StackConsumer instance. - */ - public void visitStackConsumer(StackConsumer o){ - _visitStackAccessor((Instruction) o); - } - - /** - * Ensures the general preconditions of a StackProducer instance. - */ - public void visitStackProducer(StackProducer o){ - _visitStackAccessor((Instruction) o); - } - - - /***************************************************************/ - /* "generic" visitYYYY methods where YYYY is a superclass. */ - /* therefore, we know the order of visiting; we know */ - /* these methods are called after the visitXXXX methods above. */ - /***************************************************************/ - /** - * Ensures the general preconditions of a CPInstruction instance. - */ - public void visitCPInstruction(CPInstruction o){ - int idx = o.getIndex(); - if ((idx < 0) || (idx >= cpg.getSize())){ - throw new AssertionViolatedException("Huh?! Constant pool index of instruction '"+o+"' illegal? Pass 3a should have checked this!"); - } - } - - /** - * Ensures the general preconditions of a FieldInstruction instance. - */ - public void visitFieldInstruction(FieldInstruction o){ - // visitLoadClass(o) has been called before: Every FieldOrMethod - // implements LoadClass. - // visitCPInstruction(o) has been called before. - // A FieldInstruction may be: GETFIELD, GETSTATIC, PUTFIELD, PUTSTATIC - Constant c = cpg.getConstant(o.getIndex()); - if (!(c instanceof ConstantFieldref)){ - constraintViolated(o, "Index '"+o.getIndex()+"' should refer to a CONSTANT_Fieldref_info structure, but refers to '"+c+"'."); - } - // the o.getClassType(cpg) type has passed pass 2; see visitLoadClass(o). - Type t = o.getType(cpg); - if (t instanceof ObjectType){ - String name = ((ObjectType)t).getClassName(); - Verifier v = VerifierFactory.getVerifier( name ); - VerificationResult vr = v.doPass2(); - if (vr.getStatus() != VerificationResult.VERIFIED_OK){ - constraintViolated((Instruction) o, "Class '"+name+"' is referenced, but cannot be loaded and resolved: '"+vr+"'."); - } - } - } - - /** - * Ensures the general preconditions of an InvokeInstruction instance. - */ - public void visitInvokeInstruction(InvokeInstruction o){ - // visitLoadClass(o) has been called before: Every FieldOrMethod - // implements LoadClass. - // visitCPInstruction(o) has been called before. - //TODO - } - - /** - * Ensures the general preconditions of a StackInstruction instance. - */ - public void visitStackInstruction(StackInstruction o){ - _visitStackAccessor(o); - } - - /** - * Assures the generic preconditions of a LocalVariableInstruction instance. - * That is, the index of the local variable must be valid. - */ - public void visitLocalVariableInstruction(LocalVariableInstruction o){ - if (locals().maxLocals() <= (o.getType(cpg).getSize()==1? o.getIndex() : o.getIndex()+1) ){ - constraintViolated(o, "The 'index' is not a valid index into the local variable array."); - } - } - - /** - * Assures the generic preconditions of a LoadInstruction instance. - */ - public void visitLoadInstruction(LoadInstruction o){ - //visitLocalVariableInstruction(o) is called before, because it is more generic. - - // LOAD instructions must not read Type.UNKNOWN - if (locals().get(o.getIndex()) == Type.UNKNOWN){ - constraintViolated(o, "Read-Access on local variable "+o.getIndex()+" with unknown content."); - } - - // LOAD instructions, two-slot-values at index N must have Type.UNKNOWN - // as a symbol for the higher halve at index N+1 - // [suppose some instruction put an int at N+1--- our double at N is defective] - if (o.getType(cpg).getSize() == 2){ - if (locals().get(o.getIndex()+1) != Type.UNKNOWN){ - constraintViolated(o, "Reading a two-locals value from local variables "+o.getIndex()+" and "+(o.getIndex()+1)+" where the latter one is destroyed."); - } - } - - // LOAD instructions must read the correct type. - if (!(o instanceof ALOAD)){ - if (locals().get(o.getIndex()) != o.getType(cpg) ){ - constraintViolated(o, "Local Variable type and LOADing Instruction type mismatch: Local Variable: '"+locals().get(o.getIndex())+"'; Instruction type: '"+o.getType(cpg)+"'."); - } - } - else{ // we deal with an ALOAD - if (!(locals().get(o.getIndex()) instanceof ReferenceType)){ - constraintViolated(o, "Local Variable type and LOADing Instruction type mismatch: Local Variable: '"+locals().get(o.getIndex())+"'; Instruction expects a ReferenceType."); - } - // ALOAD __IS ALLOWED__ to put uninitialized objects onto the stack! - //referenceTypeIsInitialized(o, (ReferenceType) (locals().get(o.getIndex()))); - } - - // LOAD instructions must have enough free stack slots. - if ((stack().maxStack() - stack().slotsUsed()) < o.getType(cpg).getSize()){ - constraintViolated(o, "Not enough free stack slots to load a '"+o.getType(cpg)+"' onto the OperandStack."); - } - } - - /** - * Assures the generic preconditions of a StoreInstruction instance. - */ - public void visitStoreInstruction(StoreInstruction o){ - //visitLocalVariableInstruction(o) is called before, because it is more generic. - - if (stack().isEmpty()){ // Don't bother about 1 or 2 stack slots used. This check is implicitely done below while type checking. - constraintViolated(o, "Cannot STORE: Stack to read from is empty."); - } - - if ( (!(o instanceof ASTORE)) ){ - if (! (stack().peek() == o.getType(cpg)) ){// the other xSTORE types are singletons in BCEL. - constraintViolated(o, "Stack top type and STOREing Instruction type mismatch: Stack top: '"+stack().peek()+"'; Instruction type: '"+o.getType(cpg)+"'."); - } - } - else{ // we deal with ASTORE - Type stacktop = stack().peek(); - if ( (!(stacktop instanceof ReferenceType)) && (!(stacktop instanceof ReturnaddressType)) ){ - constraintViolated(o, "Stack top type and STOREing Instruction type mismatch: Stack top: '"+stack().peek()+"'; Instruction expects a ReferenceType or a ReturnadressType."); - } - //if (stacktop instanceof ReferenceType){ - // referenceTypeIsInitialized(o, (ReferenceType) stacktop); - //} - } - } - - /** - * Assures the generic preconditions of a ReturnInstruction instance. - */ - public void visitReturnInstruction(ReturnInstruction o){ - Type method_type = mg.getType(); - if (method_type == Type.BOOLEAN || - method_type == Type.BYTE || - method_type == Type.SHORT || - method_type == Type.CHAR){ - method_type = Type.INT; - } - - if (o instanceof RETURN){ - if (method_type != Type.VOID){ - constraintViolated(o, "RETURN instruction in non-void method."); - } - else{ - return; - } - } - if (o instanceof ARETURN){ - if (stack().peek() == Type.NULL){ - return; - } - else{ - if (! (stack().peek() instanceof ReferenceType)){ - constraintViolated(o, "Reference type expected on top of stack, but is: '"+stack().peek()+"'."); - } - referenceTypeIsInitialized(o, (ReferenceType) (stack().peek())); - //ReferenceType objectref = (ReferenceType) (stack().peek()); - // TODO: This can only be checked if using Staerk-et-al's "set of object types" instead of a - // "wider cast object type" created during verification. - //if (! (objectref.isAssignmentCompatibleWith(mg.getType())) ){ - // constraintViolated(o, "Type on stack top which should be returned is a '"+stack().peek()+"' which is not assignment compatible with the return type of this method, '"+mg.getType()+"'."); - //} - } - } - else{ - if (! ( method_type.equals( stack().peek() ))){ - constraintViolated(o, "Current method has return type of '"+mg.getType()+"' expecting a '"+method_type+"' on top of the stack. But stack top is a '"+stack().peek()+"'."); - } - } - } - - /***************************************************************/ - /* "special"visitXXXX methods for one type of instruction each */ - /***************************************************************/ - - /** - * Ensures the specific preconditions of the said instruction. - */ - public void visitAALOAD(AALOAD o){ - Type arrayref = stack().peek(1); - Type index = stack().peek(0); - - indexOfInt(o, index); - if (arrayrefOfArrayType(o, arrayref)){ - if (! (((ArrayType) arrayref).getElementType() instanceof ReferenceType)){ - constraintViolated(o, "The 'arrayref' does not refer to an array with elements of a ReferenceType but to an array of "+((ArrayType) arrayref).getElementType()+"."); - } - //referenceTypeIsInitialized(o, (ReferenceType) (((ArrayType) arrayref).getElementType())); - } - } - - /** - * Ensures the specific preconditions of the said instruction. - */ - public void visitAASTORE(AASTORE o){ - try { - Type arrayref = stack().peek(2); - Type index = stack().peek(1); - Type value = stack().peek(0); - - indexOfInt(o, index); - if (!(value instanceof ReferenceType)){ - constraintViolated(o, "The 'value' is not of a ReferenceType but of type "+value+"."); - }else{ - //referenceTypeIsInitialized(o, (ReferenceType) value); - } - // Don't bother further with "referenceTypeIsInitialized()", there are no arrays - // of an uninitialized object type. - if (arrayrefOfArrayType(o, arrayref)){ - if (! (((ArrayType) arrayref).getElementType() instanceof ReferenceType)){ - constraintViolated(o, "The 'arrayref' does not refer to an array with elements of a ReferenceType but to an array of "+((ArrayType) arrayref).getElementType()+"."); - } - if (! ((ReferenceType)value).isAssignmentCompatibleWith((ReferenceType) ((ArrayType) arrayref).getElementType())){ - constraintViolated(o, "The type of 'value' ('"+value+"') is not assignment compatible to the components of the array 'arrayref' refers to. ('"+((ArrayType) arrayref).getElementType()+"')"); - } - } - } catch (ClassNotFoundException e) { - // FIXME: maybe not the best way to handle this - throw new AssertionViolatedException("Missing class: " + e.toString()); - } - } - - /** - * Ensures the specific preconditions of the said instruction. - */ - public void visitACONST_NULL(ACONST_NULL o){ - // Nothing needs to be done here. - } - - /** - * Ensures the specific preconditions of the said instruction. - */ - public void visitALOAD(ALOAD o){ - //visitLoadInstruction(LoadInstruction) is called before. - - // Nothing else needs to be done here. - } - - /** - * Ensures the specific preconditions of the said instruction. - */ - public void visitANEWARRAY(ANEWARRAY o){ - if (!stack().peek().equals(Type.INT)) { - constraintViolated(o, "The 'count' at the stack top is not of type '"+Type.INT+"' but of type '"+stack().peek()+"'."); - // The runtime constant pool item at that index must be a symbolic reference to a class, - // array, or interface type. See Pass 3a. - } - } - - /** - * Ensures the specific preconditions of the said instruction. - */ - public void visitARETURN(ARETURN o){ - if (! (stack().peek() instanceof ReferenceType) ){ - constraintViolated(o, "The 'objectref' at the stack top is not of a ReferenceType but of type '"+stack().peek()+"'."); - } - ReferenceType objectref = (ReferenceType) (stack().peek()); - referenceTypeIsInitialized(o, objectref); - - // The check below should already done via visitReturnInstruction(ReturnInstruction), see there. - // It cannot be done using Staerk-et-al's "set of object types" instead of a - // "wider cast object type", anyway. - //if (! objectref.isAssignmentCompatibleWith(mg.getReturnType() )){ - // constraintViolated(o, "The 'objectref' type "+objectref+" at the stack top is not assignment compatible with the return type '"+mg.getReturnType()+"' of the method."); - //} - } - - /** - * Ensures the specific preconditions of the said instruction. - */ - public void visitARRAYLENGTH(ARRAYLENGTH o){ - Type arrayref = stack().peek(0); - arrayrefOfArrayType(o, arrayref); - } - - /** - * Ensures the specific preconditions of the said instruction. - */ - public void visitASTORE(ASTORE o){ - if (! ( (stack().peek() instanceof ReferenceType) || (stack().peek() instanceof ReturnaddressType) ) ){ - constraintViolated(o, "The 'objectref' is not of a ReferenceType or of ReturnaddressType but of "+stack().peek()+"."); - } - //if (stack().peek() instanceof ReferenceType){ - // referenceTypeIsInitialized(o, (ReferenceType) (stack().peek()) ); - //} - } - - /** - * Ensures the specific preconditions of the said instruction. - */ - public void visitATHROW(ATHROW o){ - try { - // It's stated that 'objectref' must be of a ReferenceType --- but since Throwable is - // not derived from an ArrayType, it follows that 'objectref' must be of an ObjectType or Type.NULL. - if (! ((stack().peek() instanceof ObjectType) || (stack().peek().equals(Type.NULL))) ){ - constraintViolated(o, "The 'objectref' is not of an (initialized) ObjectType but of type "+stack().peek()+"."); - } - - // NULL is a subclass of every class, so to speak. - if (stack().peek().equals(Type.NULL)) { - return; - } - - ObjectType exc = (ObjectType) (stack().peek()); - ObjectType throwable = (ObjectType) (Type.getType("Ljava/lang/Throwable;")); - if ( (! (exc.subclassOf(throwable)) ) && (! (exc.equals(throwable))) ){ - constraintViolated(o, "The 'objectref' is not of class Throwable or of a subclass of Throwable, but of '"+stack().peek()+"'."); - } - } catch (ClassNotFoundException e) { - // FIXME: maybe not the best way to handle this - throw new AssertionViolatedException("Missing class: " + e.toString()); - } - } - - /** - * Ensures the specific preconditions of the said instruction. - */ - public void visitBALOAD(BALOAD o){ - Type arrayref = stack().peek(1); - Type index = stack().peek(0); - indexOfInt(o, index); - if (arrayrefOfArrayType(o, arrayref)){ - if (! ( (((ArrayType) arrayref).getElementType().equals(Type.BOOLEAN)) || - (((ArrayType) arrayref).getElementType().equals(Type.BYTE)) ) ){ - constraintViolated(o, "The 'arrayref' does not refer to an array with elements of a Type.BYTE or Type.BOOLEAN but to an array of '"+((ArrayType) arrayref).getElementType()+"'."); - } - } - } - - /** - * Ensures the specific preconditions of the said instruction. - */ - public void visitBASTORE(BASTORE o){ - Type arrayref = stack().peek(2); - Type index = stack().peek(1); - Type value = stack().peek(0); - - indexOfInt(o, index); - valueOfInt(o, value); - if (arrayrefOfArrayType(o, arrayref)){ - if (! ( (((ArrayType) arrayref).getElementType().equals(Type.BOOLEAN)) || - (((ArrayType) arrayref).getElementType().equals(Type.BYTE)) ) ) { - constraintViolated(o, "The 'arrayref' does not refer to an array with elements of a Type.BYTE or Type.BOOLEAN but to an array of '"+((ArrayType) arrayref).getElementType()+"'."); - } - } - } - - /** - * Ensures the specific preconditions of the said instruction. - */ - public void visitBIPUSH(BIPUSH o){ - // Nothing to do... - } - - /** - * Ensures the specific preconditions of the said instruction. - */ - public void visitBREAKPOINT(BREAKPOINT o){ - throw new AssertionViolatedException("In this JustIce verification pass there should not occur an illegal instruction such as BREAKPOINT."); - } - - /** - * Ensures the specific preconditions of the said instruction. - */ - public void visitCALOAD(CALOAD o){ - Type arrayref = stack().peek(1); - Type index = stack().peek(0); - - indexOfInt(o, index); - arrayrefOfArrayType(o, arrayref); - } - - /** - * Ensures the specific preconditions of the said instruction. - */ - public void visitCASTORE(CASTORE o){ - Type arrayref = stack().peek(2); - Type index = stack().peek(1); - Type value = stack().peek(0); - - indexOfInt(o, index); - valueOfInt(o, value); - if (arrayrefOfArrayType(o, arrayref)){ - if (! ((ArrayType) arrayref).getElementType().equals(Type.CHAR) ){ - constraintViolated(o, "The 'arrayref' does not refer to an array with elements of type char but to an array of type "+((ArrayType) arrayref).getElementType()+"."); - } - } - } - - /** - * Ensures the specific preconditions of the said instruction. - */ - public void visitCHECKCAST(CHECKCAST o){ - // The objectref must be of type reference. - Type objectref = stack().peek(0); - if (!(objectref instanceof ReferenceType)){ - constraintViolated(o, "The 'objectref' is not of a ReferenceType but of type "+objectref+"."); - } - //else{ - // referenceTypeIsInitialized(o, (ReferenceType) objectref); - //} - // The unsigned indexbyte1 and indexbyte2 are used to construct an index into the runtime constant pool of the - // current class (3.6), where the value of the index is (indexbyte1 << 8) | indexbyte2. The runtime constant - // pool item at the index must be a symbolic reference to a class, array, or interface type. - Constant c = cpg.getConstant(o.getIndex()); - if (! (c instanceof ConstantClass)){ - constraintViolated(o, "The Constant at 'index' is not a ConstantClass, but '"+c+"'."); - } - } - - /** - * Ensures the specific preconditions of the said instruction. - */ - public void visitD2F(D2F o){ - if (stack().peek() != Type.DOUBLE){ - constraintViolated(o, "The value at the stack top is not of type 'double', but of type '"+stack().peek()+"'."); - } - } - - /** - * Ensures the specific preconditions of the said instruction. - */ - public void visitD2I(D2I o){ - if (stack().peek() != Type.DOUBLE){ - constraintViolated(o, "The value at the stack top is not of type 'double', but of type '"+stack().peek()+"'."); - } - } - - /** - * Ensures the specific preconditions of the said instruction. - */ - public void visitD2L(D2L o){ - if (stack().peek() != Type.DOUBLE){ - constraintViolated(o, "The value at the stack top is not of type 'double', but of type '"+stack().peek()+"'."); - } - } - - /** - * Ensures the specific preconditions of the said instruction. - */ - public void visitDADD(DADD o){ - if (stack().peek() != Type.DOUBLE){ - constraintViolated(o, "The value at the stack top is not of type 'double', but of type '"+stack().peek()+"'."); - } - if (stack().peek(1) != Type.DOUBLE){ - constraintViolated(o, "The value at the stack next-to-top is not of type 'double', but of type '"+stack().peek(1)+"'."); - } - } - - /** - * Ensures the specific preconditions of the said instruction. - */ - public void visitDALOAD(DALOAD o){ - indexOfInt(o, stack().peek()); - if (stack().peek(1) == Type.NULL){ - return; - } - if (! (stack().peek(1) instanceof ArrayType)){ - constraintViolated(o, "Stack next-to-top must be of type double[] but is '"+stack().peek(1)+"'."); - } - Type t = ((ArrayType) (stack().peek(1))).getBasicType(); - if (t != Type.DOUBLE){ - constraintViolated(o, "Stack next-to-top must be of type double[] but is '"+stack().peek(1)+"'."); - } - } - - /** - * Ensures the specific preconditions of the said instruction. - */ - public void visitDASTORE(DASTORE o){ - if (stack().peek() != Type.DOUBLE){ - constraintViolated(o, "The value at the stack top is not of type 'double', but of type '"+stack().peek()+"'."); - } - indexOfInt(o, stack().peek(1)); - if (stack().peek(2) == Type.NULL){ - return; - } - if (! (stack().peek(2) instanceof ArrayType)){ - constraintViolated(o, "Stack next-to-next-to-top must be of type double[] but is '"+stack().peek(2)+"'."); - } - Type t = ((ArrayType) (stack().peek(2))).getBasicType(); - if (t != Type.DOUBLE){ - constraintViolated(o, "Stack next-to-next-to-top must be of type double[] but is '"+stack().peek(2)+"'."); - } - } - - /** - * Ensures the specific preconditions of the said instruction. - */ - public void visitDCMPG(DCMPG o){ - if (stack().peek() != Type.DOUBLE){ - constraintViolated(o, "The value at the stack top is not of type 'double', but of type '"+stack().peek()+"'."); - } - if (stack().peek(1) != Type.DOUBLE){ - constraintViolated(o, "The value at the stack next-to-top is not of type 'double', but of type '"+stack().peek(1)+"'."); - } - } - - /** - * Ensures the specific preconditions of the said instruction. - */ - public void visitDCMPL(DCMPL o){ - if (stack().peek() != Type.DOUBLE){ - constraintViolated(o, "The value at the stack top is not of type 'double', but of type '"+stack().peek()+"'."); - } - if (stack().peek(1) != Type.DOUBLE){ - constraintViolated(o, "The value at the stack next-to-top is not of type 'double', but of type '"+stack().peek(1)+"'."); - } - } - - /** - * Ensures the specific preconditions of the said instruction. - */ - public void visitDCONST(DCONST o){ - // There's nothing to be done here. - } - - /** - * Ensures the specific preconditions of the said instruction. - */ - public void visitDDIV(DDIV o){ - if (stack().peek() != Type.DOUBLE){ - constraintViolated(o, "The value at the stack top is not of type 'double', but of type '"+stack().peek()+"'."); - } - if (stack().peek(1) != Type.DOUBLE){ - constraintViolated(o, "The value at the stack next-to-top is not of type 'double', but of type '"+stack().peek(1)+"'."); - } - } - - /** - * Ensures the specific preconditions of the said instruction. - */ - public void visitDLOAD(DLOAD o){ - //visitLoadInstruction(LoadInstruction) is called before. - - // Nothing else needs to be done here. - } - - /** - * Ensures the specific preconditions of the said instruction. - */ - public void visitDMUL(DMUL o){ - if (stack().peek() != Type.DOUBLE){ - constraintViolated(o, "The value at the stack top is not of type 'double', but of type '"+stack().peek()+"'."); - } - if (stack().peek(1) != Type.DOUBLE){ - constraintViolated(o, "The value at the stack next-to-top is not of type 'double', but of type '"+stack().peek(1)+"'."); - } - } - - /** - * Ensures the specific preconditions of the said instruction. - */ - public void visitDNEG(DNEG o){ - if (stack().peek() != Type.DOUBLE){ - constraintViolated(o, "The value at the stack top is not of type 'double', but of type '"+stack().peek()+"'."); - } - } - - /** - * Ensures the specific preconditions of the said instruction. - */ - public void visitDREM(DREM o){ - if (stack().peek() != Type.DOUBLE){ - constraintViolated(o, "The value at the stack top is not of type 'double', but of type '"+stack().peek()+"'."); - } - if (stack().peek(1) != Type.DOUBLE){ - constraintViolated(o, "The value at the stack next-to-top is not of type 'double', but of type '"+stack().peek(1)+"'."); - } - } - - /** - * Ensures the specific preconditions of the said instruction. - */ - public void visitDRETURN(DRETURN o){ - if (stack().peek() != Type.DOUBLE){ - constraintViolated(o, "The value at the stack top is not of type 'double', but of type '"+stack().peek()+"'."); - } - } - - /** - * Ensures the specific preconditions of the said instruction. - */ - public void visitDSTORE(DSTORE o){ - //visitStoreInstruction(StoreInstruction) is called before. - - // Nothing else needs to be done here. - } - - /** - * Ensures the specific preconditions of the said instruction. - */ - public void visitDSUB(DSUB o){ - if (stack().peek() != Type.DOUBLE){ - constraintViolated(o, "The value at the stack top is not of type 'double', but of type '"+stack().peek()+"'."); - } - if (stack().peek(1) != Type.DOUBLE){ - constraintViolated(o, "The value at the stack next-to-top is not of type 'double', but of type '"+stack().peek(1)+"'."); - } - } - - /** - * Ensures the specific preconditions of the said instruction. - */ - public void visitDUP(DUP o){ - if (stack().peek().getSize() != 1){ - constraintViolated(o, "Won't DUP type on stack top '"+stack().peek()+"' because it must occupy exactly one slot, not '"+stack().peek().getSize()+"'."); - } - } - - /** - * Ensures the specific preconditions of the said instruction. - */ - public void visitDUP_X1(DUP_X1 o){ - if (stack().peek().getSize() != 1){ - constraintViolated(o, "Type on stack top '"+stack().peek()+"' should occupy exactly one slot, not '"+stack().peek().getSize()+"'."); - } - if (stack().peek(1).getSize() != 1){ - constraintViolated(o, "Type on stack next-to-top '"+stack().peek(1)+"' should occupy exactly one slot, not '"+stack().peek(1).getSize()+"'."); - } - } - - /** - * Ensures the specific preconditions of the said instruction. - */ - public void visitDUP_X2(DUP_X2 o){ - if (stack().peek().getSize() != 1){ - constraintViolated(o, "Stack top type must be of size 1, but is '"+stack().peek()+"' of size '"+stack().peek().getSize()+"'."); - } - if (stack().peek(1).getSize() == 2){ - return; // Form 2, okay. - } - else{ //stack().peek(1).getSize == 1. - if (stack().peek(2).getSize() != 1){ - constraintViolated(o, "If stack top's size is 1 and stack next-to-top's size is 1, stack next-to-next-to-top's size must also be 1, but is: '"+stack().peek(2)+"' of size '"+stack().peek(2).getSize()+"'."); - } - } - } - - /** - * Ensures the specific preconditions of the said instruction. - */ - public void visitDUP2(DUP2 o){ - if (stack().peek().getSize() == 2){ - return; // Form 2, okay. - } - else{ //stack().peek().getSize() == 1. - if (stack().peek(1).getSize() != 1){ - constraintViolated(o, "If stack top's size is 1, then stack next-to-top's size must also be 1. But it is '"+stack().peek(1)+"' of size '"+stack().peek(1).getSize()+"'."); - } - } - } - - /** - * Ensures the specific preconditions of the said instruction. - */ - public void visitDUP2_X1(DUP2_X1 o){ - if (stack().peek().getSize() == 2){ - if (stack().peek(1).getSize() != 1){ - constraintViolated(o, "If stack top's size is 2, then stack next-to-top's size must be 1. But it is '"+stack().peek(1)+"' of size '"+stack().peek(1).getSize()+"'."); - } - else{ - return; // Form 2 - } - } - else{ // stack top is of size 1 - if ( stack().peek(1).getSize() != 1 ){ - constraintViolated(o, "If stack top's size is 1, then stack next-to-top's size must also be 1. But it is '"+stack().peek(1)+"' of size '"+stack().peek(1).getSize()+"'."); - } - if ( stack().peek(2).getSize() != 1 ){ - constraintViolated(o, "If stack top's size is 1, then stack next-to-next-to-top's size must also be 1. But it is '"+stack().peek(2)+"' of size '"+stack().peek(2).getSize()+"'."); - } - } - } - - /** - * Ensures the specific preconditions of the said instruction. - */ - public void visitDUP2_X2(DUP2_X2 o){ - - if (stack().peek(0).getSize() == 2){ - if (stack().peek(1).getSize() == 2){ - return; // Form 4 - } - else{// stack top size is 2, next-to-top's size is 1 - if ( stack().peek(2).getSize() != 1 ){ - constraintViolated(o, "If stack top's size is 2 and stack-next-to-top's size is 1, then stack next-to-next-to-top's size must also be 1. But it is '"+stack().peek(2)+"' of size '"+stack().peek(2).getSize()+"'."); - } - else{ - return; // Form 2 - } - } - } - else{// stack top is of size 1 - if (stack().peek(1).getSize() == 1){ - if ( stack().peek(2).getSize() == 2 ){ - return; // Form 3 - } - else{ - if ( stack().peek(3).getSize() == 1){ - return; // Form 1 - } - } - } - } - constraintViolated(o, "The operand sizes on the stack do not match any of the four forms of usage of this instruction."); - } - - /** - * Ensures the specific preconditions of the said instruction. - */ - public void visitF2D(F2D o){ - if (stack().peek() != Type.FLOAT){ - constraintViolated(o, "The value at the stack top is not of type 'float', but of type '"+stack().peek()+"'."); - } - } - - /** - * Ensures the specific preconditions of the said instruction. - */ - public void visitF2I(F2I o){ - if (stack().peek() != Type.FLOAT){ - constraintViolated(o, "The value at the stack top is not of type 'float', but of type '"+stack().peek()+"'."); - } - } - - /** - * Ensures the specific preconditions of the said instruction. - */ - public void visitF2L(F2L o){ - if (stack().peek() != Type.FLOAT){ - constraintViolated(o, "The value at the stack top is not of type 'float', but of type '"+stack().peek()+"'."); - } - } - - /** - * Ensures the specific preconditions of the said instruction. - */ - public void visitFADD(FADD o){ - if (stack().peek() != Type.FLOAT){ - constraintViolated(o, "The value at the stack top is not of type 'float', but of type '"+stack().peek()+"'."); - } - if (stack().peek(1) != Type.FLOAT){ - constraintViolated(o, "The value at the stack next-to-top is not of type 'float', but of type '"+stack().peek(1)+"'."); - } - } - - /** - * Ensures the specific preconditions of the said instruction. - */ - public void visitFALOAD(FALOAD o){ - indexOfInt(o, stack().peek()); - if (stack().peek(1) == Type.NULL){ - return; - } - if (! (stack().peek(1) instanceof ArrayType)){ - constraintViolated(o, "Stack next-to-top must be of type float[] but is '"+stack().peek(1)+"'."); - } - Type t = ((ArrayType) (stack().peek(1))).getBasicType(); - if (t != Type.FLOAT){ - constraintViolated(o, "Stack next-to-top must be of type float[] but is '"+stack().peek(1)+"'."); - } - } - - /** - * Ensures the specific preconditions of the said instruction. - */ - public void visitFASTORE(FASTORE o){ - if (stack().peek() != Type.FLOAT){ - constraintViolated(o, "The value at the stack top is not of type 'float', but of type '"+stack().peek()+"'."); - } - indexOfInt(o, stack().peek(1)); - if (stack().peek(2) == Type.NULL){ - return; - } - if (! (stack().peek(2) instanceof ArrayType)){ - constraintViolated(o, "Stack next-to-next-to-top must be of type float[] but is '"+stack().peek(2)+"'."); - } - Type t = ((ArrayType) (stack().peek(2))).getBasicType(); - if (t != Type.FLOAT){ - constraintViolated(o, "Stack next-to-next-to-top must be of type float[] but is '"+stack().peek(2)+"'."); - } - } - - /** - * Ensures the specific preconditions of the said instruction. - */ - public void visitFCMPG(FCMPG o){ - if (stack().peek() != Type.FLOAT){ - constraintViolated(o, "The value at the stack top is not of type 'float', but of type '"+stack().peek()+"'."); - } - if (stack().peek(1) != Type.FLOAT){ - constraintViolated(o, "The value at the stack next-to-top is not of type 'float', but of type '"+stack().peek(1)+"'."); - } - } - - /** - * Ensures the specific preconditions of the said instruction. - */ - public void visitFCMPL(FCMPL o){ - if (stack().peek() != Type.FLOAT){ - constraintViolated(o, "The value at the stack top is not of type 'float', but of type '"+stack().peek()+"'."); - } - if (stack().peek(1) != Type.FLOAT){ - constraintViolated(o, "The value at the stack next-to-top is not of type 'float', but of type '"+stack().peek(1)+"'."); - } - } - - /** - * Ensures the specific preconditions of the said instruction. - */ - public void visitFCONST(FCONST o){ - // nothing to do here. - } - - /** - * Ensures the specific preconditions of the said instruction. - */ - public void visitFDIV(FDIV o){ - if (stack().peek() != Type.FLOAT){ - constraintViolated(o, "The value at the stack top is not of type 'float', but of type '"+stack().peek()+"'."); - } - if (stack().peek(1) != Type.FLOAT){ - constraintViolated(o, "The value at the stack next-to-top is not of type 'float', but of type '"+stack().peek(1)+"'."); - } - } - - /** - * Ensures the specific preconditions of the said instruction. - */ - public void visitFLOAD(FLOAD o){ - //visitLoadInstruction(LoadInstruction) is called before. - - // Nothing else needs to be done here. - } - - /** - * Ensures the specific preconditions of the said instruction. - */ - public void visitFMUL(FMUL o){ - if (stack().peek() != Type.FLOAT){ - constraintViolated(o, "The value at the stack top is not of type 'float', but of type '"+stack().peek()+"'."); - } - if (stack().peek(1) != Type.FLOAT){ - constraintViolated(o, "The value at the stack next-to-top is not of type 'float', but of type '"+stack().peek(1)+"'."); - } - } - - /** - * Ensures the specific preconditions of the said instruction. - */ - public void visitFNEG(FNEG o){ - if (stack().peek() != Type.FLOAT){ - constraintViolated(o, "The value at the stack top is not of type 'float', but of type '"+stack().peek()+"'."); - } - } - - /** - * Ensures the specific preconditions of the said instruction. - */ - public void visitFREM(FREM o){ - if (stack().peek() != Type.FLOAT){ - constraintViolated(o, "The value at the stack top is not of type 'float', but of type '"+stack().peek()+"'."); - } - if (stack().peek(1) != Type.FLOAT){ - constraintViolated(o, "The value at the stack next-to-top is not of type 'float', but of type '"+stack().peek(1)+"'."); - } - } - - /** - * Ensures the specific preconditions of the said instruction. - */ - public void visitFRETURN(FRETURN o){ - if (stack().peek() != Type.FLOAT){ - constraintViolated(o, "The value at the stack top is not of type 'float', but of type '"+stack().peek()+"'."); - } - } - - /** - * Ensures the specific preconditions of the said instruction. - */ - public void visitFSTORE(FSTORE o){ - //visitStoreInstruction(StoreInstruction) is called before. - - // Nothing else needs to be done here. - } - - /** - * Ensures the specific preconditions of the said instruction. - */ - public void visitFSUB(FSUB o){ - if (stack().peek() != Type.FLOAT){ - constraintViolated(o, "The value at the stack top is not of type 'float', but of type '"+stack().peek()+"'."); - } - if (stack().peek(1) != Type.FLOAT){ - constraintViolated(o, "The value at the stack next-to-top is not of type 'float', but of type '"+stack().peek(1)+"'."); - } - } - - /** - * Ensures the specific preconditions of the said instruction. - */ - public void visitGETFIELD(GETFIELD o){ - try { - Type objectref = stack().peek(); - if (! ( (objectref instanceof ObjectType) || (objectref == Type.NULL) ) ){ - constraintViolated(o, "Stack top should be an object reference that's not an array reference, but is '"+objectref+"'."); - } - - String field_name = o.getFieldName(cpg); - - JavaClass jc = Repository.lookupClass(o.getClassType(cpg).getClassName()); - Field[] fields = jc.getFields(); - Field f = null; - for (int i=0; i=0; i--){ - Type fromStack = stack().peek( (nargs-1) - i ); // 0 to nargs-1 - Type fromDesc = argtypes[i]; - if (fromDesc == Type.BOOLEAN || - fromDesc == Type.BYTE || - fromDesc == Type.CHAR || - fromDesc == Type.SHORT){ - fromDesc = Type.INT; - } - if (! fromStack.equals(fromDesc)){ - if (fromStack instanceof ReferenceType && fromDesc instanceof ReferenceType){ - ReferenceType rFromStack = (ReferenceType) fromStack; - //ReferenceType rFromDesc = (ReferenceType) fromDesc; - // TODO: This can only be checked when using Staerk-et-al's "set of object types" - // instead of a "wider cast object type" created during verification. - //if ( ! rFromStack.isAssignmentCompatibleWith(rFromDesc) ){ - // constraintViolated(o, "Expecting a '"+fromDesc+"' but found a '"+fromStack+"' on the stack (which is not assignment compatible)."); - //} - referenceTypeIsInitialized(o, rFromStack); - } - else{ - constraintViolated(o, "Expecting a '"+fromDesc+"' but found a '"+fromStack+"' on the stack."); - } - } - } - - Type objref = stack().peek(nargs); - if (objref == Type.NULL){ - return; - } - if (! (objref instanceof ReferenceType) ){ - constraintViolated(o, "Expecting a reference type as 'objectref' on the stack, not a '"+objref+"'."); - } - referenceTypeIsInitialized(o, (ReferenceType) objref); - if (!(objref instanceof ObjectType)){ - if (!(objref instanceof ArrayType)){ - constraintViolated(o, "Expecting an ObjectType as 'objectref' on the stack, not a '"+objref+"'."); // could be a ReturnaddressType - } - else{ - objref = GENERIC_ARRAY; - } - } - - // String objref_classname = ((ObjectType) objref).getClassName(); - // String theInterface = o.getClassName(cpg); - // TODO: This can only be checked if we're using Staerk-et-al's "set of object types" - // instead of "wider cast object types" generated during verification. - //if ( ! Repository.implementationOf(objref_classname, theInterface) ){ - // constraintViolated(o, "The 'objref' item '"+objref+"' does not implement '"+theInterface+"' as expected."); - //} - - int counted_count = 1; // 1 for the objectref - for (int i=0; i=0; i--){ - Type fromStack = stack().peek( (nargs-1) - i ); // 0 to nargs-1 - Type fromDesc = argtypes[i]; - if (fromDesc == Type.BOOLEAN || - fromDesc == Type.BYTE || - fromDesc == Type.CHAR || - fromDesc == Type.SHORT){ - fromDesc = Type.INT; - } - if (! fromStack.equals(fromDesc)){ - if (fromStack instanceof ReferenceType && fromDesc instanceof ReferenceType){ - ReferenceType rFromStack = (ReferenceType) fromStack; - ReferenceType rFromDesc = (ReferenceType) fromDesc; - // TODO: This can only be checked using Staerk-et-al's "set of object types", not - // using a "wider cast object type". - if ( ! rFromStack.isAssignmentCompatibleWith(rFromDesc) ){ - constraintViolated(o, "Expecting a '"+fromDesc+"' but found a '"+fromStack+"' on the stack (which is not assignment compatible)."); - } - referenceTypeIsInitialized(o, rFromStack); - } - else{ - constraintViolated(o, "Expecting a '"+fromDesc+"' but found a '"+fromStack+"' on the stack."); - } - } - } - - Type objref = stack().peek(nargs); - if (objref == Type.NULL){ - return; - } - if (! (objref instanceof ReferenceType) ){ - constraintViolated(o, "Expecting a reference type as 'objectref' on the stack, not a '"+objref+"'."); - } - String objref_classname = null; - if ( !(o.getMethodName(cpg).equals(Constants.CONSTRUCTOR_NAME))){ - referenceTypeIsInitialized(o, (ReferenceType) objref); - if (!(objref instanceof ObjectType)){ - if (!(objref instanceof ArrayType)){ - constraintViolated(o, "Expecting an ObjectType as 'objectref' on the stack, not a '"+objref+"'."); // could be a ReturnaddressType - } - else{ - objref = GENERIC_ARRAY; - } - } - - objref_classname = ((ObjectType) objref).getClassName(); - } - else{ - if (!(objref instanceof UninitializedObjectType)){ - constraintViolated(o, "Expecting an UninitializedObjectType as 'objectref' on the stack, not a '"+objref+"'. Otherwise, you couldn't invoke a method since an array has no methods (not to speak of a return address)."); - } - objref_classname = ((UninitializedObjectType) objref).getInitialized().getClassName(); - } - - - String theClass = o.getClassName(cpg); - if ( ! Repository.instanceOf(objref_classname, theClass) ){ - constraintViolated(o, "The 'objref' item '"+objref+"' does not implement '"+theClass+"' as expected."); - } - - } catch (ClassNotFoundException e) { - // FIXME: maybe not the best way to handle this - throw new AssertionViolatedException("Missing class: " + e.toString()); - } - } - - /** - * Ensures the specific preconditions of the said instruction. - */ - public void visitINVOKESTATIC(INVOKESTATIC o){ - try { - // Method is not native, otherwise pass 3 would not happen. - - Type t = o.getType(cpg); - if (t instanceof ObjectType){ - String name = ((ObjectType)t).getClassName(); - Verifier v = VerifierFactory.getVerifier( name ); - VerificationResult vr = v.doPass2(); - if (vr.getStatus() != VerificationResult.VERIFIED_OK){ - constraintViolated((Instruction) o, "Class '"+name+"' is referenced, but cannot be loaded and resolved: '"+vr+"'."); - } - } - - Type[] argtypes = o.getArgumentTypes(cpg); - int nargs = argtypes.length; - - for (int i=nargs-1; i>=0; i--){ - Type fromStack = stack().peek( (nargs-1) - i ); // 0 to nargs-1 - Type fromDesc = argtypes[i]; - if (fromDesc == Type.BOOLEAN || - fromDesc == Type.BYTE || - fromDesc == Type.CHAR || - fromDesc == Type.SHORT){ - fromDesc = Type.INT; - } - if (! fromStack.equals(fromDesc)){ - if (fromStack instanceof ReferenceType && fromDesc instanceof ReferenceType){ - ReferenceType rFromStack = (ReferenceType) fromStack; - ReferenceType rFromDesc = (ReferenceType) fromDesc; - // TODO: This check can possibly only be done using Staerk-et-al's "set of object types" - // instead of a "wider cast object type" created during verification. - if ( ! rFromStack.isAssignmentCompatibleWith(rFromDesc) ){ - constraintViolated(o, "Expecting a '"+fromDesc+"' but found a '"+fromStack+"' on the stack (which is not assignment compatible)."); - } - referenceTypeIsInitialized(o, rFromStack); - } - else{ - constraintViolated(o, "Expecting a '"+fromDesc+"' but found a '"+fromStack+"' on the stack."); - } - } - } - } catch (ClassNotFoundException e) { - // FIXME: maybe not the best way to handle this - throw new AssertionViolatedException("Missing class: " + e.toString()); - } - } - - /** - * Ensures the specific preconditions of the said instruction. - */ - public void visitINVOKEVIRTUAL(INVOKEVIRTUAL o){ - try { - // the o.getClassType(cpg) type has passed pass 2; see visitLoadClass(o). - - Type t = o.getType(cpg); - if (t instanceof ObjectType){ - String name = ((ObjectType)t).getClassName(); - Verifier v = VerifierFactory.getVerifier( name ); - VerificationResult vr = v.doPass2(); - if (vr.getStatus() != VerificationResult.VERIFIED_OK){ - constraintViolated((Instruction) o, "Class '"+name+"' is referenced, but cannot be loaded and resolved: '"+vr+"'."); - } - } - - - Type[] argtypes = o.getArgumentTypes(cpg); - int nargs = argtypes.length; - - for (int i=nargs-1; i>=0; i--){ - Type fromStack = stack().peek( (nargs-1) - i ); // 0 to nargs-1 - Type fromDesc = argtypes[i]; - if (fromDesc == Type.BOOLEAN || - fromDesc == Type.BYTE || - fromDesc == Type.CHAR || - fromDesc == Type.SHORT){ - fromDesc = Type.INT; - } - if (! fromStack.equals(fromDesc)){ - if (fromStack instanceof ReferenceType && fromDesc instanceof ReferenceType){ - ReferenceType rFromStack = (ReferenceType) fromStack; - ReferenceType rFromDesc = (ReferenceType) fromDesc; - // TODO: This can possibly only be checked when using Staerk-et-al's "set of object types" instead - // of a single "wider cast object type" created during verification. - if ( ! rFromStack.isAssignmentCompatibleWith(rFromDesc) ){ - constraintViolated(o, "Expecting a '"+fromDesc+"' but found a '"+fromStack+"' on the stack (which is not assignment compatible)."); - } - referenceTypeIsInitialized(o, rFromStack); - } - else{ - constraintViolated(o, "Expecting a '"+fromDesc+"' but found a '"+fromStack+"' on the stack."); - } - } - } - - Type objref = stack().peek(nargs); - if (objref == Type.NULL){ - return; - } - if (! (objref instanceof ReferenceType) ){ - constraintViolated(o, "Expecting a reference type as 'objectref' on the stack, not a '"+objref+"'."); - } - referenceTypeIsInitialized(o, (ReferenceType) objref); - if (!(objref instanceof ObjectType)){ - if (!(objref instanceof ArrayType)){ - constraintViolated(o, "Expecting an ObjectType as 'objectref' on the stack, not a '"+objref+"'."); // could be a ReturnaddressType - } - else{ - objref = GENERIC_ARRAY; - } - } - - String objref_classname = ((ObjectType) objref).getClassName(); - - String theClass = o.getClassName(cpg); - - if ( ! Repository.instanceOf(objref_classname, theClass) ){ - constraintViolated(o, "The 'objref' item '"+objref+"' does not implement '"+theClass+"' as expected."); - } - } catch (ClassNotFoundException e) { - // FIXME: maybe not the best way to handle this - throw new AssertionViolatedException("Missing class: " + e.toString()); - } - } - - /** - * Ensures the specific preconditions of the said instruction. - */ - public void visitIOR(IOR o){ - if (stack().peek() != Type.INT){ - constraintViolated(o, "The value at the stack top is not of type 'int', but of type '"+stack().peek()+"'."); - } - if (stack().peek(1) != Type.INT){ - constraintViolated(o, "The value at the stack next-to-top is not of type 'int', but of type '"+stack().peek(1)+"'."); - } - } - - /** - * Ensures the specific preconditions of the said instruction. - */ - public void visitIREM(IREM o){ - if (stack().peek() != Type.INT){ - constraintViolated(o, "The value at the stack top is not of type 'int', but of type '"+stack().peek()+"'."); - } - if (stack().peek(1) != Type.INT){ - constraintViolated(o, "The value at the stack next-to-top is not of type 'int', but of type '"+stack().peek(1)+"'."); - } - } - - /** - * Ensures the specific preconditions of the said instruction. - */ - public void visitIRETURN(IRETURN o){ - if (stack().peek() != Type.INT){ - constraintViolated(o, "The value at the stack top is not of type 'int', but of type '"+stack().peek()+"'."); - } - } - - /** - * Ensures the specific preconditions of the said instruction. - */ - public void visitISHL(ISHL o){ - if (stack().peek() != Type.INT){ - constraintViolated(o, "The value at the stack top is not of type 'int', but of type '"+stack().peek()+"'."); - } - if (stack().peek(1) != Type.INT){ - constraintViolated(o, "The value at the stack next-to-top is not of type 'int', but of type '"+stack().peek(1)+"'."); - } - } - - /** - * Ensures the specific preconditions of the said instruction. - */ - public void visitISHR(ISHR o){ - if (stack().peek() != Type.INT){ - constraintViolated(o, "The value at the stack top is not of type 'int', but of type '"+stack().peek()+"'."); - } - if (stack().peek(1) != Type.INT){ - constraintViolated(o, "The value at the stack next-to-top is not of type 'int', but of type '"+stack().peek(1)+"'."); - } - } - - /** - * Ensures the specific preconditions of the said instruction. - */ - public void visitISTORE(ISTORE o){ - //visitStoreInstruction(StoreInstruction) is called before. - - // Nothing else needs to be done here. - } - - /** - * Ensures the specific preconditions of the said instruction. - */ - public void visitISUB(ISUB o){ - if (stack().peek() != Type.INT){ - constraintViolated(o, "The value at the stack top is not of type 'int', but of type '"+stack().peek()+"'."); - } - if (stack().peek(1) != Type.INT){ - constraintViolated(o, "The value at the stack next-to-top is not of type 'int', but of type '"+stack().peek(1)+"'."); - } - } - - /** - * Ensures the specific preconditions of the said instruction. - */ - public void visitIUSHR(IUSHR o){ - if (stack().peek() != Type.INT){ - constraintViolated(o, "The value at the stack top is not of type 'int', but of type '"+stack().peek()+"'."); - } - if (stack().peek(1) != Type.INT){ - constraintViolated(o, "The value at the stack next-to-top is not of type 'int', but of type '"+stack().peek(1)+"'."); - } - } - - /** - * Ensures the specific preconditions of the said instruction. - */ - public void visitIXOR(IXOR o){ - if (stack().peek() != Type.INT){ - constraintViolated(o, "The value at the stack top is not of type 'int', but of type '"+stack().peek()+"'."); - } - if (stack().peek(1) != Type.INT){ - constraintViolated(o, "The value at the stack next-to-top is not of type 'int', but of type '"+stack().peek(1)+"'."); - } - } - - /** - * Ensures the specific preconditions of the said instruction. - */ - public void visitJSR(JSR o){ - // nothing to do here. - } - - /** - * Ensures the specific preconditions of the said instruction. - */ - public void visitJSR_W(JSR_W o){ - // nothing to do here. - } - - /** - * Ensures the specific preconditions of the said instruction. - */ - public void visitL2D(L2D o){ - if (stack().peek() != Type.LONG){ - constraintViolated(o, "The value at the stack top is not of type 'long', but of type '"+stack().peek()+"'."); - } - } - - /** - * Ensures the specific preconditions of the said instruction. - */ - public void visitL2F(L2F o){ - if (stack().peek() != Type.LONG){ - constraintViolated(o, "The value at the stack top is not of type 'long', but of type '"+stack().peek()+"'."); - } - } - - /** - * Ensures the specific preconditions of the said instruction. - */ - public void visitL2I(L2I o){ - if (stack().peek() != Type.LONG){ - constraintViolated(o, "The value at the stack top is not of type 'long', but of type '"+stack().peek()+"'."); - } - } - - /** - * Ensures the specific preconditions of the said instruction. - */ - public void visitLADD(LADD o){ - if (stack().peek() != Type.LONG){ - constraintViolated(o, "The value at the stack top is not of type 'long', but of type '"+stack().peek()+"'."); - } - if (stack().peek(1) != Type.LONG){ - constraintViolated(o, "The value at the stack next-to-top is not of type 'long', but of type '"+stack().peek(1)+"'."); - } - } - - /** - * Ensures the specific preconditions of the said instruction. - */ - public void visitLALOAD(LALOAD o){ - indexOfInt(o, stack().peek()); - if (stack().peek(1) == Type.NULL){ - return; - } - if (! (stack().peek(1) instanceof ArrayType)){ - constraintViolated(o, "Stack next-to-top must be of type long[] but is '"+stack().peek(1)+"'."); - } - Type t = ((ArrayType) (stack().peek(1))).getBasicType(); - if (t != Type.LONG){ - constraintViolated(o, "Stack next-to-top must be of type long[] but is '"+stack().peek(1)+"'."); - } - } - - /** - * Ensures the specific preconditions of the said instruction. - */ - public void visitLAND(LAND o){ - if (stack().peek() != Type.LONG){ - constraintViolated(o, "The value at the stack top is not of type 'long', but of type '"+stack().peek()+"'."); - } - if (stack().peek(1) != Type.LONG){ - constraintViolated(o, "The value at the stack next-to-top is not of type 'long', but of type '"+stack().peek(1)+"'."); - } - } - - /** - * Ensures the specific preconditions of the said instruction. - */ - public void visitLASTORE(LASTORE o){ - if (stack().peek() != Type.LONG){ - constraintViolated(o, "The value at the stack top is not of type 'long', but of type '"+stack().peek()+"'."); - } - indexOfInt(o, stack().peek(1)); - if (stack().peek(2) == Type.NULL){ - return; - } - if (! (stack().peek(2) instanceof ArrayType)){ - constraintViolated(o, "Stack next-to-next-to-top must be of type long[] but is '"+stack().peek(2)+"'."); - } - Type t = ((ArrayType) (stack().peek(2))).getBasicType(); - if (t != Type.LONG){ - constraintViolated(o, "Stack next-to-next-to-top must be of type long[] but is '"+stack().peek(2)+"'."); - } - } - - /** - * Ensures the specific preconditions of the said instruction. - */ - public void visitLCMP(LCMP o){ - if (stack().peek() != Type.LONG){ - constraintViolated(o, "The value at the stack top is not of type 'long', but of type '"+stack().peek()+"'."); - } - if (stack().peek(1) != Type.LONG){ - constraintViolated(o, "The value at the stack next-to-top is not of type 'long', but of type '"+stack().peek(1)+"'."); - } - } - - /** - * Ensures the specific preconditions of the said instruction. - */ - public void visitLCONST(LCONST o){ - // Nothing to do here. - } - - /** - * Ensures the specific preconditions of the said instruction. - */ - public void visitLDC(LDC o){ - // visitCPInstruction is called first. - - Constant c = cpg.getConstant(o.getIndex()); - if (! ( ( c instanceof ConstantInteger) || - ( c instanceof ConstantFloat ) || - ( c instanceof ConstantString ) ) ){ - constraintViolated(o, "Referenced constant should be a CONSTANT_Integer, a CONSTANT_Float or a CONSTANT_String, but is '"+c+"'."); - } - } - - /** - * Ensures the specific preconditions of the said instruction. - */ - public void visitLDC_W(LDC_W o){ - // visitCPInstruction is called first. - - Constant c = cpg.getConstant(o.getIndex()); - if (! ( ( c instanceof ConstantInteger) || - ( c instanceof ConstantFloat ) || - ( c instanceof ConstantString ) ) ){ - constraintViolated(o, "Referenced constant should be a CONSTANT_Integer, a CONSTANT_Float or a CONSTANT_String, but is '"+c+"'."); - } - } - - /** - * Ensures the specific preconditions of the said instruction. - */ - public void visitLDC2_W(LDC2_W o){ - // visitCPInstruction is called first. - - Constant c = cpg.getConstant(o.getIndex()); - if (! ( ( c instanceof ConstantLong) || - ( c instanceof ConstantDouble ) ) ){ - constraintViolated(o, "Referenced constant should be a CONSTANT_Integer, a CONSTANT_Float or a CONSTANT_String, but is '"+c+"'."); - } - } - - /** - * Ensures the specific preconditions of the said instruction. - */ - public void visitLDIV(LDIV o){ - if (stack().peek() != Type.LONG){ - constraintViolated(o, "The value at the stack top is not of type 'long', but of type '"+stack().peek()+"'."); - } - if (stack().peek(1) != Type.LONG){ - constraintViolated(o, "The value at the stack next-to-top is not of type 'long', but of type '"+stack().peek(1)+"'."); - } - } - - /** - * Ensures the specific preconditions of the said instruction. - */ - public void visitLLOAD(LLOAD o){ - //visitLoadInstruction(LoadInstruction) is called before. - - // Nothing else needs to be done here. - } - - /** - * Ensures the specific preconditions of the said instruction. - */ - public void visitLMUL(LMUL o){ - if (stack().peek() != Type.LONG){ - constraintViolated(o, "The value at the stack top is not of type 'long', but of type '"+stack().peek()+"'."); - } - if (stack().peek(1) != Type.LONG){ - constraintViolated(o, "The value at the stack next-to-top is not of type 'long', but of type '"+stack().peek(1)+"'."); - } - } - - /** - * Ensures the specific preconditions of the said instruction. - */ - public void visitLNEG(LNEG o){ - if (stack().peek() != Type.LONG){ - constraintViolated(o, "The value at the stack top is not of type 'long', but of type '"+stack().peek()+"'."); - } - } - - /** - * Ensures the specific preconditions of the said instruction. - */ - public void visitLOOKUPSWITCH(LOOKUPSWITCH o){ - if (stack().peek() != Type.INT){ - constraintViolated(o, "The value at the stack top is not of type 'int', but of type '"+stack().peek()+"'."); - } - // See also pass 3a. - } - - /** - * Ensures the specific preconditions of the said instruction. - */ - public void visitLOR(LOR o){ - if (stack().peek() != Type.LONG){ - constraintViolated(o, "The value at the stack top is not of type 'long', but of type '"+stack().peek()+"'."); - } - if (stack().peek(1) != Type.LONG){ - constraintViolated(o, "The value at the stack next-to-top is not of type 'long', but of type '"+stack().peek(1)+"'."); - } - } - - /** - * Ensures the specific preconditions of the said instruction. - */ - public void visitLREM(LREM o){ - if (stack().peek() != Type.LONG){ - constraintViolated(o, "The value at the stack top is not of type 'long', but of type '"+stack().peek()+"'."); - } - if (stack().peek(1) != Type.LONG){ - constraintViolated(o, "The value at the stack next-to-top is not of type 'long', but of type '"+stack().peek(1)+"'."); - } - } - - /** - * Ensures the specific preconditions of the said instruction. - */ - public void visitLRETURN(LRETURN o){ - if (stack().peek() != Type.LONG){ - constraintViolated(o, "The value at the stack top is not of type 'long', but of type '"+stack().peek()+"'."); - } - } - - /** - * Ensures the specific preconditions of the said instruction. - */ - public void visitLSHL(LSHL o){ - if (stack().peek() != Type.INT){ - constraintViolated(o, "The value at the stack top is not of type 'int', but of type '"+stack().peek()+"'."); - } - if (stack().peek(1) != Type.LONG){ - constraintViolated(o, "The value at the stack next-to-top is not of type 'long', but of type '"+stack().peek(1)+"'."); - } - } - - /** - * Ensures the specific preconditions of the said instruction. - */ - public void visitLSHR(LSHR o){ - if (stack().peek() != Type.INT){ - constraintViolated(o, "The value at the stack top is not of type 'int', but of type '"+stack().peek()+"'."); - } - if (stack().peek(1) != Type.LONG){ - constraintViolated(o, "The value at the stack next-to-top is not of type 'long', but of type '"+stack().peek(1)+"'."); - } - } - - /** - * Ensures the specific preconditions of the said instruction. - */ - public void visitLSTORE(LSTORE o){ - //visitStoreInstruction(StoreInstruction) is called before. - - // Nothing else needs to be done here. - } - - /** - * Ensures the specific preconditions of the said instruction. - */ - public void visitLSUB(LSUB o){ - if (stack().peek() != Type.LONG){ - constraintViolated(o, "The value at the stack top is not of type 'long', but of type '"+stack().peek()+"'."); - } - if (stack().peek(1) != Type.LONG){ - constraintViolated(o, "The value at the stack next-to-top is not of type 'long', but of type '"+stack().peek(1)+"'."); - } - } - - /** - * Ensures the specific preconditions of the said instruction. - */ - public void visitLUSHR(LUSHR o){ - if (stack().peek() != Type.INT){ - constraintViolated(o, "The value at the stack top is not of type 'int', but of type '"+stack().peek()+"'."); - } - if (stack().peek(1) != Type.LONG){ - constraintViolated(o, "The value at the stack next-to-top is not of type 'long', but of type '"+stack().peek(1)+"'."); - } - } - - /** - * Ensures the specific preconditions of the said instruction. - */ - public void visitLXOR(LXOR o){ - if (stack().peek() != Type.LONG){ - constraintViolated(o, "The value at the stack top is not of type 'long', but of type '"+stack().peek()+"'."); - } - if (stack().peek(1) != Type.LONG){ - constraintViolated(o, "The value at the stack next-to-top is not of type 'long', but of type '"+stack().peek(1)+"'."); - } - } - - /** - * Ensures the specific preconditions of the said instruction. - */ - public void visitMONITORENTER(MONITORENTER o){ - if (! ((stack().peek()) instanceof ReferenceType)){ - constraintViolated(o, "The stack top should be of a ReferenceType, but is '"+stack().peek()+"'."); - } - //referenceTypeIsInitialized(o, (ReferenceType) (stack().peek()) ); - } - - /** - * Ensures the specific preconditions of the said instruction. - */ - public void visitMONITOREXIT(MONITOREXIT o){ - if (! ((stack().peek()) instanceof ReferenceType)){ - constraintViolated(o, "The stack top should be of a ReferenceType, but is '"+stack().peek()+"'."); - } - //referenceTypeIsInitialized(o, (ReferenceType) (stack().peek()) ); - } - - /** - * Ensures the specific preconditions of the said instruction. - */ - public void visitMULTIANEWARRAY(MULTIANEWARRAY o){ - int dimensions = o.getDimensions(); - // Dimensions argument is okay: see Pass 3a. - for (int i=0; i, see Pass 3a. - - } catch (ClassNotFoundException e) { - // FIXME: maybe not the best way to handle this - throw new AssertionViolatedException("Missing class: " + e.toString()); - } - } - - /** - * Ensures the specific preconditions of the said instruction. - */ - public void visitRET(RET o){ - if (! (locals().get(o.getIndex()) instanceof ReturnaddressType)){ - constraintViolated(o, "Expecting a ReturnaddressType in local variable "+o.getIndex()+"."); - } - if (locals().get(o.getIndex()) == ReturnaddressType.NO_TARGET){ - throw new AssertionViolatedException("Oops: RET expecting a target!"); - } - // Other constraints such as non-allowed overlapping subroutines are enforced - // while building the Subroutines data structure. - } - - /** - * Ensures the specific preconditions of the said instruction. - */ - public void visitRETURN(RETURN o){ - if (mg.getName().equals(Constants.CONSTRUCTOR_NAME)){// If we leave an method - if ((Frame._this != null) && (!(mg.getClassName().equals(Type.OBJECT.getClassName()))) ) { - constraintViolated(o, "Leaving a constructor that itself did not call a constructor."); - } - } - } - - /** - * Ensures the specific preconditions of the said instruction. - */ - public void visitSALOAD(SALOAD o){ - indexOfInt(o, stack().peek()); - if (stack().peek(1) == Type.NULL){ - return; - } - if (! (stack().peek(1) instanceof ArrayType)){ - constraintViolated(o, "Stack next-to-top must be of type short[] but is '"+stack().peek(1)+"'."); - } - Type t = ((ArrayType) (stack().peek(1))).getBasicType(); - if (t != Type.SHORT){ - constraintViolated(o, "Stack next-to-top must be of type short[] but is '"+stack().peek(1)+"'."); - } - } - - /** - * Ensures the specific preconditions of the said instruction. - */ - public void visitSASTORE(SASTORE o){ - if (stack().peek() != Type.INT){ - constraintViolated(o, "The value at the stack top is not of type 'int', but of type '"+stack().peek()+"'."); - } - indexOfInt(o, stack().peek(1)); - if (stack().peek(2) == Type.NULL){ - return; - } - if (! (stack().peek(2) instanceof ArrayType)){ - constraintViolated(o, "Stack next-to-next-to-top must be of type short[] but is '"+stack().peek(2)+"'."); - } - Type t = ((ArrayType) (stack().peek(2))).getBasicType(); - if (t != Type.SHORT){ - constraintViolated(o, "Stack next-to-next-to-top must be of type short[] but is '"+stack().peek(2)+"'."); - } - } - - /** - * Ensures the specific preconditions of the said instruction. - */ - public void visitSIPUSH(SIPUSH o){ - // nothing to do here. Generic visitXXX() methods did the trick before. - } - - /** - * Ensures the specific preconditions of the said instruction. - */ - public void visitSWAP(SWAP o){ - if (stack().peek().getSize() != 1){ - constraintViolated(o, "The value at the stack top is not of size '1', but of size '"+stack().peek().getSize()+"'."); - } - if (stack().peek(1).getSize() != 1){ - constraintViolated(o, "The value at the stack next-to-top is not of size '1', but of size '"+stack().peek(1).getSize()+"'."); - } - } - - /** - * Ensures the specific preconditions of the said instruction. - */ - public void visitTABLESWITCH(TABLESWITCH o){ - indexOfInt(o, stack().peek()); - // See Pass 3a. - } - -} - diff --git a/src/org/apache/bcel/verifier/structurals/InstructionContext.java b/src/org/apache/bcel/verifier/structurals/InstructionContext.java deleted file mode 100644 index cc04e98..0000000 --- a/src/org/apache/bcel/verifier/structurals/InstructionContext.java +++ /dev/null @@ -1,105 +0,0 @@ -/* - * Copyright 2000-2004 The Apache Software Foundation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ -package org.apache.bcel.verifier.structurals; - - -import java.util.ArrayList; -import org.apache.bcel.generic.InstructionHandle; - -/** - * An InstructionContext offers convenient access - * to information like control flow successors and - * such. - * - * @version $Id: InstructionContext.java 382272 2006-03-02 03:31:46Z tcurdt $ - * @author Enver Haase - */ -public interface InstructionContext{ - - /** - * The getTag and setTag methods may be used for - * temporary flagging, such as graph colouring. - * Nothing in the InstructionContext object depends - * on the value of the tag. JustIce does not use it. - * - * @see #setTag(int tag) - */ - public int getTag(); - - /** - * The getTag and setTag methods may be used for - * temporary flagging, such as graph colouring. - * Nothing in the InstructionContext object depends - * on the value of the tag. JustIce does not use it. - * - * @see #getTag() - */ - public void setTag(int tag); - - /** - * This method symbolically executes the Instruction - * held in the InstructionContext. - * It "merges in" the incoming execution frame situation - * (see The Java Virtual Machine Specification, 2nd - * edition, page 146). - * By so doing, the outgoing execution frame situation - * is calculated. - * - * This method is JustIce-specific and is usually of - * no sense for users of the ControlFlowGraph class. - * They should use getInstruction().accept(Visitor), - * possibly in conjunction with the ExecutionVisitor. - * - * - * @see ControlFlowGraph - * @see ExecutionVisitor - * @see #getOutFrame(ArrayList) - * @return true - if and only if the "outgoing" frame situation - * changed from the one before execute()ing. - */ - boolean execute(Frame inFrame, ArrayList executionPredecessors, InstConstraintVisitor icv, ExecutionVisitor ev); - - Frame getInFrame(); - - /** - * This method returns the outgoing execution frame situation; - * therefore it has to be calculated by execute(Frame, ArrayList) - * first. - * - * @see #execute(Frame, ArrayList, InstConstraintVisitor, ExecutionVisitor) - */ - Frame getOutFrame(ArrayList executionPredecessors); - - /** - * Returns the InstructionHandle this InstructionContext is wrapped around. - * - * @return The InstructionHandle this InstructionContext is wrapped around. - */ - InstructionHandle getInstruction(); - - /** - * Returns the usual control flow successors. - * @see #getExceptionHandlers() - */ - InstructionContext[] getSuccessors(); - - /** - * Returns the exception handlers that protect this instruction. - * They are special control flow successors. - */ - ExceptionHandler[] getExceptionHandlers(); -} diff --git a/src/org/apache/bcel/verifier/structurals/LocalVariables.java b/src/org/apache/bcel/verifier/structurals/LocalVariables.java deleted file mode 100644 index 0ee13f4..0000000 --- a/src/org/apache/bcel/verifier/structurals/LocalVariables.java +++ /dev/null @@ -1,209 +0,0 @@ -/* - * Copyright 2000-2004 The Apache Software Foundation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ -package org.apache.bcel.verifier.structurals; - - -import org.apache.bcel.generic.ReferenceType; -import org.apache.bcel.generic.Type; -import org.apache.bcel.verifier.exc.AssertionViolatedException; -import org.apache.bcel.verifier.exc.StructuralCodeConstraintException; - -/** - * This class implements an array of local variables used for symbolic JVM - * simulation. - * - * @version $Id: LocalVariables.java 386056 2006-03-15 11:31:56Z tcurdt $ - * @author Enver Haase - */ -public class LocalVariables{ - /** The Type[] containing the local variable slots. */ - private Type[] locals; - - /** - * Creates a new LocalVariables object. - */ - public LocalVariables(int maxLocals){ - locals = new Type[maxLocals]; - for (int i=0; i= maxStack){ - throw new AssertionViolatedException("OperandStack too small, should have thrown proper Exception elsewhere. Stack: "+this); - } - stack.add(type); - } - - /** - * Returns the size of this OperandStack; that means, how many Type objects there are. - */ - public int size(){ - return stack.size(); - } - - /** - * Returns the number of stack slots used. - * @see #maxStack() - */ - public int slotsUsed(){ - /* XXX change this to a better implementation using a variable - that keeps track of the actual slotsUsed()-value monitoring - all push()es and pop()s. - */ - int slots = 0; - for (int i=0; i no Instruction was executed before - // => Top-Level routine (no jsr call before) - icq.add(start, new ArrayList()); - - // LOOP! - while (!icq.isEmpty()){ - InstructionContext u; - ArrayList ec; - if (!DEBUG){ - int r = random.nextInt(icq.size()); - u = icq.getIC(r); - ec = icq.getEC(r); - icq.remove(r); - } - else{ - u = icq.getIC(0); - ec = icq.getEC(0); - icq.remove(0); - } - - ArrayList oldchain = (ArrayList) (ec.clone()); - ArrayList newchain = (ArrayList) (ec.clone()); - newchain.add(u); - - if ((u.getInstruction().getInstruction()) instanceof RET){ -//System.err.println(u); - // We can only follow _one_ successor, the one after the - // JSR that was recently executed. - RET ret = (RET) (u.getInstruction().getInstruction()); - ReturnaddressType t = (ReturnaddressType) u.getOutFrame(oldchain).getLocals().get(ret.getIndex()); - InstructionContext theSuccessor = cfg.contextOf(t.getTarget()); - - // Sanity check - InstructionContext lastJSR = null; - int skip_jsr = 0; - for (int ss=oldchain.size()-1; ss >= 0; ss--){ - if (skip_jsr < 0){ - throw new AssertionViolatedException("More RET than JSR in execution chain?!"); - } -//System.err.println("+"+oldchain.get(ss)); - if (((InstructionContext) oldchain.get(ss)).getInstruction().getInstruction() instanceof JsrInstruction){ - if (skip_jsr == 0){ - lastJSR = (InstructionContext) oldchain.get(ss); - break; - } - else{ - skip_jsr--; - } - } - if (((InstructionContext) oldchain.get(ss)).getInstruction().getInstruction() instanceof RET){ - skip_jsr++; - } - } - if (lastJSR == null){ - throw new AssertionViolatedException("RET without a JSR before in ExecutionChain?! EC: '"+oldchain+"'."); - } - JsrInstruction jsr = (JsrInstruction) (lastJSR.getInstruction().getInstruction()); - if ( theSuccessor != (cfg.contextOf(jsr.physicalSuccessor())) ){ - throw new AssertionViolatedException("RET '"+u.getInstruction()+"' info inconsistent: jump back to '"+theSuccessor+"' or '"+cfg.contextOf(jsr.physicalSuccessor())+"'?"); - } - - if (theSuccessor.execute(u.getOutFrame(oldchain), newchain, icv, ev)){ - icq.add(theSuccessor, (ArrayList) newchain.clone()); - } - } - else{// "not a ret" - - // Normal successors. Add them to the queue of successors. - InstructionContext[] succs = u.getSuccessors(); - for (int s=0; sMust not be invoked on the 'top-level subroutine'. - */ - public InstructionHandle[] getEnteringJsrInstructions(); - - /** - * Returns the one and only RET that leaves the subroutine. - * Note that JustIce has a pretty rigid notion of a subroutine. - * Must not be invoked on the 'top-level subroutine'. - * - * @see org.apache.bcel.verifier.structurals.Subroutines - */ - public InstructionHandle getLeavingRET(); - - /** - * Returns all instructions that together form this subroutine. - * Note that an instruction is part of exactly one subroutine - * (the top-level code is considered to be a special subroutine) - - * else it is not reachable at all (dead code). - */ - public InstructionHandle[] getInstructions(); - - /** - * Returns if the given InstructionHandle refers to an instruction - * that is part of this subroutine. This is a convenience method - * that saves iteration over the InstructionHandle objects returned - * by getInstructions(). - * - * @see #getInstructions() - */ - public boolean contains(InstructionHandle inst); - - /** - * Returns an int[] containing the indices of the local variable slots - * accessed by this Subroutine (read-accessed, write-accessed or both); - * local variables referenced by subroutines of this subroutine are - * not included. - * - * @see #getRecursivelyAccessedLocalsIndices() - */ - public int[] getAccessedLocalsIndices(); - - /** - * Returns an int[] containing the indices of the local variable slots - * accessed by this Subroutine (read-accessed, write-accessed or both); - * local variables referenced by subroutines of this subroutine are - * included. - * - * @see #getAccessedLocalsIndices() - */ - public int[] getRecursivelyAccessedLocalsIndices(); - - /** - * Returns the subroutines that are directly called from this subroutine. - */ - public Subroutine[] subSubs(); -} diff --git a/src/org/apache/bcel/verifier/structurals/Subroutines.java b/src/org/apache/bcel/verifier/structurals/Subroutines.java deleted file mode 100644 index bed934b..0000000 --- a/src/org/apache/bcel/verifier/structurals/Subroutines.java +++ /dev/null @@ -1,651 +0,0 @@ -/* - * Copyright 2000-2004 The Apache Software Foundation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ -package org.apache.bcel.verifier.structurals; - -import java.util.ArrayList; -import java.util.HashSet; -import java.util.Hashtable; -import java.util.Iterator; -import java.util.Set; -import org.apache.bcel.generic.ASTORE; -import org.apache.bcel.generic.ATHROW; -import org.apache.bcel.generic.BranchInstruction; -import org.apache.bcel.generic.CodeExceptionGen; -import org.apache.bcel.generic.GotoInstruction; -import org.apache.bcel.generic.IndexedInstruction; -import org.apache.bcel.generic.Instruction; -import org.apache.bcel.generic.InstructionHandle; -import org.apache.bcel.generic.JsrInstruction; -import org.apache.bcel.generic.LocalVariableInstruction; -import org.apache.bcel.generic.MethodGen; -import org.apache.bcel.generic.RET; -import org.apache.bcel.generic.ReturnInstruction; -import org.apache.bcel.generic.Select; -import org.apache.bcel.verifier.exc.AssertionViolatedException; -import org.apache.bcel.verifier.exc.StructuralCodeConstraintException; - - /** - * Instances of this class contain information about the subroutines - * found in a code array of a method. - * This implementation considers the top-level (the instructions - * reachable without a JSR or JSR_W starting off from the first - * instruction in a code array of a method) being a special subroutine; - * see getTopLevel() for that. - * Please note that the definition of subroutines in the Java Virtual - * Machine Specification, Second Edition is somewhat incomplete. - * Therefore, JustIce uses an own, more rigid notion. - * Basically, a subroutine is a piece of code that starts at the target - * of a JSR of JSR_W instruction and ends at a corresponding RET - * instruction. Note also that the control flow of a subroutine - * may be complex and non-linear; and that subroutines may be nested. - * JustIce also mandates subroutines not to be protected by exception - * handling code (for the sake of control flow predictability). - * To understand JustIce's notion of subroutines, please read - * - * TODO: refer to the paper. - * - * @version $Id: Subroutines.java 386056 2006-03-15 11:31:56Z tcurdt $ - * @author Enver Haase - * @see #getTopLevel() - */ -public class Subroutines{ - /** - * This inner class implements the Subroutine interface. - */ - private class SubroutineImpl implements Subroutine{ - /** - * UNSET, a symbol for an uninitialized localVariable - * field. This is used for the "top-level" Subroutine; - * i.e. no subroutine. - */ - private static final int UNSET = -1; - - /** - * The Local Variable slot where the first - * instruction of this subroutine (an ASTORE) stores - * the JsrInstruction's ReturnAddress in and - * the RET of this subroutine operates on. - */ - private int localVariable = UNSET; - - /** The instructions that belong to this subroutine. */ - private Set instructions = new HashSet(); // Elements: InstructionHandle - - /* - * Refer to the Subroutine interface for documentation. - */ - public boolean contains(InstructionHandle inst){ - return instructions.contains(inst); - } - - /** - * The JSR or JSR_W instructions that define this - * subroutine by targeting it. - */ - private Set theJSRs = new HashSet(); - - /** - * The RET instruction that leaves this subroutine. - */ - private InstructionHandle theRET; - - /** - * Returns a String representation of this object, merely - * for debugging purposes. - * (Internal) Warning: Verbosity on a problematic subroutine may cause - * stack overflow errors due to recursive subSubs() calls. - * Don't use this, then. - */ - public String toString(){ - String ret = "Subroutine: Local variable is '"+localVariable+"', JSRs are '"+theJSRs+"', RET is '"+theRET+"', Instructions: '"+instructions.toString()+"'."; - - ret += " Accessed local variable slots: '"; - int[] alv = getAccessedLocalsIndices(); - for (int i=0; inot a - * subroutine, the top-level, is also modeled as a Subroutine - * object. - * It is a special Subroutine object where you must not invoke - * getEnteringJsrInstructions() or getLeavingRET(). - * - * @see Subroutine#getEnteringJsrInstructions() - * @see Subroutine#getLeavingRET() - */ - public Subroutine getTopLevel(){ - return TOPLEVEL; - } - /** - * A utility method that calculates the successors of a given InstructionHandle - * in the same subroutine. That means, a RET does not have any successors - * as defined here. A JsrInstruction has its physical successor as its successor - * (opposed to its target) as defined here. - */ - private static InstructionHandle[] getSuccessors(InstructionHandle instruction){ - final InstructionHandle[] empty = new InstructionHandle[0]; - final InstructionHandle[] single = new InstructionHandle[1]; - final InstructionHandle[] pair = new InstructionHandle[2]; - - Instruction inst = instruction.getInstruction(); - - if (inst instanceof RET){ - return empty; - } - - // Terminates method normally. - if (inst instanceof ReturnInstruction){ - return empty; - } - - // Terminates method abnormally, because JustIce mandates - // subroutines not to be protected by exception handlers. - if (inst instanceof ATHROW){ - return empty; - } - - // See method comment. - if (inst instanceof JsrInstruction){ - single[0] = instruction.getNext(); - return single; - } - - if (inst instanceof GotoInstruction){ - single[0] = ((GotoInstruction) inst).getTarget(); - return single; - } - - if (inst instanceof BranchInstruction){ - if (inst instanceof Select){ - // BCEL's getTargets() returns only the non-default targets, - // thanks to Eli Tilevich for reporting. - InstructionHandle[] matchTargets = ((Select) inst).getTargets(); - InstructionHandle[] ret = new InstructionHandle[matchTargets.length+1]; - ret[0] = ((Select) inst).getTarget(); - System.arraycopy(matchTargets, 0, ret, 1, matchTargets.length); - return ret; - } - else{ - pair[0] = instruction.getNext(); - pair[1] = ((BranchInstruction) inst).getTarget(); - return pair; - } - } - - // default case: Fall through. - single[0] = instruction.getNext(); - return single; - } - - /** - * Returns a String representation of this object; merely for debugging puposes. - */ - public String toString(){ - return "---\n"+subroutines.toString()+"\n---\n"; - } -} diff --git a/src/org/apache/bcel/verifier/structurals/UninitializedObjectType.java b/src/org/apache/bcel/verifier/structurals/UninitializedObjectType.java deleted file mode 100644 index cedffc2..0000000 --- a/src/org/apache/bcel/verifier/structurals/UninitializedObjectType.java +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright 2000-2004 The Apache Software Foundation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ -package org.apache.bcel.verifier.structurals; - - -import org.apache.bcel.Constants; -import org.apache.bcel.generic.ObjectType; -import org.apache.bcel.generic.ReferenceType; - -/** - * This class represents an uninitialized object type; see The Java - * Virtual Machine Specification, Second Edition, page 147: 4.9.4 for - * more details. - * - * @version $Id: UninitializedObjectType.java 386056 2006-03-15 11:31:56Z tcurdt $ - * @author Enver Haase - */ -public class UninitializedObjectType extends ReferenceType implements Constants{ - - /** The "initialized" version. */ - private ObjectType initialized; - - /** Creates a new instance. */ - public UninitializedObjectType(ObjectType t){ - super(T_UNKNOWN, ""); - initialized = t; - } - - /** - * Returns the ObjectType of the same class as the one of the uninitialized object - * represented by this UninitializedObjectType instance. - */ - public ObjectType getInitialized(){ - return initialized; - } - - /** @return a hash code value for the object. - */ - public int hashCode() { return initialized.hashCode(); } - - /** - * Returns true on equality of this and o. - * Equality means the ObjectType instances of "initialized" - * equal one another in this and the o instance. - * - */ - public boolean equals(Object o){ - if (! (o instanceof UninitializedObjectType)) { - return false; - } - return initialized.equals(((UninitializedObjectType)o).initialized); - } -} diff --git a/src/org/apache/bcel/verifier/structurals/package.html b/src/org/apache/bcel/verifier/structurals/package.html deleted file mode 100644 index 2d8ff4b..0000000 --- a/src/org/apache/bcel/verifier/structurals/package.html +++ /dev/null @@ -1,20 +0,0 @@ - - - - - - - -Provides a PassVerifier class mostly used internally by JustIce, yielding a control flow graph for public use as -a nice side effect. - -

Package Specification

- -Contained in this package is a PassVerifier class for use with the JustIce verifier and its utility classes. -Only the pass performing what Sun calls "Structural Constraints on Java Virtual Machine Code" -has a PassVerifier class here. JustIce calls this pass "Pass 3b". - - -