OSDN Git Service

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