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>