OSDN Git Service

* ChangeLog.2, ChangeLog.3, ChangeLog.4, FSFChangeLog.10,
[pf3gnuchains/gcc-fork.git] / libjava / defineclass.cc
index 962b835..85f6ce3 100644 (file)
@@ -1,6 +1,6 @@
 // defineclass.cc - defining a class from .class format.
 
-/* Copyright (C) 1999, 2000  Free Software Foundation
+/* Copyright (C) 1999, 2000, 2001  Free Software Foundation
 
    This file is part of libgcj.
 
@@ -41,12 +41,9 @@ details.  */
 #include <java/lang/IncompatibleClassChangeError.h>
 #include <java/lang/reflect/Modifier.h>
 
-// we don't verify method names that match these.
-static _Jv_Utf8Const *clinit_name = _Jv_makeUtf8Const ("<clinit>", 8);
-static _Jv_Utf8Const *init_name = _Jv_makeUtf8Const ("<init>", 6);
+using namespace gcj;
 
-
-// these go in some seperate functions, to avoid having _Jv_InitClass
+// these go in some separate functions, to avoid having _Jv_InitClass
 // inserted all over the place.
 static void throw_internal_error (char *msg)
        __attribute__ ((__noreturn__));
@@ -360,8 +357,8 @@ _Jv_ClassReader::parse ()
 
 void _Jv_ClassReader::read_constpool ()
 {
-  tags    = (unsigned char*) _Jv_AllocBytesChecked (pool_count);
-  offsets = (unsigned int *) _Jv_AllocBytesChecked (sizeof (int)
+  tags    = (unsigned char*) _Jv_AllocBytes (pool_count);
+  offsets = (unsigned int *) _Jv_AllocBytes (sizeof (int)
                                                    * pool_count) ;
 
   /** first, we scan the constant pool, collecting tags and offsets */
@@ -526,10 +523,42 @@ void _Jv_ClassReader::read_one_method_attribute (int method_index)
 
   if (is_attribute_name (name, "Exceptions"))
     {
-      /* we ignore this for now */
-      skip (length);
+      _Jv_Method *method = reinterpret_cast<_Jv_Method *>
+       (&def->methods[method_index]);
+      if (method->throws != NULL)
+       throw_class_format_error ("only one Exceptions attribute allowed per method");
+
+      int num_exceptions = read2u ();
+      // We use malloc here because the GC won't scan the method
+      // objects.  FIXME this means a memory leak if we GC a class.
+      // (Currently we never do.)
+      _Jv_Utf8Const **exceptions =
+       (_Jv_Utf8Const **) _Jv_Malloc ((num_exceptions + 1) * sizeof (_Jv_Utf8Const *));
+
+      int out = 0;
+      _Jv_word *pool_data = def->constants.data;
+      for (int i = 0; i < num_exceptions; ++i)
+       {
+         try
+           {
+             int ndx = read2u ();
+             // JLS 2nd Ed. 4.7.5 requires that the tag not be 0.
+             if (ndx != 0)
+               {
+                 check_tag (ndx, JV_CONSTANT_Class);
+                 exceptions[out++] = pool_data[ndx].utf8; 
+               }
+           }
+         catch (java::lang::Throwable *exc)
+           {
+             _Jv_Free (exceptions);
+             throw exc;
+           }
+       }
+      exceptions[out] = NULL;
+      method->throws = exceptions;
     }
-  
+
   else if (is_attribute_name (name, "Code"))
     {
       int start_off = pos;
@@ -625,9 +654,9 @@ void _Jv_ClassReader::handleConstantPool ()
   /** now, we actually define the class' constant pool */
 
   // the pool is scanned explicitly by the collector
-  jbyte *pool_tags = (jbyte*) _Jv_AllocBytesChecked (pool_count);
+  jbyte *pool_tags = (jbyte*) _Jv_AllocBytes (pool_count);
   _Jv_word *pool_data
-    = (_Jv_word*) _Jv_AllocBytesChecked (pool_count * sizeof (_Jv_word));
+    = (_Jv_word*) _Jv_AllocBytes (pool_count * sizeof (_Jv_word));
   
   def->constants.tags = pool_tags;
   def->constants.data = pool_data;
@@ -902,7 +931,11 @@ _Jv_ClassReader::handleClassBegin
   // to include references to this class.
 
   def->state = JV_STATE_PRELOADING;
-  _Jv_RegisterClass (def);
+
+  {
+    JvSynchronize sync (&java::lang::Class::class$);
+    _Jv_RegisterClass (def);
+  }
 
   if (super_class != 0)
     {
@@ -965,7 +998,7 @@ _Jv_ClassReader::checkExtends (jclass sub, jclass super)
 
 void _Jv_ClassReader::handleInterfacesBegin (int count)
 {
-  def->interfaces = (jclass*) _Jv_AllocBytesChecked (count*sizeof (jclass));
+  def->interfaces = (jclass*) _Jv_AllocBytes (count*sizeof (jclass));
   def->interface_count = count;
 }
 
@@ -1032,10 +1065,10 @@ _Jv_ClassReader::checkImplements (jclass sub, jclass super)
 void _Jv_ClassReader::handleFieldsBegin (int count)
 {
   def->fields = (_Jv_Field*) 
-    _Jv_AllocBytesChecked (count * sizeof (_Jv_Field));
+    _Jv_AllocBytes (count * sizeof (_Jv_Field));
   def->field_count = count;
   def->field_initializers = (_Jv_ushort*)
-    _Jv_AllocBytesChecked (count * sizeof (_Jv_ushort));
+    _Jv_AllocBytes (count * sizeof (_Jv_ushort));
   for (int i = 0; i < count; i++)
     def->field_initializers[i] = (_Jv_ushort) 0;
 }
@@ -1172,11 +1205,11 @@ void
 _Jv_ClassReader::handleMethodsBegin (int count)
 {
   def->methods = (_Jv_Method*)
-    _Jv_AllocBytesChecked (sizeof (_Jv_Method)*count);
+    _Jv_AllocBytes (sizeof (_Jv_Method)*count);
 
   def->interpreted_methods
-    = (_Jv_MethodBase **) _Jv_AllocBytesChecked (sizeof (_Jv_MethodBase *)
-                                                * count);
+    = (_Jv_MethodBase **) _Jv_AllocBytes (sizeof (_Jv_MethodBase *)
+                                         * count);
 
   for (int i = 0; i < count; i++)
     def->interpreted_methods[i] = 0;
@@ -1206,6 +1239,7 @@ void _Jv_ClassReader::handleMethod
 
   // intialize...
   method->ncode = 0;
+  method->throws = NULL;
   
   if (verify)
     {
@@ -1235,7 +1269,7 @@ void _Jv_ClassReader::handleCodeAttribute
 {
   int size = _Jv_InterpMethod::size (exc_table_length, code_length);
   _Jv_InterpMethod *method = 
-    (_Jv_InterpMethod*) (_Jv_AllocBytesChecked (size));
+    (_Jv_InterpMethod*) (_Jv_AllocBytes (size));
 
   method->max_stack      = max_stack;
   method->max_locals     = max_locals;
@@ -1282,7 +1316,7 @@ void _Jv_ClassReader::handleMethodsEnd ()
          else
            {
              _Jv_JNIMethod *m = (_Jv_JNIMethod *)
-               _Jv_AllocBytesChecked (sizeof (_Jv_JNIMethod));
+               _Jv_AllocBytes (sizeof (_Jv_JNIMethod));
              m->defining_class = def;
              m->self = method;
              m->function = NULL;
@@ -1576,10 +1610,9 @@ _Jv_ClassNameSamePackage (_Jv_Utf8Const *name1, _Jv_Utf8Const *name2)
 static void
 throw_no_class_def_found_error (jstring msg)
 {
-  if (msg == 0)
-    JvThrow (new java::lang::NoClassDefFoundError);
-  else
-    JvThrow (new java::lang::NoClassDefFoundError (msg));
+  throw (msg
+        ? new java::lang::NoClassDefFoundError (msg)
+        : new java::lang::NoClassDefFoundError);
 }
 
 static void
@@ -1591,17 +1624,15 @@ throw_no_class_def_found_error (char *msg)
 static void
 throw_class_format_error (jstring msg)
 {
-  if (msg == 0)
-    JvThrow (new java::lang::ClassFormatError);
-  else
-    JvThrow (new java::lang::ClassFormatError (msg));
+  throw (msg
+        ? new java::lang::ClassFormatError (msg)
+        : new java::lang::ClassFormatError);
 }
 
 static void
 throw_internal_error (char *msg)
 {
-  JvThrow 
-    (new java::lang::InternalError (JvNewStringLatin1 (msg)));
+  throw new java::lang::InternalError (JvNewStringLatin1 (msg));
 }
 
 static jfloat int_bits_to_float (jint value)
@@ -1616,12 +1647,12 @@ static jdouble long_bits_to_double (jlong value)
 
 static void throw_incompatible_class_change_error (jstring msg)
 {
-  JvThrow (new java::lang::IncompatibleClassChangeError (msg));
+  throw new java::lang::IncompatibleClassChangeError (msg);
 }
 
 static void throw_class_circularity_error (jstring msg)
 {
-  JvThrow (new java::lang::ClassCircularityError (msg));
+  throw new java::lang::ClassCircularityError (msg);
 }
 
 #endif /* INTERPRETER */