OSDN Git Service

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