From f6b733ed1f3be3a7a4648bacd62fab0dfcb1f191 Mon Sep 17 00:00:00 2001 From: Tom Tromey Date: Fri, 16 Nov 2001 19:59:16 +0000 Subject: [PATCH] verify.cc (_Jv_BytecodeVerifier::is_assignable_from_slow): New method. * verify.cc (_Jv_BytecodeVerifier::is_assignable_from_slow): New method. (type::compatible): Use it. (type::merge): Likewise. (type::promote): Return a `type&'. (get_one_type): Promote return value. From-SVN: r47097 --- libjava/ChangeLog | 7 ++++++ libjava/verify.cc | 64 ++++++++++++++++++++++++++++++++++++++++++++++++------- 2 files changed, 63 insertions(+), 8 deletions(-) diff --git a/libjava/ChangeLog b/libjava/ChangeLog index 31373d6..2d7835b 100644 --- a/libjava/ChangeLog +++ b/libjava/ChangeLog @@ -1,5 +1,12 @@ 2001-11-16 Tom Tromey + * verify.cc (_Jv_BytecodeVerifier::is_assignable_from_slow): New + method. + (type::compatible): Use it. + (type::merge): Likewise. + (type::promote): Return a `type&'. + (get_one_type): Promote return value. + Re-merge with Classpath, from Brian Jones: * java/lang/Integer.java (getInteger): Attempt to decode the value of the system property instead of the name of the system property. diff --git a/libjava/verify.cc b/libjava/verify.cc index 2691ed3..5dc90c6 100644 --- a/libjava/verify.cc +++ b/libjava/verify.cc @@ -168,6 +168,53 @@ 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; + + // _Jv_IsAssignableFrom can handle a target which is an + // interface even if it hasn't been prepared. + if ((target->state > JV_STATE_LINKED || target->isInterface ()) + && source->state > JV_STATE_LINKED) + return _Jv_IsAssignableFrom (target, source); + + 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; + } + return false; + } + else if (target == &java::lang::Object::class$) + return true; + else if (source->isInterface () + || 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 @@ -274,11 +321,12 @@ private: } // Promote a numeric type. - void promote () + type &promote () { if (key == boolean_type || key == char_type || key == byte_type || key == short_type) key = int_type; + return *this; } // If *THIS is an unresolved reference type, resolve it. @@ -373,9 +421,7 @@ private: // We must resolve both types and check assignability. resolve (); k.resolve (); - // Use _Jv_IsAssignableFrom to avoid premature class - // initialization. - return _Jv_IsAssignableFrom (data.klass, k.data.klass); + return is_assignable_from_slow (data.klass, k.data.klass); } bool isvoid () const @@ -539,9 +585,7 @@ private: // This loop will end when we hit Object. while (true) { - // Use _Jv_IsAssignableFrom to avoid premature - // class initialization. - if (_Jv_IsAssignableFrom (k, oldk)) + if (is_assignable_from_slow (k, oldk)) break; k = k->getSuperclass (); changed = true; @@ -1543,7 +1587,11 @@ private: type_val rt = get_type_val_for_signature (jchar (v)); if (arraycount == 0) - return type (rt); + { + // Callers of this function eventually push their arguments on + // the stack. So, promote them here. + return type (rt).promote (); + } jclass k = construct_primitive_array_type (rt); while (--arraycount > 0) -- 2.7.4