OSDN Git Service

PR java/8473:
[pf3gnuchains/gcc-fork.git] / libjava / defineclass.cc
index 2e8b4d9..5cd6b00 100644 (file)
@@ -96,7 +96,10 @@ struct _Jv_ClassReader {
   unsigned int      *offsets;
 
   // the class to define (see java-interp.h)
-  _Jv_InterpClass   *def;
+  jclass          def;
+  
+  // the classes associated interpreter data.
+  _Jv_InterpClass  *def_interp;
 
   /* check that the given number of input bytes are available */
   inline void check (int num)
@@ -221,7 +224,8 @@ struct _Jv_ClassReader {
     bytes  = (unsigned char*) (elements (data)+offset);
     len    = length;
     pos    = 0;
-    def    = (_Jv_InterpClass*) klass;
+    def    = klass;
+    def_interp = (_Jv_InterpClass *) def->aux_info;
   }
 
   /** and here goes the parser members defined out-of-line */
@@ -332,6 +336,8 @@ _Jv_ClassReader::parse ()
 
   // tell everyone we're done.
   def->state = JV_STATE_LOADED;
+  if (gcj::verbose_class_flag)
+    fprintf (stderr, "[Loaded (bytecode) %s]\n", def->name->chars());
   def->notifyAll ();
 
 }
@@ -772,9 +778,9 @@ _Jv_ClassReader::prepare_pool_entry (int index, unsigned char this_tag)
                           name_index, type_index);
 
          if (this_tag == JV_CONSTANT_Fieldref)
-           _Jv_VerifyFieldSignature (pool_data[type_index].utf8);
+           verify_field_signature (pool_data[type_index].utf8);
          else
-           _Jv_VerifyMethodSignature (pool_data[type_index].utf8);
+           verify_method_signature (pool_data[type_index].utf8);
 
          _Jv_Utf8Const* name = pool_data[name_index].utf8;
 
@@ -884,7 +890,7 @@ _Jv_ClassReader::handleClassBegin
       jstring msg = JvNewStringUTF ("loaded class ");
       msg = msg->concat (def->getName ());
       msg = msg->concat (_Jv_NewStringUTF (" was in fact named "));
-      jstring klass_name = _Jv_NewStringUTF (loadedName->data);
+      jstring klass_name = loadedName->toString();
       msg = msg->concat (klass_name);
 
       throw_no_class_def_found_error (msg);
@@ -1047,10 +1053,10 @@ void _Jv_ClassReader::handleFieldsBegin (int count)
   def->fields = (_Jv_Field*) 
     _Jv_AllocBytes (count * sizeof (_Jv_Field));
   def->field_count = count;
-  def->field_initializers = (_Jv_ushort*)
+  def_interp->field_initializers = (_Jv_ushort*)
     _Jv_AllocBytes (count * sizeof (_Jv_ushort));
   for (int i = 0; i < count; i++)
-    def->field_initializers[i] = (_Jv_ushort) 0;
+    def_interp->field_initializers[i] = (_Jv_ushort) 0;
 }
 
 void _Jv_ClassReader::handleField (int field_no,
@@ -1090,20 +1096,19 @@ void _Jv_ClassReader::handleField (int field_no,
            throw_class_format_error ("duplicate field name");
        }
 
-      if (field->flags & (Modifier::SYNCHRONIZED
-                         | Modifier::NATIVE
-                         | Modifier::INTERFACE
-                         | Modifier::ABSTRACT))
-       throw_class_format_error ("erroneous field access flags");
-      
+      // At most one of PUBLIC, PRIVATE, or PROTECTED is allowed.
       if (1 < ( ((field->flags & Modifier::PUBLIC) ? 1 : 0)
                +((field->flags & Modifier::PRIVATE) ? 1 : 0)
                +((field->flags & Modifier::PROTECTED) ? 1 : 0)))
        throw_class_format_error ("erroneous field access flags");
+
+      // FIXME: JVM spec S4.5: Verify ACC_FINAL and ACC_VOLATILE are not 
+      // both set. Verify modifiers for interface fields.
+      
     }
 
   if (verify)
-    _Jv_VerifyFieldSignature (sig);
+    verify_field_signature (sig);
 
   // field->type is really a jclass, but while it is still
   // unresolved we keep an _Jv_Utf8Const* instead.
