Commit 06b021af by Tom Tromey Committed by Tom Tromey

re PR libgcj/10582 (array assignment fails in some situations)

	PR libgcj/10582:
	* verify.cc (_Jv_BytecodeVerifier::is_assignable_from_slow):
	Removed.
	(type::compatible): Use _Jv_IsAssignableFrom.
	* java/lang/natClass.cc (iindex_mutex_initialized): Now static.
	(_Jv_IsAssignableFrom): Work even when source or target class is
	not prepared.

From-SVN: r66348
parent c93139b8
2003-04-30 Tom Tromey <tromey@redhat.com>
PR libgcj/10582:
* verify.cc (_Jv_BytecodeVerifier::is_assignable_from_slow):
Removed.
(type::compatible): Use _Jv_IsAssignableFrom.
* java/lang/natClass.cc (iindex_mutex_initialized): Now static.
(_Jv_IsAssignableFrom): Work even when source or target class is
not prepared.
2003-04-30 Michael Koch <konqueror@gmx.de> 2003-04-30 Michael Koch <konqueror@gmx.de>
* java/text/BreakIterator.java * java/text/BreakIterator.java
......
...@@ -981,14 +981,14 @@ _Jv_IsAssignableFrom (jclass target, jclass source) ...@@ -981,14 +981,14 @@ _Jv_IsAssignableFrom (jclass target, jclass source)
{ {
if (source == target) if (source == target)
return true; return true;
// If target is array, so must source be. // If target is array, so must source be.
if (target->isArray ()) while (target->isArray ())
{ {
if (! source->isArray()) if (! source->isArray())
return false; return false;
return _Jv_IsAssignableFrom(target->getComponentType(), target = target->getComponentType();
source->getComponentType()); source = source->getComponentType();
} }
if (target->isInterface()) if (target->isInterface())
...@@ -998,7 +998,7 @@ _Jv_IsAssignableFrom (jclass target, jclass source) ...@@ -998,7 +998,7 @@ _Jv_IsAssignableFrom (jclass target, jclass source)
if (__builtin_expect if (__builtin_expect
(source->idt == NULL || source->isInterface(), false)) (source->idt == NULL || source->isInterface(), false))
return _Jv_InterfaceAssignableFrom (target, source); return _Jv_InterfaceAssignableFrom (target, source);
_Jv_IDispatchTable *cl_idt = source->idt; _Jv_IDispatchTable *cl_idt = source->idt;
_Jv_IDispatchTable *if_idt = target->idt; _Jv_IDispatchTable *if_idt = target->idt;
...@@ -1014,23 +1014,31 @@ _Jv_IsAssignableFrom (jclass target, jclass source) ...@@ -1014,23 +1014,31 @@ _Jv_IsAssignableFrom (jclass target, jclass source)
} }
return false; return false;
} }
// Primitive TYPE classes are only assignable to themselves. // Primitive TYPE classes are only assignable to themselves.
if (__builtin_expect (target->isPrimitive(), false)) if (__builtin_expect (target->isPrimitive() || source->isPrimitive(), false))
return false; return false;
if (target == &java::lang::Object::class$) if (target == &java::lang::Object::class$)
return true;
else if (source->ancestors == NULL || target->ancestors == NULL)
{ {
if (source->isPrimitive()) // We need this case when either SOURCE or TARGET has not has
return false; // its constant-time tables prepared.
return true;
// At this point we know that TARGET can't be Object, so it is
// safe to use that as the termination point.
while (source && source != &java::lang::Object::class$)
{
if (source == target)
return true;
source = source->getSuperclass();
}
} }
else if (source->ancestors != NULL else if (source->depth >= target->depth
&& target->ancestors != NULL
&& source->depth >= target->depth
&& source->ancestors[source->depth - target->depth] == target) && source->ancestors[source->depth - target->depth] == target)
return true; return true;
return false; return false;
} }
...@@ -1373,7 +1381,7 @@ _Jv_AppendPartialITable (jclass klass, jclass iface, void **itable, ...@@ -1373,7 +1381,7 @@ _Jv_AppendPartialITable (jclass klass, jclass iface, void **itable,
} }
static _Jv_Mutex_t iindex_mutex; static _Jv_Mutex_t iindex_mutex;
bool iindex_mutex_initialized = false; static bool iindex_mutex_initialized = false;
// We need to find the correct offset in the Class Interface Dispatch // We need to find the correct offset in the Class Interface Dispatch
// Table for a given interface. Once we have that, invoking an interface // Table for a given interface. Once we have that, invoking an interface
......
...@@ -240,64 +240,6 @@ private: ...@@ -240,64 +240,6 @@ private:
return get_type_val_for_signature ((jchar) k->method_count); 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 // This is used to keep track of which `jsr's correspond to a given
// jsr target. // jsr target.
struct subr_info struct subr_info
...@@ -520,7 +462,7 @@ private: ...@@ -520,7 +462,7 @@ private:
// We must resolve both types and check assignability. // We must resolve both types and check assignability.
resolve (verifier); resolve (verifier);
k.resolve (verifier); k.resolve (verifier);
return is_assignable_from_slow (data.klass, k.data.klass); return _Jv_IsAssignableFrom (data.klass, k.data.klass);
} }
bool isvoid () const bool isvoid () const
...@@ -707,7 +649,7 @@ private: ...@@ -707,7 +649,7 @@ private:
// Ordinarily this terminates when we hit Object... // Ordinarily this terminates when we hit Object...
while (k != NULL) while (k != NULL)
{ {
if (is_assignable_from_slow (k, oldk)) if (_Jv_IsAssignableFrom (k, oldk))
break; break;
k = k->getSuperclass (); k = k->getSuperclass ();
changed = true; changed = true;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment