OSDN Git Service

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