OSDN Git Service

* testsuite/testsuite_hooks.h (__set_testsuite_memlimit): Add
[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 seperate 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       /* we ignore this for now */
530       skip (length);
531     }
532   
533   else if (is_attribute_name (name, "Code"))
534     {
535       int start_off = pos;
536       int max_stack = read2u ();
537       int max_locals = read2u ();
538       int code_length = read4 ();
539
540       int code_start = pos;
541       skip (code_length);
542       int exception_table_length = read2u ();
543
544       handleCodeAttribute (method_index, 
545                            max_stack, max_locals,
546                            code_start, code_length,
547                            exception_table_length);
548       
549
550       for (int i = 0; i < exception_table_length; i++)
551         {
552           int start_pc   = read2u ();
553           int end_pc     = read2u ();
554           int handler_pc = read2u ();
555           int catch_type = read2u ();
556
557           if (start_pc > end_pc
558               || start_pc < 0
559               || end_pc >= code_length
560               || handler_pc >= code_length)
561             throw_class_format_error ("erroneous exception handler info");
562
563           if (! (tags[catch_type] == JV_CONSTANT_Class
564                  || tags[catch_type] == 0))
565             {
566               throw_class_format_error ("erroneous exception handler info");
567             }
568
569           handleExceptionTableEntry (method_index,
570                                      i,
571                                      start_pc,
572                                      end_pc,
573                                      handler_pc, 
574                                      catch_type);
575
576         }
577
578       int attributes_count = read2u ();
579
580       for (int i = 0; i < attributes_count; i++)
581         {
582           read_one_code_attribute (method_index);
583         }
584
585       if ((pos - start_off) != length)
586         throw_class_format_error ("code attribute too short");
587     }
588
589   else
590     {
591       /* ignore unknown attributes */
592       skip (length);
593     }
594 }
595
596 void _Jv_ClassReader::read_one_code_attribute (int /*method*/) 
597 {
598   /* ignore for now, ... later we may want to pick up
599      line number information, for debugging purposes;
600      in fact, the whole debugger issue is open!  */
601
602   /* int name = */ read2u ();
603   int length = read4 ();
604   skip (length);
605
606 }
607
608 void _Jv_ClassReader::read_one_class_attribute () 
609 {
610   /* we also ignore the class attributes, ...
611      some day we'll add inner-classes support. */
612
613   /* int name = */ read2u ();
614   int length = read4 ();
615   skip (length);
616 }
617
618
619
620 \f
621 /* this section defines the semantic actions of the parser */
622
623 void _Jv_ClassReader::handleConstantPool ()
624 {
625   /** now, we actually define the class' constant pool */
626
627   // the pool is scanned explicitly by the collector
628   jbyte *pool_tags = (jbyte*) _Jv_AllocBytes (pool_count);
629   _Jv_word *pool_data
630     = (_Jv_word*) _Jv_AllocBytes (pool_count * sizeof (_Jv_word));
631   
632   def->constants.tags = pool_tags;
633   def->constants.data = pool_data;
634   def->constants.size = pool_count;
635
636   // Here we make a pass to collect the strings!   We do this, because
637   // internally in the GCJ runtime, classes are encoded with .'s not /'s. 
638   // Therefore, we first collect the strings, and then translate the rest
639   // of the utf8-entries (thus not representing strings) from /-notation
640   // to .-notation.
641   for (int i = 1; i < pool_count; i++)
642     {
643       if (tags[i] == JV_CONSTANT_String)
644         {
645           unsigned char* str_data = bytes + offsets [i];
646           int utf_index = get2u (str_data);
647           check_tag (utf_index, JV_CONSTANT_Utf8);
648           unsigned char *utf_data = bytes + offsets[utf_index];
649           int len = get2u (utf_data);
650           pool_data[i].utf8 = _Jv_makeUtf8Const ((char*)(utf_data+2), len);
651           pool_tags[i] = JV_CONSTANT_String;
652         }
653       else
654         {
655           pool_tags[i] = JV_CONSTANT_Undefined;
656         }
657     }
658
659   // and now, we scan everything else but strings & utf8-entries.  This
660   // leaves out those utf8-entries which are not used; which will be left
661   // with a tag of JV_CONSTANT_Undefined in the class definition.
662   for (int index = 1; index < pool_count; index++)
663     {
664       switch (tags[index])
665         {
666         case JV_CONSTANT_Undefined:
667         case JV_CONSTANT_String:
668         case JV_CONSTANT_Utf8:
669           continue;
670           
671         default:
672           prepare_pool_entry (index, tags[index]);
673         }
674     }  
675   
676 }
677
678 /* this is a recursive procedure, which will prepare pool entries as needed.
679    Which is how we avoid initializing those entries which go unused. */
680 void
681 _Jv_ClassReader::prepare_pool_entry (int index, unsigned char this_tag)
682 {
683   /* these two, pool_data and pool_tags, point into the class
684      structure we are currently defining */
685
686   unsigned char *pool_tags = (unsigned char*) def->constants.tags;
687   _Jv_word      *pool_data = def->constants.data;
688
689   /* this entry was already prepared */
690   if (pool_tags[index] == this_tag)
691     return;
692
693   /* this_data points to the constant-pool information for the current
694      constant-pool entry */
695
696   unsigned char *this_data = bytes + offsets[index];
697
698   switch (this_tag)
699     {
700     case JV_CONSTANT_Utf8: 
701       {
702         // If we came here, it is because some other tag needs this
703         // utf8-entry for type information!  Thus, we translate /'s to .'s in
704         // order to accomondate gcj's internal representation.
705
706         int len = get2u (this_data);
707         char *buffer = (char*) __builtin_alloca (len);
708         char *s = ((char*) this_data)+2;
709
710         /* FIXME: avoid using a buffer here */
711         for (int i = 0; i < len; i++)
712           {
713             if (s[i] == '/')
714               buffer[i] = '.';
715             else
716               buffer[i] = (char) s[i];
717           }
718         
719         pool_data[index].utf8 = _Jv_makeUtf8Const (buffer, len);
720         pool_tags[index] = JV_CONSTANT_Utf8;
721       }
722       break;
723             
724     case JV_CONSTANT_Class:      
725       {
726         int utf_index = get2u (this_data);
727         check_tag (utf_index, JV_CONSTANT_Utf8);
728         prepare_pool_entry (utf_index, JV_CONSTANT_Utf8);
729
730         if (verify)
731           verify_classname (pool_data[utf_index].utf8);
732                 
733         pool_data[index].utf8 = pool_data[utf_index].utf8;
734         pool_tags[index] = JV_CONSTANT_Class;
735       }
736       break;
737             
738     case JV_CONSTANT_String:
739       // already handled before... 
740       break;
741             
742     case JV_CONSTANT_Fieldref:
743     case JV_CONSTANT_Methodref:
744     case JV_CONSTANT_InterfaceMethodref:
745       {
746         int class_index = get2u (this_data);
747         int nat_index = get2u (this_data+2);
748
749         check_tag (class_index, JV_CONSTANT_Class);
750         prepare_pool_entry (class_index, JV_CONSTANT_Class);        
751
752         check_tag (nat_index, JV_CONSTANT_NameAndType);
753         prepare_pool_entry (nat_index, JV_CONSTANT_NameAndType);
754
755         // here, verify the signature and identifier name
756         if (verify)
757         {
758           _Jv_ushort name_index, type_index;
759           _Jv_loadIndexes (&pool_data[nat_index],
760                            name_index, type_index);
761
762           if (this_tag == JV_CONSTANT_Fieldref)
763             _Jv_VerifyFieldSignature (pool_data[type_index].utf8);
764           else
765             _Jv_VerifyMethodSignature (pool_data[type_index].utf8);
766
767           _Jv_Utf8Const* name = pool_data[name_index].utf8;
768
769           if (this_tag != JV_CONSTANT_Fieldref
770               && (   _Jv_equalUtf8Consts (name, clinit_name)
771                   || _Jv_equalUtf8Consts (name, init_name)))
772             /* ignore */;
773           else
774             verify_identifier (pool_data[name_index].utf8);
775         }
776             
777         _Jv_storeIndexes (&pool_data[index], class_index, nat_index);
778         pool_tags[index] = this_tag;
779       }
780       break;
781             
782     case JV_CONSTANT_NameAndType:
783       {
784         _Jv_ushort name_index = get2u (this_data);
785         _Jv_ushort type_index = get2u (this_data+2);
786
787         check_tag (name_index, JV_CONSTANT_Utf8);
788         prepare_pool_entry (name_index, JV_CONSTANT_Utf8);          
789
790         check_tag (type_index, JV_CONSTANT_Utf8);
791         prepare_pool_entry (type_index, JV_CONSTANT_Utf8);
792
793         _Jv_storeIndexes (&pool_data[index], name_index, type_index);
794         pool_tags[index] = JV_CONSTANT_NameAndType;
795       }
796       break;
797             
798     case JV_CONSTANT_Float:
799       {
800         jfloat f = int_bits_to_float ((jint) get4 (this_data));
801         _Jv_storeFloat (&pool_data[index], f);
802         pool_tags[index] = JV_CONSTANT_Float;
803       }
804       break;
805             
806     case JV_CONSTANT_Integer:
807       {
808         int i = get4 (this_data);
809         _Jv_storeInt (&pool_data[index], i);
810         pool_tags[index] = JV_CONSTANT_Integer;
811       }
812       break;
813             
814     case JV_CONSTANT_Double:
815       {
816         jdouble d = long_bits_to_double ((jlong) get8 (this_data));
817         _Jv_storeDouble (&pool_data[index], d);
818         pool_tags[index] = JV_CONSTANT_Double;
819       }
820       break;
821             
822     case JV_CONSTANT_Long:
823       {
824         jlong i = get8 (this_data);
825         _Jv_storeLong (&pool_data[index], i);
826         pool_tags[index] = JV_CONSTANT_Long;
827       }
828       break;
829             
830     default:
831       throw_class_format_error ("erroneous constant pool tag");
832     }
833 }
834
835
836 void
837 _Jv_ClassReader::handleClassBegin
838   (int access_flags, int this_class, int super_class)
839 {
840   using namespace java::lang::reflect;
841
842   unsigned char *pool_tags = (unsigned char*) def->constants.tags;
843   _Jv_word      *pool_data = def->constants.data;
844
845   check_tag (this_class, JV_CONSTANT_Class);
846   _Jv_Utf8Const *loadedName = pool_data[this_class].utf8;
847
848   // was ClassLoader.defineClass called with an expected class name?
849   if (def->name == 0)
850     {
851       jclass orig = _Jv_FindClassInCache (loadedName, def->loader);
852
853       if (orig == 0)
854         {
855           def->name = loadedName;
856         }
857       else
858         {
859           jstring msg = JvNewStringUTF ("anonymous "
860                                         "class data denotes "
861                                         "existing class ");
862           msg = msg->concat (orig->getName ());
863
864           throw_no_class_def_found_error (msg);
865         }
866     }
867
868   // assert that the loaded class has the expected name, 5.3.5
869   else if (! _Jv_equalUtf8Consts (loadedName, def->name))
870     {
871       jstring msg = JvNewStringUTF ("loaded class ");
872       msg = msg->concat (def->getName ());
873       msg = msg->concat (_Jv_NewStringUTF (" was in fact named "));
874       jstring klass_name = _Jv_NewStringUTF (loadedName->data);
875       msg = msg->concat (klass_name);
876
877       throw_no_class_def_found_error (msg);
878     }
879
880   def->accflags = access_flags;
881   pool_data[this_class].clazz = def;
882   pool_tags[this_class] = JV_CONSTANT_ResolvedClass;
883
884   if (super_class == 0)
885     {
886       // interfaces have java.lang.Object as super.
887       if (access_flags & Modifier::INTERFACE)
888         {
889           def->superclass = (jclass)&java::lang::Class::class$;
890         }
891
892       // FIXME: Consider this carefully!  
893       else if (!_Jv_equalUtf8Consts (def->name,
894                                      java::lang::Class::class$.name))
895         {
896           throw_no_class_def_found_error ("loading java.lang.Object");
897         }
898     }
899
900   // In the pre-loading state, it can be looked up in the
901   // cache only by this thread!  This allows the super-class
902   // to include references to this class.
903
904   def->state = JV_STATE_PRELOADING;
905   _Jv_RegisterClass (def);
906
907   if (super_class != 0)
908     {
909       // load the super class
910       check_tag (super_class, JV_CONSTANT_Class);
911       _Jv_Utf8Const* super_name = pool_data[super_class].utf8; 
912
913       // load the super class using our defining loader
914       jclass the_super = _Jv_FindClass (super_name,
915                                         def->loader);
916
917       // This will establish that we are allowed to be a subclass,
918       // and check for class circularity error
919       checkExtends (def, the_super);
920
921       def->superclass = the_super;
922       pool_data[super_class].clazz = the_super;
923       pool_tags[super_class] = JV_CONSTANT_ResolvedClass;
924     }
925             
926   // now we've come past the circularity problem, we can 
927   // now say that we're loading...
928
929   def->state = JV_STATE_LOADING;
930   def->notifyAll ();
931 }
932
933 ///// implements the checks described in sect. 5.3.5.3
934 void
935 _Jv_ClassReader::checkExtends (jclass sub, jclass super)
936 {
937   using namespace java::lang::reflect;
938
939   // having an interface or a final class as a superclass is no good
940   if ((super->accflags & (Modifier::INTERFACE | Modifier::FINAL)) != 0)
941     {
942       throw_incompatible_class_change_error (sub->getName ());
943     }
944
945   // if the super class is not public, we need to check some more
946   if ((super->accflags & Modifier::PUBLIC) == 0)
947     {
948       // With package scope, the classes must have the same
949       // class loader.
950       if (   sub->loader != super->loader
951           || !_Jv_ClassNameSamePackage (sub->name, super->name))
952         {
953           throw_incompatible_class_change_error (sub->getName ());
954         }
955     } 
956
957   for (; super != 0; super = super->superclass)
958     {
959       if (super == sub)
960         throw_class_circularity_error (sub->getName ());
961     }
962 }
963
964
965
966 void _Jv_ClassReader::handleInterfacesBegin (int count)
967 {
968   def->interfaces = (jclass*) _Jv_AllocBytes (count*sizeof (jclass));
969   def->interface_count = count;
970 }
971
972 void _Jv_ClassReader::handleInterface (int if_number, int offset)
973 {
974   _Jv_word       * pool_data = def->constants.data;
975   unsigned char  * pool_tags = (unsigned char*) def->constants.tags;
976
977   jclass the_interface;
978
979   if (pool_tags[offset] == JV_CONSTANT_Class)
980     {
981       _Jv_Utf8Const* name = pool_data[offset].utf8;
982       the_interface =  _Jv_FindClass (name, def->loader);
983     }
984   else if (pool_tags[offset] == JV_CONSTANT_ResolvedClass)
985     {
986       the_interface = pool_data[offset].clazz;
987     }
988   else
989     {
990       throw_no_class_def_found_error ("erroneous constant pool tag");
991     }
992
993   // checks the validity of the_interface, and that we are in fact
994   // allowed to implement that interface.
995   checkImplements (def, the_interface);
996   
997   pool_data[offset].clazz = the_interface;
998   pool_tags[offset] = JV_CONSTANT_ResolvedClass;
999   
1000   def->interfaces[if_number] = the_interface;
1001 }
1002
1003 void
1004 _Jv_ClassReader::checkImplements (jclass sub, jclass super)
1005 {
1006   using namespace java::lang::reflect;
1007
1008   // well, it *must* be an interface
1009   if ((super->accflags & Modifier::INTERFACE) == 0)
1010     {
1011       throw_incompatible_class_change_error (sub->getName ());
1012     }
1013
1014   // if it has package scope, it must also be defined by the 
1015   // same loader.
1016   if ((super->accflags & Modifier::PUBLIC) == 0)
1017     {
1018       if (    sub->loader != super->loader
1019           || !_Jv_ClassNameSamePackage (sub->name, super->name))
1020         {
1021           throw_incompatible_class_change_error (sub->getName ());
1022         }
1023     } 
1024
1025   // FIXME: add interface circularity check here
1026   if (sub == super)
1027     {
1028       throw_class_circularity_error (sub->getName ());
1029     }           
1030 }
1031
1032 void _Jv_ClassReader::handleFieldsBegin (int count)
1033 {
1034   def->fields = (_Jv_Field*) 
1035     _Jv_AllocBytes (count * sizeof (_Jv_Field));
1036   def->field_count = count;
1037   def->field_initializers = (_Jv_ushort*)
1038     _Jv_AllocBytes (count * sizeof (_Jv_ushort));
1039   for (int i = 0; i < count; i++)
1040     def->field_initializers[i] = (_Jv_ushort) 0;
1041 }
1042
1043 void _Jv_ClassReader::handleField (int field_no,
1044                                    int flags,
1045                                    int name,
1046                                    int desc)
1047 {
1048   using namespace java::lang::reflect;
1049
1050   _Jv_word *pool_data = def->constants.data;
1051
1052   _Jv_Field *field = &def->fields[field_no];
1053   _Jv_Utf8Const *field_name = pool_data[name].utf8;
1054
1055 #ifndef COMPACT_FIELDS
1056   field->name      = field_name;
1057 #else
1058   field->nameIndex = name;
1059 #endif
1060
1061   if (verify)
1062     verify_identifier (field_name);
1063
1064   // ignore flags we don't know about.  
1065   field->flags = flags & Modifier::ALL_FLAGS;
1066
1067   if (verify)
1068     {
1069       if (field->flags & (Modifier::SYNCHRONIZED
1070                           | Modifier::NATIVE
1071                           | Modifier::INTERFACE
1072                           | Modifier::ABSTRACT))
1073         throw_class_format_error ("erroneous field access flags");
1074       
1075       if (1 < ( ((field->flags & Modifier::PUBLIC) ? 1 : 0)
1076                 +((field->flags & Modifier::PRIVATE) ? 1 : 0)
1077                 +((field->flags & Modifier::PROTECTED) ? 1 : 0)))
1078         throw_class_format_error ("erroneous field access flags");
1079     }
1080
1081   _Jv_Utf8Const* sig = pool_data[desc].utf8;
1082
1083   if (verify)
1084     _Jv_VerifyFieldSignature (sig);
1085
1086   // field->type is really a jclass, but while it is still
1087   // unresolved we keep an _Jv_Utf8Const* instead.
1088   field->type       = (jclass) sig;
1089   field->flags     |= _Jv_FIELD_UNRESOLVED_FLAG;
1090   field->u.boffset  = 0;
1091 }
1092
1093
1094 void _Jv_ClassReader::handleConstantValueAttribute (int field_index, 
1095                                                     int value)
1096 {
1097   using namespace java::lang::reflect;
1098
1099   _Jv_Field *field = &def->fields[field_index];
1100
1101   if ((field->flags & (Modifier::STATIC
1102                        | Modifier::FINAL
1103                        | Modifier::PRIVATE)) == 0)
1104     {
1105       // Ignore, as per vmspec #4.7.2
1106       return;
1107     }
1108
1109   // do not allow multiple constant fields!
1110   if (field->flags & _Jv_FIELD_CONSTANT_VALUE)
1111     throw_class_format_error ("field has multiple ConstantValue attributes");
1112
1113   field->flags |= _Jv_FIELD_CONSTANT_VALUE;
1114   def->field_initializers[field_index] = value;
1115
1116   /* type check the initializer */
1117   
1118   if (value <= 0 || value >= pool_count)
1119     throw_class_format_error ("erroneous ConstantValue attribute");
1120
1121   /* FIXME: do the rest */
1122 }
1123
1124 void _Jv_ClassReader::handleFieldsEnd ()
1125 {
1126   using namespace java::lang::reflect;
1127
1128   // We need to reorganize the fields so that the static ones are first,
1129   // to conform to GCJ class layout.
1130
1131   int low            = 0;
1132   int high           = def->field_count-1;
1133   _Jv_Field  *fields = def->fields;
1134   _Jv_ushort *inits  = def->field_initializers;
1135
1136   // this is kind of a raw version of quicksort.
1137   while (low < high)
1138     {
1139       // go forward on low, while it's a static
1140       while (low < high && (fields[low].flags & Modifier::STATIC) != 0)
1141         low++;
1142       
1143       // go backwards on high, while it's a non-static
1144       while (low < high && (fields[high].flags & Modifier::STATIC) == 0)
1145         high--;
1146
1147       if (low==high)
1148         break;
1149
1150       _Jv_Field  tmp  = fields[low];
1151       _Jv_ushort itmp = inits[low];
1152           
1153       fields[low] = fields[high];
1154       inits[low]  = inits[high];
1155           
1156       fields[high] = tmp;
1157       inits[high]  = itmp;
1158           
1159       high -= 1;
1160       low  += 1;
1161     }
1162   
1163   if ((fields[low].flags & Modifier::STATIC) != 0) 
1164     low += 1;
1165
1166   def->static_field_count = low;
1167 }
1168
1169
1170
1171 void
1172 _Jv_ClassReader::handleMethodsBegin (int count)
1173 {
1174   def->methods = (_Jv_Method*)
1175     _Jv_AllocBytes (sizeof (_Jv_Method)*count);
1176
1177   def->interpreted_methods
1178     = (_Jv_MethodBase **) _Jv_AllocBytes (sizeof (_Jv_MethodBase *)
1179                                           * count);
1180
1181   for (int i = 0; i < count; i++)
1182     def->interpreted_methods[i] = 0;
1183
1184   def->method_count = count;
1185 }
1186
1187
1188 void _Jv_ClassReader::handleMethod 
1189     (int mth_index, int accflags, int name, int desc)
1190
1191   using namespace java::lang::reflect;
1192
1193   _Jv_word *pool_data = def->constants.data;
1194   _Jv_Method *method = &def->methods[mth_index];
1195
1196   check_tag (name, JV_CONSTANT_Utf8);
1197   prepare_pool_entry (name, JV_CONSTANT_Utf8);
1198   method->name = pool_data[name].utf8;
1199
1200   check_tag (desc, JV_CONSTANT_Utf8);
1201   prepare_pool_entry (desc, JV_CONSTANT_Utf8);
1202   method->signature = pool_data[desc].utf8;
1203
1204   // ignore unknown flags
1205   method->accflags = accflags & Modifier::ALL_FLAGS;
1206
1207   // intialize...
1208   method->ncode = 0;
1209   
1210   if (verify)
1211     {
1212       if (_Jv_equalUtf8Consts (method->name, clinit_name)
1213           || _Jv_equalUtf8Consts (method->name, init_name))
1214         /* ignore */;
1215       else
1216         verify_identifier (method->name);
1217
1218       _Jv_VerifyMethodSignature (method->signature);
1219
1220       if (method->accflags & (Modifier::VOLATILE
1221                               | Modifier::TRANSIENT
1222                               | Modifier::INTERFACE))
1223         throw_class_format_error ("erroneous method access flags");
1224       
1225       if (1 < ( ((method->accflags & Modifier::PUBLIC) ? 1 : 0)
1226                 +((method->accflags & Modifier::PRIVATE) ? 1 : 0)
1227                 +((method->accflags & Modifier::PROTECTED) ? 1 : 0)))
1228         throw_class_format_error ("erroneous method access flags");
1229     }
1230 }
1231
1232 void _Jv_ClassReader::handleCodeAttribute
1233   (int method_index, int max_stack, int max_locals, 
1234    int code_start, int code_length, int exc_table_length)
1235 {
1236   int size = _Jv_InterpMethod::size (exc_table_length, code_length);
1237   _Jv_InterpMethod *method = 
1238     (_Jv_InterpMethod*) (_Jv_AllocBytes (size));
1239
1240   method->max_stack      = max_stack;
1241   method->max_locals     = max_locals;
1242   method->code_length    = code_length;
1243   method->exc_count      = exc_table_length;
1244   method->defining_class = def;
1245   method->self           = &def->methods[method_index];
1246
1247   // grab the byte code!
1248   memcpy ((void*) method->bytecode (),
1249           (void*) (bytes+code_start),
1250           code_length);
1251   
1252   def->interpreted_methods[method_index] = method;
1253
1254   /* that's all we do for now */
1255 }
1256
1257 void _Jv_ClassReader::handleExceptionTableEntry 
1258   (int method_index, int exc_index, 
1259    int start_pc, int end_pc, int handler_pc, int catch_type)
1260 {
1261   _Jv_InterpMethod *method = reinterpret_cast<_Jv_InterpMethod *>
1262     (def->interpreted_methods[method_index]);
1263   _Jv_InterpException *exc = method->exceptions ();
1264
1265   exc[exc_index].start_pc     = start_pc;
1266   exc[exc_index].end_pc       = end_pc;
1267   exc[exc_index].handler_pc   = handler_pc;
1268   exc[exc_index].handler_type = catch_type;
1269 }
1270
1271 void _Jv_ClassReader::handleMethodsEnd ()
1272 {
1273   using namespace java::lang::reflect;
1274
1275   for (int i = 0; i < def->method_count; i++)
1276     {
1277       _Jv_Method *method = &def->methods[i];
1278       if ((method->accflags & Modifier::NATIVE) != 0)
1279         {
1280           if (def->interpreted_methods[i] != 0)
1281             throw_class_format_error ("code provided for native method");
1282           else
1283             {
1284               _Jv_JNIMethod *m = (_Jv_JNIMethod *)
1285                 _Jv_AllocBytes (sizeof (_Jv_JNIMethod));
1286               m->defining_class = def;
1287               m->self = method;
1288               m->function = NULL;
1289               def->interpreted_methods[i] = m;
1290             }
1291         }
1292       else if ((method->accflags & Modifier::ABSTRACT) != 0)
1293         {
1294           if (def->interpreted_methods[i] != 0)
1295             throw_class_format_error ("code provided for abstract method");
1296         }
1297       else
1298         {
1299           if (def->interpreted_methods[i] == 0)
1300             throw_class_format_error ("method with no code");
1301         }
1302     }
1303
1304 }
1305
1306 void _Jv_ClassReader::throw_class_format_error (char *msg)
1307 {
1308   jstring str;
1309   if (def->name != NULL)
1310     {
1311       jsize mlen = strlen (msg);
1312       unsigned char* data = (unsigned char*) def->name->data;
1313       int ulen = def->name->length;
1314       unsigned char* limit = data + ulen;
1315       jsize nlen = _Jv_strLengthUtf8 ((char *) data, ulen);
1316       jsize len = nlen + mlen + 3;
1317       str = JvAllocString(len);
1318       jchar *chrs = JvGetStringChars(str);
1319       while (data < limit)
1320         *chrs++ = UTF8_GET(data, limit);
1321       *chrs++ = ' ';
1322       *chrs++ = '(';
1323       for (;;)
1324         {
1325           char c = *msg++;
1326           if (c == 0)
1327             break;
1328           *chrs++ = c & 0xFFFF;
1329         }
1330       *chrs++ = ')';
1331     }
1332   else
1333     str = JvNewStringLatin1 (msg);
1334   ::throw_class_format_error (str);
1335 }
1336 \f
1337 /** This section takes care of verifying integrity of identifiers,
1338     signatures, field ddescriptors, and class names */
1339
1340 #define UTF8_PEEK(PTR, LIMIT) \
1341   ({ unsigned char* xxkeep = (PTR); \
1342      int xxch = UTF8_GET(PTR,LIMIT); \
1343      PTR = xxkeep; xxch; })
1344
1345 /* verify one element of a type descriptor or signature */
1346 static unsigned char*
1347 _Jv_VerifyOne (unsigned char* ptr, unsigned char* limit, bool void_ok)
1348 {
1349   if (ptr >= limit)
1350     return 0;
1351
1352   int ch = UTF8_GET (ptr, limit);
1353
1354   switch (ch)
1355     {
1356     case 'V':
1357       if (! void_ok) return 0;
1358
1359     case 'S': case 'B': case 'I': case 'J':
1360     case 'Z': case 'C': case 'F': case 'D': 
1361       break;
1362
1363     case 'L':
1364       {
1365         unsigned char *start = ptr, *end;
1366         do {
1367           if (ptr > limit)
1368             return 0;
1369                 
1370           end = ptr;
1371                 
1372           if ((ch = UTF8_GET (ptr, limit)) == -1)
1373             return 0;
1374                 
1375         } while (ch != ';');
1376         if (! _Jv_VerifyClassName (start, (unsigned short) (end-start)))
1377           return 0;
1378       }
1379       break;
1380
1381     case '[':
1382       return _Jv_VerifyOne (ptr, limit, false);
1383       break;
1384         
1385     default:
1386       return 0;
1387     }
1388
1389   return ptr;
1390     
1391 }
1392
1393
1394 /** verification and loading procedures **/
1395
1396 bool
1397 _Jv_VerifyFieldSignature (_Jv_Utf8Const*sig)
1398 {
1399   unsigned char* ptr = (unsigned char*) sig->data;
1400   unsigned char* limit = ptr + sig->length;
1401
1402   ptr = _Jv_VerifyOne (ptr, limit, false);
1403
1404   return ptr == limit;
1405 }
1406
1407 bool
1408 _Jv_VerifyMethodSignature (_Jv_Utf8Const*sig)
1409 {
1410   unsigned char* ptr = (unsigned char*) sig->data;
1411   unsigned char* limit = ptr + sig->length;
1412
1413   if (ptr == limit || UTF8_GET(ptr,limit) != '(')
1414     return false;
1415
1416   while (ptr && UTF8_PEEK (ptr, limit) != ')')
1417     ptr = _Jv_VerifyOne (ptr, limit, false);
1418     
1419   if (UTF8_GET (ptr, limit) != ')')
1420     return false;
1421
1422   // get the return type
1423   ptr = _Jv_VerifyOne (ptr, limit, true);
1424
1425   return ptr == limit;
1426 }
1427
1428 /* we try to avoid calling the Character methods all the time, 
1429    in fact, they will only be called for non-standard things */
1430
1431 static __inline__ int 
1432 is_identifier_start (int c)
1433 {
1434   unsigned int ch = (unsigned)c;
1435
1436   if ((ch - 0x41U) < 29U)               /* A ... Z */
1437     return 1;
1438   if ((ch - 0x61U) < 29U)               /* a ... z */
1439     return 1;
1440   if (ch == 0x5FU)                      /* _ */
1441     return 1;
1442
1443   return character->isJavaIdentifierStart ((jchar) ch);
1444 }
1445
1446 static __inline__ int 
1447 is_identifier_part (int c)
1448 {
1449   unsigned int ch = (unsigned)c;
1450
1451   if ((ch - 0x41U) < 29U)               /* A ... Z */
1452     return 1;
1453   if ((ch - 0x61U) < 29U)               /* a ... z */
1454     return 1;
1455   if ((ch - 0x30) < 10U)                /* 0 .. 9 */
1456     return 1;
1457   if (ch == 0x5FU || ch == 0x24U)       /* _ $ */
1458     return 1;
1459
1460   return character->isJavaIdentifierStart ((jchar) ch);
1461 }
1462
1463 bool
1464 _Jv_VerifyIdentifier (_Jv_Utf8Const* name)
1465 {
1466   unsigned char *ptr   = (unsigned char*) name->data;
1467   unsigned char *limit = ptr + name->length;
1468   int ch;
1469
1470   if ((ch = UTF8_GET (ptr, limit))==-1
1471       || ! is_identifier_start (ch))
1472     return false;
1473
1474   while (ptr != limit)
1475     {
1476       if ((ch = UTF8_GET (ptr, limit))==-1
1477           || ! is_identifier_part (ch))
1478         return false;
1479     }
1480   return true;
1481 }
1482
1483 bool
1484 _Jv_VerifyClassName (unsigned char* ptr, _Jv_ushort length)
1485 {
1486   unsigned char *limit = ptr+length;
1487   int ch;
1488
1489   if ('[' == UTF8_PEEK (ptr, limit))
1490     {
1491       if (! _Jv_VerifyOne (++ptr, limit, false))
1492         return false;
1493       else
1494         return true;
1495     }
1496
1497  next_level:
1498   for (;;) {
1499     if ((ch = UTF8_GET (ptr, limit))==-1)
1500       return false;
1501     if (! is_identifier_start (ch))
1502       return false;
1503     for (;;) {
1504       if (ptr == limit)
1505         return true;
1506       else if ((ch = UTF8_GET (ptr, limit))==-1)
1507         return false;
1508       else if (ch == '.')
1509         goto next_level;
1510       else if (! is_identifier_part (ch))
1511         return false;
1512     }
1513   }
1514 }
1515
1516 bool
1517 _Jv_VerifyClassName (_Jv_Utf8Const *name)
1518 {
1519   return _Jv_VerifyClassName ((unsigned char*)&name->data[0],
1520                               (_Jv_ushort) name->length);
1521 }
1522
1523 /** returns true, if name1 and name2 represents classes in the same
1524     package. */
1525     
1526 bool
1527 _Jv_ClassNameSamePackage (_Jv_Utf8Const *name1, _Jv_Utf8Const *name2)
1528 {
1529   unsigned char* ptr1 = (unsigned char*) name1->data;
1530   unsigned char* limit1 = ptr1 + name1->length;
1531
1532   unsigned char* last1 = ptr1;
1533
1534   // scan name1, and find the last occurrence of '.'
1535   while (ptr1 < limit1) {
1536     int ch1 = UTF8_GET (ptr1, limit1);
1537
1538     if (ch1 == '.')
1539       last1 = ptr1;
1540         
1541     else if (ch1 == -1)
1542       return false;
1543   }
1544
1545   // now the length of name1's package name is len
1546   int len = last1 - (unsigned char*) name1->data;
1547
1548   // if this is longer than name2, then we're off
1549   if (len > name2->length)
1550     return false;
1551
1552   // then compare the first len bytes for equality
1553   if (memcmp ((void*) name1->data, (void*) name2->data, len) == 0)
1554     {
1555       // check that there are no .'s after position len in name2
1556
1557       unsigned char* ptr2 = (unsigned char*) name2->data + len;
1558       unsigned char* limit2 =
1559         (unsigned char*) name2->data + name2->length;
1560
1561       while (ptr2 < limit2)
1562         {
1563           int ch2 = UTF8_GET (ptr2, limit2);
1564           if (ch2 == -1 || ch2 == '.')
1565             return false;
1566         }
1567       return true;
1568     }
1569   return false;
1570 }
1571
1572
1573 \f
1574 /** Here we define the exceptions that can be thrown */
1575
1576 static void
1577 throw_no_class_def_found_error (jstring msg)
1578 {
1579   throw (msg
1580          ? new java::lang::NoClassDefFoundError (msg)
1581          : new java::lang::NoClassDefFoundError);
1582 }
1583
1584 static void
1585 throw_no_class_def_found_error (char *msg)
1586 {
1587   throw_no_class_def_found_error (JvNewStringLatin1 (msg));
1588 }
1589
1590 static void
1591 throw_class_format_error (jstring msg)
1592 {
1593   throw (msg
1594          ? new java::lang::ClassFormatError (msg)
1595          : new java::lang::ClassFormatError);
1596 }
1597
1598 static void
1599 throw_internal_error (char *msg)
1600 {
1601   throw new java::lang::InternalError (JvNewStringLatin1 (msg));
1602 }
1603
1604 static jfloat int_bits_to_float (jint value)
1605 {
1606   return java::lang::Float::intBitsToFloat (value);
1607 }
1608
1609 static jdouble long_bits_to_double (jlong value)
1610 {
1611   return java::lang::Double::longBitsToDouble (value);
1612 }
1613
1614 static void throw_incompatible_class_change_error (jstring msg)
1615 {
1616   throw new java::lang::IncompatibleClassChangeError (msg);
1617 }
1618
1619 static void throw_class_circularity_error (jstring msg)
1620 {
1621   throw new java::lang::ClassCircularityError (msg);
1622 }
1623
1624 #endif /* INTERPRETER */
1625