OSDN Git Service

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