OSDN Git Service

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