OSDN Git Service

* defineclass.cc (handleMethodsEnd): Invoke verifier here...
[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
1287 void _Jv_ClassReader::handleExceptionTableEntry 
1288   (int method_index, int exc_index, 
1289    int start_pc, int end_pc, int handler_pc, int catch_type)
1290 {
1291   _Jv_InterpMethod *method = reinterpret_cast<_Jv_InterpMethod *>
1292     (def->interpreted_methods[method_index]);
1293   _Jv_InterpException *exc = method->exceptions ();
1294
1295   exc[exc_index].start_pc     = start_pc;
1296   exc[exc_index].end_pc       = end_pc;
1297   exc[exc_index].handler_pc   = handler_pc;
1298   exc[exc_index].handler_type = catch_type;
1299 }
1300
1301 void _Jv_ClassReader::handleMethodsEnd ()
1302 {
1303   using namespace java::lang::reflect;
1304
1305   for (int i = 0; i < def->method_count; i++)
1306     {
1307       _Jv_Method *method = &def->methods[i];
1308       if ((method->accflags & Modifier::NATIVE) != 0)
1309         {
1310           if (def->interpreted_methods[i] != 0)
1311             throw_class_format_error ("code provided for native method");
1312           else
1313             {
1314               _Jv_JNIMethod *m = (_Jv_JNIMethod *)
1315                 _Jv_AllocBytes (sizeof (_Jv_JNIMethod));
1316               m->defining_class = def;
1317               m->self = method;
1318               m->function = NULL;
1319               def->interpreted_methods[i] = m;
1320             }
1321         }
1322       else if ((method->accflags & Modifier::ABSTRACT) != 0)
1323         {
1324           if (def->interpreted_methods[i] != 0)
1325             throw_class_format_error ("code provided for abstract method");
1326         }
1327       else
1328         {
1329           if (def->interpreted_methods[i] == 0)
1330             throw_class_format_error ("method with no code");
1331
1332           if (verify)
1333             {
1334               _Jv_InterpMethod *m;
1335               m = (reinterpret_cast<_Jv_InterpMethod *>
1336                    (def->interpreted_methods[i]));
1337               // FIXME: enable once verifier is more fully tested.
1338               // _Jv_VerifyMethod (m);
1339             }
1340         }
1341     }
1342 }
1343
1344 void _Jv_ClassReader::throw_class_format_error (char *msg)
1345 {
1346   jstring str;
1347   if (def->name != NULL)
1348     {
1349       jsize mlen = strlen (msg);
1350       unsigned char* data = (unsigned char*) def->name->data;
1351       int ulen = def->name->length;
1352       unsigned char* limit = data + ulen;
1353       jsize nlen = _Jv_strLengthUtf8 ((char *) data, ulen);
1354       jsize len = nlen + mlen + 3;
1355       str = JvAllocString(len);
1356       jchar *chrs = JvGetStringChars(str);
1357       while (data < limit)
1358         *chrs++ = UTF8_GET(data, limit);
1359       *chrs++ = ' ';
1360       *chrs++ = '(';
1361       for (;;)
1362         {
1363           char c = *msg++;
1364           if (c == 0)
1365             break;
1366           *chrs++ = c & 0xFFFF;
1367         }
1368       *chrs++ = ')';
1369     }
1370   else
1371     str = JvNewStringLatin1 (msg);
1372   ::throw_class_format_error (str);
1373 }
1374 \f
1375 /** Here we define the exceptions that can be thrown */
1376
1377 static void
1378 throw_no_class_def_found_error (jstring msg)
1379 {
1380   throw (msg
1381          ? new java::lang::NoClassDefFoundError (msg)
1382          : new java::lang::NoClassDefFoundError);
1383 }
1384
1385 static void
1386 throw_no_class_def_found_error (char *msg)
1387 {
1388   throw_no_class_def_found_error (JvNewStringLatin1 (msg));
1389 }
1390
1391 static void
1392 throw_class_format_error (jstring msg)
1393 {
1394   throw (msg
1395          ? new java::lang::ClassFormatError (msg)
1396          : new java::lang::ClassFormatError);
1397 }
1398
1399 static void
1400 throw_internal_error (char *msg)
1401 {
1402   throw new java::lang::InternalError (JvNewStringLatin1 (msg));
1403 }
1404
1405 static void throw_incompatible_class_change_error (jstring msg)
1406 {
1407   throw new java::lang::IncompatibleClassChangeError (msg);
1408 }
1409
1410 static void throw_class_circularity_error (jstring msg)
1411 {
1412   throw new java::lang::ClassCircularityError (msg);
1413 }
1414
1415 #endif /* INTERPRETER */
1416
1417 \f
1418
1419 /** This section takes care of verifying integrity of identifiers,
1420     signatures, field ddescriptors, and class names */
1421
1422 #define UTF8_PEEK(PTR, LIMIT) \
1423   ({ unsigned char* xxkeep = (PTR); \
1424      int xxch = UTF8_GET(PTR,LIMIT); \
1425      PTR = xxkeep; xxch; })
1426
1427 /* Verify one element of a type descriptor or signature.  */
1428 static unsigned char*
1429 _Jv_VerifyOne (unsigned char* ptr, unsigned char* limit, bool void_ok)
1430 {
1431   if (ptr >= limit)
1432     return 0;
1433
1434   int ch = UTF8_GET (ptr, limit);
1435
1436   switch (ch)
1437     {
1438     case 'V':
1439       if (! void_ok)
1440         return 0;
1441
1442     case 'S': case 'B': case 'I': case 'J':
1443     case 'Z': case 'C': case 'F': case 'D': 
1444       break;
1445
1446     case 'L':
1447       {
1448         unsigned char *start = ptr, *end;
1449         do
1450           {
1451             if (ptr > limit)
1452               return 0;
1453
1454             end = ptr;
1455
1456             if ((ch = UTF8_GET (ptr, limit)) == -1)
1457               return 0;
1458
1459           }
1460         while (ch != ';');
1461         if (! _Jv_VerifyClassName (start, (unsigned short) (end-start)))
1462           return 0;
1463       }
1464       break;
1465
1466     case '[':
1467       return _Jv_VerifyOne (ptr, limit, false);
1468       break;
1469
1470     default:
1471       return 0;
1472     }
1473
1474   return ptr;
1475 }
1476
1477 /* Verification and loading procedures.  */
1478 bool
1479 _Jv_VerifyFieldSignature (_Jv_Utf8Const*sig)
1480 {
1481   unsigned char* ptr = (unsigned char*) sig->data;
1482   unsigned char* limit = ptr + sig->length;
1483
1484   ptr = _Jv_VerifyOne (ptr, limit, false);
1485
1486   return ptr == limit;
1487 }
1488
1489 bool
1490 _Jv_VerifyMethodSignature (_Jv_Utf8Const*sig)
1491 {
1492   unsigned char* ptr = (unsigned char*) sig->data;
1493   unsigned char* limit = ptr + sig->length;
1494
1495   if (ptr == limit || UTF8_GET(ptr,limit) != '(')
1496     return false;
1497
1498   while (ptr && UTF8_PEEK (ptr, limit) != ')')
1499     ptr = _Jv_VerifyOne (ptr, limit, false);
1500
1501   if (UTF8_GET (ptr, limit) != ')')
1502     return false;
1503
1504   // get the return type
1505   ptr = _Jv_VerifyOne (ptr, limit, true);
1506
1507   return ptr == limit;
1508 }
1509
1510 /* We try to avoid calling the Character methods all the time, in
1511    fact, they will only be called for non-standard things. */
1512 static __inline__ int 
1513 is_identifier_start (int c)
1514 {
1515   unsigned int ch = (unsigned)c;
1516
1517   if ((ch - 0x41U) < 29U)               /* A ... Z */
1518     return 1;
1519   if ((ch - 0x61U) < 29U)               /* a ... z */
1520     return 1;
1521   if (ch == 0x5FU)                      /* _ */
1522     return 1;
1523
1524   return character->isJavaIdentifierStart ((jchar) ch);
1525 }
1526
1527 static __inline__ int 
1528 is_identifier_part (int c)
1529 {
1530   unsigned int ch = (unsigned)c;
1531
1532   if ((ch - 0x41U) < 29U)               /* A ... Z */
1533     return 1;
1534   if ((ch - 0x61U) < 29U)               /* a ... z */
1535     return 1;
1536   if ((ch - 0x30) < 10U)                /* 0 .. 9 */
1537     return 1;
1538   if (ch == 0x5FU || ch == 0x24U)       /* _ $ */
1539     return 1;
1540
1541   return character->isJavaIdentifierStart ((jchar) ch);
1542 }
1543
1544 bool
1545 _Jv_VerifyIdentifier (_Jv_Utf8Const* name)
1546 {
1547   unsigned char *ptr   = (unsigned char*) name->data;
1548   unsigned char *limit = ptr + name->length;
1549   int ch;
1550
1551   if ((ch = UTF8_GET (ptr, limit))==-1
1552       || ! is_identifier_start (ch))
1553     return false;
1554
1555   while (ptr != limit)
1556     {
1557       if ((ch = UTF8_GET (ptr, limit))==-1
1558           || ! is_identifier_part (ch))
1559         return false;
1560     }
1561   return true;
1562 }
1563
1564 bool
1565 _Jv_VerifyClassName (unsigned char* ptr, _Jv_ushort length)
1566 {
1567   unsigned char *limit = ptr+length;
1568   int ch;
1569
1570   if ('[' == UTF8_PEEK (ptr, limit))
1571     {
1572       unsigned char *end = _Jv_VerifyOne (++ptr, limit, false);
1573       // _Jv_VerifyOne must leave us looking at the terminating nul
1574       // byte.
1575       if (! end || *end)
1576         return false;
1577       else
1578         return true;
1579     }
1580
1581  next_level:
1582   for (;;) {
1583     if ((ch = UTF8_GET (ptr, limit))==-1)
1584       return false;
1585     if (! is_identifier_start (ch))
1586       return false;
1587     for (;;) {
1588       if (ptr == limit)
1589         return true;
1590       else if ((ch = UTF8_GET (ptr, limit))==-1)
1591         return false;
1592       else if (ch == '.')
1593         goto next_level;
1594       else if (! is_identifier_part (ch))
1595         return false;
1596     }
1597   }
1598 }
1599
1600 bool
1601 _Jv_VerifyClassName (_Jv_Utf8Const *name)
1602 {
1603   return _Jv_VerifyClassName ((unsigned char*)&name->data[0],
1604                               (_Jv_ushort) name->length);
1605 }
1606
1607 /* Returns true, if NAME1 and NAME2 represent classes in the same
1608    package.  */
1609 bool
1610 _Jv_ClassNameSamePackage (_Jv_Utf8Const *name1, _Jv_Utf8Const *name2)
1611 {
1612   unsigned char* ptr1 = (unsigned char*) name1->data;
1613   unsigned char* limit1 = ptr1 + name1->length;
1614
1615   unsigned char* last1 = ptr1;
1616
1617   // scan name1, and find the last occurrence of '.'
1618   while (ptr1 < limit1) {
1619     int ch1 = UTF8_GET (ptr1, limit1);
1620
1621     if (ch1 == '.')
1622       last1 = ptr1;
1623
1624     else if (ch1 == -1)
1625       return false;
1626   }
1627
1628   // Now the length of NAME1's package name is LEN.
1629   int len = last1 - (unsigned char*) name1->data;
1630
1631   // If this is longer than NAME2, then we're off.
1632   if (len > name2->length)
1633     return false;
1634
1635   // Then compare the first len bytes for equality.
1636   if (memcmp ((void*) name1->data, (void*) name2->data, len) == 0)
1637     {
1638       // Check that there are no .'s after position LEN in NAME2.
1639
1640       unsigned char* ptr2 = (unsigned char*) name2->data + len;
1641       unsigned char* limit2 =
1642         (unsigned char*) name2->data + name2->length;
1643
1644       while (ptr2 < limit2)
1645         {
1646           int ch2 = UTF8_GET (ptr2, limit2);
1647           if (ch2 == -1 || ch2 == '.')
1648             return false;
1649         }
1650       return true;
1651     }
1652   return false;
1653 }