natClassLoader.cc (_Jv_UnregisterClass): Handle case where class' name is NULL.
authorTom Tromey <tromey@redhat.com>
Fri, 24 Jun 2005 22:48:33 +0000 (22:48 +0000)
committerTom Tromey <tromey@gcc.gnu.org>
Fri, 24 Jun 2005 22:48:33 +0000 (22:48 +0000)
* 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.

From-SVN: r101301

libjava/ChangeLog
libjava/defineclass.cc
libjava/include/java-interp.h
libjava/java/lang/natClassLoader.cc
libjava/java/lang/natVMClassLoader.cc

index 51820665d2a982aacdd91443d18561f5317a3ea8..fca7044704c7bfabb39ea4515545fb85961e3969 100644 (file)
@@ -1,3 +1,19 @@
+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.
index 7564957dc43740acacdc2463092940f3345007fb..e0e209cbfd22585f80dfa9af495f137b6e7a517a 100644 (file)
@@ -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
index 061520013d7097c29993cc8bb5f6382df38ff0db..5155557c769b5173f9994808c06a29c9dcc9454b 100644 (file)
@@ -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);
index fb3515b5a78914b12715b99cadf70c933c890f9e..43016bf5e63e6b6ef0020cd34a63672bef4c4cb2 100644 (file)
@@ -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;
 }
index 2e7b90da78911d835f31a65cac26f04cbb8bb5c9..bffbfc067db139ae955904241d21d9115ff1f794 100644 (file)
@@ -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().