natClassLoader.cc (defineClass0): Removed erroneous comment.
* java/lang/natClassLoader.cc (defineClass0): Removed erroneous comment. * java/lang/ClassLoader.java (defineClass): Use chained exception when rethrowing. * defineclass.cc (handleClassBegin): Mark class as interpreted. * java/lang/reflect/Modifier.java (INVISIBLE, INTERPRETED): New constants. * resolve.cc (_Jv_PrepareMissingMethods): New function. (_Jv_PrepareClass): Use it. * include/java-interp.h (_Jv_IsInterpretedClass): Rewrote. (_Jv_InterpClass): _Jv_PrepareMissingMethods now friend. * java/lang/Class.h (Class::getModifiers): Mask with ALL_FLAGS. (Class): _Jv_PrepareMissingMethods now friend. * java/lang/natClassLoader.cc (defineClass0): Use JvSynchronize. Record `NULL' for system class loader. (_Jv_RegisterInitiatingLoader): Use JvSynchronize. Special case system class loader. (_Jv_FindClassInCache): Likewise. (_Jv_UnregisterClass): Use JvSynchronize. Free old loader info. (_Jv_FindClass): Special case system class loader. * java/lang/natClass.cc (_Jv_abstractMethodError): New function. (_Jv_SetVTableEntries): Put _Jv_abstractMethodError into empty vtable slots. (_Jv_LayoutVTableMethods): Don't generate vtable slot for a method in a final class. (_getDeclaredMethod): Don't return synthetic methods. (getDeclaredMethods): Likewise. (_getMethod): Likewise. (_getMethods): Likewise. From-SVN: r60319
This commit is contained in:
parent
385405940e
commit
a1aba4f9a5
11 changed files with 221 additions and 96 deletions
|
@ -238,7 +238,7 @@ _Jv_ResolvePoolEntry (jclass klass, int index)
|
|||
|
||||
// First search the class itself.
|
||||
the_method = _Jv_SearchMethodInClass (owner, klass,
|
||||
method_name, method_signature);
|
||||
method_name, method_signature);
|
||||
|
||||
if (the_method != 0)
|
||||
{
|
||||
|
@ -246,9 +246,10 @@ _Jv_ResolvePoolEntry (jclass klass, int index)
|
|||
goto end_of_method_search;
|
||||
}
|
||||
|
||||
// If we are resolving an interface method, search the interface's
|
||||
// superinterfaces (A superinterface is not an interface's superclass -
|
||||
// a superinterface is implemented by the interface).
|
||||
// If we are resolving an interface method, search the
|
||||
// interface's superinterfaces (A superinterface is not an
|
||||
// interface's superclass - a superinterface is implemented by
|
||||
// the interface).
|
||||
if (pool->tags[index] == JV_CONSTANT_InterfaceMethodref)
|
||||
{
|
||||
_Jv_ifaces ifaces;
|
||||
|
@ -257,8 +258,8 @@ _Jv_ResolvePoolEntry (jclass klass, int index)
|
|||
ifaces.list = (jclass *) _Jv_Malloc (ifaces.len * sizeof (jclass *));
|
||||
|
||||
_Jv_GetInterfaces (owner, &ifaces);
|
||||
|
||||
for (int i=0; i < ifaces.count; i++)
|
||||
|
||||
for (int i = 0; i < ifaces.count; i++)
|
||||
{
|
||||
jclass cls = ifaces.list[i];
|
||||
the_method = _Jv_SearchMethodInClass (cls, klass, method_name,
|
||||
|
@ -269,9 +270,9 @@ _Jv_ResolvePoolEntry (jclass klass, int index)
|
|||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
_Jv_Free (ifaces.list);
|
||||
|
||||
|
||||
if (the_method != 0)
|
||||
goto end_of_method_search;
|
||||
}
|
||||
|
@ -281,7 +282,7 @@ _Jv_ResolvePoolEntry (jclass klass, int index)
|
|||
cls = cls->getSuperclass ())
|
||||
{
|
||||
the_method = _Jv_SearchMethodInClass (cls, klass,
|
||||
method_name, method_signature);
|
||||
method_name, method_signature);
|
||||
if (the_method != 0)
|
||||
{
|
||||
found_class = cls;
|
||||
|
@ -363,6 +364,58 @@ _Jv_SearchMethodInClass (jclass cls, jclass klass,
|
|||
return 0;
|
||||
}
|
||||
|
||||
// A helper for _Jv_PrepareClass. This adds missing `Miranda methods'
|
||||
// to a class.
|
||||
void
|
||||
_Jv_PrepareMissingMethods (jclass base2, jclass iface_class)
|
||||
{
|
||||
_Jv_InterpClass *base = reinterpret_cast<_Jv_InterpClass *> (base2);
|
||||
for (int i = 0; i < iface_class->interface_count; ++i)
|
||||
{
|
||||
for (int j = 0; j < iface_class->interfaces[i]->method_count; ++j)
|
||||
{
|
||||
_Jv_Method *meth = &iface_class->interfaces[i]->methods[j];
|
||||
// Don't bother with <clinit>.
|
||||
if (meth->name->data[0] == '<')
|
||||
continue;
|
||||
_Jv_Method *new_meth = _Jv_LookupDeclaredMethod (base, meth->name,
|
||||
meth->signature);
|
||||
if (! new_meth)
|
||||
{
|
||||
// We assume that such methods are very unlikely, so we
|
||||
// just reallocate the method array each time one is
|
||||
// found. This greatly simplifies the searching --
|
||||
// otherwise we have to make sure that each such method
|
||||
// found is really unique among all superinterfaces.
|
||||
int new_count = base->method_count + 1;
|
||||
_Jv_Method *new_m
|
||||
= (_Jv_Method *) _Jv_AllocBytes (sizeof (_Jv_Method)
|
||||
* new_count);
|
||||
memcpy (new_m, base->methods,
|
||||
sizeof (_Jv_Method) * base->method_count);
|
||||
|
||||
// Add new method.
|
||||
new_m[base->method_count] = *meth;
|
||||
new_m[base->method_count].index = (_Jv_ushort) -1;
|
||||
new_m[base->method_count].accflags
|
||||
|= java::lang::reflect::Modifier::INVISIBLE;
|
||||
|
||||
_Jv_MethodBase **new_im
|
||||
= (_Jv_MethodBase **) _Jv_AllocBytes (sizeof (_Jv_MethodBase *)
|
||||
* new_count);
|
||||
memcpy (new_im, base->interpreted_methods,
|
||||
sizeof (_Jv_MethodBase *) * base->method_count);
|
||||
|
||||
base->methods = new_m;
|
||||
base->interpreted_methods = new_im;
|
||||
base->method_count = new_count;
|
||||
}
|
||||
}
|
||||
|
||||
_Jv_PrepareMissingMethods (base, iface_class->interfaces[i]);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
_Jv_PrepareClass(jclass klass)
|
||||
{
|
||||
|
@ -516,13 +569,24 @@ _Jv_PrepareClass(jclass klass)
|
|||
}
|
||||
}
|
||||
|
||||
if (clz->accflags & Modifier::INTERFACE)
|
||||
if ((clz->accflags & Modifier::INTERFACE))
|
||||
{
|
||||
clz->state = JV_STATE_PREPARED;
|
||||
clz->notifyAll ();
|
||||
return;
|
||||
}
|
||||
|
||||
// A class might have so-called "Miranda methods". This is a method
|
||||
// that is declared in an interface and not re-declared in an
|
||||
// abstract class. Some compilers don't emit declarations for such
|
||||
// methods in the class; this will give us problems since we expect
|
||||
// a declaration for any method requiring a vtable entry. We handle
|
||||
// this here by searching for such methods and constructing new
|
||||
// internal declarations for them. We only need to do this for
|
||||
// abstract classes.
|
||||
if ((clz->accflags & Modifier::ABSTRACT))
|
||||
_Jv_PrepareMissingMethods (clz, clz);
|
||||
|
||||
clz->vtable_method_count = -1;
|
||||
_Jv_MakeVTable (clz);
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue