OSDN Git Service

2003-12-17 Neil Booth <neil@daikokuya.co.uk>
[pf3gnuchains/gcc-fork.git] / libjava / defineclass.cc
index dc35002..2e8b4d9 100644 (file)
@@ -1,6 +1,6 @@
 // defineclass.cc - defining a class from .class format.
 
-/* Copyright (C) 1999, 2000, 2001, 2002  Free Software Foundation
+/* Copyright (C) 1999, 2000, 2001, 2002, 2003  Free Software Foundation
 
    This file is part of libgcj.
 
@@ -75,7 +75,7 @@ struct _Jv_ClassReader {
   // allways on.  You always want this as far as I can see, but it also
   // controls weither identifiers and type descriptors/signatures are
   // verified as legal.  This could be somewhat more expensive since it
-  // will call Characher.isJavaIdentifier{Start,Part} for each character
+  // will call Character.isJavaIdentifier{Start,Part} for each character
   // in any identifier (field name or method name) it comes by.  Thus,
   // it might be useful to turn off this verification for classes that
   // come from a trusted source.  However, for GCJ, trusted classes are
@@ -403,15 +403,15 @@ void _Jv_ClassReader::read_fields ()
       int name_index       = read2u ();
       int descriptor_index = read2u ();
       int attributes_count = read2u ();
-      
+
       check_tag (name_index, JV_CONSTANT_Utf8);
       prepare_pool_entry (name_index, JV_CONSTANT_Utf8);
 
       check_tag (descriptor_index, JV_CONSTANT_Utf8);
       prepare_pool_entry (descriptor_index, JV_CONSTANT_Utf8);
-      
+
       handleField (i, access_flags, name_index, descriptor_index);
-      
+
       for (int j = 0; j < attributes_count; j++)
        {
          read_one_field_attribute (i);
@@ -890,7 +890,7 @@ _Jv_ClassReader::handleClassBegin
       throw_no_class_def_found_error (msg);
     }
 
-  def->accflags = access_flags;
+  def->accflags = access_flags | java::lang::reflect::Modifier::INTERPRETED;
   pool_data[this_class].clazz = def;
   pool_tags[this_class] = JV_CONSTANT_ResolvedClass;
 
@@ -1071,14 +1071,25 @@ void _Jv_ClassReader::handleField (int field_no,
   field->nameIndex = name;
 #endif
 
-  if (verify)
-    verify_identifier (field_name);
-
-  // ignore flags we don't know about.  
+  // Ignore flags we don't know about.  
   field->flags = flags & Modifier::ALL_FLAGS;
 
+  _Jv_Utf8Const* sig = pool_data[desc].utf8;
+
   if (verify)
     {
+      verify_identifier (field_name);
+
+      for (int i = 0; i < field_no; ++i)
+       {
+         if (_Jv_equalUtf8Consts (field_name, def->fields[i].name)
+             && _Jv_equalUtf8Consts (sig,
+                                     // We know the other fields are
+                                     // unresolved.
+                                     (_Jv_Utf8Const *) def->fields[i].type))
+           throw_class_format_error ("duplicate field name");
+       }
+
       if (field->flags & (Modifier::SYNCHRONIZED
                          | Modifier::NATIVE
                          | Modifier::INTERFACE
@@ -1091,8 +1102,6 @@ void _Jv_ClassReader::handleField (int field_no,
        throw_class_format_error ("erroneous field access flags");
     }
 
-  _Jv_Utf8Const* sig = pool_data[desc].utf8;
-
   if (verify)
     _Jv_VerifyFieldSignature (sig);
 
@@ -1233,6 +1242,14 @@ void _Jv_ClassReader::handleMethod
 
       _Jv_VerifyMethodSignature (method->signature);
 
+      for (int i = 0; i < mth_index; ++i)
+       {
+         if (_Jv_equalUtf8Consts (method->name, def->methods[i].name)
+             && _Jv_equalUtf8Consts (method->signature,
+                                     def->methods[i].signature))
+           throw_class_format_error ("duplicate method");
+       }
+
       if (method->accflags & (Modifier::VOLATILE
                              | Modifier::TRANSIENT
                              | Modifier::INTERFACE))
@@ -1253,6 +1270,7 @@ void _Jv_ClassReader::handleCodeAttribute
   _Jv_InterpMethod *method = 
     (_Jv_InterpMethod*) (_Jv_AllocBytes (size));
 
+  method->deferred      = NULL;
   method->max_stack      = max_stack;
   method->max_locals     = max_locals;
   method->code_length    = code_length;
@@ -1267,6 +1285,15 @@ void _Jv_ClassReader::handleCodeAttribute
          code_length);
 
   def->interpreted_methods[method_index] = method;
+
+  if ((method->self->accflags & java::lang::reflect::Modifier::STATIC))
+    {
+      // Precompute the ncode field for a static method.  This lets us
+      // call a static method of an interpreted class from precompiled
+      // code without first resolving the class (that will happen
+      // during class initialization instead).
+      method->self->ncode = method->ncode ();
+    }
 }
 
 void _Jv_ClassReader::handleExceptionTableEntry
@@ -1302,6 +1329,17 @@ void _Jv_ClassReader::handleMethodsEnd ()
              m->self = method;
              m->function = NULL;
              def->interpreted_methods[i] = m;
+             m->deferred = NULL;
+
+             if ((method->accflags & Modifier::STATIC))
+               {
+                 // Precompute the ncode field for a static method.
+                 // This lets us call a static method of an
+                 // interpreted class from precompiled code without
+                 // first resolving the class (that will happen
+                 // during class initialization instead).
+                 method->ncode = m->ncode ();
+               }
            }
        }
       else if ((method->accflags & Modifier::ABSTRACT) != 0)