OSDN Git Service

PR libgcj/17020
[pf3gnuchains/gcc-fork.git] / libjava / defineclass.cc
1 // defineclass.cc - defining a class from .class format.
2
3 /* Copyright (C) 1999, 2000, 2001, 2002, 2003  Free Software Foundation
4
5    This file is part of libgcj.
6
7 This software is copyrighted work licensed under the terms of the
8 Libgcj License.  Please consult the file "LIBGCJ_LICENSE" for
9 details.  */
10
11 /* 
12    Author: Kresten Krab Thorup <krab@gnu.org> 
13
14    Written using the online versions of Java Language Specification (1st
15    ed.) and The Java Virtual Machine Specification (2nd ed.). 
16
17    Future work may include reading (and handling) attributes which are
18    currently being ignored ("InnerClasses", "LineNumber", etc...).  
19 */
20
21 #include <config.h>
22
23 #include <java-interp.h>
24
25 #include <stdlib.h>
26 #include <java-cpool.h>
27 #include <gcj/cni.h>
28
29 #include <java/lang/Class.h>
30 #include <java/lang/Float.h>
31 #include <java/lang/Double.h>
32 #include <java/lang/Character.h>
33 #include <java/lang/LinkageError.h>
34 #include <java/lang/InternalError.h>
35 #include <java/lang/ClassFormatError.h>
36 #include <java/lang/NoClassDefFoundError.h>
37 #include <java/lang/ClassCircularityError.h>
38 #include <java/lang/IncompatibleClassChangeError.h>
39 #include <java/lang/reflect/Modifier.h>
40
41 using namespace gcj;
42
43 #ifdef INTERPRETER
44
45 // these go in some separate functions, to avoid having _Jv_InitClass
46 // inserted all over the place.
47 static void throw_internal_error (char *msg)
48         __attribute__ ((__noreturn__));
49 static void throw_no_class_def_found_error (jstring msg)
50         __attribute__ ((__noreturn__));
51 static void throw_no_class_def_found_error (char *msg)
52         __attribute__ ((__noreturn__));
53 static void throw_class_format_error (jstring msg)
54         __attribute__ ((__noreturn__));
55 static void throw_incompatible_class_change_error (jstring msg)
56         __attribute__ ((__noreturn__));
57 static void throw_class_circularity_error (jstring msg)
58         __attribute__ ((__noreturn__));
59
60 /**
61  * We define class reading using a class.  It is practical, since then
62  * the entire class-reader can be a friend of class Class (it needs to
63  * write all it's different structures); but also because this makes it
64  * easy to make class definition reentrant, and thus two threads can be
65  * defining classes at the same time.   This class (_Jv_ClassReader) is
66  * never exposed outside this file, so we don't have to worry about
67  * public or private members here.
68  */
69
70 struct _Jv_ClassReader {
71
72   // do verification?  Currently, there is no option to disable this.
73   // This flag just controls the verificaiton done by the class loader;
74   // i.e., checking the integrity of the constant pool; and it is
75   // allways on.  You always want this as far as I can see, but it also
76   // controls weither identifiers and type descriptors/signatures are
77   // verified as legal.  This could be somewhat more expensive since it
78   // will call Character.isJavaIdentifier{Start,Part} for each character
79   // in any identifier (field name or method name) it comes by.  Thus,
80   // it might be useful to turn off this verification for classes that
81   // come from a trusted source.  However, for GCJ, trusted classes are
82   // most likely to be linked in.
83
84   bool verify;
85
86   // input data.
87   unsigned char     *bytes;
88   int                len;
89
90   // current input position
91   int                pos;
92
93   // the constant pool data
94   int pool_count;
95   unsigned char     *tags;
96   unsigned int      *offsets;
97
98   // the class to define (see java-interp.h)
99   jclass           def;
100   
101   // the classes associated interpreter data.
102   _Jv_InterpClass  *def_interp;
103
104   /* check that the given number of input bytes are available */
105   inline void check (int num)
106   {
107     if (pos + num > len)
108       throw_class_format_error ("Premature end of data");
109   }
110
111   /* skip a given number of bytes in input */
112   inline void skip (int num)
113   {
114     check (num);
115     pos += num;
116   }
117   
118   /* read an unsignend 1-byte unit */
119   inline static jint get1u (unsigned char* bytes)
120   {
121     return bytes[0];
122   }
123   
124   /* read an unsigned 1-byte unit */
125   inline jint read1u ()
126   {
127     skip (1);
128     return get1u (bytes+pos-1);
129   }
130   
131   /* read an unsigned 2-byte unit */
132   inline static jint get2u (unsigned char *bytes)
133   {
134     return (((jint)bytes[0]) << 8) | ((jint)bytes[1]);
135   }
136   
137   /* read an unsigned 2-byte unit */
138   inline jint read2u ()
139   {
140     skip (2);  
141     return get2u (bytes+pos-2);
142   }
143   
144   /* read a 4-byte unit */
145   static jint get4 (unsigned char *bytes)
146   {
147     return (((jint)bytes[0]) << 24)
148          | (((jint)bytes[1]) << 16)
149          | (((jint)bytes[2]) << 8)
150          | (((jint)bytes[3]) << 0);
151   }
152
153   /* read a 4-byte unit, (we don't do that quite so often) */
154   inline jint read4 ()
155   {
156     skip (4);  
157     return get4 (bytes+pos-4);
158   }
159
160   /* read a 8-byte unit */
161   static jlong get8 (unsigned char* bytes)
162   {
163     return (((jlong)bytes[0]) << 56)
164          | (((jlong)bytes[1]) << 48)
165          | (((jlong)bytes[2]) << 40)
166          | (((jlong)bytes[3]) << 32) 
167          | (((jlong)bytes[4]) << 24)
168          | (((jlong)bytes[5]) << 16)
169          | (((jlong)bytes[6]) << 8)
170          | (((jlong)bytes[7]) << 0);
171   }
172
173   /* read a 8-byte unit */
174   inline jlong read8 ()
175   {
176     skip (8);  
177     return get8 (bytes+pos-8);
178   }
179
180   inline void check_tag (int index, char expected_tag)
181   {
182     if (index < 0
183         || index > pool_count
184         || tags[index] != expected_tag)
185       throw_class_format_error ("erroneous constant pool tag");
186   }
187
188   inline void verify_identifier (_Jv_Utf8Const* name)
189   {
190     if (! _Jv_VerifyIdentifier (name))
191       throw_class_format_error ("erroneous identifier");
192   }
193
194   inline void verify_classname (unsigned char* ptr, _Jv_ushort length)
195   {
196     if (! _Jv_VerifyClassName (ptr, length))
197       throw_class_format_error ("erroneous class name");
198   }
199
200   inline void verify_classname (_Jv_Utf8Const *name)
201   {
202     if (! _Jv_VerifyClassName (name))
203       throw_class_format_error ("erroneous class name");
204   }
205
206   inline void verify_field_signature (_Jv_Utf8Const *sig)
207   {
208     if (! _Jv_VerifyFieldSignature (sig))
209       throw_class_format_error ("erroneous type descriptor");
210   }
211
212   inline void verify_method_signature (_Jv_Utf8Const *sig)
213   {
214     if (! _Jv_VerifyMethodSignature (sig))
215       throw_class_format_error ("erroneous type descriptor");
216   }
217
218   _Jv_ClassReader (jclass klass, jbyteArray data, jint offset, jint length)
219   {
220     if (klass == 0 || length < 0 || offset+length > data->length)
221       throw_internal_error ("arguments to _Jv_DefineClass");
222
223     verify = true;
224     bytes  = (unsigned char*) (elements (data)+offset);
225     len    = length;
226     pos    = 0;
227     def    = klass;
228     def_interp = (_Jv_InterpClass *) def->aux_info;
229   }
230
231   /** and here goes the parser members defined out-of-line */
232   void parse ();
233   void read_constpool ();
234   void prepare_pool_entry (int index, unsigned char tag);
235   void read_fields ();
236   void read_methods ();
237   void read_one_class_attribute ();
238   void read_one_method_attribute (int method);
239   void read_one_code_attribute (int method);
240   void read_one_field_attribute (int field);
241   void throw_class_format_error (char *msg);
242
243   /** check an utf8 entry, without creating a Utf8Const object */
244   bool is_attribute_name (int index, char *name);
245
246   /** here goes the class-loader members defined out-of-line */
247   void handleConstantPool ();
248   void handleClassBegin (int, int, int);
249   void handleInterfacesBegin (int);
250   void handleInterface (int, int);
251   void handleFieldsBegin (int);
252   void handleField (int, int, int, int);
253   void handleFieldsEnd ();
254   void handleConstantValueAttribute (int,int);
255   void handleMethodsBegin (int);
256   void handleMethod (int, int, int, int);
257   void handleMethodsEnd ();
258   void handleCodeAttribute (int, int, int, int, int, int);
259   void handleExceptionTableEntry (int, int, int, int, int, int);
260
261   void checkExtends (jclass sub, jclass super);
262   void checkImplements (jclass sub, jclass super);
263
264   /*
265    * FIXME: we should keep a hash table of utf8-strings, since many will
266    * be the same.  It's a little tricky, however, because the hash table
267    * needs to interact gracefully with the garbage collector.  Much
268    * memory is to be saved by this, however!  perhaps the improvement
269    * could be implemented in prims.cc (_Jv_makeUtf8Const), since it
270    * computes the hash value anyway.
271    */
272 };
273
274 void
275 _Jv_DefineClass (jclass klass, jbyteArray data, jint offset, jint length)
276 {
277   _Jv_ClassReader reader (klass, data, offset, length);
278   reader.parse();
279
280   /* that's it! */
281 }
282
283 \f
284 /** This section defines the parsing/scanning of the class data */
285
286 void
287 _Jv_ClassReader::parse ()
288 {
289   int magic = read4 ();
290
291   /* FIXME: Decide which range of version numbers to allow */
292
293   /* int minor_version = */ read2u ();
294   /* int major_verson  = */ read2u ();
295
296   if (magic != (int) 0xCAFEBABE)
297     throw_class_format_error ("bad magic number");
298
299   pool_count = read2u ();
300
301   read_constpool ();
302
303   int access_flags = read2u ();
304   int this_class = read2u ();
305   int super_class = read2u ();
306
307   check_tag (this_class, JV_CONSTANT_Class);
308   if (super_class != 0) 
309     check_tag (super_class, JV_CONSTANT_Class);
310
311   handleClassBegin (access_flags, this_class, super_class);
312
313   int interfaces_count = read2u (); 
314         
315   handleInterfacesBegin (interfaces_count);
316
317   for (int i = 0; i < interfaces_count; i++)
318     {
319       int iface = read2u ();
320       check_tag (iface, JV_CONSTANT_Class);
321       handleInterface (i, iface);
322     }
323   
324   read_fields ();
325   read_methods ();
326   
327   int attributes_count = read2u ();
328   
329   for (int i = 0; i < attributes_count; i++)
330     {
331       read_one_class_attribute ();
332     }
333
334   if (pos != len)
335     throw_class_format_error ("unused data before end of file");
336
337   // tell everyone we're done.
338   def->state = JV_STATE_LOADED;
339   if (gcj::verbose_class_flag)
340     fprintf (stderr, "[Loaded (bytecode) %s]\n", def->name->chars());
341   def->notifyAll ();
342
343 }
344
345 void _Jv_ClassReader::read_constpool ()
346 {
347   tags    = (unsigned char*) _Jv_AllocBytes (pool_count);
348   offsets = (unsigned int *) _Jv_AllocBytes (sizeof (int)
349                                                     * pool_count) ;
350
351   /** first, we scan the constant pool, collecting tags and offsets */
352   tags[0]   = JV_CONSTANT_Undefined;
353   offsets[0] = pos;
354   for (int c = 1; c < pool_count; c++)
355     {
356       tags[c]    = read1u ();
357       offsets[c] = pos;
358
359       switch (tags[c])
360         {
361         case JV_CONSTANT_String:
362         case JV_CONSTANT_Class:
363           skip (2);
364           break;
365
366         case JV_CONSTANT_Fieldref:
367         case JV_CONSTANT_Methodref:
368         case JV_CONSTANT_InterfaceMethodref:
369         case JV_CONSTANT_NameAndType:
370         case JV_CONSTANT_Integer:
371         case JV_CONSTANT_Float:
372           skip (4);
373           break;
374
375         case JV_CONSTANT_Double:
376         case JV_CONSTANT_Long:
377           skip (8);
378           tags[++c] = JV_CONSTANT_Undefined;
379           break;
380             
381         case JV_CONSTANT_Utf8:
382           {                 
383             int len = read2u ();
384             skip (len);
385           }
386           break;
387
388         case JV_CONSTANT_Unicode:
389           throw_class_format_error ("unicode not supported");
390           break;
391
392         default:
393           throw_class_format_error ("erroneous constant pool tag");
394         }
395     }
396
397   handleConstantPool ();
398 }
399
400
401 void _Jv_ClassReader::read_fields ()
402 {
403   int fields_count = read2u ();
404   handleFieldsBegin (fields_count);
405
406   for (int i = 0; i < fields_count; i++)
407     {
408       int access_flags     = read2u ();
409       int name_index       = read2u ();
410       int descriptor_index = read2u ();
411       int attributes_count = read2u ();
412
413       check_tag (name_index, JV_CONSTANT_Utf8);
414       prepare_pool_entry (name_index, JV_CONSTANT_Utf8);
415
416       check_tag (descriptor_index, JV_CONSTANT_Utf8);
417       prepare_pool_entry (descriptor_index, JV_CONSTANT_Utf8);
418
419       handleField (i, access_flags, name_index, descriptor_index);
420
421       for (int j = 0; j < attributes_count; j++)
422         {
423           read_one_field_attribute (i);
424         }
425     }
426
427   handleFieldsEnd ();
428 }
429
430 bool
431 _Jv_ClassReader::is_attribute_name (int index, char *name)
432 {
433   check_tag (index, JV_CONSTANT_Utf8);
434   int len = get2u (bytes+offsets[index]);
435   if (len != (int) strlen (name))
436     return false;
437   else
438     return !memcmp (bytes+offsets[index]+2, name, len);
439 }
440
441 void _Jv_ClassReader::read_one_field_attribute (int field_index)
442 {
443   int name = read2u ();
444   int length = read4 ();
445
446   if (is_attribute_name (name, "ConstantValue"))
447     {
448       int cv = read2u ();
449
450       if (cv < pool_count 
451           && cv > 0
452           && (tags[cv] == JV_CONSTANT_Integer
453               || tags[cv] == JV_CONSTANT_Float
454               || tags[cv] == JV_CONSTANT_Long
455               || tags[cv] == JV_CONSTANT_Double
456               || tags[cv] == JV_CONSTANT_String))
457           {
458             handleConstantValueAttribute (field_index, cv);
459           }
460         else
461           {
462             throw_class_format_error ("erroneous ConstantValue attribute");
463           }
464
465         if (length != 2) 
466           throw_class_format_error ("erroneous ConstantValue attribute");
467       }
468
469     else
470       {
471         skip (length);
472       }
473 }
474
475 void _Jv_ClassReader::read_methods ()
476 {
477   int methods_count = read2u ();
478   
479   handleMethodsBegin (methods_count);
480   
481   for (int i = 0; i < methods_count; i++)
482     {
483       int access_flags     = read2u ();
484       int name_index       = read2u ();
485       int descriptor_index = read2u ();
486       int attributes_count = read2u ();
487       
488       check_tag (name_index, JV_CONSTANT_Utf8);
489       prepare_pool_entry (descriptor_index, JV_CONSTANT_Utf8);
490
491       check_tag (name_index, JV_CONSTANT_Utf8);
492       prepare_pool_entry (descriptor_index, JV_CONSTANT_Utf8);
493
494       handleMethod (i, access_flags, name_index,
495                     descriptor_index);
496
497       for (int j = 0; j < attributes_count; j++)
498         {
499           read_one_method_attribute (i);
500         }
501     }
502   
503   handleMethodsEnd ();
504 }
505
506 void _Jv_ClassReader::read_one_method_attribute (int method_index) 
507 {
508   int name = read2u ();
509   int length = read4 ();
510
511   if (is_attribute_name (name, "Exceptions"))
512     {
513       _Jv_Method *method = reinterpret_cast<_Jv_Method *>
514         (&def->methods[method_index]);
515       if (method->throws != NULL)
516         throw_class_format_error ("only one Exceptions attribute allowed per method");
517
518       int num_exceptions = read2u ();
519       // We use malloc here because the GC won't scan the method
520       // objects.  FIXME this means a memory leak if we GC a class.
521       // (Currently we never do.)
522       _Jv_Utf8Const **exceptions =
523         (_Jv_Utf8Const **) _Jv_Malloc ((num_exceptions + 1) * sizeof (_Jv_Utf8Const *));
524
525       int out = 0;
526       _Jv_word *pool_data = def->constants.data;
527       for (int i = 0; i < num_exceptions; ++i)
528         {
529           try
530             {
531               int ndx = read2u ();
532               // JLS 2nd Ed. 4.7.5 requires that the tag not be 0.
533               if (ndx != 0)
534                 {
535                   check_tag (ndx, JV_CONSTANT_Class);
536                   exceptions[out++] = pool_data[ndx].utf8; 
537                 }
538             }
539           catch (java::lang::Throwable *exc)
540             {
541               _Jv_Free (exceptions);
542               throw exc;
543             }
544         }
545       exceptions[out] = NULL;
546       method->throws = exceptions;
547     }
548
549   else if (is_attribute_name (name, "Code"))
550     {
551       int start_off = pos;
552       int max_stack = read2u ();
553       int max_locals = read2u ();
554       int code_length = read4 ();
555
556       int code_start = pos;
557       skip (code_length);
558       int exception_table_length = read2u ();
559
560       handleCodeAttribute (method_index, 
561                            max_stack, max_locals,
562                            code_start, code_length,
563                            exception_table_length);
564       
565
566       for (int i = 0; i < exception_table_length; i++)
567         {
568           int start_pc   = read2u ();
569           int end_pc     = read2u ();
570           int handler_pc = read2u ();
571           int catch_type = read2u ();
572
573           if (start_pc > end_pc
574               || start_pc < 0
575               // END_PC can be equal to CODE_LENGTH.
576               // See JVM Spec 4.7.4.
577               || end_pc > code_length
578               || handler_pc >= code_length)
579             throw_class_format_error ("erroneous exception handler info");
580
581           if (! (tags[catch_type] == JV_CONSTANT_Class
582                  || tags[catch_type] == 0))
583             {
584               throw_class_format_error ("erroneous exception handler info");
585             }
586
587           handleExceptionTableEntry (method_index,
588                                      i,
589                                      start_pc,
590                                      end_pc,
591                                      handler_pc, 
592                                      catch_type);
593
594         }
595
596       int attributes_count = read2u ();
597
598       for (int i = 0; i < attributes_count; i++)
599         {
600           read_one_code_attribute (method_index);
601         }
602
603       if ((pos - start_off) != length)
604         throw_class_format_error ("code attribute too short");
605     }
606
607   else
608     {
609       /* ignore unknown attributes */
610       skip (length);
611     }
612 }
613
614 void _Jv_ClassReader::read_one_code_attribute (int /*method*/) 
615 {
616   /* ignore for now, ... later we may want to pick up
617      line number information, for debugging purposes;
618      in fact, the whole debugger issue is open!  */
619
620   /* int name = */ read2u ();
621   int length = read4 ();
622   skip (length);
623
624 }
625
626 void _Jv_ClassReader::read_one_class_attribute () 
627 {
628   /* we also ignore the class attributes, ...
629      some day we'll add inner-classes support. */
630
631   /* int name = */ read2u ();
632   int length = read4 ();
633   skip (length);
634 }
635
636
637
638 \f
639 /* this section defines the semantic actions of the parser */
640
641 void _Jv_ClassReader::handleConstantPool ()
642 {
643   /** now, we actually define the class' constant pool */
644
645   // the pool is scanned explicitly by the collector
646   jbyte *pool_tags = (jbyte*) _Jv_AllocBytes (pool_count);
647   _Jv_word *pool_data
648     = (_Jv_word*) _Jv_AllocBytes (pool_count * sizeof (_Jv_word));
649   
650   def->constants.tags = pool_tags;
651   def->constants.data = pool_data;
652   def->constants.size = pool_count;
653
654   // Here we make a pass to collect the strings!   We do this, because
655   // internally in the GCJ runtime, classes are encoded with .'s not /'s. 
656   // Therefore, we first collect the strings, and then translate the rest
657   // of the utf8-entries (thus not representing strings) from /-notation
658   // to .-notation.
659   for (int i = 1; i < pool_count; i++)
660     {
661       if (tags[i] == JV_CONSTANT_String)
662         {
663           unsigned char* str_data = bytes + offsets [i];
664           int utf_index = get2u (str_data);
665           check_tag (utf_index, JV_CONSTANT_Utf8);
666           unsigned char *utf_data = bytes + offsets[utf_index];
667           int len = get2u (utf_data);
668           pool_data[i].utf8 = _Jv_makeUtf8Const ((char*)(utf_data+2), len);
669           pool_tags[i] = JV_CONSTANT_String;
670         }
671       else
672         {
673           pool_tags[i] = JV_CONSTANT_Undefined;
674         }
675     }
676
677   // and now, we scan everything else but strings & utf8-entries.  This
678   // leaves out those utf8-entries which are not used; which will be left
679   // with a tag of JV_CONSTANT_Undefined in the class definition.
680   for (int index = 1; index < pool_count; index++)
681     {
682       switch (tags[index])
683         {
684         case JV_CONSTANT_Undefined:
685         case JV_CONSTANT_String:
686         case JV_CONSTANT_Utf8:
687           continue;
688           
689         default:
690           prepare_pool_entry (index, tags[index]);
691         }
692     }  
693   
694 }
695
696 /* this is a recursive procedure, which will prepare pool entries as needed.
697    Which is how we avoid initializing those entries which go unused. */
698 void
699 _Jv_ClassReader::prepare_pool_entry (int index, unsigned char this_tag)
700 {
701   /* these two, pool_data and pool_tags, point into the class
702      structure we are currently defining */
703
704   unsigned char *pool_tags = (unsigned char*) def->constants.tags;
705   _Jv_word      *pool_data = def->constants.data;
706
707   /* this entry was already prepared */
708   if (pool_tags[index] == this_tag)
709     return;
710
711   /* this_data points to the constant-pool information for the current
712      constant-pool entry */
713
714   unsigned char *this_data = bytes + offsets[index];
715
716   switch (this_tag)
717     {
718     case JV_CONSTANT_Utf8: 
719       {
720         // If we came here, it is because some other tag needs this
721         // utf8-entry for type information!  Thus, we translate /'s to .'s in
722         // order to accomondate gcj's internal representation.
723
724         int len = get2u (this_data);
725         char *buffer = (char*) __builtin_alloca (len);
726         char *s = ((char*) this_data)+2;
727
728         /* FIXME: avoid using a buffer here */
729         for (int i = 0; i < len; i++)
730           {
731             if (s[i] == '/')
732               buffer[i] = '.';
733             else
734               buffer[i] = (char) s[i];
735           }
736         
737         pool_data[index].utf8 = _Jv_makeUtf8Const (buffer, len);
738         pool_tags[index] = JV_CONSTANT_Utf8;
739       }
740       break;
741             
742     case JV_CONSTANT_Class:      
743       {
744         int utf_index = get2u (this_data);
745         check_tag (utf_index, JV_CONSTANT_Utf8);
746         prepare_pool_entry (utf_index, JV_CONSTANT_Utf8);
747
748         if (verify)
749           verify_classname (pool_data[utf_index].utf8);
750                 
751         pool_data[index].utf8 = pool_data[utf_index].utf8;
752         pool_tags[index] = JV_CONSTANT_Class;
753       }
754       break;
755             
756     case JV_CONSTANT_String:
757       // already handled before... 
758       break;
759             
760     case JV_CONSTANT_Fieldref:
761     case JV_CONSTANT_Methodref:
762     case JV_CONSTANT_InterfaceMethodref:
763       {
764         int class_index = get2u (this_data);
765         int nat_index = get2u (this_data+2);
766
767         check_tag (class_index, JV_CONSTANT_Class);
768         prepare_pool_entry (class_index, JV_CONSTANT_Class);        
769
770         check_tag (nat_index, JV_CONSTANT_NameAndType);
771         prepare_pool_entry (nat_index, JV_CONSTANT_NameAndType);
772
773         // here, verify the signature and identifier name
774         if (verify)
775         {
776           _Jv_ushort name_index, type_index;
777           _Jv_loadIndexes (&pool_data[nat_index],
778                            name_index, type_index);
779
780           if (this_tag == JV_CONSTANT_Fieldref)
781             verify_field_signature (pool_data[type_index].utf8);
782           else
783             verify_method_signature (pool_data[type_index].utf8);
784
785           _Jv_Utf8Const* name = pool_data[name_index].utf8;
786
787           if (this_tag != JV_CONSTANT_Fieldref
788               && (   _Jv_equalUtf8Consts (name, clinit_name)
789                   || _Jv_equalUtf8Consts (name, init_name)))
790             /* ignore */;
791           else
792             verify_identifier (pool_data[name_index].utf8);
793         }
794             
795         _Jv_storeIndexes (&pool_data[index], class_index, nat_index);
796         pool_tags[index] = this_tag;
797       }
798       break;
799             
800     case JV_CONSTANT_NameAndType:
801       {
802         _Jv_ushort name_index = get2u (this_data);
803         _Jv_ushort type_index = get2u (this_data+2);
804
805         check_tag (name_index, JV_CONSTANT_Utf8);
806         prepare_pool_entry (name_index, JV_CONSTANT_Utf8);          
807
808         check_tag (type_index, JV_CONSTANT_Utf8);
809         prepare_pool_entry (type_index, JV_CONSTANT_Utf8);
810
811         _Jv_storeIndexes (&pool_data[index], name_index, type_index);
812         pool_tags[index] = JV_CONSTANT_NameAndType;
813       }
814       break;
815             
816     case JV_CONSTANT_Float:
817       {
818         jfloat f = java::lang::Float::intBitsToFloat ((jint) get4 (this_data));
819         _Jv_storeFloat (&pool_data[index], f);
820         pool_tags[index] = JV_CONSTANT_Float;
821       }
822       break;
823             
824     case JV_CONSTANT_Integer:
825       {
826         int i = get4 (this_data);
827         _Jv_storeInt (&pool_data[index], i);
828         pool_tags[index] = JV_CONSTANT_Integer;
829       }
830       break;
831             
832     case JV_CONSTANT_Double:
833       {
834         jdouble d
835           = java::lang::Double::longBitsToDouble ((jlong) get8 (this_data));
836         _Jv_storeDouble (&pool_data[index], d);
837         pool_tags[index] = JV_CONSTANT_Double;
838       }
839       break;
840             
841     case JV_CONSTANT_Long:
842       {
843         jlong i = get8 (this_data);
844         _Jv_storeLong (&pool_data[index], i);
845         pool_tags[index] = JV_CONSTANT_Long;
846       }
847       break;
848             
849     default:
850       throw_class_format_error ("erroneous constant pool tag");
851     }
852 }
853
854
855 void
856 _Jv_ClassReader::handleClassBegin
857   (int access_flags, int this_class, int super_class)
858 {
859   using namespace java::lang::reflect;
860
861   unsigned char *pool_tags = (unsigned char*) def->constants.tags;
862   _Jv_word      *pool_data = def->constants.data;
863
864   check_tag (this_class, JV_CONSTANT_Class);
865   _Jv_Utf8Const *loadedName = pool_data[this_class].utf8;
866
867   // was ClassLoader.defineClass called with an expected class name?
868   if (def->name == 0)
869     {
870       jclass orig = _Jv_FindClassInCache (loadedName, def->loader);
871
872       if (orig == 0)
873         {
874           def->name = loadedName;
875         }
876       else
877         {
878           jstring msg = JvNewStringUTF ("anonymous "
879                                         "class data denotes "
880                                         "existing class ");
881           msg = msg->concat (orig->getName ());
882
883           throw_no_class_def_found_error (msg);
884         }
885     }
886
887   // assert that the loaded class has the expected name, 5.3.5
888   else if (! _Jv_equalUtf8Consts (loadedName, def->name))
889     {
890       jstring msg = JvNewStringUTF ("loaded class ");
891       msg = msg->concat (def->getName ());
892       msg = msg->concat (_Jv_NewStringUTF (" was in fact named "));
893       jstring klass_name = loadedName->toString();
894       msg = msg->concat (klass_name);
895
896       throw_no_class_def_found_error (msg);
897     }
898
899   def->accflags = access_flags | java::lang::reflect::Modifier::INTERPRETED;
900   pool_data[this_class].clazz = def;
901   pool_tags[this_class] = JV_CONSTANT_ResolvedClass;
902
903   if (super_class == 0 && ! (access_flags & Modifier::INTERFACE))
904     {
905       // FIXME: Consider this carefully!  
906       if (! _Jv_equalUtf8Consts (def->name, java::lang::Object::class$.name))
907         throw_no_class_def_found_error ("loading java.lang.Object");
908     }
909
910   // In the pre-loading state, it can be looked up in the
911   // cache only by this thread!  This allows the super-class
912   // to include references to this class.
913
914   def->state = JV_STATE_PRELOADING;
915
916   {
917     JvSynchronize sync (&java::lang::Class::class$);
918     _Jv_RegisterClass (def);
919   }
920
921   if (super_class != 0)
922     {
923       // Load the superclass.
924       check_tag (super_class, JV_CONSTANT_Class);
925       _Jv_Utf8Const* super_name = pool_data[super_class].utf8; 
926
927       // Load the superclass using our defining loader.
928       jclass the_super = _Jv_FindClass (super_name,
929                                         def->loader);
930
931       // This will establish that we are allowed to be a subclass,
932       // and check for class circularity error.
933       checkExtends (def, the_super);
934
935       // Note: for an interface we will find Object as the
936       // superclass.  We still check it above to ensure class file
937       // validity, but we simply assign `null' to the actual field in
938       // this case.
939       def->superclass = (((access_flags & Modifier::INTERFACE))
940                          ? NULL : the_super);
941       pool_data[super_class].clazz = the_super;
942       pool_tags[super_class] = JV_CONSTANT_ResolvedClass;
943     }
944
945   // Now we've come past the circularity problem, we can 
946   // now say that we're loading.
947
948   def->state = JV_STATE_LOADING;
949   def->notifyAll ();
950 }
951
952 ///// implements the checks described in sect. 5.3.5.3
953 void
954 _Jv_ClassReader::checkExtends (jclass sub, jclass super)
955 {
956   using namespace java::lang::reflect;
957
958   // having an interface or a final class as a superclass is no good
959   if ((super->accflags & (Modifier::INTERFACE | Modifier::FINAL)) != 0)
960     {
961       throw_incompatible_class_change_error (sub->getName ());
962     }
963
964   // if the super class is not public, we need to check some more
965   if ((super->accflags & Modifier::PUBLIC) == 0)
966     {
967       // With package scope, the classes must have the same
968       // class loader.
969       if (   sub->loader != super->loader
970           || !_Jv_ClassNameSamePackage (sub->name, super->name))
971         {
972           throw_incompatible_class_change_error (sub->getName ());
973         }
974     } 
975
976   for (; super != 0; super = super->superclass)
977     {
978       if (super == sub)
979         throw_class_circularity_error (sub->getName ());
980     }
981 }
982
983
984
985 void _Jv_ClassReader::handleInterfacesBegin (int count)
986 {
987   def->interfaces = (jclass*) _Jv_AllocBytes (count*sizeof (jclass));
988   def->interface_count = count;
989 }
990
991 void _Jv_ClassReader::handleInterface (int if_number, int offset)
992 {
993   _Jv_word       * pool_data = def->constants.data;
994   unsigned char  * pool_tags = (unsigned char*) def->constants.tags;
995
996   jclass the_interface;
997
998   if (pool_tags[offset] == JV_CONSTANT_Class)
999     {
1000       _Jv_Utf8Const* name = pool_data[offset].utf8;
1001       the_interface =  _Jv_FindClass (name, def->loader);
1002     }
1003   else if (pool_tags[offset] == JV_CONSTANT_ResolvedClass)
1004     {
1005       the_interface = pool_data[offset].clazz;
1006     }
1007   else
1008     {
1009       throw_no_class_def_found_error ("erroneous constant pool tag");
1010     }
1011
1012   // checks the validity of the_interface, and that we are in fact
1013   // allowed to implement that interface.
1014   checkImplements (def, the_interface);
1015   
1016   pool_data[offset].clazz = the_interface;
1017   pool_tags[offset] = JV_CONSTANT_ResolvedClass;
1018   
1019   def->interfaces[if_number] = the_interface;
1020 }
1021
1022 void
1023 _Jv_ClassReader::checkImplements (jclass sub, jclass super)
1024 {
1025   using namespace java::lang::reflect;
1026
1027   // well, it *must* be an interface
1028   if ((super->accflags & Modifier::INTERFACE) == 0)
1029     {
1030       throw_incompatible_class_change_error (sub->getName ());
1031     }
1032
1033   // if it has package scope, it must also be defined by the 
1034   // same loader.
1035   if ((super->accflags & Modifier::PUBLIC) == 0)
1036     {
1037       if (    sub->loader != super->loader
1038           || !_Jv_ClassNameSamePackage (sub->name, super->name))
1039         {
1040           throw_incompatible_class_change_error (sub->getName ());
1041         }
1042     } 
1043
1044   // FIXME: add interface circularity check here
1045   if (sub == super)
1046     {
1047       throw_class_circularity_error (sub->getName ());
1048     }           
1049 }
1050
1051 void _Jv_ClassReader::handleFieldsBegin (int count)
1052 {
1053   def->fields = (_Jv_Field*) 
1054     _Jv_AllocBytes (count * sizeof (_Jv_Field));
1055   def->field_count = count;
1056   def_interp->field_initializers = (_Jv_ushort*)
1057     _Jv_AllocBytes (count * sizeof (_Jv_ushort));
1058   for (int i = 0; i < count; i++)
1059     def_interp->field_initializers[i] = (_Jv_ushort) 0;
1060 }
1061
1062 void _Jv_ClassReader::handleField (int field_no,
1063                                    int flags,
1064                                    int name,
1065                                    int desc)
1066 {
1067   using namespace java::lang::reflect;
1068
1069   _Jv_word *pool_data = def->constants.data;
1070
1071   _Jv_Field *field = &def->fields[field_no];
1072   _Jv_Utf8Const *field_name = pool_data[name].utf8;
1073
1074 #ifndef COMPACT_FIELDS
1075   field->name      = field_name;
1076 #else
1077   field->nameIndex = name;
1078 #endif
1079
1080   // Ignore flags we don't know about.  
1081   field->flags = flags & Modifier::ALL_FLAGS;
1082
1083   _Jv_Utf8Const* sig = pool_data[desc].utf8;
1084
1085   if (verify)
1086     {
1087       verify_identifier (field_name);
1088
1089       for (int i = 0; i < field_no; ++i)
1090         {
1091           if (_Jv_equalUtf8Consts (field_name, def->fields[i].name)
1092               && _Jv_equalUtf8Consts (sig,
1093                                       // We know the other fields are
1094                                       // unresolved.
1095                                       (_Jv_Utf8Const *) def->fields[i].type))
1096             throw_class_format_error ("duplicate field name");
1097         }
1098
1099       // At most one of PUBLIC, PRIVATE, or PROTECTED is allowed.
1100       if (1 < ( ((field->flags & Modifier::PUBLIC) ? 1 : 0)
1101                 +((field->flags & Modifier::PRIVATE) ? 1 : 0)
1102                 +((field->flags & Modifier::PROTECTED) ? 1 : 0)))
1103         throw_class_format_error ("erroneous field access flags");
1104
1105       // FIXME: JVM spec S4.5: Verify ACC_FINAL and ACC_VOLATILE are not 
1106       // both set. Verify modifiers for interface fields.
1107       
1108     }
1109
1110   if (verify)
1111     verify_field_signature (sig);
1112
1113   // field->type is really a jclass, but while it is still
1114   // unresolved we keep an _Jv_Utf8Const* instead.
1115   field->type       = (jclass) sig;
1116   field->flags     |= _Jv_FIELD_UNRESOLVED_FLAG;
1117   field->u.boffset  = 0;
1118 }
1119
1120
1121 void _Jv_ClassReader::handleConstantValueAttribute (int field_index, 
1122                                                     int value)
1123 {
1124   using namespace java::lang::reflect;
1125
1126   _Jv_Field *field = &def->fields[field_index];
1127
1128   if ((field->flags & (Modifier::STATIC
1129                        | Modifier::FINAL
1130                        | Modifier::PRIVATE)) == 0)
1131     {
1132       // Ignore, as per vmspec #4.7.2
1133       return;
1134     }
1135
1136   // do not allow multiple constant fields!
1137   if (field->flags & _Jv_FIELD_CONSTANT_VALUE)
1138     throw_class_format_error ("field has multiple ConstantValue attributes");
1139
1140   field->flags |= _Jv_FIELD_CONSTANT_VALUE;
1141   def_interp->field_initializers[field_index] = value;
1142
1143   /* type check the initializer */
1144   
1145   if (value <= 0 || value >= pool_count)
1146     throw_class_format_error ("erroneous ConstantValue attribute");
1147
1148   /* FIXME: do the rest */
1149 }
1150
1151 void _Jv_ClassReader::handleFieldsEnd ()
1152 {
1153   using namespace java::lang::reflect;
1154
1155   // We need to reorganize the fields so that the static ones are first,
1156   // to conform to GCJ class layout.
1157
1158   int low            = 0;
1159   int high           = def->field_count-1;
1160   _Jv_Field  *fields = def->fields;
1161   _Jv_ushort *inits  = def_interp->field_initializers;
1162
1163   // this is kind of a raw version of quicksort.
1164   while (low < high)
1165     {
1166       // go forward on low, while it's a static
1167       while (low < high && (fields[low].flags & Modifier::STATIC) != 0)
1168         low++;
1169       
1170       // go backwards on high, while it's a non-static
1171       while (low < high && (fields[high].flags & Modifier::STATIC) == 0)
1172         high--;
1173
1174       if (low==high)
1175         break;
1176
1177       _Jv_Field  tmp  = fields[low];
1178       _Jv_ushort itmp = inits[low];
1179           
1180       fields[low] = fields[high];
1181       inits[low]  = inits[high];
1182           
1183       fields[high] = tmp;
1184       inits[high]  = itmp;
1185           
1186       high -= 1;
1187       low  += 1;
1188     }
1189   
1190   if ((fields[low].flags & Modifier::STATIC) != 0) 
1191     low += 1;
1192
1193   def->static_field_count = low;
1194 }
1195
1196
1197
1198 void
1199 _Jv_ClassReader::handleMethodsBegin (int count)
1200 {
1201   def->methods = (_Jv_Method *) _Jv_AllocBytes (sizeof (_Jv_Method) * count);
1202
1203   def_interp->interpreted_methods
1204     = (_Jv_MethodBase **) _Jv_AllocBytes (sizeof (_Jv_MethodBase *)
1205                                           * count);
1206
1207   for (int i = 0; i < count; i++)
1208     {
1209       def_interp->interpreted_methods[i] = 0;
1210       def->methods[i].index = (_Jv_ushort) -1;
1211     }
1212
1213   def->method_count = count;
1214 }
1215
1216
1217 void _Jv_ClassReader::handleMethod 
1218     (int mth_index, int accflags, int name, int desc)
1219
1220   using namespace java::lang::reflect;
1221
1222   _Jv_word *pool_data = def->constants.data;
1223   _Jv_Method *method = &def->methods[mth_index];
1224
1225   check_tag (name, JV_CONSTANT_Utf8);
1226   prepare_pool_entry (name, JV_CONSTANT_Utf8);
1227   method->name = pool_data[name].utf8;
1228
1229   check_tag (desc, JV_CONSTANT_Utf8);
1230   prepare_pool_entry (desc, JV_CONSTANT_Utf8);
1231   method->signature = pool_data[desc].utf8;
1232
1233   // ignore unknown flags
1234   method->accflags = accflags & Modifier::ALL_FLAGS;
1235
1236   // intialize...
1237   method->ncode = 0;
1238   method->throws = NULL;
1239   
1240   if (verify)
1241     {
1242       if (_Jv_equalUtf8Consts (method->name, clinit_name)
1243           || _Jv_equalUtf8Consts (method->name, init_name))
1244         /* ignore */;
1245       else
1246         verify_identifier (method->name);
1247
1248       verify_method_signature (method->signature);
1249
1250       for (int i = 0; i < mth_index; ++i)
1251         {
1252           if (_Jv_equalUtf8Consts (method->name, def->methods[i].name)
1253               && _Jv_equalUtf8Consts (method->signature,
1254                                       def->methods[i].signature))
1255             throw_class_format_error ("duplicate method");
1256         }
1257
1258       // At most one of PUBLIC, PRIVATE, or PROTECTED is allowed.
1259       if (1 < ( ((method->accflags & Modifier::PUBLIC) ? 1 : 0)
1260                 +((method->accflags & Modifier::PRIVATE) ? 1 : 0)
1261                 +((method->accflags & Modifier::PROTECTED) ? 1 : 0)))
1262         throw_class_format_error ("erroneous method access flags");
1263
1264       // FIXME: JVM spec S4.6: if ABSTRACT modifier is set, verify other 
1265       // flags are not set. Verify flags for interface methods. Verifiy
1266       // modifiers for initializers. 
1267     }
1268 }
1269
1270 void _Jv_ClassReader::handleCodeAttribute
1271   (int method_index, int max_stack, int max_locals, 
1272    int code_start, int code_length, int exc_table_length)
1273 {
1274   int size = _Jv_InterpMethod::size (exc_table_length, code_length);
1275   _Jv_InterpMethod *method = 
1276     (_Jv_InterpMethod*) (_Jv_AllocBytes (size));
1277
1278   method->deferred       = NULL;
1279   method->max_stack      = max_stack;
1280   method->max_locals     = max_locals;
1281   method->code_length    = code_length;
1282   method->exc_count      = exc_table_length;
1283   method->defining_class = def;
1284   method->self           = &def->methods[method_index];
1285   method->prepared       = NULL;
1286
1287   // grab the byte code!
1288   memcpy ((void*) method->bytecode (),
1289           (void*) (bytes+code_start),
1290           code_length);
1291
1292   def_interp->interpreted_methods[method_index] = method;
1293
1294   if ((method->self->accflags & java::lang::reflect::Modifier::STATIC))
1295     {
1296       // Precompute the ncode field for a static method.  This lets us
1297       // call a static method of an interpreted class from precompiled
1298       // code without first resolving the class (that will happen
1299       // during class initialization instead).
1300       method->self->ncode = method->ncode ();
1301     }
1302 }
1303
1304 void _Jv_ClassReader::handleExceptionTableEntry
1305   (int method_index, int exc_index, 
1306    int start_pc, int end_pc, int handler_pc, int catch_type)
1307 {
1308   _Jv_InterpMethod *method = reinterpret_cast<_Jv_InterpMethod *>
1309     (def_interp->interpreted_methods[method_index]);
1310   _Jv_InterpException *exc = method->exceptions ();
1311
1312   exc[exc_index].start_pc.i     = start_pc;
1313   exc[exc_index].end_pc.i       = end_pc;
1314   exc[exc_index].handler_pc.i   = handler_pc;
1315   exc[exc_index].handler_type.i = catch_type;
1316 }
1317
1318 void _Jv_ClassReader::handleMethodsEnd ()
1319 {
1320   using namespace java::lang::reflect;
1321
1322   for (int i = 0; i < def->method_count; i++)
1323     {
1324       _Jv_Method *method = &def->methods[i];
1325       if ((method->accflags & Modifier::NATIVE) != 0)
1326         {
1327           if (def_interp->interpreted_methods[i] != 0)
1328             throw_class_format_error ("code provided for native method");
1329           else
1330             {
1331               _Jv_JNIMethod *m = (_Jv_JNIMethod *)
1332                 _Jv_AllocBytes (sizeof (_Jv_JNIMethod));
1333               m->defining_class = def;
1334               m->self = method;
1335               m->function = NULL;
1336               def_interp->interpreted_methods[i] = m;
1337               m->deferred = NULL;
1338
1339               if ((method->accflags & Modifier::STATIC))
1340                 {
1341                   // Precompute the ncode field for a static method.
1342                   // This lets us call a static method of an
1343                   // interpreted class from precompiled code without
1344                   // first resolving the class (that will happen
1345                   // during class initialization instead).
1346                   method->ncode = m->ncode ();
1347                 }
1348             }
1349         }
1350       else if ((method->accflags & Modifier::ABSTRACT) != 0)
1351         {
1352           if (def_interp->interpreted_methods[i] != 0)
1353             throw_class_format_error ("code provided for abstract method");
1354         }
1355       else
1356         {
1357           if (def_interp->interpreted_methods[i] == 0)
1358             throw_class_format_error ("method with no code");
1359         }
1360     }
1361 }
1362
1363 void _Jv_ClassReader::throw_class_format_error (char *msg)
1364 {
1365   jstring str;
1366   if (def->name != NULL)
1367     {
1368       jsize mlen = strlen (msg);
1369       unsigned char* data = (unsigned char*) def->name->chars();
1370       int ulen = def->name->len();
1371       unsigned char* limit = data + ulen;
1372       jsize nlen = _Jv_strLengthUtf8 ((char *) data, ulen);
1373       jsize len = nlen + mlen + 3;
1374       str = JvAllocString(len);
1375       jchar *chrs = JvGetStringChars(str);
1376       while (data < limit)
1377         *chrs++ = UTF8_GET(data, limit);
1378       *chrs++ = ' ';
1379       *chrs++ = '(';
1380       for (;;)
1381         {
1382           char c = *msg++;
1383           if (c == 0)
1384             break;
1385           *chrs++ = c & 0xFFFF;
1386         }
1387       *chrs++ = ')';
1388     }
1389   else
1390     str = JvNewStringLatin1 (msg);
1391   ::throw_class_format_error (str);
1392 }
1393 \f
1394 /** Here we define the exceptions that can be thrown */
1395
1396 static void
1397 throw_no_class_def_found_error (jstring msg)
1398 {
1399   throw (msg
1400          ? new java::lang::NoClassDefFoundError (msg)
1401          : new java::lang::NoClassDefFoundError);
1402 }
1403
1404 static void
1405 throw_no_class_def_found_error (char *msg)
1406 {
1407   throw_no_class_def_found_error (JvNewStringLatin1 (msg));
1408 }
1409
1410 static void
1411 throw_class_format_error (jstring msg)
1412 {
1413   throw (msg
1414          ? new java::lang::ClassFormatError (msg)
1415          : new java::lang::ClassFormatError);
1416 }
1417
1418 static void
1419 throw_internal_error (char *msg)
1420 {
1421   throw new java::lang::InternalError (JvNewStringLatin1 (msg));
1422 }
1423
1424 static void
1425 throw_incompatible_class_change_error (jstring msg)
1426 {
1427   throw new java::lang::IncompatibleClassChangeError (msg);
1428 }
1429
1430 static void
1431 throw_class_circularity_error (jstring msg)
1432 {
1433   throw new java::lang::ClassCircularityError (msg);
1434 }
1435
1436 #endif /* INTERPRETER */
1437
1438 \f
1439
1440 /** This section takes care of verifying integrity of identifiers,
1441     signatures, field ddescriptors, and class names */
1442
1443 #define UTF8_PEEK(PTR, LIMIT) \
1444   ({ unsigned char* xxkeep = (PTR); \
1445      int xxch = UTF8_GET(PTR,LIMIT); \
1446      PTR = xxkeep; xxch; })
1447
1448 /* Verify one element of a type descriptor or signature.  */
1449 static unsigned char*
1450 _Jv_VerifyOne (unsigned char* ptr, unsigned char* limit, bool void_ok)
1451 {
1452   if (ptr >= limit)
1453     return 0;
1454
1455   int ch = UTF8_GET (ptr, limit);
1456
1457   switch (ch)
1458     {
1459     case 'V':
1460       if (! void_ok)
1461         return 0;
1462
1463     case 'S': case 'B': case 'I': case 'J':
1464     case 'Z': case 'C': case 'F': case 'D': 
1465       break;
1466
1467     case 'L':
1468       {
1469         unsigned char *start = ptr, *end;
1470         do
1471           {
1472             if (ptr > limit)
1473               return 0;
1474
1475             end = ptr;
1476
1477             if ((ch = UTF8_GET (ptr, limit)) == -1)
1478               return 0;
1479
1480           }
1481         while (ch != ';');
1482         if (! _Jv_VerifyClassName (start, (unsigned short) (end-start)))
1483           return 0;
1484       }
1485       break;
1486
1487     case '[':
1488       return _Jv_VerifyOne (ptr, limit, false);
1489       break;
1490
1491     default:
1492       return 0;
1493     }
1494
1495   return ptr;
1496 }
1497
1498 /* Verification and loading procedures.  */
1499 bool
1500 _Jv_VerifyFieldSignature (_Jv_Utf8Const*sig)
1501 {
1502   unsigned char* ptr = (unsigned char*) sig->chars();
1503   unsigned char* limit = ptr + sig->len();
1504
1505   ptr = _Jv_VerifyOne (ptr, limit, false);
1506
1507   return ptr == limit;
1508 }
1509
1510 bool
1511 _Jv_VerifyMethodSignature (_Jv_Utf8Const*sig)
1512 {
1513   unsigned char* ptr = (unsigned char*) sig->chars();
1514   unsigned char* limit = ptr + sig->len();
1515
1516   if (ptr == limit || UTF8_GET(ptr,limit) != '(')
1517     return false;
1518
1519   while (ptr && UTF8_PEEK (ptr, limit) != ')')
1520     ptr = _Jv_VerifyOne (ptr, limit, false);
1521
1522   if (UTF8_GET (ptr, limit) != ')')
1523     return false;
1524
1525   // get the return type
1526   ptr = _Jv_VerifyOne (ptr, limit, true);
1527
1528   return ptr == limit;
1529 }
1530
1531 /* We try to avoid calling the Character methods all the time, in
1532    fact, they will only be called for non-standard things. */
1533 static __inline__ int 
1534 is_identifier_start (int c)
1535 {
1536   unsigned int ch = (unsigned)c;
1537
1538   if ((ch - 0x41U) < 29U)               /* A ... Z */
1539     return 1;
1540   if ((ch - 0x61U) < 29U)               /* a ... z */
1541     return 1;
1542   if (ch == 0x5FU)                      /* _ */
1543     return 1;
1544
1545   return java::lang::Character::isJavaIdentifierStart ((jchar) ch);
1546 }
1547
1548 static __inline__ int 
1549 is_identifier_part (int c)
1550 {
1551   unsigned int ch = (unsigned)c;
1552
1553   if ((ch - 0x41U) < 29U)               /* A ... Z */
1554     return 1;
1555   if ((ch - 0x61U) < 29U)               /* a ... z */
1556     return 1;
1557   if ((ch - 0x30) < 10U)                /* 0 .. 9 */
1558     return 1;
1559   if (ch == 0x5FU || ch == 0x24U)       /* _ $ */
1560     return 1;
1561
1562   return java::lang::Character::isJavaIdentifierStart ((jchar) ch);
1563 }
1564
1565 bool
1566 _Jv_VerifyIdentifier (_Jv_Utf8Const* name)
1567 {
1568   unsigned char *ptr   = (unsigned char*) name->chars();
1569   unsigned char *limit = (unsigned char*) name->limit();
1570   int ch;
1571
1572   if ((ch = UTF8_GET (ptr, limit))==-1
1573       || ! is_identifier_start (ch))
1574     return false;
1575
1576   while (ptr != limit)
1577     {
1578       if ((ch = UTF8_GET (ptr, limit))==-1
1579           || ! is_identifier_part (ch))
1580         return false;
1581     }
1582   return true;
1583 }
1584
1585 bool
1586 _Jv_VerifyClassName (unsigned char* ptr, _Jv_ushort length)
1587 {
1588   unsigned char *limit = ptr+length;
1589   int ch;
1590
1591   if ('[' == UTF8_PEEK (ptr, limit))
1592     {
1593       unsigned char *end = _Jv_VerifyOne (++ptr, limit, false);
1594       // _Jv_VerifyOne must leave us looking at the terminating nul
1595       // byte.
1596       if (! end || *end)
1597         return false;
1598       else
1599         return true;
1600     }
1601
1602  next_level:
1603   for (;;) {
1604     if ((ch = UTF8_GET (ptr, limit))==-1)
1605       return false;
1606     if (! is_identifier_start (ch))
1607       return false;
1608     for (;;) {
1609       if (ptr == limit)
1610         return true;
1611       else if ((ch = UTF8_GET (ptr, limit))==-1)
1612         return false;
1613       else if (ch == '.')
1614         goto next_level;
1615       else if (! is_identifier_part (ch))
1616         return false;
1617     }
1618   }
1619 }
1620
1621 bool
1622 _Jv_VerifyClassName (_Jv_Utf8Const *name)
1623 {
1624   return _Jv_VerifyClassName ((unsigned char*)name->chars(), name->len());
1625 }
1626
1627 /* Returns true, if NAME1 and NAME2 represent classes in the same
1628    package.  */
1629 bool
1630 _Jv_ClassNameSamePackage (_Jv_Utf8Const *name1, _Jv_Utf8Const *name2)
1631 {
1632   unsigned char* ptr1 = (unsigned char*) name1->chars();
1633   unsigned char* limit1 = (unsigned char*) name1->limit();
1634
1635   unsigned char* last1 = ptr1;
1636
1637   // scan name1, and find the last occurrence of '.'
1638   while (ptr1 < limit1) {
1639     int ch1 = UTF8_GET (ptr1, limit1);
1640
1641     if (ch1 == '.')
1642       last1 = ptr1;
1643
1644     else if (ch1 == -1)
1645       return false;
1646   }
1647
1648   // Now the length of NAME1's package name is LEN.
1649   int len = last1 - (unsigned char*) name1->chars();
1650
1651   // If this is longer than NAME2, then we're off.
1652   if (len > name2->len())
1653     return false;
1654
1655   // Then compare the first len bytes for equality.
1656   if (memcmp ((void*) name1->chars(), (void*) name2->chars(), len) == 0)
1657     {
1658       // Check that there are no .'s after position LEN in NAME2.
1659
1660       unsigned char* ptr2 = (unsigned char*) name2->chars() + len;
1661       unsigned char* limit2 = (unsigned char*) name2->limit();
1662
1663       while (ptr2 < limit2)
1664         {
1665           int ch2 = UTF8_GET (ptr2, limit2);
1666           if (ch2 == -1 || ch2 == '.')
1667             return false;
1668         }
1669       return true;
1670     }
1671   return false;
1672 }