First, when constructing a new object, it is the PC of the
`new' instruction which created the object. We use the special
- value UNINIT to mean that this is uninitialized, and the
- special value SELF for the case where the current method is
- itself the <init> method.
-
+ value UNINIT to mean that this is uninitialized. The special
+ value SELF is used for the case where the current method is
+ itself the <init> method. the special value EITHER is used
+ when we may optionally allow either an uninitialized or
+ initialized reference to match.
+
Second, when the key is return_address_type, this holds the PC
of the instruction following the `jsr'. */
int pc;
- #define UNINIT -2
- #define SELF -1
+#define UNINIT -2
+#define SELF -1
+#define EITHER -3
};
#if 0
if (k->klass == NULL)
verify_fail ("programmer error in type::compatible");
- /* An initialized type and an uninitialized type are not
- compatible. */
- if (type_initialized (t) != type_initialized (k))
- return false;
-
- /* Two uninitialized objects are compatible if either:
- * The PCs are identical, or
- * One PC is UNINIT. */
- if (type_initialized (t))
+ /* Handle the special 'EITHER' case, which is only used in a
+ special case of 'putfield'. Note that we only need to handle
+ this on the LHS of a check. */
+ if (! type_initialized (t) && t->pc == EITHER)
{
- if (t->pc != k->pc && t->pc != UNINIT && k->pc != UNINIT)
+ /* If the RHS is uninitialized, it must be an uninitialized
+ 'this'. */
+ if (! type_initialized (k) && k->pc != SELF)
return false;
}
+ else if (type_initialized (t) != type_initialized (k))
+ {
+ /* An initialized type and an uninitialized type are not
+ otherwise compatible. */
+ return false;
+ }
+ else
+ {
+ /* Two uninitialized objects are compatible if either:
+ * The PCs are identical, or
+ * One PC is UNINIT. */
+ if (type_initialized (t))
+ {
+ if (t->pc != k->pc && t->pc != UNINIT && k->pc != UNINIT)
+ return false;
+ }
+ }
return ref_compatible (t->klass, k->klass);
}
&& vfr->current_state->this_type.pc == SELF
&& types_equal (&vfr->current_state->this_type, &ct)
&& vfy_class_has_field (vfr->current_class, name, field_type))
- type_set_uninitialized (class_type, SELF);
+ /* Note that we don't actually know whether we're going to match
+ against 'this' or some other object of the same type. So,
+ here we set things up so that it doesn't matter. This relies
+ on knowing what our caller is up to. */
+ type_set_uninitialized (class_type, EITHER);
return t;
}