@@ -1133,7 +1138,7 @@ void _Jv_ClassReader::handleConstantValueAttribute (int field_index,
     throw_class_format_error ("field has multiple ConstantValue attributes");
 
   field->flags |= _Jv_FIELD_CONSTANT_VALUE;
-  def->field_initializers[field_index] = value;
+  def_interp->field_initializers[field_index] = value;
 
   /* type check the initializer */
   
@@ -1153,7 +1158,7 @@ void _Jv_ClassReader::handleFieldsEnd ()
   int low            = 0;
   int high           = def->field_count-1;
   _Jv_Field  *fields = def->fields;
-  _Jv_ushort *inits  = def->field_initializers;
+  _Jv_ushort *inits  = def_interp->field_initializers;
 
   // this is kind of a raw version of quicksort.
   while (low < high)
@@ -1195,13 +1200,13 @@ _Jv_ClassReader::handleMethodsBegin (int count)
 {
   def->methods = (_Jv_Method *) _Jv_AllocBytes (sizeof (_Jv_Method) * count);
 
-  def->interpreted_methods
+  def_interp->interpreted_methods
     = (_Jv_MethodBase **) _Jv_AllocBytes (sizeof (_Jv_MethodBase *)
                                          * count);
 
   for (int i = 0; i < count; i++)
     {
-      def->interpreted_methods[i] = 0;
+      def_interp->interpreted_methods[i] = 0;
       def->methods[i].index = (_Jv_ushort) -1;
     }
 
@@ -1240,7 +1245,7 @@ void _Jv_ClassReader::handleMethod
       else
        verify_identifier (method->name);
 
-      _Jv_VerifyMethodSignature (method->signature);
+      verify_method_signature (method->signature);
 
       for (int i = 0; i < mth_index; ++i)
        {
@@ -1250,15 +1255,15 @@ void _Jv_ClassReader::handleMethod
            throw_class_format_error ("duplicate method");
        }
 
-      if (method->accflags & (Modifier::VOLATILE
-                             | Modifier::TRANSIENT
-                             | Modifier::INTERFACE))
-       throw_class_format_error ("erroneous method access flags");
-      
+      // At most one of PUBLIC, PRIVATE, or PROTECTED is allowed.
       if (1 < ( ((method->accflags & Modifier::PUBLIC) ? 1 : 0)
                +((method->accflags & Modifier::PRIVATE) ? 1 : 0)
                +((method->accflags & Modifier::PROTECTED) ? 1 : 0)))
        throw_class_format_error ("erroneous method access flags");
+
+      // FIXME: JVM spec S4.6: if ABSTRACT modifier is set, verify other 
+      // flags are not set. Verify flags for interface methods. Verifiy
+      // modifiers for initializers. 
     }
 }
 
@@ -1284,7 +1289,7 @@ void _Jv_ClassReader::handleCodeAttribute
          (void*) (bytes+code_start),
          code_length);
 
