aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--libjava/ChangeLog16
-rw-r--r--libjava/defineclass.cc40
-rw-r--r--libjava/include/java-interp.h3
-rw-r--r--libjava/java/lang/natClassLoader.cc10
-rw-r--r--libjava/java/lang/natVMClassLoader.cc6
5 files changed, 53 insertions, 22 deletions
diff --git a/libjava/ChangeLog b/libjava/ChangeLog
index 51820665d2a..fca7044704c 100644
--- a/libjava/ChangeLog
+++ b/libjava/ChangeLog
@@ -1,5 +1,21 @@
2005-06-24 Tom Tromey <tromey@redhat.com>
+ * java/lang/natClassLoader.cc (_Jv_UnregisterClass): Handle case
+ where class' name is NULL.
+ (_Jv_FindClass): Don't wait for class state.
+ * java/lang/natVMClassLoader.cc (defineClass): Only unregister if
+ name found.
+ * include/java-interp.h (_Jv_DefineClass): Updated.
+ * defineclass.cc (_Jv_DefineClass): Added 'name_result' argument.
+ (struct _Jv_ClassReader): Likewise.
+ (found_name): New field.
+ (handleClassBegin): Set *found_name.
+ (_Jv_VerifyMethodSignature): Handle case where ptr==NULL.
+ (handleClassBegin): Throw error if super class not set.
+ (read_methods): Correctly call check_tag and prepare_pool_entry.
+
+2005-06-24 Tom Tromey <tromey@redhat.com>
+
* boehm.cc (_Jv_MarkObj): Handle case where field's type is NULL.
2005-06-24 Tom Tromey <tromey@redhat.com>
diff --git a/libjava/defineclass.cc b/libjava/defineclass.cc
index 7564957dc43..e0e209cbfd2 100644
--- a/libjava/defineclass.cc
+++ b/libjava/defineclass.cc
@@ -70,7 +70,8 @@ static void throw_class_circularity_error (jstring msg)
* public or private members here.
*/
-struct _Jv_ClassReader {
+struct _Jv_ClassReader
+{
// do verification? Currently, there is no option to disable this.
// This flag just controls the verificaiton done by the class loader;
@@ -104,6 +105,9 @@ struct _Jv_ClassReader {
// the classes associated interpreter data.
_Jv_InterpClass *def_interp;
+ // The name we found.
+ _Jv_Utf8Const **found_name;
+
/* check that the given number of input bytes are available */
inline void check (int num)
{
@@ -219,7 +223,8 @@ struct _Jv_ClassReader {
}
_Jv_ClassReader (jclass klass, jbyteArray data, jint offset, jint length,
- java::security::ProtectionDomain *pd)
+ java::security::ProtectionDomain *pd,
+ _Jv_Utf8Const **name_result)
{
if (klass == 0 || length < 0 || offset+length > data->length)
throw_internal_error ("arguments to _Jv_DefineClass");
@@ -229,6 +234,7 @@ struct _Jv_ClassReader {
len = length;
pos = 0;
def = klass;
+ found_name = name_result;
def->size_in_bytes = -1;
def->vtable_method_count = -1;
@@ -279,11 +285,15 @@ struct _Jv_ClassReader {
*/
};
+// Note that *NAME_RESULT will only be set if the class is registered
+// with the class loader. This is how the caller can know whether
+// unregistration is require.
void
_Jv_DefineClass (jclass klass, jbyteArray data, jint offset, jint length,
- java::security::ProtectionDomain *pd)
+ java::security::ProtectionDomain *pd,
+ _Jv_Utf8Const **name_result)
{
- _Jv_ClassReader reader (klass, data, offset, length, pd);
+ _Jv_ClassReader reader (klass, data, offset, length, pd, name_result);
reader.parse();
/* that's it! */
@@ -499,9 +509,9 @@ void _Jv_ClassReader::read_methods ()
int attributes_count = read2u ();
check_tag (name_index, JV_CONSTANT_Utf8);
- prepare_pool_entry (descriptor_index, JV_CONSTANT_Utf8);
+ prepare_pool_entry (name_index, JV_CONSTANT_Utf8);
- check_tag (name_index, JV_CONSTANT_Utf8);
+ check_tag (descriptor_index, JV_CONSTANT_Utf8);
prepare_pool_entry (descriptor_index, JV_CONSTANT_Utf8);
handleMethod (i, access_flags, name_index,
@@ -930,11 +940,11 @@ _Jv_ClassReader::handleClassBegin (int access_flags, int this_class, int super_c
pool_data[this_class].clazz = def;
pool_tags[this_class] = JV_CONSTANT_ResolvedClass;
- if (super_class == 0 && ! (access_flags & Modifier::INTERFACE))
+ if (super_class == 0)
{
- // FIXME: Consider this carefully!
- if (! _Jv_equalUtf8Consts (def->name, java::lang::Object::class$.name))
- throw_no_class_def_found_error ("loading java.lang.Object");
+ // Note that this is ok if we are defining java.lang.Object.
+ // But there is no way to have this class be interpreted.
+ throw_class_format_error ("no superclass reference");
}
def->state = JV_STATE_PRELOADING;
@@ -946,6 +956,11 @@ _Jv_ClassReader::handleClassBegin (int access_flags, int this_class, int super_c
// lock here, as our caller has acquired it.
_Jv_RegisterInitiatingLoader (def, def->loader);
+ // Note that we found a name so that unregistration can happen if
+ // needed.
+ *found_name = def->name;
+
+ jclass the_super = NULL;
if (super_class != 0)
{
// Load the superclass.
@@ -953,8 +968,7 @@ _Jv_ClassReader::handleClassBegin (int access_flags, int this_class, int super_c
_Jv_Utf8Const* super_name = pool_data[super_class].utf8;
// Load the superclass using our defining loader.
- jclass the_super = _Jv_FindClass (super_name,
- def->loader);
+ jclass the_super = _Jv_FindClass (super_name, def->loader);
// This will establish that we are allowed to be a subclass,
// and check for class circularity error.
@@ -1547,7 +1561,7 @@ _Jv_VerifyMethodSignature (_Jv_Utf8Const*sig)
while (ptr && UTF8_PEEK (ptr, limit) != ')')
ptr = _Jv_VerifyOne (ptr, limit, false);
- if (UTF8_GET (ptr, limit) != ')')
+ if (! ptr || UTF8_GET (ptr, limit) != ')')
return false;
// get the return type
diff --git a/libjava/include/java-interp.h b/libjava/include/java-interp.h
index 061520013d7..5155557c769 100644
--- a/libjava/include/java-interp.h
+++ b/libjava/include/java-interp.h
@@ -36,7 +36,8 @@ struct _Jv_ResolvedMethod;
void _Jv_InitInterpreter ();
void _Jv_DefineClass (jclass, jbyteArray, jint, jint,
- java::security::ProtectionDomain *);
+ java::security::ProtectionDomain *,
+ _Jv_Utf8Const **);
void _Jv_InitField (jobject, jclass, int);
void * _Jv_AllocMethodInvocation (jsize size);
diff --git a/libjava/java/lang/natClassLoader.cc b/libjava/java/lang/natClassLoader.cc
index fb3515b5a78..43016bf5e63 100644
--- a/libjava/java/lang/natClassLoader.cc
+++ b/libjava/java/lang/natClassLoader.cc
@@ -107,6 +107,10 @@ _Jv_FindClassInCache (_Jv_Utf8Const *name)
void
_Jv_UnregisterClass (jclass the_class)
{
+ // This can happen if the class could not be defined properly.
+ if (! the_class->name)
+ return;
+
JvSynchronize sync (&java::lang::Class::class$);
jint hash = HASH_UTF(the_class->name);
@@ -328,12 +332,6 @@ _Jv_FindClass (_Jv_Utf8Const *name, java::lang::ClassLoader *loader)
}
}
}
- else
- {
- // We need classes to be in the hash while we're loading, so
- // that they can refer to themselves.
- _Jv_Linker::wait_for_state (klass, JV_STATE_LOADED);
- }
return klass;
}
diff --git a/libjava/java/lang/natVMClassLoader.cc b/libjava/java/lang/natVMClassLoader.cc
index 2e7b90da789..bffbfc067db 100644
--- a/libjava/java/lang/natVMClassLoader.cc
+++ b/libjava/java/lang/natVMClassLoader.cc
@@ -71,16 +71,18 @@ java::lang::VMClassLoader::defineClass (java::lang::ClassLoader *loader,
klass->name = name2;
}
+ _Jv_Utf8Const *found_name = NULL;
try
{
- _Jv_DefineClass (klass, data, offset, length, pd);
+ _Jv_DefineClass (klass, data, offset, length, pd, &found_name);
}
catch (java::lang::Throwable *ex)
{
klass->state = JV_STATE_ERROR;
klass->notifyAll ();
- _Jv_UnregisterInitiatingLoader (klass, klass->loader);
+ if (found_name != NULL)
+ _Jv_UnregisterInitiatingLoader (klass, klass->loader);
// If EX is not a ClassNotFoundException, that's ok, because we
// account for the possibility in defineClass().