OSDN Git Service

* gcc.dg/overflow-warn-1.c, gcc.dg/overflow-warn-2.c,
[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, 2004, 2005  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 <stdio.h>
27 #include <java-cpool.h>
28 #include <gcj/cni.h>
29 #include <execution.h>
30
31 #include <java/lang/Class.h>
32 #include <java/lang/Float.h>
33 #include <java/lang/Double.h>
34 #include <java/lang/Character.h>
35 #include <java/lang/LinkageError.h>
36 #include <java/lang/InternalError.h>
37 #include <java/lang/ClassFormatError.h>
38 #include <java/lang/NoClassDefFoundError.h>
39 #include <java/lang/ClassCircularityError.h>
40 #include <java/lang/IncompatibleClassChangeError.h>
41 #include <java/lang/reflect/Modifier.h>
42 #include <java/security/ProtectionDomain.h>
43
44 using namespace gcj;
45
46 #ifdef INTERPRETER
47
48 // these go in some separate functions, to avoid having _Jv_InitClass
49 // inserted all over the place.
50 static void throw_internal_error (char *msg)
51         __attribute__ ((__noreturn__));
52 static void throw_no_class_def_found_error (jstring msg)
53         __attribute__ ((__noreturn__));
54 static void throw_no_class_def_found_error (char *msg)
55         __attribute__ ((__noreturn__));
56 static void throw_class_format_error (jstring msg)
57         __attribute__ ((__noreturn__));
58 static void throw_incompatible_class_change_error (jstring msg)
59         __attribute__ ((__noreturn__));
60 static void throw_class_circularity_error (jstring msg)
61         __attribute__ ((__noreturn__));
62
63 /**
64  * We define class reading using a class.  It is practical, since then
65  * the entire class-reader can be a friend of class Class (it needs to
66  * write all it's different structures); but also because this makes it
67  * easy to make class definition reentrant, and thus two threads can be
68  * defining classes at the same time.   This class (_Jv_ClassReader) is
69  * never exposed outside this file, so we don't have to worry about
70  * public or private members here.
71  */
72
73 struct _Jv_ClassReader {
74
75   // do verification?  Currently, there is no option to disable this.
76   // This flag just controls the verificaiton done by the class loader;
77   // i.e., checking the integrity of the constant pool; and it is
78   // allways on.  You always want this as far as I can see, but it also
79   // controls weither identifiers and type descriptors/signatures are
80   // verified as legal.  This could be somewhat more expensive since it
81   // will call Character.isJavaIdentifier{Start,Part} for each character
82   // in any identifier (field name or method name) it comes by.  Thus,
83   // it might be useful to turn off this verification for classes that
84   // come from a trusted source.  However, for GCJ, trusted classes are
85   // most likely to be linked in.
86
87   bool verify;
88
89   // input data.
90   unsigned char     *bytes;
91   int                len;
92
93   // current input position
94   int                pos;
95
96   // the constant pool data
97   int pool_count;
98   unsigned char     *tags;
99   unsigned int      *offsets;
100
101   // the class to define (see java-interp.h)
102   jclass           def;
103   
104   // the classes associated interpreter data.
105   _Jv_InterpClass  *def_interp;
106
107   /* check that the given number of input bytes are available */
108   inline void check (int num)
109   {
110     if (pos + num > len)
111       throw_class_format_error ("Premature end of data");
112   }
113
114   /* skip a given number of bytes in input */
115   inline void skip (int num)
116   {
117     check (num);
118     pos += num;
119   }
120   
121   /* read an unsignend 1-byte unit */
122   inline static jint get1u (unsigned char* bytes)
123   {
124     return bytes[0];
125   }
126   
127   /* read an unsigned 1-byte unit */
128   inline jint read1u ()
129   {
130     skip (1);
131     return get1u (bytes+pos-1);
132   }
133   
134   /* read an unsigned 2-byte unit */
135   inline static jint get2u (unsigned char *bytes)
136   {
137     return (((jint)bytes[0]) << 8) | ((jint)bytes[1]);
138   }
139   
140   /* read an unsigned 2-byte unit */
141   inline jint read2u ()
142   {
143     skip (2);  
144     return get2u (bytes+pos-2);
145   }
146   
147   /* read a 4-byte unit */
148   static jint get4 (unsigned char *bytes)
149   {
150     return (((jint)bytes[0]) << 24)
151          | (((jint)bytes[1]) << 16)
152          | (((jint)bytes[2]) << 8)
153          | (((jint)bytes[3]) << 0);
154   }
155
156   /* read a 4-byte unit, (we don't do that quite so often) */
157   inline jint read4 ()
158   {
159     skip (4);  
160     return get4 (bytes+pos-4);
161   }
162
163   /* read a 8-byte unit */
164   static jlong get8 (unsigned char* bytes)
165   {
166     return (((jlong)bytes[0]) << 56)
167          | (((jlong)bytes[1]) << 48)
168          | (((jlong)bytes[2]) << 40)
169          | (((jlong)bytes[3]) << 32) 
170          | (((jlong)bytes[4]) << 24)
171          | (((jlong)bytes[5]) << 16)
172          | (((jlong)bytes[6]) << 8)
173          | (((jlong)bytes[7]) << 0);
174   }
175
176   /* read a 8-byte unit */
177   inline jlong read8 ()
178   {
179     skip (8);  
180     return get8 (bytes+pos-8);
181   }
182
183   inline void check_tag (int index, char expected_tag)
184   {
185     if (index < 0
186         || index > pool_count
187         || tags[index] != expected_tag)
188       throw_class_format_error ("erroneous constant pool tag");
189   }
190
191   inline void verify_identifier (_Jv_Utf8Const* name)
192   {
193     if (! _Jv_VerifyIdentifier (name))
194       throw_class_format_error ("erroneous identifier");
195   }
196
197   inline void verify_classname (unsigned char* ptr, _Jv_ushort length)
198   {
199     if (! _Jv_VerifyClassName (ptr, length))
200       throw_class_format_error ("erroneous class name");
201   }
202
203   inline void verify_classname (_Jv_Utf8Const *name)
204   {
205     if (! _Jv_VerifyClassName (name))
206       throw_class_format_error ("erroneous class name");
207   }
208
209   inline void verify_field_signature (_Jv_Utf8Const *sig)
210   {
211     if (! _Jv_VerifyFieldSignature (sig))
212       throw_class_format_error ("erroneous type descriptor");
213   }
214
215   inline void verify_method_signature (_Jv_Utf8Const *sig)
216   {
217     if (! _Jv_VerifyMethodSignature (sig))
218       throw_class_format_error ("erroneous type descriptor");
219   }
220
221   _Jv_ClassReader (jclass klass, jbyteArray data, jint offset, jint length,
222                    java::security::ProtectionDomain *pd)
223   {
224     if (klass == 0 || length < 0 || offset+length > data->length)
225       throw_internal_error ("arguments to _Jv_DefineClass");
226
227     verify = true;
228     bytes  = (unsigned char*) (elements (data)+offset);
229     len    = length;
230     pos    = 0;
231     def    = klass;
232     def->size_in_bytes = -1;
233     def->vtable_method_count = -1;
234     def->engine = &_Jv_soleInterpreterEngine;
235     def->protectionDomain = pd;
236   }
237
238   /** and here goes the parser members defined out-of-line */
239   void parse ();
240   void read_constpool ();
241   void prepare_pool_entry (int index, unsigned char tag);
242   void read_fields ();
243   void read_methods ();
244   void read_one_class_attribute ();
245   void read_one_method_attribute (int method);
246   void read_one_code_attribute (int method);
247   void read_one_field_attribute (int field);
248   void throw_class_format_error (char *msg);
249
250   /** check an utf8 entry, without creating a Utf8Const object */
251   bool is_attribute_name (int index, char *name);
252
253   /** here goes the class-loader members defined out-of-line */
254   void handleConstantPool ();
255   void handleClassBegin (int, int, int);
256   void handleInterfacesBegin (int);
257   void handleInterface (int, int);
258   void handleFieldsBegin (int);
259   void handleField (int, int, int, int);
260   void handleFieldsEnd ();
261   void handleConstantValueAttribute (int,int);
262   void handleMethodsBegin (int);
263   void handleMethod (int, int, int, int);
264   void handleMethodsEnd ();
265   void handleCodeAttribute (int, int, int, int, int, int);
266   void handleExceptionTableEntry (int, int, int, int, int, int);
267
268   void checkExtends (jclass sub, jclass super);
269   void checkImplements (jclass sub, jclass super);
270
271   /*
272    * FIXME: we should keep a hash table of utf8-strings, since many will
273    * be the same.  It's a little tricky, however, because the hash table
274    * needs to interact gracefully with the garbage collector.  Much
275    * memory is to be saved by this, however!  perhaps the improvement
276    * could be implemented in prims.cc (_Jv_makeUtf8Const), since it
277    * computes the hash value anyway.
278    */
279 };
280
281 void
282 _Jv_DefineClass (jclass klass, jbyteArray data, jint offset, jint length,
283                  java::security::ProtectionDomain *pd)
284 {
285   _Jv_ClassReader reader (klass, data, offset, length, pd);
286   reader.parse();
287
288   /* that's it! */
289 }
290
291 \f
292 /** This section defines the parsing/scanning of the class data */
293
294 void
295 _Jv_ClassReader::parse ()
296 {
297   int magic = read4 ();
298
299   /* FIXME: Decide which range of version numbers to allow */
300
301   /* int minor_version = */ read2u ();
302   /* int major_verson  = */ read2u ();
303
304   if (magic != (int) 0xCAFEBABE)
305     throw_class_format_error ("bad magic number");
306
307   pool_count = read2u ();
308
309   read_constpool ();
310
311   int access_flags = read2u ();
312   int this_class = read2u ();
313   int super_class = read2u ();
314
315   check_tag (this_class, JV_CONSTANT_Class);
316   if (super_class != 0) 
317     check_tag (super_class, JV_CONSTANT_Class);
318
319   handleClassBegin (access_flags, this_class, super_class);
320
321   // Allocate our aux_info here, after the name is set, to fulfill our
322   // contract with the collector interface.
323   def->aux_info = (void *) _Jv_AllocBytes (sizeof (_Jv_InterpClass));
324   def_interp = (_Jv_InterpClass *) def->aux_info;
325
326   int interfaces_count = read2u (); 
327
328   handleInterfacesBegin (interfaces_count);
329
330   for (int i = 0; i < interfaces_count; i++)
331     {
332       int iface = read2u ();
333       check_tag (iface, JV_CONSTANT_Class);
334       handleInterface (i, iface);
335     }
336   
337   read_fields ();
338   read_methods ();
339   
340   int attributes_count = read2u ();
341   
342   for (int i = 0; i < attributes_count; i++)
343     {
344       read_one_class_attribute ();
345     }
346
347   if (pos != len)
348     throw_class_format_error ("unused data before end of file");
349
350   // Tell everyone we're done.
351   def->state = JV_STATE_READ;
352   if (gcj::verbose_class_flag)
353     _Jv_Linker::print_class_loaded (def);
354   def->notifyAll ();
355 }
356
357 void _Jv_ClassReader::read_constpool ()
358 {
359   tags    = (unsigned char*) _Jv_AllocBytes (pool_count);
360   offsets = (unsigned int *) _Jv_AllocBytes (sizeof (int)
361                                                     * pool_count) ;
362
363   /** first, we scan the constant pool, collecting tags and offsets */
364   tags[0]   = JV_CONSTANT_Undefined;
365   offsets[0] = pos;
366   for (int c = 1; c < pool_count; c++)
367     {
368       tags[c]    = read1u ();
369       offsets[c] = pos;
370
371       switch (tags[c])
372         {
373         case JV_CONSTANT_String:
374         case JV_CONSTANT_Class:
375           skip (2);
376           break;
377
378         case JV_CONSTANT_Fieldref:
379         case JV_CONSTANT_Methodref:
380         case JV_CONSTANT_InterfaceMethodref:
381         case JV_CONSTANT_NameAndType:
382         case JV_CONSTANT_Integer:
383         case JV_CONSTANT_Float:
384           skip (4);
385           break;
386
387         case JV_CONSTANT_Double:
388         case JV_CONSTANT_Long:
389           skip (8);
390           tags[++c] = JV_CONSTANT_Undefined;
391           break;
392             
393         case JV_CONSTANT_Utf8:
394           {                 
395             int len = read2u ();
396             skip (len);
397           }
398           break;
399
400         case JV_CONSTANT_Unicode:
401           throw_class_format_error ("unicode not supported");
402           break;
403
404         default:
405           throw_class_format_error ("erroneous constant pool tag");
406         }
407     }
408
409   handleConstantPool ();
410 }
411
412
413 void _Jv_ClassReader::read_fields ()
414 {
415   int fields_count = read2u ();
416   handleFieldsBegin (fields_count);
417
418   for (int i = 0; i < fields_count; i++)
419     {
420       int access_flags     = read2u ();
421       int name_index       = read2u ();
422       int descriptor_index = read2u ();
423       int attributes_count = read2u ();
424
425       check_tag (name_index, JV_CONSTANT_Utf8);
426       prepare_pool_entry (name_index, JV_CONSTANT_Utf8);
427
428       check_tag (descriptor_index, JV_CONSTANT_Utf8);
429       prepare_pool_entry (descriptor_index, JV_CONSTANT_Utf8);
430
431       handleField (i, access_flags, name_index, descriptor_index);
432
433       for (int j = 0; j < attributes_count; j++)
434         {
435           read_one_field_attribute (i);
436         }
437     }
438
439   handleFieldsEnd ();
440 }
441
442 bool
443 _Jv_ClassReader::is_attribute_name (int index, char *name)
444 {
445   check_tag (index, JV_CONSTANT_Utf8);
446   int len = get2u (bytes+offsets[index]);
447   if (len != (int) strlen (name))
448     return false;
449   else
450     return !memcmp (bytes+offsets[index]+2, name, len);
451 }
452
453 void _Jv_ClassReader::read_one_field_attribute (int field_index)
454 {
455   int name = read2u ();
456   int length = read4 ();
457
458   if (is_attribute_name (name, "ConstantValue"))
459     {
460       int cv = read2u ();
461
462       if (cv < pool_count 
463           && cv > 0
464           && (tags[cv] == JV_CONSTANT_Integer
465               || tags[cv] == JV_CONSTANT_Float
466               || tags[cv] == JV_CONSTANT_Long
467               || tags[cv] == JV_CONSTANT_Double
468               || tags[cv] == JV_CONSTANT_String))
469           {
470             handleConstantValueAttribute (field_index, cv);
471           }
472         else
473           {
474             throw_class_format_error ("erroneous ConstantValue attribute");
475           }
476
477         if (length != 2) 
478           throw_class_format_error ("erroneous ConstantValue attribute");
479       }
480
481     else
482       {
483         skip (length);
484       }
485 }
486
487 void _Jv_ClassReader::read_methods ()
488 {
489   int methods_count = read2u ();
490   
491   handleMethodsBegin (methods_count);
492   
493   for (int i = 0; i < methods_count; i++)
494     {
495       int access_flags     = read2u ();
496       int name_index       = read2u ();
497       int descriptor_index = read2u ();
498       int attributes_count = read2u ();
499       
500       check_tag (name_index, JV_CONSTANT_Utf8);
501       prepare_pool_entry (descriptor_index, JV_CONSTANT_Utf8);
502
503       check_tag (name_index, JV_CONSTANT_Utf8);
504       prepare_pool_entry (descriptor_index, JV_CONSTANT_Utf8);
505
506       handleMethod (i, access_flags, name_index,
507                     descriptor_index);
508
509       for (int j = 0; j < attributes_count; j++)
510         {
511           read_one_method_attribute (i);
512         }
513     }
514   
515   handleMethodsEnd ();
516 }
517
518 void _Jv_ClassReader::read_one_method_attribute (int method_index) 
519 {
520   int name = read2u ();
521   int length = read4 ();
522
523   if (is_attribute_name (name, "Exceptions"))
524     {
525       _Jv_Method *method = reinterpret_cast<_Jv_Method *>
526         (&def->methods[method_index]);
527       if (method->throws != NULL)
528         throw_class_format_error ("only one Exceptions attribute allowed per method");
529
530       int num_exceptions = read2u ();
531       _Jv_Utf8Const **exceptions =
532         (_Jv_Utf8Const **) _Jv_AllocBytes ((num_exceptions + 1)
533                                            * 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           int ndx = read2u ();
540           // JLS 2nd Ed. 4.7.5 requires that the tag not be 0.
541           if (ndx != 0)
542             {
543               check_tag (ndx, JV_CONSTANT_Class);
544               exceptions[out++] = pool_data[ndx].utf8; 
545             }
546         }
547       exceptions[out] = NULL;
548       method->throws = exceptions;
549     }
550
551   else if (is_attribute_name (name, "Code"))
552     {
553       int start_off = pos;
554       int max_stack = read2u ();
555       int max_locals = read2u ();
556       int code_length = read4 ();
557
558       int code_start = pos;
559       skip (code_length);
560       int exception_table_length = read2u ();
561
562       handleCodeAttribute (method_index, 
563                            max_stack, max_locals,
564                            code_start, code_length,
565                            exception_table_length);
566       
567
568       for (int i = 0; i < exception_table_length; i++)
569         {
570           int start_pc   = read2u ();
571           int end_pc     = read2u ();
572           int handler_pc = read2u ();
573           int catch_type = read2u ();
574
575           if (start_pc > end_pc
576               || start_pc < 0
577               // END_PC can be equal to CODE_LENGTH.
578               // See JVM Spec 4.7.4.
579               || end_pc > code_length
580               || handler_pc >= code_length)
581             throw_class_format_error ("erroneous exception handler info");
582
583           if (! (tags[catch_type] == JV_CONSTANT_Class
584                  || tags[catch_type] == 0))
585             {
586               throw_class_format_error ("erroneous exception handler info");
587             }
588
589           handleExceptionTableEntry (method_index,
590                                      i,
591                                      start_pc,
592                                      end_pc,
593                                      handler_pc, 
594                                      catch_type);
595
596         }
597
598       int attributes_count = read2u ();
599
600       for (int i = 0; i < attributes_count; i++)
601         {
602           read_one_code_attribute (method_index);
603         }
604
605       if ((pos - start_off) != length)
606         throw_class_format_error ("code attribute too short");
607     }
608
609   else
610     {
611       /* ignore unknown attributes */
612       skip (length);
613     }
614 }
615
616 void _Jv_ClassReader::read_one_code_attribute (int /*method*/) 
617 {
618   /* ignore for now, ... later we may want to pick up
619      line number information, for debugging purposes;
620      in fact, the whole debugger issue is open!  */
621
622   /* int name = */ read2u ();
623   int length = read4 ();
624   skip (length);
625
626 }
627
628 void _Jv_ClassReader::read_one_class_attribute () 
629 {
630   /* we also ignore the class attributes, ...
631      some day we'll add inner-classes support. */
632
633   /* int name = */ read2u ();
634   int length = read4 ();
635   skip (length);
636 }
637
638
639
640 \f
641 /* this section defines the semantic actions of the parser */
642
643 void _Jv_ClassReader::handleConstantPool ()
644 {
645   /** now, we actually define the class' constant pool */
646
647   // the pool is scanned explicitly by the collector
648   jbyte *pool_tags = (jbyte*) _Jv_AllocBytes (pool_count);
649   _Jv_word *pool_data
650     = (_Jv_word*) _Jv_AllocBytes (pool_count * sizeof (_Jv_word));
651   
652   def->constants.tags = pool_tags;
653   def->constants.data = pool_data;
654   def->constants.size = pool_count;
655
656   // Here we make a pass to collect the strings!   We do this, because
657   // internally in the GCJ runtime, classes are encoded with .'s not /'s. 
658   // Therefore, we first collect the strings, and then translate the rest
659   // of the utf8-entries (thus not representing strings) from /-notation
660   // to .-notation.
661   for (int i = 1; i < pool_count; i++)
662     {
663       if (tags[i] == JV_CONSTANT_String)
664         {
665           unsigned char* str_data = bytes + offsets [i];
666           int utf_index = get2u (str_data);
667           check_tag (utf_index, JV_CONSTANT_Utf8);
668           unsigned char *utf_data = bytes + offsets[utf_index];
669           int len = get2u (utf_data);
670           pool_data[i].utf8 = _Jv_makeUtf8Const ((char*)(utf_data+2), len);
671           pool_tags[i] = JV_CONSTANT_String;
672         }
673       else
674         {
675           pool_tags[i] = JV_CONSTANT_Undefined;
676         }
677     }
678
679   // and now, we scan everything else but strings & utf8-entries.  This
680   // leaves out those utf8-entries which are not used; which will be left
681   // with a tag of JV_CONSTANT_Undefined in the class definition.
682   for (int index = 1; index < pool_count; index++)
683     {
684       switch (tags[index])
685         {
686         case JV_CONSTANT_Undefined:
687         case JV_CONSTANT_String:
688         case JV_CONSTANT_Utf8:
689           continue;
690           
691         default:
692           prepare_pool_entry (index, tags[index]);
693         }
694     }  
695   
696 }
697
698 /* this is a recursive procedure, which will prepare pool entries as needed.
699    Which is how we avoid initializing those entries which go unused. */
700 void
701 _Jv_ClassReader::prepare_pool_entry (int index, unsigned char this_tag)
702 {
703   /* these two, pool_data and pool_tags, point into the class
704      structure we are currently defining */
705
706   unsigned char *pool_tags = (unsigned char*) def->constants.tags;
707   _Jv_word      *pool_data = def->constants.data;
708
709   /* this entry was already prepared */
710   if (pool_tags[index] == this_tag)
711     return;
712
713   /* this_data points to the constant-pool information for the current
714      constant-pool entry */
715
716   unsigned char *this_data = bytes + offsets[index];
717
718   switch (this_tag)
719     {
720     case JV_CONSTANT_Utf8: 
721       {
722         // If we came here, it is because some other tag needs this
723         // utf8-entry for type information!  Thus, we translate /'s to .'s in
724         // order to accomondate gcj's internal representation.
725
726         int len = get2u (this_data);
727         char *buffer = (char*) __builtin_alloca (len);
728         char *s = ((char*) this_data)+2;
729
730         /* FIXME: avoid using a buffer here */
731         for (int i = 0; i < len; i++)
732           {
733             if (s[i] == '/')
734               buffer[i] = '.';
735             else
736               buffer[i] = (char) s[i];
737           }
738         
739         pool_data[index].utf8 = _Jv_makeUtf8Const (buffer, len);
740         pool_tags[index] = JV_CONSTANT_Utf8;
741       }
742       break;
743             
744     case JV_CONSTANT_Class:      
745       {
746         int utf_index = get2u (this_data);
747         check_tag (utf_index, JV_CONSTANT_Utf8);
748         prepare_pool_entry (utf_index, JV_CONSTANT_Utf8);
749
750         if (verify)
751           verify_classname (pool_data[utf_index].utf8);
752                 
753         pool_data[index].utf8 = pool_data[utf_index].utf8;
754         pool_tags[index] = JV_CONSTANT_Class;
755       }
756       break;
757             
758     case JV_CONSTANT_String:
759       // already handled before... 
760       break;
761             
762     case JV_CONSTANT_Fieldref:
763     case JV_CONSTANT_Methodref:
764     case JV_CONSTANT_InterfaceMethodref:
765       {
766         int class_index = get2u (this_data);
767         int nat_index = get2u (this_data+2);
768
769         check_tag (class_index, JV_CONSTANT_Class);
770         prepare_pool_entry (class_index, JV_CONSTANT_Class);        
771
772         check_tag (nat_index, JV_CONSTANT_NameAndType);
773         prepare_pool_entry (nat_index, JV_CONSTANT_NameAndType);
774
775         // here, verify the signature and identifier name
776         if (verify)
777         {
778           _Jv_ushort name_index, type_index;
779           _Jv_loadIndexes (&pool_data[nat_index],
780                            name_index, type_index);
781
782           if (this_tag == JV_CONSTANT_Fieldref)
783             verify_field_signature (pool_data[type_index].utf8);
784           else
785             verify_method_signature (pool_data[type_index].utf8);
786
787           _Jv_Utf8Const* name = pool_data[name_index].utf8;
788
789           if (this_tag != JV_CONSTANT_Fieldref
790               && (   _Jv_equalUtf8Consts (name, clinit_name)
791                   || _Jv_equalUtf8Consts (name, init_name)))
792             /* ignore */;
793           else
794             verify_identifier (pool_data[name_index].utf8);
795         }
796             
797         _Jv_storeIndexes (&pool_data[index], class_index, nat_index);
798         pool_tags[index] = this_tag;
799       }
800       break;
801             
802     case JV_CONSTANT_NameAndType:
803       {
804         _Jv_ushort name_index = get2u (this_data);
805         _Jv_ushort type_index = get2u (this_data+2);
806
807         check_tag (name_index, JV_CONSTANT_Utf8);
808         prepare_pool_entry (name_index, JV_CONSTANT_Utf8);          
809
810         check_tag (type_index, JV_CONSTANT_Utf8);
811         prepare_pool_entry (type_index, JV_CONSTANT_Utf8);
812
813         _Jv_storeIndexes (&pool_data[index], name_index, type_index);
814         pool_tags[index] = JV_CONSTANT_NameAndType;
815       }
816       break;
817             
818     case JV_CONSTANT_Float:
819       {
820         jfloat f = java::lang::Float::intBitsToFloat ((jint) get4 (this_data));
821         _Jv_storeFloat (&pool_data[index], f);
822         pool_tags[index] = JV_CONSTANT_Float;
823       }
824       break;
825             
826     case JV_CONSTANT_Integer:
827       {
828         int i = get4 (this_data);
829         _Jv_storeInt (&pool_data[index], i);
830         pool_tags[index] = JV_CONSTANT_Integer;
831       }
832       break;
833             
834     case JV_CONSTANT_Double:
835       {
836         jdouble d
837           = java::lang::Double::longBitsToDouble ((jlong) get8 (this_data));
838         _Jv_storeDouble (&pool_data[index], d);
839         pool_tags[index] = JV_CONSTANT_Double;
840       }
841       break;
842             
843     case JV_CONSTANT_Long:
844       {
845         jlong i = get8 (this_data);
846         _Jv_storeLong (&pool_data[index], i);
847         pool_tags[index] = JV_CONSTANT_Long;
848       }
849       break;
850             
851     default:
852       throw_class_format_error ("erroneous constant pool tag");
853     }
854 }
855
856
857 void
858 _Jv_ClassReader::handleClassBegin (int access_flags, int this_class, int super_class)
859 {
860   using namespace java::lang::reflect;
861
862   unsigned char *pool_tags = (unsigned char*) def->constants.tags;
863   _Jv_word      *pool_data = def->constants.data;
864
865   check_tag (this_class, JV_CONSTANT_Class);
866   _Jv_Utf8Const *loadedName = pool_data[this_class].utf8;
867
868   // was ClassLoader.defineClass called with an expected class name?
869   if (def->name == 0)
870     {
871       jclass orig = def->loader->findLoadedClass(loadedName->toString());
872
873       if (orig == 0)
874         {
875           def->name = loadedName;
876         }
877       else
878         {
879           jstring msg = JvNewStringUTF ("anonymous "
880                                         "class data denotes "
881                                         "existing class ");
882           msg = msg->concat (orig->getName ());
883
884           throw_no_class_def_found_error (msg);
885         }
886     }
887
888   // assert that the loaded class has the expected name, 5.3.5
889   else if (! _Jv_equalUtf8Consts (loadedName, def->name))
890     {
891       jstring msg = JvNewStringUTF ("loaded class ");
892       msg = msg->concat (def->getName ());
893       msg = msg->concat (_Jv_NewStringUTF (" was in fact named "));
894       jstring klass_name = loadedName->toString();
895       msg = msg->concat (klass_name);
896
897       throw_no_class_def_found_error (msg);
898     }
899
900   def->accflags = access_flags | java::lang::reflect::Modifier::INTERPRETED;
901   pool_data[this_class].clazz = def;
902   pool_tags[this_class] = JV_CONSTANT_ResolvedClass;
903
904   if (super_class == 0 && ! (access_flags & Modifier::INTERFACE))
905     {
906       // FIXME: Consider this carefully!  
907       if (! _Jv_equalUtf8Consts (def->name, java::lang::Object::class$.name))
908         throw_no_class_def_found_error ("loading java.lang.Object");
909     }
910
911   def->state = JV_STATE_PRELOADING;
912
913   // Register this class with its defining loader as well (despite the
914   // name of the function we're calling), so that super class lookups
915   // work properly.  If there is an error, our caller will unregister
916   // this class from the class loader.  Also, we don't need to hold a
917   // lock here, as our caller has acquired it.
918   _Jv_RegisterInitiatingLoader (def, def->loader);
919
920   if (super_class != 0)
921     {
922       // Load the superclass.
923       check_tag (super_class, JV_CONSTANT_Class);
924       _Jv_Utf8Const* super_name = pool_data[super_class].utf8; 
925
926       // Load the superclass using our defining loader.
927       jclass the_super = _Jv_FindClass (super_name,
928                                         def->loader);
929
930       // This will establish that we are allowed to be a subclass,
931       // and check for class circularity error.
932       checkExtends (def, the_super);
933
934       // Note: for an interface we will find Object as the
935       // superclass.  We still check it above to ensure class file
936       // validity, but we simply assign `null' to the actual field in
937       // this case.
938       def->superclass = (((access_flags & Modifier::INTERFACE))
939                          ? NULL : the_super);
940       pool_data[super_class].clazz = the_super;
941       pool_tags[super_class] = JV_CONSTANT_ResolvedClass;
942     }
943
944   // Now we've come past the circularity problem, we can 
945   // now say that we're loading.
946
947   def->state = JV_STATE_LOADING;
948   def->notifyAll ();
949 }
950
951 ///// Implements the checks described in sect. 5.3.5.3
952 void
953 _Jv_ClassReader::checkExtends (jclass sub, jclass super)
954 {
955   using namespace java::lang::reflect;
956
957   _Jv_Linker::wait_for_state (super, JV_STATE_LOADING);
958
959   // Having an interface or a final class as a superclass is no good.
960   if ((super->accflags & (Modifier::INTERFACE | Modifier::FINAL)) != 0)
961     {
962       throw_incompatible_class_change_error (sub->getName ());
963     }
964
965   // If the super class is not public, we need to check some more.
966   if ((super->accflags & Modifier::PUBLIC) == 0)
967     {
968       // With package scope, the classes must have the same class
969       // loader.
970       if (   sub->loader != super->loader
971           || !_Jv_ClassNameSamePackage (sub->name, super->name))
972         {
973           throw_incompatible_class_change_error (sub->getName ());
974         }
975     } 
976
977   for (; super != 0; super = super->getSuperclass ())
978     {
979       if (super == sub)
980         throw_class_circularity_error (sub->getName ());
981     }
982 }
983
984
985
986 void _Jv_ClassReader::handleInterfacesBegin (int count)
987 {
988   def->interfaces = (jclass*) _Jv_AllocBytes (count*sizeof (jclass));
989   def->interface_count = count;
990 }
991
992 void _Jv_ClassReader::handleInterface (int if_number, int offset)
993 {
994   _Jv_word       * pool_data = def->constants.data;
995   unsigned char  * pool_tags = (unsigned char*) def->constants.tags;
996
997   jclass the_interface;
998
999   if (pool_tags[offset] == JV_CONSTANT_Class)
1000     {
1001       _Jv_Utf8Const* name = pool_data[offset].utf8;
1002       the_interface =  _Jv_FindClass (name, def->loader);
1003     }
1004   else if (pool_tags[offset] == JV_CONSTANT_ResolvedClass)
1005     {
1006       the_interface = pool_data[offset].clazz;
1007     }
1008   else
1009     {
1010       throw_no_class_def_found_error ("erroneous constant pool tag");
1011     }
1012
1013   // checks the validity of the_interface, and that we are in fact
1014   // allowed to implement that interface.
1015   checkImplements (def, the_interface);
1016   
1017   pool_data[offset].clazz = the_interface;
1018   pool_tags[offset] = JV_CONSTANT_ResolvedClass;
1019   
1020   def->interfaces[if_number] = the_interface;
1021 }
1022
1023 void
1024 _Jv_ClassReader::checkImplements (jclass sub, jclass super)
1025 {
1026   using namespace java::lang::reflect;
1027
1028   // well, it *must* be an interface
1029   if ((super->accflags & Modifier::INTERFACE) == 0)
1030     {
1031       throw_incompatible_class_change_error (sub->getName ());
1032     }
1033
1034   // if it has package scope, it must also be defined by the 
1035   // same loader.
1036   if ((super->accflags & Modifier::PUBLIC) == 0)
1037     {
1038       if (    sub->loader != super->loader
1039           || !_Jv_ClassNameSamePackage (sub->name, super->name))
1040         {
1041           throw_incompatible_class_change_error (sub->getName ());
1042         }
1043     } 
1044
1045   // FIXME: add interface circularity check here
1046   if (sub == super)
1047     {
1048       throw_class_circularity_error (sub->getName ());
1049     }           
1050 }
1051
1052 void _Jv_ClassReader::handleFieldsBegin (int count)
1053 {
1054   def->fields = (_Jv_Field*) 
1055     _Jv_AllocBytes (count * sizeof (_Jv_Field));
1056   def->field_count = count;
1057   def_interp->field_initializers = (_Jv_ushort*)
1058     _Jv_AllocBytes (count * sizeof (_Jv_ushort));
1059   for (int i = 0; i < count; i++)
1060     def_interp->field_initializers[i] = (_Jv_ushort) 0;
1061 }
1062
1063 void _Jv_ClassReader::handleField (int field_no,
1064                                    int flags,
1065                                    int name,
1066                                    int desc)
1067 {
1068   using namespace java::lang::reflect;
1069
1070   _Jv_word *pool_data = def->constants.data;
1071
1072   _Jv_Field *field = &def->fields[field_no];
1073   _Jv_Utf8Const *field_name = pool_data[name].utf8;
1074
1075   field->name      = field_name;
1076
1077   // Ignore flags we don't know about.  
1078   field->flags = flags & Modifier::ALL_FLAGS;
1079
1080   _Jv_Utf8Const* sig = pool_data[desc].utf8;
1081
1082   if (verify)
1083     {
1084       verify_identifier (field_name);
1085
1086       for (int i = 0; i < field_no; ++i)
1087         {
1088           if (_Jv_equalUtf8Consts (field_name, def->fields[i].name)
1089               && _Jv_equalUtf8Consts (sig,
1090                                       // We know the other fields are
1091                                       // unresolved.
1092                                       (_Jv_Utf8Const *) def->fields[i].type))
1093             throw_class_format_error ("duplicate field name");
1094         }
1095
1096       // At most one of PUBLIC, PRIVATE, or PROTECTED is allowed.
1097       if (1 < ( ((field->flags & Modifier::PUBLIC) ? 1 : 0)
1098                 +((field->flags & Modifier::PRIVATE) ? 1 : 0)
1099                 +((field->flags & Modifier::PROTECTED) ? 1 : 0)))
1100         throw_class_format_error ("erroneous field access flags");
1101
1102       // FIXME: JVM spec S4.5: Verify ACC_FINAL and ACC_VOLATILE are not 
1103       // both set. Verify modifiers for interface fields.
1104       
1105     }
1106
1107   if (verify)
1108     verify_field_signature (sig);
1109
1110   // field->type is really a jclass, but while it is still
1111   // unresolved we keep an _Jv_Utf8Const* instead.
1112   field->type       = (jclass) sig;
1113   field->flags     |= _Jv_FIELD_UNRESOLVED_FLAG;
1114   field->u.boffset  = 0;
1115 }
1116
1117
1118 void _Jv_ClassReader::handleConstantValueAttribute (int field_index, 
1119                                                     int value)
1120 {
1121   using namespace java::lang::reflect;
1122
1123   _Jv_Field *field = &def->fields[field_index];
1124
1125   if ((field->flags & (Modifier::STATIC
1126                        | Modifier::FINAL
1127                        | Modifier::PRIVATE)) == 0)
1128     {
1129       // Ignore, as per vmspec #4.7.2
1130       return;
1131     }
1132
1133   // do not allow multiple constant fields!
1134   if (field->flags & _Jv_FIELD_CONSTANT_VALUE)
1135     throw_class_format_error ("field has multiple ConstantValue attributes");
1136
1137   field->flags |= _Jv_FIELD_CONSTANT_VALUE;
1138   def_interp->field_initializers[field_index] = value;
1139
1140   /* type check the initializer */
1141   
1142   if (value <= 0 || value >= pool_count)
1143     throw_class_format_error ("erroneous ConstantValue attribute");
1144
1145   /* FIXME: do the rest */
1146 }
1147
1148 void _Jv_ClassReader::handleFieldsEnd ()
1149 {
1150   using namespace java::lang::reflect;
1151
1152   // We need to reorganize the fields so that the static ones are first,
1153   // to conform to GCJ class layout.
1154
1155   int low            = 0;
1156   int high           = def->field_count-1;
1157   _Jv_Field  *fields = def->fields;
1158   _Jv_ushort *inits  = def_interp->field_initializers;
1159
1160   // this is kind of a raw version of quicksort.
1161   while (low < high)
1162     {
1163       // go forward on low, while it's a static
1164       while (low < high && (fields[low].flags & Modifier::STATIC) != 0)
1165         low++;
1166       
1167       // go backwards on high, while it's a non-static
1168       while (low < high && (fields[high].flags & Modifier::STATIC) == 0)
1169         high--;
1170
1171       if (low==high)
1172         break;
1173
1174       _Jv_Field  tmp  = fields[low];
1175       _Jv_ushort itmp = inits[low];
1176           
1177       fields[low] = fields[high];
1178       inits[low]  = inits[high];
1179           
1180       fields[high] = tmp;
1181       inits[high]  = itmp;
1182           
1183       high -= 1;
1184       low  += 1;
1185     }
1186   
1187   if ((fields[low].flags & Modifier::STATIC) != 0) 
1188     low += 1;
1189
1190   def->static_field_count = low;
1191 }
1192
1193
1194
1195 void
1196 _Jv_ClassReader::handleMethodsBegin (int count)
1197 {
1198   def->methods = (_Jv_Method *) _Jv_AllocBytes (sizeof (_Jv_Method) * count);
1199
1200   def_interp->interpreted_methods
1201     = (_Jv_MethodBase **) _Jv_AllocBytes (sizeof (_Jv_MethodBase *)
1202                                           * count);
1203
1204   for (int i = 0; i < count; i++)
1205     {
1206       def_interp->interpreted_methods[i] = 0;
1207       def->methods[i].index = (_Jv_ushort) -1;
1208     }
1209
1210   def->method_count = count;
1211 }
1212
1213
1214 void _Jv_ClassReader::handleMethod 
1215     (int mth_index, int accflags, int name, int desc)
1216
1217   using namespace java::lang::reflect;
1218
1219   _Jv_word *pool_data = def->constants.data;
1220   _Jv_Method *method = &def->methods[mth_index];
1221
1222   check_tag (name, JV_CONSTANT_Utf8);
1223   prepare_pool_entry (name, JV_CONSTANT_Utf8);
1224   method->name = pool_data[name].utf8;
1225
1226   check_tag (desc, JV_CONSTANT_Utf8);
1227   prepare_pool_entry (desc, JV_CONSTANT_Utf8);
1228   method->signature = pool_data[desc].utf8;
1229
1230   // ignore unknown flags
1231   method->accflags = accflags & Modifier::ALL_FLAGS;
1232
1233   // Initialize...
1234   method->ncode = 0;
1235   method->throws = NULL;
1236   
1237   if (verify)
1238     {
1239       if (_Jv_equalUtf8Consts (method->name, clinit_name)
1240           || _Jv_equalUtf8Consts (method->name, init_name))
1241         /* ignore */;
1242       else
1243         verify_identifier (method->name);
1244
1245       verify_method_signature (method->signature);
1246
1247       for (int i = 0; i < mth_index; ++i)
1248         {
1249           if (_Jv_equalUtf8Consts (method->name, def->methods[i].name)
1250               && _Jv_equalUtf8Consts (method->signature,
1251                                       def->methods[i].signature))
1252             throw_class_format_error ("duplicate method");
1253         }
1254
1255       // At most one of PUBLIC, PRIVATE, or PROTECTED is allowed.
1256       if (1 < ( ((method->accflags & Modifier::PUBLIC) ? 1 : 0)
1257                 +((method->accflags & Modifier::PRIVATE) ? 1 : 0)
1258                 +((method->accflags & Modifier::PROTECTED) ? 1 : 0)))
1259         throw_class_format_error ("erroneous method access flags");
1260
1261       // FIXME: JVM spec S4.6: if ABSTRACT modifier is set, verify other 
1262       // flags are not set. Verify flags for interface methods. Verifiy
1263       // modifiers for initializers. 
1264     }
1265 }
1266
1267 void _Jv_ClassReader::handleCodeAttribute
1268   (int method_index, int max_stack, int max_locals, 
1269    int code_start, int code_length, int exc_table_length)
1270 {
1271   int size = _Jv_InterpMethod::size (exc_table_length, code_length);
1272   _Jv_InterpMethod *method = 
1273     (_Jv_InterpMethod*) (_Jv_AllocBytes (size));
1274
1275   method->max_stack      = max_stack;
1276   method->max_locals     = max_locals;
1277   method->code_length    = code_length;
1278   method->exc_count      = exc_table_length;
1279   method->defining_class = def;
1280   method->self           = &def->methods[method_index];
1281   method->prepared       = NULL;
1282
1283   // grab the byte code!
1284   memcpy ((void*) method->bytecode (),
1285           (void*) (bytes+code_start),
1286           code_length);
1287
1288   def_interp->interpreted_methods[method_index] = method;
1289
1290   if ((method->self->accflags & java::lang::reflect::Modifier::STATIC))
1291     {
1292       // Precompute the ncode field for a static method.  This lets us
1293       // call a static method of an interpreted class from precompiled
1294       // code without first resolving the class (that will happen
1295       // during class initialization instead).
1296       method->self->ncode = method->ncode ();
1297     }
1298 }
1299
1300 void _Jv_ClassReader::handleExceptionTableEntry
1301   (int method_index, int exc_index, 
1302    int start_pc, int end_pc, int handler_pc, int catch_type)
1303 {
1304   _Jv_InterpMethod *method = reinterpret_cast<_Jv_InterpMethod *>
1305     (def_interp->interpreted_methods[method_index]);
1306   _Jv_InterpException *exc = method->exceptions ();
1307
1308   exc[exc_index].start_pc.i     = start_pc;
1309   exc[exc_index].end_pc.i       = end_pc;
1310   exc[exc_index].handler_pc.i   = handler_pc;
1311   exc[exc_index].handler_type.i = catch_type;
1312 }
1313
1314 void _Jv_ClassReader::handleMethodsEnd ()
1315 {
1316   using namespace java::lang::reflect;
1317
1318   for (int i = 0; i < def->method_count; i++)
1319     {
1320       _Jv_Method *method = &def->methods[i];
1321       if ((method->accflags & Modifier::NATIVE) != 0)
1322         {
1323           if (def_interp->interpreted_methods[i] != 0)
1324             throw_class_format_error ("code provided for native method");
1325           else
1326             {
1327               _Jv_JNIMethod *m = (_Jv_JNIMethod *)
1328                 _Jv_AllocBytes (sizeof (_Jv_JNIMethod));
1329               m->defining_class = def;
1330               m->self = method;
1331               m->function = NULL;
1332               def_interp->interpreted_methods[i] = m;
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_interp->interpreted_methods[i] != 0)
1348             throw_class_format_error ("code provided for abstract method");
1349         }
1350       else
1351         {
1352           if (def_interp->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->chars();
1365       int ulen = def->name->len();
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->chars();
1498   unsigned char* limit = ptr + sig->len();
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->chars();
1509   unsigned char* limit = ptr + sig->len();
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->chars();
1564   unsigned char *limit = (unsigned char*) name->limit();
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->chars(), name->len());
1620 }
1621
1622 /* Returns true, if NAME1 and NAME2 represent classes in the same
1623    package.  Neither NAME2 nor NAME2 may name an array type.  */
1624 bool
1625 _Jv_ClassNameSamePackage (_Jv_Utf8Const *name1, _Jv_Utf8Const *name2)
1626 {
1627   unsigned char* ptr1 = (unsigned char*) name1->chars();
1628   unsigned char* limit1 = (unsigned char*) name1->limit();
1629
1630   unsigned char* last1 = ptr1;
1631
1632   // scan name1, and find the last occurrence of '.'
1633   while (ptr1 < limit1) {
1634     int ch1 = UTF8_GET (ptr1, limit1);
1635
1636     if (ch1 == '.')
1637       last1 = ptr1;
1638
1639     else if (ch1 == -1)
1640       return false;
1641   }
1642
1643   // Now the length of NAME1's package name is LEN.
1644   int len = last1 - (unsigned char*) name1->chars();
1645
1646   // If this is longer than NAME2, then we're off.
1647   if (len > name2->len())
1648     return false;
1649
1650   // Then compare the first len bytes for equality.
1651   if (memcmp ((void*) name1->chars(), (void*) name2->chars(), len) == 0)
1652     {
1653       // Check that there are no .'s after position LEN in NAME2.
1654
1655       unsigned char* ptr2 = (unsigned char*) name2->chars() + len;
1656       unsigned char* limit2 = (unsigned char*) name2->limit();
1657
1658       while (ptr2 < limit2)
1659         {
1660           int ch2 = UTF8_GET (ptr2, limit2);
1661           if (ch2 == -1 || ch2 == '.')
1662             return false;
1663         }
1664       return true;
1665     }
1666   return false;
1667 }