-  def->interpreted_methods[method_index] = method;
+  def_interp->interpreted_methods[method_index] = method;
 
   if ((method->self->accflags & java::lang::reflect::Modifier::STATIC))
     {
@@ -1301,7 +1306,7 @@ void _Jv_ClassReader::handleExceptionTableEntry
    int start_pc, int end_pc, int handler_pc, int catch_type)
 {
   _Jv_InterpMethod *method = reinterpret_cast<_Jv_InterpMethod *>
-    (def->interpreted_methods[method_index]);
+    (def_interp->interpreted_methods[method_index]);
   _Jv_InterpException *exc = method->exceptions ();
 
   exc[exc_index].start_pc.i     = start_pc;
@@ -1319,7 +1324,7 @@ void _Jv_ClassReader::handleMethodsEnd ()
       _Jv_Method *method = &def->methods[i];
       if ((method->accflags & Modifier::NATIVE) != 0)
        {
-         if (def->interpreted_methods[i] != 0)
+         if (def_interp->interpreted_methods[i] != 0)
            throw_class_format_error ("code provided for native method");
          else
            {
@@ -1328,7 +1333,7 @@ void _Jv_ClassReader::handleMethodsEnd ()
              m->defining_class = def;
              m->self = method;
              m->function = NULL;
-             def->interpreted_methods[i] = m;
+             def_interp->interpreted_methods[i] = m;
              m->deferred = NULL;
 
              if ((method->accflags & Modifier::STATIC))
@@ -1344,12 +1349,12 @@ void _Jv_ClassReader::handleMethodsEnd ()
        }
       else if ((method->accflags & Modifier::ABSTRACT) != 0)
        {
-         if (def->interpreted_methods[i] != 0)
+         if (def_interp->interpreted_methods[i] != 0)
            throw_class_format_error ("code provided for abstract method");
        }
       else
        {
-         if (def->interpreted_methods[i] == 0)
+         if (def_interp->interpreted_methods[i] == 0)
            throw_class_format_error ("method with no code");
        }
     }
@@ -1361,8 +1366,8 @@ void _Jv_ClassReader::throw_class_format_error (char *msg)
   if (def->name != NULL)
     {
       jsize mlen = strlen (msg);
-      unsigned char* data = (unsigned char*) def->name->data;
-      int ulen = def->name->length;
+      unsigned char* data = (unsigned char*) def->name->chars();
+      int ulen = def->name->len();
       unsigned char* limit = data + ulen;
       jsize nlen = _Jv_strLengthUtf8 ((char *) data, ulen);
       jsize len = nlen + mlen + 3;
@@ -1494,8 +1499,8 @@ _Jv_VerifyOne (unsigned char* ptr, unsigned char* limit, bool void_ok)
 bool
 _Jv_VerifyFieldSignature (_Jv_Utf8Const*sig)
 {
-  unsigned char* ptr = (unsigned char*) sig->data;
-  unsigned char* limit = ptr + sig->length;
+  unsigned char* ptr = (unsigned char*) sig->chars();
+  unsigned char* limit = ptr + sig->len();
 
   ptr = _Jv_VerifyOne (ptr, limit, false);
 
@@ -1505,8 +1510,8 @@ _Jv_VerifyFieldSignature (_Jv_Utf8Const*sig)
 bool
 _Jv_VerifyMethodSignature (_Jv_Utf8Const*sig)
 {
-  unsigned char* ptr = (unsigned char*) sig->data;
-  unsigned char* limit = ptr + sig->length;
+  unsigned char* ptr = (unsigned char*) sig->chars();
+  unsigned char* limit = ptr + sig->len();
 
   if (ptr == limit || UTF8_GET(ptr,limit) != '(')
     return false;
@@ -1560,8 +1565,8 @@ is_identifier_part (int c)
 bool
 _Jv_VerifyIdentifier (_Jv_Utf8Const* name)
 {
-  unsigned char *ptr   = (unsigned char*) name->data;
-  unsigned char *limit = ptr + name->length;
+  unsigned char *ptr   = (unsigned char*) name->chars();
+  unsigned char *limit = (unsigned char*) name->limit();
   int ch;
 
   if ((ch = UTF8_GET (ptr, limit))==-1
@@ -1616,8 +1621,7 @@ _Jv_VerifyClassName (unsigned char* ptr, _Jv_ushort length)
 bool
 _Jv_VerifyClassName (_Jv_Utf8Const *name)
 {
-  return _Jv_VerifyClassName ((unsigned char*)&name->data[0],
-                             (_Jv_ushort) name->length);
+  return _Jv_VerifyClassName ((unsigned char*)name->chars(), name->len());
 }
 
 /* Returns true, if NAME1 and NAME2 represent classes in the same
@@ -1625,8 +1629,8 @@ _Jv_VerifyClassName (_Jv_Utf8Const *name)
 bool
 _Jv_ClassNameSamePackage (_Jv_Utf8Const *name1, _Jv_Utf8Const *name2)
 {
-  unsigned char* ptr1 = (unsigned char*) name1->data;
-  unsigned char* limit1 = ptr1 + name1->length;
+  unsigned char* ptr1 = (unsigned char*) name1->chars();
+  unsigned char* limit1 = (unsigned char*) name1->limit();
 
   unsigned char* last1 = ptr1;
 
@@ -1642,20 +1646,19 @@ _Jv_ClassNameSamePackage (_Jv_Utf8Const *name1, _Jv_Utf8Const *name2)
   }
 
   // Now the length of NAME1's package name is LEN.
-  int len = last1 - (unsigned char*) name1->data;
+  int len = last1 - (unsigned char*) name1->chars();
 
   // If this is longer than NAME2, then we're off.
-  if (len > name2->length)
+  if (len > name2->len())
     return false;
 
   // Then compare the first len bytes for equality.
-  if (memcmp ((void*) name1->data, (void*) name2->data, len) == 0)
+  if (memcmp ((void*) name1->chars(), (void*) name2->chars(), len) == 0)
     {
       // Check that there are no .'s after position LEN in NAME2.
 
-      unsigned char* ptr2 = (unsigned char*) name2->data + len;
-      unsigned char* limit2 =
-       (unsigned char*) name2->data + name2->length;
+      unsigned char* ptr2 = (unsigned char*) name2->chars() + len;
+      unsigned char* limit2 = (unsigned char*) name2->limit();
 
       while (ptr2 < limit2)
        {