OSDN Git Service

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