aboutsummaryrefslogtreecommitdiff
path: root/libjava/verify.cc
diff options
context:
space:
mode:
authortromey <tromey@138bc75d-0d04-0410-961f-82ee72b054a4>2003-05-07 01:25:20 +0000
committertromey <tromey@138bc75d-0d04-0410-961f-82ee72b054a4>2003-05-07 01:25:20 +0000
commitf2910627ba7c49d2d61ba9ad2186456399ee5c90 (patch)
tree79f8ed7537cf8b90533d2148673b927b93b9a1f0 /libjava/verify.cc
parent0352af729e54036feb6032a8ac0d4c604110d51b (diff)
* verify.cc: Reverted previous patch.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@66548 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'libjava/verify.cc')
-rw-r--r--libjava/verify.cc62
1 files changed, 60 insertions, 2 deletions
diff --git a/libjava/verify.cc b/libjava/verify.cc
index 3aacc273ae2..4a6ca458849 100644
--- a/libjava/verify.cc
+++ b/libjava/verify.cc
@@ -240,6 +240,64 @@ private:
return get_type_val_for_signature ((jchar) k->method_count);
}
+ // This is like _Jv_IsAssignableFrom, but it works even if SOURCE or
+ // TARGET haven't been prepared.
+ static bool is_assignable_from_slow (jclass target, jclass source)
+ {
+ // This will terminate when SOURCE==Object.
+ while (true)
+ {
+ if (source == target)
+ return true;
+
+ if (target->isPrimitive () || source->isPrimitive ())
+ return false;
+
+ if (target->isArray ())
+ {
+ if (! source->isArray ())
+ return false;
+ target = target->getComponentType ();
+ source = source->getComponentType ();
+ }
+ else if (target->isInterface ())
+ {
+ for (int i = 0; i < source->interface_count; ++i)
+ {
+ // We use a recursive call because we also need to
+ // check superinterfaces.
+ if (is_assignable_from_slow (target, source->interfaces[i]))
+ return true;
+ }
+ source = source->getSuperclass ();
+ if (source == NULL)
+ return false;
+ }
+ // We must do this check before we check to see if SOURCE is
+ // an interface. This way we know that any interface is
+ // assignable to an Object.
+ else if (target == &java::lang::Object::class$)
+ return true;
+ else if (source->isInterface ())
+ {
+ for (int i = 0; i < target->interface_count; ++i)
+ {
+ // We use a recursive call because we also need to
+ // check superinterfaces.
+ if (is_assignable_from_slow (target->interfaces[i], source))
+ return true;
+ }
+ target = target->getSuperclass ();
+ if (target == NULL)
+ return false;
+ }
+ else if (source == &java::lang::Object::class$)
+ return false;
+ else
+ source = source->getSuperclass ();
+ }
+ }
+
// This is used to keep track of which `jsr's correspond to a given
// jsr target.
struct subr_info
@@ -462,7 +520,7 @@ private:
// We must resolve both types and check assignability.
resolve (verifier);
k.resolve (verifier);
- return _Jv_IsAssignableFrom (data.klass, k.data.klass);
+ return is_assignable_from_slow (data.klass, k.data.klass);
}
bool isvoid () const
@@ -649,7 +707,7 @@ private:
// Ordinarily this terminates when we hit Object...
while (k != NULL)
{
- if (_Jv_IsAssignableFrom (k, oldk))
+ if (is_assignable_from_slow (k, oldk))
break;
k = k->getSuperclass ();
changed = true;