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