You are viewing a plain text version of this content. The canonical link for it is here.
Posted to bcel-dev@jakarta.apache.org by en...@apache.org on 2002/08/02 13:57:51 UTC

cvs commit: jakarta-bcel/src/java/org/apache/bcel/verifier/structurals LocalVariables.java OperandStack.java

enver       2002/08/02 04:57:51

  Modified:    src/java/org/apache/bcel/generic ReferenceType.java
               src/java/org/apache/bcel/verifier/structurals
                        LocalVariables.java OperandStack.java
  Log:
  I was convinced I should not break API even with the
  slightest changes.
  - Made firstCommonSuperclass(ReferenceType) behave like yesterday,
    but deprecated.
  - Created a new method getFirstCommonSuperclass(ReferenceType) with
    needed changes.
  - Reformatted some comments.
  
  Revision  Changes    Path
  1.4       +82 -13    jakarta-bcel/src/java/org/apache/bcel/generic/ReferenceType.java
  
  Index: ReferenceType.java
  ===================================================================
  RCS file: /home/cvs/jakarta-bcel/src/java/org/apache/bcel/generic/ReferenceType.java,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- ReferenceType.java	1 Aug 2002 22:43:40 -0000	1.3
  +++ ReferenceType.java	2 Aug 2002 11:57:51 -0000	1.4
  @@ -87,9 +87,10 @@
           if (this.equals(Type.NULL))
               return true;		// If this is ever changed in isAssignmentCompatible()
   
  -        return isAssignmentCompatibleWith(t); /* Yes, it's true: It's the same definition.
  -                         * See vmspec2 AASTORE / CHECKCAST definitions.
  -                         */
  +        return isAssignmentCompatibleWith(t);
  +        /* Yes, it's true: It's the same definition.
  +         * See vmspec2 AASTORE / CHECKCAST definitions.
  +         */
       }
   
       /**
  @@ -140,8 +141,8 @@
               }
   
               /* If T is an interface type, then T must be the same interface
  -               as this or a superinterface of this (�2.13.2).
  -            */
  +             * as this or a superinterface of this (�2.13.2).
  +             */
               if ((T instanceof ObjectType) && (((ObjectType) T).referencesInterface())) {
                   if (this.equals(T)) return true;
                   if (Repository.implementationOf(((ObjectType) this).getClassName(),
  @@ -151,8 +152,8 @@
           }
   
           /* If this is an array type, namely, the type SC[], that is, an
  -           array of components of type SC, then:
  -        */
  +         * array of components of type SC, then:
  +         */
           if (this instanceof ArrayType) {
               /* If T is a class type, then T must be Object (�2.4.7).
                */
  @@ -161,8 +162,8 @@
               }
   
               /* If T is an array type TC[], that is, an array of components
  -               of type TC, then one of the following must be true:
  -            */
  +             * of type TC, then one of the following must be true:
  +             */
               if (T instanceof ArrayType) {
                   /* TC and SC are the same primitive type (�2.4.1).
                    */
  @@ -173,7 +174,8 @@
                       return true;
   
                   /* TC and SC are reference types (�2.4.6), and type SC is
  -                       assignable to TC by these runtime rules.*/
  +                 * assignable to TC by these runtime rules.
  +                 */
                   if (tc instanceof ReferenceType && sc instanceof ReferenceType &&
                           ((ReferenceType) sc).isAssignmentCompatibleWith((ReferenceType) tc))
                       return true;
  @@ -209,7 +211,7 @@
        * If not all of the two classes' superclasses cannot be found, "null" is returned.
        * See the JVM specification edition 2, "�4.9.2 The Bytecode Verifier".
        */
  -    public ReferenceType firstCommonSuperclass(ReferenceType t) {
  +    public ReferenceType getFirstCommonSuperclass(ReferenceType t) {
           if (this.equals(Type.NULL)) return t;
           if (t.equals(Type.NULL)) return this;
           if (this.equals(t)) return this;
  @@ -231,12 +233,79 @@
                       arrType1.getBasicType() instanceof ObjectType &&
                       arrType2.getBasicType() instanceof ObjectType) {
                   return new ArrayType(
  -                        ((ObjectType) arrType1.getBasicType()).firstCommonSuperclass((ObjectType) arrType2.getBasicType()),
  +                        ((ObjectType) arrType1.getBasicType()).getFirstCommonSuperclass((ObjectType) arrType2.getBasicType()),
                           arrType1.getDimensions()
                   );
   
               }
           }
  +
  +        if ((this instanceof ArrayType) || (t instanceof ArrayType))
  +            return Type.OBJECT;
  +        // TODO: Is there a proof of OBJECT being the direct ancestor of every ArrayType?
  +
  +        if (((this instanceof ObjectType) && ((ObjectType) this).referencesInterface()) ||
  +                ((t instanceof ObjectType) && ((ObjectType) t).referencesInterface()))
  +            return Type.OBJECT;
  +        // TODO: The above line is correct comparing to the vmspec2. But one could
  +        // make class file verification a bit stronger here by using the notion of
  +        // superinterfaces or even castability or assignment compatibility.
  +
  +
  +        // this and t are ObjectTypes, see above.
  +        ObjectType thiz = (ObjectType) this;
  +        ObjectType other = (ObjectType) t;
  +        JavaClass[] thiz_sups = Repository.getSuperClasses(thiz.getClassName());
  +        JavaClass[] other_sups = Repository.getSuperClasses(other.getClassName());
  +
  +        if ((thiz_sups == null) || (other_sups == null)) {
  +            return null;
  +        }
  +
  +        // Waaahh...
  +        JavaClass[] this_sups = new JavaClass[thiz_sups.length + 1];
  +        JavaClass[] t_sups = new JavaClass[other_sups.length + 1];
  +        System.arraycopy(thiz_sups, 0, this_sups, 1, thiz_sups.length);
  +        System.arraycopy(other_sups, 0, t_sups, 1, other_sups.length);
  +        this_sups[0] = Repository.lookupClass(thiz.getClassName());
  +        t_sups[0] = Repository.lookupClass(other.getClassName());
  +
  +        for (int i = 0; i < t_sups.length; i++) {
  +            for (int j = 0; j < this_sups.length; j++) {
  +                if (this_sups[j].equals(t_sups[i])) return new ObjectType(this_sups[j].getClassName());
  +            }
  +        }
  +
  +        // Huh? Did you ask for Type.OBJECT's superclass??
  +        return null;
  +    }
  +
  +   /**
  +     * This commutative operation returns the first common superclass (narrowest ReferenceType
  +     * referencing a class, not an interface).
  +     * If one of the types is a superclass of the other, the former is returned.
  +     * If "this" is Type.NULL, then t is returned.
  +     * If t is Type.NULL, then "this" is returned.
  +     * If "this" equals t ['this.equals(t)'] "this" is returned.
  +     * If "this" or t is an ArrayType, then Type.OBJECT is returned.
  +     * If "this" or t is a ReferenceType referencing an interface, then Type.OBJECT is returned.
  +     * If not all of the two classes' superclasses cannot be found, "null" is returned.
  +     * See the JVM specification edition 2, "�4.9.2 The Bytecode Verifier".
  +     *
  +     * @deprecated use getFirstCommonSuperclass(ReferenceType t) which has
  +     *             slightly changed semantics.
  +     */
  +    public ReferenceType firstCommonSuperclass(ReferenceType t) {
  +        if (this.equals(Type.NULL)) return t;
  +        if (t.equals(Type.NULL)) return this;
  +        if (this.equals(t)) return this;
  +        /*
  +         * TODO: Above sounds a little arbitrary. On the other hand, there is
  +         * no object referenced by Type.NULL so we can also say all the objects
  +         * referenced by Type.NULL were derived from java.lang.Object.
  +         * However, the Java Language's "instanceof" operator proves us wrong:
  +         * "null" is not referring to an instance of java.lang.Object :)
  +         */
   
           if ((this instanceof ArrayType) || (t instanceof ArrayType))
               return Type.OBJECT;
  
  
  
  1.2       +2 -2      jakarta-bcel/src/java/org/apache/bcel/verifier/structurals/LocalVariables.java
  
  Index: LocalVariables.java
  ===================================================================
  RCS file: /home/cvs/jakarta-bcel/src/java/org/apache/bcel/verifier/structurals/LocalVariables.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- LocalVariables.java	29 Oct 2001 20:00:41 -0000	1.1
  +++ LocalVariables.java	2 Aug 2002 11:57:51 -0000	1.2
  @@ -180,7 +180,7 @@
   		}
   		if ((locals[i] instanceof ReferenceType) && (lv.locals[i] instanceof ReferenceType)){
   			if (! locals[i].equals(lv.locals[i])){ // needed in case of two UninitializedObjectType instances
  -				Type sup = ((ReferenceType) locals[i]).firstCommonSuperclass((ReferenceType) (lv.locals[i]));
  +				Type sup = ((ReferenceType) locals[i]).getFirstCommonSuperclass((ReferenceType) (lv.locals[i]));
   
   				if (sup != null){
   					locals[i] = sup;
  
  
  
  1.2       +2 -2      jakarta-bcel/src/java/org/apache/bcel/verifier/structurals/OperandStack.java
  
  Index: OperandStack.java
  ===================================================================
  RCS file: /home/cvs/jakarta-bcel/src/java/org/apache/bcel/verifier/structurals/OperandStack.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- OperandStack.java	29 Oct 2001 20:00:41 -0000	1.1
  +++ OperandStack.java	2 Aug 2002 11:57:51 -0000	1.2
  @@ -251,7 +251,7 @@
   			if (! stack.get(i).equals(s.stack.get(i))){
   				if (	(stack.get(i) instanceof ReferenceType) &&
   							(s.stack.get(i) instanceof ReferenceType)  ){
  -					stack.set(i, ((ReferenceType) stack.get(i)).firstCommonSuperclass((ReferenceType) (s.stack.get(i))));
  +					stack.set(i, ((ReferenceType) stack.get(i)).getFirstCommonSuperclass((ReferenceType) (s.stack.get(i))));
   				}
   				else{
   					throw new StructuralCodeConstraintException("Cannot merge stacks of different types:\nStack A:\n"+this+"\nStack B:\n"+s);
  
  
  

--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>